diff --git a/.claude-plugin/plugins/unity-cli/agents/unity-helper.md b/.claude-plugin/plugins/unity-cli/agents/unity-helper.md index a9db29d9..4492bc6c 100644 --- a/.claude-plugin/plugins/unity-cli/agents/unity-helper.md +++ b/.claude-plugin/plugins/unity-cli/agents/unity-helper.md @@ -32,7 +32,7 @@ You are a Unity automation specialist. Execute multi-step workflows using `unity ### Code Scaffold -1. Create class with `create_class` or `create_csharp_file` → update code with `write_csharp_file` or `apply_csharp_edits` → build or update index → check compilation state +1. Create the script with `create_csharp_file` (LSP-validated; `create_class` is only an empty-class shortcut on the same LSP path) → update code with `write_csharp_file`, `apply_csharp_edits`, or symbol edits → build or update index → check compilation state → fix compile errors with the same LSP write tools, never with direct file edits ### Test Cycle diff --git a/.claude-plugin/plugins/unity-cli/skills/unity-2d-sprite-tilemap/references/runtime-checklist.md b/.claude-plugin/plugins/unity-cli/skills/unity-2d-sprite-tilemap/references/runtime-checklist.md index f4c50a8f..6765fc38 100644 --- a/.claude-plugin/plugins/unity-cli/skills/unity-2d-sprite-tilemap/references/runtime-checklist.md +++ b/.claude-plugin/plugins/unity-cli/skills/unity-2d-sprite-tilemap/references/runtime-checklist.md @@ -35,7 +35,7 @@ - A failed `system ping` does not prove the Editor is closed. Run `unity-cli doctor --output json` (add `--project-path ` outside the project) before any fallback such as hand-editing YAML. - Act on the `diagnosis` code: - - `SAFE_MODE` / `COMPILE_ERRORS`: the bridge is not loaded. Fix each `editorLog.compileErrors[]` entry (`file`, `line`, `code`) by editing the file directly, then let Unity recompile or restart the Editor. + - `SAFE_MODE` / `COMPILE_ERRORS`: the bridge is not loaded. Fix each `editorLog.compileErrors[]` entry (`file`, `line`, `code`) with the LSP write tools (`apply_csharp_edits`, `replace_symbol_body`, `write_csharp_file`); they run locally and do not need the bridge. Then let Unity recompile or restart the Editor. - `BRIDGE_NOT_INSTALLED`: run `unity-cli setup` (or `unity-cli bridge install`) to add `com.akiojin.unity-cli-bridge` to `Packages/manifest.json`. - `PORT_IN_USE`: `port.listenerPid` / `port.listenerProcess` hold the port. Stop it or change the bridge port and pass the same `--port`. - `EDITOR_NOT_RUNNING`: start the Editor for the project and wait for import to finish. diff --git a/.claude-plugin/plugins/unity-cli/skills/unity-audio-setup/references/runtime-checklist.md b/.claude-plugin/plugins/unity-cli/skills/unity-audio-setup/references/runtime-checklist.md index f4c50a8f..6765fc38 100644 --- a/.claude-plugin/plugins/unity-cli/skills/unity-audio-setup/references/runtime-checklist.md +++ b/.claude-plugin/plugins/unity-cli/skills/unity-audio-setup/references/runtime-checklist.md @@ -35,7 +35,7 @@ - A failed `system ping` does not prove the Editor is closed. Run `unity-cli doctor --output json` (add `--project-path ` outside the project) before any fallback such as hand-editing YAML. - Act on the `diagnosis` code: - - `SAFE_MODE` / `COMPILE_ERRORS`: the bridge is not loaded. Fix each `editorLog.compileErrors[]` entry (`file`, `line`, `code`) by editing the file directly, then let Unity recompile or restart the Editor. + - `SAFE_MODE` / `COMPILE_ERRORS`: the bridge is not loaded. Fix each `editorLog.compileErrors[]` entry (`file`, `line`, `code`) with the LSP write tools (`apply_csharp_edits`, `replace_symbol_body`, `write_csharp_file`); they run locally and do not need the bridge. Then let Unity recompile or restart the Editor. - `BRIDGE_NOT_INSTALLED`: run `unity-cli setup` (or `unity-cli bridge install`) to add `com.akiojin.unity-cli-bridge` to `Packages/manifest.json`. - `PORT_IN_USE`: `port.listenerPid` / `port.listenerProcess` hold the port. Stop it or change the bridge port and pass the same `--port`. - `EDITOR_NOT_RUNNING`: start the Editor for the project and wait for import to finish. diff --git a/.claude-plugin/plugins/unity-cli/skills/unity-cli-usage/references/runtime-checklist.md b/.claude-plugin/plugins/unity-cli/skills/unity-cli-usage/references/runtime-checklist.md index 059c7bb3..159db7d7 100644 --- a/.claude-plugin/plugins/unity-cli/skills/unity-cli-usage/references/runtime-checklist.md +++ b/.claude-plugin/plugins/unity-cli/skills/unity-cli-usage/references/runtime-checklist.md @@ -52,7 +52,7 @@ completion and inspect that call's exit code. - A failed `system ping` does not prove the Editor is closed. Run `unity-cli doctor --output json` (add `--project-path ` outside the project) before any fallback such as hand-editing YAML. - Act on the `diagnosis` code: - - `SAFE_MODE` / `COMPILE_ERRORS`: the bridge is not loaded. Fix each `editorLog.compileErrors[]` entry (`file`, `line`, `code`) by editing the file directly, then let Unity recompile or restart the Editor. + - `SAFE_MODE` / `COMPILE_ERRORS`: the bridge is not loaded. Fix each `editorLog.compileErrors[]` entry (`file`, `line`, `code`) with the LSP write tools (`apply_csharp_edits`, `replace_symbol_body`, `write_csharp_file`); they run locally and do not need the bridge. Then let Unity recompile or restart the Editor. - `BRIDGE_NOT_INSTALLED`: run `unity-cli setup` (or `unity-cli bridge install`) to add `com.akiojin.unity-cli-bridge` to `Packages/manifest.json`. - `PORT_IN_USE`: `port.listenerPid` / `port.listenerProcess` hold the port. Stop it or change the bridge port and pass the same `--port`. - `EDITOR_NOT_RUNNING`: start the Editor for the project and wait for import to finish. diff --git a/.claude-plugin/plugins/unity-cli/skills/unity-csharp-edit/SKILL.md b/.claude-plugin/plugins/unity-cli/skills/unity-csharp-edit/SKILL.md index 81398193..460f6820 100644 --- a/.claude-plugin/plugins/unity-cli/skills/unity-csharp-edit/SKILL.md +++ b/.claude-plugin/plugins/unity-cli/skills/unity-csharp-edit/SKILL.md @@ -1,14 +1,19 @@ --- name: unity-csharp-edit -description: Implement, fix, and refactor Unity C# code with unity-cli write tools. Use when the user wants to change behavior in .cs files, create or rewrite scripts, update multiple C# files together, rename a symbol, add or remove members, or change project or package settings as part of a code change. Do not use for read-only inspection with no planned edit; use `unity-csharp-navigate` instead. +description: Implement, fix, and refactor Unity C# code with unity-cli write tools. Use when the user wants to change behavior in .cs files, create a new script, class, MonoBehaviour or ScriptableObject, rewrite scripts, fix compile errors, update multiple C# files together, rename a symbol, add or remove members, or change project or package settings as part of a code change. Do not use for read-only inspection with no planned edit; use `unity-csharp-navigate` instead. allowed-tools: Bash(unity-cli:*), Read, Grep, Glob, Edit, Write metadata: author: akiojin - version: 0.3.0 + version: 0.3.2 category: code triggers: - csharp - script + - new script + - class + - monobehaviour + - scriptableobject + - compile error - rename - refactor - symbol @@ -31,7 +36,8 @@ Implement Unity C# changes with `unity-cli` as the primary write path. Prefer th ## Use When - The user intends to change C# behavior in `.cs` files. -- The user wants to create or rewrite scripts (single or coordinated multi-file). +- The user wants to create a new script, class, `MonoBehaviour`, or `ScriptableObject`, or rewrite scripts (single or coordinated multi-file). +- The user wants to fix C# compile errors. - The user asks for a symbol rename, member add/remove, or refactor. - The user changes project or package settings as part of a code change. @@ -44,22 +50,38 @@ Implement Unity C# changes with `unity-cli` as the primary write path. Prefer th ## Preferred Flow -1. Decide the write shape: symbol edit, full-file write, multi-file write, or settings change. +1. Decide the write shape: new file, symbol edit, full-file write, multi-file write, or settings change. Always write `.cs` files through the LSP write tools (`create_csharp_file`, `write_csharp_file`, `apply_csharp_edits`, symbol edits) so the text is validated before it lands; do not hand-write `.cs` files with direct file edits unless the LSP write path fails (see LSP Write Failure Fallback). 2. Read only the minimum context with `read`, `get_symbols`, `find_symbol`, or `find_refs`. 3. Preview risky symbol edits with `apply: false`. 4. Apply with `refresh`, `waitForCompile`, and `updateIndex` when later steps depend on clean diagnostics. 5. Inspect `changedFiles`, `changedSymbols`, and `diagnostics`; fix compilation issues before unrelated follow-up. ```bash +unity-cli raw create_csharp_file --json '{"relative":"Assets/Scripts/EnemyAI.cs","text":"using UnityEngine;\n\npublic class EnemyAI : MonoBehaviour\n{\n}\n","validate":true,"apply":true,"waitForCompile":true,"updateIndex":true}' unity-cli raw get_symbols --json '{"path":"Assets/Scripts/Player.cs"}' unity-cli raw rename_symbol --json '{"relative":"Assets/Scripts/Player.cs","namePath":"Player/Jump","newName":"Leap","apply":false}' unity-cli raw apply_csharp_edits --json '{"files":[{"relative":"Assets/Scripts/IPlayerMover.cs","newText":"public interface IPlayerMover { void Move(); }\n"}],"validate":true,"apply":true,"waitForCompile":true,"updateIndex":true}' unity-cli raw get_compilation_state --json '{}' ``` +## LSP Write Failure Fallback + +Use this only when an LSP write tool fails: the LSP server fails to start, the call times out, or the tool returns an unsupported-edit error. Retry once if the failure looks transient; do not stop the task. + +1. Make the same change with your own `Edit` (existing file) or `Write` (new file). Keep it identical in scope to the intended LSP write. +2. Refresh and confirm compilation with `unity-cli`: + ```bash + unity-cli raw refresh_assets --json '{}' + unity-cli raw get_compilation_state --json '{}' + ``` + Fix any reported errors before continuing; if the Editor is unreachable, say so and leave compilation unconfirmed. +3. In your work report, state that the LSP path was not used, which tool failed, and why (error code or message). + ## Examples - "Implement dash cooldown in `PlayerController.cs` and update the related tests." +- "Create an `EnemyAI` MonoBehaviour in `Assets/Scripts/AI`." +- "Fix the compile error in `PlayerController.cs`." - "Rename `Jump` to `Leap` across the player package without breaking serialized field names." - "Create a new editor utility script and change the matching project setting." - "Refactor an interface, its implementation, and the tests in one coordinated write." diff --git a/.claude-plugin/plugins/unity-cli/skills/unity-csharp-edit/references/file-write-recipes.md b/.claude-plugin/plugins/unity-cli/skills/unity-csharp-edit/references/file-write-recipes.md index ee3621e6..756803b4 100644 --- a/.claude-plugin/plugins/unity-cli/skills/unity-csharp-edit/references/file-write-recipes.md +++ b/.claude-plugin/plugins/unity-cli/skills/unity-csharp-edit/references/file-write-recipes.md @@ -32,11 +32,10 @@ Recommended options: ## Choose `create_csharp_file` When -- You need a new file that is not just a standard class shell. -- The file should contain an interface, enum, test fixture, editor utility, or multiple types. +- You need any new `.cs` file: a class, `MonoBehaviour`, `ScriptableObject`, interface, enum, test fixture, editor utility, or multiple types. - You want the same validated write contract as `write_csharp_file`. -Use `create_class` only when the class template itself is the useful shortcut. +`create_class` is a shortcut for an empty class shell (`name`, `folder`, optional `namespace` / `inherits`). It writes through the same LSP path as `create_csharp_file`, so both are safe; prefer `create_csharp_file` when the file needs members. ## Choose `apply_csharp_edits` When @@ -56,6 +55,7 @@ Keep the `files` array minimal and coherent. If files are unrelated, split the t ## Example Paths ```bash +unity-cli raw create_csharp_file --json '{"relative":"Assets/Scripts/EnemyAI.cs","text":"using UnityEngine;\n\npublic class EnemyAI : MonoBehaviour\n{\n}\n","validate":true,"apply":true,"waitForCompile":true,"updateIndex":true}' unity-cli raw replace_symbol_body --json '{"relative":"Assets/Scripts/PlayerController.cs","namePath":"PlayerController/Move","body":"{ transform.position += direction * speed * Time.deltaTime; }","apply":false}' unity-cli raw write_csharp_file --json '{"relative":"Assets/Scripts/PlayerController.cs","newText":"using UnityEngine;\n\npublic sealed class PlayerController : MonoBehaviour {}\n","validate":true,"apply":true,"waitForCompile":true,"updateIndex":true}' unity-cli raw apply_csharp_edits --json '{"files":[{"relative":"Assets/Scripts/IPlayerMover.cs","newText":"public interface IPlayerMover { void Move(); }\n"},{"relative":"Assets/Scripts/PlayerMover.cs","newText":"public sealed class PlayerMover : IPlayerMover { public void Move() {} }\n"},{"relative":"Assets/Tests/EditMode/PlayerMoverTests.cs","newText":"using NUnit.Framework;\n\npublic class PlayerMoverTests {}\n"}],"validate":true,"apply":true,"waitForCompile":true,"updateIndex":true}' diff --git a/.claude-plugin/plugins/unity-cli/skills/unity-csharp-edit/references/lsp-write-safety.md b/.claude-plugin/plugins/unity-cli/skills/unity-csharp-edit/references/lsp-write-safety.md index 2782701b..e2063ec5 100644 --- a/.claude-plugin/plugins/unity-cli/skills/unity-csharp-edit/references/lsp-write-safety.md +++ b/.claude-plugin/plugins/unity-cli/skills/unity-csharp-edit/references/lsp-write-safety.md @@ -25,7 +25,15 @@ 3. Run `get_compilation_state` for non-trivial edits or when diagnostics are still unclear. 4. Report and fix real diagnostics before attempting unrelated follow-up changes. -## Class Creation +## New Files -- Use `create_class` for new files instead of hand-writing boilerplate when possible. +- Use `create_csharp_file` for every new `.cs` file (classes, `MonoBehaviour`, `ScriptableObject`, interfaces, enums, tests). It validates the text through LSP before writing. +- `create_class` (`name`, `folder`, optional `namespace` / `inherits`) is a shortcut that renders an empty class shell and writes it through the same LSP path as `create_csharp_file`. Prefer `create_csharp_file` when the file needs any members. +- Do not create or edit `.cs` files with direct file writes; they skip LSP validation. The only exception is the `LSP Write Failure Fallback` in `SKILL.md`. - Use `validate_text_edits` when constructing larger manual replacements. + +## Compile Error Fixes + +- Read the error `file` / `line` from `get_compilation_state` or `editorLog.compileErrors[]`. +- Fix it with the smallest LSP write: `replace_symbol_body` for one member, `write_csharp_file` for one file, `apply_csharp_edits` when several files must change together. +- These tools run locally, so they work in `SAFE_MODE` when the bridge is not loaded. diff --git a/.claude-plugin/plugins/unity-cli/skills/unity-development-loop/references/runtime-checklist.md b/.claude-plugin/plugins/unity-cli/skills/unity-development-loop/references/runtime-checklist.md index be3cb6c4..3fe6e0ff 100644 --- a/.claude-plugin/plugins/unity-cli/skills/unity-development-loop/references/runtime-checklist.md +++ b/.claude-plugin/plugins/unity-cli/skills/unity-development-loop/references/runtime-checklist.md @@ -22,7 +22,7 @@ - A failed `system ping` does not prove the Editor is closed. Run `unity-cli doctor --output json` (add `--project-path ` outside the project) before any fallback such as hand-editing YAML. - Act on the `diagnosis` code: - - `SAFE_MODE` / `COMPILE_ERRORS`: the bridge is not loaded. Fix each `editorLog.compileErrors[]` entry (`file`, `line`, `code`) by editing the file directly, then let Unity recompile or restart the Editor. + - `SAFE_MODE` / `COMPILE_ERRORS`: the bridge is not loaded. Fix each `editorLog.compileErrors[]` entry (`file`, `line`, `code`) with the LSP write tools (`apply_csharp_edits`, `replace_symbol_body`, `write_csharp_file`); they run locally and do not need the bridge. Then let Unity recompile or restart the Editor. - `BRIDGE_NOT_INSTALLED`: add `com.akiojin.unity-cli-bridge` to `Packages/manifest.json`. - `PORT_IN_USE`: `port.listenerPid` / `port.listenerProcess` hold the port. Stop it or change the bridge port and pass the same `--port`. - `EDITOR_NOT_RUNNING`: start the Editor for the project and wait for import to finish. diff --git a/.claude-plugin/plugins/unity-cli/skills/unity-gameobject-edit/SKILL.md b/.claude-plugin/plugins/unity-cli/skills/unity-gameobject-edit/SKILL.md index 51e2c985..1a7c4889 100644 --- a/.claude-plugin/plugins/unity-cli/skills/unity-gameobject-edit/SKILL.md +++ b/.claude-plugin/plugins/unity-cli/skills/unity-gameobject-edit/SKILL.md @@ -57,6 +57,19 @@ Modify existing GameObjects and their components in an already-prepared scene. T 4. Reserve `delete_gameobject` and `remove_component` for confirmed scopes. 5. Save the scene after destructive or bulk updates so reloads do not lose work. +## Target Parameter Names + +The key that names the target object differs by tool. A wrong key fails locally with `INVALID_ARGUMENT` (`$. is required` or `$. is not allowed`) before reaching Unity. + +| Key | Tools | +| ---------------- | ------------------------------------------------------------------------------------------------- | +| `path` | `modify_gameobject` (its `name` renames), `delete_gameobject` (`paths` for several) | +| `gameObjectPath` | `add_component`, `modify_component`, `set_component_field`, `remove_component`, `list_components` | +| `name` | `find_gameobject`, `create_gameobject` (parent via `parentPath`) | +| `gameObjectName` | read-only queries such as `get_component_values`; see `unity-scene-inspect` | + +When unsure, read the schema: `unity-cli tool schema --output json`. + ```bash unity-cli raw modify_gameobject --json '{"path":"/Player","name":"Hero","active":true}' unity-cli raw add_component --json '{"gameObjectPath":"/Player","componentType":"Rigidbody"}' diff --git a/.claude-plugin/plugins/unity-cli/skills/unity-localization/references/runtime-checklist.md b/.claude-plugin/plugins/unity-cli/skills/unity-localization/references/runtime-checklist.md index f4c50a8f..6765fc38 100644 --- a/.claude-plugin/plugins/unity-cli/skills/unity-localization/references/runtime-checklist.md +++ b/.claude-plugin/plugins/unity-cli/skills/unity-localization/references/runtime-checklist.md @@ -35,7 +35,7 @@ - A failed `system ping` does not prove the Editor is closed. Run `unity-cli doctor --output json` (add `--project-path ` outside the project) before any fallback such as hand-editing YAML. - Act on the `diagnosis` code: - - `SAFE_MODE` / `COMPILE_ERRORS`: the bridge is not loaded. Fix each `editorLog.compileErrors[]` entry (`file`, `line`, `code`) by editing the file directly, then let Unity recompile or restart the Editor. + - `SAFE_MODE` / `COMPILE_ERRORS`: the bridge is not loaded. Fix each `editorLog.compileErrors[]` entry (`file`, `line`, `code`) with the LSP write tools (`apply_csharp_edits`, `replace_symbol_body`, `write_csharp_file`); they run locally and do not need the bridge. Then let Unity recompile or restart the Editor. - `BRIDGE_NOT_INSTALLED`: run `unity-cli setup` (or `unity-cli bridge install`) to add `com.akiojin.unity-cli-bridge` to `Packages/manifest.json`. - `PORT_IN_USE`: `port.listenerPid` / `port.listenerProcess` hold the port. Stop it or change the bridge port and pass the same `--port`. - `EDITOR_NOT_RUNNING`: start the Editor for the project and wait for import to finish. diff --git a/.claude-plugin/plugins/unity-cli/skills/unity-project-bootstrap/references/runtime-checklist.md b/.claude-plugin/plugins/unity-cli/skills/unity-project-bootstrap/references/runtime-checklist.md index 9a43d936..b0bc30bf 100644 --- a/.claude-plugin/plugins/unity-cli/skills/unity-project-bootstrap/references/runtime-checklist.md +++ b/.claude-plugin/plugins/unity-cli/skills/unity-project-bootstrap/references/runtime-checklist.md @@ -35,7 +35,7 @@ - A failed `system ping` does not prove the Editor is closed. Run `unity-cli doctor --output json` (add `--project-path ` outside the project) before any fallback such as hand-editing YAML. - Act on the `diagnosis` code: - - `SAFE_MODE` / `COMPILE_ERRORS`: the bridge is not loaded. Fix each `editorLog.compileErrors[]` entry (`file`, `line`, `code`) by editing the file directly, then let Unity recompile or restart the Editor. + - `SAFE_MODE` / `COMPILE_ERRORS`: the bridge is not loaded. Fix each `editorLog.compileErrors[]` entry (`file`, `line`, `code`) with the LSP write tools (`apply_csharp_edits`, `replace_symbol_body`, `write_csharp_file`); they run locally and do not need the bridge. Then let Unity recompile or restart the Editor. - `BRIDGE_NOT_INSTALLED`: run `unity-cli setup` (or `unity-cli bridge install`) to add `com.akiojin.unity-cli-bridge` to `Packages/manifest.json`. - `PORT_IN_USE`: `port.listenerPid` / `port.listenerProcess` hold the port. Stop it or change the bridge port and pass the same `--port`. - `EDITOR_NOT_RUNNING`: start the Editor for the project and wait for import to finish. diff --git a/.claude-plugin/plugins/unity-cli/skills/unity-scene-inspect/SKILL.md b/.claude-plugin/plugins/unity-cli/skills/unity-scene-inspect/SKILL.md index 14de6dc5..688a39c2 100644 --- a/.claude-plugin/plugins/unity-cli/skills/unity-scene-inspect/SKILL.md +++ b/.claude-plugin/plugins/unity-cli/skills/unity-scene-inspect/SKILL.md @@ -44,6 +44,19 @@ Inspect scene hierarchy, find objects, and read component data without mutating 3. Inspect targets with `get_gameobject_details`, `get_component_values`, or animator queries. 4. Use `analyze_scene_contents` with `includeInactive` for broad audits. +## Target Parameter Names + +Read-only queries name their target differently from the edit tools. A wrong key fails locally with `INVALID_ARGUMENT` before reaching Unity. + +| Key | Tools | +| -------------------------- | -------------------------------------------------------------------------------------------------- | +| `gameObjectName` | `get_component_values`, `get_object_references`, `get_animator_state`, `get_animator_runtime_info` | +| `gameObjectName` or `path` | `get_gameobject_details` | +| `name` | `find_gameobject` | +| `rootPath` | `get_hierarchy` | + +`gameObjectName` takes a name or a hierarchy path such as `/Root/Child`. Edit tools use `path` or `gameObjectPath` instead; see `unity-gameobject-edit`. When unsure: `unity-cli tool schema --output json`. + ```bash unity-cli raw get_hierarchy --json '{"nameOnly":true}' unity-cli raw find_gameobject --json '{"name":"Player"}' diff --git a/.claude-plugin/plugins/unity-cli/skills/unity-ui-toolkit-build/references/runtime-checklist.md b/.claude-plugin/plugins/unity-cli/skills/unity-ui-toolkit-build/references/runtime-checklist.md index f4c50a8f..6765fc38 100644 --- a/.claude-plugin/plugins/unity-cli/skills/unity-ui-toolkit-build/references/runtime-checklist.md +++ b/.claude-plugin/plugins/unity-cli/skills/unity-ui-toolkit-build/references/runtime-checklist.md @@ -35,7 +35,7 @@ - A failed `system ping` does not prove the Editor is closed. Run `unity-cli doctor --output json` (add `--project-path ` outside the project) before any fallback such as hand-editing YAML. - Act on the `diagnosis` code: - - `SAFE_MODE` / `COMPILE_ERRORS`: the bridge is not loaded. Fix each `editorLog.compileErrors[]` entry (`file`, `line`, `code`) by editing the file directly, then let Unity recompile or restart the Editor. + - `SAFE_MODE` / `COMPILE_ERRORS`: the bridge is not loaded. Fix each `editorLog.compileErrors[]` entry (`file`, `line`, `code`) with the LSP write tools (`apply_csharp_edits`, `replace_symbol_body`, `write_csharp_file`); they run locally and do not need the bridge. Then let Unity recompile or restart the Editor. - `BRIDGE_NOT_INSTALLED`: run `unity-cli setup` (or `unity-cli bridge install`) to add `com.akiojin.unity-cli-bridge` to `Packages/manifest.json`. - `PORT_IN_USE`: `port.listenerPid` / `port.listenerProcess` hold the port. Stop it or change the bridge port and pass the same `--port`. - `EDITOR_NOT_RUNNING`: start the Editor for the project and wait for import to finish. diff --git a/.claude-plugin/plugins/unity-cli/skills/unity-urp-setup/references/runtime-checklist.md b/.claude-plugin/plugins/unity-cli/skills/unity-urp-setup/references/runtime-checklist.md index f4c50a8f..6765fc38 100644 --- a/.claude-plugin/plugins/unity-cli/skills/unity-urp-setup/references/runtime-checklist.md +++ b/.claude-plugin/plugins/unity-cli/skills/unity-urp-setup/references/runtime-checklist.md @@ -35,7 +35,7 @@ - A failed `system ping` does not prove the Editor is closed. Run `unity-cli doctor --output json` (add `--project-path ` outside the project) before any fallback such as hand-editing YAML. - Act on the `diagnosis` code: - - `SAFE_MODE` / `COMPILE_ERRORS`: the bridge is not loaded. Fix each `editorLog.compileErrors[]` entry (`file`, `line`, `code`) by editing the file directly, then let Unity recompile or restart the Editor. + - `SAFE_MODE` / `COMPILE_ERRORS`: the bridge is not loaded. Fix each `editorLog.compileErrors[]` entry (`file`, `line`, `code`) with the LSP write tools (`apply_csharp_edits`, `replace_symbol_body`, `write_csharp_file`); they run locally and do not need the bridge. Then let Unity recompile or restart the Editor. - `BRIDGE_NOT_INSTALLED`: run `unity-cli setup` (or `unity-cli bridge install`) to add `com.akiojin.unity-cli-bridge` to `Packages/manifest.json`. - `PORT_IN_USE`: `port.listenerPid` / `port.listenerProcess` hold the port. Stop it or change the bridge port and pass the same `--port`. - `EDITOR_NOT_RUNNING`: start the Editor for the project and wait for import to finish. diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 3f6960f8..03b5c921 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -34,6 +34,11 @@ updates: cargo: patterns: - "*" + ignore: + # bincode >=2 changes the persisted embedding index format; retain 1.3.3 (#342, #475). + # bincode 3.0.0 is also a compile_error!-only release (#472). + - dependency-name: "bincode" + versions: [">=2"] commit-message: prefix: "chore(deps)" labels: diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 0d1ca35c..711c1706 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -15,7 +15,8 @@ `setup --dry-run`, OS screenshot fallback) and is installed through `scripts/install.ps1` - Linux: the same `platform-checks.py` under Xvfb with the X11 screenshot - tools; none of these checks need a Unity Editor + tools, then its screenshot check again with `grim` under a headless `sway` + (Wayland); none of these checks need a Unity Editor - `dotnet test lsp/Server.Tests.csproj` - `cargo llvm-cov` (Rust coverage gate, line >= 90%) - `dotnet test ... /p:CollectCoverage=true` (LSP coverage gate, line >= 90%) @@ -23,6 +24,12 @@ - runs after `chore(release):` pushes to `main` or manual dispatch - creates the release tag, builds release binaries for Linux/macOS/Windows - publishes GitHub Release assets +- `published-install.yml` + - installs the latest published release on `windows-latest` with + `irm .../main/scripts/install.ps1 | iex` and checks `unity-cli --version` + - runs after the `Release` workflow, weekly, on manual dispatch, and for PRs + that change the check itself (not on every PR: it depends on the network + and on the published release) - `main-pr-policy.yml` - branch policy for PRs into `main` - `auto-merge.yml` @@ -30,3 +37,14 @@ `akiojin` or `dependabot[bot]` into `develop` and for the `develop` -> `main` release PR - merges happen only after the branch-protection required checks pass + - external (fork) PRs into `develop` merge only after a threat review: + 1. a reviewer reads the full diff and confirms nothing in it is a threat + 2. a user with write or higher permission (or `akiojin`) adds the + `reviewed-safe` label to the non-draft PR + 3. the workflow enables auto-merge with + `gh pr merge --auto --merge --match-head-commit `, + so commits pushed after the review are never merged + - a new push to a labeled fork PR (`synchronize`) removes `reviewed-safe` and + disables auto-merge; the PR needs a new review and a new label + - runs under `pull_request_target` but never checks out or runs fork code; + every step only calls the `gh` API diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml index bb003205..054a4d94 100644 --- a/.github/workflows/auto-merge.yml +++ b/.github/workflows/auto-merge.yml @@ -2,7 +2,7 @@ name: Auto Merge PR on: pull_request_target: - types: [opened, synchronize, reopened, ready_for_review] + types: [opened, synchronize, reopened, ready_for_review, labeled] branches: - main - develop @@ -16,6 +16,7 @@ jobs: name: Enable auto-merge runs-on: ubuntu-latest if: | + github.event.action != 'labeled' && github.event.pull_request.draft == false && github.event.pull_request.head.repo.full_name == github.repository && (github.event.pull_request.user.login == 'akiojin' || @@ -58,3 +59,89 @@ jobs: echo "Failed to enable auto-merge after 10 minutes" >&2 exit 1 + + # External (fork) PRs: a write+ reviewer approves the threat review by adding + # `reviewed-safe`. Only the head SHA seen at label time may merge. + # Fork code is never checked out; every step only calls the gh API. + external-reviewed: + name: Enable auto-merge for reviewed external PR + runs-on: ubuntu-latest + if: | + github.event.action == 'labeled' && + github.event.label.name == 'reviewed-safe' && + github.event.pull_request.head.repo.full_name != github.repository && + github.event.pull_request.draft == false && + github.event.pull_request.base.ref == 'develop' + steps: + - name: Verify reviewer and enable pinned auto-merge + env: + GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }} + PR_NUMBER: ${{ github.event.pull_request.number }} + REPO: ${{ github.repository }} + ACTOR: ${{ github.event.sender.login }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + LABEL: reviewed-safe + run: | + set -euo pipefail + + revoke() { + echo "$1" >&2 + gh pr edit "$PR_NUMBER" --repo "$REPO" --remove-label "$LABEL" || true + exit 1 + } + + if [ "$ACTOR" != "akiojin" ]; then + permission=$(gh api "repos/$REPO/collaborators/$ACTOR/permission" --jq .permission || echo "none") + case "$permission" in + admin|maintain|write) ;; + *) revoke "$ACTOR has '$permission' permission; write or higher is required to approve" ;; + esac + fi + + current_sha=$(gh pr view "$PR_NUMBER" --repo "$REPO" --json headRefOid --jq .headRefOid) + if [ "$current_sha" != "$HEAD_SHA" ]; then + revoke "Head moved from $HEAD_SHA to $current_sha after labeling; re-review required" + fi + + for i in $(seq 1 60); do + echo "Attempt $i: enable auto-merge for #$PR_NUMBER at $HEAD_SHA" + + if gh pr merge "$PR_NUMBER" --auto --merge --match-head-commit "$HEAD_SHA" --repo "$REPO"; then + echo "Auto-merge enabled" + exit 0 + fi + + mergeable=$(gh pr view "$PR_NUMBER" --repo "$REPO" --json mergeable --jq .mergeable || echo "UNKNOWN") + if [ "$mergeable" = "CONFLICTING" ]; then + echo "PR has merge conflicts; cannot auto-merge" >&2 + exit 1 + fi + + sleep 10 + done + + echo "Failed to enable auto-merge after 10 minutes" >&2 + exit 1 + + # A push after approval invalidates the review: drop the label and auto-merge. + external-revoke: + name: Revoke review on new external commits + runs-on: ubuntu-latest + if: | + github.event.action == 'synchronize' && + github.event.pull_request.head.repo.full_name != github.repository && + contains(github.event.pull_request.labels.*.name, 'reviewed-safe') + steps: + - name: Remove reviewed-safe and disable auto-merge + env: + GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }} + PR_NUMBER: ${{ github.event.pull_request.number }} + REPO: ${{ github.repository }} + LABEL: reviewed-safe + run: | + set -euo pipefail + + gh pr edit "$PR_NUMBER" --repo "$REPO" --remove-label "$LABEL" + gh pr merge "$PR_NUMBER" --repo "$REPO" --disable-auto \ + || echo "Auto-merge was not enabled" + echo "New commits after review; re-review and re-add $LABEL" diff --git a/.github/workflows/lsp-write-reliability.yml b/.github/workflows/lsp-write-reliability.yml new file mode 100644 index 00000000..385a1a57 --- /dev/null +++ b/.github/workflows/lsp-write-reliability.yml @@ -0,0 +1,108 @@ +name: LSP Write Reliability + +on: + workflow_call: + inputs: + repetitions: + default: '3' + type: string + cold_repetitions: + default: '1' + type: string + schedule: + - cron: '17 2 * * 2' + workflow_dispatch: + inputs: + repetitions: + description: Samples per scenario and installed-LSP condition + default: '20' + type: string + cold_repetitions: + description: Samples per scenario for daemon_stopped and first_download + default: '5' + type: string + +permissions: + contents: read + +jobs: + measure: + name: LSP Write Reliability (${{ matrix.os }}) + strategy: + fail-fast: false + matrix: + os: [windows-latest, macos-latest, ubuntu-latest] + runs-on: ${{ matrix.os }} + # Windows cold starts take about 46s each; weekly 20/5 samples need > 2h. + timeout-minutes: 240 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@stable + - uses: actions/setup-dotnet@v6 + with: + dotnet-version: '10.0.x' + - uses: actions/setup-python@v7 + with: + python-version: '3.11' + - uses: actions/cache@v6 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-lsp-reliability-${{ hashFiles('Cargo.lock') }} + - name: Build the real CLI + run: cargo build --bin unity-cli + - name: Publish the real LSP for this runner + shell: bash + run: | + rid=$(python -c 'import platform; print({"Windows":"win","Darwin":"osx","Linux":"linux"}[platform.system()] + ("-arm64" if platform.machine().lower() in ("arm64", "aarch64") else "-x64"))') + dotnet publish lsp/Server.csproj -c Release -r "$rid" --self-contained true -o .cache/lsp-reliability-publish + - name: Verify the measurement and regression gate + run: python -B -m unittest discover -s tests/scripts -p test_lsp_write_reliability.py + - name: Measure writes, cold starts, real downloads, and direct-edit differences + shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPETITIONS: ${{ inputs.repetitions || (github.event_name == 'schedule' && '20') || '3' }} + COLD_REPETITIONS: ${{ inputs.cold_repetitions || (github.event_name == 'schedule' && '5') || '1' }} + run: | + cli=target/debug/unity-cli + if [ "$RUNNER_OS" = Windows ]; then cli="$cli.exe"; fi + python scripts/lsp-write-reliability.py --unity-cli "$cli" \ + --lsp-publish .cache/lsp-reliability-publish --out .cache/lsp-reliability \ + --repetitions "$REPETITIONS" --cold-repetitions "$COLD_REPETITIONS" \ + --download-repetitions "$COLD_REPETITIONS" \ + --baseline tests/fixtures/lsp-write-baseline.json + - name: Upload measured failures as well as successes + if: always() + uses: actions/upload-artifact@v7 + with: + name: lsp-write-reliability-${{ matrix.os }} + path: .cache/lsp-reliability/ + if-no-files-found: error + retention-days: 30 + + report: + name: LSP Write Reliability Report + needs: measure + if: always() + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-python@v7 + with: + python-version: '3.11' + - uses: actions/download-artifact@v8 + with: + pattern: lsp-write-reliability-* + path: .cache/reliability-reports + - name: Aggregate every OS without masking missing or failing measurements + run: | + python scripts/lsp-write-reliability.py --merge .cache/reliability-reports/*/results.json --out .cache/combined-reliability + cat .cache/combined-reliability/summary.md >> "$GITHUB_STEP_SUMMARY" + - uses: actions/upload-artifact@v7 + with: + name: lsp-write-reliability-report + path: .cache/combined-reliability/ + if-no-files-found: error diff --git a/.github/workflows/published-install.yml b/.github/workflows/published-install.yml new file mode 100644 index 00000000..51022358 --- /dev/null +++ b/.github/workflows/published-install.yml @@ -0,0 +1,35 @@ +name: Published Install + +# Installs the latest published release on a clean runner (#465). It depends on +# the network and on the state of the published release, so it stays off the +# per-PR path: it runs after a release, weekly, on demand, and for PRs that +# change this check itself. +on: + workflow_run: + workflows: [Release] + types: [completed] + schedule: + - cron: '17 3 * * 1' + workflow_dispatch: + pull_request: + paths: + - .github/workflows/published-install.yml + - tests/scripts/install-ps1-published-test.ps1 + +permissions: + contents: read + +jobs: + windows-published-install: + name: Windows Published Install + runs-on: windows-latest + timeout-minutes: 15 + if: github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' + steps: + - uses: actions/checkout@v7 + + - name: Install the latest release with install.ps1 and check its version + shell: pwsh + env: + GH_TOKEN: ${{ github.token }} + run: ./tests/scripts/install-ps1-published-test.ps1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5193ebc2..b423ba96 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,6 +11,9 @@ permissions: contents: read jobs: + lsp-write-reliability: + uses: ./.github/workflows/lsp-write-reliability.yml + cli-latency: name: CLI Latency (required) runs-on: ubuntu-latest @@ -49,7 +52,7 @@ jobs: - name: Upload CLI latency evidence if: always() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: cli-latency path: artifacts/cli-latency*.json @@ -135,6 +138,11 @@ jobs: shell: pwsh run: ./tests/scripts/install-ps1-binary-test.ps1 -Binary target/debug/unity-cli.exe + - name: Install the built binary with install-from-source.ps1 + if: ${{ !cancelled() }} + shell: pwsh + run: ./tests/scripts/install-from-source-ps1-test.ps1 -Binary target/debug/unity-cli.exe + linux-platform-checks: name: Linux Platform Checks runs-on: ubuntu-latest @@ -155,10 +163,10 @@ jobs: key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} restore-keys: ${{ runner.os }}-cargo- - - name: Install Xvfb and X11 screenshot tools + - name: Install Xvfb, X11 screenshot tools, sway and grim run: | sudo apt-get update - sudo apt-get install -y xvfb imagemagick scrot maim + sudo apt-get install -y xvfb imagemagick scrot maim sway grim - name: Build unity-cli run: cargo build --bin unity-cli @@ -168,10 +176,47 @@ jobs: xvfb-run -a -s "-screen 0 1280x720x24" python3 tests/scripts/platform-checks.py --unity-cli target/debug/unity-cli + - name: Install the built binary with install-from-source.sh + run: sh tests/scripts/install-from-source-sh-test.sh target/debug/unity-cli + + - name: Check the grim OS screenshot fallback under headless sway + # A wlroots compositor on the headless backend with the software + # renderer; WAYLAND_DISPLAY switches the check to grim (#465). + env: + WLR_BACKENDS: headless + WLR_LIBINPUT_NO_DEVICES: '1' + WLR_RENDERER: pixman + run: | + XDG_RUNTIME_DIR="$(mktemp -d)" + export XDG_RUNTIME_DIR + chmod 700 "$XDG_RUNTIME_DIR" + sway -c /dev/null > "$RUNNER_TEMP/sway.log" 2>&1 & + socket="" + for _ in $(seq 1 50); do + socket="$(find "$XDG_RUNTIME_DIR" -maxdepth 1 -type s -name 'wayland-*' | head -n 1)" + [ -n "$socket" ] && break + sleep 0.2 + done + if [ -z "$socket" ]; then + cat "$RUNNER_TEMP/sway.log" + echo "sway did not create a Wayland socket" >&2 + exit 1 + fi + WAYLAND_DISPLAY="$(basename "$socket")" + export WAYLAND_DISPLAY + python3 tests/scripts/platform-checks.py --unity-cli target/debug/unity-cli --checks screenshot + lsp-test: name: LSP Tests (required) + needs: lsp-write-reliability + if: always() runs-on: ubuntu-latest steps: + - name: Require passing LSP write measurements on every OS + env: + RELIABILITY_RESULT: ${{ needs.lsp-write-reliability.result }} + run: test "$RELIABILITY_RESULT" = success + - uses: actions/checkout@v7 - name: Setup .NET SDK 10 @@ -185,6 +230,21 @@ jobs: - name: Test hot reload validation and execution observations run: dotnet test tests/hot-reload/HotReload.Tests.csproj + windows-lsp-test: + name: Windows LSP Tests + runs-on: windows-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v7 + + - name: Setup .NET SDK 10 + uses: actions/setup-dotnet@v6 + with: + dotnet-version: '10.0.x' + + - name: Run dotnet test + run: dotnet test lsp/Server.Tests.csproj + rust-coverage: name: Rust Coverage >= 90% (required) runs-on: ubuntu-latest @@ -217,14 +277,16 @@ jobs: --fail-under-lines 90 \ -- --test-threads=1 + # Codecov upload is best-effort: the 90% gate above stays required, an external outage must not block merges (#472). - name: Upload Rust coverage to Codecov + continue-on-error: true uses: codecov/codecov-action@v7 with: token: ${{ secrets.CODECOV_TOKEN }} files: coverage/rust/cobertura.xml flags: rust name: rust-coverage - fail_ci_if_error: true + fail_ci_if_error: false verbose: true lsp-coverage: @@ -247,14 +309,16 @@ jobs: /p:ThresholdType=line \ /p:ThresholdStat=total + # Codecov upload is best-effort: the 90% gate above stays required, an external outage must not block merges (#472). - name: Upload LSP coverage to Codecov + continue-on-error: true uses: codecov/codecov-action@v7 with: token: ${{ secrets.CODECOV_TOKEN }} files: lsp/coverage.cobertura.xml flags: lsp name: lsp-coverage - fail_ci_if_error: true + fail_ci_if_error: false verbose: true lsp-perf: diff --git a/.gwt/work/events/03/03bbaa8914b9928f4ba937590b265c466f58f19e0e1cedbf2ea8d401b8997bb6.jsonl b/.gwt/work/events/03/03bbaa8914b9928f4ba937590b265c466f58f19e0e1cedbf2ea8d401b8997bb6.jsonl new file mode 100644 index 00000000..7c3a344c --- /dev/null +++ b/.gwt/work/events/03/03bbaa8914b9928f4ba937590b265c466f58f19e0e1cedbf2ea8d401b8997bb6.jsonl @@ -0,0 +1 @@ +{"id":"7cb0a09c-e15c-431f-b271-67f29b647da0","work_item_id":"work-work-issue-520-2c5b16f7","kind":"update","title":null,"intent":"2,000生成件一致を確認し、全LSP・coverageの正式検証","summary":null,"progress_summary":"AC-1を含む未配送ソースを保全。AC-2固定RED8件と拡張生成器11不一致を最小修正し、2,000件不一致0。","status_category":null,"owner":"Issue #520","next_action":null,"agent_session_id":"fad8f3f5-654a-4ea4-b0c6-e65546d2f5bb","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-520","worktree_path":"E:\\unity-cli\\work\\issue-520","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T06:29:26.841141500Z"} diff --git a/.gwt/work/events/05/05e8edbe8d25d9bcae6025bbcd40e04d6543ceb284a0bc51a44876a1b770977b.jsonl b/.gwt/work/events/05/05e8edbe8d25d9bcae6025bbcd40e04d6543ceb284a0bc51a44876a1b770977b.jsonl new file mode 100644 index 00000000..53aa0ab6 --- /dev/null +++ b/.gwt/work/events/05/05e8edbe8d25d9bcae6025bbcd40e04d6543ceb284a0bc51a44876a1b770977b.jsonl @@ -0,0 +1 @@ +{"id":"43a20342-fb94-4066-b0ad-312627a7f2ab","work_item_id":"work-work-issue-522-b9f798d4","kind":"resume","title":"chore(release): LSP 既定化と LSP 書き込み信頼性修正を含む v0.19.0 をリリースする","intent":"Check Board for latest updates","summary":"Claude Code is running","progress_summary":null,"status_category":"active","owner":"Issue #522","next_action":"Check Board for latest updates","agent_session_id":"17d778c4-6063-4b7f-85f1-78dab6102c83","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-522","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-522","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-19T01:15:30.750424Z"} diff --git a/.gwt/work/events/06/068f272fd49df6fcd7a525d56e05c85d5c4c0d7e615458d34682bb7bff292a30.jsonl b/.gwt/work/events/06/068f272fd49df6fcd7a525d56e05c85d5c4c0d7e615458d34682bb7bff292a30.jsonl new file mode 100644 index 00000000..5e2e5878 --- /dev/null +++ b/.gwt/work/events/06/068f272fd49df6fcd7a525d56e05c85d5c4c0d7e615458d34682bb7bff292a30.jsonl @@ -0,0 +1 @@ +{"id":"34292acb-30f2-46c4-af57-745f925210b5","work_item_id":"work-work-issue-472-3e7dc4d8","kind":"update","title":"Issue #472 の残り受け入れ基準の実装","intent":"Issue #472 の受け入れ基準を評価中","summary":null,"progress_summary":null,"status_category":null,"owner":"Issue #472","next_action":null,"agent_session_id":"af4d50d1-e3e4-4be1-984c-46d1c52b560c","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-472","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-472","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-05T06:23:59.102393Z"} diff --git a/.gwt/work/events/0e/0ef73dc5867f2bb56feea74f2745a763da628128b9b209f25de5e04def3609d4.jsonl b/.gwt/work/events/0e/0ef73dc5867f2bb56feea74f2745a763da628128b9b209f25de5e04def3609d4.jsonl new file mode 100644 index 00000000..3fe949d8 --- /dev/null +++ b/.gwt/work/events/0e/0ef73dc5867f2bb56feea74f2745a763da628128b9b209f25de5e04def3609d4.jsonl @@ -0,0 +1 @@ +{"id":"d79e484a-3e42-40d5-bb27-228e5a5aa330","work_item_id":"work-work-issue-516-59f2c1be","kind":"pr","title":null,"intent":null,"summary":null,"progress_summary":null,"status_category":"active","owner":null,"next_action":null,"agent_session_id":"2422daaa-fb2e-42af-a9de-476f61a2dc84","agent_id":null,"display_name":null,"board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-516","pr_number":517,"pr_url":"https://github.com/akiojin/unity-cli/pull/517","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-14T00:55:14.793037Z"} diff --git a/.gwt/work/events/18/18d3bf1a6bb8fc275fa3131e26a7fbeb99949367b6d7fe8cfc07fbf9457fa491.jsonl b/.gwt/work/events/18/18d3bf1a6bb8fc275fa3131e26a7fbeb99949367b6d7fe8cfc07fbf9457fa491.jsonl new file mode 100644 index 00000000..8baa9676 --- /dev/null +++ b/.gwt/work/events/18/18d3bf1a6bb8fc275fa3131e26a7fbeb99949367b6d7fe8cfc07fbf9457fa491.jsonl @@ -0,0 +1 @@ +{"id":"a395a6a6-71cd-4296-a592-067f751dc3cc","work_item_id":"work-work-issue-490-ce1c1f9a","kind":"pr","title":null,"intent":null,"summary":null,"progress_summary":null,"status_category":"done","owner":null,"next_action":null,"agent_session_id":"c0ac1284-51ea-49d8-82e3-da19507a6ba5","agent_id":null,"display_name":null,"board_entry_id":null,"execution_container":{"branch":"work/issue-490","worktree_path":"E:\\unity-cli\\work\\issue-490","pr_number":497,"pr_url":"https://github.com/akiojin/unity-cli/pull/497","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-13T08:46:22.603682700Z"} diff --git a/.gwt/work/events/1a/1adf5461732dc1447867bfa2d72a9da813868c6e5e7fc9291fbbc760e9dd24bd.jsonl b/.gwt/work/events/1a/1adf5461732dc1447867bfa2d72a9da813868c6e5e7fc9291fbbc760e9dd24bd.jsonl new file mode 100644 index 00000000..3d3af2f0 --- /dev/null +++ b/.gwt/work/events/1a/1adf5461732dc1447867bfa2d72a9da813868c6e5e7fc9291fbbc760e9dd24bd.jsonl @@ -0,0 +1 @@ +{"id":"bac7b601-c210-4aa7-833c-4381836db4d3","work_item_id":"work-work-issue-498-892fdd8e","kind":"start","title":"fix(lsp): keep the original BOM and newlines when C# LSP write tools save a file","intent":"Check Board for latest updates","summary":"Claude Code is running","progress_summary":null,"status_category":"active","owner":"Issue #498","next_action":"Check Board for latest updates","agent_session_id":"59a2fa97-8e6a-4559-996b-52a6865f473b","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-498","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-498","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T09:40:12.350761Z"} diff --git a/.gwt/work/events/1c/1c40465646d8f462527102859bfc4f8a90bb135ccb359e85f7e6397f7fc58eb8.jsonl b/.gwt/work/events/1c/1c40465646d8f462527102859bfc4f8a90bb135ccb359e85f7e6397f7fc58eb8.jsonl new file mode 100644 index 00000000..768bb288 --- /dev/null +++ b/.gwt/work/events/1c/1c40465646d8f462527102859bfc4f8a90bb135ccb359e85f7e6397f7fc58eb8.jsonl @@ -0,0 +1 @@ +{"id":"c412255e-4eff-4fa9-9b63-27824161bde8","work_item_id":"work-work-issue-520-2c5b16f7","kind":"resume","title":"fix(lsp): keep closed-string CRs in sibling branches hidden by an unterminated literal (#516 follow-up)","intent":"3 active agents","summary":"3 active agents","progress_summary":null,"status_category":"active","owner":"Issue #520","next_action":"Check Board for latest updates","agent_session_id":"fad8f3f5-654a-4ea4-b0c6-e65546d2f5bb","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-520","worktree_path":"E:/unity-cli/work/issue-520","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T06:13:18.980268300Z"} diff --git a/.gwt/work/events/1d/1dcc0e96f278faa950cf84eba19aa3697b6fe974cc3d063e567d035940bd197f.jsonl b/.gwt/work/events/1d/1dcc0e96f278faa950cf84eba19aa3697b6fe974cc3d063e567d035940bd197f.jsonl new file mode 100644 index 00000000..1d89fb75 --- /dev/null +++ b/.gwt/work/events/1d/1dcc0e96f278faa950cf84eba19aa3697b6fe974cc3d063e567d035940bd197f.jsonl @@ -0,0 +1 @@ +{"id":"cddd4c76-3dfc-419e-a102-e14015afbeeb","work_item_id":"work-work-issue-498-892fdd8e","kind":"update","title":null,"intent":"PR #507 の auto-merge と verify.run 完了待ち","summary":"run 38397430741 の再実行で Rust Format & Lint が success。PR #507 は auto-merge 待ち、verify.run は lease 待ち","progress_summary":null,"status_category":null,"owner":"Issue #498","next_action":null,"agent_session_id":"59a2fa97-8e6a-4559-996b-52a6865f473b","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-498","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-498","pr_number":507,"pr_url":"https://github.com/akiojin/unity-cli/pull/507","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-13T12:30:55.796785Z"} diff --git a/.gwt/work/events/28/28fa8c792aee41fe0b4e79084fb54eb3fff8b95db8dd0467dc69e71c7264cbc6.jsonl b/.gwt/work/events/28/28fa8c792aee41fe0b4e79084fb54eb3fff8b95db8dd0467dc69e71c7264cbc6.jsonl new file mode 100644 index 00000000..05dfed4b --- /dev/null +++ b/.gwt/work/events/28/28fa8c792aee41fe0b4e79084fb54eb3fff8b95db8dd0467dc69e71c7264cbc6.jsonl @@ -0,0 +1 @@ +{"id":"533267ed-456b-4e4e-ae96-8e10df85df0d","work_item_id":"work-work-issue-516-59f2c1be","kind":"start","title":"fix(lsp): normalize lone CR in edits to the file's newline style for LF and CRLF files","intent":"Check Board for latest updates","summary":"Codex is running","progress_summary":null,"status_category":"active","owner":"Issue #516","next_action":"Check Board for latest updates","agent_session_id":"9df139e6-24fb-452f-98d6-3388b16297b3","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"E:\\unity-cli\\work\\issue-516","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T00:57:21.834855200Z"} diff --git a/.gwt/work/events/2e/2ee3c747145cdff3740985cdc077426ef0946a2da923b2d96fff2a533ba123f1.jsonl b/.gwt/work/events/2e/2ee3c747145cdff3740985cdc077426ef0946a2da923b2d96fff2a533ba123f1.jsonl new file mode 100644 index 00000000..58679f2a --- /dev/null +++ b/.gwt/work/events/2e/2ee3c747145cdff3740985cdc077426ef0946a2da923b2d96fff2a533ba123f1.jsonl @@ -0,0 +1 @@ +{"id":"89ce584b-b926-498f-a6fb-6bf905037f49","work_item_id":"work-work-issue-504-10f6aa4a","kind":"start","title":"fix(lsp): cut the 43-second wait before the first C# write on Windows when lspd is not running","intent":"Check Board for latest updates","summary":"Codex is running","progress_summary":null,"status_category":"active","owner":"Issue #504","next_action":"Check Board for latest updates","agent_session_id":"04108877-9f1d-4de6-859d-a4bbad4605b7","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-504","worktree_path":"E:\\unity-cli\\work\\issue-504","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T11:34:29.435000400Z"} diff --git a/.gwt/work/events/2f/2fb1ab5f402ffab8b0f4a5c7bb32841b3d7856a820d69ac429ec5bf75a28e795.jsonl b/.gwt/work/events/2f/2fb1ab5f402ffab8b0f4a5c7bb32841b3d7856a820d69ac429ec5bf75a28e795.jsonl new file mode 100644 index 00000000..6c611089 --- /dev/null +++ b/.gwt/work/events/2f/2fb1ab5f402ffab8b0f4a5c7bb32841b3d7856a820d69ac429ec5bf75a28e795.jsonl @@ -0,0 +1 @@ +{"id":"c1ba1255-13f1-49a2-8bd8-44a812e57911","work_item_id":"work-work-issue-520-2c5b16f7","kind":"done","title":null,"intent":"実装と正式検証済み。PR #521への配送と新SHA独立レビュー・CI確認","summary":null,"progress_summary":"AC-2のoracle条件置換とliteral単位の終端判定、回復trivia再帰走査を修正。2,000生成件不一致0、839 LSP/15 Python、coverage99.62%、400分岐約34ms。次はcommit/push→fresh verify→PM独立レビュー→Ready/CI auto-merge。Issueはdevelop配送まで完了扱いにしない。","status_category":"done","owner":"Issue #520","next_action":null,"agent_session_id":"fad8f3f5-654a-4ea4-b0c6-e65546d2f5bb","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-520","worktree_path":"E:\\unity-cli\\work\\issue-520","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T06:43:07.812719400Z"} diff --git a/.gwt/work/events/30/30d165d1ee5b55af68841d8bf4737cb00806f6c33292c757fa1d37f5b92aaf91.jsonl b/.gwt/work/events/30/30d165d1ee5b55af68841d8bf4737cb00806f6c33292c757fa1d37f5b92aaf91.jsonl new file mode 100644 index 00000000..985d6d7f --- /dev/null +++ b/.gwt/work/events/30/30d165d1ee5b55af68841d8bf4737cb00806f6c33292c757fa1d37f5b92aaf91.jsonl @@ -0,0 +1 @@ +{"id":"d51c72ea-58d6-4eaf-a2b0-44cfb22b3158","work_item_id":"work-work-issue-498-892fdd8e","kind":"pr","title":null,"intent":null,"summary":null,"progress_summary":null,"status_category":"active","owner":null,"next_action":null,"agent_session_id":"28641b50-7397-40b7-98fc-192f96e72d4a","agent_id":null,"display_name":null,"board_entry_id":null,"execution_container":{"branch":"work/issue-498","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-498","pr_number":513,"pr_url":"https://github.com/akiojin/unity-cli/pull/513","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-13T14:04:50.925733Z"} diff --git a/.gwt/work/events/33/3318750b0538f8e5e450d19c82aeaae85c0be992f09a28b3bd54af7a265861c3.jsonl b/.gwt/work/events/33/3318750b0538f8e5e450d19c82aeaae85c0be992f09a28b3bd54af7a265861c3.jsonl new file mode 100644 index 00000000..c16f70d8 --- /dev/null +++ b/.gwt/work/events/33/3318750b0538f8e5e450d19c82aeaae85c0be992f09a28b3bd54af7a265861c3.jsonl @@ -0,0 +1 @@ +{"id":"fdba7846-8c4e-4d11-a671-fd122fcd0380","work_item_id":"work-work-issue-516-59f2c1be","kind":"update","title":null,"intent":"指示名の前の Unicode 空白も含めた AC-1 の最終検証","summary":null,"progress_summary":"Ready PR #518 を develop と同期済み。レビュー中にプリプロセッサ指示内の追加空白2ケースをREDで再現し、文字列CR保持を補強。","status_category":null,"owner":"Issue #516","next_action":null,"agent_session_id":"7dec144f-cdc1-4a98-b90f-fe2f1f41e128","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"E:\\unity-cli\\work\\issue-516","pr_number":518,"pr_url":"https://github.com/akiojin/unity-cli/pull/518","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-14T01:29:24.426439700Z"} diff --git a/.gwt/work/events/34/348bd9ca0e21d1290afe10c97ba1f37b999f1bb2c6803b81f9ddd0d7d7ad5e42.jsonl b/.gwt/work/events/34/348bd9ca0e21d1290afe10c97ba1f37b999f1bb2c6803b81f9ddd0d7d7ad5e42.jsonl new file mode 100644 index 00000000..d9458a8c --- /dev/null +++ b/.gwt/work/events/34/348bd9ca0e21d1290afe10c97ba1f37b999f1bb2c6803b81f9ddd0d7d7ad5e42.jsonl @@ -0,0 +1 @@ +{"id":"a8614755-69e2-4858-a465-340c7c87cc03","work_item_id":"work-work-issue-516-59f2c1be","kind":"update","title":null,"intent":"統合した分岐解析修正の正式検証と再レビュー","summary":null,"progress_summary":"02dbdea/d435a0bの修正と回帰テストを取り込み、入れ子の字句干渉・長い条件式・誤った文字列保護を補完。LSP全433件が成功。","status_category":null,"owner":"Issue #516","next_action":null,"agent_session_id":"7dec144f-cdc1-4a98-b90f-fe2f1f41e128","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"E:\\unity-cli\\work\\issue-516","pr_number":518,"pr_url":"https://github.com/akiojin/unity-cli/pull/518","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-14T03:01:36.577158600Z"} diff --git a/.gwt/work/events/37/3723641c1ce4c73b4f89b1ee25efc8f5cb6a847000ce98d4708bdaea7aba04f5.jsonl b/.gwt/work/events/37/3723641c1ce4c73b4f89b1ee25efc8f5cb6a847000ce98d4708bdaea7aba04f5.jsonl new file mode 100644 index 00000000..7ac31081 --- /dev/null +++ b/.gwt/work/events/37/3723641c1ce4c73b4f89b1ee25efc8f5cb6a847000ce98d4708bdaea7aba04f5.jsonl @@ -0,0 +1 @@ +{"id":"af94df37-d68b-45cd-a50e-847052424e98","work_item_id":"work-work-issue-520-2c5b16f7","kind":"update","title":"Issue #520 閉じたソースの整合性修正","intent":"要件・未配送差分と実行契約の確認","summary":null,"progress_summary":null,"status_category":null,"owner":"Issue #520","next_action":null,"agent_session_id":"fad8f3f5-654a-4ea4-b0c6-e65546d2f5bb","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-520","worktree_path":"E:\\unity-cli\\work\\issue-520","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T06:15:34.019590200Z"} diff --git a/.gwt/work/events/37/376d6e3699f9e37edb97bbfa5526ded79e5b1eb03f253c4312352f1a17399f75.jsonl b/.gwt/work/events/37/376d6e3699f9e37edb97bbfa5526ded79e5b1eb03f253c4312352f1a17399f75.jsonl new file mode 100644 index 00000000..60514f9f --- /dev/null +++ b/.gwt/work/events/37/376d6e3699f9e37edb97bbfa5526ded79e5b1eb03f253c4312352f1a17399f75.jsonl @@ -0,0 +1 @@ +{"id":"c2e0a584-da07-4988-b8cc-b57849f4899a","work_item_id":"work-work-issue-386-8f91ee0d","kind":"resume","title":"test(windows): #362 / #363 / #369 の Windows・Linux 実機検証","intent":"Check Board for latest updates","summary":"Codex is running","progress_summary":null,"status_category":"active","owner":"Issue #386","next_action":"Check Board for latest updates","agent_session_id":"58337a13-2327-417b-b9f2-9b4b847857c4","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-386","worktree_path":"E:/unity-cli/work/issue-386","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-03T04:08:49.375693400Z"} diff --git a/.gwt/work/events/38/3834654f5f68ca691272799a90a4ea9bd17ebae147163b8a35388a9f9b57d637.jsonl b/.gwt/work/events/38/3834654f5f68ca691272799a90a4ea9bd17ebae147163b8a35388a9f9b57d637.jsonl new file mode 100644 index 00000000..1072af18 --- /dev/null +++ b/.gwt/work/events/38/3834654f5f68ca691272799a90a4ea9bd17ebae147163b8a35388a9f9b57d637.jsonl @@ -0,0 +1 @@ +{"id":"04fd7df6-803a-403b-8ffa-91b4ee165336","work_item_id":"work-work-issue-522-b9f798d4","kind":"update","title":null,"intent":"性能ゲート待機(load1 < 8.5 待ち)","summary":null,"progress_summary":"origin/develop (2a79fbfd) へ ff し、前セッションのリリース差分(5 ファイル, v0.19.0)を再適用。release CLI 0.19.0 をビルド済み。","status_category":null,"owner":"Issue #522","next_action":null,"agent_session_id":"17d778c4-6063-4b7f-85f1-78dab6102c83","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-522","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-522","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-19T01:19:03.159869Z"} diff --git a/.gwt/work/events/41/418c51b4b4dfad2e325a1aeecea90939fca7b98d7e7c99645bb79f1f86f17fd8.jsonl b/.gwt/work/events/41/418c51b4b4dfad2e325a1aeecea90939fca7b98d7e7c99645bb79f1f86f17fd8.jsonl new file mode 100644 index 00000000..4da4bde1 --- /dev/null +++ b/.gwt/work/events/41/418c51b4b4dfad2e325a1aeecea90939fca7b98d7e7c99645bb79f1f86f17fd8.jsonl @@ -0,0 +1 @@ +{"id":"147231ec-66e7-44f9-8a92-142db3422f35","work_item_id":"work-work-issue-490-ce1c1f9a","kind":"done","title":null,"intent":"測定実装を確定し、fresh verification と3 OS CIへ","summary":null,"progress_summary":"19シナリオ/全10ツール/4起動条件の実CLI測定、厳密baseline、既存必須チェックにつながる3OS CI、MarkdownとWindows57試行の証跡を実装。回帰11件とWindows38試行のrunner検証PASS。Rust品質とLinux .NET53件PASS。BOM追加/末尾コメント消失/ScriptableObject using欠落等はPMへ個別登録依頼中。owner ACはCI実測と登録確認後に同期する。","status_category":"done","owner":"Issue #490","next_action":null,"agent_session_id":"c0ac1284-51ea-49d8-82e3-da19507a6ba5","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-490","worktree_path":"E:\\unity-cli\\work\\issue-490","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T08:33:35.161036400Z"} diff --git a/.gwt/work/events/47/475c64b51b35785f3b585ceb5284f62720976c36da133b2d981dc39c025d09f4.jsonl b/.gwt/work/events/47/475c64b51b35785f3b585ceb5284f62720976c36da133b2d981dc39c025d09f4.jsonl new file mode 100644 index 00000000..68611b74 --- /dev/null +++ b/.gwt/work/events/47/475c64b51b35785f3b585ceb5284f62720976c36da133b2d981dc39c025d09f4.jsonl @@ -0,0 +1 @@ +{"id":"a6337369-8166-4e96-80c5-f65b2cd287ef","work_item_id":"work-work-issue-522-b9f798d4","kind":"start","title":"chore(release): LSP 既定化と LSP 書き込み信頼性修正を含む v0.19.0 をリリースする","intent":"Check Board for latest updates","summary":"Claude Code is running","progress_summary":null,"status_category":"active","owner":"Issue #522","next_action":"Check Board for latest updates","agent_session_id":"c270a89f-b89c-48d0-a8ba-b3d897512283","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-522","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-522","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T10:02:26.974713Z"} diff --git a/.gwt/work/events/4c/4ce33f50346a3954a42153f2d493b2cea761ec44d14099efd65ba15f50e4ead0.jsonl b/.gwt/work/events/4c/4ce33f50346a3954a42153f2d493b2cea761ec44d14099efd65ba15f50e4ead0.jsonl new file mode 100644 index 00000000..e50ee245 --- /dev/null +++ b/.gwt/work/events/4c/4ce33f50346a3954a42153f2d493b2cea761ec44d14099efd65ba15f50e4ead0.jsonl @@ -0,0 +1 @@ +{"id":"372bc20d-c4b2-43ac-9d14-eab74dfd1226","work_item_id":"work-work-issue-511-ac1c61e3","kind":"update","title":"Issue #511 の受入条件を満たす","intent":"既存実装と受入条件の監査","summary":null,"progress_summary":null,"status_category":null,"owner":"Issue #511","next_action":null,"agent_session_id":"d0aa10d9-7f81-4304-905c-47fc4ce7b80c","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-511","worktree_path":"E:\\unity-cli\\work\\issue-511","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T13:01:10.833188100Z"} diff --git a/.gwt/work/events/50/504ccd1c84fac1827f014249f48b5ab7f52e3cbb94d4d3c7d50eeb51f5336fac.jsonl b/.gwt/work/events/50/504ccd1c84fac1827f014249f48b5ab7f52e3cbb94d4d3c7d50eeb51f5336fac.jsonl new file mode 100644 index 00000000..07b60273 --- /dev/null +++ b/.gwt/work/events/50/504ccd1c84fac1827f014249f48b5ab7f52e3cbb94d4d3c7d50eeb51f5336fac.jsonl @@ -0,0 +1 @@ +{"id":"bb0fae43-086d-40f5-87a6-78bf84c24e82","work_item_id":"work-work-issue-516-59f2c1be","kind":"update","title":null,"intent":"PR #518 の分岐間字句干渉を修正・検証","summary":null,"progress_summary":"初回追加修正のCIは全成功。CodeRabbit指摘を再現し、条件分岐ごとの独立解析へ修正中。","status_category":null,"owner":"Issue #516","next_action":null,"agent_session_id":"7dec144f-cdc1-4a98-b90f-fe2f1f41e128","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"E:\\unity-cli\\work\\issue-516","pr_number":518,"pr_url":"https://github.com/akiojin/unity-cli/pull/518","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-14T02:19:56.855868400Z"} diff --git a/.gwt/work/events/5a/5a65e9f1c65d8ab67ed443ed887af899da13af957950a01b8fa70a7ec102f24a.jsonl b/.gwt/work/events/5a/5a65e9f1c65d8ab67ed443ed887af899da13af957950a01b8fa70a7ec102f24a.jsonl new file mode 100644 index 00000000..12f2cbac --- /dev/null +++ b/.gwt/work/events/5a/5a65e9f1c65d8ab67ed443ed887af899da13af957950a01b8fa70a7ec102f24a.jsonl @@ -0,0 +1 @@ +{"id":"42e4468c-2e15-49eb-8708-373b0bd7ac3e","work_item_id":"work-work-issue-511-ac1c61e3","kind":"pr","title":null,"intent":null,"summary":null,"progress_summary":null,"status_category":"done","owner":null,"next_action":null,"agent_session_id":"d0aa10d9-7f81-4304-905c-47fc4ce7b80c","agent_id":null,"display_name":null,"board_entry_id":null,"execution_container":{"branch":"work/issue-511","worktree_path":"E:\\unity-cli\\work\\issue-511","pr_number":512,"pr_url":"https://github.com/akiojin/unity-cli/pull/512","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-13T13:41:06.595205700Z"} diff --git a/.gwt/work/events/5f/5fd9170317f93c84d7bd08a61bdadf697afd2d420395a03aa4a6779f7342ec3d.jsonl b/.gwt/work/events/5f/5fd9170317f93c84d7bd08a61bdadf697afd2d420395a03aa4a6779f7342ec3d.jsonl new file mode 100644 index 00000000..2f5e2645 --- /dev/null +++ b/.gwt/work/events/5f/5fd9170317f93c84d7bd08a61bdadf697afd2d420395a03aa4a6779f7342ec3d.jsonl @@ -0,0 +1 @@ +{"id":"68858545-e0ec-4227-a28f-668ba32c3397","work_item_id":"work-work-issue-490-ce1c1f9a","kind":"start","title":"test(lsp): measure the reliability of the C# LSP write tools before enforcing them","intent":"Check Board for latest updates","summary":"Codex is running","progress_summary":null,"status_category":"active","owner":"Issue #490","next_action":"Check Board for latest updates","agent_session_id":"c0ac1284-51ea-49d8-82e3-da19507a6ba5","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-490","worktree_path":"E:\\unity-cli\\work\\issue-490","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T07:35:00.887269Z"} diff --git a/.gwt/work/events/64/641d5dcf5c6d583437f35493d957682eac6ee5dfaacd3722b570c1be67f715f4.jsonl b/.gwt/work/events/64/641d5dcf5c6d583437f35493d957682eac6ee5dfaacd3722b570c1be67f715f4.jsonl new file mode 100644 index 00000000..a3a951e7 --- /dev/null +++ b/.gwt/work/events/64/641d5dcf5c6d583437f35493d957682eac6ee5dfaacd3722b570c1be67f715f4.jsonl @@ -0,0 +1 @@ +{"id":"5e925ba0-9763-4339-a233-559a058a813e","work_item_id":"work-work-issue-516-59f2c1be","kind":"done","title":null,"intent":"653d81aを正本として入れ子分岐・文字列範囲を最小修正、441件PASS。PR #518の正式検証とCI配送へ","summary":"Issue #516の残存ACをorigin/developに対して監査し、未配送ソースと回帰テストを通常mergeで統合","progress_summary":null,"status_category":"done","owner":"Issue #516","next_action":"verify.run → push → fresh verify → PR Ready更新 → 3 OS CIとレビュー → developマージ確認","agent_session_id":"7dec144f-cdc1-4a98-b90f-fe2f1f41e128","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"E:\\unity-cli\\work\\issue-516","pr_number":518,"pr_url":"https://github.com/akiojin/unity-cli/pull/518","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-14T03:24:22.391578600Z"} diff --git a/.gwt/work/events/64/6483d1feaeffee6ef5d6bc013b5c20e3abb9181188424a8c3f1d85f60bcaa091.jsonl b/.gwt/work/events/64/6483d1feaeffee6ef5d6bc013b5c20e3abb9181188424a8c3f1d85f60bcaa091.jsonl new file mode 100644 index 00000000..4872aaec --- /dev/null +++ b/.gwt/work/events/64/6483d1feaeffee6ef5d6bc013b5c20e3abb9181188424a8c3f1d85f60bcaa091.jsonl @@ -0,0 +1 @@ +{"id":"163b0f15-be73-4ad7-b729-cd5770422463","work_item_id":"work-work-issue-386-8f91ee0d","kind":"update","title":"Issue #386 の修正","intent":"Issue と実行状態の確認","summary":null,"progress_summary":null,"status_category":null,"owner":"Issue #386","next_action":null,"agent_session_id":"58337a13-2327-417b-b9f2-9b4b847857c4","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-386","worktree_path":"E:/unity-cli/work/issue-386","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-03T04:26:24.498553Z"} diff --git a/.gwt/work/events/6c/6c33430f6e49c43af88d6fc2513a32f63d5accca68a326f7320cf23df81bd2ef.jsonl b/.gwt/work/events/6c/6c33430f6e49c43af88d6fc2513a32f63d5accca68a326f7320cf23df81bd2ef.jsonl new file mode 100644 index 00000000..da90be1d --- /dev/null +++ b/.gwt/work/events/6c/6c33430f6e49c43af88d6fc2513a32f63d5accca68a326f7320cf23df81bd2ef.jsonl @@ -0,0 +1 @@ +{"id":"0131453b-482f-45f2-bbdf-d9d4d16a9319","work_item_id":"work-work-issue-465-f794e601","kind":"start","title":"ci(windows,linux): 公開版の導入・Wayland スクリーンショット・skills 導入を CI で確認する(#386 から切り出し 第2弾)","intent":"Check Board for latest updates","summary":"Claude Code is running","progress_summary":null,"status_category":"active","owner":"Issue #465","next_action":"Check Board for latest updates","agent_session_id":"1730113d-3d73-4722-b1ca-61b9d6af50c5","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-465","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-465","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-03T13:29:32.497019Z"} diff --git a/.gwt/work/events/6f/6f5ed846e86ffd579cd4f0b7ab48d5ff55c1bcf33ef1a62641fff9214bf69dae.jsonl b/.gwt/work/events/6f/6f5ed846e86ffd579cd4f0b7ab48d5ff55c1bcf33ef1a62641fff9214bf69dae.jsonl new file mode 100644 index 00000000..21c67b99 --- /dev/null +++ b/.gwt/work/events/6f/6f5ed846e86ffd579cd4f0b7ab48d5ff55c1bcf33ef1a62641fff9214bf69dae.jsonl @@ -0,0 +1 @@ +{"id":"c5600ee3-4c19-45a8-b97d-c48a355bbf2e","work_item_id":"work-work-issue-516-59f2c1be","kind":"start","title":"Issue #516","intent":"Check Board for latest updates","summary":"Claude Code is running","progress_summary":null,"status_category":"active","owner":"Issue #516","next_action":"Check Board for latest updates","agent_session_id":"2422daaa-fb2e-42af-a9de-476f61a2dc84","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-516","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T00:38:53.802182Z"} diff --git a/.gwt/work/events/73/73b467d1e0a3cc013a72b0652e38fed6e26722b1ce0ec23d228c83b5c83b3a3e.jsonl b/.gwt/work/events/73/73b467d1e0a3cc013a72b0652e38fed6e26722b1ce0ec23d228c83b5c83b3a3e.jsonl new file mode 100644 index 00000000..1c17cb37 --- /dev/null +++ b/.gwt/work/events/73/73b467d1e0a3cc013a72b0652e38fed6e26722b1ce0ec23d228c83b5c83b3a3e.jsonl @@ -0,0 +1 @@ +{"id":"555af658-147e-45ed-a0fd-81dbc39e0299","work_item_id":"work-work-issue-520-2c5b16f7","kind":"resume","title":"fix(lsp): keep closed-string CRs in sibling branches hidden by an unterminated literal (#516 follow-up)","intent":"3 active agents","summary":"3 active agents","progress_summary":null,"status_category":"active","owner":"Issue #520","next_action":"Check Board for latest updates","agent_session_id":"f97055a1-cd47-43bf-9694-0bf7ec2bc1a4","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-520","worktree_path":"E:/unity-cli/work/issue-520","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T05:56:32.056995800Z"} diff --git a/.gwt/work/events/79/792461313595178b02462ac3e615640b8b798b38b5ce45f19a43e6a3ff1631f1.jsonl b/.gwt/work/events/79/792461313595178b02462ac3e615640b8b798b38b5ce45f19a43e6a3ff1631f1.jsonl new file mode 100644 index 00000000..7118f4a2 --- /dev/null +++ b/.gwt/work/events/79/792461313595178b02462ac3e615640b8b798b38b5ce45f19a43e6a3ff1631f1.jsonl @@ -0,0 +1 @@ +{"id":"e8b05b9a-1a0f-463f-9ed7-1cfc93469731","work_item_id":"work-successor-7c2dfc5d2b5cce43936b35438f6127d998d532280cf12c1dd034899b09313645","kind":"start","title":"fix(lsp): normalize lone CR in edits to the file's newline style for LF and CRLF files","intent":"Check Board for latest updates","summary":"Claude Code is running","progress_summary":null,"status_category":"active","owner":"Issue #516","next_action":"Check Board for latest updates","agent_session_id":"efd1f1c5-7a52-4d29-9970-e43f2e9a9519","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-516","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":"work-work-issue-516-59f2c1be","updated_at":"2026-10-14T01:44:06.698532Z"} diff --git a/.gwt/work/events/7b/7b6b4995bb17c553187016b9b3c83cf50965552eabe0e82ef77cf38ee5d807db.jsonl b/.gwt/work/events/7b/7b6b4995bb17c553187016b9b3c83cf50965552eabe0e82ef77cf38ee5d807db.jsonl new file mode 100644 index 00000000..3dd34dbf --- /dev/null +++ b/.gwt/work/events/7b/7b6b4995bb17c553187016b9b3c83cf50965552eabe0e82ef77cf38ee5d807db.jsonl @@ -0,0 +1 @@ +{"id":"f4286761-bffe-484b-ae2d-4f86d9e2317f","work_item_id":"work-work-issue-520-2c5b16f7","kind":"start","title":"fix(lsp): keep closed-string CRs in sibling branches hidden by an unterminated literal (#516 follow-up)","intent":"Check Board for latest updates","summary":"Codex is running","progress_summary":null,"status_category":"active","owner":"Issue #520","next_action":"Check Board for latest updates","agent_session_id":"6acf4230-981e-436f-be5c-c4f470ebbee7","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-520","worktree_path":"E:\\unity-cli\\work\\issue-520","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T05:17:01.340837900Z"} diff --git a/.gwt/work/events/7c/7c14f5a78ceeacb1ab14f22b5b21777b62d1dedac999bb68c0f74b168176e0d8.jsonl b/.gwt/work/events/7c/7c14f5a78ceeacb1ab14f22b5b21777b62d1dedac999bb68c0f74b168176e0d8.jsonl new file mode 100644 index 00000000..7ca015b8 --- /dev/null +++ b/.gwt/work/events/7c/7c14f5a78ceeacb1ab14f22b5b21777b62d1dedac999bb68c0f74b168176e0d8.jsonl @@ -0,0 +1 @@ +{"id":"5f6f6b8d-2451-463c-b149-a49898690982","work_item_id":"work-work-issue-498-892fdd8e","kind":"update","title":null,"intent":"#497 ハーネスで BOM なし baseline のローカル検証中","summary":null,"progress_summary":"LspSourceFile ヘルパで既存ファイルの BOM/エンコーディング/改行規約を保持、新規は BOM なし UTF-8。LSP テスト 92 件 PASS。docs/tools.md に規約追記。","status_category":null,"owner":"Issue #498","next_action":null,"agent_session_id":"59a2fa97-8e6a-4559-996b-52a6865f473b","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-498","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-498","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T10:03:15.040663Z"} diff --git a/.gwt/work/events/7c/7c838c2d01c392fb6ab24eed7a8bead0ff63e7d879103f14a870fafe4afe199f.jsonl b/.gwt/work/events/7c/7c838c2d01c392fb6ab24eed7a8bead0ff63e7d879103f14a870fafe4afe199f.jsonl new file mode 100644 index 00000000..a1f86530 --- /dev/null +++ b/.gwt/work/events/7c/7c838c2d01c392fb6ab24eed7a8bead0ff63e7d879103f14a870fafe4afe199f.jsonl @@ -0,0 +1 @@ +{"id":"a99fa910-87a9-44e9-a447-239027e7729a","work_item_id":"work-work-issue-516-59f2c1be","kind":"pr","title":null,"intent":null,"summary":null,"progress_summary":null,"status_category":"done","owner":null,"next_action":null,"agent_session_id":"7dec144f-cdc1-4a98-b90f-fe2f1f41e128","agent_id":null,"display_name":null,"board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"E:\\unity-cli\\work\\issue-516","pr_number":519,"pr_url":"https://github.com/akiojin/unity-cli/pull/519","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-14T03:28:14.901672800Z"} diff --git a/.gwt/work/events/7f/7fe1378430b7f6985d9297f51aa92c388a79025f34063639c0607dffafd19fc6.jsonl b/.gwt/work/events/7f/7fe1378430b7f6985d9297f51aa92c388a79025f34063639c0607dffafd19fc6.jsonl new file mode 100644 index 00000000..34c4f2cc --- /dev/null +++ b/.gwt/work/events/7f/7fe1378430b7f6985d9297f51aa92c388a79025f34063639c0607dffafd19fc6.jsonl @@ -0,0 +1 @@ +{"id":"72c033d0-b9f8-4366-87a7-ee049fb0c941","work_item_id":"work-work-issue-498-892fdd8e","kind":"update","title":null,"intent":"PR #507 の auto-merge 待機","summary":"PR #507 は CI green、PM が Ready 化済み。auto-merge 待ち","progress_summary":null,"status_category":null,"owner":"Issue #498","next_action":null,"agent_session_id":"59a2fa97-8e6a-4559-996b-52a6865f473b","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-498","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-498","pr_number":507,"pr_url":"https://github.com/akiojin/unity-cli/pull/507","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-13T12:26:08.290578Z"} diff --git a/.gwt/work/events/80/8021ea88ebe8fc33004155e7772aba79316189b993fd3b8822cfbfe3b7af7f81.jsonl b/.gwt/work/events/80/8021ea88ebe8fc33004155e7772aba79316189b993fd3b8822cfbfe3b7af7f81.jsonl new file mode 100644 index 00000000..f3a77ba3 --- /dev/null +++ b/.gwt/work/events/80/8021ea88ebe8fc33004155e7772aba79316189b993fd3b8822cfbfe3b7af7f81.jsonl @@ -0,0 +1 @@ +{"id":"aff272b6-abeb-4b22-97d5-ac6857d5bdb1","work_item_id":"work-work-issue-516-59f2c1be","kind":"resume","title":"fix(lsp): normalize lone CR in edits to the file's newline style for LF and CRLF files","intent":"Codex started work on Issue #516 fix(lsp): normalize lone CR in edits to the file's newline style for LF and CRLF files (work/issue-516)","summary":"3 active agents","progress_summary":null,"status_category":"active","owner":"Issue #516","next_action":"Check Board for latest updates","agent_session_id":"7dec144f-cdc1-4a98-b90f-fe2f1f41e128","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"E:/unity-cli/work/issue-516","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T01:13:28.924834700Z"} diff --git a/.gwt/work/events/82/82e8442c61f6767bd775b77e39984e58182bfbec209257e7181b4bc5888c3230.jsonl b/.gwt/work/events/82/82e8442c61f6767bd775b77e39984e58182bfbec209257e7181b4bc5888c3230.jsonl new file mode 100644 index 00000000..02665fa0 --- /dev/null +++ b/.gwt/work/events/82/82e8442c61f6767bd775b77e39984e58182bfbec209257e7181b4bc5888c3230.jsonl @@ -0,0 +1 @@ +{"id":"3fa5c1b6-d3ba-47e5-b2f8-6b2dd8ccfc9a","work_item_id":"work-work-issue-498-892fdd8e","kind":"update","title":null,"intent":"PR #507 CI 確認","summary":"PR #507 の CI(LSP Write Reliability 3 OS)待ち","progress_summary":"LspSourceFile ヘルパで既存ファイルの BOM/エンコーディング/改行規約を保持し、新規ファイルは BOM なし UTF-8(AC-1/AC-2)。LSP テスト 92 件 PASS。develop(#497 含む)に追従し、baseline の checkout failures から bom_added を全削除(published 0.18.1 の例外は残す)。ローカルハーネス warm_indexed 19/19 PASS。PR #507 を Draft で作成・更新し push 済み。","status_category":null,"owner":"Issue #498","next_action":null,"agent_session_id":"59a2fa97-8e6a-4559-996b-52a6865f473b","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-498","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-498","pr_number":507,"pr_url":"https://github.com/akiojin/unity-cli/pull/507","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-13T12:07:50.340283Z"} diff --git a/.gwt/work/events/85/85330751a3a1c3e31e07a5d7cf63fc3405b0c956e64ae2f81009a29370d69499.jsonl b/.gwt/work/events/85/85330751a3a1c3e31e07a5d7cf63fc3405b0c956e64ae2f81009a29370d69499.jsonl new file mode 100644 index 00000000..58110bc7 --- /dev/null +++ b/.gwt/work/events/85/85330751a3a1c3e31e07a5d7cf63fc3405b0c956e64ae2f81009a29370d69499.jsonl @@ -0,0 +1 @@ +{"id":"2b0fa7d0-3c4d-429a-b8a6-678fe8ee9aa7","work_item_id":"work-work-issue-522-b9f798d4","kind":"update","title":null,"intent":"性能ゲート 3 回目(静かな時間帯を待って自動開始)","summary":null,"progress_summary":"origin/develop 1e369872 (#526 含む) へ ff、v0.19.0 版数 + CHANGELOG(#524/#526 追記, 日付 2026-10-19)。性能ゲート 2 回は frontmost のみ FAIL(計測中 load1 13〜17)、background は 23/23 PASS。v0.18.1 との A/B で回帰なし。Release PR 本文草稿 .cache/issue-522/release-pr-body.md 作成済み。","status_category":null,"owner":"Issue #522","next_action":null,"agent_session_id":"17d778c4-6063-4b7f-85f1-78dab6102c83","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-522","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-522","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-19T02:51:42.564005Z"} diff --git a/.gwt/work/events/87/87518854cd606f8fb7879ae5aa7a927cd3270f94952a1394e40c74c0d1c29dd9.jsonl b/.gwt/work/events/87/87518854cd606f8fb7879ae5aa7a927cd3270f94952a1394e40c74c0d1c29dd9.jsonl new file mode 100644 index 00000000..4bc3e28c --- /dev/null +++ b/.gwt/work/events/87/87518854cd606f8fb7879ae5aa7a927cd3270f94952a1394e40c74c0d1c29dd9.jsonl @@ -0,0 +1 @@ +{"id":"d0df8370-674e-40f5-a015-d7e43a868c00","work_item_id":"work-work-issue-475-ccff3abe","kind":"start","title":"chore(deps): cargo 依存更新(#474: fastembed 7 / base64 0.23)を取り込み、bincode は 1.x に固定","intent":"Check Board for latest updates","summary":"Codex is running","progress_summary":null,"status_category":"active","owner":"Issue #475","next_action":"Check Board for latest updates","agent_session_id":"4a83e26a-e282-4ed3-99ee-9fcb8e1a903c","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-475","worktree_path":"E:\\unity-cli\\work\\issue-475","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-05T10:33:16.717425800Z"} diff --git a/.gwt/work/events/8d/8d6df80bc742ba4724d2b29edd2ab9b17bdffd5b2d93fa95c29558048b097dc5.jsonl b/.gwt/work/events/8d/8d6df80bc742ba4724d2b29edd2ab9b17bdffd5b2d93fa95c29558048b097dc5.jsonl new file mode 100644 index 00000000..284a7efa --- /dev/null +++ b/.gwt/work/events/8d/8d6df80bc742ba4724d2b29edd2ab9b17bdffd5b2d93fa95c29558048b097dc5.jsonl @@ -0,0 +1 @@ +{"id":"635a50b1-e5ad-485d-b1b2-6b33cd402bf3","work_item_id":"work-work-issue-465-f794e601","kind":"pr","title":null,"intent":null,"summary":null,"progress_summary":null,"status_category":"active","owner":null,"next_action":null,"agent_session_id":"1730113d-3d73-4722-b1ca-61b9d6af50c5","agent_id":null,"display_name":null,"board_entry_id":null,"execution_container":{"branch":"work/issue-465","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-465","pr_number":466,"pr_url":"https://github.com/akiojin/unity-cli/pull/466","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-03T13:37:19.211991Z"} diff --git a/.gwt/work/events/8e/8ed6def970a43a8e22014334dafec05839fb0595a4c62eaa078e7555617c25ae.jsonl b/.gwt/work/events/8e/8ed6def970a43a8e22014334dafec05839fb0595a4c62eaa078e7555617c25ae.jsonl new file mode 100644 index 00000000..50165e15 --- /dev/null +++ b/.gwt/work/events/8e/8ed6def970a43a8e22014334dafec05839fb0595a4c62eaa078e7555617c25ae.jsonl @@ -0,0 +1 @@ +{"id":"0317fd08-2bd2-4a47-b053-7f5cb9809757","work_item_id":"work-work-issue-472-3e7dc4d8","kind":"start","title":"ci: Codecov アップロード失敗で必須カバレッジチェックが落ちる問題と bincode 3 の除外","intent":"Check Board for latest updates","summary":"Claude Code is running","progress_summary":null,"status_category":"active","owner":"Issue #472","next_action":"Check Board for latest updates","agent_session_id":"af4d50d1-e3e4-4be1-984c-46d1c52b560c","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-472","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-472","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-05T06:23:48.482316Z"} diff --git a/.gwt/work/events/90/90c69a6a42a1e0f3e9c8bb72dbfff8ba0093f762fd9b70042c2f343167dee802.jsonl b/.gwt/work/events/90/90c69a6a42a1e0f3e9c8bb72dbfff8ba0093f762fd9b70042c2f343167dee802.jsonl new file mode 100644 index 00000000..230e3fe1 --- /dev/null +++ b/.gwt/work/events/90/90c69a6a42a1e0f3e9c8bb72dbfff8ba0093f762fd9b70042c2f343167dee802.jsonl @@ -0,0 +1 @@ +{"id":"5e77a8aa-a7e2-4c37-818e-ac699afbc8bd","work_item_id":"work-work-issue-490-ce1c1f9a","kind":"update","title":"Issue #490 の受け入れ条件対応","intent":"既存実装と受け入れ条件の監査","summary":null,"progress_summary":null,"status_category":null,"owner":"Issue #490","next_action":null,"agent_session_id":"c0ac1284-51ea-49d8-82e3-da19507a6ba5","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-490","worktree_path":"E:\\unity-cli\\work\\issue-490","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T07:37:10.390988600Z"} diff --git a/.gwt/work/events/94/946595126fec4af72bd325bb618180f5799c68e043cb6145d400e5e32345bd9b.jsonl b/.gwt/work/events/94/946595126fec4af72bd325bb618180f5799c68e043cb6145d400e5e32345bd9b.jsonl new file mode 100644 index 00000000..e7016b39 --- /dev/null +++ b/.gwt/work/events/94/946595126fec4af72bd325bb618180f5799c68e043cb6145d400e5e32345bd9b.jsonl @@ -0,0 +1 @@ +{"id":"39223122-1863-4d4a-a755-962ebe880c2a","work_item_id":"work-work-issue-516-59f2c1be","kind":"update","title":null,"intent":".NET の変更範囲に合う正式検証と PR 作成","summary":null,"progress_summary":"条件コンパイル全分岐の文字列 CR 保護を実装し、LSP 全339テストが成功。指示行の空白ケースを追加して正式検証へ進む。","status_category":null,"owner":"Issue #516","next_action":null,"agent_session_id":"7dec144f-cdc1-4a98-b90f-fe2f1f41e128","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"E:\\unity-cli\\work\\issue-516","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T01:21:37.696264300Z"} diff --git a/.gwt/work/events/98/985343f37d9890b38f154f4201bcc76343fd387167eb1dfc6b35da38c8c88e66.jsonl b/.gwt/work/events/98/985343f37d9890b38f154f4201bcc76343fd387167eb1dfc6b35da38c8c88e66.jsonl new file mode 100644 index 00000000..304f3eac --- /dev/null +++ b/.gwt/work/events/98/985343f37d9890b38f154f4201bcc76343fd387167eb1dfc6b35da38c8c88e66.jsonl @@ -0,0 +1 @@ +{"id":"71dc8444-f077-41c3-9527-443c381b504a","work_item_id":"work-work-issue-516-59f2c1be","kind":"update","title":null,"intent":"verify.run(TMPDIR=/tmp)と PR CI の完了待ち","summary":"verify.run を再実行中です(3 回目)。PR CI は残り 3 件です。","progress_summary":"ApplyNewlines で単独 CR を行終端子として正規化しました(文字列リテラル内の CR は保持)。3×3 改行行列テストとリテラルテストを追加し、LSP テストは 229 件合格です。Draft PR #517 を作成しました。macOS の書き込み信頼性ゲートは checkout LSP の条件で 100% です。verify.run の cargo test 失敗は、verify の長い TMPDIR が Unix socket パス制限を超えるという環境要因と特定しました。TMPDIR=/tmp を付けて再実行しています。","status_category":null,"owner":"Issue #516","next_action":null,"agent_session_id":"2422daaa-fb2e-42af-a9de-476f61a2dc84","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-516","pr_number":517,"pr_url":"https://github.com/akiojin/unity-cli/pull/517","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-14T01:03:23.908908Z"} diff --git a/.gwt/work/events/99/99ea4094ca2c7435e791ea7e4c7c99da5d81b6374305c665de44bb0ff8d6e9f7.jsonl b/.gwt/work/events/99/99ea4094ca2c7435e791ea7e4c7c99da5d81b6374305c665de44bb0ff8d6e9f7.jsonl new file mode 100644 index 00000000..f31acc12 --- /dev/null +++ b/.gwt/work/events/99/99ea4094ca2c7435e791ea7e4c7c99da5d81b6374305c665de44bb0ff8d6e9f7.jsonl @@ -0,0 +1 @@ +{"id":"8c0c79a3-56ab-4684-ade8-fc3237db148c","work_item_id":"work-work-issue-465-f794e601","kind":"update","title":"Issue #465 の残り受け入れ基準の実装","intent":"Issue #465 の受け入れ基準を評価中","summary":null,"progress_summary":null,"status_category":null,"owner":"Issue #465","next_action":null,"agent_session_id":"1730113d-3d73-4722-b1ca-61b9d6af50c5","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-465","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-465","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-03T13:29:40.684629Z"} diff --git a/.gwt/work/events/9a/9a605b22f1057785d3f3efb2a49448954a2ae0b91d17d07fbcd44c5d16a7d0ea.jsonl b/.gwt/work/events/9a/9a605b22f1057785d3f3efb2a49448954a2ae0b91d17d07fbcd44c5d16a7d0ea.jsonl new file mode 100644 index 00000000..afe3c77f --- /dev/null +++ b/.gwt/work/events/9a/9a605b22f1057785d3f3efb2a49448954a2ae0b91d17d07fbcd44c5d16a7d0ea.jsonl @@ -0,0 +1 @@ +{"id":"16520be6-a198-41a3-9086-8a82434141cf","work_item_id":"work-work-issue-386-8f91ee0d","kind":"update","title":"Windows・Linux 実機検証 #386","intent":"Windows の Editor 起動ハンドル継承とシーン保存先作成の回帰テスト","summary":null,"progress_summary":null,"status_category":null,"owner":"Issue #386","next_action":null,"agent_session_id":"58337a13-2327-417b-b9f2-9b4b847857c4","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-386","worktree_path":"E:/unity-cli/work/issue-386","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-03T04:39:30.680687400Z"} diff --git a/.gwt/work/events/9c/9c434a5da95639afd344c6072831888ac98fe9eaa65c9bc8e4f556a384422c8b.jsonl b/.gwt/work/events/9c/9c434a5da95639afd344c6072831888ac98fe9eaa65c9bc8e4f556a384422c8b.jsonl new file mode 100644 index 00000000..3ea7ff23 --- /dev/null +++ b/.gwt/work/events/9c/9c434a5da95639afd344c6072831888ac98fe9eaa65c9bc8e4f556a384422c8b.jsonl @@ -0,0 +1 @@ +{"id":"a806a0f9-e9a1-4274-a21d-15d21db5b50d","work_item_id":"work-work-issue-386-8f91ee0d","kind":"blocked","title":"Windows・Linux 実機検証 #386","intent":"Windows 修正・証跡整理済み。skill リンク作成権限、Linux 実 Editor、原資料、winget 公開設定、正式検証枠の不足を解消して再開","summary":"Windows 23操作は比較条件で成功。最終 Cargo は605成功・リンク制約で1失敗、fmt/clippy/Unity11件成功。Issueコメントに証跡記録。PR未作成。","progress_summary":null,"status_category":"blocked","owner":"Issue #386","next_action":"不足する検証環境と配布設定を確認し、正規リンクの checkout で正式 verify.run を再実行する","agent_session_id":"58337a13-2327-417b-b9f2-9b4b847857c4","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-386","worktree_path":"E:/unity-cli/work/issue-386","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-03T15:57:16.222752200Z"} diff --git a/.gwt/work/events/9c/9c58f642272910cc3dffb7ab234a9def2d8f9677ffa53af5bded950f93764212.jsonl b/.gwt/work/events/9c/9c58f642272910cc3dffb7ab234a9def2d8f9677ffa53af5bded950f93764212.jsonl new file mode 100644 index 00000000..c2f471c9 --- /dev/null +++ b/.gwt/work/events/9c/9c58f642272910cc3dffb7ab234a9def2d8f9677ffa53af5bded950f93764212.jsonl @@ -0,0 +1 @@ +{"id":"dd2b5d86-e8f2-4ca3-bbbc-a3249c578b3c","work_item_id":"work-work-issue-465-f794e601","kind":"update","title":null,"intent":"PM へ引き継ぎ済み(PR作成可)。PM の pr.ready 待ち","summary":null,"progress_summary":"AC-1〜4 を実装し Draft PR #466 の CI が全ジョブ PASS(head b0df8c0)。#386 本文と #465 のチェックを更新済み。gwtd verify.run は host lease の競合で未実行、PM 裁定により CI を最終確認として引き継いだ。","status_category":null,"owner":"Issue #465","next_action":null,"agent_session_id":"1730113d-3d73-4722-b1ca-61b9d6af50c5","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-465","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-465","pr_number":466,"pr_url":"https://github.com/akiojin/unity-cli/pull/466","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-03T13:51:56.593992Z"} diff --git a/.gwt/work/events/9d/9d86038043fa672eed535443166fd5dfd5e5b07bd95611ee614f760823af2cb0.jsonl b/.gwt/work/events/9d/9d86038043fa672eed535443166fd5dfd5e5b07bd95611ee614f760823af2cb0.jsonl new file mode 100644 index 00000000..0577de0a --- /dev/null +++ b/.gwt/work/events/9d/9d86038043fa672eed535443166fd5dfd5e5b07bd95611ee614f760823af2cb0.jsonl @@ -0,0 +1 @@ +{"id":"da62bab5-67c1-48bf-abd5-cfc9d10d2a4a","work_item_id":"work-work-issue-516-59f2c1be","kind":"resume","title":"fix(lsp): normalize lone CR in edits to the file's newline style for LF and CRLF files","intent":"verify.run を実行中です。PR CI も待っています。","summary":"2 active agents","progress_summary":null,"status_category":"active","owner":"Issue #516","next_action":"Check Board for latest updates","agent_session_id":"09be6709-cd11-44d6-9b30-8fdea359c0ef","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-516","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T00:58:43.869889Z"} diff --git a/.gwt/work/events/a1/a1adfecc1aebb92b2a0e9800b7d73a9f5244d88575597a049f0c682111478415.jsonl b/.gwt/work/events/a1/a1adfecc1aebb92b2a0e9800b7d73a9f5244d88575597a049f0c682111478415.jsonl new file mode 100644 index 00000000..32e75162 --- /dev/null +++ b/.gwt/work/events/a1/a1adfecc1aebb92b2a0e9800b7d73a9f5244d88575597a049f0c682111478415.jsonl @@ -0,0 +1 @@ +{"id":"4037547a-a33f-465b-ac18-142147abf076","work_item_id":"work-work-issue-511-ac1c61e3","kind":"done","title":"Windows LSP の file URI 解決","intent":"検証済み変更の配送と CI 自動マージ","summary":null,"progress_summary":"#511 全 AC の変更前監査で未達を確認。C#/Rust の正規 file URI 双方向変換、特殊文字/UNC 往復、Assets 検索と URI 再利用、独立 Windows CI を実装。canonical verify 10/10 PASS、Rust627件、Windows/Linux C#各111件、coverage99.66%、実Windows CLI/LSP3操作 PASS。","status_category":"done","owner":"Issue #511","next_action":"commit/push → fresh verify → Ready PR → CI/自動マージ確認 → AC同期とIssue close","agent_session_id":"d0aa10d9-7f81-4304-905c-47fc4ce7b80c","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-511","worktree_path":"E:\\unity-cli\\work\\issue-511","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T13:35:57.324265100Z"} diff --git a/.gwt/work/events/a3/a3eb4c7a657a8280a1a0917df2e9769f19afdd67b295b3a73da4825d040ec581.jsonl b/.gwt/work/events/a3/a3eb4c7a657a8280a1a0917df2e9769f19afdd67b295b3a73da4825d040ec581.jsonl new file mode 100644 index 00000000..3c9c8745 --- /dev/null +++ b/.gwt/work/events/a3/a3eb4c7a657a8280a1a0917df2e9769f19afdd67b295b3a73da4825d040ec581.jsonl @@ -0,0 +1 @@ +{"id":"abece4bc-f732-4e64-a63e-2c8d1dde2f1a","work_item_id":"work-work-issue-516-59f2c1be","kind":"resume","title":"Issue #516 の改行正規化修正を届ける","intent":"PR #518 のCodeRabbit指摘(無効分岐の未完了コメントが有効分岐の文字列判定へ干渉)を担当します。回帰テストで再現し、分岐と祖先の選択ごとに解析する方式へ変更中です。未完了文字列の保護範囲も選択分岐に限定します。LspSourceFile.cs/SourceFileFormatTests.cs の修正・正式検証・push・スレッド回答までこのSessionで進めるため、同じHEADへの並行pushは避けてください。","summary":"3 active agents","progress_summary":null,"status_category":"active","owner":"Issue #516","next_action":"Check Board for latest updates","agent_session_id":"7dec144f-cdc1-4a98-b90f-fe2f1f41e128","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"E:/unity-cli/work/issue-516","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T03:11:27.600281600Z"} diff --git a/.gwt/work/events/a4/a446bced7269a52c5c357c9dd849d90d5824daa8fbf7b07a0a13c3cd6fcf7341.jsonl b/.gwt/work/events/a4/a446bced7269a52c5c357c9dd849d90d5824daa8fbf7b07a0a13c3cd6fcf7341.jsonl new file mode 100644 index 00000000..0de855a4 --- /dev/null +++ b/.gwt/work/events/a4/a446bced7269a52c5c357c9dd849d90d5824daa8fbf7b07a0a13c3cd6fcf7341.jsonl @@ -0,0 +1 @@ +{"id":"ec40077f-e57c-473f-b22d-60ccabb788a2","work_item_id":"work-work-issue-504-10f6aa4a","kind":"update","title":"Windows の C# 初回書き込み待機を短縮","intent":"AC-1〜3 未達、TCP 接続待機の原因確認","summary":null,"progress_summary":"全受入条件を監査。既存実装の修正と Windows 改善の証跡はありません。","status_category":null,"owner":"Issue #504","next_action":null,"agent_session_id":"04108877-9f1d-4de6-859d-a4bbad4605b7","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-504","worktree_path":"E:\\unity-cli\\work\\issue-504","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T11:37:35.601557300Z"} diff --git a/.gwt/work/events/a4/a4b4785c35358bc10513ba81717f336b0f678f89d1e54101551e6c61689eebdc.jsonl b/.gwt/work/events/a4/a4b4785c35358bc10513ba81717f336b0f678f89d1e54101551e6c61689eebdc.jsonl new file mode 100644 index 00000000..cafc322e --- /dev/null +++ b/.gwt/work/events/a4/a4b4785c35358bc10513ba81717f336b0f678f89d1e54101551e6c61689eebdc.jsonl @@ -0,0 +1 @@ +{"id":"5e1134be-5e8f-4bee-a9f8-c7d496bad0b9","work_item_id":"work-work-issue-475-ccff3abe","kind":"done","title":"Cargo 依存更新(#475)","intent":"実装とローカル検証が終了。正式検証記録・置換 PR・CI マージを進める","summary":"base64 0.23.1 / fastembed 7.1.0 / socket2 0.6.5 / libc 0.2.189 を更新。bincode=1.3.3 と既存インデックス形式を保持。Rust611件、clippy/fmt/skills lint PASS。Windows LSP既存2件失敗はbaseline再現・PM共有済み。","progress_summary":null,"status_category":"done","owner":"Issue #475","next_action":"commit/push後に全Rust targetの正式verify.runを実行し、#474置換Ready PRをauto-mergeまで追跡する","agent_session_id":"4a83e26a-e282-4ed3-99ee-9fcb8e1a903c","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-475","worktree_path":"E:\\unity-cli\\work\\issue-475","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-05T10:49:16.238847400Z"} diff --git a/.gwt/work/events/a5/a5365cc444d1548328d1cc9a21c64f1e6994f668eb13febf2fcdf23a7988c680.jsonl b/.gwt/work/events/a5/a5365cc444d1548328d1cc9a21c64f1e6994f668eb13febf2fcdf23a7988c680.jsonl new file mode 100644 index 00000000..dac66923 --- /dev/null +++ b/.gwt/work/events/a5/a5365cc444d1548328d1cc9a21c64f1e6994f668eb13febf2fcdf23a7988c680.jsonl @@ -0,0 +1 @@ +{"id":"e6ee7dd2-74dc-4789-8eb7-3a18d932e5af","work_item_id":"work-work-issue-465-f794e601","kind":"resume","title":"ci(windows,linux): 公開版の導入・Wayland スクリーンショット・skills 導入を CI で確認する(#386 から切り出し 第2弾)","intent":"Claude Code started work on Issue #465 ci(windows,linux): 公開版の導入・Wayland スクリーンショット・skills 導入を CI で確認する(#386 から切り出し 第2弾) (work/issue-465)","summary":"2 active agents","progress_summary":null,"status_category":"active","owner":"Issue #465","next_action":"Check Board for latest updates","agent_session_id":"fe9e4e72-804e-4519-99c5-032aefc86976","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-465","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-465","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-03T13:40:02.862336Z"} diff --git a/.gwt/work/events/a7/a7ac6a6e9f002714e266210435aeb76900d77e23e5611ee84ee50e8fef642639.jsonl b/.gwt/work/events/a7/a7ac6a6e9f002714e266210435aeb76900d77e23e5611ee84ee50e8fef642639.jsonl new file mode 100644 index 00000000..cb8802ab --- /dev/null +++ b/.gwt/work/events/a7/a7ac6a6e9f002714e266210435aeb76900d77e23e5611ee84ee50e8fef642639.jsonl @@ -0,0 +1 @@ +{"id":"16925dea-044b-451d-81e2-b5d2f12f3b3d","work_item_id":"work-work-issue-516-59f2c1be","kind":"update","title":null,"intent":"verify.run(再実行)と PR CI の完了待ち","summary":"プロジェクト品質ゲート(--test-threads=1)で verify.run を再実行中です。","progress_summary":"ApplyNewlines で単独 CR を行終端子として正規化しました(文字列リテラル内の CR は保持)。3×3 改行行列テストとリテラルテストを追加し、LSP テストは 229 件合格です。Draft PR #517 を作成しました。ローカル macOS の書き込み信頼性ゲートは、checkout LSP の条件で 100% でした。derived matrix の verify.run は、並列実行の cargo test で daemon 系テストが失敗しました。単一スレッドでは全件合格です(変更していない Rust コードの環境要因)。","status_category":null,"owner":"Issue #516","next_action":null,"agent_session_id":"2422daaa-fb2e-42af-a9de-476f61a2dc84","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-516","pr_number":517,"pr_url":"https://github.com/akiojin/unity-cli/pull/517","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-14T01:00:43.049416Z"} diff --git a/.gwt/work/events/ab/abc231a6dd43be48ac970c69e1d90fd3f858a6e97fab37f8e1ccb58aaab139f5.jsonl b/.gwt/work/events/ab/abc231a6dd43be48ac970c69e1d90fd3f858a6e97fab37f8e1ccb58aaab139f5.jsonl new file mode 100644 index 00000000..6e2e8bd9 --- /dev/null +++ b/.gwt/work/events/ab/abc231a6dd43be48ac970c69e1d90fd3f858a6e97fab37f8e1ccb58aaab139f5.jsonl @@ -0,0 +1 @@ +{"id":"5f11c1c6-23c4-4103-9d81-6225112a154c","work_item_id":"work-work-issue-520-2c5b16f7","kind":"resume","title":"fix(lsp): keep closed-string CRs in sibling branches hidden by an unterminated literal (#516 follow-up)","intent":"Codex is ready for the next instruction on Issue #520 fix(lsp): keep closed-string CRs in sibling branches hidden by an unterminated literal (#516 follow-up) (work/issue-520)","summary":"3 active agents","progress_summary":null,"status_category":"active","owner":"Issue #520","next_action":"Check Board for latest updates","agent_session_id":"24541411-db4e-4036-b84a-7d3017c8757e","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-520","worktree_path":"E:/unity-cli/work/issue-520","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T05:52:06.788146100Z"} diff --git a/.gwt/work/events/ad/ad4ba11da76717162859737bc36a4b305017cbf6c4002112f651fcc2959754d1.jsonl b/.gwt/work/events/ad/ad4ba11da76717162859737bc36a4b305017cbf6c4002112f651fcc2959754d1.jsonl new file mode 100644 index 00000000..1619d5b5 --- /dev/null +++ b/.gwt/work/events/ad/ad4ba11da76717162859737bc36a4b305017cbf6c4002112f651fcc2959754d1.jsonl @@ -0,0 +1 @@ +{"id":"7545127f-79bd-457e-910d-d616caa0ac1e","work_item_id":"work-work-issue-498-892fdd8e","kind":"done","title":null,"intent":"PR #513 の CI 待ち(PM が Ready にする)","summary":null,"progress_summary":"AC-1 の残件(UTF-32 BE BOM と CR 単独改行)を実装し、Draft PR #513 を作成。dotnet test 192 件 pass、fmt と clippy も pass。Issue にコメント済み。","status_category":"done","owner":"Issue #498","next_action":null,"agent_session_id":"28641b50-7397-40b7-98fc-192f96e72d4a","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-498","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-498","pr_number":513,"pr_url":"https://github.com/akiojin/unity-cli/pull/513","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-13T14:05:57.542827Z"} diff --git a/.gwt/work/events/ad/adf8548a76ec7f2e0af45130f8f8dd859b92e2ba8fb0e412f6759e6e37c7a54c.jsonl b/.gwt/work/events/ad/adf8548a76ec7f2e0af45130f8f8dd859b92e2ba8fb0e412f6759e6e37c7a54c.jsonl new file mode 100644 index 00000000..688aedb2 --- /dev/null +++ b/.gwt/work/events/ad/adf8548a76ec7f2e0af45130f8f8dd859b92e2ba8fb0e412f6759e6e37c7a54c.jsonl @@ -0,0 +1 @@ +{"id":"231cd0a0-b6ef-47bb-8c7a-044a265ad564","work_item_id":"work-work-issue-475-ccff3abe","kind":"update","title":"Issue #475 の受け入れ条件","intent":"Issue 本文、関連 PR、実装を照合し、残る受け入れ条件を監査","summary":null,"progress_summary":null,"status_category":null,"owner":"Issue #475","next_action":null,"agent_session_id":"4a83e26a-e282-4ed3-99ee-9fcb8e1a903c","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-475","worktree_path":"E:\\unity-cli\\work\\issue-475","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-05T10:35:30.643259600Z"} diff --git a/.gwt/work/events/af/afade077dd64ef32dddfd526ea6a0e174992f8ac171907a5ab55aedcfe836a73.jsonl b/.gwt/work/events/af/afade077dd64ef32dddfd526ea6a0e174992f8ac171907a5ab55aedcfe836a73.jsonl new file mode 100644 index 00000000..b20038a5 --- /dev/null +++ b/.gwt/work/events/af/afade077dd64ef32dddfd526ea6a0e174992f8ac171907a5ab55aedcfe836a73.jsonl @@ -0,0 +1 @@ +{"id":"a159f90c-fea6-4070-a8ac-5dab1e86852c","work_item_id":"work-work-issue-516-59f2c1be","kind":"update","title":null,"intent":"PR #517 の CI 待ち","summary":null,"progress_summary":"ApplyNewlines で単独 CR を行終端として正規化(文字列リテラル内は保持)。9 通り行列テストとリテラルテストを追加、LSP テスト 229 件合格。Draft PR #517 作成。","status_category":null,"owner":"Issue #516","next_action":null,"agent_session_id":"2422daaa-fb2e-42af-a9de-476f61a2dc84","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-516","pr_number":517,"pr_url":"https://github.com/akiojin/unity-cli/pull/517","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-14T00:55:19.883034Z"} diff --git a/.gwt/work/events/b3/b3e7a05f2a2cf0525bc69558d25091debc7dc318add5d26c4167e598616b4ef6.jsonl b/.gwt/work/events/b3/b3e7a05f2a2cf0525bc69558d25091debc7dc318add5d26c4167e598616b4ef6.jsonl new file mode 100644 index 00000000..503dc792 --- /dev/null +++ b/.gwt/work/events/b3/b3e7a05f2a2cf0525bc69558d25091debc7dc318add5d26c4167e598616b4ef6.jsonl @@ -0,0 +1 @@ +{"id":"33e6ea8d-4da6-4c4d-91dd-c2812be558b5","work_item_id":"work-work-issue-522-b9f798d4","kind":"update","title":null,"intent":"性能ゲート: load1 < 8.5 待ち","summary":null,"progress_summary":"v0.19.0 のバージョン更新 5 ファイルと CHANGELOG(Breaking changes 節含む)を作成、release バイナリをビルド済み。性能ゲート実行待ち(未コミット)","status_category":null,"owner":"Issue #522","next_action":null,"agent_session_id":"c270a89f-b89c-48d0-a8ba-b3d897512283","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-522","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-522","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T10:27:41.248750Z"} diff --git a/.gwt/work/events/b5/b5d75d20837cdbfe8ea439dbd4d88fb6590a3c7ad37297584d6cb01335c81218.jsonl b/.gwt/work/events/b5/b5d75d20837cdbfe8ea439dbd4d88fb6590a3c7ad37297584d6cb01335c81218.jsonl new file mode 100644 index 00000000..a711ddb9 --- /dev/null +++ b/.gwt/work/events/b5/b5d75d20837cdbfe8ea439dbd4d88fb6590a3c7ad37297584d6cb01335c81218.jsonl @@ -0,0 +1 @@ +{"id":"f729ada6-8b65-49ef-b62b-46b95036194e","work_item_id":"work-work-issue-516-59f2c1be","kind":"update","title":null,"intent":"verify.run と PR CI の完了待ち","summary":"verify.run を実行中です。PR CI も待っています。","progress_summary":"ApplyNewlines で単独 CR を行終端子として正規化しました(文字列リテラル内の CR は保持)。3×3 改行行列テストとリテラルテストを追加し、LSP テストは 229 件合格です。Draft PR #517 を作成しました。ローカル macOS の書き込み信頼性ゲートは、checkout LSP を使う 2 条件(warm_indexed / unindexed)が全シナリオ 100%、baseline 判定は exit 0 です。","status_category":null,"owner":"Issue #516","next_action":null,"agent_session_id":"2422daaa-fb2e-42af-a9de-476f61a2dc84","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-516","pr_number":517,"pr_url":"https://github.com/akiojin/unity-cli/pull/517","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-14T00:57:27.920652Z"} diff --git a/.gwt/work/events/ba/ba1ba8be7a52c932ed55e5d9484075ae37f41b44045f9660ac3289785df2a128.jsonl b/.gwt/work/events/ba/ba1ba8be7a52c932ed55e5d9484075ae37f41b44045f9660ac3289785df2a128.jsonl new file mode 100644 index 00000000..37cc89a4 --- /dev/null +++ b/.gwt/work/events/ba/ba1ba8be7a52c932ed55e5d9484075ae37f41b44045f9660ac3289785df2a128.jsonl @@ -0,0 +1 @@ +{"id":"acd77777-733b-49b4-ba14-f478f9d87c11","work_item_id":"work-work-issue-490-ce1c1f9a","kind":"update","title":null,"intent":"Windows 実測、既知不具合の厳密な baseline、3 OS CI の検証","summary":null,"progress_summary":"19 シナリオ・全10ツール、4起動条件の実CLI/LSPランナーとCIを実装。測定ロジック回帰7件PASS。Windows実測でBOM追加、末尾コメント喪失、ScriptableObject using欠落を確認し、PMへ個別Issue登録を依頼。","status_category":null,"owner":"Issue #490","next_action":null,"agent_session_id":"c0ac1284-51ea-49d8-82e3-da19507a6ba5","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-490","worktree_path":"E:\\unity-cli\\work\\issue-490","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T08:05:25.880779200Z"} diff --git a/.gwt/work/events/bb/bb6f404b351d7e2650cffbe763118c484a58e8ccab3377ffce522eb5939df416.jsonl b/.gwt/work/events/bb/bb6f404b351d7e2650cffbe763118c484a58e8ccab3377ffce522eb5939df416.jsonl new file mode 100644 index 00000000..5e540752 --- /dev/null +++ b/.gwt/work/events/bb/bb6f404b351d7e2650cffbe763118c484a58e8ccab3377ffce522eb5939df416.jsonl @@ -0,0 +1 @@ +{"id":"0ba0d709-6430-4c49-ac46-9d2293246329","work_item_id":"work-work-issue-465-f794e601","kind":"update","title":"公開版導入・Wayland スクリーンショット・skills 導入の CI 確認 (#465)","intent":"AC-1〜3 の CI テストを実装中","summary":null,"progress_summary":"AC 監査完了: AC-1〜4 すべて未達。sway headless + grim が Ubuntu 24.04 で PNG を生成することを Docker で確認済み。","status_category":null,"owner":"Issue #465","next_action":null,"agent_session_id":"1730113d-3d73-4722-b1ca-61b9d6af50c5","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-465","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-465","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-03T13:32:04.778621Z"} diff --git a/.gwt/work/events/bb/bb77301504a6ced56569c8335a63a352bd7cc308c3378de4eaa820358085e6d0.jsonl b/.gwt/work/events/bb/bb77301504a6ced56569c8335a63a352bd7cc308c3378de4eaa820358085e6d0.jsonl new file mode 100644 index 00000000..b3ae1a55 --- /dev/null +++ b/.gwt/work/events/bb/bb77301504a6ced56569c8335a63a352bd7cc308c3378de4eaa820358085e6d0.jsonl @@ -0,0 +1 @@ +{"id":"7870472f-ab27-4cb7-9b24-0bc936374999","work_item_id":"work-work-issue-516-59f2c1be","kind":"update","title":null,"intent":"無効な条件コンパイル分岐の CR 保持を再現・修正","summary":null,"progress_summary":"origin/develop に初回修正が収録済み。残 AC-1 は無効分岐内の文字列 CR 保護。","status_category":null,"owner":"Issue #516","next_action":null,"agent_session_id":"7dec144f-cdc1-4a98-b90f-fe2f1f41e128","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"E:\\unity-cli\\work\\issue-516","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T01:16:42.946264500Z"} diff --git a/.gwt/work/events/bd/bd8505d24c63b97797a97e0499fe15642e69200aa39bc8d29606d04659920fdf.jsonl b/.gwt/work/events/bd/bd8505d24c63b97797a97e0499fe15642e69200aa39bc8d29606d04659920fdf.jsonl new file mode 100644 index 00000000..388a6119 --- /dev/null +++ b/.gwt/work/events/bd/bd8505d24c63b97797a97e0499fe15642e69200aa39bc8d29606d04659920fdf.jsonl @@ -0,0 +1 @@ +{"id":"ba79a513-351f-426e-88c3-b67b4a7fc2ee","work_item_id":"work-work-issue-520-2c5b16f7","kind":"update","title":null,"intent":"AC-2拡張生成器で検出した構文回復の不一致を修正","summary":null,"progress_summary":"実行権限復旧。固定RED8件確認、元の1000生成件は一致。拡張生成器11不一致の原因を特定。","status_category":null,"owner":"Issue #520","next_action":null,"agent_session_id":"fad8f3f5-654a-4ea4-b0c6-e65546d2f5bb","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-520","worktree_path":"E:\\unity-cli\\work\\issue-520","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T06:22:38.931324900Z"} diff --git a/.gwt/work/events/c2/c272cda4b82a1e0c01d54f9ec52168270b59a40c0244106531add4bb6760242d.jsonl b/.gwt/work/events/c2/c272cda4b82a1e0c01d54f9ec52168270b59a40c0244106531add4bb6760242d.jsonl new file mode 100644 index 00000000..ba312030 --- /dev/null +++ b/.gwt/work/events/c2/c272cda4b82a1e0c01d54f9ec52168270b59a40c0244106531add4bb6760242d.jsonl @@ -0,0 +1 @@ +{"id":"3790a9c8-40b7-448d-87a6-54d2a455aad9","work_item_id":"work-work-issue-516-59f2c1be","kind":"update","title":"Issue #516 の実装と develop への配信","intent":"受け入れ基準の評価","summary":null,"progress_summary":null,"status_category":null,"owner":"Issue #516","next_action":null,"agent_session_id":"2422daaa-fb2e-42af-a9de-476f61a2dc84","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-516","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T00:39:08.831132Z"} diff --git a/.gwt/work/events/c3/c375b7253ea0622ffdbd14c0b666c9bd77b80207a30c56b03281050561808547.jsonl b/.gwt/work/events/c3/c375b7253ea0622ffdbd14c0b666c9bd77b80207a30c56b03281050561808547.jsonl new file mode 100644 index 00000000..10a0b89e --- /dev/null +++ b/.gwt/work/events/c3/c375b7253ea0622ffdbd14c0b666c9bd77b80207a30c56b03281050561808547.jsonl @@ -0,0 +1 @@ +{"id":"a3fac5c7-e020-4dc7-8818-b85ea11e087d","work_item_id":"work-work-issue-498-892fdd8e","kind":"resume","title":"fix(lsp): keep the original BOM and newlines when C# LSP write tools save a file","intent":"Check Board for latest updates","summary":"Claude Code is running","progress_summary":null,"status_category":"active","owner":"Issue #498","next_action":"Check Board for latest updates","agent_session_id":"28641b50-7397-40b7-98fc-192f96e72d4a","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-498","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-498","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T13:38:52.132622Z"} diff --git a/.gwt/work/events/c7/c7d35bd1295c92ec473b7da5492d6277384ca9d18f70c54372b8107558f11696.jsonl b/.gwt/work/events/c7/c7d35bd1295c92ec473b7da5492d6277384ca9d18f70c54372b8107558f11696.jsonl new file mode 100644 index 00000000..4003f4b5 --- /dev/null +++ b/.gwt/work/events/c7/c7d35bd1295c92ec473b7da5492d6277384ca9d18f70c54372b8107558f11696.jsonl @@ -0,0 +1 @@ +{"id":"8b2f177c-b10e-49ac-8a63-3f8a30ff4f0a","work_item_id":"work-work-issue-511-ac1c61e3","kind":"start","title":"fix(lsp): resolve Windows file URIs so symbol search finds Assets files on Windows","intent":"Check Board for latest updates","summary":"Codex is running","progress_summary":null,"status_category":"active","owner":"Issue #511","next_action":"Check Board for latest updates","agent_session_id":"d0aa10d9-7f81-4304-905c-47fc4ce7b80c","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-511","worktree_path":"E:\\unity-cli\\work\\issue-511","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T12:59:55.693971100Z"} diff --git a/.gwt/work/events/cb/cbb6fd086b6e0ac48784a806749d1a69f92f36d306270df41f5c2fbd4f12fa9c.jsonl b/.gwt/work/events/cb/cbb6fd086b6e0ac48784a806749d1a69f92f36d306270df41f5c2fbd4f12fa9c.jsonl new file mode 100644 index 00000000..cdeed495 --- /dev/null +++ b/.gwt/work/events/cb/cbb6fd086b6e0ac48784a806749d1a69f92f36d306270df41f5c2fbd4f12fa9c.jsonl @@ -0,0 +1 @@ +{"id":"2cadaff0-9129-49fa-b82b-f7a6ac3482c7","work_item_id":"work-work-issue-504-10f6aa4a","kind":"update","title":"Issue #504 の受入条件を充足","intent":"受入条件と既存実装の監査","summary":null,"progress_summary":null,"status_category":null,"owner":"Issue #504","next_action":null,"agent_session_id":"04108877-9f1d-4de6-859d-a4bbad4605b7","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-504","worktree_path":"E:\\unity-cli\\work\\issue-504","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T11:35:57.236479500Z"} diff --git a/.gwt/work/events/ce/ce5e6b98fd2a773f841a502ee45eecc84efa3be1775ba65f4cdb890a4613a29d.jsonl b/.gwt/work/events/ce/ce5e6b98fd2a773f841a502ee45eecc84efa3be1775ba65f4cdb890a4613a29d.jsonl new file mode 100644 index 00000000..c0162444 --- /dev/null +++ b/.gwt/work/events/ce/ce5e6b98fd2a773f841a502ee45eecc84efa3be1775ba65f4cdb890a4613a29d.jsonl @@ -0,0 +1 @@ +{"id":"b9d6016e-de5c-46f1-ad45-ab4f27081814","work_item_id":"work-work-issue-386-8f91ee0d","kind":"update","title":"Windows・Linux 実機検証 #386","intent":"Windows 23 操作が比較資料の設定で成功。共通検証枠を待ちながら証跡・未達条件を整理","summary":null,"progress_summary":null,"status_category":null,"owner":"Issue #386","next_action":null,"agent_session_id":"58337a13-2327-417b-b9f2-9b4b847857c4","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-386","worktree_path":"E:/unity-cli/work/issue-386","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-03T15:04:19.275941Z"} diff --git a/.gwt/work/events/d1/d11d070eaa16ffde4327dd6732584ce29d4868294f9548f10c9f2ec4dad54949.jsonl b/.gwt/work/events/d1/d11d070eaa16ffde4327dd6732584ce29d4868294f9548f10c9f2ec4dad54949.jsonl new file mode 100644 index 00000000..b6cb858c --- /dev/null +++ b/.gwt/work/events/d1/d11d070eaa16ffde4327dd6732584ce29d4868294f9548f10c9f2ec4dad54949.jsonl @@ -0,0 +1 @@ +{"id":"9a40c654-fc4c-4e24-aa65-83557e570316","work_item_id":"work-successor-7c2dfc5d2b5cce43936b35438f6127d998d532280cf12c1dd034899b09313645","kind":"pr","title":null,"intent":null,"summary":null,"progress_summary":null,"status_category":"done","owner":null,"next_action":null,"agent_session_id":"efd1f1c5-7a52-4d29-9970-e43f2e9a9519","agent_id":null,"display_name":null,"board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-516","pr_number":518,"pr_url":"https://github.com/akiojin/unity-cli/pull/518","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-14T01:49:14.247281Z"} diff --git a/.gwt/work/events/d5/d5632de57ae50f64b59d7c3fa6db39f74033569483f7dc6407390800eb844fe7.jsonl b/.gwt/work/events/d5/d5632de57ae50f64b59d7c3fa6db39f74033569483f7dc6407390800eb844fe7.jsonl new file mode 100644 index 00000000..60a9926a --- /dev/null +++ b/.gwt/work/events/d5/d5632de57ae50f64b59d7c3fa6db39f74033569483f7dc6407390800eb844fe7.jsonl @@ -0,0 +1 @@ +{"id":"613ce139-0256-4818-a25e-f86b4d4a59ae","work_item_id":"work-work-issue-516-59f2c1be","kind":"update","title":"Issue #516 の改行正規化修正を届ける","intent":"実行手順と未配信差分の確認","summary":null,"progress_summary":null,"status_category":null,"owner":"Issue #516","next_action":null,"agent_session_id":"7dec144f-cdc1-4a98-b90f-fe2f1f41e128","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"E:\\unity-cli\\work\\issue-516","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T01:14:18.065917600Z"} diff --git a/.gwt/work/events/da/da12e9f6b2845608bfb8503d7662d02fbada6d1024058a2c21e0c7244cd2c0b9.jsonl b/.gwt/work/events/da/da12e9f6b2845608bfb8503d7662d02fbada6d1024058a2c21e0c7244cd2c0b9.jsonl new file mode 100644 index 00000000..2d03941b --- /dev/null +++ b/.gwt/work/events/da/da12e9f6b2845608bfb8503d7662d02fbada6d1024058a2c21e0c7244cd2c0b9.jsonl @@ -0,0 +1 @@ +{"id":"ba97b431-504b-459a-9e9b-bd5bef1805fb","work_item_id":"work-work-issue-516-59f2c1be","kind":"resume","title":"fix(lsp): normalize lone CR in edits to the file's newline style for LF and CRLF files","intent":"Codex started work on Issue #516 fix(lsp): normalize lone CR in edits to the file's newline style for LF and CRLF files (work/issue-516)","summary":"2 active agents","progress_summary":null,"status_category":"active","owner":"Issue #516","next_action":"Check Board for latest updates","agent_session_id":"df5ad3b4-6dc1-488f-a0a9-a3cd91749075","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"E:/unity-cli/work/issue-516","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T01:07:33.740196800Z"} diff --git a/.gwt/work/events/e1/e127649332e27225ca5dc363608f7d4eaa3e0dfb51962b6782b74a847b438dc1.jsonl b/.gwt/work/events/e1/e127649332e27225ca5dc363608f7d4eaa3e0dfb51962b6782b74a847b438dc1.jsonl new file mode 100644 index 00000000..e1c639df --- /dev/null +++ b/.gwt/work/events/e1/e127649332e27225ca5dc363608f7d4eaa3e0dfb51962b6782b74a847b438dc1.jsonl @@ -0,0 +1 @@ +{"id":"77355af4-c7c0-4f75-8e8b-c6a0d3615ee6","work_item_id":"work-work-issue-504-10f6aa4a","kind":"done","title":"Windows の C# 初回書き込み待機を短縮","intent":"実装と計測証跡を確定し、正式検証・PR・必須 CI へ","summary":null,"progress_summary":"全ACの変更前監査、原因記録、RED/GREEN、Windows実測を完了。cold p50 13.183s→5.518s、Rust 全テスト・clippy・skills lint と Linux C# 56テストがPASS。未変更C#のWindows URI失敗2件はPMへ別件報告。User Verification Result: n/a (autonomous)。PRのWindows計測でAC-3を確認し自動マージまで継続。","status_category":"done","owner":"Issue #504","next_action":null,"agent_session_id":"04108877-9f1d-4de6-859d-a4bbad4605b7","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-504","worktree_path":"E:\\unity-cli\\work\\issue-504","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T11:53:34.685101600Z"} diff --git a/.gwt/work/events/e3/e37e976620ce21655b07f3169ff6850ef750f28999646897424cf16d30382ebd.jsonl b/.gwt/work/events/e3/e37e976620ce21655b07f3169ff6850ef750f28999646897424cf16d30382ebd.jsonl new file mode 100644 index 00000000..cb7546bc --- /dev/null +++ b/.gwt/work/events/e3/e37e976620ce21655b07f3169ff6850ef750f28999646897424cf16d30382ebd.jsonl @@ -0,0 +1 @@ +{"id":"85520592-bb0f-41a9-8c02-827e03e42fd8","work_item_id":"work-work-issue-465-f794e601","kind":"update","title":null,"intent":"Draft PR #466 の CI(Windows / Wayland ジョブ)を待機中","summary":null,"progress_summary":"AC-1〜3 を実装して push、Draft PR #466 を作成。ローカル品質ゲートと Linux コンテナでの sway+grim / Xvfb チェックは PASS。Windows の 2 項目は CI で確認中。残り: CI 確認、#386 本文更新 (AC-4)、Ready 化。","status_category":null,"owner":"Issue #465","next_action":null,"agent_session_id":"1730113d-3d73-4722-b1ca-61b9d6af50c5","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-465","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-465","pr_number":466,"pr_url":"https://github.com/akiojin/unity-cli/pull/466","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-03T13:37:25.651163Z"} diff --git a/.gwt/work/events/e5/e5ba87b8461511630b51977eae7e76fe5b17a00aa8ef2826da72fc1e7e6e16eb.jsonl b/.gwt/work/events/e5/e5ba87b8461511630b51977eae7e76fe5b17a00aa8ef2826da72fc1e7e6e16eb.jsonl new file mode 100644 index 00000000..2a26f838 --- /dev/null +++ b/.gwt/work/events/e5/e5ba87b8461511630b51977eae7e76fe5b17a00aa8ef2826da72fc1e7e6e16eb.jsonl @@ -0,0 +1 @@ +{"id":"7dbc9a61-b6b7-4993-ac0a-59e337b8449d","work_item_id":"work-work-issue-516-59f2c1be","kind":"pr","title":null,"intent":null,"summary":null,"progress_summary":null,"status_category":"active","owner":null,"next_action":null,"agent_session_id":"7dec144f-cdc1-4a98-b90f-fe2f1f41e128","agent_id":null,"display_name":null,"board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"E:\\unity-cli\\work\\issue-516","pr_number":518,"pr_url":"https://github.com/akiojin/unity-cli/pull/518","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-14T01:24:52.918816600Z"} diff --git a/.gwt/work/events/e9/e9e18901ca33f9af77112a6a65f739f7ed25afc9fee373d21f6bfb4f401ee735.jsonl b/.gwt/work/events/e9/e9e18901ca33f9af77112a6a65f739f7ed25afc9fee373d21f6bfb4f401ee735.jsonl new file mode 100644 index 00000000..e8e6390d --- /dev/null +++ b/.gwt/work/events/e9/e9e18901ca33f9af77112a6a65f739f7ed25afc9fee373d21f6bfb4f401ee735.jsonl @@ -0,0 +1 @@ +{"id":"e5c04312-d6a0-439f-8c11-3a1fef7fbfa9","work_item_id":"work-work-issue-498-892fdd8e","kind":"pr","title":null,"intent":null,"summary":null,"progress_summary":null,"status_category":"active","owner":null,"next_action":null,"agent_session_id":"59a2fa97-8e6a-4559-996b-52a6865f473b","agent_id":null,"display_name":null,"board_entry_id":null,"execution_container":{"branch":"work/issue-498","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-498","pr_number":507,"pr_url":"https://github.com/akiojin/unity-cli/pull/507","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-13T12:05:09.340813Z"} diff --git a/.gwt/work/events/ec/ec83444727761f4cc622d5b16bf1cf72e8f7ef5afa1abf76c504de71f16d2741.jsonl b/.gwt/work/events/ec/ec83444727761f4cc622d5b16bf1cf72e8f7ef5afa1abf76c504de71f16d2741.jsonl new file mode 100644 index 00000000..48b7c0e3 --- /dev/null +++ b/.gwt/work/events/ec/ec83444727761f4cc622d5b16bf1cf72e8f7ef5afa1abf76c504de71f16d2741.jsonl @@ -0,0 +1 @@ +{"id":"40b4ea96-0c98-4512-a610-813fe95da3d5","work_item_id":"work-work-issue-511-ac1c61e3","kind":"update","title":null,"intent":"Rust / C# 間の正規 URI 相互運用","summary":null,"progress_summary":"C# Windows/Linux 108/108、coverage 99.66%、workflow 検査 PASS。実クライアント境界に同じ未エンコード/未デコードを発見し RED を確認。","status_category":null,"owner":"Issue #511","next_action":null,"agent_session_id":"d0aa10d9-7f81-4304-905c-47fc4ce7b80c","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-511","worktree_path":"E:\\unity-cli\\work\\issue-511","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T13:14:17.156690900Z"} diff --git a/.gwt/work/events/ee/eeb5d58edef74597116a67bb02a7d085199df22202724e9325546b959d6a0a24.jsonl b/.gwt/work/events/ee/eeb5d58edef74597116a67bb02a7d085199df22202724e9325546b959d6a0a24.jsonl new file mode 100644 index 00000000..5905b169 --- /dev/null +++ b/.gwt/work/events/ee/eeb5d58edef74597116a67bb02a7d085199df22202724e9325546b959d6a0a24.jsonl @@ -0,0 +1 @@ +{"id":"382dbfc9-2d5a-45d0-849c-04ea8004e8e0","work_item_id":"work-successor-7c2dfc5d2b5cce43936b35438f6127d998d532280cf12c1dd034899b09313645","kind":"done","title":null,"intent":"受け入れ基準を origin/develop で確認済み","summary":null,"progress_summary":"work/issue-516 は origin/develop (69ad5ab) と同一で、未配送のコミットはない。修正 d3359d6 (PR #517) は develop にマージ済みで、CI は全 green (LSP Write Reliability 3 OS を含む)。ローカルの dotnet test は 229 件すべて pass。3x3 改行マトリクスのテスト (NewlineMatrix) と文字列リテラル内 CR のテスト (ApplyNewlines_KeepsLoneCrInsideStringLiterals) があることを確認。AC-1〜3 はすべて満たしている。新しい PR は不要。Issue は手動で close せず、release PR で自動 close させる。","status_category":"done","owner":"Issue #516","next_action":null,"agent_session_id":"efd1f1c5-7a52-4d29-9970-e43f2e9a9519","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-516","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-516","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T01:45:03.057639Z"} diff --git a/.gwt/work/events/f0/f0e1940255e9fb0fd98a452397926a5f393ed3b321c6779953fe15a7466921f8.jsonl b/.gwt/work/events/f0/f0e1940255e9fb0fd98a452397926a5f393ed3b321c6779953fe15a7466921f8.jsonl new file mode 100644 index 00000000..5dfccce7 --- /dev/null +++ b/.gwt/work/events/f0/f0e1940255e9fb0fd98a452397926a5f393ed3b321c6779953fe15a7466921f8.jsonl @@ -0,0 +1 @@ +{"id":"fc57b9d5-1a72-4b71-af87-2c9399fb8f95","work_item_id":"work-work-issue-511-ac1c61e3","kind":"update","title":"Windows LSP の file URI 解決","intent":"Windows / Linux の往復と全件検証","summary":null,"progress_summary":"全 AC の変更前監査と RED を確認。共通 URI 変換、エンコード付き検索、Windows CI を実装。","status_category":null,"owner":"Issue #511","next_action":null,"agent_session_id":"d0aa10d9-7f81-4304-905c-47fc4ce7b80c","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-511","worktree_path":"E:\\unity-cli\\work\\issue-511","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T13:06:44.886302Z"} diff --git a/.gwt/work/events/f1/f14878cd3f200f95e5d73531596dc75b4a0cdb07727819bbb636dcd50911dd4b.jsonl b/.gwt/work/events/f1/f14878cd3f200f95e5d73531596dc75b4a0cdb07727819bbb636dcd50911dd4b.jsonl new file mode 100644 index 00000000..9d71ba3a --- /dev/null +++ b/.gwt/work/events/f1/f14878cd3f200f95e5d73531596dc75b4a0cdb07727819bbb636dcd50911dd4b.jsonl @@ -0,0 +1 @@ +{"id":"665fab9d-8bc2-4b2c-b1d2-b8a0be55a4ae","work_item_id":"work-work-issue-498-892fdd8e","kind":"resume","title":"fix(lsp): keep the original BOM and newlines when C# LSP write tools save a file","intent":"Check Board for latest updates","summary":"Claude Code is running","progress_summary":null,"status_category":"active","owner":"Issue #498","next_action":"Check Board for latest updates","agent_session_id":"e1d54ec9-5124-4889-9240-91f209dd091b","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-498","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-498","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T13:04:35.586129Z"} diff --git a/.gwt/work/events/f6/f63643df3e6f6ed1256f4c39c188267f332f994b79ee25d09d60ddbb45310c8f.jsonl b/.gwt/work/events/f6/f63643df3e6f6ed1256f4c39c188267f332f994b79ee25d09d60ddbb45310c8f.jsonl new file mode 100644 index 00000000..499b7dff --- /dev/null +++ b/.gwt/work/events/f6/f63643df3e6f6ed1256f4c39c188267f332f994b79ee25d09d60ddbb45310c8f.jsonl @@ -0,0 +1 @@ +{"id":"17033026-3813-4a43-a7d9-5667e4424725","work_item_id":"work-work-issue-520-2c5b16f7","kind":"resume","title":"fix(lsp): keep closed-string CRs in sibling branches hidden by an unterminated literal (#516 follow-up)","intent":"Codex started work on Issue #520 fix(lsp): keep closed-string CRs in sibling branches hidden by an unterminated literal (#516 follow-up) (work/issue-520)","summary":"2 active agents","progress_summary":null,"status_category":"active","owner":"Issue #520","next_action":"Check Board for latest updates","agent_session_id":"b2230ae6-4256-4a85-b63c-c8a3a6dd9132","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-520","worktree_path":"E:/unity-cli/work/issue-520","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-14T05:31:52.463721300Z"} diff --git a/.gwt/work/events/f8/f820fbe3d464e9214fe1e65994a7a8ef2101ff34d97e461542aadb981fe1ab4e.jsonl b/.gwt/work/events/f8/f820fbe3d464e9214fe1e65994a7a8ef2101ff34d97e461542aadb981fe1ab4e.jsonl new file mode 100644 index 00000000..e39fa0a9 --- /dev/null +++ b/.gwt/work/events/f8/f820fbe3d464e9214fe1e65994a7a8ef2101ff34d97e461542aadb981fe1ab4e.jsonl @@ -0,0 +1 @@ +{"id":"d46b3b1b-f8e0-4083-9865-97f14d1a347c","work_item_id":"work-work-issue-498-892fdd8e","kind":"resume","title":"fix(lsp): keep the original BOM and newlines when C# LSP write tools save a file","intent":"Check Board for latest updates","summary":"2 active agents","progress_summary":null,"status_category":"active","owner":"Issue #498","next_action":"Check Board for latest updates","agent_session_id":"09f6982f-e4aa-44e9-84f3-338e44faa7ff","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-498","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-498","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T12:05:35.433882Z"} diff --git a/.gwt/work/events/f8/f86f2649a47a5515cb101314be0ec192b7fc1b63f92e82466f433bdfe9305837.jsonl b/.gwt/work/events/f8/f86f2649a47a5515cb101314be0ec192b7fc1b63f92e82466f433bdfe9305837.jsonl new file mode 100644 index 00000000..b2a84903 --- /dev/null +++ b/.gwt/work/events/f8/f86f2649a47a5515cb101314be0ec192b7fc1b63f92e82466f433bdfe9305837.jsonl @@ -0,0 +1 @@ +{"id":"c40ccc57-c6f8-4afa-bb79-a07deec714ee","work_item_id":"work-work-issue-498-892fdd8e","kind":"update","title":"C# LSP 書き込み時の BOM/改行保持","intent":"PR #513 の CI 待ち","summary":null,"progress_summary":"#498 の AC-1 で残っていた UTF-32 BE BOM と CR 単独改行の保持を修正。42 件の RED を確認後、dotnet test は 192 件すべて pass。fmt と clippy も pass。Draft PR #513 を develop 向けに作成。","status_category":null,"owner":"Issue #498","next_action":null,"agent_session_id":"28641b50-7397-40b7-98fc-192f96e72d4a","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-498","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-498","pr_number":513,"pr_url":"https://github.com/akiojin/unity-cli/pull/513","pr_state":"OPEN"},"related_work_item_id":null,"updated_at":"2026-10-13T14:04:57.936134Z"} diff --git a/.gwt/work/events/fe/fe3e27ca8db2966e8db6bb98fbfe022696fd8cbd096903acb885d88316a61e7b.jsonl b/.gwt/work/events/fe/fe3e27ca8db2966e8db6bb98fbfe022696fd8cbd096903acb885d88316a61e7b.jsonl new file mode 100644 index 00000000..e2e58c59 --- /dev/null +++ b/.gwt/work/events/fe/fe3e27ca8db2966e8db6bb98fbfe022696fd8cbd096903acb885d88316a61e7b.jsonl @@ -0,0 +1 @@ +{"id":"4263ce85-9cce-4caa-9b2d-efacaf1916c2","work_item_id":"work-successor-3057df15a3a56389941d9d6badd9f07a06f89ea077e09b2b3f2f0e79a596ef6d","kind":"start","title":"fix(lsp): keep the original BOM and newlines when C# LSP write tools save a file","intent":"Check Board for latest updates","summary":"Claude Code is running","progress_summary":null,"status_category":"active","owner":"Issue #498","next_action":"Check Board for latest updates","agent_session_id":"f8a5d838-ed43-4759-8676-8ac572fdfb4c","agent_id":"claude","display_name":"Claude Code","board_entry_id":null,"execution_container":{"branch":"work/issue-498","worktree_path":"/Users/akiojin/Workbench/unity-cli/work/issue-498","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":"work-work-issue-498-892fdd8e","updated_at":"2026-10-13T14:09:24.085409Z"} diff --git a/.gwt/work/events/ff/ff71ead878a9d61af6335afed219025504a14533bec43fbd4be7f873f6471672.jsonl b/.gwt/work/events/ff/ff71ead878a9d61af6335afed219025504a14533bec43fbd4be7f873f6471672.jsonl new file mode 100644 index 00000000..1d2da904 --- /dev/null +++ b/.gwt/work/events/ff/ff71ead878a9d61af6335afed219025504a14533bec43fbd4be7f873f6471672.jsonl @@ -0,0 +1 @@ +{"id":"0d9ff232-beeb-4980-a698-8b8722a0b2dc","work_item_id":"work-work-issue-490-ce1c1f9a","kind":"update","title":"C# LSP 書き込み信頼性の測定","intent":"全 AC 監査済み、実 CLI 測定シナリオと CI を実装","summary":null,"progress_summary":"AC-1〜5 は未達。既存は個別/性能テストのみで、OS・起動条件別の成功率/編集差分レポートがない。関連検索で #490 が測定の owner、#488 は実装済み。","status_category":null,"owner":"Issue #490","next_action":null,"agent_session_id":"c0ac1284-51ea-49d8-82e3-da19507a6ba5","agent_id":"codex","display_name":"Codex","board_entry_id":null,"execution_container":{"branch":"work/issue-490","worktree_path":"E:\\unity-cli\\work\\issue-490","pr_number":null,"pr_url":null,"pr_state":null},"related_work_item_id":null,"updated_at":"2026-10-13T07:41:02.891169800Z"} diff --git a/CHANGELOG.md b/CHANGELOG.md index 77d77268..ce5d6e82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,113 @@ ## [Unreleased] +## [0.19.0] - 2026-10-19 + +### Breaking changes and migration + +- `create_class` now writes through the C# LSP write path (the same path as + `create_csharp_file`) instead of writing the file directly + ([#493](https://github.com/akiojin/unity-cli/pull/493)). With + `UNITY_CLI_LSP_MODE=off` it now fails with a "requires LSP" error and writes + nothing; in v0.18.1 it wrote the file silently. Arguments are unchanged, and + the output keeps `success` / `path` / `content` and adds the LSP result fields + (`applied`, `changedFiles`, `diagnostics`, `backend`). + Migration: remove `UNITY_CLI_LSP_MODE=off` (or set it to `auto` / + `required`) and install the LSP with `unity-cli lsp install`. Automation that + must run without the LSP should write the `.cs` file itself, then run + `unity-cli raw refresh_assets` and check `get_compilation_state`. + +### Features + +- *(lsp)* Make LSP the default backend for C# symbol search + (`get_symbols` / `find_symbol` / `find_refs` / `build_index`). An unset + `UNITY_CLI_LSP_MODE` now means `auto`: the LSP is used when available, and the + local index is used otherwise, with `backend: "index"` and a `fallbackReason` + (`lsp_not_installed`, `lsp_unavailable`, `lsp_timeout`, `lsp_disabled`). + `UNITY_CLI_LSP_AUTO_TIMEOUT_MS` (default 10000) sets the fallback timeout. A + missing LSP is installed in the background + ([#495](https://github.com/akiojin/unity-cli/pull/495)). +- *(scripts)* Add `scripts/install-from-source.sh` / `.ps1` to install a source + build as the managed binary ([#481](https://github.com/akiojin/unity-cli/pull/481)). +- *(skills)* Route C# script creation and compile-error fixes through the LSP + write tools, with a documented fallback when the LSP write path fails + ([#493](https://github.com/akiojin/unity-cli/pull/493), + [#496](https://github.com/akiojin/unity-cli/pull/496)). + +### 🐛 Bug Fixes + +- *(lsp)* Keep the original BOM (UTF-8, UTF-16 LE/BE, UTF-32 LE/BE) and newline + convention (LF, CRLF, lone CR) when the C# LSP write tools save a file + ([#507](https://github.com/akiojin/unity-cli/pull/507), + [#513](https://github.com/akiojin/unity-cli/pull/513)). +- *(lsp)* Normalize a lone CR in edits to the file's newline style in LF and + CRLF files, while keeping CRs that are part of string values, including in + inactive and malformed preprocessor branches + ([#517](https://github.com/akiojin/unity-cli/pull/517), + [#518](https://github.com/akiojin/unity-cli/pull/518), + [#519](https://github.com/akiojin/unity-cli/pull/519), + [#521](https://github.com/akiojin/unity-cli/pull/521)). +- *(lsp)* Keep trailing comments when `replace_symbol_body` replaces a method + body ([#503](https://github.com/akiojin/unity-cli/pull/503)). +- *(lsp)* Add `using UnityEngine;` to ScriptableObject classes from + `create_class` ([#502](https://github.com/akiojin/unity-cli/pull/502)). +- *(lsp)* Resolve canonical file URIs across Windows and Unix, so Assets symbol + search works with `file:///C:/...` roots + ([#512](https://github.com/akiojin/unity-cli/pull/512)). +- *(lsp)* Wait for a live auto-started lspd (up to + `UNITY_CLI_LSPD_START_TIMEOUT_MS`, default 60000) instead of failing after + 5 seconds, log lspd stderr to `lspd.log`, and bound Windows cold-start TCP + connection waits ([#505](https://github.com/akiojin/unity-cli/pull/505), + [#506](https://github.com/akiojin/unity-cli/pull/506)). +- *(update)* Keep the installed CLI on `unityd start` / `lspd` when + `UNITY_CLI_NO_AUTO_UPDATE=1` ([#479](https://github.com/akiojin/unity-cli/pull/479)). +- *(install)* Retry transient download errors in `install.sh` / `install.ps1` + ([#515](https://github.com/akiojin/unity-cli/pull/515)). +- *(windows)* Harden Editor launches, `\\?\` path handling, MCP profile + isolation, reference fetch and bake validation on Windows + ([#471](https://github.com/akiojin/unity-cli/pull/471)). + +### 🧪 Testing + +- *(lsp)* Measure C# write reliability on macOS, Linux and Windows + ([#497](https://github.com/akiojin/unity-cli/pull/497), + [#508](https://github.com/akiojin/unity-cli/pull/508), + [#510](https://github.com/akiojin/unity-cli/pull/510)). +- *(ci)* Check the published install on Windows, Wayland `grim` screenshots and + the global skills install ([#466](https://github.com/akiojin/unity-cli/pull/466)). + +### 📚 Documentation + +- *(readme)* Split install instructions into an LLM-agent prompt and a manual + path; the prompt also updates the CLI and the Unity bridge + ([#485](https://github.com/akiojin/unity-cli/pull/485), + [#489](https://github.com/akiojin/unity-cli/pull/489)). +- *(skills)* Document per-tool GameObject parameter names + ([#478](https://github.com/akiojin/unity-cli/pull/478)). + +### ⚙️ Miscellaneous Tasks + +- *(ci)* Auto-merge reviewed external PRs pinned to the labeled head SHA + ([#492](https://github.com/akiojin/unity-cli/pull/492)); make the Codecov + upload non-fatal ([#473](https://github.com/akiojin/unity-cli/pull/473)). +- *(deps)* Update cargo, npm and GitHub Actions dependencies, keeping bincode 1 + so existing embedding indexes still load, and move to zip 9 for reference + archive extraction + ([#467](https://github.com/akiojin/unity-cli/pull/467), + [#469](https://github.com/akiojin/unity-cli/pull/469), + [#476](https://github.com/akiojin/unity-cli/pull/476), + [#482](https://github.com/akiojin/unity-cli/pull/482), + [#483](https://github.com/akiojin/unity-cli/pull/483), + [#524](https://github.com/akiojin/unity-cli/pull/524), + [#526](https://github.com/akiojin/unity-cli/pull/526), for + [#525](https://github.com/akiojin/unity-cli/issues/525)). + +### Acknowledgements + +- Thanks to @arghhhhh for + [#478](https://github.com/akiojin/unity-cli/pull/478), + [#479](https://github.com/akiojin/unity-cli/pull/479) and + [#481](https://github.com/akiojin/unity-cli/pull/481). + ## [0.18.1] - 2026-10-03 ### 📦 Distribution diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3921fd35..c7b8f1d3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,6 +28,22 @@ docker build -t unity-cli-dev . docker run --rm unity-cli-dev ``` +### Running Your Build + +To test a change the way users run unity-cli (through `unityd` and your agent's +skills), install your checkout as the managed binary, where `scripts/install.sh` +and `scripts/install.ps1` put a release: + +```bash +./scripts/install-from-source.sh --skills claude-code # macOS / Linux +./scripts/install-from-source.ps1 -Skills claude-code # Windows +``` + +It builds a release binary, stops `unityd`, installs into +`~/.unity/tools/unity-cli//` and refreshes installed skills to the build. +Set `UNITY_CLI_NO_AUTO_UPDATE=1` while you run a source build, or the next +release's self-update replaces it. Run the release installer again to go back. + ## Validation Commands ```bash @@ -178,6 +194,23 @@ docker build -t unity-cli-dev . docker run --rm unity-cli-dev ``` +### 自分のビルドを使う + +ユーザーと同じ経路(`unityd` とエージェントの skill)で変更を確認するには、 +チェックアウトを managed バイナリとしてインストールします。配置先は +`scripts/install.sh` / `scripts/install.ps1` がリリースを置く場所と同じです。 + +```bash +./scripts/install-from-source.sh --skills claude-code # macOS / Linux +./scripts/install-from-source.ps1 -Skills claude-code # Windows +``` + +リリースビルドを作成し、`unityd` を停止して `~/.unity/tools/unity-cli//` +にインストールし、インストール済みの skill をビルドに合わせて更新します。 +ソースビルドを使う間は `UNITY_CLI_NO_AUTO_UPDATE=1` を設定してください。 +設定しないと次のリリースの自動更新で置き換わります。戻すときはリリース用 +インストーラーを再実行します。 + ## 検証コマンド ```bash diff --git a/Cargo.lock b/Cargo.lock index 5972bb11..f0d523b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -332,9 +332,12 @@ checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" [[package]] name = "constant_time_eq" -version = "0.4.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" +checksum = "9eb6feb175df65d0a3ccd3e73484e940d0ac664e8034f0519fd49a93db3071d9" +dependencies = [ + "rustversion", +] [[package]] name = "cookie" @@ -642,7 +645,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.52.0", ] [[package]] @@ -653,9 +656,9 @@ checksum = "d817e038c30374a4bcb22f94d0a8a0e216958d4c3dcde369b1439fec4bdda6e6" [[package]] name = "fastembed" -version = "6.1.0" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf2876a78b0fa3a9095baf8bbec83126b3c5b7eab8fc4e1e7ad9e68b14ed5c8a" +checksum = "ca64ada7d0ad74737f45609542930cd5813fcb453b3f72ecb4255d8bd6fe4604" dependencies = [ "hf-hub", "ndarray", @@ -1221,9 +1224,9 @@ checksum = "34b357333733e8260735ba5894eb928c02ecc69c78715f01a8019e7fa7f2db4c" [[package]] name = "libc" -version = "0.2.184" +version = "0.2.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" [[package]] name = "libloading" @@ -1283,9 +1286,9 @@ checksum = "e20f57f9918e5bd7bc58c22cdd70a6afc7375d4dd9683af5f2b34bd3d2bba619" [[package]] name = "lzma-rust2" -version = "0.16.5" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca93e534d1142d1d0dcca6d25fe302508a5dfb40b302802904577725ea0b695b" +checksum = "7277c9742229dc25243236d578b6471a798c554512c6f6a04365ec2e87c2a3bb" dependencies = [ "sha2", ] @@ -1412,6 +1415,18 @@ dependencies = [ "rawpointer", ] +[[package]] +name = "nix" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" +dependencies = [ + "bitflags", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "nom" version = "7.1.3" @@ -1939,7 +1954,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.60.2", + "windows-sys 0.52.0", ] [[package]] @@ -2082,9 +2097,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.151" +version = "1.0.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" dependencies = [ "itoa", "memchr", @@ -2128,9 +2143,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +checksum = "47d7069beb7d6ac7b9acd1039986e73443f24234f41074da099d6f994ac9ad19" dependencies = [ "cfg-if", "cpufeatures", @@ -2181,9 +2196,9 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", "windows-sys 0.60.2", @@ -2288,7 +2303,7 @@ dependencies = [ "getrandom 0.4.1", "once_cell", "rustix", - "windows-sys 0.60.2", + "windows-sys 0.52.0", ] [[package]] @@ -2412,9 +2427,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.53.1" +version = "1.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" +checksum = "ce3335fa71841cda333a58d7615b03901380ecf09d59b3296d21f8bbac0dde4e" dependencies = [ "bytes", "libc", @@ -2461,18 +2476,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "1.1.1+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +checksum = "2b86d767906c6c42421dcba507eb9d203e779497710a47782a224bb871653053" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.25.15+spec-1.1.0" +version = "0.25.17+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1340ea94a5856333492c9064b02c778b191dd2c853778d9609debdcdfea3a614" +checksum = "e3641d5bbb5349a79e1020a242d251efbc546ad8048d133958323ce9c40a9c9c" dependencies = [ "indexmap", "toml_datetime", @@ -2483,18 +2498,18 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.1.3+spec-1.1.0" +version = "1.1.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" +checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" dependencies = [ "winnow", ] [[package]] name = "toml_writer" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" +checksum = "06bdbd8cfc056b8d2e2e85f29b56a3bdbecb527cef81eb39e3e7b98af4652770" [[package]] name = "tower" @@ -2667,9 +2682,10 @@ checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3" [[package]] name = "unity-cli" -version = "0.18.1" +version = "0.19.0" dependencies = [ "anyhow", + "base64 0.23.1", "bincode", "clap", "dirs 7.0.0", @@ -2689,6 +2705,7 @@ dependencies = [ "tracing", "tracing-subscriber", "ureq", + "url", "walkdir", "zip", ] @@ -2988,7 +3005,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.52.0", ] [[package]] @@ -3367,9 +3384,9 @@ dependencies = [ [[package]] name = "zip" -version = "8.6.0" +version = "9.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d04a6b5381502aa6087c94c669499eb1602eb9c5e8198e534de571f7154809b" +checksum = "6e04976da629d3b04204ba8105b396a193af8ad2583b2c79bfb3ab8af580a11e" dependencies = [ "aes", "bzip2", @@ -3380,8 +3397,9 @@ dependencies = [ "getrandom 0.4.1", "hmac", "indexmap", - "lzma-rust2 0.16.5", + "lzma-rust2 0.22.0", "memchr", + "nix", "pbkdf2", "ppmd-rust", "sha1", @@ -3418,27 +3436,27 @@ dependencies = [ [[package]] name = "zstd" -version = "0.13.3" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +checksum = "db3ae9bf90af6e40197bef767eeefc46ad6397420fe873830bd85e5fbbfb3c70" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.2.4" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +checksum = "ded520f16b29e1a9b771c722221b2b0a0398c2316d9bb3c42b458a5414d7434b" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.16+zstd.1.5.7" +version = "2.1.2+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" +checksum = "481ada9c543b2323cbb7bbdbb5249177fbf0188ed959ed2c15e4b22421c84ed3" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index edbfb2cb..cad5cc7d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "unity-cli" -version = "0.18.1" +version = "0.19.0" edition = "2021" description = "Rust CLI for Unity Editor automation over the Unity TCP protocol" readme = "README.md" @@ -12,6 +12,7 @@ keywords = ["unity", "cli", "automation", "editor"] categories = ["command-line-utilities", "development-tools"] include = [ "/src/**", + "/tests/fixtures/reference-embedding/*.bin", "/build.rs", "/.claude-plugin/plugins/unity-cli/skills/**", "/Cargo.toml", @@ -26,6 +27,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" +base64 = "0.23" clap = { version = "4.6", features = ["derive"] } dirs = "7.0" serde = { version = "1.0", features = ["derive"] } @@ -39,21 +41,22 @@ regex = "1.12" walkdir = "2.5" sha2 = "0.11" ureq = { version = "3.3", features = ["json"] } +url = "2.5" serde_yml = "0.0.13" similar = "3" tempfile = "3.27" socket2 = "0.6" -zip = "8" +zip = "9" # bincode 3.0.0 intentionally compile_error!s; retain the existing index format (#342). bincode = "=1.3.3" # ONNX Runtime ships no prebuilt binaries for Intel macOS, so that target loads # libonnxruntime dynamically at runtime (ORT_DYLIB_PATH / Homebrew onnxruntime). [target.'cfg(not(all(target_os = "macos", target_arch = "x86_64")))'.dependencies] -fastembed = { version = "6", default-features = false, features = ["hf-hub-rustls-tls", "ort-download-binaries"] } +fastembed = { version = "7", default-features = false, features = ["hf-hub-rustls-tls", "ort-download-binaries"] } [target.'cfg(all(target_os = "macos", target_arch = "x86_64"))'.dependencies] -fastembed = { version = "6", default-features = false, features = ["hf-hub-rustls-tls", "ort-load-dynamic"] } +fastembed = { version = "7", default-features = false, features = ["hf-hub-rustls-tls", "ort-load-dynamic"] } [target.'cfg(unix)'.dependencies] libc = "0.2" diff --git a/README.de.md b/README.de.md index bb2dd0cd..315d9b48 100644 --- a/README.de.md +++ b/README.de.md @@ -24,24 +24,128 @@ Einige Code Tools (`read`, `search`, `find_symbol`, `find_refs` usw.) laufen lok ## Einstieg -### Empfohlen: Claude Code Plugin +### Editor Kompatibilitat -Installieren Sie das `unity-cli` Plugin aus dem Claude Code Marketplace: +Die Bridge benotigt Unity 2022.3 oder neuer. Die macOS Matrix umfasst +2022.3.62f3, 6000.0.84f1, 6000.3.25f1, 6000.4.11f1, 6000.5.3f1, +6000.6.3f1, 6000.7.0a2 und 6000.7.0b2 (Abnahme E2E: PASS am 2026-09-30). Prufen Sie die +[Testdaten und Ergebnisse](docs/editor-compatibility.md), bevor Sie eine Version wahlen. +Der Unity 6000.7 Editor lauft auf Mono; CoreCLR Player Builds sind nicht Teil dieser Matrix. + +### Installation oder Aktualisierung mit einem LLM Agenten + +Kopieren Sie diesen Prompt in Claude Code, Codex oder einen anderen Coding Agenten, +der in Ihrem Unity Projekt geoffnet ist. Fuhren Sie denselben Prompt spater erneut aus, +um CLI und Unity Bridge Paket gemeinsam zu aktualisieren: + +```text +Installiere oder aktualisiere unity-cli fur dieses Unity Projekt, halte das Unity Bridge +Paket auf derselben Version wie die CLI und verbinde es mit dem Unity Editor. + +1. Erkenne mein Betriebssystem (macOS, Linux oder Windows). +2. Wenn `unity-cli` noch nicht im PATH ist, fuhre das offizielle Quick Install Skript aus: + - macOS / Linux: curl -fsSL https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.sh | sh + - Windows (PowerShell): irm https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.ps1 | iex +3. Wenn `unity-cli` bereits im PATH ist, aktualisiere es stattdessen auf das neueste Release. + Wenn UNITY_CLI_NO_AUTO_UPDATE=1 oder UNITY_CLI_VERSION gesetzt ist, habe ich die Version + absichtlich fixiert: aktualisiere nicht, sag es mir und frage zuerst. Andernfalls ermittle, + wo die Binardatei tatsachlich liegt (Symlinks folgen), und aktualisiere sie auf dem Weg, + auf dem sie installiert wurde: + - Quick Install (verwaltete Kopie unter ~/.unity/tools): unity-cli cli install + - Homebrew: brew upgrade akiojin/tap/unity-cli + - winget: winget upgrade akiojin.unity-cli + - Alles andere (cargo install, manueller Download): sag mir, wie es installiert wurde, + und frage, bevor du etwas anderst. +4. Prufe, dass `unity-cli --version` uber den PATH funktioniert. Wenn es unter macOS / Linux + nicht gefunden wird, fuge ~/.local/bin fur diese Shell zum PATH hinzu und nenne mir die + Zeile fur mein Shell Profil. Unter Windows offne eine neue Shell, damit der aktualisierte + Benutzer PATH gilt. +5. Bevor du mein Projekt anderst, sage mir, dass setup Packages/manifest.json bearbeitet + (fugt die OpenUPM Scoped Registry und com.akiojin.unity-cli-bridge in der CLI Version hinzu) + und bei Projekten nur mit dem alten Input Manager activeInputHandler in + ProjectSettings/ProjectSettings.asset auf Both setzt. Warte auf meine Bestatigung. +6. Fuhre im Unity Projektstamm aus: unity-cli --output json setup --launch-editor + Wenn das JSON ok: false enthalt, folge editor.hint (der erste Import kann einige + Minuten dauern; fuhre setup erneut aus, um weiter zu warten). +7. Prufe die Bridge Version mit: unity-cli --output json bridge status + - Wenn source registry ist und versionCheck.status (hier oder im setup Bericht) mismatch ist: + sag mir, dass dies die Zeile com.akiojin.unity-cli-bridge in Packages/manifest.json auf + die CLI Version andert, und warte auf meine Bestatigung. Fuhre dann unity-cli bridge upgrade + aus und lass den Unity Editor das Paket neu importieren. + - Wenn source custom oder embedded ist (Git URL, lokaler Pfad oder eine Kopie unter + Packages/) oder versionCheck.status unknown ist: nicht umschreiben. Melde mir stattdessen + source und beide Versionen. +8. Prufe die Verbindung mit: unity-cli system ping + Bestatige, dass versionCheck.status match ist (CLI und Bridge haben dieselbe Version). +9. Wenn ein Schritt fehlschlagt, fuhre aus: unity-cli doctor --output json + Melde den diagnosis Code und folge dessen Hinweis, bevor du es erneut versuchst. +``` + +**Claude Code Plugin**: Installieren Sie das `unity-cli` Plugin aus dem Claude Code +Marketplace, damit der Agent die Unity Workflow Skills nutzen kann: ```bash /plugin marketplace add akiojin/unity-cli ``` -Das Marketplace Plugin installiert nur Skills. Installieren Sie das -`unity-cli` Binary separat mit einer der manuellen Optionen unten. - -### Codex Skills +Das Plugin liefert Skills; Binary und Unity Bridge werden bei Bedarf eingerichtet. +Wenn eine Aufgabe Unity benotigt und `unity-cli` fehlt, lasst der Skill +`unity-cli-usage` den Agenten das Quick Install Skript und danach `unity-cli setup` +in Ihrem Unity Projekt ausfuhren (er informiert Sie, bevor `Packages/manifest.json` +geandert wird). -Wenn Sie dieses Repository mit Codex verwenden, sind Skills uber `.codex/skills/` verfugbar (Symlinks zur Plugin Quelle). +**Codex Skills**: Wenn Sie dieses Repository mit Codex verwenden, sind Skills uber +`.agents/skills/` verfugbar (Symlinks zur Plugin Quelle, auch uber `.claude/skills/`). Es ist keine zusatzliche Einrichtung erforderlich — klonen Sie einfach das Repository. ### Manuelle Installation +#### Quick Install (empfohlen) + +macOS (Apple silicon / Intel) und Linux: + +```bash +curl -fsSL https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.sh | sh +``` + +Windows (PowerShell): + +```powershell +irm https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.ps1 | iex +``` + +Beide Installer laden das Release Binary in das verwaltete Layout +`~/.unity/tools/unity-cli/{rid}/` und prufen es vor der Installation gegen die +Release `SHA256SUMS`; bei abweichender Prufsumme wird die Installation abgebrochen und +das vorhandene Binary bleibt unverandert. `install.sh` legt einen Symlink unter +`~/.local/bin/unity-cli` an; `install.ps1` fugt das verwaltete Verzeichnis zum Benutzer +`PATH` hinzu. Mit `UNITY_CLI_VERSION=v0.16.0` fixieren Sie ein Release. Nach der +Erstinstallation pruft die CLI im Hintergrund automatisch auf Updates, und jedes Update +wird gegen dieselben Prufsummen verifiziert. + +Wenn `~/.local/bin` nicht im PATH ist, fugen Sie Folgendes zu Ihrem Shell Profil hinzu +(z. B. `~/.zshrc` oder `~/.bashrc`): + +```bash +export PATH="$HOME/.local/bin:$PATH" +``` + +Setzen Sie `UNITY_CLI_NO_AUTO_UPDATE=1`, um Auto Updates zu deaktivieren. + +#### Paketmanager + +```bash +brew install akiojin/tap/unity-cli # macOS / Linux (Homebrew) +winget install akiojin.unity-cli # Windows (winget) +``` + +Installationen uber Paketmanager werden mit `brew upgrade` / `winget upgrade` aktualisiert. +Unter Intel macOS laden Reference Embeddings (`unity-cli reference embed-build` / `embed-search`) ONNX Runtime +dynamisch; die Homebrew Formula installiert `onnxruntime`, andernfalls fuhren Sie +`brew install onnxruntime` aus oder setzen `ORT_DYLIB_PATH`. + +#### Releases oder cargo install + Laden Sie das neueste Binary von [GitHub Releases](https://github.com/akiojin/unity-cli/releases) herunter oder installieren Sie es aus einem lokalen Checkout: @@ -52,9 +156,28 @@ cd unity-cli cargo install --path . ``` -Bridge Paket auf Unity Seite (eine Option wahlen): +#### Projekt Einrichtung -**OpenUPM** (empfohlen): +Projekt Einrichtung mit einem Befehl (Binary Prufung → Bridge Installation → Editor Verbindung): + +```bash +cd /path/to/YourUnityProject +unity-cli --output json setup --launch-editor +``` + +`setup` fugt die OpenUPM Scoped Registry und `com.akiojin.unity-cli-bridge` +(auf die CLI Version fixiert) zu `Packages/manifest.json` hinzu, startet optional den +Unity Hub Editor des Projekts, wartet auf die Bridge und gibt einen JSON Bericht zuruck. +`unity-cli bridge install | upgrade | status` verwalten das Paket einzeln; `install` ist +idempotent, und `setup` / `system ping` melden einen `versionCheck`, wenn sich CLI und +Bridge Version unterscheiden. Nutzt das Projekt nur den alten Input Manager und ist der +Editor geschlossen, setzt `install` zusatzlich `activeInputHandler` in +`ProjectSettings/ProjectSettings.asset` auf Both, damit die Input System Abhangigkeit +ohne blockierenden Neustart Dialog importiert wird. + +Bridge Paket auf Unity Seite, manuelle Alternativen (eine Option wahlen): + +**OpenUPM**: ```bash openupm add com.akiojin.unity-cli-bridge @@ -66,12 +189,23 @@ openupm add com.akiojin.unity-cli-bridge https://github.com/akiojin/unity-cli.git?path=UnityCliBridge/Packages/unity-cli-bridge ``` -Verbindungstest: +#### Verbindungstest ```bash unity-cli system ping +unity-cli doctor --output json # wenn ping fehlschlagt: SAFE_MODE / BRIDGE_NOT_INSTALLED / PORT_IN_USE / ... ``` +#### Wartung des verwalteten Binary + +```bash +unity-cli cli doctor +unity-cli cli install +``` + +`unityd` und `lspd` aktualisieren ihre verwalteten `unity-cli` / C# LSP Binaries beim Daemon Start automatisch. +Die verwalteten Kopien liegen unter `UNITY_CLI_TOOLS_ROOT` (oder dem OS Standard Tools Verzeichnis) und werden ohne interaktive Bestatigung aktualisiert. + ## Skills (13) | Kategorie | Skills | @@ -110,7 +244,8 @@ unity-cli tool call run_tests --json '{"mode":"editmode"}' | `UNITY_CLI_HOST` | Unity Editor Host | `localhost` | | `UNITY_CLI_PORT` | Unity Editor Port | `6400` | | `UNITY_CLI_TIMEOUT_MS` | Command Timeout (ms) | `30000` | -| `UNITY_CLI_LSP_MODE` | LSP Modus (`off` / `auto` / `required`) | `off` | +| `UNITY_CLI_LSP_MODE` | LSP Modus (`off` / `auto` / `required`). `auto` bevorzugt den C# LSP fur die Symbolsuche und fallt auf den lokalen Index zuruck (`backend: "index"`, `fallbackReason`) | `auto` | +| `UNITY_CLI_LSP_AUTO_TIMEOUT_MS` | Obergrenze (ms), wie lange eine `auto` Symbolsuche auf den LSP wartet, bevor sie auf den lokalen Index zuruckfallt | `10000` | | `UNITY_CLI_TOOLS_ROOT` | Root Verzeichnis fur heruntergeladene Tools | OS default | Legacy MCP Umgebungsvariablen werden nicht unterstutzt. Nutzen Sie nur `UNITY_CLI_*`. diff --git a/README.es.md b/README.es.md index 775e9429..e9a66b67 100644 --- a/README.es.md +++ b/README.es.md @@ -24,27 +24,127 @@ Algunas herramientas de codigo (`read`, `search`, `find_symbol`, `find_refs`, et ## Inicio rapido -### Recomendado: plugin de Claude Code +### Compatibilidad del Editor -Instala el plugin `unity-cli` desde Claude Code Marketplace: +El Bridge requiere Unity 2022.3 o posterior. La matriz de macOS cubre +2022.3.62f3, 6000.0.84f1, 6000.3.25f1, 6000.4.11f1, 6000.5.3f1, +6000.6.3f1, 6000.7.0a2 y 6000.7.0b2 (E2E de aceptacion: PASS el 2026-09-30). Consulte las +[fechas y resultados de verificacion](docs/editor-compatibility.md) antes de elegir una version. +El Editor de Unity 6000.7 se ejecuta sobre Mono; los builds de Player con CoreCLR quedan fuera de esta matriz. + +### Instalar o actualizar con un agente LLM + +Copie este prompt en Claude Code, Codex u otro agente de programacion abierto en +su proyecto de Unity. Ejecute el mismo prompt mas adelante para actualizar juntos el CLI +y el paquete bridge de Unity: + +```text +Instala o actualiza unity-cli para este proyecto de Unity, manten el paquete bridge de +Unity en la misma version que el CLI y conectalo al Unity Editor. + +1. Detecta mi sistema operativo (macOS, Linux o Windows). +2. Si `unity-cli` todavia no esta en el PATH, ejecuta el script oficial de Quick Install: + - macOS / Linux: curl -fsSL https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.sh | sh + - Windows (PowerShell): irm https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.ps1 | iex +3. Si `unity-cli` ya esta en el PATH, actualizalo a la ultima version en su lugar. + Si UNITY_CLI_NO_AUTO_UPDATE=1 o UNITY_CLI_VERSION estan definidos, fije la version a + proposito: no lo actualices; dimelo y preguntame primero. En otro caso, averigua donde esta + realmente el binario (siguiendo enlaces simbolicos) y actualizalo segun como se instalo: + - Quick Install (copia gestionada en ~/.unity/tools): unity-cli cli install + - Homebrew: brew upgrade akiojin/tap/unity-cli + - winget: winget upgrade akiojin.unity-cli + - Cualquier otro caso (cargo install, descarga manual): dime como se instalo y + preguntame antes de cambiarlo. +4. Comprueba que `unity-cli --version` funciona desde el PATH. En macOS / Linux, si no se + encuentra, agrega ~/.local/bin al PATH de esta shell y dime la linea que debo agregar a + mi perfil de shell. En Windows, abre una shell nueva para aplicar el PATH de usuario actualizado. +5. Antes de modificar mi proyecto, dime que setup edita Packages/manifest.json (agrega el + scoped registry de OpenUPM y com.akiojin.unity-cli-bridge fijado a la version del CLI) y, + en proyectos que solo usan el Input Manager antiguo, establece activeInputHandler en Both + en ProjectSettings/ProjectSettings.asset. Espera mi confirmacion. +6. Desde la raiz del proyecto de Unity, ejecuta: unity-cli --output json setup --launch-editor + Si el JSON tiene ok: false, sigue editor.hint (la primera importacion puede tardar + varios minutos; vuelve a ejecutar setup para seguir esperando). +7. Comprueba la version del bridge con: unity-cli --output json bridge status + - Si source es registry y versionCheck.status (aqui o en el informe de setup) es mismatch: + dime que esto cambia la linea com.akiojin.unity-cli-bridge de Packages/manifest.json a la + version del CLI y espera mi confirmacion. Luego ejecuta unity-cli bridge upgrade y deja + que el Unity Editor vuelva a importar el paquete. + - Si source es custom o embedded (URL de Git, ruta local o una copia en Packages/), o + versionCheck.status es unknown: no lo reescribas. En su lugar, informame del source y + de ambas versiones. +8. Verifica la conexion con: unity-cli system ping + Confirma que versionCheck.status es match (el CLI y el bridge usan la misma version). +9. Si algun paso falla, ejecuta: unity-cli doctor --output json + Informa el codigo diagnosis y sigue su indicacion antes de reintentar. +``` + +**Plugin de Claude Code**: instale el plugin `unity-cli` desde Claude Code +Marketplace para que el agente pueda usar los skills de flujos de trabajo de Unity: ```bash /plugin marketplace add akiojin/unity-cli ``` -El plugin del Marketplace instala solo los skills. Instala el binario -`unity-cli` por separado con una de las opciones manuales de abajo. - -### Codex Skills +El plugin incluye skills; el binario y el bridge de Unity se preparan cuando hacen falta. +Cuando una tarea necesita Unity y falta `unity-cli`, el skill `unity-cli-usage` hace que +el agente ejecute el script de Quick Install y luego `unity-cli setup` en su proyecto de +Unity (le avisa antes de editar `Packages/manifest.json`). -Al usar este repositorio con Codex, los skills estan disponibles a traves de `.codex/skills/` (enlaces simbolicos a la fuente del plugin). -No se requiere configuracion adicional — solo clona el repositorio. +**Codex Skills**: si usa este repositorio con Codex, los skills estan disponibles en +`.agents/skills/` (symlinks a la fuente del plugin, tambien expuestos en `.claude/skills/`). +No requiere configuracion adicional — solo clone el repositorio. ### Instalacion manual -Descarga el binario mas reciente desde [GitHub -Releases](https://github.com/akiojin/unity-cli/releases), o instalalo desde -un clon local: +#### Quick Install (recomendado) + +macOS (Apple silicon / Intel) y Linux: + +```bash +curl -fsSL https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.sh | sh +``` + +Windows (PowerShell): + +```powershell +irm https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.ps1 | iex +``` + +Ambos instaladores descargan el binario de la release en la estructura administrada +`~/.unity/tools/unity-cli/{rid}/` y lo verifican con los `SHA256SUMS` de la release antes +de instalar; si la suma de comprobacion no coincide, la instalacion se cancela y el binario +existente no se toca. `install.sh` crea un symlink en `~/.local/bin/unity-cli`; +`install.ps1` agrega el directorio administrado al `PATH` del usuario. Defina +`UNITY_CLI_VERSION=v0.16.0` para fijar una release. Tras la instalacion inicial, el CLI +busca actualizaciones automaticamente en segundo plano, y cada actualizacion se verifica +con las mismas sumas de comprobacion. + +Si `~/.local/bin` no esta en su PATH, agregue lo siguiente a su perfil de shell +(por ejemplo `~/.zshrc` o `~/.bashrc`): + +```bash +export PATH="$HOME/.local/bin:$PATH" +``` + +Defina `UNITY_CLI_NO_AUTO_UPDATE=1` para desactivar la actualizacion automatica. + +#### Gestores de paquetes + +```bash +brew install akiojin/tap/unity-cli # macOS / Linux (Homebrew) +winget install akiojin.unity-cli # Windows (winget) +``` + +Las instalaciones con gestores de paquetes se actualizan con `brew upgrade` / `winget upgrade`. +En macOS Intel, los embeddings de reference (`unity-cli reference embed-build` / `embed-search`) cargan ONNX Runtime +de forma dinamica; la formula de Homebrew instala `onnxruntime`; en otro caso ejecute +`brew install onnxruntime` o defina `ORT_DYLIB_PATH`. + +#### Releases o cargo install + +Descargue el binario mas reciente desde [GitHub +Releases](https://github.com/akiojin/unity-cli/releases) o instale desde un checkout local: ```bash git clone https://github.com/akiojin/unity-cli.git @@ -52,9 +152,28 @@ cd unity-cli cargo install --path . ``` -Paquete bridge para Unity (elige una opcion): +#### Configuracion del proyecto -**OpenUPM** (recomendado): +Configuracion del proyecto en un solo comando (comprobacion del binario → instalacion del bridge → conexion con el Editor): + +```bash +cd /path/to/YourUnityProject +unity-cli --output json setup --launch-editor +``` + +`setup` agrega el scoped registry de OpenUPM y `com.akiojin.unity-cli-bridge` +(fijado a la version del CLI) a `Packages/manifest.json`, opcionalmente inicia el Editor +de Unity Hub del proyecto, espera al bridge y devuelve un informe JSON. +`unity-cli bridge install | upgrade | status` administran el paquete por separado; +`install` es idempotente, y `setup` / `system ping` informan un `versionCheck` cuando las +versiones del CLI y del bridge difieren. Si el proyecto aun usa solo el Input Manager +antiguo y el Editor esta cerrado, `install` tambien establece `activeInputHandler` en Both +en `ProjectSettings/ProjectSettings.asset`, para que la dependencia de Input System se +importe sin un aviso de reinicio bloqueante. + +Paquete bridge del lado de Unity, alternativas manuales (elija una): + +**OpenUPM**: ```bash openupm add com.akiojin.unity-cli-bridge @@ -66,12 +185,23 @@ openupm add com.akiojin.unity-cli-bridge https://github.com/akiojin/unity-cli.git?path=UnityCliBridge/Packages/unity-cli-bridge ``` -Comprobacion de conexion: +#### Comprobacion de conexion ```bash unity-cli system ping +unity-cli doctor --output json # si ping falla: SAFE_MODE / BRIDGE_NOT_INSTALLED / PORT_IN_USE / ... ``` +#### Mantenimiento del binario administrado + +```bash +unity-cli cli doctor +unity-cli cli install +``` + +`unityd` y `lspd` actualizan automaticamente sus binarios administrados de `unity-cli` / C# LSP al iniciar el daemon. +Las copias administradas residen en `UNITY_CLI_TOOLS_ROOT` (o en el directorio de tools predeterminado del SO) y se actualizan sin confirmacion interactiva. + ## Skills (13) | Categoria | Skills | @@ -110,7 +240,8 @@ unity-cli tool call run_tests --json '{"mode":"editmode"}' | `UNITY_CLI_HOST` | Host de Unity Editor | `localhost` | | `UNITY_CLI_PORT` | Puerto de Unity Editor | `6400` | | `UNITY_CLI_TIMEOUT_MS` | Timeout del comando (ms) | `30000` | -| `UNITY_CLI_LSP_MODE` | Modo LSP (`off` / `auto` / `required`) | `off` | +| `UNITY_CLI_LSP_MODE` | Modo LSP (`off` / `auto` / `required`). `auto` prefiere el LSP de C# para buscar simbolos y vuelve al indice local (`backend: "index"`, `fallbackReason`) | `auto` | +| `UNITY_CLI_LSP_AUTO_TIMEOUT_MS` | Limite (ms) que una busqueda de simbolos en `auto` espera al LSP antes de volver al indice local | `10000` | | `UNITY_CLI_TOOLS_ROOT` | Directorio raiz de herramientas descargadas | OS default | No se admiten variables legacy con prefijo MCP. Usa solo `UNITY_CLI_*`. diff --git a/README.fr.md b/README.fr.md index 55203395..704b7ec0 100644 --- a/README.fr.md +++ b/README.fr.md @@ -24,27 +24,128 @@ Certains outils code (`read`, `search`, `find_symbol`, `find_refs`, etc.) s exec ## Demarrage -### Recommande: plugin Claude Code +### Compatibilite de l'Editor -Installez le plugin `unity-cli` depuis la Marketplace de Claude Code: +Le Bridge requiert Unity 2022.3 ou plus recent. La matrice macOS couvre +2022.3.62f3, 6000.0.84f1, 6000.3.25f1, 6000.4.11f1, 6000.5.3f1, +6000.6.3f1, 6000.7.0a2 et 6000.7.0b2 (E2E d'acceptation: PASS le 2026-09-30). Consultez les +[dates et resultats de verification](docs/editor-compatibility.md) avant de choisir une version. +L'Editor Unity 6000.7 s'execute sur Mono; les builds Player CoreCLR sont hors de cette matrice. + +### Installer ou mettre a jour avec un agent LLM + +Copiez ce prompt dans Claude Code, Codex ou un autre agent de code ouvert dans +votre projet Unity. Relancez le meme prompt plus tard pour mettre a jour ensemble le CLI +et le package bridge Unity: + +```text +Installe ou mets a jour unity-cli pour ce projet Unity, garde le package bridge Unity a la +meme version que le CLI et connecte-le au Unity Editor. + +1. Detecte mon systeme d'exploitation (macOS, Linux ou Windows). +2. Si `unity-cli` n'est pas encore dans le PATH, execute le script officiel de Quick Install: + - macOS / Linux: curl -fsSL https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.sh | sh + - Windows (PowerShell): irm https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.ps1 | iex +3. Si `unity-cli` est deja dans le PATH, mets-le plutot a jour vers la derniere version. + Si UNITY_CLI_NO_AUTO_UPDATE=1 ou UNITY_CLI_VERSION est defini, j'ai fixe la version + volontairement: ne le mets pas a jour; previens-moi et demande d'abord. Sinon, determine + ou se trouve reellement le binaire (en suivant les liens symboliques) et mets-le a jour + selon sa methode d'installation: + - Quick Install (copie geree sous ~/.unity/tools): unity-cli cli install + - Homebrew: brew upgrade akiojin/tap/unity-cli + - winget: winget upgrade akiojin.unity-cli + - Tout autre cas (cargo install, telechargement manuel): dis-moi comment il a ete + installe et demande avant de le modifier. +4. Verifie que `unity-cli --version` fonctionne depuis le PATH. Sous macOS / Linux, s'il est + introuvable, ajoute ~/.local/bin au PATH de ce shell et indique-moi la ligne a ajouter a + mon profil de shell. Sous Windows, ouvre un nouveau shell pour appliquer le PATH utilisateur mis a jour. +5. Avant de modifier mon projet, dis-moi que setup modifie Packages/manifest.json (ajoute le + scoped registry OpenUPM et com.akiojin.unity-cli-bridge fixe a la version du CLI) et, pour + les projets qui n'utilisent que l'ancien Input Manager, met activeInputHandler a Both dans + ProjectSettings/ProjectSettings.asset. Attends ma confirmation. +6. A la racine du projet Unity, execute: unity-cli --output json setup --launch-editor + Si le JSON contient ok: false, suis editor.hint (le premier import peut prendre + plusieurs minutes; relance setup pour continuer a attendre). +7. Verifie la version du bridge avec: unity-cli --output json bridge status + - Si source vaut registry et que versionCheck.status (ici ou dans le rapport de setup) vaut + mismatch: dis-moi que cela remplace la ligne com.akiojin.unity-cli-bridge de + Packages/manifest.json par la version du CLI et attends ma confirmation. Execute ensuite + unity-cli bridge upgrade et laisse le Unity Editor reimporter le package. + - Si source vaut custom ou embedded (URL Git, chemin local ou copie sous Packages/), ou si + versionCheck.status vaut unknown: ne le reecris pas. Indique-moi plutot le source et + les deux versions. +8. Verifie la connexion avec: unity-cli system ping + Confirme que versionCheck.status vaut match (le CLI et le bridge ont la meme version). +9. Si une etape echoue, execute: unity-cli doctor --output json + Indique le code diagnosis et suis son conseil avant de reessayer. +``` + +**Plugin Claude Code**: installez le plugin `unity-cli` depuis Claude Code +Marketplace pour que l'agent puisse utiliser les skills de workflow Unity: ```bash /plugin marketplace add akiojin/unity-cli ``` -Le plugin Marketplace installe uniquement les skills. Installez le binaire -`unity-cli` separement avec l une des options manuelles ci-dessous. - -### Codex Skills +Le plugin fournit les skills; le binaire et le bridge Unity sont installes a la demande. +Quand une tache necessite Unity et que `unity-cli` manque, le skill `unity-cli-usage` fait +executer par l'agent le script de Quick Install puis `unity-cli setup` dans votre projet +Unity (il vous previent avant de modifier `Packages/manifest.json`). -Lorsque vous utilisez ce depot avec Codex, les skills sont disponibles via `.codex/skills/` (liens symboliques vers la source du plugin). -Aucune configuration supplementaire n est necessaire — il suffit de cloner le depot. +**Codex Skills**: si vous utilisez ce depot avec Codex, les skills sont disponibles via +`.agents/skills/` (liens symboliques vers la source du plugin, aussi exposes via +`.claude/skills/`). Aucune configuration supplementaire n'est requise — clonez simplement le depot. ### Installation manuelle +#### Quick Install (recommande) + +macOS (Apple silicon / Intel) et Linux: + +```bash +curl -fsSL https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.sh | sh +``` + +Windows (PowerShell): + +```powershell +irm https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.ps1 | iex +``` + +Les deux installeurs telechargent le binaire de la release dans l'arborescence geree +`~/.unity/tools/unity-cli/{rid}/` et le verifient avec les `SHA256SUMS` de la release avant +l'installation; en cas de somme de controle differente, l'installation est annulee et le +binaire existant reste intact. `install.sh` cree un lien symbolique `~/.local/bin/unity-cli`; +`install.ps1` ajoute le repertoire gere au `PATH` utilisateur. Definissez +`UNITY_CLI_VERSION=v0.16.0` pour fixer une release. Apres l'installation initiale, le CLI +verifie automatiquement les mises a jour en arriere-plan, et chaque mise a jour est +verifiee avec les memes sommes de controle. + +Si `~/.local/bin` n'est pas dans votre PATH, ajoutez ceci a votre profil de shell +(par ex. `~/.zshrc` ou `~/.bashrc`): + +```bash +export PATH="$HOME/.local/bin:$PATH" +``` + +Definissez `UNITY_CLI_NO_AUTO_UPDATE=1` pour desactiver la mise a jour automatique. + +#### Gestionnaires de paquets + +```bash +brew install akiojin/tap/unity-cli # macOS / Linux (Homebrew) +winget install akiojin.unity-cli # Windows (winget) +``` + +Les installations par gestionnaire de paquets se mettent a jour avec `brew upgrade` / `winget upgrade`. +Sous macOS Intel, les embeddings reference (`unity-cli reference embed-build` / `embed-search`) chargent ONNX Runtime +dynamiquement; la formule Homebrew installe `onnxruntime`, sinon executez +`brew install onnxruntime` ou definissez `ORT_DYLIB_PATH`. + +#### Releases ou cargo install + Telechargez le dernier binaire depuis [GitHub -Releases](https://github.com/akiojin/unity-cli/releases), ou installez-le -depuis un clone local: +Releases](https://github.com/akiojin/unity-cli/releases) ou installez depuis un checkout local: ```bash git clone https://github.com/akiojin/unity-cli.git @@ -52,9 +153,28 @@ cd unity-cli cargo install --path . ``` -Package bridge cote Unity (choisir une option): +#### Configuration du projet -**OpenUPM** (recommande): +Configuration du projet en une commande (verification du binaire → installation du bridge → connexion a l'Editor): + +```bash +cd /path/to/YourUnityProject +unity-cli --output json setup --launch-editor +``` + +`setup` ajoute le scoped registry OpenUPM et `com.akiojin.unity-cli-bridge` +(fixe a la version du CLI) a `Packages/manifest.json`, lance eventuellement l'Editor Unity +Hub du projet, attend le bridge et renvoie un rapport JSON. +`unity-cli bridge install | upgrade | status` gerent le paquet separement; `install` est +idempotent, et `setup` / `system ping` signalent un `versionCheck` quand les versions du CLI +et du bridge different. Si le projet n'utilise encore que l'ancien Input Manager et que +l'Editor est ferme, `install` met aussi `activeInputHandler` a Both dans +`ProjectSettings/ProjectSettings.asset`, afin que la dependance Input System s'importe sans +demande de redemarrage bloquante. + +Paquet bridge cote Unity, alternatives manuelles (choisissez une option): + +**OpenUPM**: ```bash openupm add com.akiojin.unity-cli-bridge @@ -66,12 +186,23 @@ openupm add com.akiojin.unity-cli-bridge https://github.com/akiojin/unity-cli.git?path=UnityCliBridge/Packages/unity-cli-bridge ``` -Verification de connexion: +#### Verification de connexion ```bash unity-cli system ping +unity-cli doctor --output json # si ping echoue: SAFE_MODE / BRIDGE_NOT_INSTALLED / PORT_IN_USE / ... ``` +#### Maintenance du binaire gere + +```bash +unity-cli cli doctor +unity-cli cli install +``` + +`unityd` et `lspd` mettent automatiquement a jour leurs binaires geres `unity-cli` / C# LSP au demarrage du daemon. +Les copies gerees se trouvent sous `UNITY_CLI_TOOLS_ROOT` (ou le repertoire tools par defaut de l'OS) et sont mises a jour sans confirmation interactive. + ## Skills (13) | Categorie | Skills | @@ -110,7 +241,8 @@ unity-cli tool call run_tests --json '{"mode":"editmode"}' | `UNITY_CLI_HOST` | Hote Unity Editor | `localhost` | | `UNITY_CLI_PORT` | Port Unity Editor | `6400` | | `UNITY_CLI_TIMEOUT_MS` | Timeout de commande (ms) | `30000` | -| `UNITY_CLI_LSP_MODE` | Mode LSP (`off` / `auto` / `required`) | `off` | +| `UNITY_CLI_LSP_MODE` | Mode LSP (`off` / `auto` / `required`). `auto` privilegie le LSP C# pour la recherche de symboles et revient a l'index local (`backend: "index"`, `fallbackReason`) | `auto` | +| `UNITY_CLI_LSP_AUTO_TIMEOUT_MS` | Limite (ms) d'attente du LSP pour une recherche de symboles en `auto` avant le retour a l'index local | `10000` | | `UNITY_CLI_TOOLS_ROOT` | Repertoire racine des outils telecharges | OS default | Les variables legacy prefixees MCP ne sont pas supportees. Utilisez uniquement `UNITY_CLI_*`. diff --git a/README.it.md b/README.it.md index 67dac398..6c7f48b9 100644 --- a/README.it.md +++ b/README.it.md @@ -24,27 +24,127 @@ Alcuni strumenti di codice (`read`, `search`, `find_symbol`, `find_refs`, ecc.) ## Inizio rapido -### Consigliato: plugin Claude Code +### Compatibilita dell'Editor -Installa il plugin `unity-cli` dal Claude Code Marketplace: +Il Bridge richiede Unity 2022.3 o successivo. La matrice macOS copre +2022.3.62f3, 6000.0.84f1, 6000.3.25f1, 6000.4.11f1, 6000.5.3f1, +6000.6.3f1, 6000.7.0a2 e 6000.7.0b2 (E2E di accettazione: PASS il 2026-09-30). Consultare le +[date e i risultati di verifica](docs/editor-compatibility.md) prima di scegliere una versione. +L'Editor Unity 6000.7 gira su Mono; le build Player CoreCLR sono escluse da questa matrice. + +### Installare o aggiornare con un agente LLM + +Copiare questo prompt in Claude Code, Codex o un altro agente di programmazione aperto +nel proprio progetto Unity. Eseguire di nuovo lo stesso prompt in seguito per aggiornare +insieme la CLI e il pacchetto bridge di Unity: + +```text +Installa o aggiorna unity-cli per questo progetto Unity, mantieni il pacchetto bridge di +Unity alla stessa versione della CLI e collegalo allo Unity Editor. + +1. Rileva il mio sistema operativo (macOS, Linux o Windows). +2. Se `unity-cli` non e ancora nel PATH, esegui lo script ufficiale di Quick Install: + - macOS / Linux: curl -fsSL https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.sh | sh + - Windows (PowerShell): irm https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.ps1 | iex +3. Se `unity-cli` e gia nel PATH, aggiornalo invece all'ultima release. + Se UNITY_CLI_NO_AUTO_UPDATE=1 o UNITY_CLI_VERSION sono impostati, ho fissato la versione + di proposito: non aggiornarlo; dimmelo e chiedimi prima. Altrimenti individua dove si trova + davvero il binario (seguendo i link simbolici) e aggiornalo nel modo in cui e stato installato: + - Quick Install (copia gestita sotto ~/.unity/tools): unity-cli cli install + - Homebrew: brew upgrade akiojin/tap/unity-cli + - winget: winget upgrade akiojin.unity-cli + - Qualsiasi altro caso (cargo install, download manuale): dimmi come e stato installato e + chiedimi prima di modificarlo. +4. Verifica che `unity-cli --version` funzioni dal PATH. Su macOS / Linux, se non viene + trovato, aggiungi ~/.local/bin al PATH di questa shell e indicami la riga da aggiungere al + mio profilo della shell. Su Windows, apri una nuova shell per applicare il PATH utente aggiornato. +5. Prima di modificare il mio progetto, dimmi che setup modifica Packages/manifest.json + (aggiunge lo scoped registry OpenUPM e com.akiojin.unity-cli-bridge fissato alla versione + della CLI) e, per i progetti che usano solo il vecchio Input Manager, imposta + activeInputHandler su Both in ProjectSettings/ProjectSettings.asset. Attendi la mia conferma. +6. Dalla radice del progetto Unity, esegui: unity-cli --output json setup --launch-editor + Se il JSON contiene ok: false, segui editor.hint (la prima importazione puo richiedere + alcuni minuti; riesegui setup per continuare ad attendere). +7. Controlla la versione del bridge con: unity-cli --output json bridge status + - Se source e registry e versionCheck.status (qui o nel report di setup) e mismatch: + dimmi che questo cambia la riga com.akiojin.unity-cli-bridge in Packages/manifest.json + alla versione della CLI e attendi la mia conferma. Poi esegui unity-cli bridge upgrade e + lascia che lo Unity Editor reimporti il pacchetto. + - Se source e custom o embedded (URL Git, percorso locale o una copia sotto Packages/), o + versionCheck.status e unknown: non riscriverlo. Riportami invece il source ed entrambe + le versioni. +8. Verifica la connessione con: unity-cli system ping + Conferma che versionCheck.status e match (la CLI e il bridge usano la stessa versione). +9. Se un passaggio fallisce, esegui: unity-cli doctor --output json + Riporta il codice diagnosis e segui il suo suggerimento prima di riprovare. +``` + +**Plugin Claude Code**: installare il plugin `unity-cli` da Claude Code +Marketplace per permettere all'agente di usare gli skill dei workflow Unity: ```bash /plugin marketplace add akiojin/unity-cli ``` -Il plugin del Marketplace installa solo gli skill. Installa il binario -`unity-cli` separatamente con una delle opzioni manuali qui sotto. - -### Codex Skills +Il plugin fornisce gli skill; il binario e il bridge Unity vengono preparati quando servono. +Quando un'attivita richiede Unity e `unity-cli` manca, lo skill `unity-cli-usage` fa eseguire +all'agente lo script di Quick Install e poi `unity-cli setup` nel progetto Unity +(avvisa prima di modificare `Packages/manifest.json`). -Quando si utilizza questo repository con Codex, le skill sono disponibili tramite `.codex/skills/` (link simbolici alla sorgente del plugin). -Non e necessaria alcuna configurazione aggiuntiva — basta clonare il repository. +**Codex Skills**: usando questo repository con Codex, gli skill sono disponibili tramite +`.agents/skills/` (symlink alla sorgente del plugin, esposti anche tramite `.claude/skills/`). +Non serve alcuna configurazione aggiuntiva — basta clonare il repository. ### Installazione manuale -Scarica il binary piu recente da [GitHub -Releases](https://github.com/akiojin/unity-cli/releases), oppure installalo da -un clone locale: +#### Quick Install (consigliato) + +macOS (Apple silicon / Intel) e Linux: + +```bash +curl -fsSL https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.sh | sh +``` + +Windows (PowerShell): + +```powershell +irm https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.ps1 | iex +``` + +Entrambi gli installer scaricano il binario della release nella struttura gestita +`~/.unity/tools/unity-cli/{rid}/` e lo verificano con i `SHA256SUMS` della release prima +dell'installazione; se il checksum non corrisponde, l'installazione viene interrotta e il +binario esistente non viene toccato. `install.sh` crea un symlink in `~/.local/bin/unity-cli`; +`install.ps1` aggiunge la directory gestita al `PATH` utente. Impostare +`UNITY_CLI_VERSION=v0.16.0` per fissare una release. Dopo l'installazione iniziale la CLI +controlla automaticamente gli aggiornamenti in background, e ogni aggiornamento viene +verificato con gli stessi checksum. + +Se `~/.local/bin` non e nel PATH, aggiungere quanto segue al profilo della shell +(ad es. `~/.zshrc` o `~/.bashrc`): + +```bash +export PATH="$HOME/.local/bin:$PATH" +``` + +Impostare `UNITY_CLI_NO_AUTO_UPDATE=1` per disattivare l'aggiornamento automatico. + +#### Gestori di pacchetti + +```bash +brew install akiojin/tap/unity-cli # macOS / Linux (Homebrew) +winget install akiojin.unity-cli # Windows (winget) +``` + +Le installazioni tramite gestore di pacchetti si aggiornano con `brew upgrade` / `winget upgrade`. +Su macOS Intel, gli embedding reference (`unity-cli reference embed-build` / `embed-search`) caricano ONNX Runtime +dinamicamente; la formula Homebrew installa `onnxruntime`, altrimenti eseguire +`brew install onnxruntime` o impostare `ORT_DYLIB_PATH`. + +#### Releases o cargo install + +Scaricare il binario piu recente da [GitHub +Releases](https://github.com/akiojin/unity-cli/releases) oppure installarlo da un checkout locale: ```bash git clone https://github.com/akiojin/unity-cli.git @@ -52,9 +152,28 @@ cd unity-cli cargo install --path . ``` -Pacchetto bridge lato Unity (scegli un'opzione): +#### Configurazione del progetto -**OpenUPM** (consigliato): +Configurazione del progetto con un solo comando (controllo del binario → installazione del bridge → connessione all'Editor): + +```bash +cd /path/to/YourUnityProject +unity-cli --output json setup --launch-editor +``` + +`setup` aggiunge lo scoped registry OpenUPM e `com.akiojin.unity-cli-bridge` +(fissato alla versione della CLI) a `Packages/manifest.json`, avvia facoltativamente +l'Editor Unity Hub del progetto, attende il bridge e restituisce un report JSON. +`unity-cli bridge install | upgrade | status` gestiscono il pacchetto separatamente; +`install` e idempotente, e `setup` / `system ping` segnalano un `versionCheck` quando le +versioni di CLI e bridge differiscono. Se il progetto usa ancora solo il vecchio Input +Manager e l'Editor e chiuso, `install` imposta anche `activeInputHandler` su Both in +`ProjectSettings/ProjectSettings.asset`, cosi la dipendenza Input System viene importata +senza un prompt di riavvio bloccante. + +Pacchetto bridge lato Unity, alternative manuali (sceglierne una): + +**OpenUPM**: ```bash openupm add com.akiojin.unity-cli-bridge @@ -66,12 +185,23 @@ openupm add com.akiojin.unity-cli-bridge https://github.com/akiojin/unity-cli.git?path=UnityCliBridge/Packages/unity-cli-bridge ``` -Verifica connessione: +#### Verifica della connessione ```bash unity-cli system ping +unity-cli doctor --output json # se ping fallisce: SAFE_MODE / BRIDGE_NOT_INSTALLED / PORT_IN_USE / ... ``` +#### Manutenzione del binario gestito + +```bash +unity-cli cli doctor +unity-cli cli install +``` + +`unityd` e `lspd` aggiornano automaticamente i propri binari gestiti `unity-cli` / C# LSP all'avvio del daemon. +Le copie gestite si trovano in `UNITY_CLI_TOOLS_ROOT` (o nella directory tools predefinita del sistema operativo) e vengono aggiornate senza conferma interattiva. + ## Skills (13) | Categoria | Skills | @@ -110,7 +240,8 @@ unity-cli tool call run_tests --json '{"mode":"editmode"}' | `UNITY_CLI_HOST` | Host Unity Editor | `localhost` | | `UNITY_CLI_PORT` | Porta Unity Editor | `6400` | | `UNITY_CLI_TIMEOUT_MS` | Timeout comando (ms) | `30000` | -| `UNITY_CLI_LSP_MODE` | Modalita LSP (`off` / `auto` / `required`) | `off` | +| `UNITY_CLI_LSP_MODE` | Modalita LSP (`off` / `auto` / `required`). `auto` preferisce il LSP C# per la ricerca dei simboli e torna all'indice locale (`backend: "index"`, `fallbackReason`) | `auto` | +| `UNITY_CLI_LSP_AUTO_TIMEOUT_MS` | Limite (ms) di attesa del LSP per una ricerca simboli in `auto` prima di tornare all'indice locale | `10000` | | `UNITY_CLI_TOOLS_ROOT` | Directory root dei tool scaricati | OS default | Le variabili legacy con prefisso MCP non sono supportate. Usa solo `UNITY_CLI_*`. diff --git a/README.ja.md b/README.ja.md index 85fc0529..ea7e71ab 100644 --- a/README.ja.md +++ b/README.ja.md @@ -33,9 +33,56 @@ Bridge の最小バージョンは Unity 2022.3 です。macOS 検証対象は [対応表の検証日・結果](docs/editor-compatibility.md)を確認してください。 6000.7 の Editor は Mono で動作し、CoreCLR Player ビルドはこの検証の対象外です。 -### 推奨: Claude Code プラグイン +### LLM エージェントでインストール・更新 -Claude Code Marketplace から `unity-cli` プラグインをインストールします: +Unity プロジェクトで開いた Claude Code や Codex などのコーディングエージェントに、 +次のプロンプトをそのまま貼り付けてください。後から同じプロンプトを再実行すると、CLI と +Unity 側の bridge パッケージをまとめて更新できます: + +```text +この Unity プロジェクトに unity-cli をインストールまたは更新し、Unity 側の bridge パッケージを +CLI と同じバージョンに揃えて、Unity Editor と接続してください。 + +1. OS(macOS / Linux / Windows)を判定してください。 +2. `unity-cli` が PATH 上にない場合は、公式のクイックインストールスクリプトを実行してください: + - macOS / Linux: curl -fsSL https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.sh | sh + - Windows(PowerShell): irm https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.ps1 | iex +3. `unity-cli` がすでに PATH 上にある場合は、代わりに最新リリースへ更新してください。 + UNITY_CLI_NO_AUTO_UPDATE=1 または UNITY_CLI_VERSION が設定されている場合は、私が意図的に + バージョンを固定しています。更新せず、私に伝えて確認を取ってください。それ以外の場合は、 + バイナリの実体の場所を(シンボリックリンクをたどって)確認し、導入方法に合わせて更新してください: + - クイックインストール(~/.unity/tools 配下の managed コピー): unity-cli cli install + - Homebrew: brew upgrade akiojin/tap/unity-cli + - winget: winget upgrade akiojin.unity-cli + - それ以外(cargo install や手動ダウンロード): 導入方法を私に伝え、変更前に確認を取ってください。 +4. PATH から `unity-cli --version` が実行できることを確認してください。macOS / Linux で + 見つからない場合は、このシェルの PATH に ~/.local/bin を追加し、シェルプロファイルに + 追記する行を教えてください。Windows では、更新されたユーザー PATH を反映するため + 新しいシェルを開いてください。 +5. プロジェクトを変更する前に、setup が Packages/manifest.json を編集すること + (OpenUPM の scoped registry と、CLI と同じバージョンに固定した + com.akiojin.unity-cli-bridge を追加すること)と、旧 Input Manager のみのプロジェクトでは + ProjectSettings/ProjectSettings.asset の activeInputHandler を Both に設定することを + 説明し、私の確認を待ってください。 +6. Unity プロジェクトのルートで次を実行してください: unity-cli --output json setup --launch-editor + JSON が ok: false の場合は editor.hint に従ってください(初回インポートは数分かかる + ことがあります。待ち続けるには setup を再実行します)。 +7. 次のコマンドで bridge のバージョンを確認してください: unity-cli --output json bridge status + - source が registry で、versionCheck.status(この結果または setup の結果)が mismatch の場合: + Packages/manifest.json の com.akiojin.unity-cli-bridge の行を CLI のバージョンに変更することを + 私に伝え、確認を待ってください。その後 unity-cli bridge upgrade を実行し、 + Unity Editor にパッケージを再インポートさせてください。 + - source が custom または embedded(Git URL、ローカルパス、Packages/ 配下のコピー)の場合や、 + versionCheck.status が unknown の場合: 書き換えないでください。代わりに source と + 両方のバージョンを私に報告してください。 +8. 次のコマンドで接続を確認してください: unity-cli system ping + versionCheck.status が match(CLI と bridge が同じバージョン)であることを確認してください。 +9. いずれかの手順が失敗した場合は、次を実行してください: unity-cli doctor --output json + diagnosis コードを報告し、そのヒントに従ってから再試行してください。 +``` + +**Claude Code プラグイン**: Claude Code Marketplace から `unity-cli` プラグインを +インストールすると、エージェントが Unity 操作用のスキルを使えるようになります: ```bash /plugin marketplace add akiojin/unity-cli @@ -43,15 +90,16 @@ Claude Code Marketplace から `unity-cli` プラグインをインストール プラグインが提供するのはスキルで、バイナリと Unity ブリッジは必要時に導入されます。 Unity 操作が必要なのに `unity-cli` が未導入の場合、`unity-cli-usage` スキルに従って -エージェントがインストールスクリプト(`scripts/install.sh`)を実行し、Unity プロジェクトで +エージェントがクイックインストールスクリプトを実行し、Unity プロジェクトで `unity-cli setup` を実行します(`Packages/manifest.json` を変更する前にユーザーへ明示します)。 -### Codex スキル - -Codex でこのリポジトリを利用する場合、`.codex/skills/` にスキルのシンボリックリンクが配置済みです。 +**Codex スキル**: Codex でこのリポジトリを利用する場合、`.agents/skills/` に +スキルのシンボリックリンクが配置済みです(`.claude/skills/` からも参照できます)。 リポジトリをクローンするだけで追加セットアップは不要です。 -### クイックインストール(推奨) +### 手動でインストール + +#### クイックインストール(推奨) macOS(Apple silicon / Intel)と Linux: @@ -70,10 +118,19 @@ irm https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.ps1 ハッシュが一致しない場合は導入を中止し、既存のバイナリには触れません。 `install.sh` は `~/.local/bin/unity-cli` にシンボリックリンクを作り、`install.ps1` は managed ディレクトリをユーザーの `PATH` に追加します。`UNITY_CLI_VERSION=v0.16.0` で -リリースを固定できます。導入後の自動更新も同じチェックサムで検証されます。 +リリースを固定できます。導入後は CLI がバックグラウンドで自動更新を確認し、 +更新も同じチェックサムで検証されます。 + +`~/.local/bin` が PATH に含まれていない場合は、シェルプロファイル +(例: `~/.zshrc` や `~/.bashrc`)に次を追加してください: + +```bash +export PATH="$HOME/.local/bin:$PATH" +``` + 自動更新を止めるには `UNITY_CLI_NO_AUTO_UPDATE=1` を設定してください。 -### パッケージマネージャ +#### パッケージマネージャ ```bash brew install akiojin/tap/unity-cli # macOS / Linux(Homebrew) @@ -85,7 +142,7 @@ Intel Mac の reference 埋め込み(`unity-cli reference embed-build` / `embe Homebrew formula は `onnxruntime` を依存として導入します。それ以外の導入方法では `brew install onnxruntime` を実行するか、`ORT_DYLIB_PATH` を設定してください。 -### 手動インストール +#### Releases / cargo install 最新バイナリは [GitHub Releases](https://github.com/akiojin/unity-cli/releases) から取得できます。 @@ -97,6 +154,8 @@ cd unity-cli cargo install --path . ``` +#### プロジェクトのセットアップ + プロジェクトのセットアップを 1 コマンドで行う(binary 検証 → bridge 導入 → Editor 接続確認): ```bash @@ -127,14 +186,14 @@ openupm add com.akiojin.unity-cli-bridge https://github.com/akiojin/unity-cli.git?path=UnityCliBridge/Packages/unity-cli-bridge ``` -接続確認: +#### 接続確認 ```bash unity-cli system ping unity-cli doctor --output json # ping 失敗時: SAFE_MODE / BRIDGE_NOT_INSTALLED / PORT_IN_USE など ``` -managed バイナリの確認と更新: +#### managed バイナリの確認と更新 ```bash unity-cli cli doctor @@ -182,7 +241,8 @@ unity-cli tool call run_tests --json '{"mode":"editmode"}' | `UNITY_CLI_HOST` | Unity Editor ホスト | `127.0.0.1` | | `UNITY_CLI_PORT` | Unity Editor ポート | `6400` | | `UNITY_CLI_TIMEOUT_MS` | コマンドタイムアウト (ms) | `30000` | -| `UNITY_CLI_LSP_MODE` | LSP モード (`off` / `auto` / `required`) | `off` | +| `UNITY_CLI_LSP_MODE` | LSP モード (`off` / `auto` / `required`)。`auto` はシンボル検索で C# LSP を優先し、使えないときはローカルインデックスに戻る(`backend: "index"`, `fallbackReason`) | `auto` | +| `UNITY_CLI_LSP_AUTO_TIMEOUT_MS` | `auto` のシンボル検索が LSP を待つ上限 (ms)。超えるとローカルインデックスに戻る | `10000` | | `UNITY_CLI_TOOLS_ROOT` | ダウンロード済みツールのルートディレクトリ | OS 既定 | 旧 MCP 接頭辞の環境変数は非対応です。`UNITY_CLI_*` のみ使用してください。 diff --git a/README.md b/README.md index a0dfbd54..88898cbc 100644 --- a/README.md +++ b/README.md @@ -46,9 +46,58 @@ The Bridge requires Unity 2022.3 or newer. The macOS matrix covers [verification dates and results](docs/editor-compatibility.md) before choosing a version. Unity 6000.7 Editor runs on Mono; CoreCLR Player builds are outside this matrix. -### Recommended: Claude Code Plugin +### Install or update with an LLM agent -Install the `unity-cli` plugin from Claude Code Marketplace: +Copy this prompt into Claude Code, Codex, or another coding agent opened in +your Unity project. Run the same prompt again later to update the CLI and the +Unity bridge package together: + +```text +Install or update unity-cli for this Unity project, keep the Unity bridge +package on the same version as the CLI, and connect it to the Unity Editor. + +1. Detect my OS (macOS, Linux, or Windows). +2. If `unity-cli` is not already on PATH, run the official Quick Install script: + - macOS / Linux: curl -fsSL https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.sh | sh + - Windows (PowerShell): irm https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.ps1 | iex +3. If `unity-cli` is already on PATH, update it to the latest release instead. + If UNITY_CLI_NO_AUTO_UPDATE=1 or UNITY_CLI_VERSION is set, I pinned the + version on purpose: do not update it; tell me and ask first. Otherwise + resolve where the binary really lives (follow symlinks) and update it the + way it was installed: + - Quick Install (managed copy under ~/.unity/tools): unity-cli cli install + - Homebrew: brew upgrade akiojin/tap/unity-cli + - winget: winget upgrade akiojin.unity-cli + - Anything else (cargo install, manual download): tell me how it was + installed and ask before changing it. +4. Check that `unity-cli --version` works from PATH. On macOS / Linux, if it is + not found, add ~/.local/bin to PATH for this shell and tell me the line to add + to my shell profile. On Windows, open a new shell so the updated user PATH applies. +5. Before changing my project, tell me that setup edits Packages/manifest.json + (adds the OpenUPM scoped registry and com.akiojin.unity-cli-bridge pinned to + the CLI version) and, for legacy-input-only projects, sets activeInputHandler + to Both in ProjectSettings/ProjectSettings.asset. Wait for my confirmation. +6. From the Unity project root, run: unity-cli --output json setup --launch-editor + If the JSON has ok: false, follow editor.hint (the first import can take + several minutes; rerun setup to keep waiting). +7. Check the bridge version with: unity-cli --output json bridge status + - If source is registry and versionCheck.status (here or in the setup + report) is mismatch: tell me that this changes the + com.akiojin.unity-cli-bridge line in Packages/manifest.json to the CLI + version and wait for my confirmation. Then run: unity-cli bridge upgrade + and let the Unity Editor reimport the package. + - If source is custom or embedded (Git URL, local path, or a copy under + Packages/), or versionCheck.status is unknown: do not rewrite it. Report + the source and both versions to me instead. +8. Verify the connection with: unity-cli system ping + Confirm that versionCheck.status is match (the CLI and the bridge use the + same version). +9. If any step fails, run: unity-cli doctor --output json + Report the diagnosis code and follow its hint before retrying. +``` + +**Claude Code plugin**: install the `unity-cli` plugin from Claude Code +Marketplace to give the agent the Unity workflow skills: ```bash /plugin marketplace add akiojin/unity-cli @@ -56,16 +105,17 @@ Install the `unity-cli` plugin from Claude Code Marketplace: The plugin ships skills; the binary and the Unity bridge are bootstrapped on demand. When a task needs Unity and `unity-cli` is missing, the -`unity-cli-usage` skill has the agent run the Quick Install script below and then +`unity-cli-usage` skill has the agent run the Quick Install script and then `unity-cli setup` in your Unity project (it tells you before editing `Packages/manifest.json`). -### Codex Skills +**Codex Skills**: when using this repository with Codex, skills are available +via `.agents/skills/` (symlinks to the plugin source, also exposed through +`.claude/skills/`). No additional setup is required - just clone the repository. -When using this repository with Codex, skills are available via `.agents/skills/` (symlinks to the plugin source, also exposed through `.claude/skills/`). -No additional setup is required - just clone the repository. +### Install manually -### Quick Install (recommended) +#### Quick Install (recommended) macOS (Apple silicon / Intel) and Linux: @@ -97,7 +147,7 @@ export PATH="$HOME/.local/bin:$PATH" Set `UNITY_CLI_NO_AUTO_UPDATE=1` to disable auto-update. -### Package Managers +#### Package Managers ```bash brew install akiojin/tap/unity-cli # macOS / Linux (Homebrew) @@ -109,7 +159,7 @@ On Intel macOS, reference embeddings (`unity-cli reference embed-build` / `embed dynamically; the Homebrew formula installs `onnxruntime`, otherwise run `brew install onnxruntime` or set `ORT_DYLIB_PATH`. -### Manual Install +#### Releases or cargo install Download the latest binary from [GitHub Releases](https://github.com/akiojin/unity-cli/releases), or install from a @@ -121,6 +171,8 @@ cd unity-cli cargo install --path . ``` +#### Project setup + One-command project setup (binary check → bridge install → Editor connection): ```bash @@ -152,14 +204,14 @@ openupm add com.akiojin.unity-cli-bridge https://github.com/akiojin/unity-cli.git?path=UnityCliBridge/Packages/unity-cli-bridge ``` -Connection check: +#### Connection check ```bash unity-cli system ping unity-cli doctor --output json # when ping fails: SAFE_MODE / BRIDGE_NOT_INSTALLED / PORT_IN_USE / ... ``` -Managed binary maintenance: +#### Managed binary maintenance ```bash unity-cli cli doctor @@ -227,7 +279,8 @@ policy, required CI, and skill documentation changes. | `UNITY_CLI_HOST` | Unity Editor host | `127.0.0.1` | | `UNITY_CLI_PORT` | Unity Editor port | `6400` | | `UNITY_CLI_TIMEOUT_MS` | Command timeout (ms) | `30000` | -| `UNITY_CLI_LSP_MODE` | LSP mode (`off` / `auto` / `required`) | `off` | +| `UNITY_CLI_LSP_MODE` | LSP mode (`off` / `auto` / `required`). `auto` prefers the C# LSP for symbol search and falls back to the local index (`backend: "index"`, `fallbackReason`) | `auto` | +| `UNITY_CLI_LSP_AUTO_TIMEOUT_MS` | Upper bound (ms) for an `auto` symbol search to wait for the LSP before falling back to the local index | `10000` | | `UNITY_CLI_TOOLS_ROOT` | Downloaded tools root directory | OS default | | `UNITY_CLI_NO_AUTO_UPDATE` | Disable background auto-update (`1` to disable) | *(unset)* | diff --git a/README.zh.md b/README.zh.md index 22125b6b..ef5f0c28 100644 --- a/README.zh.md +++ b/README.zh.md @@ -24,25 +24,121 @@ Claude Code ## 快速开始 -### 推荐: Claude Code 插件 +### Editor 兼容性 -从 Claude Code Marketplace 安装 `unity-cli` 插件: +Bridge 要求 Unity 2022.3 或更高版本。macOS 验证矩阵覆盖 +2022.3.62f3、6000.0.84f1、6000.3.25f1、6000.4.11f1、6000.5.3f1、 +6000.6.3f1、6000.7.0a2 和 6000.7.0b2(2026-09-30 验收 E2E: 全部 PASS)。 +选择版本前请查看[验证日期与结果](docs/editor-compatibility.md)。 +Unity 6000.7 的 Editor 运行在 Mono 上,CoreCLR Player 构建不在此矩阵范围内。 + +### 使用 LLM 代理安装或更新 + +在 Unity 项目中打开 Claude Code、Codex 或其他编码代理,然后直接粘贴以下提示词。之后再次运行 +同一提示词,即可同时更新 CLI 和 Unity 端的 bridge 包: + +```text +请为这个 Unity 项目安装或更新 unity-cli,让 Unity 端的 bridge 包与 CLI 保持相同版本, +并将其连接到 Unity Editor。 + +1. 判断我的操作系统(macOS、Linux 或 Windows)。 +2. 如果 PATH 中还没有 `unity-cli`,运行官方快速安装脚本: + - macOS / Linux: curl -fsSL https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.sh | sh + - Windows(PowerShell): irm https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.ps1 | iex +3. 如果 `unity-cli` 已在 PATH 中,请改为将其更新到最新版本。 + 如果设置了 UNITY_CLI_NO_AUTO_UPDATE=1 或 UNITY_CLI_VERSION,说明我有意固定了版本: + 不要更新,先告诉我并征得我的确认。否则,请找出二进制文件的实际位置(跟随符号链接), + 并按照安装方式进行更新: + - Quick Install(~/.unity/tools 下的 managed 副本): unity-cli cli install + - Homebrew: brew upgrade akiojin/tap/unity-cli + - winget: winget upgrade akiojin.unity-cli + - 其他方式(cargo install、手动下载): 告诉我安装方式,并在修改前征得我的确认。 +4. 确认可以从 PATH 运行 `unity-cli --version`。在 macOS / Linux 上如果找不到, + 请把 ~/.local/bin 加入当前 shell 的 PATH,并告诉我需要写入 shell 配置文件的那一行。 + 在 Windows 上,请打开新的 shell 以应用更新后的用户 PATH。 +5. 修改项目之前,请告诉我 setup 会编辑 Packages/manifest.json(添加 OpenUPM + scoped registry 以及固定为 CLI 同版本的 com.akiojin.unity-cli-bridge),并且对于 + 只使用旧 Input Manager 的项目,会把 ProjectSettings/ProjectSettings.asset 中的 + activeInputHandler 设为 Both。等待我的确认。 +6. 在 Unity 项目根目录运行: unity-cli --output json setup --launch-editor + 如果 JSON 返回 ok: false,请按照 editor.hint 处理(首次导入可能需要几分钟; + 重新运行 setup 可继续等待)。 +7. 使用以下命令检查 bridge 版本: unity-cli --output json bridge status + - 如果 source 为 registry,且 versionCheck.status(此结果或 setup 报告中)为 mismatch: + 告诉我这会把 Packages/manifest.json 中 com.akiojin.unity-cli-bridge 这一行改为 CLI 版本, + 并等待我的确认。然后运行 unity-cli bridge upgrade,并让 Unity Editor 重新导入该包。 + - 如果 source 为 custom 或 embedded(Git URL、本地路径或 Packages/ 下的副本), + 或 versionCheck.status 为 unknown: 不要改写它,而是向我报告 source 和两个版本。 +8. 使用以下命令验证连接: unity-cli system ping + 确认 versionCheck.status 为 match(CLI 与 bridge 版本相同)。 +9. 如果任何步骤失败,请运行: unity-cli doctor --output json + 报告 diagnosis 代码,并按照其提示处理后再重试。 +``` + +**Claude Code 插件**: 从 Claude Code Marketplace 安装 `unity-cli` 插件, +让代理可以使用 Unity 工作流 Skills: ```bash /plugin marketplace add akiojin/unity-cli ``` -Marketplace 插件只会安装 skills。`unity-cli` 二进制本体需要使用下面的手动方式之一单独安装。 - -### Codex Skills +插件只提供 Skills,二进制文件和 Unity bridge 会在需要时自动引导安装。 +当任务需要 Unity 但尚未安装 `unity-cli` 时,`unity-cli-usage` skill 会让代理运行 +快速安装脚本,然后在 Unity 项目中运行 `unity-cli setup` +(编辑 `Packages/manifest.json` 之前会先告知你)。 -使用 Codex 时,`.codex/skills/` 中已提供指向插件源的符号链接。 -只需克隆仓库即可,无需额外配置。 +**Codex Skills**: 在 Codex 中使用本仓库时,可以通过 `.agents/skills/` 使用 Skills +(指向插件源码的符号链接,也可通过 `.claude/skills/` 访问)。只需克隆仓库,无需额外设置。 ### 手动安装 -可以从 [GitHub Releases](https://github.com/akiojin/unity-cli/releases) -下载最新二进制,或者从本地 clone 安装: +#### 快速安装(推荐) + +macOS(Apple silicon / Intel)和 Linux: + +```bash +curl -fsSL https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.sh | sh +``` + +Windows(PowerShell): + +```powershell +irm https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.ps1 | iex +``` + +两个安装脚本都会把发布版二进制文件下载到 managed 目录 +`~/.unity/tools/unity-cli/{rid}/`,并在安装前使用发布版的 `SHA256SUMS` 校验; +校验不一致时会中止安装,且不会改动已有的二进制文件。`install.sh` 会创建 +`~/.local/bin/unity-cli` 符号链接;`install.ps1` 会把 managed 目录加入用户 `PATH`。 +设置 `UNITY_CLI_VERSION=v0.16.0` 可固定发布版本。首次安装后,CLI 会在后台自动检查更新, +每次更新都使用相同的校验和进行验证。 + +如果 `~/.local/bin` 不在 PATH 中,请将以下内容加入 shell 配置文件 +(例如 `~/.zshrc` 或 `~/.bashrc`): + +```bash +export PATH="$HOME/.local/bin:$PATH" +``` + +设置 `UNITY_CLI_NO_AUTO_UPDATE=1` 可关闭自动更新。 + +#### 包管理器 + +```bash +brew install akiojin/tap/unity-cli # macOS / Linux(Homebrew) +winget install akiojin.unity-cli # Windows(winget) +``` + +通过包管理器安装时,使用 `brew upgrade` / `winget upgrade` 更新。 +在 Intel macOS 上,reference 嵌入(`unity-cli reference embed-build` / `embed-search`)会动态加载 ONNX Runtime; +Homebrew formula 会安装 `onnxruntime`,其他安装方式请运行 +`brew install onnxruntime` 或设置 `ORT_DYLIB_PATH`。 + +#### Releases 或 cargo install + +从 [GitHub +Releases](https://github.com/akiojin/unity-cli/releases) 下载最新二进制文件, +或从本地 checkout 安装: ```bash git clone https://github.com/akiojin/unity-cli.git @@ -50,9 +146,26 @@ cd unity-cli cargo install --path . ``` -Unity 侧桥接包(选择其一): +#### 项目设置 -**OpenUPM**(推荐): +一条命令完成项目设置(二进制检查 → bridge 安装 → Editor 连接): + +```bash +cd /path/to/YourUnityProject +unity-cli --output json setup --launch-editor +``` + +`setup` 会向 `Packages/manifest.json` 添加 OpenUPM scoped registry 和 +`com.akiojin.unity-cli-bridge`(固定为 CLI 同版本),必要时启动项目对应的 Unity Hub Editor, +等待 bridge 响应,并返回一份 JSON 报告。`unity-cli bridge install | upgrade | status` +可单独管理该包;`install` 是幂等的,CLI 与 bridge 版本不一致时,`setup` / `system ping` +会通过 `versionCheck` 报告。当项目仍只使用旧 Input Manager 且 Editor 已关闭时, +`install` 还会把 `ProjectSettings/ProjectSettings.asset` 中的 `activeInputHandler` 设为 Both, +从而在导入 Input System 依赖时避免阻塞式的重启提示。 + +Unity 端 bridge 包的手动安装方式(任选其一): + +**OpenUPM**: ```bash openupm add com.akiojin.unity-cli-bridge @@ -64,12 +177,23 @@ openupm add com.akiojin.unity-cli-bridge https://github.com/akiojin/unity-cli.git?path=UnityCliBridge/Packages/unity-cli-bridge ``` -连接检查: +#### 连接检查 ```bash unity-cli system ping +unity-cli doctor --output json # ping 失败时: SAFE_MODE / BRIDGE_NOT_INSTALLED / PORT_IN_USE / ... ``` +#### managed 二进制维护 + +```bash +unity-cli cli doctor +unity-cli cli install +``` + +`unityd` 和 `lspd` 会在 daemon 启动时自动更新 managed `unity-cli` / C# LSP 二进制文件。 +managed 副本位于 `UNITY_CLI_TOOLS_ROOT`(未设置时为操作系统默认的 tools 目录)下,更新时不会弹出交互式确认。 + ## Skills (13) | 类别 | Skills | @@ -108,7 +232,8 @@ unity-cli tool call run_tests --json '{"mode":"editmode"}' | `UNITY_CLI_HOST` | Unity Editor 主机 | `localhost` | | `UNITY_CLI_PORT` | Unity Editor 端口 | `6400` | | `UNITY_CLI_TIMEOUT_MS` | 命令超时 (ms) | `30000` | -| `UNITY_CLI_LSP_MODE` | LSP 模式 (`off` / `auto` / `required`) | `off` | +| `UNITY_CLI_LSP_MODE` | LSP 模式 (`off` / `auto` / `required`)。`auto` 在符号搜索中优先使用 C# LSP,不可用时回退到本地索引(`backend: "index"`, `fallbackReason`) | `auto` | +| `UNITY_CLI_LSP_AUTO_TIMEOUT_MS` | `auto` 符号搜索等待 LSP 的上限 (ms),超时后回退到本地索引 | `10000` | | `UNITY_CLI_TOOLS_ROOT` | 已下载工具根目录 | OS 默认 | 不支持旧 MCP 前缀环境变量。请仅使用 `UNITY_CLI_*`。 diff --git a/UnityCliBridge/Packages/unity-cli-bridge/Editor/Handlers/BakeHandler.cs b/UnityCliBridge/Packages/unity-cli-bridge/Editor/Handlers/BakeHandler.cs index 2bcd15d3..29d2c7a9 100644 --- a/UnityCliBridge/Packages/unity-cli-bridge/Editor/Handlers/BakeHandler.cs +++ b/UnityCliBridge/Packages/unity-cli-bridge/Editor/Handlers/BakeHandler.cs @@ -77,7 +77,7 @@ public static object StartBake(JObject args) string path = args?["scenePath"]?.Value(); if (string.IsNullOrEmpty(path) || !path.StartsWith("Assets/", StringComparison.Ordinal) || !path.EndsWith(".unity", StringComparison.Ordinal) || path != scene.path || !File.Exists(path)) return Error("SCENE_MISMATCH", "scenePath must identify the saved active scene under Assets/."); - if (SceneManager.sceneCount != 1 || EditorSceneManager.previewSceneCount != 0) + if (SceneManager.sceneCount != 1 || EditorSceneManager.IsPreviewScene(scene)) return Error("MULTIPLE_SCENES", "Load only the target scene before baking."); if (scene.isDirty) return Error("SCENE_DIRTY", "Save the scene before baking."); Component surface = null; diff --git a/UnityCliBridge/Packages/unity-cli-bridge/Editor/Handlers/SceneHandler.cs b/UnityCliBridge/Packages/unity-cli-bridge/Editor/Handlers/SceneHandler.cs index 4fe30d9f..593b46bd 100644 --- a/UnityCliBridge/Packages/unity-cli-bridge/Editor/Handlers/SceneHandler.cs +++ b/UnityCliBridge/Packages/unity-cli-bridge/Editor/Handlers/SceneHandler.cs @@ -62,7 +62,7 @@ public static object CreateScene(JObject parameters) } // Ensure directory exists - var directory = Path.GetDirectoryName(scenePath); + var directory = Path.GetDirectoryName(scenePath).Replace('\\', '/'); if (!AssetDatabase.IsValidFolder(directory)) { // Create directory structure @@ -310,7 +310,7 @@ public static object SaveScene(JObject parameters) } // Ensure directory exists - var directory = Path.GetDirectoryName(savePath); + var directory = Path.GetDirectoryName(savePath).Replace('\\', '/'); if (!AssetDatabase.IsValidFolder(directory)) { // Create directory structure diff --git a/UnityCliBridge/Packages/unity-cli-bridge/Tests/Editor/Handlers/BakeHandlerTests.cs b/UnityCliBridge/Packages/unity-cli-bridge/Tests/Editor/Handlers/BakeHandlerTests.cs index a3b4562d..f76416bb 100644 --- a/UnityCliBridge/Packages/unity-cli-bridge/Tests/Editor/Handlers/BakeHandlerTests.cs +++ b/UnityCliBridge/Packages/unity-cli-bridge/Tests/Editor/Handlers/BakeHandlerTests.cs @@ -133,6 +133,22 @@ [Test] public void AdditiveSceneIsRejectedWithoutSwitchingActiveScene() Assert.That(UnityEngine.SceneManagement.SceneManager.GetActiveScene(), Is.EqualTo(original)); } + [Test] public void PreviewSceneDoesNotBlockSavedScene() + { + var preview = EditorSceneManager.NewPreviewScene(); + try + { + Assert.That(UnityEngine.SceneManagement.SceneManager.sceneCount, Is.EqualTo(1)); + Assert.That(EditorSceneManager.previewSceneCount, Is.GreaterThan(0)); + var accepted = QueueBake(); + Assert.That((string)accepted["status"], Is.EqualTo("running"), accepted.ToString()); + } + finally + { + EditorSceneManager.ClosePreviewScene(preview); + } + } + [Test] public void DirtySceneIsRejected() { EditorSceneManager.MarkSceneDirty(UnityEngine.SceneManagement.SceneManager.GetActiveScene()); diff --git a/UnityCliBridge/Packages/unity-cli-bridge/Tests/Editor/Handlers/SceneHandlerTests.cs b/UnityCliBridge/Packages/unity-cli-bridge/Tests/Editor/Handlers/SceneHandlerTests.cs index 69f45a3b..731bdb28 100644 --- a/UnityCliBridge/Packages/unity-cli-bridge/Tests/Editor/Handlers/SceneHandlerTests.cs +++ b/UnityCliBridge/Packages/unity-cli-bridge/Tests/Editor/Handlers/SceneHandlerTests.cs @@ -93,6 +93,35 @@ public void CreateScene_ShouldWorkWithCustomPath() Assert.IsTrue(File.Exists(path)); } + [Test] + public void CreateScene_ShouldCreateNestedFolders() + { + var folder = testSceneFolder + "/Nested/Generated"; + var result = ToJObject(SceneHandler.CreateScene(new JObject + { + ["sceneName"] = "TestScene_Nested", + ["path"] = folder, + ["loadScene"] = false + })); + + Assert.IsNull(result.Value("error"), result.ToString()); + Assert.IsTrue(AssetDatabase.IsValidFolder(folder)); + Assert.IsTrue(File.Exists(folder + "/TestScene_Nested.unity")); + } + + [Test] + public void SaveScene_ShouldCreateNestedFolders() + { + EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); + var path = testSceneFolder + "/Saved/Generated/TestScene_Saved.unity"; + var result = ToJObject(SceneHandler.SaveScene(new JObject { ["scenePath"] = path })); + + Assert.IsNull(result.Value("error"), result.ToString()); + Assert.IsTrue(AssetDatabase.IsValidFolder(testSceneFolder + "/Saved/Generated")); + Assert.IsTrue(File.Exists(path)); + EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); + } + [Test] public void CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse() { diff --git a/UnityCliBridge/Packages/unity-cli-bridge/Tests/PlayMode/InputSimulationAutomationPlayModeTests.cs b/UnityCliBridge/Packages/unity-cli-bridge/Tests/PlayMode/InputSimulationAutomationPlayModeTests.cs index 53b3bcbe..bd1cffc2 100644 --- a/UnityCliBridge/Packages/unity-cli-bridge/Tests/PlayMode/InputSimulationAutomationPlayModeTests.cs +++ b/UnityCliBridge/Packages/unity-cli-bridge/Tests/PlayMode/InputSimulationAutomationPlayModeTests.cs @@ -458,7 +458,21 @@ private static string GetStatusText() private static int GetStatusInt(string key) { - var match = Regex.Match(GetStatusText(), "^" + Regex.Escape(key) + "=(\\d+)$", RegexOptions.Multiline); + return ParseStatusInt(GetStatusText(), key); + } + + [TestCase("MouseReleases=1\r\n", "MouseReleases", 1)] + [TestCase("TouchPresses=2\nTouchReleases=1\n", "TouchReleases", 1)] + [TestCase("MouseReleases=1", "MouseReleases", 1)] + [TestCase("MouseReleases=1\r\n", "TouchReleases", 0)] + public void StatusCounterParser_HandlesLineEndings(string status, string key, int expected) + { + Assert.That(ParseStatusInt(status, key), Is.EqualTo(expected)); + } + + private static int ParseStatusInt(string status, string key) + { + var match = Regex.Match(status, "^" + Regex.Escape(key) + "=(\\d+)\\r?$", RegexOptions.Multiline); return match.Success ? int.Parse(match.Groups[1].Value) : 0; } } diff --git a/UnityCliBridge/Packages/unity-cli-bridge/Tests/PlayMode/TouchGesturePlayModeTests.cs b/UnityCliBridge/Packages/unity-cli-bridge/Tests/PlayMode/TouchGesturePlayModeTests.cs index e088ea6b..66fec0e6 100644 --- a/UnityCliBridge/Packages/unity-cli-bridge/Tests/PlayMode/TouchGesturePlayModeTests.cs +++ b/UnityCliBridge/Packages/unity-cli-bridge/Tests/PlayMode/TouchGesturePlayModeTests.cs @@ -66,6 +66,7 @@ public sealed class TouchGesturePlayModeTests public void SetUp() { Assert.IsTrue(Application.isPlaying); + Application.logMessageReceived += ExpectBridgeConnectionLog; previousFrameRate = Application.targetFrameRate; previousVSync = QualitySettings.vSyncCount; previousRunInBackground = Application.runInBackground; @@ -105,6 +106,14 @@ public IEnumerator TearDown() InputSystem.settings.editorInputBehaviorInPlayMode = previousEditorInputBehavior; InputSystem.settings.updateMode = previousUpdateMode; Time.fixedDeltaTime = previousFixedDeltaTime; + Application.logMessageReceived -= ExpectBridgeConnectionLog; + } + + private static void ExpectBridgeConnectionLog(string message, string stackTrace, LogType type) + { + if (type == LogType.Log && System.Text.RegularExpressions.Regex.IsMatch(message, + @"^\[unity-cli-bridge\] Client connected from 127\.0\.0\.1:\d+$")) + LogAssert.Expect(type, message); } [UnityTest] diff --git a/UnityCliBridge/Packages/unity-cli-bridge/package.json b/UnityCliBridge/Packages/unity-cli-bridge/package.json index 8815dbec..12cb6b40 100644 --- a/UnityCliBridge/Packages/unity-cli-bridge/package.json +++ b/UnityCliBridge/Packages/unity-cli-bridge/package.json @@ -1,7 +1,7 @@ { "name": "com.akiojin.unity-cli-bridge", "displayName": "Unity CLI Bridge", - "version": "0.18.1", + "version": "0.19.0", "unity": "2022.3", "description": "Unity Editor bridge package for unity-cli automation (screenshots, video capture, scene analysis, input automation).", "keywords": [ diff --git a/docs/architecture.md b/docs/architecture.md index 1751ba69..a65f82b6 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -71,7 +71,11 @@ C# ソースコードの静的解析を行う Language Server Protocol 実装で - **役割**: - シンボル検索・参照解析 - インデックスの構築と更新 -- **起動制御**: `UNITY_CLI_LSP_MODE` 環境変数で制御 (`off` | `auto` | `required`) +- **起動制御**: `UNITY_CLI_LSP_MODE` 環境変数で制御 (`off` | `auto` | `required`、既定は `auto`) + - `auto`: `get_symbols` / `find_symbol` / `find_refs` / `build_index` は LSP を優先する。LSP が未インストール(バックグラウンドで `unity-cli lsp install` を起動)、起動失敗、または `UNITY_CLI_LSP_AUTO_TIMEOUT_MS`(既定 10000ms)以内に応答しない場合はローカルインデックスに戻り、結果に `backend: "index"` / `fallbackReason` / `fallbackDetail` を含める + - `off`: 常にローカルの正規表現インデックスを使う(`fallbackReason: "lsp_disabled"`) + - `required`: LSP を必須とし、失敗をそのままエラーにする + - 書き込み系ツール(`write_csharp_file` など)は、未設定時は従来どおり direct LSP セッションを使う。lspd 経由にするのは `auto` / `required` を明示したときだけ ## 通信プロトコル @@ -123,7 +127,9 @@ CLI 側 Unity Editor 側 | `UNITY_CLI_HOST` | Unity Editor の接続先ホスト | `127.0.0.1` | | `UNITY_CLI_PORT` | Unity Editor の接続先ポート | `6400` | | `UNITY_CLI_TIMEOUT_MS` | コマンドタイムアウト (ミリ秒) | ― | -| `UNITY_CLI_LSP_MODE` | LSP 起動モード | `off` | +| `UNITY_CLI_LSP_MODE` | LSP 起動モード | `auto` | +| `UNITY_CLI_LSP_AUTO_TIMEOUT_MS` | `auto` のシンボル検索が LSP を待つ上限 (ミリ秒) | `10000` | +| `UNITY_CLI_LSPD_START_TIMEOUT_MS` | lspd 自動起動で `ping` 応答を待つ上限 (ミリ秒)。起動プロセスが途中で終了した場合は待たずに失敗し、エラーに待ち時間と `lspd.log` の場所を含める | `60000` | | `UNITY_CLI_LSP_COMMAND` | LSP 実行コマンド | ― | | `UNITY_CLI_LSP_BIN` | LSP 実行ファイルパス | ― | | `UNITY_PROJECT_ROOT` | Unity プロジェクトルート | ― | diff --git a/docs/comparison.md b/docs/comparison.md index fb0dd64e..cb400fd0 100644 --- a/docs/comparison.md +++ b/docs/comparison.md @@ -43,6 +43,23 @@ Each table row links to its evidence: | Editor / project lifecycle | Bridge setup and installed Editor open/close/headless lifecycle; use Unity Hub or the official CLI for Editor installation and licenses. [Setup](../src/app/setup.rs), [lifecycle implementation](../src/app/editor.rs). | Editor/module install, licensing, project creation/opening, builds, tests and version control. [Official skill][official-skill]. | | Agent integration | Claude Code plugin and Codex skills. [Skill contract](skills.md). | Claude Code / Codex plugin, task skills and `unity mcp`. [Official skill][official-skill], [integration guide][official-integration]. | +Windows validation was added separately in [Issue #386 evidence](verification/issue-386/README.md): +CLI / Bridge 0.18.1 with Unity 6000.4.4f1 verified real setup, lockfile discovery, +OS screenshot fallback during an Editor modal, and all 23 listed operations with +DisableDomainReload / PlayUnfocused. A separate Windows comparison with official CLI +1.0.0-beta.11 and Pipeline 0.8.0-exp.1 measured 100 process samples per operation +with the Editor frontmost and minimized. Resident measurements covered all 23 +operations with 100 samples per tool and condition. [Windows timings](verification/issue-386/resume/windows-comparison.md) +record the debug build, a contended host, and the minimized background condition. +The timings below remain macOS measurements. [Additional functional evidence](verification/issue-386/resume/README.md) +includes successful Test Runner result collection with Domain Reload enabled and disabled, +Prefab, Timeline, InputActions persistence, animation, video, reference fetching, +baking, real Hot Reload, and a built Windows Player. Complex input passed 11 checks +after correcting the test's CRLF counter parsing. +Linux screenshot tools produced real images using TCP fixtures; a licensed Linux +Unity Editor, winget installation, and comparison with the original staff report +remain unverified. + ### Coexistence Both packages were loaded into **one real Unity 6000.3.25f1 Editor project** on @@ -165,6 +182,18 @@ Editor 側の **Pipeline**(`com.unity.pipeline`)を提供しています。 | Editor・プロジェクト管理 | Bridge 導入、導入済み Editor の起動・終了・headless運用。Editor インストールやライセンスは Hub / 公式 CLI を利用。[setup](../src/app/setup.rs)、[ライフサイクル](../src/app/editor.rs)。 | Editor / モジュール導入、ライセンス、プロジェクト作成・起動、ビルド、テスト、VCS。[公式資料][official-skill]。 | | エージェント連携 | Claude Code プラグイン / Codex スキル。[契約](skills.md)。 | Claude Code / Codex プラグイン、タスクスキル、`unity mcp`。[公式スキル][official-skill]、[連携ガイド][official-integration]。 | +Windows の実機確認は [Issue #386 の証跡](verification/issue-386/README.md) を追加しました。 +CLI / Bridge 0.18.1、Unity 6000.4.4f1 で実 setup、lockfile 発見、Editor モーダル中の OS +画面取得、および DisableDomainReload / PlayUnfocused 条件で公開23操作を確認しています。 +公式 CLI 1.0.0-beta.11 / Pipeline 0.8.0-exp.1 の Windows 比較では、プロセス方式を +各操作100回、Editor 前面・最小化の2条件で計測しました。常駐方式も23操作を各100回完了しました。 +[Windows計測値](verification/issue-386/resume/windows-comparison.md)に、debugビルド・他の処理が稼働中のhost・最小化した背景条件を記録しています。 +下の速度比較は macOS の計測です。 +[追加の機能検証](verification/issue-386/resume/README.md)では、Domain Reload 有効・無効でのTest Runnerの結果取得、 +Prefab、Timeline、InputActions 保存、Animation、Video、Reference、Bake、実 Hot Reload、実 Windows Player が成功しました。 +複合入力はテストのCRLFカウンター読取を修正して11件成功しました。Linux の画面取得ツールは TCP fixture で実画像を生成しましたが、 +認証済み Linux Unity Editor、winget 導入、スタッフ原資料との網羅性確認は未検証です。 + ### 同一プロジェクトでの併用 Apple Silicon macOS の **同じ Unity 6000.3.25f1 プロジェクト**に両パッケージを diff --git a/docs/development.md b/docs/development.md index 91b6c25e..d57411cb 100644 --- a/docs/development.md +++ b/docs/development.md @@ -51,15 +51,16 @@ docker run --rm unity-cli-dev dotnet test lsp/Server.Tests.csproj `unity-cli` works with defaults, but these variables are recommended for CI and multi-instance setups. -| Env | Default | Notes | -| ------------------------------- | ---------------: | ---------------------------------------------- | -| `UNITY_PROJECT_ROOT` | auto-detect | Directory containing `Assets/` and `Packages/` | -| `UNITY_CLI_HOST` | `127.0.0.1` | Unity TCP listener host | -| `UNITY_CLI_PORT` | `6400` | Unity TCP listener port | -| `UNITY_CLI_TIMEOUT_MS` | `30000` | Command timeout (ms) | -| `UNITY_CLI_LSP_MODE` | `off` | `off`, `auto`, `required` | -| `UNITY_CLI_UNITYD_IDLE_TIMEOUT` | `600` | Daemon idle timeout (seconds) | -| `UNITY_CLI_TOOLS_ROOT` | platform default | Root directory for downloaded tools | +| Env | Default | Notes | +| ------------------------------- | ---------------: | ----------------------------------------------- | +| `UNITY_PROJECT_ROOT` | auto-detect | Directory containing `Assets/` and `Packages/` | +| `UNITY_CLI_HOST` | `127.0.0.1` | Unity TCP listener host | +| `UNITY_CLI_PORT` | `6400` | Unity TCP listener port | +| `UNITY_CLI_TIMEOUT_MS` | `30000` | Command timeout (ms) | +| `UNITY_CLI_LSP_MODE` | `auto` | `off`, `auto`, `required` | +| `UNITY_CLI_LSP_AUTO_TIMEOUT_MS` | `10000` | `auto` symbol search wait before index fallback | +| `UNITY_CLI_UNITYD_IDLE_TIMEOUT` | `600` | Daemon idle timeout (seconds) | +| `UNITY_CLI_TOOLS_ROOT` | platform default | Root directory for downloaded tools | Minimal setup: @@ -556,11 +557,12 @@ Windows verification is tracked separately in Issue #308. ### LSP Issues -| Symptom | Fix | -| ---------------------------- | ------------------------------------------ | -| LSP command not found | Run `unity-cli lsp install` and retry | -| LSP timeout | Increase `UNITY_CLI_TIMEOUT_MS` and retry | -| LSP required but unavailable | Use `UNITY_CLI_LSP_MODE=auto` during setup | +| Symptom | Fix | +| ---------------------------------------- | ------------------------------------------------------------------------------------------- | +| LSP command not found | Run `unity-cli lsp install` and retry | +| LSP timeout | Increase `UNITY_CLI_TIMEOUT_MS` and retry | +| LSP required but unavailable | Use `UNITY_CLI_LSP_MODE=auto` during setup | +| Symbol search returns `backend: "index"` | Read `fallbackReason`; run `unity-cli lsp install` or raise `UNITY_CLI_LSP_AUTO_TIMEOUT_MS` | ### WSL2/Docker -> Windows Unity @@ -585,7 +587,7 @@ echo "$UNITY_CLI_HOST:$UNITY_CLI_PORT" ## CI Overview -CI is defined in `.github/workflows/lint.yml`, `.github/workflows/test.yml`, and `.github/workflows/skill-routing-eval.yml`. +CI is defined in `.github/workflows/lint.yml`, `.github/workflows/test.yml`, `.github/workflows/published-install.yml`, and `.github/workflows/skill-routing-eval.yml`. | Job | Trigger | Description | | ------------------------------ | ----------------------- | ------------------------------------------------------------------------------------- | @@ -595,6 +597,7 @@ CI is defined in `.github/workflows/lint.yml`, `.github/workflows/test.yml`, and | LSP Performance (required) | push / PR | `scripts/lsp-perf-check.sh` (full cases + history artifact) | | CLI Latency (required) | push / PR | `scripts/bench-cli-latency.py` (p50/p95 budgets + injected-delay evidence) | | Skill Routing Eval | daily schedule / manual | `scripts/skill-eval/llm-routing-eval.sh` (`.github/workflows/skill-routing-eval.yml`) | +| Windows Published Install | release / cron / manual | latest release via `install.ps1` (`.github/workflows/published-install.yml`) | Skill Contract Check, Rust Tests, LSP Tests, LSP Performance, and CLI Latency are required checks for PR merges. @@ -938,7 +941,8 @@ docker run --rm unity-cli-dev dotnet test lsp/Server.Tests.csproj | `UNITY_CLI_HOST` | `127.0.0.1` | Unity TCP リスナーのホスト | | `UNITY_CLI_PORT` | `6400` | Unity TCP リスナーのポート | | `UNITY_CLI_TIMEOUT_MS` | `30000` | コマンドタイムアウト (ms) | -| `UNITY_CLI_LSP_MODE` | `off` | `off`, `auto`, `required` | +| `UNITY_CLI_LSP_MODE` | `auto` | `off`, `auto`, `required` | +| `UNITY_CLI_LSP_AUTO_TIMEOUT_MS` | `10000` | `auto` のシンボル検索が LSP を待つ上限 (ms) | | `UNITY_CLI_UNITYD_IDLE_TIMEOUT` | `600` | デーモンアイドルタイムアウト(秒) | | `UNITY_CLI_TOOLS_ROOT` | OS依存既定 | ツール配置ルート | @@ -1211,11 +1215,12 @@ batch / sequence の応答もジェスチャー終了待ちではなく受付結 ### LSP関連 -| 症状 | 対処 | -| ----------------------------- | ------------------------------------------------- | -| LSP実行ファイルが見つからない | `unity-cli lsp install` を実行して再試行 | -| LSPタイムアウト | `UNITY_CLI_TIMEOUT_MS` を延長 | -| 必須LSPモードで失敗 | セットアップ中は `UNITY_CLI_LSP_MODE=auto` を利用 | +| 症状 | 対処 | +| ---------------------------------------- | ------------------------------------------------------------------------------------------------------ | +| LSP実行ファイルが見つからない | `unity-cli lsp install` を実行して再試行 | +| LSPタイムアウト | `UNITY_CLI_TIMEOUT_MS` を延長 | +| 必須LSPモードで失敗 | セットアップ中は `UNITY_CLI_LSP_MODE=auto` を利用 | +| シンボル検索が `backend: "index"` を返す | `fallbackReason` を確認し、`unity-cli lsp install` を実行するか `UNITY_CLI_LSP_AUTO_TIMEOUT_MS` を延長 | ### WSL2/Docker -> Windows Unity @@ -1240,7 +1245,7 @@ echo "$UNITY_CLI_HOST:$UNITY_CLI_PORT" ## CI の概要 -CI は `.github/workflows/lint.yml` / `.github/workflows/test.yml` / `.github/workflows/skill-routing-eval.yml` で定義されています。 +CI は `.github/workflows/lint.yml` / `.github/workflows/test.yml` / `.github/workflows/published-install.yml` / `.github/workflows/skill-routing-eval.yml` で定義されています。 | ジョブ | トリガー | 内容 | | ------------------------------ | ----------------------- | -------------------------------------------------------------------------------------- | @@ -1250,6 +1255,7 @@ CI は `.github/workflows/lint.yml` / `.github/workflows/test.yml` / `.github/wo | LSP Performance (required) | push / PR | `scripts/lsp-perf-check.sh`(全ケース実行 + 履歴artifact) | | CLI Latency (required) | push / PR | `scripts/bench-cli-latency.py`(p50/p95 予算 + 遅延注入の証跡) | | Skill Routing Eval | 毎日スケジュール / 手動 | `scripts/skill-eval/llm-routing-eval.sh`(`.github/workflows/skill-routing-eval.yml`) | +| Windows Published Install | Release 後/週次/手動 | 最新の公開版を `install.ps1` で導入(`.github/workflows/published-install.yml`) | Skill Contract Check / Rust Tests / LSP Tests / LSP Performance / CLI Latency は PR マージの必須チェックです。 diff --git a/docs/hot-reload.md b/docs/hot-reload.md index 5bf960eb..f36d440c 100644 --- a/docs/hot-reload.md +++ b/docs/hot-reload.md @@ -23,8 +23,10 @@ Silicon (ARM64) macOS**. Real method replacement is verified on macOS with 6000.3.25f1 and 2022.3.62f3, both as native ARM64 Editors and as x64 Editors under Rosetta 2. Any other host is rejected before compilation or native patching with `HOT_RELOAD_PLATFORM_UNSUPPORTED`; on such a host use an x64 -build of the Editor. Windows and Linux hardware verification is tracked in -Issue #386. +build of the Editor. Windows x64 Unity 6000.4.4f1 also passed 25 real replacement, +state preservation, failure and recovery checks with FSR 1.8.0: +[Issue #386 evidence](verification/issue-386/resume/hot-reload-results.txt). +Linux hardware verification remains pending in Issue #386. Disable Fast Script Reload's automatic and on-demand reload before beginning. The Bridge rejects concurrent ownership instead of changing those preferences. diff --git a/docs/lsp-write-reliability-windows.json b/docs/lsp-write-reliability-windows.json new file mode 100644 index 00000000..7ddb563b --- /dev/null +++ b/docs/lsp-write-reliability-windows.json @@ -0,0 +1,2622 @@ +{ + "schema_version": 1, + "os": "Windows", + "rid": "win-x64", + "started_at": "2026-10-13T07:56:21.677570+00:00", + "cli_sha256": "36c6d6ff78e301e9c07fa880628eebdfee2f41c9e11fb524206300b0ea68ee23", + "scope": "Completed warm_indexed slice, initial Windows measurement; other conditions are not represented.", + "source_head": "ef464584543a9d4f692120366b0b485cc6bec43c", + "summary": { + "attempts": 57, + "successes": 6, + "success_rate": 0.10526315789473684, + "failure_types": { + "bom_added": 51, + "text_changed": 6 + }, + "p50_ms": 260.755, + "p95_ms": 293.267, + "direct_p50_ms": 0.596, + "direct_p95_ms": 1.198 + }, + "rows": [ + { + "scenario": "create_class_monobehaviour", + "tool": "create_class", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 0.9078000002773479, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "bbd67e077a1ea2071930829d291635208f148a019060826ffbd182dcb66b6c1d", + "lsp_sha256": "a5709764cc34583026940f58eb1c0f5b6786b067cfabb0169a57ada0417193ed", + "direct_bytes": 60, + "lsp_bytes": 63, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,4 +1,4 @@\n-using UnityEngine;\n+using UnityEngine;\n \n public class Sample : MonoBehaviour\n {\n" + } + ], + "setup_ms": 2726.3216999999713, + "returncode": 0, + "response": { + "command": "raw create_class", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "content": "using UnityEngine;\n\npublic class Sample : MonoBehaviour\n{\n}\n", + "diagnostics": [], + "diffPreview": [], + "path": "Assets/Sample.cs", + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_class\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"content\":\"using UnityEngine;\\n\\npublic class Sample : MonoBehaviour\\n{\\n}\\n\",\"diagnostics\":[],\"diffPreview\":[],\"path\":\"Assets/Sample.cs\",\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 277.27239999876474, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "create_class_monobehaviour", + "tool": "create_class", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.9804000001167879, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "bbd67e077a1ea2071930829d291635208f148a019060826ffbd182dcb66b6c1d", + "lsp_sha256": "a5709764cc34583026940f58eb1c0f5b6786b067cfabb0169a57ada0417193ed", + "direct_bytes": 60, + "lsp_bytes": 63, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,4 +1,4 @@\n-using UnityEngine;\n+using UnityEngine;\n \n public class Sample : MonoBehaviour\n {\n" + } + ], + "setup_ms": 2767.2376000009535, + "returncode": 0, + "response": { + "command": "raw create_class", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "content": "using UnityEngine;\n\npublic class Sample : MonoBehaviour\n{\n}\n", + "diagnostics": [], + "diffPreview": [], + "path": "Assets/Sample.cs", + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_class\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"content\":\"using UnityEngine;\\n\\npublic class Sample : MonoBehaviour\\n{\\n}\\n\",\"diagnostics\":[],\"diffPreview\":[],\"path\":\"Assets/Sample.cs\",\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 277.41040000000794, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "create_class_monobehaviour", + "tool": "create_class", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 1.0604999988572672, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "bbd67e077a1ea2071930829d291635208f148a019060826ffbd182dcb66b6c1d", + "lsp_sha256": "a5709764cc34583026940f58eb1c0f5b6786b067cfabb0169a57ada0417193ed", + "direct_bytes": 60, + "lsp_bytes": 63, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,4 +1,4 @@\n-using UnityEngine;\n+using UnityEngine;\n \n public class Sample : MonoBehaviour\n {\n" + } + ], + "setup_ms": 2928.5495999993145, + "returncode": 0, + "response": { + "command": "raw create_class", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "content": "using UnityEngine;\n\npublic class Sample : MonoBehaviour\n{\n}\n", + "diagnostics": [], + "diffPreview": [], + "path": "Assets/Sample.cs", + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_class\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"content\":\"using UnityEngine;\\n\\npublic class Sample : MonoBehaviour\\n{\\n}\\n\",\"diagnostics\":[],\"diffPreview\":[],\"path\":\"Assets/Sample.cs\",\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 276.7844999998488, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "create_class_scriptableobject", + "tool": "create_class", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 1.0077000006276648, + "failures": [ + "bom_added", + "text_changed" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "9e4068040ddbcd6fd5e13bdec0cccb8834f4d7c50cb83621ba8b1f94006e8114", + "lsp_sha256": "61cc7c4b376b878b0c07bfc7ca64fb4a357bff0b546ed72bb358f9ffeef89f34", + "direct_bytes": 63, + "lsp_bytes": 46, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,5 +1,3 @@\n-using UnityEngine;\n-\n-public class Sample : ScriptableObject\n+public class Sample : ScriptableObject\n {\n }\n" + } + ], + "setup_ms": 2938.434600000619, + "returncode": 0, + "response": { + "command": "raw create_class", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "content": "public class Sample : ScriptableObject\n{\n}\n", + "diagnostics": [], + "diffPreview": [], + "path": "Assets/Sample.cs", + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_class\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"content\":\"public class Sample : ScriptableObject\\n{\\n}\\n\",\"diagnostics\":[],\"diffPreview\":[],\"path\":\"Assets/Sample.cs\",\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 274.7672000004968, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "create_class_scriptableobject", + "tool": "create_class", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.8920000000216532, + "failures": [ + "bom_added", + "text_changed" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "9e4068040ddbcd6fd5e13bdec0cccb8834f4d7c50cb83621ba8b1f94006e8114", + "lsp_sha256": "61cc7c4b376b878b0c07bfc7ca64fb4a357bff0b546ed72bb358f9ffeef89f34", + "direct_bytes": 63, + "lsp_bytes": 46, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,5 +1,3 @@\n-using UnityEngine;\n-\n-public class Sample : ScriptableObject\n+public class Sample : ScriptableObject\n {\n }\n" + } + ], + "setup_ms": 2944.0462999991723, + "returncode": 0, + "response": { + "command": "raw create_class", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "content": "public class Sample : ScriptableObject\n{\n}\n", + "diagnostics": [], + "diffPreview": [], + "path": "Assets/Sample.cs", + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_class\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"content\":\"public class Sample : ScriptableObject\\n{\\n}\\n\",\"diagnostics\":[],\"diffPreview\":[],\"path\":\"Assets/Sample.cs\",\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 277.60940000007395, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "create_class_scriptableobject", + "tool": "create_class", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 0.9135000000242144, + "failures": [ + "bom_added", + "text_changed" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "9e4068040ddbcd6fd5e13bdec0cccb8834f4d7c50cb83621ba8b1f94006e8114", + "lsp_sha256": "61cc7c4b376b878b0c07bfc7ca64fb4a357bff0b546ed72bb358f9ffeef89f34", + "direct_bytes": 63, + "lsp_bytes": 46, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,5 +1,3 @@\n-using UnityEngine;\n-\n-public class Sample : ScriptableObject\n+public class Sample : ScriptableObject\n {\n }\n" + } + ], + "setup_ms": 2918.0077000000892, + "returncode": 0, + "response": { + "command": "raw create_class", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "content": "public class Sample : ScriptableObject\n{\n}\n", + "diagnostics": [], + "diffPreview": [], + "path": "Assets/Sample.cs", + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_class\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"content\":\"public class Sample : ScriptableObject\\n{\\n}\\n\",\"diagnostics\":[],\"diffPreview\":[],\"path\":\"Assets/Sample.cs\",\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 274.4991999988997, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "create_class_plain", + "tool": "create_class", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 1.0087999999086605, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "c629ef557fa767f4e896d8a91c5ea5f17ab4bd190bd2f7154b70949cde68905b", + "lsp_sha256": "2396be216daf166ada783949e3ce24a74bd439b90959def00decb977835de99b", + "direct_bytes": 24, + "lsp_bytes": 27, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,3 +1,3 @@\n-public class Sample\n+public class Sample\n {\n }\n" + } + ], + "setup_ms": 2953.842999999324, + "returncode": 0, + "response": { + "command": "raw create_class", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "content": "public class Sample\n{\n}\n", + "diagnostics": [], + "diffPreview": [], + "path": "Assets/Sample.cs", + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_class\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"content\":\"public class Sample\\n{\\n}\\n\",\"diagnostics\":[],\"diffPreview\":[],\"path\":\"Assets/Sample.cs\",\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 276.31750000000466, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "create_class_plain", + "tool": "create_class", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.9522000000288244, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "c629ef557fa767f4e896d8a91c5ea5f17ab4bd190bd2f7154b70949cde68905b", + "lsp_sha256": "2396be216daf166ada783949e3ce24a74bd439b90959def00decb977835de99b", + "direct_bytes": 24, + "lsp_bytes": 27, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,3 +1,3 @@\n-public class Sample\n+public class Sample\n {\n }\n" + } + ], + "setup_ms": 2966.1285000001953, + "returncode": 0, + "response": { + "command": "raw create_class", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "content": "public class Sample\n{\n}\n", + "diagnostics": [], + "diffPreview": [], + "path": "Assets/Sample.cs", + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_class\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"content\":\"public class Sample\\n{\\n}\\n\",\"diagnostics\":[],\"diffPreview\":[],\"path\":\"Assets/Sample.cs\",\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 277.72229999936826, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "create_class_plain", + "tool": "create_class", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 1.0165999992750585, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "c629ef557fa767f4e896d8a91c5ea5f17ab4bd190bd2f7154b70949cde68905b", + "lsp_sha256": "2396be216daf166ada783949e3ce24a74bd439b90959def00decb977835de99b", + "direct_bytes": 24, + "lsp_bytes": 27, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,3 +1,3 @@\n-public class Sample\n+public class Sample\n {\n }\n" + } + ], + "setup_ms": 2941.6794999997364, + "returncode": 0, + "response": { + "command": "raw create_class", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "content": "public class Sample\n{\n}\n", + "diagnostics": [], + "diffPreview": [], + "path": "Assets/Sample.cs", + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_class\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"content\":\"public class Sample\\n{\\n}\\n\",\"diagnostics\":[],\"diffPreview\":[],\"path\":\"Assets/Sample.cs\",\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 276.1365000005753, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "create_plain", + "tool": "create_csharp_file", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 0.9224999994330574, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "edbe481b5cca42c8e7665f2a02eddba612cd759d03f48a710d6f9ac8f41dcf3e", + "lsp_sha256": "9cd38476c737f80a85845c39b9c6d5cc11e918feb37fb325f615e72f42b0f312", + "direct_bytes": 23, + "lsp_bytes": 26, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample {}\n+public class Sample {}\n" + } + ], + "setup_ms": 2924.0387000008923, + "returncode": 0, + "response": { + "command": "raw create_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 272.0348000002559, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "create_plain", + "tool": "create_csharp_file", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.8880000004864996, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "edbe481b5cca42c8e7665f2a02eddba612cd759d03f48a710d6f9ac8f41dcf3e", + "lsp_sha256": "9cd38476c737f80a85845c39b9c6d5cc11e918feb37fb325f615e72f42b0f312", + "direct_bytes": 23, + "lsp_bytes": 26, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample {}\n+public class Sample {}\n" + } + ], + "setup_ms": 2954.666300000099, + "returncode": 0, + "response": { + "command": "raw create_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 272.54480000010517, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "create_plain", + "tool": "create_csharp_file", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 1.0884999992413213, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "edbe481b5cca42c8e7665f2a02eddba612cd759d03f48a710d6f9ac8f41dcf3e", + "lsp_sha256": "9cd38476c737f80a85845c39b9c6d5cc11e918feb37fb325f615e72f42b0f312", + "direct_bytes": 23, + "lsp_bytes": 26, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample {}\n+public class Sample {}\n" + } + ], + "setup_ms": 2948.2929000005242, + "returncode": 0, + "response": { + "command": "raw create_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 272.28550000108953, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "create_monobehaviour", + "tool": "create_csharp_file", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 1.0600000005069887, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "cdfd3cb55c9b959cf5bcf9f1bb41f5b36eb12fa419acf9cded1138cba4fd700d", + "lsp_sha256": "50b6c9b1e277e77df822088d892da43cf1546524f8305fce72fbbc8b069ec0cf", + "direct_bytes": 58, + "lsp_bytes": 61, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,2 +1,2 @@\n-using UnityEngine;\n+using UnityEngine;\n public class Sample : MonoBehaviour {}\n" + } + ], + "setup_ms": 2937.5804999999673, + "returncode": 0, + "response": { + "command": "raw create_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 283.6886000004597, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "create_monobehaviour", + "tool": "create_csharp_file", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 1.060100001268438, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "cdfd3cb55c9b959cf5bcf9f1bb41f5b36eb12fa419acf9cded1138cba4fd700d", + "lsp_sha256": "50b6c9b1e277e77df822088d892da43cf1546524f8305fce72fbbc8b069ec0cf", + "direct_bytes": 58, + "lsp_bytes": 61, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,2 +1,2 @@\n-using UnityEngine;\n+using UnityEngine;\n public class Sample : MonoBehaviour {}\n" + } + ], + "setup_ms": 2943.190500000128, + "returncode": 0, + "response": { + "command": "raw create_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 278.33079999982147, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "create_monobehaviour", + "tool": "create_csharp_file", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 1.0497000002942514, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "cdfd3cb55c9b959cf5bcf9f1bb41f5b36eb12fa419acf9cded1138cba4fd700d", + "lsp_sha256": "50b6c9b1e277e77df822088d892da43cf1546524f8305fce72fbbc8b069ec0cf", + "direct_bytes": 58, + "lsp_bytes": 61, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,2 +1,2 @@\n-using UnityEngine;\n+using UnityEngine;\n public class Sample : MonoBehaviour {}\n" + } + ], + "setup_ms": 2966.040899998916, + "returncode": 0, + "response": { + "command": "raw create_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 277.54950000053213, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "create_scriptableobject", + "tool": "create_csharp_file", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 0.9907999992719851, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "fdd183a4d7fcc3118e98d3f62079dff999a0c2310d5de2e98f7cb1cf055b24d2", + "lsp_sha256": "7eba30a7b9514668698fe135a10bf742ada3503fe3540cb1c9050d31e400a3e5", + "direct_bytes": 61, + "lsp_bytes": 64, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,2 +1,2 @@\n-using UnityEngine;\n+using UnityEngine;\n public class Sample : ScriptableObject {}\n" + } + ], + "setup_ms": 2937.8426000002946, + "returncode": 0, + "response": { + "command": "raw create_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 287.3501000012766, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "create_scriptableobject", + "tool": "create_csharp_file", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.9838000005402137, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "fdd183a4d7fcc3118e98d3f62079dff999a0c2310d5de2e98f7cb1cf055b24d2", + "lsp_sha256": "7eba30a7b9514668698fe135a10bf742ada3503fe3540cb1c9050d31e400a3e5", + "direct_bytes": 61, + "lsp_bytes": 64, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,2 +1,2 @@\n-using UnityEngine;\n+using UnityEngine;\n public class Sample : ScriptableObject {}\n" + } + ], + "setup_ms": 2961.0620999992534, + "returncode": 0, + "response": { + "command": "raw create_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 283.5336999996798, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "create_scriptableobject", + "tool": "create_csharp_file", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 1.154899999164627, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "fdd183a4d7fcc3118e98d3f62079dff999a0c2310d5de2e98f7cb1cf055b24d2", + "lsp_sha256": "7eba30a7b9514668698fe135a10bf742ada3503fe3540cb1c9050d31e400a3e5", + "direct_bytes": 61, + "lsp_bytes": 64, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,2 +1,2 @@\n-using UnityEngine;\n+using UnityEngine;\n public class Sample : ScriptableObject {}\n" + } + ], + "setup_ms": 2949.3394999990414, + "returncode": 0, + "response": { + "command": "raw create_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw create_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 276.03049999925133, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "replace_body", + "tool": "replace_symbol_body", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 0.5518000016309088, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 3019.1185000003316, + "returncode": 0, + "response": { + "command": "raw replace_symbol_body", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw replace_symbol_body\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 263.8390000010986, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "replace_body", + "tool": "replace_symbol_body", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.4943999992974568, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 3004.1794999997364, + "returncode": 0, + "response": { + "command": "raw replace_symbol_body", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw replace_symbol_body\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 257.6360000002751, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "replace_body", + "tool": "replace_symbol_body", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 0.5726999988837633, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 3012.814800000342, + "returncode": 0, + "response": { + "command": "raw replace_symbol_body", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw replace_symbol_body\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 255.59340000108932, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 0.46890000157873146, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 2997.1442999994906, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 229.74100000101316, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.48919999971985817, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 3008.276399999886, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 221.43129999858502, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 0.5059000013716286, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 3010.096699999849, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 223.1549999996787, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "insert_before", + "tool": "insert_before_symbol", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 0.4769000006490387, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "d69ec0dbd444819d7ab99c2a495a056f641b131bc27815437e5a69c02ac9e736", + "lsp_sha256": "00d2d4dfe04b5d03979eee2ac5bc2ea66329255591a91bd05605dc37d9ead354", + "direct_bytes": 67, + "lsp_bytes": 70, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample {public int Added;public int Run(){return 1;}}\n+public class Sample {public int Added;public int Run(){return 1;}}\n" + } + ], + "setup_ms": 3062.878800001272, + "returncode": 0, + "response": { + "command": "raw insert_before_symbol", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw insert_before_symbol\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 264.19560000067577, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "insert_before", + "tool": "insert_before_symbol", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.5049999999755528, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "d69ec0dbd444819d7ab99c2a495a056f641b131bc27815437e5a69c02ac9e736", + "lsp_sha256": "00d2d4dfe04b5d03979eee2ac5bc2ea66329255591a91bd05605dc37d9ead354", + "direct_bytes": 67, + "lsp_bytes": 70, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample {public int Added;public int Run(){return 1;}}\n+public class Sample {public int Added;public int Run(){return 1;}}\n" + } + ], + "setup_ms": 3026.5687000010075, + "returncode": 0, + "response": { + "command": "raw insert_before_symbol", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw insert_before_symbol\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 262.19660000060685, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "insert_before", + "tool": "insert_before_symbol", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 0.4496000001381617, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "d69ec0dbd444819d7ab99c2a495a056f641b131bc27815437e5a69c02ac9e736", + "lsp_sha256": "00d2d4dfe04b5d03979eee2ac5bc2ea66329255591a91bd05605dc37d9ead354", + "direct_bytes": 67, + "lsp_bytes": 70, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample {public int Added;public int Run(){return 1;}}\n+public class Sample {public int Added;public int Run(){return 1;}}\n" + } + ], + "setup_ms": 3020.2819000005547, + "returncode": 0, + "response": { + "command": "raw insert_before_symbol", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw insert_before_symbol\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 260.6156000001647, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "insert_after", + "tool": "insert_after_symbol", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 0.47679999988758937, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "04ee4146423db15d890a6fdc7a66107e933dbad7d335c76b899548c84a276f8a", + "lsp_sha256": "3204a749c2dbfac81557fba80883dea1ece77d9b178e8c4bd560c08221a7d8ab", + "direct_bytes": 67, + "lsp_bytes": 70, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample {public int Run(){return 1;}public int Added;}\n+public class Sample {public int Run(){return 1;}public int Added;}\n" + } + ], + "setup_ms": 3011.7695999997522, + "returncode": 0, + "response": { + "command": "raw insert_after_symbol", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw insert_after_symbol\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 260.75479999963136, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "insert_after", + "tool": "insert_after_symbol", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.45679999857384246, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "04ee4146423db15d890a6fdc7a66107e933dbad7d335c76b899548c84a276f8a", + "lsp_sha256": "3204a749c2dbfac81557fba80883dea1ece77d9b178e8c4bd560c08221a7d8ab", + "direct_bytes": 67, + "lsp_bytes": 70, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample {public int Run(){return 1;}public int Added;}\n+public class Sample {public int Run(){return 1;}public int Added;}\n" + } + ], + "setup_ms": 3019.4062999999005, + "returncode": 0, + "response": { + "command": "raw insert_after_symbol", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw insert_after_symbol\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 265.448699999979, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "insert_after", + "tool": "insert_after_symbol", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 0.44750000051863026, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "04ee4146423db15d890a6fdc7a66107e933dbad7d335c76b899548c84a276f8a", + "lsp_sha256": "3204a749c2dbfac81557fba80883dea1ece77d9b178e8c4bd560c08221a7d8ab", + "direct_bytes": 67, + "lsp_bytes": 70, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample {public int Run(){return 1;}public int Added;}\n+public class Sample {public int Run(){return 1;}public int Added;}\n" + } + ], + "setup_ms": 3007.0403999998234, + "returncode": 0, + "response": { + "command": "raw insert_after_symbol", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw insert_after_symbol\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 260.5844999998226, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "remove_member", + "tool": "remove_symbol", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 0.6964000003790716, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "edbe481b5cca42c8e7665f2a02eddba612cd759d03f48a710d6f9ac8f41dcf3e", + "lsp_sha256": "9cd38476c737f80a85845c39b9c6d5cc11e918feb37fb325f615e72f42b0f312", + "direct_bytes": 23, + "lsp_bytes": 26, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample {}\n+public class Sample {}\n" + } + ], + "setup_ms": 2998.348700000861, + "returncode": 0, + "response": { + "command": "raw remove_symbol", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw remove_symbol\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 255.70640000114508, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "remove_member", + "tool": "remove_symbol", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.4540999998425832, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "edbe481b5cca42c8e7665f2a02eddba612cd759d03f48a710d6f9ac8f41dcf3e", + "lsp_sha256": "9cd38476c737f80a85845c39b9c6d5cc11e918feb37fb325f615e72f42b0f312", + "direct_bytes": 23, + "lsp_bytes": 26, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample {}\n+public class Sample {}\n" + } + ], + "setup_ms": 3051.758300000074, + "returncode": 0, + "response": { + "command": "raw remove_symbol", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw remove_symbol\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 252.6543000003585, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "remove_member", + "tool": "remove_symbol", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 0.5821999984618742, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "edbe481b5cca42c8e7665f2a02eddba612cd759d03f48a710d6f9ac8f41dcf3e", + "lsp_sha256": "9cd38476c737f80a85845c39b9c6d5cc11e918feb37fb325f615e72f42b0f312", + "direct_bytes": 23, + "lsp_bytes": 26, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample {}\n+public class Sample {}\n" + } + ], + "setup_ms": 3032.8964999989694, + "returncode": 0, + "response": { + "command": "raw remove_symbol", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw remove_symbol\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 253.75359999998182, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "namespace_partial_generic_attributes", + "tool": "replace_symbol_body", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 0.5580999986705137, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "f2958b4d92901e48bc79cb95602dd97f9acc75094171c71096b130e96354bc43", + "lsp_sha256": "b0ffa3094f22b01473580725d49c4b3766228f1ff3dc56917319a31d5050db91", + "direct_bytes": 121, + "lsp_bytes": 124, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-namespace Demo { [System.Serializable] public partial class Sample { public T Run(){throw new System.Exception();}} }\n+namespace Demo { [System.Serializable] public partial class Sample { public T Run(){throw new System.Exception();}} }\n" + } + ], + "setup_ms": 3042.409299998326, + "returncode": 0, + "response": { + "command": "raw replace_symbol_body", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw replace_symbol_body\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 261.83640000090236, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "namespace_partial_generic_attributes", + "tool": "replace_symbol_body", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.4955000003974419, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "f2958b4d92901e48bc79cb95602dd97f9acc75094171c71096b130e96354bc43", + "lsp_sha256": "b0ffa3094f22b01473580725d49c4b3766228f1ff3dc56917319a31d5050db91", + "direct_bytes": 121, + "lsp_bytes": 124, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-namespace Demo { [System.Serializable] public partial class Sample { public T Run(){throw new System.Exception();}} }\n+namespace Demo { [System.Serializable] public partial class Sample { public T Run(){throw new System.Exception();}} }\n" + } + ], + "setup_ms": 3037.8657999990537, + "returncode": 0, + "response": { + "command": "raw replace_symbol_body", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw replace_symbol_body\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 261.2568000004103, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "namespace_partial_generic_attributes", + "tool": "replace_symbol_body", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 0.4626000009011477, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "f2958b4d92901e48bc79cb95602dd97f9acc75094171c71096b130e96354bc43", + "lsp_sha256": "b0ffa3094f22b01473580725d49c4b3766228f1ff3dc56917319a31d5050db91", + "direct_bytes": 121, + "lsp_bytes": 124, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-namespace Demo { [System.Serializable] public partial class Sample { public T Run(){throw new System.Exception();}} }\n+namespace Demo { [System.Serializable] public partial class Sample { public T Run(){throw new System.Exception();}} }\n" + } + ], + "setup_ms": 3029.089200001181, + "returncode": 0, + "response": { + "command": "raw replace_symbol_body", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw replace_symbol_body\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 260.2519000010943, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "replace_preserve_comment", + "tool": "replace_symbol_body", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 0.4487000005610753, + "failures": [ + "bom_added", + "text_changed" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "6c34cfdc6d1551adcc04b467110a0f49dcd57dbd64161f53b2c40f3d3213acb4", + "lsp_sha256": "b325682282a26cf6d3fffbe65624f11f535ccf233915b4f647defb6d3eea891b", + "direct_bytes": 112, + "lsp_bytes": 83, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,2 +1 @@\n-public class Sample { public int Run(){return 2;} // 日本語の説明を保持\n-public int Next(){return 3;} }\n+public class Sample { public int Run(){return 2;}public int Next(){return 3;} }\n" + } + ], + "setup_ms": 3028.714800000671, + "returncode": 0, + "response": { + "command": "raw replace_symbol_body", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw replace_symbol_body\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 262.7495999986422, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "replace_preserve_comment", + "tool": "replace_symbol_body", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.594900000578491, + "failures": [ + "bom_added", + "text_changed" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "6c34cfdc6d1551adcc04b467110a0f49dcd57dbd64161f53b2c40f3d3213acb4", + "lsp_sha256": "b325682282a26cf6d3fffbe65624f11f535ccf233915b4f647defb6d3eea891b", + "direct_bytes": 112, + "lsp_bytes": 83, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,2 +1 @@\n-public class Sample { public int Run(){return 2;} // 日本語の説明を保持\n-public int Next(){return 3;} }\n+public class Sample { public int Run(){return 2;}public int Next(){return 3;} }\n" + } + ], + "setup_ms": 3024.2627000006905, + "returncode": 0, + "response": { + "command": "raw replace_symbol_body", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw replace_symbol_body\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 260.5406000002404, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "replace_preserve_comment", + "tool": "replace_symbol_body", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 0.5334999987098854, + "failures": [ + "bom_added", + "text_changed" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "6c34cfdc6d1551adcc04b467110a0f49dcd57dbd64161f53b2c40f3d3213acb4", + "lsp_sha256": "b325682282a26cf6d3fffbe65624f11f535ccf233915b4f647defb6d3eea891b", + "direct_bytes": 112, + "lsp_bytes": 83, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,2 +1 @@\n-public class Sample { public int Run(){return 2;} // 日本語の説明を保持\n-public int Next(){return 3;} }\n+public class Sample { public int Run(){return 2;}public int Next(){return 3;} }\n" + } + ], + "setup_ms": 2987.321799999336, + "returncode": 0, + "response": { + "command": "raw replace_symbol_body", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [ + "Sample/Run" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw replace_symbol_body\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[\"Sample/Run\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 257.1067999997467, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "rename_multifile", + "tool": "rename_symbol", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 1.1981999996351078, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "8b604ff92426cc52db63d2309c15a04982106e971961f496c1e7f4e4d4d56fc4", + "lsp_sha256": "6dcbae88500610aa7d38e3f641da418e52421ef87902009d7f8ca51294481a20", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-namespace Demo { public partial class Renamed {} }\n+namespace Demo { public partial class Renamed {} }\n" + }, + { + "path": "Assets/Use.cs", + "direct_sha256": "5feab48ffd84735381e60d33891d68cf7cde00ada091203d28cc830af6563a40", + "lsp_sha256": "009564a8d3056d887a37850f104c973de022a7110d8299ecb80383d52f39a4f8", + "direct_bytes": 67, + "lsp_bytes": 70, + "diff": "--- direct/Assets/Use.cs\n+++ lsp/Assets/Use.cs\n@@ -1 +1 @@\n-namespace Demo { public class Consumer { public Renamed Value; } }\n+namespace Demo { public class Consumer { public Renamed Value; } }\n" + } + ], + "setup_ms": 3007.145200001105, + "returncode": 0, + "response": { + "command": "raw rename_symbol", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs", + "Assets/Use.cs" + ], + "changedSymbols": [ + "Renamed" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw rename_symbol\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\",\"Assets/Use.cs\"],\"changedSymbols\":[\"Renamed\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 293.2671999988088, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "rename_multifile", + "tool": "rename_symbol", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 1.5234000002237735, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "8b604ff92426cc52db63d2309c15a04982106e971961f496c1e7f4e4d4d56fc4", + "lsp_sha256": "6dcbae88500610aa7d38e3f641da418e52421ef87902009d7f8ca51294481a20", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-namespace Demo { public partial class Renamed {} }\n+namespace Demo { public partial class Renamed {} }\n" + }, + { + "path": "Assets/Use.cs", + "direct_sha256": "5feab48ffd84735381e60d33891d68cf7cde00ada091203d28cc830af6563a40", + "lsp_sha256": "009564a8d3056d887a37850f104c973de022a7110d8299ecb80383d52f39a4f8", + "direct_bytes": 67, + "lsp_bytes": 70, + "diff": "--- direct/Assets/Use.cs\n+++ lsp/Assets/Use.cs\n@@ -1 +1 @@\n-namespace Demo { public class Consumer { public Renamed Value; } }\n+namespace Demo { public class Consumer { public Renamed Value; } }\n" + } + ], + "setup_ms": 3012.4161999992793, + "returncode": 0, + "response": { + "command": "raw rename_symbol", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs", + "Assets/Use.cs" + ], + "changedSymbols": [ + "Renamed" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw rename_symbol\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\",\"Assets/Use.cs\"],\"changedSymbols\":[\"Renamed\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 294.02939999999944, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "rename_multifile", + "tool": "rename_symbol", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 1.3335999992705183, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "8b604ff92426cc52db63d2309c15a04982106e971961f496c1e7f4e4d4d56fc4", + "lsp_sha256": "6dcbae88500610aa7d38e3f641da418e52421ef87902009d7f8ca51294481a20", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-namespace Demo { public partial class Renamed {} }\n+namespace Demo { public partial class Renamed {} }\n" + }, + { + "path": "Assets/Use.cs", + "direct_sha256": "5feab48ffd84735381e60d33891d68cf7cde00ada091203d28cc830af6563a40", + "lsp_sha256": "009564a8d3056d887a37850f104c973de022a7110d8299ecb80383d52f39a4f8", + "direct_bytes": 67, + "lsp_bytes": 70, + "diff": "--- direct/Assets/Use.cs\n+++ lsp/Assets/Use.cs\n@@ -1 +1 @@\n-namespace Demo { public class Consumer { public Renamed Value; } }\n+namespace Demo { public class Consumer { public Renamed Value; } }\n" + } + ], + "setup_ms": 3045.9191000009014, + "returncode": 0, + "response": { + "command": "raw rename_symbol", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs", + "Assets/Use.cs" + ], + "changedSymbols": [ + "Renamed" + ], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw rename_symbol\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\",\"Assets/Use.cs\"],\"changedSymbols\":[\"Renamed\"],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 296.29690000001574, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "unicode_no_bom_crlf", + "tool": "write_csharp_file", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 0.5963000003248453, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "dcf3eb1713c010b8259f7d7246f3f557df2f406a6f87331b07219c6966697a3b", + "lsp_sha256": "d2d48c3889d71a6d5b915edfde91ed49a35a4a3b9e48c9fa35596913bc190569", + "direct_bytes": 83, + "lsp_bytes": 86, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,2 +1,2 @@\n-// 日本語コメント 🐈\r\n+// 日本語コメント 🐈\r\n public class Sample { public int Run(){return 2;}}\r\n" + } + ], + "setup_ms": 3057.0062000006146, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 223.1314000000566, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "unicode_no_bom_crlf", + "tool": "write_csharp_file", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.5143999987922143, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "dcf3eb1713c010b8259f7d7246f3f557df2f406a6f87331b07219c6966697a3b", + "lsp_sha256": "d2d48c3889d71a6d5b915edfde91ed49a35a4a3b9e48c9fa35596913bc190569", + "direct_bytes": 83, + "lsp_bytes": 86, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,2 +1,2 @@\n-// 日本語コメント 🐈\r\n+// 日本語コメント 🐈\r\n public class Sample { public int Run(){return 2;}}\r\n" + } + ], + "setup_ms": 2852.099100000487, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 219.99809999942954, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "unicode_no_bom_crlf", + "tool": "write_csharp_file", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 0.5265999989205739, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "dcf3eb1713c010b8259f7d7246f3f557df2f406a6f87331b07219c6966697a3b", + "lsp_sha256": "d2d48c3889d71a6d5b915edfde91ed49a35a4a3b9e48c9fa35596913bc190569", + "direct_bytes": 83, + "lsp_bytes": 86, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,2 +1,2 @@\n-// 日本語コメント 🐈\r\n+// 日本語コメント 🐈\r\n public class Sample { public int Run(){return 2;}}\r\n" + } + ], + "setup_ms": 3080.259300000762, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 220.59280000030412, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "unicode_bom_crlf", + "tool": "write_csharp_file", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 0.5582000012509525, + "failures": [], + "differences": [], + "setup_ms": 3098.4207000001334, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 221.45300000011048, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "unicode_bom_crlf", + "tool": "write_csharp_file", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.5144999995536637, + "failures": [], + "differences": [], + "setup_ms": 3071.7471999996633, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 223.90329999871028, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "unicode_bom_crlf", + "tool": "write_csharp_file", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 0.5811000009998679, + "failures": [], + "differences": [], + "setup_ms": 3043.7713999999687, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 223.55900000002293, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "large_3500_lines", + "tool": "write_csharp_file", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 0.6112000010034535, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "eaa743feccdbb5e5488cd91d7d78299beade017c47a0ea09e202ea40f4ed1875", + "lsp_sha256": "5cf2f01510d47655d012cbc1c7db081d1073aa96201f48be3ccde767fc6d03a5", + "direct_bytes": 113302, + "lsp_bytes": 113305, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,4 +1,4 @@\n-public class Sample {\n+public class Sample {\n public int Field0 = 0;\n public int Field1 = 1;\n public int Field2 = 2;\n" + } + ], + "setup_ms": 3169.600700000956, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 253.24469999941357, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "large_3500_lines", + "tool": "write_csharp_file", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.751499999751104, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "eaa743feccdbb5e5488cd91d7d78299beade017c47a0ea09e202ea40f4ed1875", + "lsp_sha256": "5cf2f01510d47655d012cbc1c7db081d1073aa96201f48be3ccde767fc6d03a5", + "direct_bytes": 113302, + "lsp_bytes": 113305, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,4 +1,4 @@\n-public class Sample {\n+public class Sample {\n public int Field0 = 0;\n public int Field1 = 1;\n public int Field2 = 2;\n" + } + ], + "setup_ms": 3092.7720999989106, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 255.7035999998334, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "large_3500_lines", + "tool": "write_csharp_file", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 0.5707999989681412, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "eaa743feccdbb5e5488cd91d7d78299beade017c47a0ea09e202ea40f4ed1875", + "lsp_sha256": "5cf2f01510d47655d012cbc1c7db081d1073aa96201f48be3ccde767fc6d03a5", + "direct_bytes": 113302, + "lsp_bytes": 113305, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1,4 +1,4 @@\n-public class Sample {\n+public class Sample {\n public int Field0 = 0;\n public int Field1 = 1;\n public int Field2 = 2;\n" + } + ], + "setup_ms": 3127.936700000646, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 253.46890000037092, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "repair_syntax_error", + "tool": "apply_csharp_edits", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 0.97980000100506, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "b03ed722922dca9fdfd87c27472e32c8f90643c5c670f156aef519ac36f960a6", + "lsp_sha256": "ba70d71cf92a2900d9361b83a5876a358484ad591d094070c92b4bcf95c736a0", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 1;}}\n+public class Sample { public int Run(){return 1;}}\n" + }, + { + "path": "Assets/Second.cs", + "direct_sha256": "d62a11646bf6465a334da9c80b94badcb52b96ab98f72972a2ad95c7f63ac45a", + "lsp_sha256": "6f373feff72aab117838b78284f5b3fa36fc0d7fb1d3d5617e646a70bf9e2c7b", + "direct_bytes": 42, + "lsp_bytes": 45, + "diff": "--- direct/Assets/Second.cs\n+++ lsp/Assets/Second.cs\n@@ -1 +1 @@\n-public class Second { public int Added; }\n+public class Second { public int Added; }\n" + } + ], + "setup_ms": 3050.6514999997307, + "returncode": 0, + "response": { + "command": "raw apply_csharp_edits", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs", + "Assets/Second.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw apply_csharp_edits\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\",\"Assets/Second.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 241.70750000121188, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "repair_syntax_error", + "tool": "apply_csharp_edits", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.921599999855971, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "b03ed722922dca9fdfd87c27472e32c8f90643c5c670f156aef519ac36f960a6", + "lsp_sha256": "ba70d71cf92a2900d9361b83a5876a358484ad591d094070c92b4bcf95c736a0", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 1;}}\n+public class Sample { public int Run(){return 1;}}\n" + }, + { + "path": "Assets/Second.cs", + "direct_sha256": "d62a11646bf6465a334da9c80b94badcb52b96ab98f72972a2ad95c7f63ac45a", + "lsp_sha256": "6f373feff72aab117838b78284f5b3fa36fc0d7fb1d3d5617e646a70bf9e2c7b", + "direct_bytes": 42, + "lsp_bytes": 45, + "diff": "--- direct/Assets/Second.cs\n+++ lsp/Assets/Second.cs\n@@ -1 +1 @@\n-public class Second { public int Added; }\n+public class Second { public int Added; }\n" + } + ], + "setup_ms": 3459.9058000003424, + "returncode": 0, + "response": { + "command": "raw apply_csharp_edits", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs", + "Assets/Second.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw apply_csharp_edits\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\",\"Assets/Second.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 244.0794999984064, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "repair_syntax_error", + "tool": "apply_csharp_edits", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 0.9767000010469928, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "b03ed722922dca9fdfd87c27472e32c8f90643c5c670f156aef519ac36f960a6", + "lsp_sha256": "ba70d71cf92a2900d9361b83a5876a358484ad591d094070c92b4bcf95c736a0", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 1;}}\n+public class Sample { public int Run(){return 1;}}\n" + }, + { + "path": "Assets/Second.cs", + "direct_sha256": "d62a11646bf6465a334da9c80b94badcb52b96ab98f72972a2ad95c7f63ac45a", + "lsp_sha256": "6f373feff72aab117838b78284f5b3fa36fc0d7fb1d3d5617e646a70bf9e2c7b", + "direct_bytes": 42, + "lsp_bytes": 45, + "diff": "--- direct/Assets/Second.cs\n+++ lsp/Assets/Second.cs\n@@ -1 +1 @@\n-public class Second { public int Added; }\n+public class Second { public int Added; }\n" + } + ], + "setup_ms": 3057.992500000182, + "returncode": 0, + "response": { + "command": "raw apply_csharp_edits", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs", + "Assets/Second.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw apply_csharp_edits\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\",\"Assets/Second.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 241.2251000005199, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "validate_without_write", + "tool": "validate_text_edits", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 0.500300000567222, + "failures": [], + "differences": [], + "setup_ms": 3095.0474000001122, + "returncode": 0, + "response": { + "command": "raw validate_text_edits", + "data": { + "backend": "lsp", + "diagnostics": [], + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw validate_text_edits\",\"data\":{\"backend\":\"lsp\",\"diagnostics\":[],\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 206.67649999995774, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "validate_without_write", + "tool": "validate_text_edits", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.601499999902444, + "failures": [], + "differences": [], + "setup_ms": 3048.9940000006754, + "returncode": 0, + "response": { + "command": "raw validate_text_edits", + "data": { + "backend": "lsp", + "diagnostics": [], + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw validate_text_edits\",\"data\":{\"backend\":\"lsp\",\"diagnostics\":[],\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 207.30180000100518, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + }, + { + "scenario": "validate_without_write", + "tool": "validate_text_edits", + "condition": "warm_indexed", + "sample": 2, + "direct_ms": 0.5584999998973217, + "failures": [], + "differences": [], + "setup_ms": 3071.909800000867, + "returncode": 0, + "response": { + "command": "raw validate_text_edits", + "data": { + "backend": "lsp", + "diagnostics": [], + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw validate_text_edits\",\"data\":{\"backend\":\"lsp\",\"diagnostics\":[],\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 207.53160000094795, + "lsp_version": "checkout", + "lsp_sha256": "f8f5ce4a833238e45da4fa4f9c9f0518bd8527b1a8f3ae3f65009345e0f1c944" + } + ] +} diff --git a/docs/lsp-write-reliability.md b/docs/lsp-write-reliability.md new file mode 100644 index 00000000..f7e3d13a --- /dev/null +++ b/docs/lsp-write-reliability.md @@ -0,0 +1,266 @@ +# C# LSP 書き込みの信頼性測定(#490) + +## 結論: 現時点では直接編集を禁止できない(DO NOT ENFORCE) + +3 OS × 4 開始条件 × 19 シナリオの全セルを各 3 試行、計 684 試行測定しました。 +期待バイト列と一致したのは各 OS とも 228 試行中 24 試行(10.5%)です。 +目安(全シナリオ・全 OS で成功率 99% 以上、誤編集・エンコーディング/改行の破壊 0 件)を +どの OS・どの開始条件でも満たしていません。オーナーの最終判断のための測定であり、 +この測定は禁止を導入しません。 + +根拠は次のとおりです。 + +1. **BOM の付加(#498)**: BOM なしのファイルを扱う 17 シナリオすべてで、3 OS・4 条件・全試行に + UTF-8 BOM(EF BB BF)が付きました(各 OS 204 件)。直接編集では起きない差分が + ほぼ全ファイルに入ります。一致したのは BOM あり CRLF の更新と、ファイルを変更しない + 構文検証の 2 シナリオだけです。 +2. **コメントの消失(#499)**: `replace_symbol_body` が末尾コメントと改行を消し、次のメンバーと + 連結していました。checkout の LSP では #503 で修正済みで、`warm_indexed` / `unindexed` + では 3 OS とも再発していません。ただし利用者が実際に取得する公開版 LSP `0.18.1` + (`daemon_stopped` / `first_download`)では 3 OS とも 3/3 で再現します。 + 次のリリースまで、エージェントの実環境ではコードを壊す誤編集が残ります。 +3. **ScriptableObject の `using` 欠落(#500)**: #502 で修正済みです。この測定では + 全 OS・全条件で再発していません(残る差分は BOM のみ)。 +4. **コールド起動の遅さと失敗(#501 / #504)**: デーモン停止中の最初の呼び出しは + macOS / Linux で p50 約 3〜4 秒、Windows で p50 約 13 秒でした。先行の run + 38372615105 では Windows が約 43 秒でした。macOS のローカル実行では、自動起動の + 5 秒待ちを超えて編集が行われない試行が 1 件ありました(#501、PR #505 で修正済み)。 + +禁止を再検討できる条件は、#498 の修正、#499 の修正を含む LSP の公開、#504 の改善です。 +checkout の LSP を使う 2 条件では BOM 以外の失敗がないため、#498 を直せば全シナリオが一致する見込みです。 +その後に週次の多試行測定(各 20 試行、コールド各 5 試行)で 99% 以上を確認してください。 +少数試行での 100% は将来の 99% を保証しません。 + +## 測定データの出典 + +| 項目 | 値 | +| --- | --- | +| CI run | [38380911276](https://github.com/akiojin/unity-cli/actions/runs/38380911276)(`Test` workflow、PR #497) | +| 測定対象 | `b5a4059f`(develop の #502 / #503 を取り込み済み) | +| 取得日時 | 2026-10-13 10:05〜10:44 UTC(artifact 取得: 2026-10-13) | +| RID | `win-x64` / `osx-arm64` / `linux-x64`(GitHub-hosted `*-latest`) | +| 試行数 | 各セル 3 試行(コールド条件も 3 試行) | +| LSP | `warm_indexed` / `unindexed` は checkout、`daemon_stopped` / `first_download` は公開版 `0.18.1` | +| 回帰ゲート | 3 OS とも baseline 外の失敗 0 件 | + +CI artifact(`results.json` の生応答と diff)は保存期間 30 日で失われます。 +本文の表がこのレポートの一次資料です。Windows の初期測定の生データは +[lsp-write-reliability-windows.json](lsp-write-reliability-windows.json) に残しています。 + +## OS × 開始条件 + +一致率は期待バイト列と完全に一致した試行の割合です。処理が実行された率や、 +意味的に正しいコードの率ではありません。p50 / p95 は失敗を含む全試行の値です。 + +| OS | 開始条件 | 一致 / 試行 | 一致率 | LSP p50 / p95 ms | 直接編集 p50 / p95 ms | 失敗の種類(件数) | +| --- | --- | ---: | ---: | ---: | ---: | --- | +| Windows | `warm_indexed` | 6/57 | 10.5% | 273 / 297 | 0.50 / 1.23 | bom_added 51 | +| Windows | `daemon_stopped` | 6/57 | 10.5% | 12,929 / 13,338 | 0.56 / 1.27 | bom_added 51, text_changed 3 | +| Windows | `unindexed` | 6/57 | 10.5% | 512 / 560 | 0.62 / 1.21 | bom_added 51 | +| Windows | `first_download` | 6/57 | 10.5% | 13,453 / 14,443 | 0.55 / 1.32 | bom_added 51, text_changed 3 | +| Windows | **全条件** | 24/228 | 10.5% | 578 / 13,636 | 0.55 / 1.23 | bom_added 204, text_changed 6 | +| macOS | `warm_indexed` | 6/57 | 10.5% | 328 / 435 | 0.40 / 2.43 | bom_added 51 | +| macOS | `daemon_stopped` | 6/57 | 10.5% | 3,257 / 4,759 | 0.33 / 1.17 | bom_added 51, text_changed 3 | +| macOS | `unindexed` | 6/57 | 10.5% | 468 / 558 | 0.27 / 1.78 | bom_added 51 | +| macOS | `first_download` | 6/57 | 10.5% | 3,878 / 4,610 | 1.02 / 49.19 | bom_added 51, text_changed 3 | +| macOS | **全条件** | 24/228 | 10.5% | 569 / 4,231 | 0.37 / 19.87 | bom_added 204, text_changed 6 | +| Linux | `warm_indexed` | 6/57 | 10.5% | 242 / 259 | 0.07 / 0.10 | bom_added 51 | +| Linux | `daemon_stopped` | 6/57 | 10.5% | 3,631 / 3,778 | 0.06 / 0.10 | bom_added 51, text_changed 3 | +| Linux | `unindexed` | 6/57 | 10.5% | 354 / 391 | 0.06 / 0.09 | bom_added 51 | +| Linux | `first_download` | 6/57 | 10.5% | 4,045 / 4,281 | 0.07 / 0.11 | bom_added 51, text_changed 3 | +| Linux | **全条件** | 24/228 | 10.5% | 416 / 4,145 | 0.06 / 0.10 | bom_added 204, text_changed 6 | + +## 禁止前に直すべき不具合 + +| Issue | 状態 | 実測 | 代表的な差分 | +| --- | --- | --- | --- | +| [#498](https://github.com/akiojin/unity-cli/issues/498) BOM の付加 | 未修正 | 3 OS × 4 条件で BOM なしの 17 シナリオ全試行 | 先頭に `EF BB BF` が付く | +| [#499](https://github.com/akiojin/unity-cli/issues/499) 末尾コメントの消失 | checkout で修正済み(PR #503)、公開版 `0.18.1` は未修正 | コールド 2 条件 × 3 OS で 3/3 | `public int Run(){return 2;} // 日本語の説明を保持` → `public int Run(){return 2;}public int Next(){return 3;} }` | +| [#500](https://github.com/akiojin/unity-cli/issues/500) ScriptableObject の `using` 欠落 | 修正済み(#502) | 再発 0 件 | (修正前)`using UnityEngine;` が出力されない | +| [#501](https://github.com/akiojin/unity-cli/issues/501) lspd 自動起動の 5 秒タイムアウト | 修正済み(PR #505、この測定の対象 `b5a4059f` には未反映) | macOS ローカル 19 試行中 1 件 | `lspd failed to start within timeout`、編集なし | +| [#504](https://github.com/akiojin/unity-cli/issues/504) Windows のコールド起動 | 修正中(PR #506) | Windows p50 約 13 秒(先行 run では約 43 秒) | 編集は成功するが待ち時間が長い | + +測定ハーネス自体の不具合(macOS の大文字小文字を区別しないファイルシステムで +`Server` を自身へコピーして失敗)は、この PR で修正済みです。製品の不具合とは分けて扱います。 + +## 再現 + +.NET 10、Rust、Python 3.11 以上を使用します。Unity Editor は不要です。 +リポジトリ直下から、対象 OS の RID に合わせて実行します。 + +```bash +cargo build --bin unity-cli +dotnet publish lsp/Server.csproj -c Release -r win-x64 --self-contained true -o .cache/lsp-reliability-publish +python scripts/lsp-write-reliability.py --unity-cli target/debug/unity-cli.exe --lsp-publish .cache/lsp-reliability-publish --out .cache/lsp-reliability --repetitions 20 --download-repetitions 1 --baseline tests/fixtures/lsp-write-baseline.json +``` + +macOS は `osx-arm64` / `osx-x64`、Linux は `linux-x64` / `linux-arm64` を +指定し、CLI パスから `.exe` を除きます。初回ダウンロードにはネットワーク接続が +必要です。既知の失敗も含めて収集するだけなら `--baseline` の代わりに +`--record-only` を指定します。観測した失敗は、どちらのモードでも失敗のまま保存します。 + +## シナリオと起動条件 + +全 10 ツールを 19 シナリオで測定します。 + +| 作業 | ツール / 入力 | +| --- | --- | +| MonoBehaviour / ScriptableObject / 通常クラスの新規作成 | `create_class` と `create_csharp_file` の各 3 種 | +| メソッド本体の置換 | `replace_symbol_body`、通常・namespace/partial/ジェネリクス/属性・日本語の末尾コメント | +| メンバー追加・削除 | `insert_before_symbol` / `insert_after_symbol` / `remove_symbol` | +| ファイル全体の更新 | `write_csharp_file` | +| 複数ファイルのリネーム | `rename_symbol`、別 namespace の同名型は変更しない | +| 日本語 / 絵文字 / UTF-8 / CRLF | BOM ありとなしの両方で `write_csharp_file` | +| 大きなファイル | 3,502 行、最後のフィールドを更新 | +| 構文エラーの修正・複数ファイル更新 | `apply_csharp_edits` | +| 構文検証のみ | `validate_text_edits`、ディスクが変更されないことも検証 | + +| 条件 | 測定開始時の状態 | +| --- | --- | +| `warm_indexed` | 専用 lspd を起動し、そのプロジェクトで `build_index` を完了済み | +| `daemon_stopped` | LSP はインストール済み、lspd は停止。CLI の自動起動を含む | +| `unindexed` | lspd は起動済み、プロジェクトのインデックスは未構築 | +| `first_download` | LSP 未導入の専用 tools root。CLI が公開 LSP を実際に取得する | + +各シナリオ・各試行で空の専用プロジェクトと tools root を使用します。 +直接編集の oracle は独立した期待バイト列を書き込み、LSP 結果から生成しません。 +大きな入力は `--params-file` を使い、Windows のコマンドライン長制限を避けます。 +Windows の lspd はポート 6421 を共有するため、既存の利用者がいる場合は起動失敗として +記録し、他プロセスを停止しません。Unix は試行ごとの専用ソケットを使用します。 + +## 記録と判定 + +`results.json` に OS / RID / CLI SHA256 / LSP SHA256 と VERSION、試行数、 +成功率、各試行の所要時間、失敗分類、CLI の生応答、期待結果との SHA256・バイト数・ +unified diff を記録します。p50 / p95 は失敗を含む全試行の nearest-rank 値です。 +直接編集はファイル書き込み時間、LSP は CLI 起動・パラメーター読込・LSP 呼び出しを含む +時間です。事前のデーモン起動・インデックス構築は `setup_ms` に分離します。 + +成功には CLI と payload の成功、`backend: lsp`、全 `.cs` ファイルの期待バイト列との +一致が必要です。文字列の見た目が同じでも BOM の追加・除去、改行変換を失敗に数えます。 +`text_changed` は空白の差も含む厳密な差分で、意味的誤編集とは自動的に断定しません。 +`lsp_startup_failure` / `timeout` / `download_failure` / `tool_rejected` / `wrong_backend` / +`other` と、`bom_added` / `bom_removed` / `newlines_changed` / `text_changed` / +`file_set_changed` を分け、複数の原因がある試行は各原因を記録します。 + +初回ダウンロードは公開済み LSP、インデックス構築済み/未構築は checkout の LSP を測ります。 +デーモンの自動起動には LSP 自動更新があるため、この条件の実際の VERSION / SHA256 も +記録して区別します。Unity の AssetDatabase refresh、コンパイル、Editor +インポートの信頼性はこの測定の範囲外です。 + +目安は全シナリオ・全 OS で成功率 99% 以上、誤編集・エンコーディング/改行破壊 0 件です。 +OS / 条件 / シナリオが欠ける結果は `INSUFFICIENT`、失敗がある完全なマトリクスは +`DO NOT ENFORCE` と報告します。少数試行での 100% は将来の 99% の保証にはなりません。 +CI は PR / develop push の各 3 試行、週次と手動実行の既定は各 20 試行です。 +PR / push は `Test` workflow から呼び出します。既存の必須 +`LSP Tests (required)` は全 OS の測定完了を待ち、測定失敗時には明示的に失敗します。 +依存 job の skip が成功扱いになる経路も `if: always()` と結果チェックで防ぎます。 +デーモン停止・初回ダウンロードは PR / push で各シナリオ 1 試行、 +週次・手動の既定は各 5 試行を別枠で記録します。このレポートの数値は、 +コールド条件も一時的に各 3 試行とした PR の測定 run 1 回分です。Windows の +コールド起動は 1 試行あたり約 13〜46 秒かかるため、週次・手動の多試行を +完了できるよう測定 job の上限は 240 分です。 +`--cold-repetitions` / `--download-repetitions` で増やせます。 + +既知の不具合は `tests/fixtures/lsp-write-baseline.json` にシナリオ単位で明記します。 +これは合格率を補正する仕組みではありません。既知の失敗はレポート上も失敗です。 +CI は baseline に含まれない失敗を終了コード 1 で拒否します。既知のテキスト差分も +正規化した内容の SHA256 を照合し、別の誤編集を隠しません。修正による失敗の解消は +許可します。baseline の変更は再現証跡と不具合 Issue を伴うレビュー対象です。 +Issue #499 のコメント喪失修正は checkout 条件で回帰を拒否します。公開 LSP を使う +コールド条件では、実測した公開版 `0.18.1` の既知のテキスト SHA256 だけを +許容します。VERSION 不明・checkout・後続の公開版にはこの例外を適用しません。 +無関係のファイルへの BOM 追加も regression として拒否します。 +Issue #498 の BOM 修正後は checkout 条件の `bom_added` も regression として拒否します。 +公開版 `0.18.1` の `bom_added` は、各シナリオの `published` 例外でのみ許容します。 +再測定を絞る場合は `--scenarios create_plain` のように指定できます。絞った実行は +完全なマトリクスの代わりにならず、レポートの欠けたセル数に反映します。 + +## 付録: シナリオ × 開始条件 × OS + +各セルは「期待バイト列と一致した試行 / 試行数」です。 + +| シナリオ | ツール | 開始条件 | Windows | macOS | Linux | 失敗の種類(3 OS 合計) | +| --- | --- | --- | ---: | ---: | ---: | --- | +| `create_class_monobehaviour` | `create_class` | `warm_indexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_class_monobehaviour` | `create_class` | `daemon_stopped` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_class_monobehaviour` | `create_class` | `unindexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_class_monobehaviour` | `create_class` | `first_download` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_class_scriptableobject` | `create_class` | `warm_indexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_class_scriptableobject` | `create_class` | `daemon_stopped` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_class_scriptableobject` | `create_class` | `unindexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_class_scriptableobject` | `create_class` | `first_download` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_class_plain` | `create_class` | `warm_indexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_class_plain` | `create_class` | `daemon_stopped` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_class_plain` | `create_class` | `unindexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_class_plain` | `create_class` | `first_download` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_plain` | `create_csharp_file` | `warm_indexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_plain` | `create_csharp_file` | `daemon_stopped` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_plain` | `create_csharp_file` | `unindexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_plain` | `create_csharp_file` | `first_download` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_monobehaviour` | `create_csharp_file` | `warm_indexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_monobehaviour` | `create_csharp_file` | `daemon_stopped` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_monobehaviour` | `create_csharp_file` | `unindexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_monobehaviour` | `create_csharp_file` | `first_download` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_scriptableobject` | `create_csharp_file` | `warm_indexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_scriptableobject` | `create_csharp_file` | `daemon_stopped` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_scriptableobject` | `create_csharp_file` | `unindexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `create_scriptableobject` | `create_csharp_file` | `first_download` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `replace_body` | `replace_symbol_body` | `warm_indexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `replace_body` | `replace_symbol_body` | `daemon_stopped` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `replace_body` | `replace_symbol_body` | `unindexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `replace_body` | `replace_symbol_body` | `first_download` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `write_file` | `write_csharp_file` | `warm_indexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `write_file` | `write_csharp_file` | `daemon_stopped` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `write_file` | `write_csharp_file` | `unindexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `write_file` | `write_csharp_file` | `first_download` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `insert_before` | `insert_before_symbol` | `warm_indexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `insert_before` | `insert_before_symbol` | `daemon_stopped` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `insert_before` | `insert_before_symbol` | `unindexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `insert_before` | `insert_before_symbol` | `first_download` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `insert_after` | `insert_after_symbol` | `warm_indexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `insert_after` | `insert_after_symbol` | `daemon_stopped` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `insert_after` | `insert_after_symbol` | `unindexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `insert_after` | `insert_after_symbol` | `first_download` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `remove_member` | `remove_symbol` | `warm_indexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `remove_member` | `remove_symbol` | `daemon_stopped` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `remove_member` | `remove_symbol` | `unindexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `remove_member` | `remove_symbol` | `first_download` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `namespace_partial_generic_attributes` | `replace_symbol_body` | `warm_indexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `namespace_partial_generic_attributes` | `replace_symbol_body` | `daemon_stopped` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `namespace_partial_generic_attributes` | `replace_symbol_body` | `unindexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `namespace_partial_generic_attributes` | `replace_symbol_body` | `first_download` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `replace_preserve_comment` | `replace_symbol_body` | `warm_indexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `replace_preserve_comment` | `replace_symbol_body` | `daemon_stopped` | 0/3 | 0/3 | 0/3 | bom_added 9, text_changed 9 | +| `replace_preserve_comment` | `replace_symbol_body` | `unindexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `replace_preserve_comment` | `replace_symbol_body` | `first_download` | 0/3 | 0/3 | 0/3 | bom_added 9, text_changed 9 | +| `rename_multifile` | `rename_symbol` | `warm_indexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `rename_multifile` | `rename_symbol` | `daemon_stopped` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `rename_multifile` | `rename_symbol` | `unindexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `rename_multifile` | `rename_symbol` | `first_download` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `unicode_no_bom_crlf` | `write_csharp_file` | `warm_indexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `unicode_no_bom_crlf` | `write_csharp_file` | `daemon_stopped` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `unicode_no_bom_crlf` | `write_csharp_file` | `unindexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `unicode_no_bom_crlf` | `write_csharp_file` | `first_download` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `unicode_bom_crlf` | `write_csharp_file` | `warm_indexed` | 3/3 | 3/3 | 3/3 | なし | +| `unicode_bom_crlf` | `write_csharp_file` | `daemon_stopped` | 3/3 | 3/3 | 3/3 | なし | +| `unicode_bom_crlf` | `write_csharp_file` | `unindexed` | 3/3 | 3/3 | 3/3 | なし | +| `unicode_bom_crlf` | `write_csharp_file` | `first_download` | 3/3 | 3/3 | 3/3 | なし | +| `large_3500_lines` | `write_csharp_file` | `warm_indexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `large_3500_lines` | `write_csharp_file` | `daemon_stopped` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `large_3500_lines` | `write_csharp_file` | `unindexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `large_3500_lines` | `write_csharp_file` | `first_download` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `repair_syntax_error` | `apply_csharp_edits` | `warm_indexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `repair_syntax_error` | `apply_csharp_edits` | `daemon_stopped` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `repair_syntax_error` | `apply_csharp_edits` | `unindexed` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `repair_syntax_error` | `apply_csharp_edits` | `first_download` | 0/3 | 0/3 | 0/3 | bom_added 9 | +| `validate_without_write` | `validate_text_edits` | `warm_indexed` | 3/3 | 3/3 | 3/3 | なし | +| `validate_without_write` | `validate_text_edits` | `daemon_stopped` | 3/3 | 3/3 | 3/3 | なし | +| `validate_without_write` | `validate_text_edits` | `unindexed` | 3/3 | 3/3 | 3/3 | なし | +| `validate_without_write` | `validate_text_edits` | `first_download` | 3/3 | 3/3 | 3/3 | なし | + +Launch mode: autonomous + +User Verification Result: n/a (autonomous) + +Agent Visual Check: n/a (no UI surface) diff --git a/docs/skills.md b/docs/skills.md index ee555b91..b5fb2ced 100644 --- a/docs/skills.md +++ b/docs/skills.md @@ -63,7 +63,8 @@ unity-cli skills show unity-scene-create | `vscode` | `.github/skills/` | `~/.copilot/skills/` | These clients read `SKILL.md` directories directly; reference files retain their -relative paths. See the client documentation for +relative paths. The home directory is `$HOME` on Unix and `%USERPROFILE%` on +Windows, the same location the clients read. See the client documentation for [Claude Code](https://code.claude.com/docs/en/skills), [Cursor](https://cursor.com/docs/skills), [Windsurf](https://docs.windsurf.com/windsurf/cascade/skills), and diff --git a/docs/tools.md b/docs/tools.md index c0402509..cade5edb 100644 --- a/docs/tools.md +++ b/docs/tools.md @@ -369,6 +369,12 @@ python3 scripts/e2e-prefab.py --launch --editmode --versions 6000.3.25f1,2022.3. | `apply_csharp_edits` | Apply structured C# source edits | | `create_class` | Create a C# class | +The C# write tools keep the file encoding of an existing file: its byte order +mark (present or absent) and, when the file uses a single newline convention +(LF or CRLF), that convention for the whole saved text. New files from +`create_csharp_file` and `create_class` are UTF-8 without a BOM and keep the +newlines of the given text. + `hot_reload` changes the body of existing methods while Play Mode keeps running (scene, objects and field values are preserved; the `.cs` file on disk is not modified). Prerequisites: the optional FastScriptReload 1.8.0 package installed diff --git a/docs/verification/issue-386/README.md b/docs/verification/issue-386/README.md new file mode 100644 index 00000000..bb1c4f40 --- /dev/null +++ b/docs/verification/issue-386/README.md @@ -0,0 +1,205 @@ +# Issue #386: Windows 実機検証と残る検証条件 + +対象: [Issue #386](https://github.com/akiojin/unity-cli/issues/386)。計測日時は各 JSON の UTC 時刻を参照。 +Windows 11 x64 / Unity 6000.4.4f1 / CLI・Bridge 0.18.1 を使用した。 +CLI は base `338f426119b61123567b74028e7e8fe3bd99caa5` に本変更を加えた開発ビルドで、 +公開 Release 0.18.1 のバイナリも別に導入して接続を確認した。 +[環境・ソースファイル・バイナリの SHA256](environment.json) で区別できる。 +MCP profile 修正後の [最終ソース・バイナリ SHA256](environment-final.json) は別に収録した。 +先に測定した Windows 操作にはその測定時点のバイナリ SHA256 を残している。 + +**Overall: FAIL — Issue 全体は未完了。PR は未作成。** +個別の成功を Linux 実 Editor、winget 導入や原資料の全シナリオへ拡張しない。 + +## 2026-10-04 の継続検証 + +前回の停止条件を解消する作業を継続した。Windows Git placeholder の参照を正しく検証する +修正後、native Cargo 全件は **610 PASS / 0 FAIL**、skills lint は **23 skills / 0 violations**。 +fmt / clippy と実 Unity の SceneHandlerTests 11件も成功した。 +公開23操作、実 Editor のモーダルによる GDI fallback、公開版 CLI の実 Editor ping を再実行した。 + +[継続検証の全コマンド・テスト名・証跡](resume/README.md)を追加した。 +Prefab45+22、Timeline40、eval18+1000連続実行、InputActions保存/再起動50、動画6、Animation25+26、 +参照取得/解決9、Bake4 backendの101チェック、Windows Playerの実ビルドとGUI描画が成功した。 +Test RunnerのDomain Reload有効/無効の4件、InputActions型12・通知4、Gamepad2・Touch15も成功した。 +隔離したWindows x64 / FSR1.8.0で実Hot Reload25件が成功し、状態保持・部分適用・復旧を確認した。 +複合入力の失敗はCRLFを読めないテストhelperが原因で、改行回帰4件を含む11件がheadlessと最終GUIで成功した。 +GUI再起動後のTouch15件・入力11件はerror / skip 0だった。 +公式CLIのWindows比較はプロセス/常駐・前面/最小化の4条件を各操作100回、計10,400測定完了。 +[Windows計測値](resume/windows-comparison.md)に全p50・p95、debugビルドとhost負荷、背景条件の違いを記録した。 +スタッフ原資料との網羅性は未確認である。 + +WSL Ubuntu 24.04 に各デスクトップ環境を導入し、実 CLI から grim / gnome-screenshot / +spectacle と X11 の import / scrot / maim で実 PNG を生成した。 +これらは応答しない TCP fixture を使う OS capture の検証で、Linux 実 Unity の成功とは区別する。 +公式 Linux Unity 6000.4.4f1 は展開・起動済みだが、ライセンスがなく exit 198 で停止した。 +Unity Hub 3.22.2 の checksum と起動を確認し、認証可能な環境を用意した。 + +winget 初回提出用の3ファイルを [packaging/winget](../../../packaging/winget/README.md) に用意し、 +`winget validate` が成功した。公開 source への提出・反映と `WINGET_TOKEN` 設定は未完了。 +正式 `verify.run` は再度1500秒待機して deferred。 +また、blocked 復旧用の `derive:true` が library のない本プロジェクトに `cargo test --workspace --lib` +を生成し、Cargo が `no library targets found` と拒否するツール側の問題も PM に報告した。 +派生記録の編集や空 library の追加による回避は行っていない。 + +スタッフ原資料の代替調査では #243–260 / #390–395 に、23操作以外の入力・bake・build・動画・ +Animation・InputActions・C# reference の確認項目があると分かった。原資料との一致は未確認で、 +Windows の追加検証を収録した。下記の旧605成功・1失敗などの証跡は初回検証の記録として残す。 + +## 受け入れ基準の実測状況 + +| AC | 結果 | 証跡・残る条件 | +| --- | --- | --- | +| 1: Windows lockfile / PID / 自動発見 | PASS | 実 Editor が `%USERPROFILE%\.unity-cli\editors` に発行した [lockfile(認証情報除去)](lockfiles.json)、`tasklist`、[自動発見](fresh-setup-summary.json)。 | +| 2: 実 setup / Bridge 導入・接続 | PASS | 空の隔離プロジェクトで `setup --launch-editor --wait-secs 420` を実行。40.549秒、exit 0、`projectMatches: true`。[結果](setup.stdout.json)、[実行時間と ping](fresh-setup-summary.json)。dry-run ではない。 | +| 3: 証跡の Issue / PR 記録 | PASS | 本資料と [Issue コメント](https://github.com/akiojin/unity-cli/issues/386#issuecomment-5970471700) に成功・失敗・未検証条件を記録。正式検証記録が未取得のため PR 未作成。 | +| 4: Windows / Linux OS フォールバック | Windows PASS / Linux 部分 | Windows 実 Editor のモーダルで PowerShell + GDI が成功。Linux Wayland / X11 の6ツールは実 PNG 生成成功、Linux 実 Editor はライセンス認証待ち。 | +| 5: スタッフ原資料の全シナリオ・比較表 | 部分 | 公開済み23操作と、多数の[追加実機シナリオ](resume/README.md)が成功。複合入力も改行修正後11件成功。原資料 `pm-scratch/staff-report.md` は未取得。公式 CLI の Windows 比較は全条件未達で、原資料との網羅性は未確認。 | +| 6: 公開 install.ps1 / winget / ping | PowerShell PASS / winget 未検証 | 公開 installer と実 Editor ping 成功。初回 manifest の validate 成功。公開 package / `WINGET_TOKEN` がなく、winget install / ping は未実施。 | + +## 実機で発見して修正した問題 + +1. Windows では `Command::spawn` が CLI の標準出力ハンドルを Editor に継承させ、 + 呼び出し元の `Command::output` が Editor 終了まで待つ。 + setup、editor open、test の起動を既存 `spawn_detached` に統一した。 + `setup_launch_returns_output_while_editor_is_still_running` は修正前に + `setup output waited for the Editor to exit` で失敗し、修正後に成功した。 + 実 Editor の新規 setup も40.549秒で戻り、Editor は起動したまま接続できた。 +2. Windows の `canonicalize` が返す `\\?\` / `\\?\UNC\` を Unity の起動引数に渡すと、 + この Editor では正しく起動できなかった。Unity に渡す project / log パスを通常形式へ変換した。 + `editor_launch_uses_paths_supported_by_unity` は local / UNC の両方で修正前に失敗し、修正後に成功した。 + CLI の自動 headless 起動による実 Unity テストと GUI 起動の両方でも確認した。 +3. Windows の `Path.GetDirectoryName` は `\` を返す。 + シーンの作成・保存は `/` で分割して AssetDatabase のフォルダを作るため失敗していた。 + AssetDatabase に渡す前に区切り文字を `/` に揃えた。 + 深いフォルダへの作成・保存の回帰テストを追加し、実 Unity で RED → GREEN を確認した。 + +4. 全件検証で MCP configure の Windows profile 解決も確認した。 + `dirs::home_dir` の Windows shell API はプロセスの `USERPROFILE` 上書きを参照しないため、 + Windsurf の設定テストが実ユーザープロファイルへ書き込んでいた。 + Windows では明示した `USERPROFILE` を優先し、未設定なら従来の解決方法に戻すよう修正した。 + テストは dry-run の出力先と、指定先で更新された `command` を確認するよう強化した。 + `windsurf: preview must target the isolated configuration directory` の RED を確認し、 + 修正後は MCP / auth warning / tool list の11件が成功した。 + 今回生成された実プロファイルの設定ファイルは、内容・SHA256・作成時刻で検証実行の生成物と + 確認して削除した。[削除前のメタデータと削除結果](profile-audit.json)。 + +5. Windows の `core.symlinks=false` checkout は、Git の symlink を参照先文字列の + 通常ファイルとして展開する。skills lint はこの正規の展開形式を誤った参照先と扱っていた。 + Windows ではこの相対参照を解決し、従来どおり canonical skill の実ディレクトリと照合する。 + 欠落・異なる skill・存在しない参照先・複数行の不正ファイルは回帰テストで拒否を確認した。 + checkout ファイル、Git index、Developer Mode の設定は変更していない。 + +Windows の clippy で検出された既存の Unix 専用テストの未使用 import / helper には +`cfg(unix)` を付けた。LSP の動作変更はない。 + +Windows の Python E2E helper も修正した。`os.kill(pid, 0)` は Windows では Unix の +生存確認と異なり、コンソール制御イベントになる。終了済み PID を生存扱いする RED を確認した。 +`OpenProcess(SYNCHRONIZE)` と `WaitForSingleObject(0)` に置き換え、実行中の子が終了しないこと、 +終了済み・無効 PID の拒否、終了コード259の判定を Windows native の4テストで確認した。 +既存 authentication の3テストと Linux の回帰テストも成功した。 + +継続検証ではGit HTTP認証形式、Windowsの長いreferenceパス、batchの診断喪失、 +Preview SceneによるBakeの誤判定も再現して修正した。 +各RED→GREENと実取得・実アセットの証跡は[継続検証](resume/README.md)に収録した。 + +## Windows OS キャプチャ + +実 Editor PID 44232 に同期 `EditorUtility.DisplayDialog("Issue386FallbackProbe", ...)` を開き、 +その PID 所有のモーダルウィンドウが存在することを確認してから実行した。 + +```text +unity-cli --project-path --timeout-ms 1000 raw capture_screenshot --json '{}' +unity-cli --project-path --timeout-ms 1000 raw capture_screenshot --json '{"osFallback":false}' +``` + +前者は exit 0、`fallback: "os"`、PNG 1512 × 949。 +後者は exit 6、`TIMEOUT`。[実行記録と PNG SHA256](modal-summary.json)、 +[成功レスポンス](modal-os-fallback.stdout.json)、[無効化時のエラー](modal-fallback-disabled.stdout.json)。 +PNG 自体はローカルの隔離プロジェクトに保持し、この証跡には寸法と SHA256 を収録した。 +終了時は対象 PID の検証用ダイアログだけを閉じた。 + +## 公開23操作 + +`scripts/bench-editor-ops.py::operations()` の23操作を使用した。 +シーンとアセットは隔離プロジェクトの `Assets/Scenes/Generated/E2E/Performance` に作成した。 +これは各操作1回の動作確認であり、100サンプルの速度比較や前面・背面のベンチマークではない。 + +最初の試走は Input System の restart ダイアログでアセット3操作が停止した。 +Editor を閉じた状態で setup により `activeInputHandler: 2` に変更し、再試走した。 +初回 setup 用の最小プロジェクトにも、初回 ping 後に同じ Input System の警告が開いた。 +初回接続の成功はその時点の結果であり、設定ファイルのない最小プロジェクトを +継続して無人運用できることまでは主張しない。検証終了時に警告を確認して閉じた。 +その通常 Domain Reload 有効の試走では21/23が成功し、Play 後の状態ポーリングに +`OPERATION_FAILED: early eof`、直後の Stop に `UNAUTHORIZED` が発生した。 +後続の Stop により検証用 Play Mode は終了した。[最初の結果](first-operations.json)、[通常設定の結果](operations.json)。 + +[既存比較資料](../../comparison.md) と同じ `DisableDomainReload` / `PlayUnfocused` にすると、 +23/23が成功した。[設定変更と以前の値](staff-play-settings.stdout.json)、 +[全呼び出しの終了コード・時間](staff-final-summary.json)、[操作別結果](staff-final-operations.json)。 +通常 Domain Reload 中の接続エラーを修正済みとは扱わない。 +ローカル C# 読取は embedded package の `Packages/com.akiojin.unity-cli-bridge/Editor/Core/UnityCliBridgeHost.cs` を使用した。 + +## 配布経路 + +公開スクリプト `https://raw.githubusercontent.com/akiojin/unity-cli/main/scripts/install.ps1` を +Windows PowerShell 5 の `irm ... | iex` で実行した。 +`UNITY_CLI_TOOLS_ROOT` を隔離先に設定し、`UNITY_CLI_SKIP_PATH_UPDATE=1` でユーザーの PATH 更新を省いた。 +Windows PowerShell 5 の module path はプロセス内でその `$PSHOME\Modules` に設定した。 +Release 0.18.1 の Windows バイナリを SHA256SUMS 検証後に導入し、 +[version](release-version.json) と [実 Editor ping](fresh-setup-summary.json) が成功した。 +[公開 Release のアセット](release.json) と [バイナリの SHA256](environment.json) を収録している。 + +[winget show](winget.json) は「入力条件に一致するパッケージが見つかりませんでした」。 +[repository secret の名前一覧](repository-secret-names.json) に `WINGET_TOKEN` はない。 +トークン値は読み取っていない。winget での install / ping、初回公開提出とトークン設定は未実施。 + +## 初回の Verification Report(履歴) + +Mode: full。Launch mode: interactive (`launch_route: manual`)。 +Baseline: `origin/develop` / HEAD `338f426119b61123567b74028e7e8fe3bd99caa5`。 +Changed surfaces: interactive CLI、Editor 外部連携、C# シーン作成・保存、テスト条件、docs。 +Detected runners: Cargo、Unity Test Framework。Playwright と LSP の dotnet test は対象外。 + +直接実行の結果: + +| コマンド | 結果 | +| --- | --- | +| `cargo build --bin unity-cli` | PASS(Windows native) | +| `cargo clippy --all-targets -- -D warnings` | PASS(Windows native、Unix 専用 import の条件修正後) | +| `cargo test --test setup_dry_run -- --test-threads=1` | PASS、2件 | +| `cargo test editor_launch_uses_paths_supported_by_unity -- --test-threads=1` | PASS、1件 | +| `unity-cli test --mode editmode --filter SceneHandlerTests ...` | PASS、11件。[JUnit GREEN](green-results.xml)。修正前は11件中3件失敗。[JUnit RED](red-results.xml)。 | +| `cargo test --all-targets --no-fail-fast -- --test-threads=1` | FAIL。最終修正で **605 PASS / 1 FAIL**。失敗は `json_envelope::skills_show_and_lint_use_envelopes` のみ。[結果](final-checks.json)、[全件ログ](cargo-all-final.txt)。 | +| `unity-cli skills lint --severity error` | FAIL。checkout の skill リンク46件が通常ファイルになっている。 | + +全件ゲートの失敗は `core.symlinks=false` の Windows checkout が Git の symlink を +リンク先文字列の通常ファイルとして展開したことによる R20 / R21 エラー。 +Git blob と内容一致を確認した上で実リンクへの復元を試したが、`WinError 1314`(権限不足)で失敗し、 +リンク変更は行われなかった。lint の抑制や Developer Mode / セキュリティ設定の変更は行っていない。 + +正式な `verify.plan` / `verify.run` には fmt、clippy、全 targets の単一スレッド test +(`--no-fail-fast` で全 suite の結果を収集)、skills lint、実 Unity の SceneHandlerTests を登録した。 +正式 run は [300秒待機](verify-run.json)、[1500秒待機](verify-run-second.json) の両方で +他プロジェクトの host-wide lease により `deferred`。コマンドは正式 run からは未実行で、 +Verification Run Record は未生成。lease 保有者には介入していない。 +上表の最終 Cargo 結果は通常の直接実行で、正式記録と区別する。 + +Test Inventory: [Cargo 全606件のテスト名・suite・結果](cargo-test-inventory.json)。 +Unity の実行テスト名は JUnit に全11件を収録。 +追加 Rust テストは `app::editor::tests::editor_launch_uses_paths_supported_by_unity` と +`setup_launch_returns_output_while_editor_is_still_running`。 +最終バイナリの自動 headless 起動でも SceneHandlerTests 11/11 が成功した。[最終実行ログ](unity-final.txt)。 +`mcp::configure_all_clients_preserves_other_servers_and_dry_run` は出力先と更新内容を確認するテストに強化した。 + +User Verification Result: pending。自動実行の成功をユーザー確認済みとは扱わない。 +自動ゲートが失敗しているため、追加のユーザー確認を Ready 判定に使わない。 +Agent Visual Check: n/a(CLI と Editor 連携を検証。Web/TUI の表示変更なし)。 + +## 再開条件 + +1. 原資料 `pm-scratch/staff-report.md` の所在を確認し、追加した Windows 検証との網羅性を照合する。 +2. 用意した Linux Editor / Unity Hub でライセンス認証し、実 Editor を含む AC-4 を実行する。 +3. winget 初回公開と `WINGET_TOKEN` の設定を行い、公開 source から install / ping を検証する。 +4. 派生検証の binary-only Cargo 対応と共通検証枠を確保し、正式記録と必要なユーザー確認後に Ready PR を作成する。 +5. 原資料の全シナリオを今回のWindows実測と照合し、追加の条件があれば検証する。 diff --git a/docs/verification/issue-386/cargo-all-final.txt b/docs/verification/issue-386/cargo-all-final.txt new file mode 100644 index 00000000..e37cd86e --- /dev/null +++ b/docs/verification/issue-386/cargo-all-final.txt @@ -0,0 +1,721 @@ + Compiling unity-cli v0.18.1 () + Finished `test` profile [unoptimized + debuginfo] target(s) in 9.05s + Running unittests src\main.rs (target\debug\deps\unity_cli-66a997df271e997b.exe) + +running 554 tests +test app::editor::tests::editor_launch_uses_paths_supported_by_unity ... ok +test app::runner::tests::ambiguous_editor_fails_before_contacting_any_editor ... ok +test app::runner::tests::animation_curve_edits_accept_operations_and_tangent_modes ... ok +test app::runner::tests::animation_curve_edits_reject_missing_identifiers_and_invalid_nested_fields ... ok +test app::runner::tests::animation_curve_queries_validate_complete_binding_filters ... ok +test app::runner::tests::audio_mixer_arguments_are_action_specific ... ok +test app::runner::tests::augment_command_stats_inserts_cli_snapshot ... ok +test app::runner::tests::baking_invalid_target_missing_scene_and_missing_job_are_rejected ... ok +test app::runner::tests::baking_surface_requires_path_before_contacting_editor ... ok +test app::runner::tests::baking_valid_targets_and_polling_are_accepted ... ok +test app::runner::tests::bridge_commands_resolve_explicit_project_path ... ok +test app::runner::tests::build_reference_call_clean_defaults ... ok +test app::runner::tests::build_reference_call_clean_with_version ... ok +test app::runner::tests::build_reference_call_diff_path_mode_with_limit ... ok +test app::runner::tests::build_reference_call_diff_symbol_mode ... ok +test app::runner::tests::build_reference_call_embed_build_includes_version ... ok +test app::runner::tests::build_reference_call_embed_build_omits_optional_version ... ok +test app::runner::tests::build_reference_call_embed_search_omits_optional_top_k ... ok +test app::runner::tests::build_reference_call_embed_search_with_top_k ... ok +test app::runner::tests::build_reference_call_fetch_carries_all_flags ... ok +test app::runner::tests::build_reference_call_fetch_defaults_without_overrides ... ok +test app::runner::tests::build_reference_call_find_symbol_minimal ... ok +test app::runner::tests::build_reference_call_find_symbol_with_filters ... ok +test app::runner::tests::build_reference_call_grep_defaults_context_to_zero ... ok +test app::runner::tests::build_reference_call_grep_with_file_glob_and_context ... ok +test app::runner::tests::build_reference_call_resolve_symbol_at_minimal ... ok +test app::runner::tests::build_reference_call_resolve_symbol_at_with_version ... ok +test app::runner::tests::build_reference_call_search_minimal_pattern ... ok +test app::runner::tests::build_reference_call_search_with_all_options ... ok +test app::runner::tests::build_reference_call_status_includes_explicit_version ... ok +test app::runner::tests::build_reference_call_status_omits_optional_version ... ok +test app::runner::tests::build_reference_call_view_omits_optional_lines ... ok +test app::runner::tests::build_reference_call_view_with_range ... ok +test app::runner::tests::capture_screenshot_timeout_respects_os_fallback_flag ... ok +test app::runner::tests::env_var_guard_restores_previous_value ... ok +test app::runner::tests::eval_cli_accepts_code_and_rejects_invalid_mode ... ok +test app::runner::tests::eval_dry_run_does_not_execute_arbitrary_code ... ok +test app::runner::tests::eval_schemas_require_code_and_status_id ... ok +test app::runner::tests::eval_transport_error_keeps_generated_request_id ... ok +test app::runner::tests::execute_tool_skips_mutating_tool_in_dry_run_mode ... ok +test app::runner::tests::hot_reload_requires_revision_and_explicit_action ... ok +test app::runner::tests::init_tracing_accepts_verbose_levels ... ok +test app::runner::tests::instances_list_defaults_host_to_ipv4_loopback ... ok +test app::runner::tests::load_params_defaults_to_empty_object ... ok +test app::runner::tests::load_params_reads_inline_json ... ok +test app::runner::tests::load_params_reads_json_from_file ... ok +test app::runner::tests::load_params_rejects_when_json_and_params_file_are_both_set ... ok +test app::runner::tests::parse_external_tool_command_accepts_json_flag ... ok +test app::runner::tests::parse_external_tool_command_rejects_unknown_flag ... ok +test app::runner::tests::parse_external_tool_command_requires_tool_name ... ok +test app::runner::tests::parse_external_tool_command_requires_values_for_flags ... ok +test app::runner::tests::parse_external_tool_command_supports_equals_forms ... ok +test app::runner::tests::parse_json_object_accepts_object ... ok +test app::runner::tests::parse_json_object_rejects_non_object ... ok +test app::runner::tests::parse_ports_deduplicates_values ... ok +test app::runner::tests::parse_ports_rejects_invalid_values ... ok +test app::runner::tests::parse_ports_returns_empty_for_none ... ok +test app::runner::tests::parse_ports_with_diagnostics_reports_duplicate_values ... ok +test app::runner::tests::ping_version_check_reports_mismatch_and_unknown ... ok +test app::runner::tests::prefab_override_validation_requires_explicit_scope_and_apply_target ... ok +test app::runner::tests::print_value_text_handles_string_and_object ... ok +test app::runner::tests::project_path_flag_is_global_and_feeds_runtime_overrides ... ok +test app::runner::tests::run_with_cli_batch_marks_skipped_items_in_dry_run_mode ... ok +test app::runner::tests::run_with_cli_exercises_remote_command_error_paths ... ok +test app::runner::tests::run_with_cli_handles_instances_and_daemon_commands_without_server ... ok +test app::runner::tests::run_with_cli_handles_local_tool_and_batch_paths ... ok +test app::runner::tests::run_with_cli_rejects_unknown_external_tool ... ok +test app::runner::tests::run_with_cli_requires_batch_input_source ... ok +test app::runner::tests::run_with_cli_set_active_text_output_when_reachable ... ok +test app::runner::tests::run_with_cli_supports_tool_schema_command ... ok +test app::runner::tests::runtime_overrides_are_derived_from_cli_at_app_boundary ... ok +test app::runner::tests::setup_and_bridge_cli_arguments_parse ... ok +test app::runner::tests::timeline_manage_is_skipped_in_dry_run ... ok +test app::runner::tests::timeline_validation_requires_target_and_valid_action ... ok +test app::runner::tests::validate_tool_params_accepts_add_component_payload ... ok +test app::runner::tests::validate_tool_params_accepts_addressables_manage_add_entry ... ok +test app::runner::tests::validate_tool_params_accepts_analyze_asset_dependencies_get_dependencies ... ok +test app::runner::tests::validate_tool_params_accepts_build_index_output_path ... ok +test app::runner::tests::validate_tool_params_accepts_create_animation_clip_payload ... ok +test app::runner::tests::validate_tool_params_accepts_create_animator_controller_payload ... ok +test app::runner::tests::validate_tool_params_accepts_create_gameobject_with_vector_fields ... ok +test app::runner::tests::validate_tool_params_accepts_create_sprite_atlas_payload ... ok +test app::runner::tests::validate_tool_params_accepts_delete_gameobject_with_path_and_paths ... ok +test app::runner::tests::validate_tool_params_accepts_execute_menu_item_get_available_menus ... ok +test app::runner::tests::validate_tool_params_accepts_execute_menu_item_without_action ... ok +test app::runner::tests::validate_tool_params_accepts_get_input_actions_state_with_asset_path ... ok +test app::runner::tests::validate_tool_params_accepts_input_keyboard_batch_actions ... ok +test app::runner::tests::validate_tool_params_accepts_load_scene_by_name ... ok +test app::runner::tests::validate_tool_params_accepts_lsp_write_payload_with_path_alias ... ok +test app::runner::tests::validate_tool_params_accepts_manage_layers_get_by_index ... ok +test app::runner::tests::validate_tool_params_accepts_package_manager_list_action ... ok +test app::runner::tests::validate_tool_params_accepts_profiler_start_payload ... ok +test app::runner::tests::validate_tool_params_accepts_valid_payload ... ok +test app::runner::tests::validate_tool_params_accepts_write_csharp_file_payload ... ok +test app::runner::tests::validate_tool_params_rejects_addressables_analyze_dependencies_without_asset_path ... ok +test app::runner::tests::validate_tool_params_rejects_addressables_manage_move_entry_without_target_group ... ok +test app::runner::tests::validate_tool_params_rejects_analyze_asset_dependencies_get_dependencies_without_asset_path ... ok +test app::runner::tests::validate_tool_params_rejects_analyze_asset_dependencies_invalid_action ... ok +test app::runner::tests::validate_tool_params_rejects_analyze_screenshot_without_source ... ok +test app::runner::tests::validate_tool_params_rejects_create_animation_clip_without_sprite_paths ... ok +test app::runner::tests::validate_tool_params_rejects_create_package_setting_without_value ... ok +test app::runner::tests::validate_tool_params_rejects_delete_gameobject_without_target ... ok +test app::runner::tests::validate_tool_params_rejects_execute_menu_item_without_action_or_menu_path ... ok +test app::runner::tests::validate_tool_params_rejects_execute_menu_item_without_menu_path ... ok +test app::runner::tests::validate_tool_params_rejects_invalid_animator_condition_mode ... ok +test app::runner::tests::validate_tool_params_rejects_invalid_sprite_atlas_filter_mode ... ok +test app::runner::tests::validate_tool_params_rejects_load_scene_with_both_identifiers ... ok +test app::runner::tests::validate_tool_params_rejects_manage_asset_database_move_without_to_path ... ok +test app::runner::tests::validate_tool_params_rejects_manage_layers_add_without_layer_name ... ok +test app::runner::tests::validate_tool_params_rejects_manage_layers_invalid_action ... ok +test app::runner::tests::validate_tool_params_rejects_manage_selection_set_without_object_paths ... ok +test app::runner::tests::validate_tool_params_rejects_manage_tools_activate_without_tool_name ... ok +test app::runner::tests::validate_tool_params_rejects_manage_windows_focus_without_window_type ... ok +test app::runner::tests::validate_tool_params_rejects_missing_required_property ... ok +test app::runner::tests::validate_tool_params_rejects_package_manager_search_without_keyword ... ok +test app::runner::tests::validate_tool_params_rejects_registry_config_add_scope_without_scope ... ok +test app::runner::tests::validate_tool_params_rejects_remove_input_binding_without_selector ... ok +test app::runner::tests::validate_tool_params_rejects_set_component_field_missing_required ... ok +test app::runner::tests::validate_tool_params_rejects_unknown_field_for_clear_logs ... ok +test app::runner::tests::validate_tool_params_rejects_unknown_property_when_schema_is_strict ... ok +test app::runner::tests::validate_tool_params_rejects_unknown_run_tests_property ... ok +test app::setup::tests::hub_paths_for_windows_and_linux_do_not_depend_on_test_host ... ok +test app::setup::tests::launch_editor_skips_when_project_is_locked_and_errors_without_editor ... ok +test app::setup::tests::project_unity_version_and_hub_path ... ok +test app::setup::tests::setup_dry_run_leaves_editor_unchecked_and_skips_writes ... ok +test app::setup::tests::setup_flags_editor_serving_another_project ... ok +test app::setup::tests::setup_installs_bridge_and_confirms_matching_editor ... ok +test app::setup::tests::setup_reports_version_mismatch_as_json ... ok +test app::setup::tests::setup_without_dry_run_reports_unreachable_editor ... ok +test app::test_report::tests::github_annotations_extract_unity_location_and_escape_injection ... ok +test app::test_report::tests::junit_preserves_failed_skipped_and_escaped_details ... ok +test app::test_report::tests::junit_time_is_millisecond_precision_for_xunit_schema ... ok +test app::test_report::tests::nunit_nests_test_cases_in_a_suite_and_preserves_details ... ok +test app::test_report::tests::parent_suite_rollups_do_not_duplicate_leaf_failures ... ok +test app::test_report::tests::suite_failure_is_reported_even_without_failed_leaves ... ok +test cli::test_command_tests::test_command_accepts_report_output_without_changing_global_output ... ok +test core::bridge::tests::dry_run_reports_change_without_writing ... ok +test core::bridge::tests::embedded_package_is_reported_and_not_duplicated ... ok +test core::bridge::tests::input_backends_untouched_when_setting_absent_or_already_enabled ... ok +test core::bridge::tests::install_adds_openupm_registry_and_cli_version ... ok +test core::bridge::tests::install_adds_scope_to_existing_openupm_registry ... ok +test core::bridge::tests::install_enables_input_system_backends_while_editor_is_closed ... ok +test core::bridge::tests::install_is_noop_when_already_configured_by_hand ... ok +test core::bridge::tests::install_keeps_other_version_and_upgrade_pins_cli_version ... ok +test core::bridge::tests::install_leaves_input_backends_when_editor_is_open_or_dry_run ... ok +test core::bridge::tests::install_twice_leaves_manifest_byte_identical ... ok +test core::bridge::tests::rejects_malformed_manifest ... ok +test core::bridge::tests::resolve_project_root_walks_up_and_validates_explicit_path ... ok +test core::bridge::tests::status_prefers_lock_resolution_and_reports_missing ... ok +test core::bridge::tests::upgrade_leaves_custom_sources_alone ... ok +test core::bridge::tests::version_check_classifies_versions ... ok +test core::command_stats::tests::snapshot_groups_calls_by_tool_and_route ... ok +test core::config::tests::default_host_returns_ipv4_loopback_without_env ... ok +test core::config::tests::default_port_returns_6400_without_env ... ok +test core::config::tests::default_timeout_returns_30000_without_env ... ok +test core::config::tests::empty_value_is_ignored ... ok +test core::config::tests::execution_context_uses_defaults ... ok +test core::config::tests::fails_when_legacy_alias_is_set ... ok +test core::config::tests::fails_when_removed_unityd_env_is_set ... ok +test core::config::tests::returns_none_when_no_keys_set ... ok +test core::config::tests::u16_env_parses_correctly ... ok +test core::config::tests::u16_env_rejects_zero ... ok +test core::config::tests::u64_env_parses_correctly ... ok +test core::config::tests::u64_env_rejects_zero ... ok +test core::doctor::tests::classification_priority ... ok +test core::doctor::tests::editor_import_workers_are_not_reusable_editors ... ok +test core::doctor::tests::parses_safe_mode_and_latest_compile_errors ... ok +test core::doctor::tests::reads_bridge_version_from_local_file_dependency ... ok +test core::doctor::tests::reads_project_bridge_port ... ok +test core::doctor::tests::recognizes_editor_command_lines_only ... ok +test core::doctor::tests::reports_editor_not_running ... ok +test core::doctor::tests::reports_port_in_use_with_owner_pid ... ok +test core::doctor::tests::safe_mode_exit_clears_flag ... ok +test core::editor_discovery::tests::ambiguous_error_json_lists_candidates ... ok +test core::editor_discovery::tests::dead_pid_marks_lockfile_stale ... ok +test core::editor_discovery::tests::discover_reads_lockfiles_and_skips_garbage ... ok +test core::editor_discovery::tests::expired_heartbeat_marks_lockfile_stale ... ok +test core::editor_discovery::tests::pid_zero_is_never_alive ... ok +test core::editor_discovery::tests::select_for_path_ignores_stale_editors_and_sibling_prefixes ... ok +test core::editor_discovery::tests::select_for_path_prefers_deepest_live_project ... ok +test core::endpoint::tests::active_instance_keeps_priority_over_lockfile_discovery ... ok +test core::endpoint::tests::cli_override_wins_over_active_instance ... ok +test core::endpoint::tests::cwd_inside_project_selects_that_editor ... ok +test core::endpoint::tests::cwd_outside_projects_with_two_editors_is_ambiguous ... ok +test core::endpoint::tests::env_port_wins_when_no_cli_override ... ok +test core::endpoint::tests::explicit_port_wins_over_project_path_and_lockfiles ... ok +test core::endpoint::tests::no_lockfiles_keeps_legacy_default ... ok +test core::endpoint::tests::project_command_targets_its_own_editor_among_several ... ok +test core::endpoint::tests::project_command_without_its_editor_uses_default_endpoint ... ok +test core::endpoint::tests::project_path_selects_matching_editor ... ok +test core::endpoint::tests::project_path_without_running_editor_is_not_found ... ok +test core::endpoint::tests::project_root_env_falls_back_to_default_without_any_lockfile ... ok +test core::endpoint::tests::single_running_editor_is_used_from_anywhere ... ok +test core::endpoint::tests::stale_editors_do_not_cause_ambiguity ... ok +test core::endpoint::tests::unity_project_root_env_acts_as_project_path ... ok +test core::instances::tests::authenticated_health_checks_support_listing_and_selection ... ok +test core::instances::tests::list_instances_adds_default_port_when_no_entries_exist ... ok +test core::instances::tests::list_instances_enumerates_lockfiles_without_ports ... ok +test core::instances::tests::list_instances_keeps_explicit_ports_next_to_lockfiles ... ok +test core::instances::tests::list_instances_reports_down_for_tcp_listener_that_is_not_unity_bridge ... ok +test core::instances::tests::list_instances_reports_up_for_reachable_port ... ok +test core::instances::tests::load_registry_reconstructs_missing_ids ... ok +test core::instances::tests::parse_id_validates_shape ... ok +test core::instances::tests::registry_path_uses_env_and_creates_parent_directory ... ok +test core::instances::tests::registry_round_trip_serialization_shape_is_supported ... ok +test core::instances::tests::set_active_fails_for_unreachable_instance ... ok +test core::instances::tests::set_active_succeeds_for_reachable_instance_and_tracks_previous ... ok +test core::managed_binaries::tests::cache_root_falls_back_to_home_unity_cache ... ok +test core::managed_binaries::tests::cache_root_prefers_unity_cli_cache_root_env ... ok +test core::managed_binaries::tests::detect_rid_returns_known_target_triple ... ok +test core::managed_binaries::tests::download_latest_binary_applies_matching_checksum ... ok +test core::managed_binaries::tests::download_latest_binary_rejects_checksum_mismatch_and_keeps_existing_install ... ok +test core::managed_binaries::tests::ensure_latest_for_can_skip_remote_checks_in_tests ... ok +test core::managed_binaries::tests::ensure_local_uses_existing_binary_without_download ... ok +test core::managed_binaries::tests::get_json_fails_with_status_and_body ... ok +test core::managed_binaries::tests::get_json_parses_http_body ... ok +test core::managed_binaries::tests::get_json_retries_transient_server_error ... ok +test core::managed_binaries::tests::get_optional_text_returns_body_for_success ... ok +test core::managed_binaries::tests::get_optional_text_returns_none_for_not_found ... ok +test core::managed_binaries::tests::get_response_includes_authorization_header ... ok +test core::managed_binaries::tests::get_response_reports_http_status_errors ... ok +test core::managed_binaries::tests::parse_sha256sums_reads_text_and_binary_mode_entries ... ok +test core::managed_binaries::tests::read_local_version_returns_none_for_missing_or_blank_file ... ok +test core::managed_binaries::tests::replace_file_atomic_overwrites_destination ... ok +test core::managed_binaries::tests::sha256_file_matches_known_hash ... ok +test core::managed_binaries::tests::tools_root_falls_back_to_home_unity_tools_when_env_unset ... ok +test core::managed_binaries::tests::tools_root_prefers_unity_cli_tools_root_env ... ok +test core::managed_binaries::tests::unity_cli_status_uses_managed_install_layout ... ok +test core::managed_binaries::tests::verify_manifest_against_checksums_requires_matching_entry ... ok +test core::managed_binaries::tests::write_and_read_local_version_round_trip ... ok +test core::runtime_paths::tests::daemon_dir_is_under_run_root ... ok +test core::self_update::tests::is_recent_returns_false_for_missing_path ... ok +test core::self_update::tests::is_recent_returns_true_for_freshly_touched_file ... ok +test core::self_update::tests::last_check_path_uses_unity_cli_tools_root_env ... ok +test core::self_update::tests::maybe_self_update_skipped_when_opt_out_env_set ... ok +test core::self_update::tests::maybe_self_update_skips_when_recent_check_exists ... ok +test core::self_update::tests::touch_creates_parent_and_writes_marker ... ok +test core::self_update::tests::warn_cargo_conflict_runs_without_panic ... ok +test daemon::runtime::tests::runtime_module_builds_without_warnings_when_unix_code_is_disabled ... ok +test daemon::spawn::tests::spawn_detached_starts_the_command ... ok +test daemon::spawn::tests::spawn_module_builds_for_windows_without_warnings ... ok +test daemon::spawn::tests::spawned_child_does_not_hold_the_callers_stdout_pipe ... ok +test daemon::unityd::tests::daemon_call_error_classification ... ok +test daemon::unityd::tests::daemon_request_batch_round_trip ... ok +test daemon::unityd::tests::daemon_request_ping_round_trip ... ok +test daemon::unityd::tests::daemon_request_status_round_trip ... ok +test daemon::unityd::tests::daemon_request_stop_round_trip ... ok +test daemon::unityd::tests::daemon_request_tool_round_trip ... ok +test daemon::unityd::tests::daemon_response_error_round_trip ... ok +test daemon::unityd::tests::daemon_response_round_trip ... ok +test daemon::unityd::tests::daemon_response_round_trip_preserves_timing ... ok +test daemon::unityd::tests::idle_timeout_default ... ok +test daemon::unityd::tests::pid_file_path_is_under_tools_dir ... ok +test daemon::unityd::tests::pooled_connection_closed_by_editor_restart_is_reconnected_before_sending ... ok +test daemon::unityd::tests::pooled_connection_uses_each_requests_timeout ... ok +test daemon::unityd::tests::request_lost_after_sending_is_reported_and_not_resent ... ok +test daemon::unityd::tests::startup_lock_times_out_and_is_reusable_after_release ... ok +test daemon::unityd::tests::tools_dir_creates_directory ... ok +test lsp::client::tests::collect_document_symbols_flattens_nested_symbols ... ok +test lsp::client::tests::get_apply_defaults_to_false ... ok +test lsp::client::tests::id_matches_accepts_number_and_string_id ... ok +test lsp::client::tests::kind_from_lsp_maps_known_values ... ok +test lsp::client::tests::normalize_lsp_write_result_adds_contract_fields ... ok +test lsp::client::tests::normalize_rel_path_accepts_assets_packages_and_library ... ok +test lsp::client::tests::normalize_rel_path_extracts_supported_prefix_from_absolute_like_input ... ok +test lsp::client::tests::normalize_rel_path_rejects_parent_traversal ... ok +test lsp::client::tests::path_matches_scope_filters_paths ... ok +test lsp::client::tests::remove_symbol_request_includes_fail_on_references_when_set ... ok +test lsp::client::tests::remove_symbol_request_omits_fail_on_references_when_unset ... ok +test lsp::client::tests::require_helpers_validate_expected_fields ... ok +test lsp::client::tests::retryable_session_error_detects_transport_failures ... ok +test lsp::client::tests::retryable_session_error_ignores_argument_errors ... ok +test lsp::client::tests::to_project_relative_or_raw_returns_relative_for_absolute_under_root ... ok +test lsp::client::tests::uri_and_ref_path_helpers_resolve_project_relative_paths ... ok +test lsp::client::tests::uri_to_rel_path_rejects_non_file_uris ... ok +test lsp::daemon::tests::daemon_idle_timeout_uses_env_override ... ok +test lsp::daemon::tests::handle_request_handles_ping_status_and_stop ... ok +test lsp::daemon::tests::is_would_block_checks_error_kind ... ok +test lsp::daemon::tests::write_all_with_retry_handles_would_block_and_partial_writes ... ok +test lsp::daemon::tests::write_all_with_retry_rejects_zero_byte_progress ... ok +test lsp::daemon::tests::write_pid_file_and_cleanup_manage_files_under_tools_root ... ok +test mcp::configure::tests::custom_root_may_have_missing_ancestors_without_creating_them ... ok +test mcp::configure::tests::invalid_config_is_never_overwritten_and_preview_creates_nothing ... ok +test mcp::configure::tests::malformed_shapes_and_http_name_collisions_are_rejected ... ok +test mcp::configure::tests::merges_inline_toml_without_losing_other_servers_or_options ... ok +test mcp::configure::tests::windows_and_local_paths ... ok +test mcp::tests::projects_owned_custom_descriptor_without_an_mcp_specific_schema ... ok +test reference::cache::tests::gc_empty_root_returns_empty ... ok +test reference::cache::tests::gc_keep_zero_removes_all_versions ... ok +test reference::cache::tests::gc_keeps_n_newest_and_returns_removed ... ok +test reference::cache::tests::gc_skips_non_directory_entries ... ok +test reference::cache::tests::list_versions_empty_when_root_missing ... ok +test reference::cache::tests::list_versions_returns_existing_dirs ... ok +test reference::cache::tests::list_versions_skips_files_in_root ... ok +test reference::cache::tests::meta_roundtrip ... ok +test reference::cache::tests::read_meta_returns_error_for_invalid_json ... ok +test reference::cache::tests::read_meta_returns_error_when_missing ... ok +test reference::cache::tests::version_dir_rejects_empty ... ok +test reference::cache::tests::version_dir_rejects_paths_outside_single_cache_entry ... ok +test reference::cache::tests::version_dir_under_cache_root ... ok +test reference::diff::tests::compute_line_diff_empty_for_identical_lines ... ok +test reference::diff::tests::compute_line_diff_for_deletes_only_returns_removal_hunk ... ok +test reference::diff::tests::compute_line_diff_for_inserts_only_returns_addition_hunk ... ok +test reference::diff::tests::compute_line_diff_for_separate_changes_produces_multiple_hunks ... ok +test reference::diff::tests::compute_line_diff_replacement_isolates_changed_lines ... ok +test reference::diff::tests::compute_path_diff_can_be_truncated ... ok +test reference::diff::tests::compute_path_diff_categorises_runtime_export ... ok +test reference::diff::tests::compute_symbol_diff_detects_changed_animator ... ok +test reference::diff::tests::compute_symbol_diff_returns_diff_when_only_one_side_has_symbol ... ok +test reference::diff::tests::compute_symbol_diff_returns_none_for_missing_in_both ... ok +test reference::diff::tests::ensure_cache_dir_errors_on_missing ... ok +test reference::diff::tests::split_fqn_separates_namespace_and_name ... ok +test reference::embed::tests::build_embedding_index_handles_empty_symbol_index ... ok +test reference::embed::tests::build_embedding_index_with_mock_embedder ... ok +test reference::embed::tests::cosine_similarity_handles_zero_vectors ... ok +test reference::embed::tests::embedding_roundtrip_via_bincode ... ok +test reference::embed::tests::resolve_onnxruntime_dylib_explains_how_to_install_when_missing ... ok +test reference::embed::tests::resolve_onnxruntime_dylib_falls_back_to_first_existing_candidate ... ok +test reference::embed::tests::resolve_onnxruntime_dylib_prefers_existing_env_path ... ok +test reference::embed::tests::resolve_onnxruntime_dylib_rejects_missing_env_path ... ok +test reference::embed::tests::search_ranks_by_cosine_similarity ... ok +test reference::embed::tests::search_returns_empty_for_empty_index ... ok +test reference::embed::tests::search_returns_empty_for_empty_query ... ok +test reference::embed::tests::symbol_to_text_includes_namespace_and_kind ... ok +test reference::embed::tests::symbol_to_text_without_namespace_omits_dot ... ok +test reference::fetcher::tests::api_discovery_paginates_branches_and_includes_tags ... ok +test reference::fetcher::tests::api_discovery_surfaces_http_errors ... ok +test reference::fetcher::tests::archive_url_uses_unity_cs_reference_org ... ok +test reference::fetcher::tests::build_clone_args_emits_shallow_single_branch ... ok +test reference::fetcher::tests::ensure_git_available_succeeds_in_test_env ... ok +test reference::fetcher::tests::extract_zip_to_rejects_entries_with_parent_segments ... ok +test reference::fetcher::tests::extract_zip_to_strips_top_level_prefix_and_writes_files ... ok +test reference::fetcher::tests::fetch_selected_pins_commit_after_branch_advances ... ok +test reference::fetcher::tests::fetch_selected_rejects_invalid_commit_before_creating_destination ... ok +test reference::fetcher::tests::github_token_returns_none_when_env_unset ... ok +test reference::fetcher::tests::github_token_skips_empty_and_picks_first_non_empty ... ok +test reference::fetcher::tests::license_ok_when_env_set ... ok +test reference::fetcher::tests::license_ok_when_flag_true ... ok +test reference::fetcher::tests::license_rejects_zero_value ... ok +test reference::fetcher::tests::license_required_when_flag_false_and_env_unset ... ok +test reference::fetcher::tests::list_public_refs_discovers_branches_and_tags ... ok +test reference::fetcher::tests::list_public_refs_preserves_transport_error ... ok +test reference::fetcher::tests::run_clone_rejects_when_license_not_accepted ... ok +test reference::index::tests::build_or_update_index_handles_existing_fixture ... ok +test reference::index::tests::build_or_update_index_persists_signature ... ok +test reference::index::tests::build_or_update_index_skips_already_indexed_files_until_change ... ok +test reference::index::tests::extract_symbols_from_text_captures_namespace ... ok +test reference::index::tests::extract_symbols_from_text_does_not_double_capture_class_name ... ok +test reference::index::tests::extract_symbols_from_text_finds_class ... ok +test reference::index::tests::extract_symbols_from_text_finds_methods ... ok +test reference::index::tests::extract_symbols_from_text_finds_property ... ok +test reference::index::tests::extract_symbols_from_text_finds_struct_and_interface ... ok +test reference::index::tests::file_signature_changes_when_content_changes ... ok +test reference::index::tests::find_symbol_filters_by_kind_and_namespace ... ok +test reference::index::tests::validate_kind_accepts_known_and_rejects_unknown ... ok +test reference::search::tests::grep_filters_by_filename_glob ... ok +test reference::search::tests::grep_finds_class_animator_with_line_numbers ... ok +test reference::search::tests::grep_returns_context_lines ... ok +test reference::search::tests::view_rejects_parent_traversal ... ok +test reference::search::tests::view_returns_requested_line_range ... ok +test reference::tests::cached_fetch_and_status_report_stored_provenance ... ok +test reference::tests::cached_unknown_version_can_be_used_without_branch_resolution ... ok +test reference::tests::dir_size_empty_returns_zero ... ok +test reference::tests::dir_size_sums_file_lengths ... ok +test reference::tests::execute_clean_dry_run_false_actually_removes ... ok +test reference::tests::execute_clean_dry_run_on_empty_cache_returns_empty_removed ... ok +test reference::tests::execute_diff_errors_when_cache_missing ... ok +test reference::tests::execute_diff_path_mode_returns_added_removed_changed ... ok +test reference::tests::execute_diff_requires_from_and_to ... ok +test reference::tests::execute_diff_requires_symbol_or_path ... ok +test reference::tests::execute_diff_symbol_mode_returns_diffs ... ok +test reference::tests::execute_embed_build_errors_when_cache_missing ... ok +test reference::tests::execute_embed_search_errors_when_index_missing ... ok +test reference::tests::execute_embed_search_requires_query ... ok +test reference::tests::execute_fetch_force_preserves_existing_on_transport_failure ... ok +test reference::tests::execute_fetch_skips_when_destination_exists_without_force ... ok +test reference::tests::execute_find_symbol_empty_hits_for_unknown_name ... ok +test reference::tests::execute_find_symbol_filters_namespace ... ok +test reference::tests::execute_find_symbol_rejects_unknown_kind ... ok +test reference::tests::execute_find_symbol_requires_name ... ok +test reference::tests::execute_find_symbol_returns_error_when_cache_missing ... ok +test reference::tests::execute_find_symbol_returns_hits_from_fixture ... ok +test reference::tests::execute_grep_invalid_regex_returns_error ... ok +test reference::tests::execute_grep_requires_pattern ... ok +test reference::tests::execute_grep_supports_file_glob_filter ... ok +test reference::tests::execute_grep_via_dispatcher_returns_hits ... ok +test reference::tests::execute_resolve_symbol_at_empty_token_for_blank_position ... ok +test reference::tests::execute_resolve_symbol_at_finds_token_via_fixture ... ok +test reference::tests::execute_resolve_symbol_at_requires_path_line_column ... ok +test reference::tests::execute_resolve_symbol_at_requires_project_prefix ... ok +test reference::tests::execute_search_requires_pattern ... ok +test reference::tests::execute_search_via_dispatcher_truncates_max_results ... ok +test reference::tests::execute_search_without_max_results_returns_all_hits ... ok +test reference::tests::execute_status_includes_size_bytes ... ok +test reference::tests::execute_status_returns_versions_list ... ok +test reference::tests::execute_view_rejects_parent_traversal_via_dispatcher ... ok +test reference::tests::execute_view_requires_path_param ... ok +test reference::tests::execute_view_via_dispatcher_returns_lines ... ok +test reference::tests::extract_token_at_cursor_handles_edge_cases ... ok +test reference::tests::extract_token_at_cursor_handles_escaped_quote_in_string ... ok +test reference::tests::extract_token_at_cursor_returns_ident_after_closed_string ... ok +test reference::tests::extract_token_at_cursor_skips_line_comment ... ok +test reference::tests::extract_token_at_cursor_skips_string_literal ... ok +test reference::tests::fetch_resolves_project_and_explicit_refs_and_records_actual_commit ... ok +test reference::tests::legacy_metadata_keeps_unknown_match_instead_of_claiming_exact ... ok +test reference::tests::maybe_execute_returns_none_for_unknown_tool ... ok +test reference::tests::now_unix_seconds_string_is_decimal ... ok +test reference::tests::resolve_version_falls_back_to_project_detection ... ok +test reference::tests::resolve_version_uses_explicit_param ... ok +test reference::version::tests::ambiguous_auto_candidates_and_unknown_versions_return_candidates ... ok +test reference::version::tests::detect_returns_error_when_editor_version_line_absent ... ok +test reference::version::tests::detect_returns_error_when_editor_version_value_empty ... ok +test reference::version::tests::detect_returns_error_when_project_version_missing ... ok +test reference::version::tests::exact_tag_precedes_minor_but_version_named_head_is_not_exact ... ok +test reference::version::tests::explicit_ref_has_priority_and_ambiguous_short_names_require_full_ref ... ok +test reference::version::tests::minor_version_key_rejects_invalid_inputs ... ok +test reference::version::tests::parse_editor_version_returns_value_directly ... ok +test reference::version::tests::parses_remote_refs_with_peeled_tag_commits_in_any_order ... ok +test reference::version::tests::public_resolver_handles_previously_supported_minors ... ok +test reference::version::tests::reads_known_project_version ... ok +test reference::version::tests::reads_unknown_minor_without_static_mapping ... ok +test reference::version::tests::selects_new_and_existing_minor_branches_without_claiming_exact_match ... ok +test skills::loader::tests::load_skills_handles_missing_root_and_skips_non_skill_entries ... ok +test skills::loader::tests::load_skills_supports_single_skill_root_and_dir_name_fallback ... ok +test skills::loader::tests::parse_frontmatter_and_collect_references_cover_optional_branches ... ok +test skills::loader::tests::parse_frontmatter_extracts_metadata ... ok +test skills::loader::tests::split_frontmatter_and_parse_frontmatter_cover_edge_cases ... ok +test skills::loader::tests::split_frontmatter_handles_basic_skill ... ok +test skills::tests::good_skill_passes_all_rules ... ok +test skills::tests::model_helpers_cover_skill_accessors_and_tool_sets ... ok +test skills::tests::r01_missing_description_fires ... ok +test skills::tests::r01_missing_multiple_required_fields_fire ... ok +test skills::tests::r02_name_mismatch_fires ... ok +test skills::tests::r03_disallowed_tool_fires ... ok +test skills::tests::r03_legacy_bare_bash_fires ... ok +test skills::tests::r04_unknown_category_fires ... ok +test skills::tests::r05_empty_and_duplicate_triggers_fire ... ok +test skills::tests::r05_uppercase_trigger_fires ... ok +test skills::tests::r06_unknown_sibling_fires ... ok +test skills::tests::r07_too_long_description_fires ... ok +test skills::tests::r08_missing_front_trigger_fires ... ok +test skills::tests::r09_first_person_fires ... ok +test skills::tests::r10_missing_use_when_fires ... ok +test skills::tests::r11_missing_sibling_mention_fires ... ok +test skills::tests::r12_unidirectional_sibling_fires ... ok +test skills::tests::r13_too_long_body_fires ... ok +test skills::tests::r14_missing_heading_fires ... ok +test skills::tests::r15_references_without_link_fires ... ok +test skills::tests::r16_time_sensitive_phrase_fires ... ok +test skills::tests::r17_missing_runtime_checklist_fires ... ok +test skills::tests::r18_long_reference_without_toc_fires ... ok +test skills::tests::r19_reference_link_to_reference_fires ... ok +test skills::tests::r22_collision_without_cross_listing_fires ... ok +test skills::tests::report_and_runner_cover_text_json_discovery_and_error_paths ... ok +test test_env::isolated_runtime_restores_inherited_environment_after_unwind ... ok +test tooling::discovery::tests::bridge_reserved_names_match_the_cli_catalog_including_local_tools ... ok +test tooling::discovery::tests::builtin_descriptors_keep_schemas_and_mark_their_source ... ok +test tooling::discovery::tests::custom_descriptor_roundtrips_owned_names_and_schema ... ok +test tooling::discovery::tests::list_tools_is_a_read_only_remote_builtin ... ok +test tooling::local_tools::tests::build_index_and_find_symbol_roundtrip ... ok +test tooling::local_tools::tests::collect_cs_files_and_index_helpers_cover_readiness_branches ... ok +test tooling::local_tools::tests::create_class_generates_simple_class ... ok +test tooling::local_tools::tests::create_class_rejects_existing_file ... ok +test tooling::local_tools::tests::create_class_rejects_invalid_name ... ok +test tooling::local_tools::tests::create_class_with_namespace_and_inherits ... ok +test tooling::local_tools::tests::default_runtime_config_falls_back_to_ipv4_loopback ... ok +test tooling::local_tools::tests::extract_symbols_from_text_covers_major_symbol_kinds ... ok +test tooling::local_tools::tests::find_refs_supports_cursor_paging ... ok +test tooling::local_tools::tests::find_symbol_returns_index_not_ready_before_build ... ok +test tooling::local_tools::tests::get_symbols_extracts_class_and_method ... ok +test tooling::local_tools::tests::helper_comment_and_snippet_processing_works ... ok +test tooling::local_tools::tests::helper_path_normalization_and_resolution_cover_edge_cases ... ok +test tooling::local_tools::tests::helper_symbol_and_scope_predicates_work ... ok +test tooling::local_tools::tests::list_packages_lists_package_dirs ... ok +test tooling::local_tools::tests::lsp_write_tools_require_lsp_mode ... ok +test tooling::local_tools::tests::post_write_refresh_failure_preserves_applied_files_without_runtime_panic ... ok +test tooling::local_tools::tests::read_returns_file_slice ... ok +test tooling::local_tools::tests::requires_unityengine_using_only_for_monobehaviour ... ok +test tooling::local_tools::tests::search_finds_matching_lines ... ok +test tooling::local_tools::tests::update_index_refreshes_symbol_names ... ok +test tooling::os_capture::tests::capture_fails_when_no_candidate_exists ... ok +test tooling::os_capture::tests::detects_daemon_stringified_timeouts ... ok +test tooling::os_capture::tests::disabled_fallback_returns_the_timeout_error ... ok +test tooling::os_capture::tests::failed_os_capture_keeps_both_errors ... ok +test tooling::os_capture::tests::fallback_flag_defaults_on_and_is_stripped ... ok +test tooling::os_capture::tests::non_timeout_errors_are_not_recovered ... ok +test tooling::os_capture::tests::output_path_follows_bridge_capture_directory ... ok +test tooling::os_capture::tests::timeout_is_recovered_with_os_fallback_marker ... ok +test tooling::os_capture::tests::verbatim_prefix_is_dropped_before_the_path_reaches_os_tools ... ok +test tooling::tool_catalog::tests::action_enum_schemas_use_composite_variants ... ok +test tooling::tool_catalog::tests::addressables_analyze_schema_uses_action_specific_variants ... ok +test tooling::tool_catalog::tests::addressables_manage_schema_has_manage_actions ... ok +test tooling::tool_catalog::tests::all_tools_e2e_covers_catalog_or_documents_exclusion ... ok +test tooling::tool_catalog::tests::analyze_asset_dependencies_schema_has_expected_actions ... ok +test tooling::tool_catalog::tests::animation_curve_tools_advertise_strict_unity_contracts ... ok +test tooling::tool_catalog::tests::baking_tools_have_explicit_target_and_polling_contracts ... ok +test tooling::tool_catalog::tests::build_index_schema_allows_output_path ... ok +test tooling::tool_catalog::tests::build_player_schema_requires_explicit_safe_build_inputs ... ok +test tooling::tool_catalog::tests::capture_video_start_schema_restricts_mode_and_format ... ok +test tooling::tool_catalog::tests::clear_logs_schema_is_strict_empty_object ... ok +test tooling::tool_catalog::tests::create_animation_clip_schema_requires_clip_and_sprite_paths ... ok +test tooling::tool_catalog::tests::create_animator_controller_schema_is_strict_and_nested ... ok +test tooling::tool_catalog::tests::create_prefab_schema_allows_template_mode_without_source_object ... ok +test tooling::tool_catalog::tests::create_sprite_atlas_schema_is_strict_and_nested ... ok +test tooling::tool_catalog::tests::csharp_file_write_schemas_are_local_and_strict ... ok +test tooling::tool_catalog::tests::delete_gameobject_schema_uses_any_of_targets ... ok +test tooling::tool_catalog::tests::execute_menu_item_schema_supports_default_and_action_variants ... ok +test tooling::tool_catalog::tests::get_build_status_is_read_only_and_requires_build_id ... ok +test tooling::tool_catalog::tests::get_gameobject_details_schema_uses_any_of_identifiers ... ok +test tooling::tool_catalog::tests::get_index_status_schema_is_strict_empty_object ... ok +test tooling::tool_catalog::tests::hot_reload_tools_expose_explicit_preview_and_recovery_contract ... ok +test tooling::tool_catalog::tests::input_keyboard_schema_uses_any_of_for_action_or_actions ... ok +test tooling::tool_catalog::tests::known_tool_lookup_works ... ok +test tooling::tool_catalog::tests::load_scene_schema_uses_one_of_identifier_variants ... ok +test tooling::tool_catalog::tests::local_executor_tools_are_marked ... ok +test tooling::tool_catalog::tests::manage_asset_database_schema_uses_action_specific_variants ... ok +test tooling::tool_catalog::tests::manage_layers_schema_requires_action_enum ... ok +test tooling::tool_catalog::tests::modify_gameobject_schema_requires_path ... ok +test tooling::tool_catalog::tests::package_manager_schema_has_required_action ... ok +test tooling::tool_catalog::tests::ping_schema_is_strict_object ... ok +test tooling::tool_catalog::tests::prefab_override_tools_have_strict_discoverable_schemas ... ok +test tooling::tool_catalog::tests::quit_editor_exposes_optional_scene_protection_parameter ... ok +test tooling::tool_catalog::tests::remote_tools_have_unity_bridge_dispatch_cases ... ok +test tooling::tool_catalog::tests::rename_symbol_schema_is_strict_and_requires_name_path ... ok +test tooling::tool_catalog::tests::run_tests_schema_allows_test_mode_enum ... ok +test tooling::tool_catalog::tests::set_component_field_schema_requires_component_and_field ... ok +test tooling::tool_catalog::tests::timeline_schema_exposes_actions_and_stale_clip_guard ... ok +test tooling::tool_catalog::tests::timeline_tools_are_discoverable_with_correct_mutation_flags ... ok +test tooling::tool_catalog::tests::tool_catalog_avoids_default_params_schema_for_known_tools ... ok +test tooling::tool_catalog::tests::tool_catalog_keeps_manifest_parity_count ... ok +test tooling::tool_catalog::tests::tool_specs_cover_catalog ... ok +test tooling::tool_catalog::tests::tools_doc_matches_registered_catalog ... ok +test tooling::tool_catalog::tests::vfx_apply_is_mutating_and_requires_op ... ok +test tooling::tool_catalog::tests::vfx_describe_graph_is_read_only_and_requires_asset_path ... ok +test tooling::tool_catalog::tests::vfx_runtime_is_mutating_and_requires_op_and_game_object ... ok +test tooling::tool_catalog::tests::vfx_settings_is_mutating_and_requires_op ... ok +test tooling::tool_index::tests::category_accepts_heading_or_slug ... ok +test tooling::tool_index::tests::every_tool_has_exactly_one_index_entry_with_a_short_summary ... ok +test tooling::tool_index::tests::query_matches_name_or_summary_case_insensitively ... ok +test tooling::tool_index::tests::tool_index_matches_docs_headings ... ok +test tooling::tool_index::tests::unknown_category_lists_valid_slugs ... ok +test unity::auth::tests::credentials_are_endpoint_scoped_and_absent_from_discovery_output ... ok +test unity::auth::tests::explicit_mounted_lockfile_and_invalid_file_errors_do_not_expose_token ... ok +test unity::auth::tests::only_exact_one_enables_legacy_opt_out ... ok +test unity::transport::tests::call_tool_returns_error_on_failure_response ... ok +test unity::transport::tests::call_tool_returns_result_on_success ... ok +test unity::transport::tests::call_tool_with_timing_reports_non_negative_durations ... ok +test unity::transport::tests::every_request_carries_token_from_private_lockfile ... ok +test unity::transport::tests::normalize_failure_preserves_complete_error_envelope ... ok +test unity::transport::tests::normalize_response_handles_success_and_error_shapes ... ok +test unity::transport::tests::parse_embedded_json_keeps_plain_strings ... ok +test unity::transport::tests::parse_json_accepts_trimmed_json ... ok +test unity::transport::tests::parse_json_rejects_empty_and_non_utf8_payload ... ok +test unity::transport::tests::ping_backfills_bridge_version_from_editor_state_envelope ... ok + +test result: ok. 554 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 41.15s + + Running tests\auth_warning.rs (target\debug\deps\auth_warning-fcf05279c683382e.exe) + +running 1 test +test legacy_opt_out_warns_on_stderr_only_for_exact_one ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 8.82s + + Running tests\bridge_package_dependencies.rs (target\debug\deps\bridge_package_dependencies-ca7aa8976d9aff95.exe) + +running 1 test +test bridge_declares_ugui_when_sources_use_it ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s + + Running tests\build_failure_output.rs (target\debug\deps\build_failure_output-072d26c38af5069a.exe) + +running 1 test +test failed_build_status_keeps_json_report_and_nonzero_exit ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.42s + + Running tests\ci_tests.rs (target\debug\deps\ci_tests-3334446bbab2c8fb.exe) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests\csharp_post_write.rs (target\debug\deps\csharp_post_write-0cbd1abd0894dff0.exe) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests\custom_tools.rs (target\debug\deps\custom_tools-5d4f508f07ac9ebf.exe) + +running 10 tests +test batch_validates_all_custom_arguments_before_any_side_effect ... ok +test custom_method_is_not_retried_after_lost_response ... ok +test custom_numeric_ranges_and_nullable_defaults_are_validated_before_execution ... ok +test discovery_merges_schemas_and_sources_and_filters_custom_tools ... ok +test discovery_rejects_conflicting_or_malformed_editor_catalogs ... ok +test dry_run_and_unknown_tools_never_invoke_a_custom_method ... ok +test invalid_custom_arguments_never_reach_the_method ... ok +test names_only_and_compact_preserve_small_list_shapes ... ok +test old_bridges_keep_the_builtin_catalog_but_auth_errors_are_visible ... ok +test schema_and_all_call_spellings_support_custom_names ... ok + +test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.16s + + Running tests\editor_lifecycle.rs (target\debug\deps\editor_lifecycle-aeb0970475380a52.exe) + +running 4 tests +test close_requires_bridge_scene_protection_before_sending_quit ... ok +test editor_lifecycle_commands_are_available ... ok +test missing_editor_explains_official_install_and_returns_precondition ... ok +test status_reports_compilation_from_the_selected_project ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.11s + + Running tests\install_script.rs (target\debug\deps\install_script-b6d8d13afae90fa0.exe) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests\json_envelope.rs (target\debug\deps\json_envelope-12e7edbd882a2b08.exe) + +running 15 tests +test batch_with_failed_operation_does_not_exit_zero ... ok +test bridge_errors_preserve_codes_and_authentication_exit ... ok +test bridge_warnings_reach_the_public_envelope ... ok +test clap_usage_error_has_json_envelope ... ok +test direct_authentication_and_bridge_failures_match_daemon ... ok +test invalid_batch_is_usage_error ... ok +test invalid_json_is_usage_error ... ok +test invalid_port_list_is_usage_error ... ok +test invalid_tool_routes_are_usage_errors ... ok +test local_success_uses_single_envelope ... ok +test nested_bridge_failure_is_not_reported_as_success ... ok +test response_timeout_is_retryable_operation_failure ... ok +test skills_show_and_lint_use_envelopes ... FAILED +test test_completion_distinguishes_failed_and_passed ... ok +test unreachable_editor_is_exit_seven ... ok + +failures: + +---- skills_show_and_lint_use_envelopes stdout ---- + +thread 'skills_show_and_lint_use_envelopes' (50576) panicked at tests\json_envelope.rs:37:5: +assertion `left == right` failed: stderr= + left: Some(1) + right: Some(0) +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + skills_show_and_lint_use_envelopes + +test result: FAILED. 14 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 10.87s + +error: test failed, to rerun pass `--test json_envelope` + Running tests\mcp.rs (target\debug\deps\mcp-86a7609ca7ad34e1.exe) + +running 3 tests +test configure_all_clients_preserves_other_servers_and_dry_run ... ok +test malformed_requests_do_not_end_session_or_execute_tools_before_initialization ... ok +test stdio_catalog_and_failure_contract_without_editor ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 7.51s + + Running tests\mcp_dynamic.rs (target\debug\deps\mcp_dynamic-499b85548652bf36.exe) + +running 1 test +test custom_catalog_calls_and_live_removal_share_cli_discovery_and_validation ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.11s + + Running tests\setup_dry_run.rs (target\debug\deps\setup_dry_run-e3a3263aee254c2d.exe) + +running 2 tests +test setup_dry_run_prints_plan_without_connections_writes_or_launches ... ok +test setup_launch_returns_output_while_editor_is_still_running ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.86s + + Running tests\skills_install.rs (target\debug\deps\skills_install-e3670c19589ccb8a.exe) + +running 7 tests +test all_clients_install_embedded_references_and_show_works_outside_repository ... ok +test dry_run_prints_only_paths_without_creating_files ... ok +test global_dry_run_flag_also_prevents_installation ... ok +test install_protects_unowned_directory_and_force_keeps_unrelated_files ... ok +test invalid_ledger_paths_are_rejected_even_with_force ... ok +test refresh_does_not_install_clients_without_a_ledger ... ok +test refresh_syncs_an_older_owned_version_and_protects_local_edits ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.89s + + Running tests\tool_list_filters.rs (target\debug\deps\tool_list_filters-71cf420645a1f348.exe) + +running 7 tests +test category_returns_only_that_docs_section ... ok +test compact_is_name_and_description_only_and_at_most_half_of_full_catalog ... ok +test limit_and_offset_page_the_filtered_list ... ok +test offline_default_list_has_schemas_and_names_only_is_compatible ... ok +test query_returns_only_matching_tools ... ok +test unknown_category_is_rejected ... ok +test unopened_project_still_exposes_the_offline_builtin_catalog ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.35s + + Running tests\unityd_autostart.rs (target\debug\deps\unityd_autostart-c58b98ce6bcf74d1.exe) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + +error: 1 target failed: + `--test json_envelope` diff --git a/docs/verification/issue-386/cargo-test-inventory.json b/docs/verification/issue-386/cargo-test-inventory.json new file mode 100644 index 00000000..4b65d119 --- /dev/null +++ b/docs/verification/issue-386/cargo-test-inventory.json @@ -0,0 +1,3039 @@ +{ + "counts": { + "PASS": 605, + "FAIL": 1, + "SKIP": 0 + }, + "tests": [ + { + "suite": "unittests", + "name": "app::editor::tests::editor_launch_uses_paths_supported_by_unity", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::ambiguous_editor_fails_before_contacting_any_editor", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::animation_curve_edits_accept_operations_and_tangent_modes", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::animation_curve_edits_reject_missing_identifiers_and_invalid_nested_fields", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::animation_curve_queries_validate_complete_binding_filters", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::audio_mixer_arguments_are_action_specific", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::augment_command_stats_inserts_cli_snapshot", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::baking_invalid_target_missing_scene_and_missing_job_are_rejected", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::baking_surface_requires_path_before_contacting_editor", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::baking_valid_targets_and_polling_are_accepted", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::bridge_commands_resolve_explicit_project_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_clean_defaults", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_clean_with_version", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_diff_path_mode_with_limit", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_diff_symbol_mode", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_embed_build_includes_version", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_embed_build_omits_optional_version", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_embed_search_omits_optional_top_k", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_embed_search_with_top_k", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_fetch_carries_all_flags", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_fetch_defaults_without_overrides", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_find_symbol_minimal", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_find_symbol_with_filters", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_grep_defaults_context_to_zero", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_grep_with_file_glob_and_context", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_resolve_symbol_at_minimal", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_resolve_symbol_at_with_version", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_search_minimal_pattern", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_search_with_all_options", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_status_includes_explicit_version", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_status_omits_optional_version", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_view_omits_optional_lines", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::build_reference_call_view_with_range", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::capture_screenshot_timeout_respects_os_fallback_flag", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::env_var_guard_restores_previous_value", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::eval_cli_accepts_code_and_rejects_invalid_mode", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::eval_dry_run_does_not_execute_arbitrary_code", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::eval_schemas_require_code_and_status_id", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::eval_transport_error_keeps_generated_request_id", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::execute_tool_skips_mutating_tool_in_dry_run_mode", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::hot_reload_requires_revision_and_explicit_action", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::init_tracing_accepts_verbose_levels", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::instances_list_defaults_host_to_ipv4_loopback", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::load_params_defaults_to_empty_object", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::load_params_reads_inline_json", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::load_params_reads_json_from_file", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::load_params_rejects_when_json_and_params_file_are_both_set", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::parse_external_tool_command_accepts_json_flag", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::parse_external_tool_command_rejects_unknown_flag", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::parse_external_tool_command_requires_tool_name", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::parse_external_tool_command_requires_values_for_flags", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::parse_external_tool_command_supports_equals_forms", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::parse_json_object_accepts_object", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::parse_json_object_rejects_non_object", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::parse_ports_deduplicates_values", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::parse_ports_rejects_invalid_values", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::parse_ports_returns_empty_for_none", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::parse_ports_with_diagnostics_reports_duplicate_values", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::ping_version_check_reports_mismatch_and_unknown", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::prefab_override_validation_requires_explicit_scope_and_apply_target", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::print_value_text_handles_string_and_object", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::project_path_flag_is_global_and_feeds_runtime_overrides", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::run_with_cli_batch_marks_skipped_items_in_dry_run_mode", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::run_with_cli_exercises_remote_command_error_paths", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::run_with_cli_handles_instances_and_daemon_commands_without_server", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::run_with_cli_handles_local_tool_and_batch_paths", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::run_with_cli_rejects_unknown_external_tool", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::run_with_cli_requires_batch_input_source", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::run_with_cli_set_active_text_output_when_reachable", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::run_with_cli_supports_tool_schema_command", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::runtime_overrides_are_derived_from_cli_at_app_boundary", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::setup_and_bridge_cli_arguments_parse", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::timeline_manage_is_skipped_in_dry_run", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::timeline_validation_requires_target_and_valid_action", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_add_component_payload", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_addressables_manage_add_entry", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_analyze_asset_dependencies_get_dependencies", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_build_index_output_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_create_animation_clip_payload", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_create_animator_controller_payload", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_create_gameobject_with_vector_fields", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_create_sprite_atlas_payload", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_delete_gameobject_with_path_and_paths", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_execute_menu_item_get_available_menus", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_execute_menu_item_without_action", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_get_input_actions_state_with_asset_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_input_keyboard_batch_actions", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_load_scene_by_name", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_lsp_write_payload_with_path_alias", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_manage_layers_get_by_index", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_package_manager_list_action", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_profiler_start_payload", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_valid_payload", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_accepts_write_csharp_file_payload", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_addressables_analyze_dependencies_without_asset_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_addressables_manage_move_entry_without_target_group", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_analyze_asset_dependencies_get_dependencies_without_asset_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_analyze_asset_dependencies_invalid_action", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_analyze_screenshot_without_source", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_create_animation_clip_without_sprite_paths", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_create_package_setting_without_value", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_delete_gameobject_without_target", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_execute_menu_item_without_action_or_menu_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_execute_menu_item_without_menu_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_invalid_animator_condition_mode", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_invalid_sprite_atlas_filter_mode", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_load_scene_with_both_identifiers", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_manage_asset_database_move_without_to_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_manage_layers_add_without_layer_name", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_manage_layers_invalid_action", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_manage_selection_set_without_object_paths", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_manage_tools_activate_without_tool_name", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_manage_windows_focus_without_window_type", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_missing_required_property", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_package_manager_search_without_keyword", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_registry_config_add_scope_without_scope", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_remove_input_binding_without_selector", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_set_component_field_missing_required", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_unknown_field_for_clear_logs", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_unknown_property_when_schema_is_strict", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::runner::tests::validate_tool_params_rejects_unknown_run_tests_property", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::setup::tests::hub_paths_for_windows_and_linux_do_not_depend_on_test_host", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::setup::tests::launch_editor_skips_when_project_is_locked_and_errors_without_editor", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::setup::tests::project_unity_version_and_hub_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::setup::tests::setup_dry_run_leaves_editor_unchecked_and_skips_writes", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::setup::tests::setup_flags_editor_serving_another_project", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::setup::tests::setup_installs_bridge_and_confirms_matching_editor", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::setup::tests::setup_reports_version_mismatch_as_json", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::setup::tests::setup_without_dry_run_reports_unreachable_editor", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::test_report::tests::github_annotations_extract_unity_location_and_escape_injection", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::test_report::tests::junit_preserves_failed_skipped_and_escaped_details", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::test_report::tests::junit_time_is_millisecond_precision_for_xunit_schema", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::test_report::tests::nunit_nests_test_cases_in_a_suite_and_preserves_details", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::test_report::tests::parent_suite_rollups_do_not_duplicate_leaf_failures", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "app::test_report::tests::suite_failure_is_reported_even_without_failed_leaves", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "cli::test_command_tests::test_command_accepts_report_output_without_changing_global_output", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::bridge::tests::dry_run_reports_change_without_writing", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::bridge::tests::embedded_package_is_reported_and_not_duplicated", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::bridge::tests::input_backends_untouched_when_setting_absent_or_already_enabled", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::bridge::tests::install_adds_openupm_registry_and_cli_version", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::bridge::tests::install_adds_scope_to_existing_openupm_registry", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::bridge::tests::install_enables_input_system_backends_while_editor_is_closed", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::bridge::tests::install_is_noop_when_already_configured_by_hand", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::bridge::tests::install_keeps_other_version_and_upgrade_pins_cli_version", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::bridge::tests::install_leaves_input_backends_when_editor_is_open_or_dry_run", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::bridge::tests::install_twice_leaves_manifest_byte_identical", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::bridge::tests::rejects_malformed_manifest", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::bridge::tests::resolve_project_root_walks_up_and_validates_explicit_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::bridge::tests::status_prefers_lock_resolution_and_reports_missing", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::bridge::tests::upgrade_leaves_custom_sources_alone", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::bridge::tests::version_check_classifies_versions", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::command_stats::tests::snapshot_groups_calls_by_tool_and_route", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::config::tests::default_host_returns_ipv4_loopback_without_env", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::config::tests::default_port_returns_6400_without_env", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::config::tests::default_timeout_returns_30000_without_env", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::config::tests::empty_value_is_ignored", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::config::tests::execution_context_uses_defaults", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::config::tests::fails_when_legacy_alias_is_set", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::config::tests::fails_when_removed_unityd_env_is_set", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::config::tests::returns_none_when_no_keys_set", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::config::tests::u16_env_parses_correctly", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::config::tests::u16_env_rejects_zero", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::config::tests::u64_env_parses_correctly", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::config::tests::u64_env_rejects_zero", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::doctor::tests::classification_priority", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::doctor::tests::editor_import_workers_are_not_reusable_editors", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::doctor::tests::parses_safe_mode_and_latest_compile_errors", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::doctor::tests::reads_bridge_version_from_local_file_dependency", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::doctor::tests::reads_project_bridge_port", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::doctor::tests::recognizes_editor_command_lines_only", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::doctor::tests::reports_editor_not_running", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::doctor::tests::reports_port_in_use_with_owner_pid", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::doctor::tests::safe_mode_exit_clears_flag", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::editor_discovery::tests::ambiguous_error_json_lists_candidates", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::editor_discovery::tests::dead_pid_marks_lockfile_stale", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::editor_discovery::tests::discover_reads_lockfiles_and_skips_garbage", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::editor_discovery::tests::expired_heartbeat_marks_lockfile_stale", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::editor_discovery::tests::pid_zero_is_never_alive", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::editor_discovery::tests::select_for_path_ignores_stale_editors_and_sibling_prefixes", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::editor_discovery::tests::select_for_path_prefers_deepest_live_project", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::endpoint::tests::active_instance_keeps_priority_over_lockfile_discovery", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::endpoint::tests::cli_override_wins_over_active_instance", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::endpoint::tests::cwd_inside_project_selects_that_editor", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::endpoint::tests::cwd_outside_projects_with_two_editors_is_ambiguous", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::endpoint::tests::env_port_wins_when_no_cli_override", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::endpoint::tests::explicit_port_wins_over_project_path_and_lockfiles", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::endpoint::tests::no_lockfiles_keeps_legacy_default", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::endpoint::tests::project_command_targets_its_own_editor_among_several", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::endpoint::tests::project_command_without_its_editor_uses_default_endpoint", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::endpoint::tests::project_path_selects_matching_editor", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::endpoint::tests::project_path_without_running_editor_is_not_found", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::endpoint::tests::project_root_env_falls_back_to_default_without_any_lockfile", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::endpoint::tests::single_running_editor_is_used_from_anywhere", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::endpoint::tests::stale_editors_do_not_cause_ambiguity", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::endpoint::tests::unity_project_root_env_acts_as_project_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::instances::tests::authenticated_health_checks_support_listing_and_selection", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::instances::tests::list_instances_adds_default_port_when_no_entries_exist", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::instances::tests::list_instances_enumerates_lockfiles_without_ports", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::instances::tests::list_instances_keeps_explicit_ports_next_to_lockfiles", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::instances::tests::list_instances_reports_down_for_tcp_listener_that_is_not_unity_bridge", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::instances::tests::list_instances_reports_up_for_reachable_port", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::instances::tests::load_registry_reconstructs_missing_ids", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::instances::tests::parse_id_validates_shape", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::instances::tests::registry_path_uses_env_and_creates_parent_directory", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::instances::tests::registry_round_trip_serialization_shape_is_supported", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::instances::tests::set_active_fails_for_unreachable_instance", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::instances::tests::set_active_succeeds_for_reachable_instance_and_tracks_previous", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::cache_root_falls_back_to_home_unity_cache", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::cache_root_prefers_unity_cli_cache_root_env", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::detect_rid_returns_known_target_triple", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::download_latest_binary_applies_matching_checksum", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::download_latest_binary_rejects_checksum_mismatch_and_keeps_existing_install", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::ensure_latest_for_can_skip_remote_checks_in_tests", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::ensure_local_uses_existing_binary_without_download", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::get_json_fails_with_status_and_body", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::get_json_parses_http_body", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::get_json_retries_transient_server_error", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::get_optional_text_returns_body_for_success", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::get_optional_text_returns_none_for_not_found", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::get_response_includes_authorization_header", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::get_response_reports_http_status_errors", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::parse_sha256sums_reads_text_and_binary_mode_entries", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::read_local_version_returns_none_for_missing_or_blank_file", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::replace_file_atomic_overwrites_destination", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::sha256_file_matches_known_hash", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::tools_root_falls_back_to_home_unity_tools_when_env_unset", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::tools_root_prefers_unity_cli_tools_root_env", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::unity_cli_status_uses_managed_install_layout", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::verify_manifest_against_checksums_requires_matching_entry", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::managed_binaries::tests::write_and_read_local_version_round_trip", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::runtime_paths::tests::daemon_dir_is_under_run_root", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::self_update::tests::is_recent_returns_false_for_missing_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::self_update::tests::is_recent_returns_true_for_freshly_touched_file", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::self_update::tests::last_check_path_uses_unity_cli_tools_root_env", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::self_update::tests::maybe_self_update_skipped_when_opt_out_env_set", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::self_update::tests::maybe_self_update_skips_when_recent_check_exists", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::self_update::tests::touch_creates_parent_and_writes_marker", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "core::self_update::tests::warn_cargo_conflict_runs_without_panic", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::runtime::tests::runtime_module_builds_without_warnings_when_unix_code_is_disabled", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::spawn::tests::spawn_detached_starts_the_command", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::spawn::tests::spawn_module_builds_for_windows_without_warnings", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::spawn::tests::spawned_child_does_not_hold_the_callers_stdout_pipe", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::unityd::tests::daemon_call_error_classification", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::unityd::tests::daemon_request_batch_round_trip", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::unityd::tests::daemon_request_ping_round_trip", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::unityd::tests::daemon_request_status_round_trip", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::unityd::tests::daemon_request_stop_round_trip", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::unityd::tests::daemon_request_tool_round_trip", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::unityd::tests::daemon_response_error_round_trip", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::unityd::tests::daemon_response_round_trip", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::unityd::tests::daemon_response_round_trip_preserves_timing", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::unityd::tests::idle_timeout_default", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::unityd::tests::pid_file_path_is_under_tools_dir", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::unityd::tests::pooled_connection_closed_by_editor_restart_is_reconnected_before_sending", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::unityd::tests::pooled_connection_uses_each_requests_timeout", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::unityd::tests::request_lost_after_sending_is_reported_and_not_resent", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::unityd::tests::startup_lock_times_out_and_is_reusable_after_release", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "daemon::unityd::tests::tools_dir_creates_directory", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::client::tests::collect_document_symbols_flattens_nested_symbols", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::client::tests::get_apply_defaults_to_false", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::client::tests::id_matches_accepts_number_and_string_id", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::client::tests::kind_from_lsp_maps_known_values", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::client::tests::normalize_lsp_write_result_adds_contract_fields", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::client::tests::normalize_rel_path_accepts_assets_packages_and_library", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::client::tests::normalize_rel_path_extracts_supported_prefix_from_absolute_like_input", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::client::tests::normalize_rel_path_rejects_parent_traversal", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::client::tests::path_matches_scope_filters_paths", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::client::tests::remove_symbol_request_includes_fail_on_references_when_set", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::client::tests::remove_symbol_request_omits_fail_on_references_when_unset", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::client::tests::require_helpers_validate_expected_fields", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::client::tests::retryable_session_error_detects_transport_failures", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::client::tests::retryable_session_error_ignores_argument_errors", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::client::tests::to_project_relative_or_raw_returns_relative_for_absolute_under_root", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::client::tests::uri_and_ref_path_helpers_resolve_project_relative_paths", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::client::tests::uri_to_rel_path_rejects_non_file_uris", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::daemon::tests::daemon_idle_timeout_uses_env_override", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::daemon::tests::handle_request_handles_ping_status_and_stop", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::daemon::tests::is_would_block_checks_error_kind", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::daemon::tests::write_all_with_retry_handles_would_block_and_partial_writes", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::daemon::tests::write_all_with_retry_rejects_zero_byte_progress", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "lsp::daemon::tests::write_pid_file_and_cleanup_manage_files_under_tools_root", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "mcp::configure::tests::custom_root_may_have_missing_ancestors_without_creating_them", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "mcp::configure::tests::invalid_config_is_never_overwritten_and_preview_creates_nothing", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "mcp::configure::tests::malformed_shapes_and_http_name_collisions_are_rejected", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "mcp::configure::tests::merges_inline_toml_without_losing_other_servers_or_options", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "mcp::configure::tests::windows_and_local_paths", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "mcp::tests::projects_owned_custom_descriptor_without_an_mcp_specific_schema", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::cache::tests::gc_empty_root_returns_empty", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::cache::tests::gc_keep_zero_removes_all_versions", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::cache::tests::gc_keeps_n_newest_and_returns_removed", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::cache::tests::gc_skips_non_directory_entries", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::cache::tests::list_versions_empty_when_root_missing", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::cache::tests::list_versions_returns_existing_dirs", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::cache::tests::list_versions_skips_files_in_root", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::cache::tests::meta_roundtrip", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::cache::tests::read_meta_returns_error_for_invalid_json", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::cache::tests::read_meta_returns_error_when_missing", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::cache::tests::version_dir_rejects_empty", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::cache::tests::version_dir_rejects_paths_outside_single_cache_entry", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::cache::tests::version_dir_under_cache_root", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::diff::tests::compute_line_diff_empty_for_identical_lines", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::diff::tests::compute_line_diff_for_deletes_only_returns_removal_hunk", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::diff::tests::compute_line_diff_for_inserts_only_returns_addition_hunk", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::diff::tests::compute_line_diff_for_separate_changes_produces_multiple_hunks", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::diff::tests::compute_line_diff_replacement_isolates_changed_lines", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::diff::tests::compute_path_diff_can_be_truncated", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::diff::tests::compute_path_diff_categorises_runtime_export", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::diff::tests::compute_symbol_diff_detects_changed_animator", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::diff::tests::compute_symbol_diff_returns_diff_when_only_one_side_has_symbol", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::diff::tests::compute_symbol_diff_returns_none_for_missing_in_both", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::diff::tests::ensure_cache_dir_errors_on_missing", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::diff::tests::split_fqn_separates_namespace_and_name", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::embed::tests::build_embedding_index_handles_empty_symbol_index", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::embed::tests::build_embedding_index_with_mock_embedder", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::embed::tests::cosine_similarity_handles_zero_vectors", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::embed::tests::embedding_roundtrip_via_bincode", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::embed::tests::resolve_onnxruntime_dylib_explains_how_to_install_when_missing", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::embed::tests::resolve_onnxruntime_dylib_falls_back_to_first_existing_candidate", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::embed::tests::resolve_onnxruntime_dylib_prefers_existing_env_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::embed::tests::resolve_onnxruntime_dylib_rejects_missing_env_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::embed::tests::search_ranks_by_cosine_similarity", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::embed::tests::search_returns_empty_for_empty_index", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::embed::tests::search_returns_empty_for_empty_query", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::embed::tests::symbol_to_text_includes_namespace_and_kind", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::embed::tests::symbol_to_text_without_namespace_omits_dot", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::api_discovery_paginates_branches_and_includes_tags", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::api_discovery_surfaces_http_errors", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::archive_url_uses_unity_cs_reference_org", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::build_clone_args_emits_shallow_single_branch", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::ensure_git_available_succeeds_in_test_env", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::extract_zip_to_rejects_entries_with_parent_segments", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::extract_zip_to_strips_top_level_prefix_and_writes_files", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::fetch_selected_pins_commit_after_branch_advances", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::fetch_selected_rejects_invalid_commit_before_creating_destination", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::github_token_returns_none_when_env_unset", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::github_token_skips_empty_and_picks_first_non_empty", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::license_ok_when_env_set", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::license_ok_when_flag_true", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::license_rejects_zero_value", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::license_required_when_flag_false_and_env_unset", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::list_public_refs_discovers_branches_and_tags", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::list_public_refs_preserves_transport_error", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::fetcher::tests::run_clone_rejects_when_license_not_accepted", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::index::tests::build_or_update_index_handles_existing_fixture", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::index::tests::build_or_update_index_persists_signature", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::index::tests::build_or_update_index_skips_already_indexed_files_until_change", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::index::tests::extract_symbols_from_text_captures_namespace", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::index::tests::extract_symbols_from_text_does_not_double_capture_class_name", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::index::tests::extract_symbols_from_text_finds_class", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::index::tests::extract_symbols_from_text_finds_methods", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::index::tests::extract_symbols_from_text_finds_property", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::index::tests::extract_symbols_from_text_finds_struct_and_interface", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::index::tests::file_signature_changes_when_content_changes", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::index::tests::find_symbol_filters_by_kind_and_namespace", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::index::tests::validate_kind_accepts_known_and_rejects_unknown", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::search::tests::grep_filters_by_filename_glob", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::search::tests::grep_finds_class_animator_with_line_numbers", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::search::tests::grep_returns_context_lines", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::search::tests::view_rejects_parent_traversal", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::search::tests::view_returns_requested_line_range", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::cached_fetch_and_status_report_stored_provenance", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::cached_unknown_version_can_be_used_without_branch_resolution", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::dir_size_empty_returns_zero", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::dir_size_sums_file_lengths", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_clean_dry_run_false_actually_removes", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_clean_dry_run_on_empty_cache_returns_empty_removed", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_diff_errors_when_cache_missing", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_diff_path_mode_returns_added_removed_changed", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_diff_requires_from_and_to", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_diff_requires_symbol_or_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_diff_symbol_mode_returns_diffs", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_embed_build_errors_when_cache_missing", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_embed_search_errors_when_index_missing", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_embed_search_requires_query", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_fetch_force_preserves_existing_on_transport_failure", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_fetch_skips_when_destination_exists_without_force", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_find_symbol_empty_hits_for_unknown_name", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_find_symbol_filters_namespace", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_find_symbol_rejects_unknown_kind", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_find_symbol_requires_name", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_find_symbol_returns_error_when_cache_missing", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_find_symbol_returns_hits_from_fixture", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_grep_invalid_regex_returns_error", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_grep_requires_pattern", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_grep_supports_file_glob_filter", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_grep_via_dispatcher_returns_hits", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_resolve_symbol_at_empty_token_for_blank_position", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_resolve_symbol_at_finds_token_via_fixture", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_resolve_symbol_at_requires_path_line_column", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_resolve_symbol_at_requires_project_prefix", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_search_requires_pattern", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_search_via_dispatcher_truncates_max_results", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_search_without_max_results_returns_all_hits", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_status_includes_size_bytes", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_status_returns_versions_list", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_view_rejects_parent_traversal_via_dispatcher", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_view_requires_path_param", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::execute_view_via_dispatcher_returns_lines", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::extract_token_at_cursor_handles_edge_cases", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::extract_token_at_cursor_handles_escaped_quote_in_string", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::extract_token_at_cursor_returns_ident_after_closed_string", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::extract_token_at_cursor_skips_line_comment", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::extract_token_at_cursor_skips_string_literal", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::fetch_resolves_project_and_explicit_refs_and_records_actual_commit", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::legacy_metadata_keeps_unknown_match_instead_of_claiming_exact", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::maybe_execute_returns_none_for_unknown_tool", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::now_unix_seconds_string_is_decimal", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::resolve_version_falls_back_to_project_detection", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::tests::resolve_version_uses_explicit_param", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::version::tests::ambiguous_auto_candidates_and_unknown_versions_return_candidates", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::version::tests::detect_returns_error_when_editor_version_line_absent", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::version::tests::detect_returns_error_when_editor_version_value_empty", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::version::tests::detect_returns_error_when_project_version_missing", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::version::tests::exact_tag_precedes_minor_but_version_named_head_is_not_exact", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::version::tests::explicit_ref_has_priority_and_ambiguous_short_names_require_full_ref", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::version::tests::minor_version_key_rejects_invalid_inputs", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::version::tests::parse_editor_version_returns_value_directly", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::version::tests::parses_remote_refs_with_peeled_tag_commits_in_any_order", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::version::tests::public_resolver_handles_previously_supported_minors", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::version::tests::reads_known_project_version", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::version::tests::reads_unknown_minor_without_static_mapping", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "reference::version::tests::selects_new_and_existing_minor_branches_without_claiming_exact_match", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::loader::tests::load_skills_handles_missing_root_and_skips_non_skill_entries", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::loader::tests::load_skills_supports_single_skill_root_and_dir_name_fallback", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::loader::tests::parse_frontmatter_and_collect_references_cover_optional_branches", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::loader::tests::parse_frontmatter_extracts_metadata", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::loader::tests::split_frontmatter_and_parse_frontmatter_cover_edge_cases", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::loader::tests::split_frontmatter_handles_basic_skill", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::good_skill_passes_all_rules", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::model_helpers_cover_skill_accessors_and_tool_sets", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r01_missing_description_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r01_missing_multiple_required_fields_fire", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r02_name_mismatch_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r03_disallowed_tool_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r03_legacy_bare_bash_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r04_unknown_category_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r05_empty_and_duplicate_triggers_fire", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r05_uppercase_trigger_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r06_unknown_sibling_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r07_too_long_description_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r08_missing_front_trigger_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r09_first_person_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r10_missing_use_when_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r11_missing_sibling_mention_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r12_unidirectional_sibling_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r13_too_long_body_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r14_missing_heading_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r15_references_without_link_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r16_time_sensitive_phrase_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r17_missing_runtime_checklist_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r18_long_reference_without_toc_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r19_reference_link_to_reference_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::r22_collision_without_cross_listing_fires", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "skills::tests::report_and_runner_cover_text_json_discovery_and_error_paths", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "test_env::isolated_runtime_restores_inherited_environment_after_unwind", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::discovery::tests::bridge_reserved_names_match_the_cli_catalog_including_local_tools", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::discovery::tests::builtin_descriptors_keep_schemas_and_mark_their_source", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::discovery::tests::custom_descriptor_roundtrips_owned_names_and_schema", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::discovery::tests::list_tools_is_a_read_only_remote_builtin", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::build_index_and_find_symbol_roundtrip", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::collect_cs_files_and_index_helpers_cover_readiness_branches", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::create_class_generates_simple_class", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::create_class_rejects_existing_file", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::create_class_rejects_invalid_name", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::create_class_with_namespace_and_inherits", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::default_runtime_config_falls_back_to_ipv4_loopback", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::extract_symbols_from_text_covers_major_symbol_kinds", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::find_refs_supports_cursor_paging", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::find_symbol_returns_index_not_ready_before_build", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::get_symbols_extracts_class_and_method", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::helper_comment_and_snippet_processing_works", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::helper_path_normalization_and_resolution_cover_edge_cases", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::helper_symbol_and_scope_predicates_work", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::list_packages_lists_package_dirs", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::lsp_write_tools_require_lsp_mode", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::post_write_refresh_failure_preserves_applied_files_without_runtime_panic", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::read_returns_file_slice", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::requires_unityengine_using_only_for_monobehaviour", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::search_finds_matching_lines", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::local_tools::tests::update_index_refreshes_symbol_names", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::os_capture::tests::capture_fails_when_no_candidate_exists", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::os_capture::tests::detects_daemon_stringified_timeouts", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::os_capture::tests::disabled_fallback_returns_the_timeout_error", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::os_capture::tests::failed_os_capture_keeps_both_errors", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::os_capture::tests::fallback_flag_defaults_on_and_is_stripped", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::os_capture::tests::non_timeout_errors_are_not_recovered", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::os_capture::tests::output_path_follows_bridge_capture_directory", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::os_capture::tests::timeout_is_recovered_with_os_fallback_marker", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::os_capture::tests::verbatim_prefix_is_dropped_before_the_path_reaches_os_tools", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::action_enum_schemas_use_composite_variants", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::addressables_analyze_schema_uses_action_specific_variants", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::addressables_manage_schema_has_manage_actions", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::all_tools_e2e_covers_catalog_or_documents_exclusion", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::analyze_asset_dependencies_schema_has_expected_actions", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::animation_curve_tools_advertise_strict_unity_contracts", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::baking_tools_have_explicit_target_and_polling_contracts", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::build_index_schema_allows_output_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::build_player_schema_requires_explicit_safe_build_inputs", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::capture_video_start_schema_restricts_mode_and_format", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::clear_logs_schema_is_strict_empty_object", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::create_animation_clip_schema_requires_clip_and_sprite_paths", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::create_animator_controller_schema_is_strict_and_nested", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::create_prefab_schema_allows_template_mode_without_source_object", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::create_sprite_atlas_schema_is_strict_and_nested", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::csharp_file_write_schemas_are_local_and_strict", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::delete_gameobject_schema_uses_any_of_targets", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::execute_menu_item_schema_supports_default_and_action_variants", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::get_build_status_is_read_only_and_requires_build_id", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::get_gameobject_details_schema_uses_any_of_identifiers", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::get_index_status_schema_is_strict_empty_object", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::hot_reload_tools_expose_explicit_preview_and_recovery_contract", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::input_keyboard_schema_uses_any_of_for_action_or_actions", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::known_tool_lookup_works", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::load_scene_schema_uses_one_of_identifier_variants", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::local_executor_tools_are_marked", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::manage_asset_database_schema_uses_action_specific_variants", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::manage_layers_schema_requires_action_enum", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::modify_gameobject_schema_requires_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::package_manager_schema_has_required_action", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::ping_schema_is_strict_object", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::prefab_override_tools_have_strict_discoverable_schemas", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::quit_editor_exposes_optional_scene_protection_parameter", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::remote_tools_have_unity_bridge_dispatch_cases", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::rename_symbol_schema_is_strict_and_requires_name_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::run_tests_schema_allows_test_mode_enum", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::set_component_field_schema_requires_component_and_field", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::timeline_schema_exposes_actions_and_stale_clip_guard", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::timeline_tools_are_discoverable_with_correct_mutation_flags", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::tool_catalog_avoids_default_params_schema_for_known_tools", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::tool_catalog_keeps_manifest_parity_count", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::tool_specs_cover_catalog", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::tools_doc_matches_registered_catalog", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::vfx_apply_is_mutating_and_requires_op", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::vfx_describe_graph_is_read_only_and_requires_asset_path", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::vfx_runtime_is_mutating_and_requires_op_and_game_object", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_catalog::tests::vfx_settings_is_mutating_and_requires_op", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_index::tests::category_accepts_heading_or_slug", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_index::tests::every_tool_has_exactly_one_index_entry_with_a_short_summary", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_index::tests::query_matches_name_or_summary_case_insensitively", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_index::tests::tool_index_matches_docs_headings", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "tooling::tool_index::tests::unknown_category_lists_valid_slugs", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "unity::auth::tests::credentials_are_endpoint_scoped_and_absent_from_discovery_output", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "unity::auth::tests::explicit_mounted_lockfile_and_invalid_file_errors_do_not_expose_token", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "unity::auth::tests::only_exact_one_enables_legacy_opt_out", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "unity::transport::tests::call_tool_returns_error_on_failure_response", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "unity::transport::tests::call_tool_returns_result_on_success", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "unity::transport::tests::call_tool_with_timing_reports_non_negative_durations", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "unity::transport::tests::every_request_carries_token_from_private_lockfile", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "unity::transport::tests::normalize_failure_preserves_complete_error_envelope", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "unity::transport::tests::normalize_response_handles_success_and_error_shapes", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "unity::transport::tests::parse_embedded_json_keeps_plain_strings", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "unity::transport::tests::parse_json_accepts_trimmed_json", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "unity::transport::tests::parse_json_rejects_empty_and_non_utf8_payload", + "status": "PASS" + }, + { + "suite": "unittests", + "name": "unity::transport::tests::ping_backfills_bridge_version_from_editor_state_envelope", + "status": "PASS" + }, + { + "suite": "auth_warning.rs", + "name": "legacy_opt_out_warns_on_stderr_only_for_exact_one", + "status": "PASS" + }, + { + "suite": "bridge_package_dependencies.rs", + "name": "bridge_declares_ugui_when_sources_use_it", + "status": "PASS" + }, + { + "suite": "build_failure_output.rs", + "name": "failed_build_status_keeps_json_report_and_nonzero_exit", + "status": "PASS" + }, + { + "suite": "custom_tools.rs", + "name": "batch_validates_all_custom_arguments_before_any_side_effect", + "status": "PASS" + }, + { + "suite": "custom_tools.rs", + "name": "custom_method_is_not_retried_after_lost_response", + "status": "PASS" + }, + { + "suite": "custom_tools.rs", + "name": "custom_numeric_ranges_and_nullable_defaults_are_validated_before_execution", + "status": "PASS" + }, + { + "suite": "custom_tools.rs", + "name": "discovery_merges_schemas_and_sources_and_filters_custom_tools", + "status": "PASS" + }, + { + "suite": "custom_tools.rs", + "name": "discovery_rejects_conflicting_or_malformed_editor_catalogs", + "status": "PASS" + }, + { + "suite": "custom_tools.rs", + "name": "dry_run_and_unknown_tools_never_invoke_a_custom_method", + "status": "PASS" + }, + { + "suite": "custom_tools.rs", + "name": "invalid_custom_arguments_never_reach_the_method", + "status": "PASS" + }, + { + "suite": "custom_tools.rs", + "name": "names_only_and_compact_preserve_small_list_shapes", + "status": "PASS" + }, + { + "suite": "custom_tools.rs", + "name": "old_bridges_keep_the_builtin_catalog_but_auth_errors_are_visible", + "status": "PASS" + }, + { + "suite": "custom_tools.rs", + "name": "schema_and_all_call_spellings_support_custom_names", + "status": "PASS" + }, + { + "suite": "editor_lifecycle.rs", + "name": "close_requires_bridge_scene_protection_before_sending_quit", + "status": "PASS" + }, + { + "suite": "editor_lifecycle.rs", + "name": "editor_lifecycle_commands_are_available", + "status": "PASS" + }, + { + "suite": "editor_lifecycle.rs", + "name": "missing_editor_explains_official_install_and_returns_precondition", + "status": "PASS" + }, + { + "suite": "editor_lifecycle.rs", + "name": "status_reports_compilation_from_the_selected_project", + "status": "PASS" + }, + { + "suite": "json_envelope.rs", + "name": "batch_with_failed_operation_does_not_exit_zero", + "status": "PASS" + }, + { + "suite": "json_envelope.rs", + "name": "bridge_errors_preserve_codes_and_authentication_exit", + "status": "PASS" + }, + { + "suite": "json_envelope.rs", + "name": "bridge_warnings_reach_the_public_envelope", + "status": "PASS" + }, + { + "suite": "json_envelope.rs", + "name": "clap_usage_error_has_json_envelope", + "status": "PASS" + }, + { + "suite": "json_envelope.rs", + "name": "direct_authentication_and_bridge_failures_match_daemon", + "status": "PASS" + }, + { + "suite": "json_envelope.rs", + "name": "invalid_batch_is_usage_error", + "status": "PASS" + }, + { + "suite": "json_envelope.rs", + "name": "invalid_json_is_usage_error", + "status": "PASS" + }, + { + "suite": "json_envelope.rs", + "name": "invalid_port_list_is_usage_error", + "status": "PASS" + }, + { + "suite": "json_envelope.rs", + "name": "invalid_tool_routes_are_usage_errors", + "status": "PASS" + }, + { + "suite": "json_envelope.rs", + "name": "local_success_uses_single_envelope", + "status": "PASS" + }, + { + "suite": "json_envelope.rs", + "name": "nested_bridge_failure_is_not_reported_as_success", + "status": "PASS" + }, + { + "suite": "json_envelope.rs", + "name": "response_timeout_is_retryable_operation_failure", + "status": "PASS" + }, + { + "suite": "json_envelope.rs", + "name": "skills_show_and_lint_use_envelopes", + "status": "FAIL" + }, + { + "suite": "json_envelope.rs", + "name": "test_completion_distinguishes_failed_and_passed", + "status": "PASS" + }, + { + "suite": "json_envelope.rs", + "name": "unreachable_editor_is_exit_seven", + "status": "PASS" + }, + { + "suite": "mcp.rs", + "name": "configure_all_clients_preserves_other_servers_and_dry_run", + "status": "PASS" + }, + { + "suite": "mcp.rs", + "name": "malformed_requests_do_not_end_session_or_execute_tools_before_initialization", + "status": "PASS" + }, + { + "suite": "mcp.rs", + "name": "stdio_catalog_and_failure_contract_without_editor", + "status": "PASS" + }, + { + "suite": "mcp_dynamic.rs", + "name": "custom_catalog_calls_and_live_removal_share_cli_discovery_and_validation", + "status": "PASS" + }, + { + "suite": "setup_dry_run.rs", + "name": "setup_dry_run_prints_plan_without_connections_writes_or_launches", + "status": "PASS" + }, + { + "suite": "setup_dry_run.rs", + "name": "setup_launch_returns_output_while_editor_is_still_running", + "status": "PASS" + }, + { + "suite": "skills_install.rs", + "name": "all_clients_install_embedded_references_and_show_works_outside_repository", + "status": "PASS" + }, + { + "suite": "skills_install.rs", + "name": "dry_run_prints_only_paths_without_creating_files", + "status": "PASS" + }, + { + "suite": "skills_install.rs", + "name": "global_dry_run_flag_also_prevents_installation", + "status": "PASS" + }, + { + "suite": "skills_install.rs", + "name": "install_protects_unowned_directory_and_force_keeps_unrelated_files", + "status": "PASS" + }, + { + "suite": "skills_install.rs", + "name": "invalid_ledger_paths_are_rejected_even_with_force", + "status": "PASS" + }, + { + "suite": "skills_install.rs", + "name": "refresh_does_not_install_clients_without_a_ledger", + "status": "PASS" + }, + { + "suite": "skills_install.rs", + "name": "refresh_syncs_an_older_owned_version_and_protects_local_edits", + "status": "PASS" + }, + { + "suite": "tool_list_filters.rs", + "name": "category_returns_only_that_docs_section", + "status": "PASS" + }, + { + "suite": "tool_list_filters.rs", + "name": "compact_is_name_and_description_only_and_at_most_half_of_full_catalog", + "status": "PASS" + }, + { + "suite": "tool_list_filters.rs", + "name": "limit_and_offset_page_the_filtered_list", + "status": "PASS" + }, + { + "suite": "tool_list_filters.rs", + "name": "offline_default_list_has_schemas_and_names_only_is_compatible", + "status": "PASS" + }, + { + "suite": "tool_list_filters.rs", + "name": "query_returns_only_matching_tools", + "status": "PASS" + }, + { + "suite": "tool_list_filters.rs", + "name": "unknown_category_is_rejected", + "status": "PASS" + }, + { + "suite": "tool_list_filters.rs", + "name": "unopened_project_still_exposes_the_offline_builtin_catalog", + "status": "PASS" + } + ] +} diff --git a/docs/verification/issue-386/clippy.txt b/docs/verification/issue-386/clippy.txt new file mode 100644 index 00000000..52b4ece6 --- /dev/null +++ b/docs/verification/issue-386/clippy.txt @@ -0,0 +1,2 @@ + Checking unity-cli v0.18.1 () + Finished `dev` profile [unoptimized + debuginfo] target(s) in 7.97s diff --git a/docs/verification/issue-386/environment-final.json b/docs/verification/issue-386/environment-final.json new file mode 100644 index 00000000..1c1979b5 --- /dev/null +++ b/docs/verification/issue-386/environment-final.json @@ -0,0 +1,19 @@ +{ + "observed_at": "2026-10-03T15:48:32.464333+00:00", + "source_file_sha256": { + "UnityCliBridge/Packages/unity-cli-bridge/Editor/Handlers/SceneHandler.cs": "3d44351bdbeda87ffb1a432f3ac013e6c86f2709935bbc7462e01e057a3cc2f9", + "UnityCliBridge/Packages/unity-cli-bridge/Tests/Editor/Handlers/SceneHandlerTests.cs": "381ffee4c4341d6ab7442523ff4e4cec82ae3d9fe8d8239de1edfbbb7bda4717", + "src/app/editor.rs": "12ea2e975445003f9f47e5a8b9e62bbf9c5c7be5ca5e1393ef6bfab022c67199", + "src/app/setup.rs": "eab8bdf7cd59500812ac40c9acc104cf5a6c2c35140733e23571583a0829aa1f", + "src/app/test_runner.rs": "f8023e20459795926704614160cbb05b782f1fdc8b32e6c196d7695b38ae5691", + "src/daemon/unityd.rs": "3cbc5499fc3edb1b8ad3422a864e2e64c94a8f2be4f73f98513a4e5df55d629d", + "src/lsp/client.rs": "7c676ee0a967f79f6914140c1e147d29b58100ac5ec4fa41829b32563bbfd838", + "src/lsp/daemon.rs": "581ac8fd1f9df763069df66c0ed17d6507919ee63c52afff9741aa452f49fc7b", + "src/skills/tests.rs": "77bdd7487e0abc90357bf64d9f3ebc84d6e0f3fba42963a97b368381c15b0fa5", + "tests/setup_dry_run.rs": "b833e5151da71df57eba9770fa88d446a6142c605c5c56a94ae76f0e64344ea8", + "src/mcp/configure.rs": "eced95030b0b011ae2a661b4b8cec1420549064c4945aa74242cc6e38523be64", + "tests/mcp.rs": "bcecb2c5333ddff5d980c9d8f62bfcd6a0e802bda8b8e18b04e213ad7c73a9c8" + }, + "binary_sha256": "9204ab2ad1edaa4b511e559401a04a84b628153c74b08e240d54c4720369eb59", + "note": "Latest native Cargo checks include the MCP profile fix; earlier Windows functional measurements retain their own binary hash." +} diff --git a/docs/verification/issue-386/environment.json b/docs/verification/issue-386/environment.json new file mode 100644 index 00000000..28462eb2 --- /dev/null +++ b/docs/verification/issue-386/environment.json @@ -0,0 +1,23 @@ +{ + "observed_at": "2026-10-03T15:01:21.948334+00:00", + "os": "Windows-11-10.0.26300-SP0", + "machine": "AMD64", + "source_commit": "338f426119b61123567b74028e7e8fe3bd99caa5", + "source_file_sha256": { + "UnityCliBridge/Packages/unity-cli-bridge/Editor/Handlers/SceneHandler.cs": "3d44351bdbeda87ffb1a432f3ac013e6c86f2709935bbc7462e01e057a3cc2f9", + "UnityCliBridge/Packages/unity-cli-bridge/Tests/Editor/Handlers/SceneHandlerTests.cs": "381ffee4c4341d6ab7442523ff4e4cec82ae3d9fe8d8239de1edfbbb7bda4717", + "src/app/editor.rs": "12ea2e975445003f9f47e5a8b9e62bbf9c5c7be5ca5e1393ef6bfab022c67199", + "src/app/setup.rs": "eab8bdf7cd59500812ac40c9acc104cf5a6c2c35140733e23571583a0829aa1f", + "src/app/test_runner.rs": "f8023e20459795926704614160cbb05b782f1fdc8b32e6c196d7695b38ae5691", + "src/daemon/unityd.rs": "3cbc5499fc3edb1b8ad3422a864e2e64c94a8f2be4f73f98513a4e5df55d629d", + "src/lsp/client.rs": "7c676ee0a967f79f6914140c1e147d29b58100ac5ec4fa41829b32563bbfd838", + "src/lsp/daemon.rs": "581ac8fd1f9df763069df66c0ed17d6507919ee63c52afff9741aa452f49fc7b", + "src/skills/tests.rs": "77bdd7487e0abc90357bf64d9f3ebc84d6e0f3fba42963a97b368381c15b0fa5", + "tests/setup_dry_run.rs": "b833e5151da71df57eba9770fa88d446a6142c605c5c56a94ae76f0e64344ea8" + }, + "binary_sha256": "abb04eca3cee68b3260c4701f6a10b2b053c87c1eaef95423117143cf4288eeb", + "release_binary_sha256": "efcd697b940f78b6457829453888d9c608f19d2fcd331d0005b1ff47a7839357", + "unity_version": "6000.4.4f1", + "cli_version": "0.18.1", + "bridge_version": "0.18.1" +} diff --git a/docs/verification/issue-386/final-checks.json b/docs/verification/issue-386/final-checks.json new file mode 100644 index 00000000..84320ce5 --- /dev/null +++ b/docs/verification/issue-386/final-checks.json @@ -0,0 +1,58 @@ +[ + { + "argv": [ + "cargo", + "fmt", + "--all", + "--", + "--check" + ], + "started_at": "2026-10-03T15:40:57.221387+00:00", + "finished_at": "2026-10-03T15:40:58.257958+00:00", + "exit_code": 0, + "log": "fmt.txt" + }, + { + "argv": [ + "cargo", + "clippy", + "--all-targets", + "--", + "-D", + "warnings" + ], + "started_at": "2026-10-03T15:40:58.258389+00:00", + "finished_at": "2026-10-03T15:41:08.285820+00:00", + "exit_code": 0, + "log": "clippy.txt" + }, + { + "argv": [ + "cargo", + "test", + "--all-targets", + "--no-fail-fast", + "--", + "--test-threads=1" + ], + "started_at": "2026-10-03T15:41:08.286169+00:00", + "finished_at": "2026-10-03T15:42:46.665584+00:00", + "exit_code": 101, + "log": "cargo-all-final.txt" + }, + { + "argv": [ + "cargo", + "run", + "--", + "skills", + "lint", + "--severity", + "error" + ], + "started_at": "2026-10-03T15:42:46.666218+00:00", + "finished_at": "2026-10-03T15:42:48.136472+00:00", + "exit_code": 1, + "log": "skills-lint-final.txt" + } +] diff --git a/docs/verification/issue-386/first-operations.json b/docs/verification/issue-386/first-operations.json new file mode 100644 index 00000000..6711d46f --- /dev/null +++ b/docs/verification/issue-386/first-operations.json @@ -0,0 +1,140 @@ +[ + { + "name": "editor_state", + "tool": "get_editor_state", + "status": "PASS", + "elapsed_seconds": 0.159 + }, + { + "name": "hierarchy", + "tool": "get_hierarchy", + "status": "PASS", + "elapsed_seconds": 0.072 + }, + { + "name": "find_gameobject", + "tool": "find_gameobject", + "status": "PASS", + "elapsed_seconds": 0.217 + }, + { + "name": "transform", + "tool": "get_component_values", + "status": "PASS", + "elapsed_seconds": 0.117 + }, + { + "name": "position", + "tool": "modify_gameobject", + "status": "PASS", + "elapsed_seconds": 0.08 + }, + { + "name": "create_cube", + "tool": "create_gameobject", + "status": "PASS", + "elapsed_seconds": 0.292 + }, + { + "name": "add_component", + "tool": "add_component", + "status": "PASS", + "elapsed_seconds": 0.108 + }, + { + "name": "remove_component", + "tool": "remove_component", + "status": "PASS", + "elapsed_seconds": 0.194 + }, + { + "name": "delete_gameobject", + "tool": "delete_gameobject", + "status": "PASS", + "elapsed_seconds": 0.302 + }, + { + "name": "scene_info", + "tool": "get_scene_info", + "status": "PASS", + "elapsed_seconds": 0.393 + }, + { + "name": "scene_save", + "tool": "save_scene", + "status": "PASS", + "elapsed_seconds": 0.431 + }, + { + "name": "console", + "tool": "read_console", + "status": "PASS", + "elapsed_seconds": 0.626 + }, + { + "name": "screenshot", + "tool": "capture_screenshot", + "status": "PASS", + "elapsed_seconds": 0.459 + }, + { + "name": "material_search", + "tool": "manage_asset_database", + "status": "PASS", + "elapsed_seconds": 0.092 + }, + { + "name": "asset_copy", + "tool": "manage_asset_database", + "status": "FAIL", + "error": "Command '['E:\\\\unity-cli\\\\work\\\\issue-386\\\\target\\\\debug\\\\unity-cli.exe', '--output', 'json', '--project-path', 'E:\\\\unity-cli\\\\work\\\\issue-386\\\\.cache\\\\issue-386\\\\red-project', '--timeout-ms', '60000', 'raw', 'manage_asset_database', '--json', '{\"action\": \"copy_asset\", \"fromPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfSource.mat\", \"toPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfCopy.mat\"}']' timed out after 120 seconds" + }, + { + "name": "asset_move", + "tool": "manage_asset_database", + "status": "FAIL", + "error": "Command '['E:\\\\unity-cli\\\\work\\\\issue-386\\\\target\\\\debug\\\\unity-cli.exe', '--output', 'json', '--project-path', 'E:\\\\unity-cli\\\\work\\\\issue-386\\\\.cache\\\\issue-386\\\\red-project', '--timeout-ms', '60000', 'raw', 'manage_asset_database', '--json', '{\"action\": \"move_asset\", \"fromPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfCopy.mat\", \"toPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfMoved.mat\"}']' timed out after 120 seconds" + }, + { + "name": "asset_delete", + "tool": "manage_asset_database", + "status": "FAIL", + "error": "Command '['E:\\\\unity-cli\\\\work\\\\issue-386\\\\target\\\\debug\\\\unity-cli.exe', '--output', 'json', '--project-path', 'E:\\\\unity-cli\\\\work\\\\issue-386\\\\.cache\\\\issue-386\\\\red-project', '--timeout-ms', '60000', 'raw', 'manage_asset_database', '--json', '{\"action\": \"delete_asset\", \"assetPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfMoved.mat\"}']' timed out after 120 seconds" + }, + { + "name": "import_settings", + "tool": "manage_asset_import_settings", + "status": "PASS", + "elapsed_seconds": 8.369 + }, + { + "name": "material_modify", + "tool": "modify_material", + "status": "PASS", + "elapsed_seconds": 0.072 + }, + { + "name": "time_settings", + "tool": "get_project_settings", + "status": "PASS", + "elapsed_seconds": 0.041 + }, + { + "name": "read_csharp", + "tool": "read", + "status": "PASS", + "elapsed_seconds": 0.039 + }, + { + "name": "play_until_ready", + "tool": "play_game", + "status": "FAIL", + "error": "{'code': 'OPERATION_FAILED', 'error': 'OPERATION_FAILED: early eof', 'status': 'error'}" + }, + { + "name": "stop_until_ready", + "tool": "stop_game", + "status": "FAIL", + "error": "{'code': 'UNAUTHORIZED', 'error': 'Missing or invalid authentication token', 'id': '1', 'status': 'error'}" + } +] diff --git a/docs/verification/issue-386/fmt.txt b/docs/verification/issue-386/fmt.txt new file mode 100644 index 00000000..e69de29b diff --git a/docs/verification/issue-386/fresh-setup-summary.json b/docs/verification/issue-386/fresh-setup-summary.json new file mode 100644 index 00000000..e7cc2496 --- /dev/null +++ b/docs/verification/issue-386/fresh-setup-summary.json @@ -0,0 +1,70 @@ +{ + "started_at": "2026-10-03T14:30:44.503670+00:00", + "source_commit": "338f426119b61123567b74028e7e8fe3bd99caa5", + "binary_sha256": "abb04eca3cee68b3260c4701f6a10b2b053c87c1eaef95423117143cf4288eeb", + "cases": { + "setup": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\fresh-setup-project", + "--port", + "6488", + "setup", + "--launch-editor", + "--wait-secs", + "420" + ], + "exit_code": 0, + "elapsed_seconds": 40.549, + "success": true + }, + "ping": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\fresh-setup-project", + "system", + "ping" + ], + "exit_code": 0, + "elapsed_seconds": 1.212, + "success": true + }, + "auto-discovery": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\fresh-setup-project", + "instances", + "list" + ], + "exit_code": 0, + "elapsed_seconds": 3.259, + "success": true + }, + "release-ping": { + "argv": [ + "\\.cache\\issue-386\\installed-tools\\unity-cli\\win-x64\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\fresh-setup-project", + "system", + "ping" + ], + "exit_code": 0, + "elapsed_seconds": 0.552, + "success": true + } + }, + "editor_pid": 14140, + "unity_version": "6000.4.4f1", + "finished_at": "2026-10-03T14:31:30.524967+00:00" +} diff --git a/docs/verification/issue-386/green-results.xml b/docs/verification/issue-386/green-results.xml new file mode 100644 index 00000000..a7b758d4 --- /dev/null +++ b/docs/verification/issue-386/green-results.xml @@ -0,0 +1,13 @@ + +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders + diff --git a/docs/verification/issue-386/install-release.txt b/docs/verification/issue-386/install-release.txt new file mode 100644 index 00000000..b335606d --- /dev/null +++ b/docs/verification/issue-386/install-release.txt @@ -0,0 +1,9 @@ +Detected platform: win-x64 +Fetching latest release... +Release: v0.18.1 +Downloading unity-cli-win-x64... +Checksum verified. +Installed unity-cli 0.18.1 -> E:\unity-cli\work\issue-386\.cache\issue-386\installed-tools\unity-cli\win-x64\unity-cli.exe + +Done. Run 'unity-cli --version' to verify. +unity-cli 0.18.1 diff --git a/docs/verification/issue-386/linux-tool-paths.txt b/docs/verification/issue-386/linux-tool-paths.txt new file mode 100644 index 00000000..c9c846db --- /dev/null +++ b/docs/verification/issue-386/linux-tool-paths.txt @@ -0,0 +1 @@ +/usr/bin/Xvfb diff --git a/docs/verification/issue-386/lockfiles.json b/docs/verification/issue-386/lockfiles.json new file mode 100644 index 00000000..71925144 --- /dev/null +++ b/docs/verification/issue-386/lockfiles.json @@ -0,0 +1,44 @@ +{ + "directory": "%USERPROFILE%\\.unity-cli\\editors", + "locks": [ + { + "schemaVersion": 1, + "pid": 14140, + "projectPath": "\\.cache\\issue-386\\fresh-setup-project", + "host": "127.0.0.1", + "port": 6488, + "configuredPort": 6488, + "unityVersion": "6000.4.4f1", + "bridgeVersion": "0.18.1", + "state": "ready", + "startedAt": 1791037874.9763892, + "heartbeatAt": 1791039672.4251444 + }, + { + "schemaVersion": 1, + "pid": 44232, + "projectPath": "\\.cache\\issue-386\\setup-project", + "host": "127.0.0.1", + "port": 6486, + "configuredPort": 6486, + "unityVersion": "6000.4.4f1", + "bridgeVersion": "0.18.1", + "state": "ready", + "startedAt": 1791001895.7939308, + "heartbeatAt": 1791039677.1909142 + }, + { + "schemaVersion": 1, + "pid": 52408, + "projectPath": "\\.cache\\issue-386\\red-project", + "host": "127.0.0.1", + "port": 6487, + "configuredPort": 6487, + "unityVersion": "6000.4.4f1", + "bridgeVersion": "0.18.1", + "state": "ready", + "startedAt": 1791039377.3480923, + "heartbeatAt": 1791039672.755435 + } + ] +} diff --git a/docs/verification/issue-386/mcp-green.txt b/docs/verification/issue-386/mcp-green.txt new file mode 100644 index 00000000..fb601fa5 --- /dev/null +++ b/docs/verification/issue-386/mcp-green.txt @@ -0,0 +1,30 @@ + Compiling unity-cli v0.18.1 () + Finished `test` profile [unoptimized + debuginfo] target(s) in 6.27s + Running tests\auth_warning.rs (target\debug\deps\auth_warning-fcf05279c683382e.exe) + +running 1 test +test legacy_opt_out_warns_on_stderr_only_for_exact_one ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 8.70s + + Running tests\mcp.rs (target\debug\deps\mcp-86a7609ca7ad34e1.exe) + +running 3 tests +test configure_all_clients_preserves_other_servers_and_dry_run ... ok +test malformed_requests_do_not_end_session_or_execute_tools_before_initialization ... ok +test stdio_catalog_and_failure_contract_without_editor ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 9.24s + + Running tests\tool_list_filters.rs (target\debug\deps\tool_list_filters-71cf420645a1f348.exe) + +running 7 tests +test category_returns_only_that_docs_section ... ok +test compact_is_name_and_description_only_and_at_most_half_of_full_catalog ... ok +test limit_and_offset_page_the_filtered_list ... ok +test offline_default_list_has_schemas_and_names_only_is_compatible ... ok +test query_returns_only_matching_tools ... ok +test unknown_category_is_rejected ... ok +test unopened_project_still_exposes_the_offline_builtin_catalog ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.53s diff --git a/docs/verification/issue-386/mcp-red.txt b/docs/verification/issue-386/mcp-red.txt new file mode 100644 index 00000000..dd750f76 --- /dev/null +++ b/docs/verification/issue-386/mcp-red.txt @@ -0,0 +1,22 @@ + Compiling unity-cli v0.18.1 () + Finished `test` profile [unoptimized + debuginfo] target(s) in 1.06s + Running tests\mcp.rs (target\debug\deps\mcp-86a7609ca7ad34e1.exe) + +running 1 test +test configure_all_clients_preserves_other_servers_and_dry_run ... FAILED + +failures: + +---- configure_all_clients_preserves_other_servers_and_dry_run stdout ---- + +thread 'configure_all_clients_preserves_other_servers_and_dry_run' (49484) panicked at tests\mcp.rs:189:9: +windsurf: preview must target the isolated configuration directory +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + configure_all_clients_preserves_other_servers_and_dry_run + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.77s + +error: test failed, to rerun pass `--test mcp` diff --git a/docs/verification/issue-386/modal-fallback-disabled.stdout.json b/docs/verification/issue-386/modal-fallback-disabled.stdout.json new file mode 100644 index 00000000..471c67da --- /dev/null +++ b/docs/verification/issue-386/modal-fallback-disabled.stdout.json @@ -0,0 +1,16 @@ +{ + "command": "raw capture_screenshot", + "data": { + "code": "TIMEOUT", + "error": "OPERATION_FAILED: Timed out while waiting for Unity response header: deadline has elapsed", + "status": "error" + }, + "errors": [ + { + "code": "TIMEOUT", + "message": "OPERATION_FAILED: Timed out while waiting for Unity response header: deadline has elapsed (code: TIMEOUT)" + } + ], + "success": false, + "warnings": [] +} diff --git a/docs/verification/issue-386/modal-os-fallback.stdout.json b/docs/verification/issue-386/modal-os-fallback.stdout.json new file mode 100644 index 00000000..ae1a2740 --- /dev/null +++ b/docs/verification/issue-386/modal-os-fallback.stdout.json @@ -0,0 +1,17 @@ +{ + "command": "raw capture_screenshot", + "data": { + "captureMode": "game", + "fallback": "os", + "fallbackTool": "powershell", + "fileSize": 637755, + "height": 949, + "message": "Desktop screenshot captured by the OS (Unity Editor did not respond)", + "note": "Unity Editor did not respond (OPERATION_FAILED: Timed out while waiting for Unity response header: deadline has elapsed (code: TIMEOUT)); captured the whole desktop with an OS screenshot instead. The Editor main thread may be blocked by a modal dialog. Pass \"osFallback\": false to get the timeout error instead.", + "path": "\\.cache\\issue-386\\setup-project\\.unity\\capture\\image_os_1791037847148.png", + "width": 1512 + }, + "errors": [], + "success": true, + "warnings": [] +} diff --git a/docs/verification/issue-386/modal-summary.json b/docs/verification/issue-386/modal-summary.json new file mode 100644 index 00000000..adcf338c --- /dev/null +++ b/docs/verification/issue-386/modal-summary.json @@ -0,0 +1,49 @@ +{ + "started_at": "2026-10-03T14:30:44.505484+00:00", + "source_commit": "338f426119b61123567b74028e7e8fe3bd99caa5", + "binary_sha256": "abb04eca3cee68b3260c4701f6a10b2b053c87c1eaef95423117143cf4288eeb", + "cases": { + "modal-os-fallback": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\setup-project", + "--timeout-ms", + "1000", + "raw", + "capture_screenshot", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 2.917, + "success": true + }, + "modal-fallback-disabled": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\setup-project", + "--timeout-ms", + "1000", + "raw", + "capture_screenshot", + "--json", + "{\"osFallback\":false}" + ], + "exit_code": 6, + "elapsed_seconds": 3.212, + "success": false + } + }, + "png": { + "width": 1512, + "height": 949, + "sha256": "08a9cea00d74d0d463b6d345a3755a96066b9ef6bee6857d563e1e91b12cab41" + }, + "finished_at": "2026-10-03T14:30:51.515950+00:00" +} diff --git a/docs/verification/issue-386/operations.json b/docs/verification/issue-386/operations.json new file mode 100644 index 00000000..03d41ef7 --- /dev/null +++ b/docs/verification/issue-386/operations.json @@ -0,0 +1,140 @@ +[ + { + "name": "editor_state", + "tool": "get_editor_state", + "status": "PASS", + "elapsed_seconds": 0.157 + }, + { + "name": "hierarchy", + "tool": "get_hierarchy", + "status": "PASS", + "elapsed_seconds": 0.172 + }, + { + "name": "find_gameobject", + "tool": "find_gameobject", + "status": "PASS", + "elapsed_seconds": 0.345 + }, + { + "name": "transform", + "tool": "get_component_values", + "status": "PASS", + "elapsed_seconds": 0.412 + }, + { + "name": "position", + "tool": "modify_gameobject", + "status": "PASS", + "elapsed_seconds": 0.51 + }, + { + "name": "create_cube", + "tool": "create_gameobject", + "status": "PASS", + "elapsed_seconds": 0.589 + }, + { + "name": "add_component", + "tool": "add_component", + "status": "PASS", + "elapsed_seconds": 0.105 + }, + { + "name": "remove_component", + "tool": "remove_component", + "status": "PASS", + "elapsed_seconds": 0.1 + }, + { + "name": "delete_gameobject", + "tool": "delete_gameobject", + "status": "PASS", + "elapsed_seconds": 0.102 + }, + { + "name": "scene_info", + "tool": "get_scene_info", + "status": "PASS", + "elapsed_seconds": 0.094 + }, + { + "name": "scene_save", + "tool": "save_scene", + "status": "PASS", + "elapsed_seconds": 0.342 + }, + { + "name": "console", + "tool": "read_console", + "status": "PASS", + "elapsed_seconds": 0.126 + }, + { + "name": "screenshot", + "tool": "capture_screenshot", + "status": "PASS", + "elapsed_seconds": 0.32 + }, + { + "name": "material_search", + "tool": "manage_asset_database", + "status": "PASS", + "elapsed_seconds": 0.563 + }, + { + "name": "asset_copy", + "tool": "manage_asset_database", + "status": "PASS", + "elapsed_seconds": 0.119 + }, + { + "name": "asset_move", + "tool": "manage_asset_database", + "status": "PASS", + "elapsed_seconds": 1.08 + }, + { + "name": "asset_delete", + "tool": "manage_asset_database", + "status": "PASS", + "elapsed_seconds": 0.069 + }, + { + "name": "import_settings", + "tool": "manage_asset_import_settings", + "status": "PASS", + "elapsed_seconds": 0.045 + }, + { + "name": "material_modify", + "tool": "modify_material", + "status": "PASS", + "elapsed_seconds": 0.074 + }, + { + "name": "time_settings", + "tool": "get_project_settings", + "status": "PASS", + "elapsed_seconds": 0.042 + }, + { + "name": "read_csharp", + "tool": "read", + "status": "PASS", + "elapsed_seconds": 0.035 + }, + { + "name": "play_until_ready", + "tool": "play_game", + "status": "FAIL", + "error": "{'code': 'OPERATION_FAILED', 'error': 'OPERATION_FAILED: early eof', 'status': 'error'}" + }, + { + "name": "stop_until_ready", + "tool": "stop_game", + "status": "FAIL", + "error": "{'code': 'UNAUTHORIZED', 'error': 'Missing or invalid authentication token', 'id': '1', 'status': 'error'}" + } +] diff --git a/docs/verification/issue-386/profile-audit.json b/docs/verification/issue-386/profile-audit.json new file mode 100644 index 00000000..d2ab8fda --- /dev/null +++ b/docs/verification/issue-386/profile-audit.json @@ -0,0 +1,19 @@ +{ + "path": "%USERPROFILE%/.codeium/windsurf/mcp_config.json", + "created_at": "2026-10-03T15:14:29.659230+00:00", + "modified_at": "2026-10-03T15:14:29.660750+00:00", + "sha256": "29153948358c2c3e6db04ed03afe13bbe1f3eb6b738d8b6dc2bc8978761b4d10", + "top_level_keys": [ + "mcpServers" + ], + "server_names": [ + "unity-cli" + ], + "only_generated_entry": true, + "generated_file_removed": true, + "generated_file_still_absent_after_green": true, + "removed_empty_directories_created_by_test": [ + ".codeium/windsurf", + ".codeium" + ] +} diff --git a/docs/verification/issue-386/red-results.xml b/docs/verification/issue-386/red-results.xml new file mode 100644 index 00000000..a444a614 --- /dev/null +++ b/docs/verification/issue-386/red-results.xml @@ -0,0 +1,40 @@ + +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested + { + "error": "Failed to save scene" +} + Expected: null + But was: "Failed to save scene" +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +Parent directory must exist before creating asset at: Assets/TestScenes/Nested/Generated/TestScene_Nested.unity +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath + Expected: null + But was: "Failed to save scene" +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +Parent directory must exist before creating asset at: Assets/Scenes/TestScene_Auto.unity + { + "error": "Failed to save scene" +} + Expected: null + But was: "Failed to save scene" +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +Parent directory must exist before creating asset at: Assets/TestScenes/Saved/Generated/TestScene_Saved.unity + diff --git a/docs/verification/issue-386/release-version.json b/docs/verification/issue-386/release-version.json new file mode 100644 index 00000000..5321e864 --- /dev/null +++ b/docs/verification/issue-386/release-version.json @@ -0,0 +1,10 @@ +{ + "argv": [ + "\\.cache\\issue-386\\installed-tools\\unity-cli\\win-x64\\unity-cli.exe", + "--version" + ], + "exit_code": 0, + "stdout": "unity-cli 0.18.1\n", + "stderr": "", + "observed_at": "2026-10-03T15:01:21.887453+00:00" +} diff --git a/docs/verification/issue-386/release.json b/docs/verification/issue-386/release.json new file mode 100644 index 00000000..7c897865 --- /dev/null +++ b/docs/verification/issue-386/release.json @@ -0,0 +1,16 @@ +{ + "argv": [ + "gh", + "release", + "view", + "v0.18.1", + "--repo", + "akiojin/unity-cli", + "--json", + "tagName,url,assets" + ], + "exit_code": 0, + "stdout": "{\"assets\":[{\"apiUrl\":\"https://api.github.com/repos/akiojin/unity-cli/releases/assets/606103537\",\"contentType\":\"application/octet-stream\",\"createdAt\":\"2026-10-02T17:18:19Z\",\"digest\":\"sha256:88d78c90a4f1530c1d1fab96d04f4d18ecb4f150ace344ce2ad9218408450c9d\",\"downloadCount\":0,\"id\":\"RA_kwDORR8NH84kIGfx\",\"label\":\"\",\"name\":\"csharp-lsp-linux-arm64\",\"size\":97260271,\"state\":\"uploaded\",\"updatedAt\":\"2026-10-02T17:18:24Z\",\"url\":\"https://github.com/akiojin/unity-cli/releases/download/v0.18.1/csharp-lsp-linux-arm64\"},{\"apiUrl\":\"https://api.github.com/repos/akiojin/unity-cli/releases/assets/606103535\",\"contentType\":\"application/octet-stream\",\"createdAt\":\"2026-10-02T17:18:19Z\",\"digest\":\"sha256:80503f54c025c5f602ba321a2c169f0f85cd8feb9f012324e48d375c269c8ed4\",\"downloadCount\":4,\"id\":\"RA_kwDORR8NH84kIGfv\",\"label\":\"\",\"name\":\"csharp-lsp-linux-x64\",\"size\":89837645,\"state\":\"uploaded\",\"updatedAt\":\"2026-10-02T17:18:24Z\",\"url\":\"https://github.com/akiojin/unity-cli/releases/download/v0.18.1/csharp-lsp-linux-x64\"},{\"apiUrl\":\"https://api.github.com/repos/akiojin/unity-cli/releases/assets/606103528\",\"contentType\":\"application/json\",\"createdAt\":\"2026-10-02T17:18:19Z\",\"digest\":\"sha256:2c91efd0efa8af84b7036d6be385c37cbc8269d79e177f036916f44bd31602ef\",\"downloadCount\":4,\"id\":\"RA_kwDORR8NH84kIGfo\",\"label\":\"\",\"name\":\"csharp-lsp-manifest.json\",\"size\":1191,\"state\":\"uploaded\",\"updatedAt\":\"2026-10-02T17:18:19Z\",\"url\":\"https://github.com/akiojin/unity-cli/releases/download/v0.18.1/csharp-lsp-manifest.json\"},{\"apiUrl\":\"https://api.github.com/repos/akiojin/unity-cli/releases/assets/606103539\",\"contentType\":\"application/octet-stream\",\"createdAt\":\"2026-10-02T17:18:19Z\",\"digest\":\"sha256:c7427a1845e0bc3d96667a63a27331e10bd346067333e58ef94fcaca3053d64b\",\"downloadCount\":0,\"id\":\"RA_kwDORR8NH84kIGfz\",\"label\":\"\",\"name\":\"csharp-lsp-osx-arm64\",\"size\":96438839,\"state\":\"uploaded\",\"updatedAt\":\"2026-10-02T17:18:24Z\",\"url\":\"https://github.com/akiojin/unity-cli/releases/download/v0.18.1/csharp-lsp-osx-arm64\"},{\"apiUrl\":\"https://api.github.com/repos/akiojin/unity-cli/releases/assets/606103540\",\"contentType\":\"application/octet-stream\",\"createdAt\":\"2026-10-02T17:18:19Z\",\"digest\":\"sha256:3a915a97a00560a634bcb4e37ab12fe3df15702fe6b4adc73da56671df8a178b\",\"downloadCount\":0,\"id\":\"RA_kwDORR8NH84kIGf0\",\"label\":\"\",\"name\":\"csharp-lsp-osx-x64\",\"size\":89173351,\"state\":\"uploaded\",\"updatedAt\":\"2026-10-02T17:18:24Z\",\"url\":\"https://github.com/akiojin/unity-cli/releases/download/v0.18.1/csharp-lsp-osx-x64\"},{\"apiUrl\":\"https://api.github.com/repos/akiojin/unity-cli/releases/assets/606103542\",\"contentType\":\"application/octet-stream\",\"createdAt\":\"2026-10-02T17:18:19Z\",\"digest\":\"sha256:255da253cca997a38c2ee4d9daefe1ce843e1ff901c411dbef350b6280291927\",\"downloadCount\":0,\"id\":\"RA_kwDORR8NH84kIGf2\",\"label\":\"\",\"name\":\"csharp-lsp-win-x64\",\"size\":89822243,\"state\":\"uploaded\",\"updatedAt\":\"2026-10-02T17:18:24Z\",\"url\":\"https://github.com/akiojin/unity-cli/releases/download/v0.18.1/csharp-lsp-win-x64\"},{\"apiUrl\":\"https://api.github.com/repos/akiojin/unity-cli/releases/assets/606103536\",\"contentType\":\"application/octet-stream\",\"createdAt\":\"2026-10-02T17:18:19Z\",\"digest\":\"sha256:486597bce974b41bb47c20de96ea87929cb66874ac80a97688fb6647129765a1\",\"downloadCount\":276,\"id\":\"RA_kwDORR8NH84kIGfw\",\"label\":\"\",\"name\":\"SHA256SUMS\",\"size\":1130,\"state\":\"uploaded\",\"updatedAt\":\"2026-10-02T17:18:19Z\",\"url\":\"https://github.com/akiojin/unity-cli/releases/download/v0.18.1/SHA256SUMS\"},{\"apiUrl\":\"https://api.github.com/repos/akiojin/unity-cli/releases/assets/606103544\",\"contentType\":\"application/octet-stream\",\"createdAt\":\"2026-10-02T17:18:19Z\",\"digest\":\"sha256:adcf93e3e75fdb29a7262c84d0a3b91a83d7aeee93bf26b4e0c220a366b22f22\",\"downloadCount\":0,\"id\":\"RA_kwDORR8NH84kIGf4\",\"label\":\"\",\"name\":\"unity-cli-linux-arm64\",\"size\":32675272,\"state\":\"uploaded\",\"updatedAt\":\"2026-10-02T17:18:22Z\",\"url\":\"https://github.com/akiojin/unity-cli/releases/download/v0.18.1/unity-cli-linux-arm64\"},{\"apiUrl\":\"https://api.github.com/repos/akiojin/unity-cli/releases/assets/606103531\",\"contentType\":\"application/octet-stream\",\"createdAt\":\"2026-10-02T17:18:19Z\",\"digest\":\"sha256:f0b12f5e4815e77a7c71098903ff9e1dd86ca350dd59e06f50fa27fd256b0a8e\",\"downloadCount\":19,\"id\":\"RA_kwDORR8NH84kIGfr\",\"label\":\"\",\"name\":\"unity-cli-linux-x64\",\"size\":33825448,\"state\":\"uploaded\",\"updatedAt\":\"2026-10-02T17:18:22Z\",\"url\":\"https://github.com/akiojin/unity-cli/releases/download/v0.18.1/unity-cli-linux-x64\"},{\"apiUrl\":\"https://api.github.com/repos/akiojin/unity-cli/releases/assets/606103541\",\"contentType\":\"application/json\",\"createdAt\":\"2026-10-02T17:18:19Z\",\"digest\":\"sha256:a9a8c7539a2cf3718d778e073dd103e610dcf63e9ab87692fbe851ef1936677b\",\"downloadCount\":449,\"id\":\"RA_kwDORR8NH84kIGf1\",\"label\":\"\",\"name\":\"unity-cli-manifest.json\",\"size\":1186,\"state\":\"uploaded\",\"updatedAt\":\"2026-10-02T17:18:19Z\",\"url\":\"https://github.com/akiojin/unity-cli/releases/download/v0.18.1/unity-cli-manifest.json\"},{\"apiUrl\":\"https://api.github.com/repos/akiojin/unity-cli/releases/assets/606103543\",\"contentType\":\"application/octet-stream\",\"createdAt\":\"2026-10-02T17:18:19Z\",\"digest\":\"sha256:73283bfff946a4363affc6093fabaf5aaaf878075e3147ee26a445d30888ba5e\",\"downloadCount\":10,\"id\":\"RA_kwDORR8NH84kIGf3\",\"label\":\"\",\"name\":\"unity-cli-osx-arm64\",\"size\":27006240,\"state\":\"uploaded\",\"updatedAt\":\"2026-10-02T17:18:21Z\",\"url\":\"https://github.com/akiojin/unity-cli/releases/download/v0.18.1/unity-cli-osx-arm64\"},{\"apiUrl\":\"https://api.github.com/repos/akiojin/unity-cli/releases/assets/606103530\",\"contentType\":\"application/octet-stream\",\"createdAt\":\"2026-10-02T17:18:19Z\",\"digest\":\"sha256:bbd4884cb0e7de60241a6c38255486e86e506221586aec6a8412187426f74500\",\"downloadCount\":0,\"id\":\"RA_kwDORR8NH84kIGfq\",\"label\":\"\",\"name\":\"unity-cli-osx-x64\",\"size\":10443032,\"state\":\"uploaded\",\"updatedAt\":\"2026-10-02T17:18:20Z\",\"url\":\"https://github.com/akiojin/unity-cli/releases/download/v0.18.1/unity-cli-osx-x64\"},{\"apiUrl\":\"https://api.github.com/repos/akiojin/unity-cli/releases/assets/606103533\",\"contentType\":\"application/octet-stream\",\"createdAt\":\"2026-10-02T17:18:19Z\",\"digest\":\"sha256:efcd697b940f78b6457829453888d9c608f19d2fcd331d0005b1ff47a7839357\",\"downloadCount\":142,\"id\":\"RA_kwDORR8NH84kIGft\",\"label\":\"\",\"name\":\"unity-cli-win-x64\",\"size\":33678336,\"state\":\"uploaded\",\"updatedAt\":\"2026-10-02T17:18:22Z\",\"url\":\"https://github.com/akiojin/unity-cli/releases/download/v0.18.1/unity-cli-win-x64\"},{\"apiUrl\":\"https://api.github.com/repos/akiojin/unity-cli/releases/assets/606103534\",\"contentType\":\"application/x-msdos-program\",\"createdAt\":\"2026-10-02T17:18:19Z\",\"digest\":\"sha256:efcd697b940f78b6457829453888d9c608f19d2fcd331d0005b1ff47a7839357\",\"downloadCount\":5,\"id\":\"RA_kwDORR8NH84kIGfu\",\"label\":\"\",\"name\":\"unity-cli-win-x64.exe\",\"size\":33678336,\"state\":\"uploaded\",\"updatedAt\":\"2026-10-02T17:18:22Z\",\"url\":\"https://github.com/akiojin/unity-cli/releases/download/v0.18.1/unity-cli-win-x64.exe\"}],\"tagName\":\"v0.18.1\",\"url\":\"https://github.com/akiojin/unity-cli/releases/tag/v0.18.1\"}\n", + "stderr": "", + "observed_at": "2026-10-03T15:01:21.710037+00:00" +} diff --git a/docs/verification/issue-386/repository-secret-names.json b/docs/verification/issue-386/repository-secret-names.json new file mode 100644 index 00000000..95166442 --- /dev/null +++ b/docs/verification/issue-386/repository-secret-names.json @@ -0,0 +1,13 @@ +{ + "argv": [ + "gh", + "secret", + "list", + "--repo", + "akiojin/unity-cli" + ], + "exit_code": 0, + "stdout": "CARGO_REGISTRY_TOKEN\t2026-03-06T02:37:14Z\nCODECOV_TOKEN\t2026-03-11T02:17:20Z\nHOMEBREW_TAP_TOKEN\t2026-10-02T03:29:54Z\nPERSONAL_ACCESS_TOKEN\t2026-03-03T08:17:23Z\n", + "stderr": "", + "observed_at": "2026-10-03T15:01:21.069791+00:00" +} diff --git a/docs/verification/issue-386/resume/AnimationCurveHandlerTests.xml b/docs/verification/issue-386/resume/AnimationCurveHandlerTests.xml new file mode 100644 index 00000000..6ddafa4a --- /dev/null +++ b/docs/verification/issue-386/resume/AnimationCurveHandlerTests.xml @@ -0,0 +1,522 @@ + +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ChildComponentCurve_AndFilter +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ExistingUnimportedFile_IsNotOverwritten +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("binding") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("path") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("component") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("root") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("duplicate") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("negative") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("mode") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("infinity") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("packages") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidInput_DoesNotCreateAsset("extension") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.InvalidLaterKey_IsAtomicForExistingClip +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("upsert_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.KeyEdits_RecalculateNeighboringLinearTangents("remove_keys") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.MissingRemovalKey_DoesNotPartiallyWrite +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Sprite","UnityEngine.SpriteRenderer") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.NonNumericBinding_IsRejected("m_Enabled","UnityEngine.BoxCollider") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.PlayModePolicy_RejectsEditsAllowsReads +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.ReadOnlyClip_IsRejectedWithoutMutation +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.Set_LinearMidpointAndReimport_PreserveKeysAndTangents +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Constant") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Auto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("ClampedAuto") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.TangentModes_RoundTripAndOmittedUpdatesPreserve("Free") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.AnimationCurveHandlerTests.UpsertRemove_PreserveOtherBindingsEventsAndSettings + diff --git a/docs/verification/issue-386/resume/BakeHandlerTests.xml b/docs/verification/issue-386/resume/BakeHandlerTests.xml new file mode 100644 index 00000000..84d1295b --- /dev/null +++ b/docs/verification/issue-386/resume/BakeHandlerTests.xml @@ -0,0 +1,32 @@ + +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.AdditiveSceneIsRejectedWithoutSwitchingActiveScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.AdditiveSceneIsRejectedWithoutSwitchingActiveScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.ConcurrentBakeIsRejectedBeforeEditorTick +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.ConcurrentBakeIsRejectedBeforeEditorTick +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.DifferentSceneIsRejected +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.DifferentSceneIsRejected +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.DirtySceneIsRejected +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.DirtySceneIsRejected +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.EmptySceneIsRejected("lighting") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.EmptySceneIsRejected("lighting") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.EmptySceneIsRejected("navmesh-legacy") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.EmptySceneIsRejected("navmesh-legacy") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.EmptySceneIsRejected("occlusion") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.EmptySceneIsRejected("occlusion") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.LegacyRejectsSurfaceOwnedNavigationData +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.LegacyRejectsSurfaceOwnedNavigationData +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.MissingTargetIsRejected +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.MissingTargetIsRejected +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.PreviewSceneDoesNotBlockSavedScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.PreviewSceneDoesNotBlockSavedScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.QueuedJobIsRunningAndHasNoArtifacts +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.QueuedJobIsRunningAndHasNoArtifacts +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.SceneChangeFailsAcceptedJobWithoutSuccessArtifacts +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.SceneChangeFailsAcceptedJobWithoutSuccessArtifacts +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.SceneEditedAfterAcceptanceFailsBeforeBaking +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.SceneEditedAfterAcceptanceFailsBeforeBaking +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.SurfaceRequiresExplicitPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.SurfaceRequiresExplicitPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.UnknownJobDoesNotReportSuccess +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.UnknownJobDoesNotReportSuccess + diff --git a/docs/verification/issue-386/resume/GamepadStickInputPlayModeTests.xml b/docs/verification/issue-386/resume/GamepadStickInputPlayModeTests.xml new file mode 100644 index 00000000..295115f1 --- /dev/null +++ b/docs/verification/issue-386/resume/GamepadStickInputPlayModeTests.xml @@ -0,0 +1,98 @@ + +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.LeftStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.GamepadStickInputPlayModeTests.RightStick_ProcessedAxesMatchRequestedValuesInGameUpdate + diff --git a/docs/verification/issue-386/resume/InputActionNotificationTests.xml b/docs/verification/issue-386/resume/InputActionNotificationTests.xml new file mode 100644 index 00000000..07b226bf --- /dev/null +++ b/docs/verification/issue-386/resume/InputActionNotificationTests.xml @@ -0,0 +1,104 @@ + +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverKeyboardMouseAndGamepadPressAndRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverKeyboardMouseAndGamepadPressAndRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverKeyboardMouseAndGamepadPressAndRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverKeyboardMouseAndGamepadPressAndRelease +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverScheduledKeyboardRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverScheduledKeyboardRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverScheduledKeyboardRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverScheduledKeyboardRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverScheduledKeyboardRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverScheduledKeyboardRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverScheduledKeyboardRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverScheduledKeyboardRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverScheduledKeyboardRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverScheduledKeyboardRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverScheduledKeyboardRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverScheduledKeyboardRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverScheduledKeyboardRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverScheduledKeyboardRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverScheduledKeyboardRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverScheduledKeyboardRelease +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: space (Keyboard) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverTouchPhaseChanges +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverTouchPhaseChanges +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverTouchPhaseChanges +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverTouchPhaseChanges +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverTouchPhaseChanges +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverTouchPhaseChanges +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverTouchPhaseChanges +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverTouchPhaseChanges +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverTouchPhaseChanges +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverTouchPhaseChanges +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverTouchPhaseChanges +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverTouchPhaseChanges +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverTouchPhaseChanges +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverTouchPhaseChanges +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverTouchPhaseChanges +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_DeliverTouchPhaseChanges +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_PreserveOtherGamepadControls +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_PreserveOtherGamepadControls +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_PreserveOtherGamepadControls +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_PreserveOtherGamepadControls +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_PreserveOtherGamepadControls +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_PreserveOtherGamepadControls +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_PreserveOtherGamepadControls +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_PreserveOtherGamepadControls +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_PreserveOtherGamepadControls +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_PreserveOtherGamepadControls +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_PreserveOtherGamepadControls +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_PreserveOtherGamepadControls +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_PreserveOtherGamepadControls +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_PreserveOtherGamepadControls +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_PreserveOtherGamepadControls +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionNotificationTests.EditorUpdates_PreserveOtherGamepadControls + diff --git a/docs/verification/issue-386/resume/InputActionsHandlerTests.xml b/docs/verification/issue-386/resume/InputActionsHandlerTests.xml new file mode 100644 index 00000000..c1db46a7 --- /dev/null +++ b/docs/verification/issue-386/resume/InputActionsHandlerTests.xml @@ -0,0 +1,38 @@ + +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType("Button","Button","Button") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType("Button","Button","Button") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType("Button","Button","Button") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType("PassThrough","PassThrough","") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType("PassThrough","PassThrough","") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType("PassThrough","PassThrough","") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType("Value","Value","Vector2") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType("Value","Value","Vector2") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType("Value","Value","Vector2") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType(null,"Button","Button") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType(null,"Button","Button") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType(null,"Button","Button") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType("invalid","Value","") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType("invalid","Value","") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType("invalid","Value","") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType("999","Value","") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType("999","Value","") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.AddInputAction_PreservesActionType("999","Value","") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType("Button","Button","Button") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType("Button","Button","Button") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType("Button","Button","Button") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType("PassThrough","PassThrough","") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType("PassThrough","PassThrough","") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType("PassThrough","PassThrough","") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType("Value","Value","Vector2") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType("Value","Value","Vector2") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType("Value","Value","Vector2") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType(null,"Button","Button") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType(null,"Button","Button") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType(null,"Button","Button") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType("invalid","Value","") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType("invalid","Value","") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType("invalid","Value","") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType("999","Value","") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType("999","Value","") +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.InputActionsHandlerTests.CreateActionMap_PreservesActionType("999","Value","") + diff --git a/docs/verification/issue-386/resume/InputSimulationAutomationPlayModeTests-counter-green.xml b/docs/verification/issue-386/resume/InputSimulationAutomationPlayModeTests-counter-green.xml new file mode 100644 index 00000000..6d8b6821 --- /dev/null +++ b/docs/verification/issue-386/resume/InputSimulationAutomationPlayModeTests-counter-green.xml @@ -0,0 +1,38 @@ + +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][InputSystemHandler] Created virtual keyboard device +[unity-cli-bridge][InputSystemHandler] Simulating key press: A (UnityCliVirtualKeyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: A (UnityCliVirtualKeyboard) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][InputSystemHandler] Created virtual keyboard device +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (UnityCliVirtualKeyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (UnityCliVirtualKeyboard) +[unity-cli-bridge][InputSystemHandler] Simulating text input: "Hi" (UnityCliVirtualKeyboard) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][InputSystemHandler] Created virtual keyboard device +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (UnityCliVirtualKeyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (UnityCliVirtualKeyboard) +targetFrameRate=120, elapsed=1.005047s, frames=100 +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][InputSystemHandler] Created virtual keyboard device +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (UnityCliVirtualKeyboard) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\resume\hot-reload-windows\Project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (UnityCliVirtualKeyboard) +targetFrameRate=30, elapsed=1.004716s, frames=28 +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][InputSystemHandler] Created virtual keyboard device +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (UnityCliVirtualKeyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (UnityCliVirtualKeyboard) +targetFrameRate=60, elapsed=1.011087s, frames=55 +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][InputSystemHandler] Created virtual keyboard device +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (UnityCliVirtualKeyboard) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\resume\hot-reload-windows\Project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (UnityCliVirtualKeyboard) +targetFrameRate=-1, elapsed=1.002694s, frames=2028 +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.StatusCounterParser_HandlesLineEndings("MouseReleases=1\r\n","MouseReleases",1) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.StatusCounterParser_HandlesLineEndings("TouchPresses=2\nTouchReleases=1\n","TouchReleases",1) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.StatusCounterParser_HandlesLineEndings("MouseReleases=1","MouseReleases",1) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.StatusCounterParser_HandlesLineEndings("MouseReleases=1\r\n","TouchReleases",0) + diff --git a/docs/verification/issue-386/resume/InputSimulationAutomationPlayModeTests-counter-red.xml b/docs/verification/issue-386/resume/InputSimulationAutomationPlayModeTests-counter-red.xml new file mode 100644 index 00000000..700b2ce7 --- /dev/null +++ b/docs/verification/issue-386/resume/InputSimulationAutomationPlayModeTests-counter-red.xml @@ -0,0 +1,131 @@ + +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][InputSystemHandler] Created virtual keyboard device +[unity-cli-bridge][InputSystemHandler] Simulating key press: A (UnityCliVirtualKeyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: A (UnityCliVirtualKeyboard) +Timed out waiting for condition. Status: +Ready=True +CaptureCount=602 +TextInput=(empty) +KeyboardPressed=(none) +KeyboardPresses=0 +KeyboardReleases=0 +MousePosition=222.0,111.0 +MouseLeftPressed=False +MousePresses=0 +MouseReleases=0 +MouseScroll=0.0,0.0 +GamepadButtonA=False +GamepadButtonPresses=1 +GamepadButtonReleases=1 +GamepadLeftStick=0.25,0.50 +GamepadLeftTrigger=0.00 +GamepadDpad=0.00,0.00 +TouchPresses=0 +TouchReleases=0 +TouchMaxSimultaneous=0 +TouchLast=none +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\resume\hot-reload-windows\Project\.unity\tests\test-run-state.json (status=running) +Timed out waiting for condition. Status: +Ready=True +CaptureCount=606 +TextInput=Hi +KeyboardPressed=(none) +KeyboardPresses=0 +KeyboardReleases=0 +MousePosition=120.0,140.0 +MouseLeftPressed=False +MousePresses=1 +MouseReleases=1 +MouseScroll=0.0,0.0 +GamepadButtonA=False +GamepadButtonPresses=0 +GamepadButtonReleases=0 +GamepadLeftStick=0.25,0.50 +GamepadLeftTrigger=0.00 +GamepadDpad=0.00,0.00 +TouchPresses=0 +TouchReleases=0 +TouchMaxSimultaneous=0 +TouchLast=none +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][InputSystemHandler] Created virtual keyboard device +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (UnityCliVirtualKeyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (UnityCliVirtualKeyboard) +[unity-cli-bridge][InputSystemHandler] Simulating text input: "Hi" (UnityCliVirtualKeyboard) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][InputSystemHandler] Created virtual keyboard device +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (UnityCliVirtualKeyboard) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\resume\hot-reload-windows\Project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (UnityCliVirtualKeyboard) +targetFrameRate=120, elapsed=1.011509s, frames=98 +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][InputSystemHandler] Created virtual keyboard device +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (UnityCliVirtualKeyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (UnityCliVirtualKeyboard) +targetFrameRate=30, elapsed=1.028968s, frames=29 +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][InputSystemHandler] Created virtual keyboard device +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (UnityCliVirtualKeyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (UnityCliVirtualKeyboard) +targetFrameRate=60, elapsed=1.009028s, frames=55 +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][InputSystemHandler] Created virtual keyboard device +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (UnityCliVirtualKeyboard) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\resume\hot-reload-windows\Project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (UnityCliVirtualKeyboard) +targetFrameRate=-1, elapsed=1.002823s, frames=2181 + Expected: 1 + But was: 0 +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.StatusCounterParser_HandlesLineEndings("MouseReleases=1\r\n","MouseReleases",1) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.StatusCounterParser_HandlesLineEndings("TouchPresses=2\nTouchReleases=1\n","TouchReleases",1) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.StatusCounterParser_HandlesLineEndings("MouseReleases=1","MouseReleases",1) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.StatusCounterParser_HandlesLineEndings("MouseReleases=1\r\n","TouchReleases",0) + diff --git a/docs/verification/issue-386/resume/InputSimulationAutomationPlayModeTests-gui-final.txt b/docs/verification/issue-386/resume/InputSimulationAutomationPlayModeTests-gui-final.txt new file mode 100644 index 00000000..562291bc --- /dev/null +++ b/docs/verification/issue-386/resume/InputSimulationAutomationPlayModeTests-gui-final.txt @@ -0,0 +1,2 @@ +Reusing Editor (pid 28772) +11 tests, 0 failed; report: \.cache\issue-386\resume\InputSimulationAutomationPlayModeTests-gui-final.xml diff --git a/docs/verification/issue-386/resume/InputSimulationAutomationPlayModeTests-gui-final.xml b/docs/verification/issue-386/resume/InputSimulationAutomationPlayModeTests-gui-final.xml new file mode 100644 index 00000000..7acf1787 --- /dev/null +++ b/docs/verification/issue-386/resume/InputSimulationAutomationPlayModeTests-gui-final.xml @@ -0,0 +1,42 @@ + +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][InputSystemHandler] Simulating key press: A (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: A (Keyboard) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating text input: "Hi" (Keyboard) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +targetFrameRate=120, elapsed=1.013509s, frames=84 +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +targetFrameRate=30, elapsed=1.004072s, frames=27 +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +targetFrameRate=60, elapsed=1.007810s, frames=51 +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +targetFrameRate=-1, elapsed=1.002497s, frames=535 +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.StatusCounterParser_HandlesLineEndings("MouseReleases=1\r\n","MouseReleases",1) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.StatusCounterParser_HandlesLineEndings("MouseReleases=1\r\n","MouseReleases",1) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.StatusCounterParser_HandlesLineEndings("TouchPresses=2\nTouchReleases=1\n","TouchReleases",1) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.StatusCounterParser_HandlesLineEndings("TouchPresses=2\nTouchReleases=1\n","TouchReleases",1) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.StatusCounterParser_HandlesLineEndings("MouseReleases=1","MouseReleases",1) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.StatusCounterParser_HandlesLineEndings("MouseReleases=1","MouseReleases",1) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.StatusCounterParser_HandlesLineEndings("MouseReleases=1\r\n","TouchReleases",0) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.StatusCounterParser_HandlesLineEndings("MouseReleases=1\r\n","TouchReleases",0) + diff --git a/docs/verification/issue-386/resume/InputSimulationAutomationPlayModeTests.xml b/docs/verification/issue-386/resume/InputSimulationAutomationPlayModeTests.xml new file mode 100644 index 00000000..f5dcc200 --- /dev/null +++ b/docs/verification/issue-386/resume/InputSimulationAutomationPlayModeTests.xml @@ -0,0 +1,366 @@ + +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.CreateInputSequence_AppliesDelayAndFinalState +[unity-cli-bridge][InputSystemHandler] Simulating key press: A (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: A (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: A (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: A (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: A (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: A (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: A (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: A (Keyboard) +Timed out waiting for condition. Status: +Ready=True +CaptureCount=602 +TextInput=(empty) +KeyboardPressed=(none) +KeyboardPresses=0 +KeyboardReleases=0 +MousePosition=222.0,111.0 +MouseLeftPressed=False +MousePresses=0 +MouseReleases=0 +MouseScroll=0.0,0.0 +GamepadButtonA=False +GamepadButtonPresses=1 +GamepadButtonReleases=1 +GamepadLeftStick=0.25,0.50 +GamepadLeftTrigger=0.00 +GamepadDpad=0.00,0.00 +TouchPresses=3 +TouchReleases=3 +TouchMaxSimultaneous=1 +TouchLast=0:Ended@100.0,200.0 +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.GamepadAndTouchInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +Timed out waiting for condition. Status: +Ready=True +CaptureCount=606 +TextInput=Hi +KeyboardPressed=(none) +KeyboardPresses=0 +KeyboardReleases=0 +MousePosition=120.0,140.0 +MouseLeftPressed=False +MousePresses=1 +MouseReleases=1 +MouseScroll=0.0,0.0 +GamepadButtonA=False +GamepadButtonPresses=0 +GamepadButtonReleases=0 +GamepadLeftStick=0.25,0.50 +GamepadLeftTrigger=0.00 +GamepadDpad=0.00,0.00 +TouchPresses=3 +TouchReleases=3 +TouchMaxSimultaneous=1 +TouchLast=0:Ended@100.0,200.0 +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardAndMouseInput_AreObserved +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating text input: "Hi" (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating text input: "Hi" (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating text input: "Hi" (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating text input: "Hi" (Keyboard) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_120Fps_UsesElapsedTime +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +targetFrameRate=120, elapsed=1.008113s, frames=86 +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_30Fps_UsesElapsedTime +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +targetFrameRate=30, elapsed=1.034271s, frames=28 +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_60Fps_UsesElapsedTime +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +targetFrameRate=60, elapsed=1.021651s, frames=51 +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.InputSimulationAutomationPlayModeTests.KeyboardHoldSeconds_UnlimitedFps_UsesElapsedTime +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key press: Space (Keyboard) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +[unity-cli-bridge][InputSystemHandler] Simulating key release: Space (Keyboard) +targetFrameRate=-1, elapsed=1.003568s, frames=566 + diff --git a/docs/verification/issue-386/resume/README.md b/docs/verification/issue-386/resume/README.md new file mode 100644 index 00000000..177e3f8f --- /dev/null +++ b/docs/verification/issue-386/resume/README.md @@ -0,0 +1,127 @@ +# #386 継続検証の記録 + +2026-10-04 JST。Windows 11 x64 / Unity 6000.4.4f1 / CLI・Bridge 0.18.1。 +成功した独立検証と、Issue 全体の未達条件を区別する。 + +**Overall: FAIL — Issue 全体は未完了、PR 未作成。** + +## 実行した検証 + +| 対象 | 実測 | 証跡 | +| --- | --- | --- | +| Windows native Rust | 610 PASS / 0 FAIL(558 unit +52 integration) | [全件ログ](cargo-all-final.txt)、[全610テスト名](cargo-test-inventory.json)、[コマンド・exit・時刻](final-checks.json) | +| fmt / clippy / skills lint | PASS、23 skills / 0 violations | [fmt](fmt.txt)、[clippy](clippy.txt)、[skills](skills-lint-final.txt) | +| all-features clippy / rustdoc / Markdown | warningsをエラーとして全件成功 | [コマンド・exit・時刻](final-doc-checks.json) | +| Python の PID 生存確認 | Windows4件、Linux3件成功・Windows専用1件skip | [Windows](python-windows.txt)、[Linux](python-linux.txt)、[最終Windows4件](process-liveness-final.txt) | +| 実 Editor の公開23操作 | 23/23、各1回の機能確認 | [操作と結果](staff-final-operations.json)、[条件・バイナリ](staff-final-summary.json) | +| Windows 公式 CLI 比較・プロセス方式 | 作成・階層・evalを両CLIで各100回、前面・最小化の2条件。3 warmup | [前面](official-windows-process-frontmost.json)、[最小化](official-windows-process-background.json)、[公式binary検証](official-windows-binary.json) | +| Windows 公式 CLI 比較・常駐方式 | 全23操作を両CLIで各100回、前面・最小化の2条件。3 warmup、同じunityd / shellを保持 | [前面](official-windows-resident-frontmost.json)、[最小化](official-windows-resident-background.json)、[p50・p95の全表](windows-comparison.md) | +| 実 Editor モーダル / Windows GDI fallback | PNG生成、無効時 TIMEOUT | [結果](modal-summary.json) | +| Prefab | 45 runtime +22 EditMode、失敗0 | [結果](prefab-results.json)、[実行ログ](prefab.txt) | +| Timeline | 40 PASS / 0 FAIL | [実行ログ](timeline.txt) | +| C# eval | 18 PASS / 0 FAIL、1000連続実行 | [実行ログ](eval.txt)。追加assembly4、管理memory増加2,658,304 bytes | +| Test Runner の Domain Reload | 有効2件・無効2件とも結果取得成功、設定復元 | [全テスト・実行条件](domain-reload.json) | +| 実 Hot Reload | Windows x64 / FSR1.8.0、25 PASS / 0 FAIL | [実行ログ](hot-reload-results.txt)、[条件・終了処理](hot-reload-summary.json) | +| InputActions の保存・再起動 | 50 PASS / 0 FAIL、Editor2回起動 | [実行ログ](input-actions-persistence.txt) | +| InputActions の型 / 通知 | 型12件、通知4件とも成功 | [型](InputActionsHandlerTests.xml)、[通知](InputActionNotificationTests.xml) | +| Animation Curves | 数値・reimport等25項目、EditMode26件成功 | [runtime](animation-curves.txt)、[EditMode](AnimationCurveHandlerTests.xml) | +| 動画形式 | mp4 / webm / PNG sequence / 再実行・拒否を含む6項目成功 | [結果](video-summary.json)、[実行ログ](video-formats.txt) | +| C# reference | 実fetch5項目 + ref選択/status/grep/cache4項目成功 | [fetch](reference-fetch-summary.json)、[解決](reference-resolution-summary.json) | +| Bake | 4 backend、101チェック成功。保存・再読込・実NavMesh問い合わせを確認 | [実行ログ](bake-headed-final.txt)、[操作条件](bake-headed-result.json)、[実ファイルSHA256](bake-artifact-metadata.json) | +| Bake / Scene の回帰テスト | 15件 /11件成功 | [Bake](BakeHandlerTests.xml)、[Scene](SceneHandlerTests.xml) | +| Windows Player | 実ビルド、exe / Data / BuildReport一致、headless起動5秒、GUI描画 | [ビルド・起動](windows-player-result.json)、[640×360の描画観測](windows-player-graphical.json)。ゲーム入力は未確認 | +| Gamepad Stick / Touch | 2件 /15件成功。最終GUI再起動後もTouch15件成功、error / skip 0 | [Gamepad](GamepadStickInputPlayModeTests.xml)、[最終Touch](TouchGesturePlayModeTests-gui-final.xml)、[条件・ソースhash](final-gui-results.json) | +| 複合入力・カウンター読取 | Windows headlessと最終GUIの双方で11/11成功。元の7件と改行回帰4件、error / skip 0 | [RED: 11件中3失敗](InputSimulationAutomationPlayModeTests-counter-red.xml)、[headless GREEN](InputSimulationAutomationPlayModeTests-counter-green.xml)、[最終GUI](InputSimulationAutomationPlayModeTests-gui-final.xml)、[条件・ソースhash](final-gui-results.json) | +| Linux X11 | import / scrot / maim、12チェック成功 | [実行ログ](linux-x11-platform.txt) | +| Linux Wayland | GNOME / sway(grim) / KWin(spectacle) の実PNG生成成功 | [GNOME](linux-gnome-fallback-result.json)、[grim](linux-wayland-first-results.json)、[spectacle](linux-wayland-extra-results.json) | +| Linux 実 Unity | 起動exit198、認証未完了 | [匿名化した結果](linux-license.json)。上記captureはsilent TCP fixtureであり実Editorの証明ではない | +| winget初回manifest | validate PASS | [結果](winget-manifest-validate.txt)。公開sourceからのinstall / pingは未実施 | + +## 確認して修正した原因 + +- Git smart HTTP に `Authorization: token` を渡すと有効なGitHub tokenでも失敗した。 + 同じtokenのBasic形式で成功を確認し、HTTP fixtureの回帰テストをRED→GREENにした。 + [RED](reference-auth-red.txt)、[GREEN](reference-auth-green.txt)、[値を含まない実transport検証](reference-auth-probe.json)。 +- Windowsの深いC# referenceキャッシュでcheckoutが`Filename too long`になった。 + Gitの子プロセスだけに`core.longpaths=true`を指定し、設定falseの環境でも実checkoutできる + [RED](reference-longpath-red.txt)→[GREEN](reference-longpath-green.txt)を確認した。 +- batch失敗時に配列から診断を読めず`UNKNOWN_ERROR`になった。 + 最初の失敗項目からmessage/codeを読み、全結果の配列を保持する。 + [RED](batch-message-red.txt)、[GREEN](batch-message-green.txt)。 +- 保存シーン1つでも内部Preview SceneがあるとBakeを拒否していた。 + 対象シーンのPreview判定と通常シーン数を確認するよう修正した。 + [RED](bake-preview-red.xml)、[GREEN](bake-preview-green.xml)。追加ロードした通常シーンの拒否も15件のsuiteで確認した。 +- offlineのMCP / warningテストが実Editorを自動発見していた。 + 期待値のCLIも同じ未接続port1を指定し、実Editor起動中に検証した。 +- Touchの端末除去テストは通常のCLI接続ログを予期しないログと扱っていた。 + loopbackからの接続を示す既知のLogだけを期待値として登録する。 + Warning / Error / Exceptionの検出を保ったまま15件すべて成功した。 + +Bakeのheaded検証では、Unityが生成シーンの外部変更確認を5回表示した。 +自分が起動したEditorのPID、ダイアログ名、生成シーン1つだけのパスを照合し、 +`Ignore`を選択してtracked sceneを維持した。操作履歴を上表の条件JSONに残している。 +UI操作なしの最初の実行はTIMEOUTだった。無人実行での成功とは扱わない。 + +複合入力の初回[7件中2失敗](InputSimulationAutomationPlayModeTests.xml)は、テストがWindowsの +CRLF表示からカウンターを読み取れず0にしたことが原因だった。数値読取の`$`の前に任意の +`\r`を認め、CRLF / LF / 末尾改行なし / キー欠落の4ケースを追加した。 +旧正規表現では新CRLFケースと複合2件が失敗し、修正後は元の入力シナリオを含む11件が成功した。 +現在のソースをコピーしてGUI Editorを再起動した最終実行でも11件成功、error / skip 0を確認した。 +入力runtime、50msのhold、ミリ秒単位のswipe20ms、元のアサーションは変更していない。 +調査用のruntime変更や一時fixtureは製品差分から除外した。 + +## 証跡の帰属と残る条件 + +[ソース・最新Windows CLI・公開Linux CLIのSHA256](source-snapshot.json)を保存した。 +公開Linux CLIのSHA256はRelease 0.18.1の`SHA256SUMS`と一致する。 +先に実行した23操作・Prefab等には、その時点のバイナリSHA256を別のJSONに保持している。 +全結果を同一バイナリの実行と扱わない。 +公開ログは個人パス・ANSI表示と行末の空白を正規化した。元の実行データは`.cache/issue-386/resume`に保持している。 + +[スタッフ範囲の再構成](staff-scope-reconstruction.md)は#243–260 / #390–395からの推論であり、 +未取得の`pm-scratch/staff-report.md`そのものではない。元の全行・印・正のシナリオとの一致は未確認。 +Windowsでの公式CLI比較はプロセス・常駐それぞれの前面・最小化、全4条件で完了した。 +合計10,400の測定値について、各操作100サンプルと全p50・p95の計算を確認した。 +同じUnity6000.4.4f1のプロジェクトにBridge0.18.1とPipeline0.8.0-exp.1を入れ、 +両CLIの応答からプロジェクトとUnityバージョンの一致を確認した。 +背景条件は、Windowsが既存GWTウィンドウの前面化を拒否したため、自分のEditorだけを最小化した。 +macOSの表示したままの背景条件とは異なる。ほかのプロジェクトの正式検証が稼働中のhostであり、 +Windowsの性能予算や過去のbaselineを満たしたという結果ではない。 +[通常の背景へ切り替えられなかった実行](official-windows-comparison-before-minimized.txt)も保存している。 +常駐方式の初回は、公式`find_assets`の文字列`search_in`に配列を渡して失敗した。 +[失敗記録](official-windows-resident-frontmost-search-array-failure.json)を残し、 +導入済みPipelineの実メソッド定義に合わせて文字列を渡すよう修正した。 +[比較スクリプトの15件の回帰テスト](comparison-unit-linux.txt)も成功した。 +[既存macOS証跡と比較表の5件の検証](comparison-historical-linux.txt)も成功し、過去の表と計測値の一致を確認した。 + +Windows用の[計測アダプター](windows-comparison-adapter.py)は、既存スクリプトの操作・検証・交互順序・ +focus変化時の除外を使い、macOSのfocus取得をWindows HWNDへ、POSIXの`select`をreader threadへ置き換えた。 +実行場所は`.cache/issue-386/windows-comparison.py`で、所有するfixtureとTCP listenerのPIDを照合する。 +プロセス測定済みJSONを保持して常駐測定を再開した版を保存しており、各測定JSONのscript SHA256はその実行時の値を維持する。 +前面プロセス測定後に公式`search_in`を修正したため、全条件を同一scriptの実行とは扱わない。 + +正式な`verify.run`は共通host leaseを1500秒待って2回ともdeferred。 +[1回目](canonical-verify.txt)、[2回目](canonical-verify-second.txt)。通常の直接実行とは区別する。 +同一sessionのblocked復旧用deriveはbinary-only Cargoに`--lib`を生成し、 +[実Cargoがno library targets foundで拒否する](derived-lib-error.txt)。 +修正コミット後の[最新derive](derived-plan-final.json)も同じ`--lib`を生成し、 +[実Windows Cargoがexit101で拒否](derived-lib-final.json)した。PMに修復裁定を依頼済み。 + +User Verification Result: pending。Agentの描画観測を人の確認済みとは扱わない。 +最終確認でも[wingetの公開sourceはpackage not found](winget-source-final.txt)、 +[WINGET_TOKENというSecret名は未登録](winget-secret-state.json)だった。Secretの値は参照していない。 +不足するLinux認証・スタッフ原資料・winget公開/Secretの操作経路・正式検証復旧が揃った後、 +元資料と照合して必要なユーザー確認とReady PRへ進む。 + +## ユーザー確認の導線 + +手動起動sessionのため、正式ゲート復旧後に次の確認結果を記録する。現在は未確認である。 +コマンドはリポジトリルートのWindows PowerShellで実行する。 + +1. Build: `cargo build --bin unity-cli`でWindowsバイナリをビルドする。 +2. Launch: `target\debug\unity-cli.exe --port 6487 editor open --project-path .cache\issue-386\staff-project`で用意済みの隔離プロジェクトを開く。 +3. Navigate: `target\debug\unity-cli.exe instances list --output json`で、このプロジェクトを指す実Editorの発見を確認する。 +4. Observe: `target\debug\unity-cli.exe --port 6487 system ping`の成功と、コマンド終了後もEditorが開いていることを確認する。 + +確認項目は、実Editorのプロジェクトが隔離fixtureであること、lockfileからそのEditorを発見できること、 +CLIが終了待ちにならずpingの応答を返すこと。回答を得るまで`confirmed`とは記録しない。 diff --git a/docs/verification/issue-386/resume/SceneHandlerTests.xml b/docs/verification/issue-386/resume/SceneHandlerTests.xml new file mode 100644 index 00000000..d821dc8e --- /dev/null +++ b/docs/verification/issue-386/resume/SceneHandlerTests.xml @@ -0,0 +1,266 @@ + +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldAddToBuildSettings_WhenRequested +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForEmptySceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForExistingScene +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldFailForInvalidSceneName +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldHandleMissingParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldNotLoadScene_WhenLoadSceneIsFalse +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithCustomPath +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.CreateScene_ShouldWorkWithMinimalParameters +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.SceneHandlerTests.SaveScene_ShouldCreateNestedFolders + diff --git a/docs/verification/issue-386/resume/TouchGesturePlayModeTests-fresh.xml b/docs/verification/issue-386/resume/TouchGesturePlayModeTests-fresh.xml new file mode 100644 index 00000000..39eee3b2 --- /dev/null +++ b/docs/verification/issue-386/resume/TouchGesturePlayModeTests-fresh.xml @@ -0,0 +1,29 @@ + +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.DefaultTap_IsObservedAndReleased +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.DistinctSlots_OverlapAndRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.NativeTouchControl_IsVisibleToUpdateProbe +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.RemovedDevice_DoesNotBreakSubsequentGesture +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.RemovingDevice_CancelsOnlyStartedGesture +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.SameSlotGestures_AreQueuedInOrder +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.SparseTouchId_HasOneLogicalStateEntry +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.Swipe_120Fps +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.Swipe_30Fps +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.Swipe_Uncapped +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.Tap_120Fps +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.Tap_30Fps +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.Tap_FixedInputUpdate +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.Tap_Uncapped +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.ZeroDurationSwipe_ExposesStartEndpointAndRelease +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) + diff --git a/docs/verification/issue-386/resume/TouchGesturePlayModeTests-gui-final.txt b/docs/verification/issue-386/resume/TouchGesturePlayModeTests-gui-final.txt new file mode 100644 index 00000000..8c4eb165 --- /dev/null +++ b/docs/verification/issue-386/resume/TouchGesturePlayModeTests-gui-final.txt @@ -0,0 +1,2 @@ +Reusing Editor (pid 28772) +15 tests, 0 failed; report: \.cache\issue-386\resume\TouchGesturePlayModeTests-gui-final.xml diff --git a/docs/verification/issue-386/resume/TouchGesturePlayModeTests-gui-final.xml b/docs/verification/issue-386/resume/TouchGesturePlayModeTests-gui-final.xml new file mode 100644 index 00000000..9cab4d3a --- /dev/null +++ b/docs/verification/issue-386/resume/TouchGesturePlayModeTests-gui-final.xml @@ -0,0 +1,25 @@ + +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.DefaultTap_IsObservedAndReleased +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.DistinctSlots_OverlapAndRelease +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.NativeTouchControl_IsVisibleToUpdateProbe +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.RemovedDevice_DoesNotBreakSubsequentGesture +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.RemovingDevice_CancelsOnlyStartedGesture +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.SameSlotGestures_AreQueuedInOrder +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.SparseTouchId_HasOneLogicalStateEntry +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.Swipe_120Fps +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.Swipe_30Fps +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.Swipe_Uncapped +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.Tap_120Fps +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.Tap_30Fps +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.Tap_FixedInputUpdate +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.Tap_Uncapped +[unity-cli-bridge][TestExecutionHandler] Persisted run state to <workspace>\.cache\issue-386\staff-project\.unity\tests\test-run-state.json (status=running) +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.TouchGesturePlayModeTests.ZeroDurationSwipe_ExposesStartEndpointAndRelease + diff --git a/docs/verification/issue-386/resume/animation-curves.txt b/docs/verification/issue-386/resume/animation-curves.txt new file mode 100644 index 00000000..4819a37a --- /dev/null +++ b/docs/verification/issue-386/resume/animation-curves.txt @@ -0,0 +1,26 @@ +PASS: refresh_assets succeeds +PASS: create_gameobject succeeds +PASS: created root has integer id +PASS: edit_animation_curve succeeds +PASS: get_animation_curves succeeds +PASS: linear keys and slope encode midpoint value 1 +PASS: manage_asset_import_settings succeeds +PASS: get_animation_curves succeeds +PASS: saved keys and interpolation survive reimport +PASS: edit_animation_curve succeeds +PASS: get_animation_curves succeeds +PASS: edit_animation_curve succeeds +PASS: get_animation_curves succeeds +PASS: existing key updated and new key inserted +PASS: edit_animation_curve succeeds +PASS: get_animation_curves succeeds +PASS: requested key removed +PASS: other binding preserved after key updates and removal +PASS: edit_animation_curve succeeds +PASS: get_animation_curves succeeds +PASS: curve removed while other binding preserved +PASS: invalid binding returns clear error +PASS: unsupported clip returns clear error +PASS: get_animation_curves succeeds +PASS: rejected edits preserve the original clip +Animation curves E2E: 25 passed, 0 failed; log: /tmp/unity-cli-animation-curves-20261004-064617-3937.log diff --git a/docs/verification/issue-386/resume/auth-warning-offline-green.txt b/docs/verification/issue-386/resume/auth-warning-offline-green.txt new file mode 100644 index 00000000..22d50653 --- /dev/null +++ b/docs/verification/issue-386/resume/auth-warning-offline-green.txt @@ -0,0 +1,8 @@ + Compiling unity-cli v0.18.1 () + Finished `test` profile [unoptimized + debuginfo] target(s) in 1.30s + Running tests\auth_warning.rs (target\debug\deps\auth_warning-c35c20bac6c142a9.exe) + +running 1 test +test legacy_opt_out_warns_on_stderr_only_for_exact_one ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 13.30s diff --git a/docs/verification/issue-386/resume/bake-artifact-metadata.json b/docs/verification/issue-386/resume/bake-artifact-metadata.json new file mode 100644 index 00000000..73a8d863 --- /dev/null +++ b/docs/verification/issue-386/resume/bake-artifact-metadata.json @@ -0,0 +1,67 @@ +[ + { + "path": "Assets/Scenes/Generated/E2E/Baking/Empty/Empty.unity", + "bytes": 3606, + "sha256": "5c276ea6c3621876c7d993fb924cd28e0fbf4a688c6a1aa3836649bdbbbae0c5" + }, + { + "path": "Assets/Scenes/Generated/E2E/Baking/Legacy/Legacy/NavMesh.asset", + "bytes": 7720, + "sha256": "5595c0b9bdf772fc4672d56969c5fc7d2fbb9a5d35de049dabf8b6f4cafffc53" + }, + { + "path": "Assets/Scenes/Generated/E2E/Baking/Legacy/Legacy.unity", + "bytes": 18413, + "sha256": "3a4568641fd655197c5d45c3862f833ece3905ea964a94d290e89a4d1dffb0d6" + }, + { + "path": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting/LightingData.asset", + "bytes": 18177, + "sha256": "09a2d12600d0e84ab0c33112ec7078fa486734ade2150e7d038be9490d16e36d" + }, + { + "path": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting/Lightmap-0_comp_light.exr", + "bytes": 30656, + "sha256": "a5e264877518b72fce6a4ff6a850aa75233f3d2f35fbcbb6999ce2ee7f0b9652" + }, + { + "path": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting/ReflectionProbe-0.exr", + "bytes": 133557, + "sha256": "2fd8c777d30adf04ea0853a0ad64f45313477598f5610fd8738bc1603777b2a2" + }, + { + "path": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", + "bytes": 18375, + "sha256": "d465ae4dc335123d9274353fe445528e529d4a0fe7bfdfdfe81c0dde3c3b8969" + }, + { + "path": "Assets/Scenes/Generated/E2E/Baking/NoOutput/NoOutput.unity", + "bytes": 20158, + "sha256": "17f43b216c331933e81ed6e7b8e346e76ea312b58d6e42cd37b8e7e0f3f90aab" + }, + { + "path": "Assets/Scenes/Generated/E2E/Baking/Occlusion/Occlusion/OcclusionCullingData.asset", + "bytes": 3297, + "sha256": "1fb2419647675b3e4d40f3a9880b326031f3cf031dfa55f11089ab00ac1529da" + }, + { + "path": "Assets/Scenes/Generated/E2E/Baking/Occlusion/Occlusion.unity", + "bytes": 18427, + "sha256": "706a0bfa069e223625b7831918a2ae88edf5341f572e0a84a4e6e943421fe522" + }, + { + "path": "Assets/Scenes/Generated/E2E/Baking/Surface/NavMesh-1460193e843a4c22b9df488c8680ff44.asset", + "bytes": 7752, + "sha256": "e86eec5ffa392d5a5f86c9563002ffc838eef368b108c673e21dc2f064ae5b03" + }, + { + "path": "Assets/Scenes/Generated/E2E/Baking/Surface/NavMesh-e93b59e165ad4e07a7d2c53838f25092.asset", + "bytes": 7752, + "sha256": "8902cfa09d93a255529a92f8b2246134907d86f8e064c6d3171da456eb967537" + }, + { + "path": "Assets/Scenes/Generated/E2E/Baking/Surface/Surface.unity", + "bytes": 20246, + "sha256": "c35c9f2f3ca249d1dc8051bef48e5feb80e63ba3e4fbf1dc454bdb58e4edbe78" + } +] \ No newline at end of file diff --git a/docs/verification/issue-386/resume/bake-fixed-final.txt b/docs/verification/issue-386/resume/bake-fixed-final.txt new file mode 100644 index 00000000..ce935728 --- /dev/null +++ b/docs/verification/issue-386/resume/bake-fixed-final.txt @@ -0,0 +1,35 @@ +get_editor_info {"assetsPath": "/.cache/issue-386/staff-project/Assets", "codeIndexRoot": "/.cache/issue-386/staff-project/.unity/cache/code-index", "packagesPath": "/.cache/issue-386/staff-project/Packages", "projectRoot": "/.cache/issue-386/staff-project", "unity": {"platform": "WindowsEditor", "productName": "staff-project", "unityVersion": "6000.4.4f1"}} +PASS get_scene_bake_status returns a genuine error +PASS get_scene_bake_status rejects with JOB_NOT_FOUND: {"command":"raw get_scene_bake_status","data":{"code":"JOB_NOT_FOUND","error":"No bake job exists for this jobId in this Editor session.","reason":"No bake job exists for this jobId in this Editor session.","status":"error","unityVersion":"6000.4.4f1"},"errors":[{"code":"JOB_NOT_FOUND","message":"No bake job exists for this jobId in this Editor session. (code: JOB_NOT_FOUND)"}],"success":false,"warnings":[]} + +execute_menu_item {"executed": true, "executionTime": 460, "menuExists": true, "menuPath": "Tools/Unity CLI/Baking/Prepare Lighting", "message": "Menu item executed successfully", "success": true} +PASS Prepare Lighting +PASS start_scene_bake returns a genuine error +PASS start_scene_bake rejects with SCENE_MISMATCH: {"command":"raw start_scene_bake","data":{"code":"SCENE_MISMATCH","error":"scenePath must identify the saved active scene under Assets/.","reason":"scenePath must identify the saved active scene under Assets/.","status":"error","unityVersion":"6000.4.4f1"},"errors":[{"code":"SCENE_MISMATCH","message":"scenePath must identify the saved active scene under Assets/. (code: SCENE_MISMATCH)"}],"success":false,"warnings":[]} + +start_scene_bake {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "76215e87e1564dd3b2f947467c9870b0", "phase": "queued", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS lighting starts tracked asynchronous job +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "76215e87e1564dd3b2f947467c9870b0", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "76215e87e1564dd3b2f947467c9870b0", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "76215e87e1564dd3b2f947467c9870b0", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "76215e87e1564dd3b2f947467c9870b0", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "76215e87e1564dd3b2f947467c9870b0", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "76215e87e1564dd3b2f947467c9870b0", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "76215e87e1564dd3b2f947467c9870b0", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "76215e87e1564dd3b2f947467c9870b0", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "76215e87e1564dd3b2f947467c9870b0", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "76215e87e1564dd3b2f947467c9870b0", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "76215e87e1564dd3b2f947467c9870b0", "phase": "finalizing", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +FAIL TimeoutExpired(['\\target\\debug\\unity-cli.exe', 'raw', 'get_scene_bake_status', '--json', '{"jobId": "76215e87e1564dd3b2f947467c9870b0"}', '--host', '127.0.0.1', '--port', '6487', '--timeout-ms', '120000', '--output', 'json'], 150) +Baking E2E: passed=17 failed=1 diff --git a/docs/verification/issue-386/resume/bake-fresh-0.txt b/docs/verification/issue-386/resume/bake-fresh-0.txt new file mode 100644 index 00000000..dd85b91b --- /dev/null +++ b/docs/verification/issue-386/resume/bake-fresh-0.txt @@ -0,0 +1,11 @@ +get_editor_info {"assetsPath": "/.cache/issue-386/staff-project/Assets", "codeIndexRoot": "/.cache/issue-386/staff-project/.unity/cache/code-index", "packagesPath": "/.cache/issue-386/staff-project/Packages", "projectRoot": "/.cache/issue-386/staff-project", "unity": {"platform": "WindowsEditor", "productName": "staff-project", "unityVersion": "6000.4.4f1"}} +PASS get_scene_bake_status returns a genuine error +PASS get_scene_bake_status rejects with JOB_NOT_FOUND: {"command":"raw get_scene_bake_status","data":{"code":"JOB_NOT_FOUND","error":"No bake job exists for this jobId in this Editor session.","reason":"No bake job exists for this jobId in this Editor session.","status":"error","unityVersion":"6000.4.4f1"},"errors":[{"code":"JOB_NOT_FOUND","message":"No bake job exists for this jobId in this Editor session. (code: JOB_NOT_FOUND)"}],"success":false,"warnings":[]} + +execute_menu_item {"executed": true, "executionTime": 595, "menuExists": true, "menuPath": "Tools/Unity CLI/Baking/Prepare Lighting", "message": "Menu item executed successfully", "success": true} +PASS Prepare Lighting +PASS start_scene_bake returns a genuine error +PASS start_scene_bake rejects with SCENE_MISMATCH: {"command":"raw start_scene_bake","data":{"code":"SCENE_MISMATCH","error":"scenePath must identify the saved active scene under Assets/.","reason":"scenePath must identify the saved active scene under Assets/.","status":"error","unityVersion":"6000.4.4f1"},"errors":[{"code":"SCENE_MISMATCH","message":"scenePath must identify the saved active scene under Assets/. (code: SCENE_MISMATCH)"}],"success":false,"warnings":[]} + +FAIL AssertionError(('start_scene_bake', '{"command":"raw start_scene_bake","data":{"code":"MULTIPLE_SCENES","error":"Load only the target scene before baking.","reason":"Load only the target scene before baking.","status":"error","unityVersion":"6000.4.4f1"},"errors":[{"code":"MULTIPLE_SCENES","message":"Load only the target scene before baking. (code: MULTIPLE_SCENES)"}],"success":false,"warnings":[]}\n')) +Baking E2E: passed=5 failed=1 diff --git a/docs/verification/issue-386/resume/bake-headed-final.txt b/docs/verification/issue-386/resume/bake-headed-final.txt new file mode 100644 index 00000000..0118bd75 --- /dev/null +++ b/docs/verification/issue-386/resume/bake-headed-final.txt @@ -0,0 +1,164 @@ +get_editor_info {"assetsPath": "/.cache/issue-386/staff-project/Assets", "codeIndexRoot": "/.cache/issue-386/staff-project/.unity/cache/code-index", "packagesPath": "/.cache/issue-386/staff-project/Packages", "projectRoot": "/.cache/issue-386/staff-project", "unity": {"platform": "WindowsEditor", "productName": "staff-project", "unityVersion": "6000.4.4f1"}} +PASS get_scene_bake_status returns a genuine error +PASS get_scene_bake_status rejects with JOB_NOT_FOUND: {"command":"raw get_scene_bake_status","data":{"code":"JOB_NOT_FOUND","error":"No bake job exists for this jobId in this Editor session.","reason":"No bake job exists for this jobId in this Editor session.","status":"error","unityVersion":"6000.4.4f1"},"errors":[{"code":"JOB_NOT_FOUND","message":"No bake job exists for this jobId in this Editor session. (code: JOB_NOT_FOUND)"}],"success":false,"warnings":[]} + +execute_menu_item {"executed": true, "executionTime": 400, "menuExists": true, "menuPath": "Tools/Unity CLI/Baking/Prepare Lighting", "message": "Menu item executed successfully", "success": true} +PASS Prepare Lighting +PASS start_scene_bake returns a genuine error +PASS start_scene_bake rejects with SCENE_MISMATCH: {"command":"raw start_scene_bake","data":{"code":"SCENE_MISMATCH","error":"scenePath must identify the saved active scene under Assets/.","reason":"scenePath must identify the saved active scene under Assets/.","status":"error","unityVersion":"6000.4.4f1"},"errors":[{"code":"SCENE_MISMATCH","message":"scenePath must identify the saved active scene under Assets/. (code: SCENE_MISMATCH)"}],"success":false,"warnings":[]} + +start_scene_bake {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "3749cee9acaf46a1a1eba2fc20402ae1", "phase": "queued", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS lighting starts tracked asynchronous job +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "3749cee9acaf46a1a1eba2fc20402ae1", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "3749cee9acaf46a1a1eba2fc20402ae1", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "3749cee9acaf46a1a1eba2fc20402ae1", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "3749cee9acaf46a1a1eba2fc20402ae1", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "3749cee9acaf46a1a1eba2fc20402ae1", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "3749cee9acaf46a1a1eba2fc20402ae1", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "3749cee9acaf46a1a1eba2fc20402ae1", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "3749cee9acaf46a1a1eba2fc20402ae1", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "3749cee9acaf46a1a1eba2fc20402ae1", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "lighting", "code": "BAKE_STARTED", "jobId": "3749cee9acaf46a1a1eba2fc20402ae1", "phase": "finalizing", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": ["Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting/LightingData.asset", "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting/Lightmap-0_comp_light.exr", "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting/Lightmap-0_comp_dir.png"], "backend": "lighting", "code": "BAKE_SUCCEEDED", "jobId": "3749cee9acaf46a1a1eba2fc20402ae1", "phase": "complete", "reason": "Bake artifacts and saved scene references verified.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "succeeded", "unityVersion": "6000.4.4f1", "verification": {"generatedThisRun": true, "navigationQuery": null, "passed": true, "persisted": true, "sceneReferenced": true}} +PASS stable job identity +PASS lighting genuine success: {'artifacts': ['Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting/LightingData.asset', 'Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting/Lightmap-0_comp_light.exr', 'Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting/Lightmap-0_comp_dir.png'], 'backend': 'lighting', 'code': 'BAKE_SUCCEEDED', 'jobId': '3749cee9acaf46a1a1eba2fc20402ae1', 'phase': 'complete', 'reason': 'Bake artifacts and saved scene references verified.', 'scenePath': 'Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity', 'status': 'succeeded', 'unityVersion': '6000.4.4f1', 'verification': {'generatedThisRun': True, 'navigationQuery': None, 'passed': True, 'persisted': True, 'sceneReferenced': True}} +PASS lighting reports version, backend and phase +PASS lighting reports nonempty artifact paths +PASS lighting artifact exists: Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting/LightingData.asset +PASS lighting artifact exists: Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting/Lightmap-0_comp_light.exr +PASS lighting artifact exists: Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting/Lightmap-0_comp_dir.png +execute_menu_item {"executed": true, "executionTime": 565, "menuExists": true, "menuPath": "Tools/Unity CLI/Baking/Validate Lighting", "message": "Menu item executed successfully", "success": true} +PASS Validate Lighting +PASS lighting persisted reload validation: {'target': 'Lighting', 'unityVersion': '6000.4.4f1', 'passed': True, 'error': '', 'lightmapCount': 1, 'pathCorners': 0, 'persistedAsset': 'Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting/LightingData.asset'} +PASS fresh validation evidence belongs to lighting +EVIDENCE {"target": "Lighting", "unityVersion": "6000.4.4f1", "passed": true, "error": "", "lightmapCount": 1, "pathCorners": 0, "persistedAsset": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting/LightingData.asset"} +get_scene_bake_status {"artifacts": ["Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting/LightingData.asset", "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting/Lightmap-0_comp_light.exr", "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting/Lightmap-0_comp_dir.png"], "backend": "lighting", "code": "BAKE_SUCCEEDED", "jobId": "3749cee9acaf46a1a1eba2fc20402ae1", "phase": "complete", "reason": "Bake artifacts and saved scene references verified.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", "status": "succeeded", "unityVersion": "6000.4.4f1", "verification": {"generatedThisRun": true, "navigationQuery": null, "passed": true, "persisted": true, "sceneReferenced": true}} +PASS lighting terminal result remains queryable after scene reload +execute_menu_item {"executed": true, "executionTime": 346, "menuExists": true, "menuPath": "Tools/Unity CLI/Baking/Prepare Legacy", "message": "Menu item executed successfully", "success": true} +PASS Prepare Legacy +PASS start_scene_bake returns a genuine error +PASS start_scene_bake rejects with SCENE_MISMATCH: {"command":"raw start_scene_bake","data":{"code":"SCENE_MISMATCH","error":"scenePath must identify the saved active scene under Assets/.","reason":"scenePath must identify the saved active scene under Assets/.","status":"error","unityVersion":"6000.4.4f1"},"errors":[{"code":"SCENE_MISMATCH","message":"scenePath must identify the saved active scene under Assets/. (code: SCENE_MISMATCH)"}],"success":false,"warnings":[]} + +start_scene_bake {"artifacts": [], "backend": "navmesh-legacy", "code": "BAKE_STARTED", "jobId": "1ff5ce13e5d249b3bff5a0b1a7750164", "phase": "queued", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Legacy/Legacy.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS navmesh-legacy starts tracked asynchronous job +get_scene_bake_status {"artifacts": [], "backend": "navmesh-legacy", "code": "BAKE_STARTED", "jobId": "1ff5ce13e5d249b3bff5a0b1a7750164", "phase": "baking", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Legacy/Legacy.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": ["Assets/Scenes/Generated/E2E/Baking/Legacy/Legacy/NavMesh.asset"], "backend": "navmesh-legacy", "code": "BAKE_SUCCEEDED", "jobId": "1ff5ce13e5d249b3bff5a0b1a7750164", "phase": "complete", "reason": "Bake artifacts and saved scene references verified.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Legacy/Legacy.unity", "status": "succeeded", "unityVersion": "6000.4.4f1", "verification": {"generatedThisRun": true, "navigationQuery": true, "passed": true, "persisted": true, "sceneReferenced": true}} +PASS stable job identity +PASS navmesh-legacy genuine success: {'artifacts': ['Assets/Scenes/Generated/E2E/Baking/Legacy/Legacy/NavMesh.asset'], 'backend': 'navmesh-legacy', 'code': 'BAKE_SUCCEEDED', 'jobId': '1ff5ce13e5d249b3bff5a0b1a7750164', 'phase': 'complete', 'reason': 'Bake artifacts and saved scene references verified.', 'scenePath': 'Assets/Scenes/Generated/E2E/Baking/Legacy/Legacy.unity', 'status': 'succeeded', 'unityVersion': '6000.4.4f1', 'verification': {'generatedThisRun': True, 'navigationQuery': True, 'passed': True, 'persisted': True, 'sceneReferenced': True}} +PASS navmesh-legacy reports version, backend and phase +PASS navmesh-legacy reports nonempty artifact paths +PASS navmesh-legacy artifact exists: Assets/Scenes/Generated/E2E/Baking/Legacy/Legacy/NavMesh.asset +execute_menu_item {"executed": true, "executionTime": 579, "menuExists": true, "menuPath": "Tools/Unity CLI/Baking/Validate Legacy", "message": "Menu item executed successfully", "success": true} +PASS Validate Legacy +PASS navmesh-legacy persisted reload validation: {'target': 'Legacy', 'unityVersion': '6000.4.4f1', 'passed': True, 'error': '', 'lightmapCount': 0, 'pathCorners': 2, 'persistedAsset': 'Assets/Scenes/Generated/E2E/Baking/Legacy/Legacy/NavMesh.asset'} +PASS fresh validation evidence belongs to navmesh-legacy +EVIDENCE {"target": "Legacy", "unityVersion": "6000.4.4f1", "passed": true, "error": "", "lightmapCount": 0, "pathCorners": 2, "persistedAsset": "Assets/Scenes/Generated/E2E/Baking/Legacy/Legacy/NavMesh.asset"} +get_scene_bake_status {"artifacts": ["Assets/Scenes/Generated/E2E/Baking/Legacy/Legacy/NavMesh.asset"], "backend": "navmesh-legacy", "code": "BAKE_SUCCEEDED", "jobId": "1ff5ce13e5d249b3bff5a0b1a7750164", "phase": "complete", "reason": "Bake artifacts and saved scene references verified.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Legacy/Legacy.unity", "status": "succeeded", "unityVersion": "6000.4.4f1", "verification": {"generatedThisRun": true, "navigationQuery": true, "passed": true, "persisted": true, "sceneReferenced": true}} +PASS navmesh-legacy terminal result remains queryable after scene reload +execute_menu_item {"executed": true, "executionTime": 325, "menuExists": true, "menuPath": "Tools/Unity CLI/Baking/Prepare Surface", "message": "Menu item executed successfully", "success": true} +PASS Prepare Surface +PASS start_scene_bake returns a genuine error +PASS start_scene_bake rejects with surfacePath: {"command":"raw start_scene_bake","data":null,"errors":[{"code":"INVALID_ARGUMENT","message":"INVALID_ARGUMENT: Invalid parameters for tool `start_scene_bake`: $ must satisfy exactly one schema variant (matched 0); details: $.surfacePath is required"}],"success":false,"warnings":[]} + +PASS start_scene_bake returns a genuine error +PASS start_scene_bake rejects with SURFACE_NOT_FOUND: {"command":"raw start_scene_bake","data":{"code":"SURFACE_NOT_FOUND","error":"surfacePath must identify exactly one NavMeshSurface in the target scene.","reason":"surfacePath must identify exactly one NavMeshSurface in the target scene.","status":"error","unityVersion":"6000.4.4f1"},"errors":[{"code":"SURFACE_NOT_FOUND","message":"surfacePath must identify exactly one NavMeshSurface in the target scene. (code: SURFACE_NOT_FOUND)"}],"success":false,"warnings":[]} + +PASS start_scene_bake returns a genuine error +PASS start_scene_bake rejects with SCENE_MISMATCH: {"command":"raw start_scene_bake","data":{"code":"SCENE_MISMATCH","error":"scenePath must identify the saved active scene under Assets/.","reason":"scenePath must identify the saved active scene under Assets/.","status":"error","unityVersion":"6000.4.4f1"},"errors":[{"code":"SCENE_MISMATCH","message":"scenePath must identify the saved active scene under Assets/. (code: SCENE_MISMATCH)"}],"success":false,"warnings":[]} + +start_scene_bake {"artifacts": [], "backend": "navmesh-surface", "code": "BAKE_STARTED", "jobId": "1460193e843a4c22b9df488c8680ff44", "phase": "queued", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Surface/Surface.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS navmesh-surface starts tracked asynchronous job +get_scene_bake_status {"artifacts": [], "backend": "navmesh-surface", "code": "BAKE_STARTED", "jobId": "1460193e843a4c22b9df488c8680ff44", "phase": "finalizing", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Surface/Surface.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": ["Assets/Scenes/Generated/E2E/Baking/Surface/NavMesh-1460193e843a4c22b9df488c8680ff44.asset"], "backend": "navmesh-surface", "code": "BAKE_SUCCEEDED", "jobId": "1460193e843a4c22b9df488c8680ff44", "phase": "complete", "reason": "Bake artifacts and saved scene references verified.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Surface/Surface.unity", "status": "succeeded", "unityVersion": "6000.4.4f1", "verification": {"generatedThisRun": true, "navigationQuery": true, "passed": true, "persisted": true, "sceneReferenced": true}} +PASS stable job identity +PASS navmesh-surface genuine success: {'artifacts': ['Assets/Scenes/Generated/E2E/Baking/Surface/NavMesh-1460193e843a4c22b9df488c8680ff44.asset'], 'backend': 'navmesh-surface', 'code': 'BAKE_SUCCEEDED', 'jobId': '1460193e843a4c22b9df488c8680ff44', 'phase': 'complete', 'reason': 'Bake artifacts and saved scene references verified.', 'scenePath': 'Assets/Scenes/Generated/E2E/Baking/Surface/Surface.unity', 'status': 'succeeded', 'unityVersion': '6000.4.4f1', 'verification': {'generatedThisRun': True, 'navigationQuery': True, 'passed': True, 'persisted': True, 'sceneReferenced': True}} +PASS navmesh-surface reports version, backend and phase +PASS navmesh-surface reports nonempty artifact paths +PASS navmesh-surface artifact exists: Assets/Scenes/Generated/E2E/Baking/Surface/NavMesh-1460193e843a4c22b9df488c8680ff44.asset +execute_menu_item {"executed": true, "executionTime": 622, "menuExists": true, "menuPath": "Tools/Unity CLI/Baking/Validate Surface", "message": "Menu item executed successfully", "success": true} +PASS Validate Surface +PASS navmesh-surface persisted reload validation: {'target': 'Surface', 'unityVersion': '6000.4.4f1', 'passed': True, 'error': '', 'lightmapCount': 0, 'pathCorners': 2, 'persistedAsset': 'Assets/Scenes/Generated/E2E/Baking/Surface/NavMesh-1460193e843a4c22b9df488c8680ff44.asset'} +PASS fresh validation evidence belongs to navmesh-surface +EVIDENCE {"target": "Surface", "unityVersion": "6000.4.4f1", "passed": true, "error": "", "lightmapCount": 0, "pathCorners": 2, "persistedAsset": "Assets/Scenes/Generated/E2E/Baking/Surface/NavMesh-1460193e843a4c22b9df488c8680ff44.asset"} +get_scene_bake_status {"artifacts": ["Assets/Scenes/Generated/E2E/Baking/Surface/NavMesh-1460193e843a4c22b9df488c8680ff44.asset"], "backend": "navmesh-surface", "code": "BAKE_SUCCEEDED", "jobId": "1460193e843a4c22b9df488c8680ff44", "phase": "complete", "reason": "Bake artifacts and saved scene references verified.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Surface/Surface.unity", "status": "succeeded", "unityVersion": "6000.4.4f1", "verification": {"generatedThisRun": true, "navigationQuery": true, "passed": true, "persisted": true, "sceneReferenced": true}} +PASS navmesh-surface terminal result remains queryable after scene reload +start_scene_bake {"artifacts": [], "backend": "navmesh-surface", "code": "BAKE_STARTED", "jobId": "e93b59e165ad4e07a7d2c53838f25092", "phase": "queued", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Surface/Surface.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS rebake has an independent job identity +get_scene_bake_status {"artifacts": [], "backend": "navmesh-surface", "code": "BAKE_STARTED", "jobId": "e93b59e165ad4e07a7d2c53838f25092", "phase": "finalizing", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Surface/Surface.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": ["Assets/Scenes/Generated/E2E/Baking/Surface/NavMesh-e93b59e165ad4e07a7d2c53838f25092.asset"], "backend": "navmesh-surface", "code": "BAKE_SUCCEEDED", "jobId": "e93b59e165ad4e07a7d2c53838f25092", "phase": "complete", "reason": "Bake artifacts and saved scene references verified.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Surface/Surface.unity", "status": "succeeded", "unityVersion": "6000.4.4f1", "verification": {"generatedThisRun": true, "navigationQuery": true, "passed": true, "persisted": true, "sceneReferenced": true}} +PASS stable job identity +PASS same-scene rebake succeeds +PASS rebake writes fresh artifacts +execute_menu_item {"executed": true, "executionTime": 527, "menuExists": true, "menuPath": "Tools/Unity CLI/Baking/Validate Surface", "message": "Menu item executed successfully", "success": true} +PASS Validate Surface +PASS rebake persists usable NavMesh +execute_menu_item {"executed": true, "executionTime": 143, "menuExists": true, "menuPath": "Tools/Unity CLI/Baking/Exclude Surface Geometry", "message": "Menu item executed successfully", "success": true} +PASS Exclude Surface Geometry +start_scene_bake {"artifacts": [], "backend": "navmesh-surface", "code": "BAKE_STARTED", "jobId": "633a415774ed4665b614afb8f1f76942", "phase": "queued", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Surface/Surface.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +get_scene_bake_status {"artifacts": [], "backend": "navmesh-surface", "code": "BAKE_STARTED", "jobId": "633a415774ed4665b614afb8f1f76942", "phase": "finalizing", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Surface/Surface.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "navmesh-surface", "code": "ARTIFACT_VERIFICATION_FAILED", "jobId": "633a415774ed4665b614afb8f1f76942", "phase": "failed", "reason": "Generated NavMesh cannot answer a complete path query.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Surface/Surface.unity", "status": "failed", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +PASS empty rebake cannot reuse old NavMesh as success +execute_menu_item {"executed": true, "executionTime": 545, "menuExists": true, "menuPath": "Tools/Unity CLI/Baking/Validate Surface", "message": "Menu item executed successfully", "success": true} +PASS Validate Surface +PASS failed rebake preserves prior usable Surface data and scene assignment +execute_menu_item {"executed": true, "executionTime": 364, "menuExists": true, "menuPath": "Tools/Unity CLI/Baking/Prepare Occlusion", "message": "Menu item executed successfully", "success": true} +PASS Prepare Occlusion +PASS start_scene_bake returns a genuine error +PASS start_scene_bake rejects with SCENE_MISMATCH: {"command":"raw start_scene_bake","data":{"code":"SCENE_MISMATCH","error":"scenePath must identify the saved active scene under Assets/.","reason":"scenePath must identify the saved active scene under Assets/.","status":"error","unityVersion":"6000.4.4f1"},"errors":[{"code":"SCENE_MISMATCH","message":"scenePath must identify the saved active scene under Assets/. (code: SCENE_MISMATCH)"}],"success":false,"warnings":[]} + +start_scene_bake {"artifacts": [], "backend": "occlusion", "code": "BAKE_STARTED", "jobId": "5803ae1102d54f75a7bfaed2fcd834a3", "phase": "queued", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Occlusion/Occlusion.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS occlusion starts tracked asynchronous job +get_scene_bake_status {"artifacts": [], "backend": "occlusion", "code": "BAKE_STARTED", "jobId": "5803ae1102d54f75a7bfaed2fcd834a3", "phase": "finalizing", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Occlusion/Occlusion.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": ["Assets/Scenes/Generated/E2E/Baking/Occlusion/Occlusion/OcclusionCullingData.asset"], "backend": "occlusion", "code": "BAKE_SUCCEEDED", "jobId": "5803ae1102d54f75a7bfaed2fcd834a3", "phase": "complete", "reason": "Bake artifacts and saved scene references verified.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Occlusion/Occlusion.unity", "status": "succeeded", "unityVersion": "6000.4.4f1", "verification": {"generatedThisRun": true, "navigationQuery": null, "passed": true, "persisted": true, "sceneReferenced": true}} +PASS stable job identity +PASS occlusion genuine success: {'artifacts': ['Assets/Scenes/Generated/E2E/Baking/Occlusion/Occlusion/OcclusionCullingData.asset'], 'backend': 'occlusion', 'code': 'BAKE_SUCCEEDED', 'jobId': '5803ae1102d54f75a7bfaed2fcd834a3', 'phase': 'complete', 'reason': 'Bake artifacts and saved scene references verified.', 'scenePath': 'Assets/Scenes/Generated/E2E/Baking/Occlusion/Occlusion.unity', 'status': 'succeeded', 'unityVersion': '6000.4.4f1', 'verification': {'generatedThisRun': True, 'navigationQuery': None, 'passed': True, 'persisted': True, 'sceneReferenced': True}} +PASS occlusion reports version, backend and phase +PASS occlusion reports nonempty artifact paths +PASS occlusion artifact exists: Assets/Scenes/Generated/E2E/Baking/Occlusion/Occlusion/OcclusionCullingData.asset +execute_menu_item {"executed": true, "executionTime": 600, "menuExists": true, "menuPath": "Tools/Unity CLI/Baking/Validate Occlusion", "message": "Menu item executed successfully", "success": true} +PASS Validate Occlusion +PASS occlusion persisted reload validation: {'target': 'Occlusion', 'unityVersion': '6000.4.4f1', 'passed': True, 'error': '', 'lightmapCount': 0, 'pathCorners': 0, 'persistedAsset': 'Assets/Scenes/Generated/E2E/Baking/Occlusion/Occlusion/OcclusionCullingData.asset'} +PASS fresh validation evidence belongs to occlusion +EVIDENCE {"target": "Occlusion", "unityVersion": "6000.4.4f1", "passed": true, "error": "", "lightmapCount": 0, "pathCorners": 0, "persistedAsset": "Assets/Scenes/Generated/E2E/Baking/Occlusion/Occlusion/OcclusionCullingData.asset"} +get_scene_bake_status {"artifacts": ["Assets/Scenes/Generated/E2E/Baking/Occlusion/Occlusion/OcclusionCullingData.asset"], "backend": "occlusion", "code": "BAKE_SUCCEEDED", "jobId": "5803ae1102d54f75a7bfaed2fcd834a3", "phase": "complete", "reason": "Bake artifacts and saved scene references verified.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/Occlusion/Occlusion.unity", "status": "succeeded", "unityVersion": "6000.4.4f1", "verification": {"generatedThisRun": true, "navigationQuery": null, "passed": true, "persisted": true, "sceneReferenced": true}} +PASS occlusion terminal result remains queryable after scene reload +execute_menu_item {"executed": true, "executionTime": 433, "menuExists": true, "menuPath": "Tools/Unity CLI/Baking/Prepare NoOutput", "message": "Menu item executed successfully", "success": true} +PASS Prepare NoOutput +start_scene_bake {"artifacts": [], "backend": "navmesh-surface", "code": "BAKE_STARTED", "jobId": "b3bc45b27e8b470ebbc5a39cc517ff2e", "phase": "queued", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/NoOutput/NoOutput.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +get_scene_bake_status {"artifacts": [], "backend": "navmesh-surface", "code": "BAKE_STARTED", "jobId": "b3bc45b27e8b470ebbc5a39cc517ff2e", "phase": "finalizing", "reason": "Bake accepted; poll get_scene_bake_status for verified completion.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/NoOutput/NoOutput.unity", "status": "running", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +get_scene_bake_status {"artifacts": [], "backend": "navmesh-surface", "code": "ARTIFACT_VERIFICATION_FAILED", "jobId": "b3bc45b27e8b470ebbc5a39cc517ff2e", "phase": "failed", "reason": "Generated NavMesh cannot answer a complete path query.", "scenePath": "Assets/Scenes/Generated/E2E/Baking/NoOutput/NoOutput.unity", "status": "failed", "unityVersion": "6000.4.4f1", "verification": {"passed": false}} +PASS stable job identity +PASS backend completion without navigable output is a failed job +PASS no-output job reports diagnostic code and reason +PASS failed no-output job does not report successful artifacts +PASS no-output job does not persist unusable NavMeshData +execute_menu_item {"executed": true, "executionTime": 330, "menuExists": true, "menuPath": "Tools/Unity CLI/Baking/Prepare Empty", "message": "Menu item executed successfully", "success": true} +PASS Prepare Empty +PASS start_scene_bake returns a genuine error +PASS start_scene_bake rejects with NO_GEOMETRY: {"command":"raw start_scene_bake","data":{"code":"NO_GEOMETRY","error":"The target scene contains no active geometry to bake.","reason":"The target scene contains no active geometry to bake.","status":"error","unityVersion":"6000.4.4f1"},"errors":[{"code":"NO_GEOMETRY","message":"The target scene contains no active geometry to bake. (code: NO_GEOMETRY)"}],"success":false,"warnings":[]} + +PASS start_scene_bake returns a genuine error +PASS start_scene_bake rejects with NO_GEOMETRY: {"command":"raw start_scene_bake","data":{"code":"NO_GEOMETRY","error":"The target scene contains no active geometry to bake.","reason":"The target scene contains no active geometry to bake.","status":"error","unityVersion":"6000.4.4f1"},"errors":[{"code":"NO_GEOMETRY","message":"The target scene contains no active geometry to bake. (code: NO_GEOMETRY)"}],"success":false,"warnings":[]} + +PASS start_scene_bake returns a genuine error +PASS start_scene_bake rejects with NO_GEOMETRY: {"command":"raw start_scene_bake","data":{"code":"NO_GEOMETRY","error":"The target scene contains no active geometry to bake.","reason":"The target scene contains no active geometry to bake.","status":"error","unityVersion":"6000.4.4f1"},"errors":[{"code":"NO_GEOMETRY","message":"The target scene contains no active geometry to bake. (code: NO_GEOMETRY)"}],"success":false,"warnings":[]} + +PASS empty scene rejection creates no bake artifacts +Baking E2E: passed=101 failed=0 diff --git a/docs/verification/issue-386/resume/bake-headed-result.json b/docs/verification/issue-386/resume/bake-headed-result.json new file mode 100644 index 00000000..741c706c --- /dev/null +++ b/docs/verification/issue-386/resume/bake-headed-result.json @@ -0,0 +1,47 @@ +{ + "argv": [ + "py", + "-3", + "-X", + "utf8", + "-B", + "scripts/e2e-bake.py", + "--unity-cli", + "\\target\\debug\\unity-cli.exe", + "--port", + "6487", + "--project-root", + "\\.cache\\issue-386\\staff-project" + ], + "started_at": "2026-10-03T22:12:57.649158+00:00", + "editor_pid": 53380, + "owned_dialog_actions": [ + { + "scene": "Assets/Scenes/Generated/E2E/Baking/Lighting/Lighting.unity", + "action": "Ignore external reload, keep live bake scene", + "at": "2026-10-03T22:13:17.017866+00:00" + }, + { + "scene": "Assets/Scenes/Generated/E2E/Baking/Legacy/Legacy.unity", + "action": "Ignore external reload, keep live bake scene", + "at": "2026-10-03T22:13:23.035841+00:00" + }, + { + "scene": "Assets/Scenes/Generated/E2E/Baking/Surface/Surface.unity", + "action": "Ignore external reload, keep live bake scene", + "at": "2026-10-03T22:13:30.057345+00:00" + }, + { + "scene": "Assets/Scenes/Generated/E2E/Baking/Surface/Surface.unity", + "action": "Ignore external reload, keep live bake scene", + "at": "2026-10-03T22:13:34.069832+00:00" + }, + { + "scene": "Assets/Scenes/Generated/E2E/Baking/Occlusion/Occlusion.unity", + "action": "Ignore external reload, keep live bake scene", + "at": "2026-10-03T22:13:42.095729+00:00" + } + ], + "exit_code": 0, + "finished_at": "2026-10-03T22:13:51.120050+00:00" +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/bake-preview-green.xml b/docs/verification/issue-386/resume/bake-preview-green.xml new file mode 100644 index 00000000..6278f95e --- /dev/null +++ b/docs/verification/issue-386/resume/bake-preview-green.xml @@ -0,0 +1,3 @@ + +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.PreviewSceneDoesNotBlockSavedScene + diff --git a/docs/verification/issue-386/resume/bake-preview-red.xml b/docs/verification/issue-386/resume/bake-preview-red.xml new file mode 100644 index 00000000..6e99be17 --- /dev/null +++ b/docs/verification/issue-386/resume/bake-preview-red.xml @@ -0,0 +1,25 @@ + + { + "status": "error", + "code": "MULTIPLE_SCENES", + "reason": "Load only the target scene before baking.", + "error": "Load only the target scene before baking.", + "unityVersion": "6000.4.4f1" +} + Expected string length 7 but was 5. Strings differ at index 0. + Expected: "running" + But was: "error" + -----------^ +[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.BakeHandlerTests.PreviewSceneDoesNotBlockSavedScene + diff --git a/docs/verification/issue-386/resume/batch-message-green.txt b/docs/verification/issue-386/resume/batch-message-green.txt new file mode 100644 index 00000000..dd6119a6 --- /dev/null +++ b/docs/verification/issue-386/resume/batch-message-green.txt @@ -0,0 +1,8 @@ + Compiling unity-cli v0.18.1 () + Finished `test` profile [unoptimized + debuginfo] target(s) in 20.68s + Running unittests src\main.rs (target\debug\deps\unity_cli-6f9d4071c936636c.exe) + +running 1 test +test core::failure::tests::failed_batch_preserves_first_failure_message_and_all_results ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 556 filtered out; finished in 0.00s diff --git a/docs/verification/issue-386/resume/batch-message-red.txt b/docs/verification/issue-386/resume/batch-message-red.txt new file mode 100644 index 00000000..dc7775fe --- /dev/null +++ b/docs/verification/issue-386/resume/batch-message-red.txt @@ -0,0 +1,22 @@ + Compiling unity-cli v0.18.1 () + Finished `test` profile [unoptimized + debuginfo] target(s) in 10.43s + Running unittests src\main.rs (target\debug\deps\unity_cli-6f9d4071c936636c.exe) + +running 1 test +test core::failure::tests::failed_batch_preserves_first_failure_message_and_all_results ... FAILED + +failures: + +---- core::failure::tests::failed_batch_preserves_first_failure_message_and_all_results stdout ---- + +thread 'core::failure::tests::failed_batch_preserves_first_failure_message_and_all_results' (52600) panicked at src\core\failure.rs:166:9: +assertion failed: format!("{error:#}").contains("Failed to connect to Unity at 127.0.0.1:9") +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + core::failure::tests::failed_batch_preserves_first_failure_message_and_all_results + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 556 filtered out; finished in 0.00s + +error: test failed, to rerun pass `--bin unity-cli` diff --git a/docs/verification/issue-386/resume/canonical-verify-second.txt b/docs/verification/issue-386/resume/canonical-verify-second.txt new file mode 100644 index 00000000..bd31da56 --- /dev/null +++ b/docs/verification/issue-386/resume/canonical-verify-second.txt @@ -0,0 +1,2 @@ +{"error":"unexpected server response: verify: deferred — host busy for 1500s (budget 1500s): verification lease held by verification 99a8660247f5bc49--verification--4d3836567f81bbf5 (pid 52908 alive, job running, nice unknown, spawn-host inherit, 2692s left, 4 batches ≈ 4102s); holder progressing: held 103m52s, its 10 working processes gained 6607ms of CPU over the last 2.8s (240.3% of one core), and its process set turned over; next_turn_reserved: yes; queue_position: 1; rerun `verify.run` in about 4102s (timing hint only; a progressing holder renews its TTL) — a deferral is not a failure and there is no attempt cap: your turn stays reserved, so keep rerunning `verify.run` while the holder makes progress","exit_code":1,"ok":false,"operation":"verify.run"} +gwtd verify.run: unexpected server response: verify: deferred — host busy for 1500s (budget 1500s): verification lease held by verification 99a8660247f5bc49--verification--4d3836567f81bbf5 (pid 52908 alive, job running, nice unknown, spawn-host inherit, 2692s left, 4 batches ≈ 4102s); holder progressing: held 103m52s, its 10 working processes gained 6607ms of CPU over the last 2.8s (240.3% of one core), and its process set turned over; next_turn_reserved: yes; queue_position: 1; rerun `verify.run` in about 4102s (timing hint only; a progressing holder renews its TTL) — a deferral is not a failure and there is no attempt cap: your turn stays reserved, so keep rerunning `verify.run` while the holder makes progress diff --git a/docs/verification/issue-386/resume/canonical-verify.txt b/docs/verification/issue-386/resume/canonical-verify.txt new file mode 100644 index 00000000..24bb87fc --- /dev/null +++ b/docs/verification/issue-386/resume/canonical-verify.txt @@ -0,0 +1,8 @@ +{ + "error": "unexpected server response: verify: deferred — host busy for 1500s (budget 1500s): verification lease held by verification 99a8660247f5bc49--verification--4d3836567f81bbf5 (pid 52908 alive, job running, nice unknown, spawn-host inherit, 2699s left, 7 batches ≈ 597s); holder progressing: held 68m20s, its 7 working processes gained 515ms of CPU over the last 5.0s (10.3% of one core), and its process set turned over; next_turn_reserved: yes; queue_position: 1; rerun `verify.run` in about 597s (timing hint only; a progressing holder renews its TTL) — a deferral is not a failure and there is no attempt cap: your turn stays reserved, so keep rerunning `verify.run` while the holder makes progress", + "exit_code": 1, + "ok": false, + "operation": "verify.run", + "output": "" +} +gwtd verify.run: unexpected server response: verify: deferred — host busy for 1500s (budget 1500s): verification lease held by verification 99a8660247f5bc49--verification--4d3836567f81bbf5 (pid 52908 alive, job running, nice unknown, spawn-host inherit, 2699s left, 7 batches ≈ 597s); holder progressing: held 68m20s, its 7 working processes gained 515ms of CPU over the last 5.0s (10.3% of one core), and its process set turned over; next_turn_reserved: yes; queue_position: 1; rerun `verify.run` in about 597s (timing hint only; a progressing holder renews its TTL) — a deferral is not a failure and there is no attempt cap: your turn stays reserved, so keep rerunning `verify.run` while the holder makes progress diff --git a/docs/verification/issue-386/resume/cargo-all-final.txt b/docs/verification/issue-386/resume/cargo-all-final.txt new file mode 100644 index 00000000..e7b019fe --- /dev/null +++ b/docs/verification/issue-386/resume/cargo-all-final.txt @@ -0,0 +1,706 @@ + Finished `test` profile [unoptimized + debuginfo] target(s) in 1.03s + Running unittests src\main.rs (target\debug\deps\unity_cli-6f9d4071c936636c.exe) + +running 558 tests +test app::editor::tests::editor_launch_uses_paths_supported_by_unity ... ok +test app::runner::tests::ambiguous_editor_fails_before_contacting_any_editor ... ok +test app::runner::tests::animation_curve_edits_accept_operations_and_tangent_modes ... ok +test app::runner::tests::animation_curve_edits_reject_missing_identifiers_and_invalid_nested_fields ... ok +test app::runner::tests::animation_curve_queries_validate_complete_binding_filters ... ok +test app::runner::tests::audio_mixer_arguments_are_action_specific ... ok +test app::runner::tests::augment_command_stats_inserts_cli_snapshot ... ok +test app::runner::tests::baking_invalid_target_missing_scene_and_missing_job_are_rejected ... ok +test app::runner::tests::baking_surface_requires_path_before_contacting_editor ... ok +test app::runner::tests::baking_valid_targets_and_polling_are_accepted ... ok +test app::runner::tests::bridge_commands_resolve_explicit_project_path ... ok +test app::runner::tests::build_reference_call_clean_defaults ... ok +test app::runner::tests::build_reference_call_clean_with_version ... ok +test app::runner::tests::build_reference_call_diff_path_mode_with_limit ... ok +test app::runner::tests::build_reference_call_diff_symbol_mode ... ok +test app::runner::tests::build_reference_call_embed_build_includes_version ... ok +test app::runner::tests::build_reference_call_embed_build_omits_optional_version ... ok +test app::runner::tests::build_reference_call_embed_search_omits_optional_top_k ... ok +test app::runner::tests::build_reference_call_embed_search_with_top_k ... ok +test app::runner::tests::build_reference_call_fetch_carries_all_flags ... ok +test app::runner::tests::build_reference_call_fetch_defaults_without_overrides ... ok +test app::runner::tests::build_reference_call_find_symbol_minimal ... ok +test app::runner::tests::build_reference_call_find_symbol_with_filters ... ok +test app::runner::tests::build_reference_call_grep_defaults_context_to_zero ... ok +test app::runner::tests::build_reference_call_grep_with_file_glob_and_context ... ok +test app::runner::tests::build_reference_call_resolve_symbol_at_minimal ... ok +test app::runner::tests::build_reference_call_resolve_symbol_at_with_version ... ok +test app::runner::tests::build_reference_call_search_minimal_pattern ... ok +test app::runner::tests::build_reference_call_search_with_all_options ... ok +test app::runner::tests::build_reference_call_status_includes_explicit_version ... ok +test app::runner::tests::build_reference_call_status_omits_optional_version ... ok +test app::runner::tests::build_reference_call_view_omits_optional_lines ... ok +test app::runner::tests::build_reference_call_view_with_range ... ok +test app::runner::tests::capture_screenshot_timeout_respects_os_fallback_flag ... ok +test app::runner::tests::env_var_guard_restores_previous_value ... ok +test app::runner::tests::eval_cli_accepts_code_and_rejects_invalid_mode ... ok +test app::runner::tests::eval_dry_run_does_not_execute_arbitrary_code ... ok +test app::runner::tests::eval_schemas_require_code_and_status_id ... ok +test app::runner::tests::eval_transport_error_keeps_generated_request_id ... ok +test app::runner::tests::execute_tool_skips_mutating_tool_in_dry_run_mode ... ok +test app::runner::tests::hot_reload_requires_revision_and_explicit_action ... ok +test app::runner::tests::init_tracing_accepts_verbose_levels ... ok +test app::runner::tests::instances_list_defaults_host_to_ipv4_loopback ... ok +test app::runner::tests::load_params_defaults_to_empty_object ... ok +test app::runner::tests::load_params_reads_inline_json ... ok +test app::runner::tests::load_params_reads_json_from_file ... ok +test app::runner::tests::load_params_rejects_when_json_and_params_file_are_both_set ... ok +test app::runner::tests::parse_external_tool_command_accepts_json_flag ... ok +test app::runner::tests::parse_external_tool_command_rejects_unknown_flag ... ok +test app::runner::tests::parse_external_tool_command_requires_tool_name ... ok +test app::runner::tests::parse_external_tool_command_requires_values_for_flags ... ok +test app::runner::tests::parse_external_tool_command_supports_equals_forms ... ok +test app::runner::tests::parse_json_object_accepts_object ... ok +test app::runner::tests::parse_json_object_rejects_non_object ... ok +test app::runner::tests::parse_ports_deduplicates_values ... ok +test app::runner::tests::parse_ports_rejects_invalid_values ... ok +test app::runner::tests::parse_ports_returns_empty_for_none ... ok +test app::runner::tests::parse_ports_with_diagnostics_reports_duplicate_values ... ok +test app::runner::tests::ping_version_check_reports_mismatch_and_unknown ... ok +test app::runner::tests::prefab_override_validation_requires_explicit_scope_and_apply_target ... ok +test app::runner::tests::print_value_text_handles_string_and_object ... ok +test app::runner::tests::project_path_flag_is_global_and_feeds_runtime_overrides ... ok +test app::runner::tests::run_with_cli_batch_marks_skipped_items_in_dry_run_mode ... ok +test app::runner::tests::run_with_cli_exercises_remote_command_error_paths ... ok +test app::runner::tests::run_with_cli_handles_instances_and_daemon_commands_without_server ... ok +test app::runner::tests::run_with_cli_handles_local_tool_and_batch_paths ... ok +test app::runner::tests::run_with_cli_rejects_unknown_external_tool ... ok +test app::runner::tests::run_with_cli_requires_batch_input_source ... ok +test app::runner::tests::run_with_cli_set_active_text_output_when_reachable ... ok +test app::runner::tests::run_with_cli_supports_tool_schema_command ... ok +test app::runner::tests::runtime_overrides_are_derived_from_cli_at_app_boundary ... ok +test app::runner::tests::setup_and_bridge_cli_arguments_parse ... ok +test app::runner::tests::timeline_manage_is_skipped_in_dry_run ... ok +test app::runner::tests::timeline_validation_requires_target_and_valid_action ... ok +test app::runner::tests::validate_tool_params_accepts_add_component_payload ... ok +test app::runner::tests::validate_tool_params_accepts_addressables_manage_add_entry ... ok +test app::runner::tests::validate_tool_params_accepts_analyze_asset_dependencies_get_dependencies ... ok +test app::runner::tests::validate_tool_params_accepts_build_index_output_path ... ok +test app::runner::tests::validate_tool_params_accepts_create_animation_clip_payload ... ok +test app::runner::tests::validate_tool_params_accepts_create_animator_controller_payload ... ok +test app::runner::tests::validate_tool_params_accepts_create_gameobject_with_vector_fields ... ok +test app::runner::tests::validate_tool_params_accepts_create_sprite_atlas_payload ... ok +test app::runner::tests::validate_tool_params_accepts_delete_gameobject_with_path_and_paths ... ok +test app::runner::tests::validate_tool_params_accepts_execute_menu_item_get_available_menus ... ok +test app::runner::tests::validate_tool_params_accepts_execute_menu_item_without_action ... ok +test app::runner::tests::validate_tool_params_accepts_get_input_actions_state_with_asset_path ... ok +test app::runner::tests::validate_tool_params_accepts_input_keyboard_batch_actions ... ok +test app::runner::tests::validate_tool_params_accepts_load_scene_by_name ... ok +test app::runner::tests::validate_tool_params_accepts_lsp_write_payload_with_path_alias ... ok +test app::runner::tests::validate_tool_params_accepts_manage_layers_get_by_index ... ok +test app::runner::tests::validate_tool_params_accepts_package_manager_list_action ... ok +test app::runner::tests::validate_tool_params_accepts_profiler_start_payload ... ok +test app::runner::tests::validate_tool_params_accepts_valid_payload ... ok +test app::runner::tests::validate_tool_params_accepts_write_csharp_file_payload ... ok +test app::runner::tests::validate_tool_params_rejects_addressables_analyze_dependencies_without_asset_path ... ok +test app::runner::tests::validate_tool_params_rejects_addressables_manage_move_entry_without_target_group ... ok +test app::runner::tests::validate_tool_params_rejects_analyze_asset_dependencies_get_dependencies_without_asset_path ... ok +test app::runner::tests::validate_tool_params_rejects_analyze_asset_dependencies_invalid_action ... ok +test app::runner::tests::validate_tool_params_rejects_analyze_screenshot_without_source ... ok +test app::runner::tests::validate_tool_params_rejects_create_animation_clip_without_sprite_paths ... ok +test app::runner::tests::validate_tool_params_rejects_create_package_setting_without_value ... ok +test app::runner::tests::validate_tool_params_rejects_delete_gameobject_without_target ... ok +test app::runner::tests::validate_tool_params_rejects_execute_menu_item_without_action_or_menu_path ... ok +test app::runner::tests::validate_tool_params_rejects_execute_menu_item_without_menu_path ... ok +test app::runner::tests::validate_tool_params_rejects_invalid_animator_condition_mode ... ok +test app::runner::tests::validate_tool_params_rejects_invalid_sprite_atlas_filter_mode ... ok +test app::runner::tests::validate_tool_params_rejects_load_scene_with_both_identifiers ... ok +test app::runner::tests::validate_tool_params_rejects_manage_asset_database_move_without_to_path ... ok +test app::runner::tests::validate_tool_params_rejects_manage_layers_add_without_layer_name ... ok +test app::runner::tests::validate_tool_params_rejects_manage_layers_invalid_action ... ok +test app::runner::tests::validate_tool_params_rejects_manage_selection_set_without_object_paths ... ok +test app::runner::tests::validate_tool_params_rejects_manage_tools_activate_without_tool_name ... ok +test app::runner::tests::validate_tool_params_rejects_manage_windows_focus_without_window_type ... ok +test app::runner::tests::validate_tool_params_rejects_missing_required_property ... ok +test app::runner::tests::validate_tool_params_rejects_package_manager_search_without_keyword ... ok +test app::runner::tests::validate_tool_params_rejects_registry_config_add_scope_without_scope ... ok +test app::runner::tests::validate_tool_params_rejects_remove_input_binding_without_selector ... ok +test app::runner::tests::validate_tool_params_rejects_set_component_field_missing_required ... ok +test app::runner::tests::validate_tool_params_rejects_unknown_field_for_clear_logs ... ok +test app::runner::tests::validate_tool_params_rejects_unknown_property_when_schema_is_strict ... ok +test app::runner::tests::validate_tool_params_rejects_unknown_run_tests_property ... ok +test app::setup::tests::hub_paths_for_windows_and_linux_do_not_depend_on_test_host ... ok +test app::setup::tests::launch_editor_skips_when_project_is_locked_and_errors_without_editor ... ok +test app::setup::tests::project_unity_version_and_hub_path ... ok +test app::setup::tests::setup_dry_run_leaves_editor_unchecked_and_skips_writes ... ok +test app::setup::tests::setup_flags_editor_serving_another_project ... ok +test app::setup::tests::setup_installs_bridge_and_confirms_matching_editor ... ok +test app::setup::tests::setup_reports_version_mismatch_as_json ... ok +test app::setup::tests::setup_without_dry_run_reports_unreachable_editor ... ok +test app::test_report::tests::github_annotations_extract_unity_location_and_escape_injection ... ok +test app::test_report::tests::junit_preserves_failed_skipped_and_escaped_details ... ok +test app::test_report::tests::junit_time_is_millisecond_precision_for_xunit_schema ... ok +test app::test_report::tests::nunit_nests_test_cases_in_a_suite_and_preserves_details ... ok +test app::test_report::tests::parent_suite_rollups_do_not_duplicate_leaf_failures ... ok +test app::test_report::tests::suite_failure_is_reported_even_without_failed_leaves ... ok +test cli::test_command_tests::test_command_accepts_report_output_without_changing_global_output ... ok +test core::bridge::tests::dry_run_reports_change_without_writing ... ok +test core::bridge::tests::embedded_package_is_reported_and_not_duplicated ... ok +test core::bridge::tests::input_backends_untouched_when_setting_absent_or_already_enabled ... ok +test core::bridge::tests::install_adds_openupm_registry_and_cli_version ... ok +test core::bridge::tests::install_adds_scope_to_existing_openupm_registry ... ok +test core::bridge::tests::install_enables_input_system_backends_while_editor_is_closed ... ok +test core::bridge::tests::install_is_noop_when_already_configured_by_hand ... ok +test core::bridge::tests::install_keeps_other_version_and_upgrade_pins_cli_version ... ok +test core::bridge::tests::install_leaves_input_backends_when_editor_is_open_or_dry_run ... ok +test core::bridge::tests::install_twice_leaves_manifest_byte_identical ... ok +test core::bridge::tests::rejects_malformed_manifest ... ok +test core::bridge::tests::resolve_project_root_walks_up_and_validates_explicit_path ... ok +test core::bridge::tests::status_prefers_lock_resolution_and_reports_missing ... ok +test core::bridge::tests::upgrade_leaves_custom_sources_alone ... ok +test core::bridge::tests::version_check_classifies_versions ... ok +test core::command_stats::tests::snapshot_groups_calls_by_tool_and_route ... ok +test core::config::tests::default_host_returns_ipv4_loopback_without_env ... ok +test core::config::tests::default_port_returns_6400_without_env ... ok +test core::config::tests::default_timeout_returns_30000_without_env ... ok +test core::config::tests::empty_value_is_ignored ... ok +test core::config::tests::execution_context_uses_defaults ... ok +test core::config::tests::fails_when_legacy_alias_is_set ... ok +test core::config::tests::fails_when_removed_unityd_env_is_set ... ok +test core::config::tests::returns_none_when_no_keys_set ... ok +test core::config::tests::u16_env_parses_correctly ... ok +test core::config::tests::u16_env_rejects_zero ... ok +test core::config::tests::u64_env_parses_correctly ... ok +test core::config::tests::u64_env_rejects_zero ... ok +test core::doctor::tests::classification_priority ... ok +test core::doctor::tests::editor_import_workers_are_not_reusable_editors ... ok +test core::doctor::tests::parses_safe_mode_and_latest_compile_errors ... ok +test core::doctor::tests::reads_bridge_version_from_local_file_dependency ... ok +test core::doctor::tests::reads_project_bridge_port ... ok +test core::doctor::tests::recognizes_editor_command_lines_only ... ok +test core::doctor::tests::reports_editor_not_running ... ok +test core::doctor::tests::reports_port_in_use_with_owner_pid ... ok +test core::doctor::tests::safe_mode_exit_clears_flag ... ok +test core::editor_discovery::tests::ambiguous_error_json_lists_candidates ... ok +test core::editor_discovery::tests::dead_pid_marks_lockfile_stale ... ok +test core::editor_discovery::tests::discover_reads_lockfiles_and_skips_garbage ... ok +test core::editor_discovery::tests::expired_heartbeat_marks_lockfile_stale ... ok +test core::editor_discovery::tests::pid_zero_is_never_alive ... ok +test core::editor_discovery::tests::select_for_path_ignores_stale_editors_and_sibling_prefixes ... ok +test core::editor_discovery::tests::select_for_path_prefers_deepest_live_project ... ok +test core::endpoint::tests::active_instance_keeps_priority_over_lockfile_discovery ... ok +test core::endpoint::tests::cli_override_wins_over_active_instance ... ok +test core::endpoint::tests::cwd_inside_project_selects_that_editor ... ok +test core::endpoint::tests::cwd_outside_projects_with_two_editors_is_ambiguous ... ok +test core::endpoint::tests::env_port_wins_when_no_cli_override ... ok +test core::endpoint::tests::explicit_port_wins_over_project_path_and_lockfiles ... ok +test core::endpoint::tests::no_lockfiles_keeps_legacy_default ... ok +test core::endpoint::tests::project_command_targets_its_own_editor_among_several ... ok +test core::endpoint::tests::project_command_without_its_editor_uses_default_endpoint ... ok +test core::endpoint::tests::project_path_selects_matching_editor ... ok +test core::endpoint::tests::project_path_without_running_editor_is_not_found ... ok +test core::endpoint::tests::project_root_env_falls_back_to_default_without_any_lockfile ... ok +test core::endpoint::tests::single_running_editor_is_used_from_anywhere ... ok +test core::endpoint::tests::stale_editors_do_not_cause_ambiguity ... ok +test core::endpoint::tests::unity_project_root_env_acts_as_project_path ... ok +test core::failure::tests::failed_batch_preserves_first_failure_message_and_all_results ... ok +test core::instances::tests::authenticated_health_checks_support_listing_and_selection ... ok +test core::instances::tests::list_instances_adds_default_port_when_no_entries_exist ... ok +test core::instances::tests::list_instances_enumerates_lockfiles_without_ports ... ok +test core::instances::tests::list_instances_keeps_explicit_ports_next_to_lockfiles ... ok +test core::instances::tests::list_instances_reports_down_for_tcp_listener_that_is_not_unity_bridge ... ok +test core::instances::tests::list_instances_reports_up_for_reachable_port ... ok +test core::instances::tests::load_registry_reconstructs_missing_ids ... ok +test core::instances::tests::parse_id_validates_shape ... ok +test core::instances::tests::registry_path_uses_env_and_creates_parent_directory ... ok +test core::instances::tests::registry_round_trip_serialization_shape_is_supported ... ok +test core::instances::tests::set_active_fails_for_unreachable_instance ... ok +test core::instances::tests::set_active_succeeds_for_reachable_instance_and_tracks_previous ... ok +test core::managed_binaries::tests::cache_root_falls_back_to_home_unity_cache ... ok +test core::managed_binaries::tests::cache_root_prefers_unity_cli_cache_root_env ... ok +test core::managed_binaries::tests::detect_rid_returns_known_target_triple ... ok +test core::managed_binaries::tests::download_latest_binary_applies_matching_checksum ... ok +test core::managed_binaries::tests::download_latest_binary_rejects_checksum_mismatch_and_keeps_existing_install ... ok +test core::managed_binaries::tests::ensure_latest_for_can_skip_remote_checks_in_tests ... ok +test core::managed_binaries::tests::ensure_local_uses_existing_binary_without_download ... ok +test core::managed_binaries::tests::get_json_fails_with_status_and_body ... ok +test core::managed_binaries::tests::get_json_parses_http_body ... ok +test core::managed_binaries::tests::get_json_retries_transient_server_error ... ok +test core::managed_binaries::tests::get_optional_text_returns_body_for_success ... ok +test core::managed_binaries::tests::get_optional_text_returns_none_for_not_found ... ok +test core::managed_binaries::tests::get_response_includes_authorization_header ... ok +test core::managed_binaries::tests::get_response_reports_http_status_errors ... ok +test core::managed_binaries::tests::parse_sha256sums_reads_text_and_binary_mode_entries ... ok +test core::managed_binaries::tests::read_local_version_returns_none_for_missing_or_blank_file ... ok +test core::managed_binaries::tests::replace_file_atomic_overwrites_destination ... ok +test core::managed_binaries::tests::sha256_file_matches_known_hash ... ok +test core::managed_binaries::tests::tools_root_falls_back_to_home_unity_tools_when_env_unset ... ok +test core::managed_binaries::tests::tools_root_prefers_unity_cli_tools_root_env ... ok +test core::managed_binaries::tests::unity_cli_status_uses_managed_install_layout ... ok +test core::managed_binaries::tests::verify_manifest_against_checksums_requires_matching_entry ... ok +test core::managed_binaries::tests::write_and_read_local_version_round_trip ... ok +test core::runtime_paths::tests::daemon_dir_is_under_run_root ... ok +test core::self_update::tests::is_recent_returns_false_for_missing_path ... ok +test core::self_update::tests::is_recent_returns_true_for_freshly_touched_file ... ok +test core::self_update::tests::last_check_path_uses_unity_cli_tools_root_env ... ok +test core::self_update::tests::maybe_self_update_skipped_when_opt_out_env_set ... ok +test core::self_update::tests::maybe_self_update_skips_when_recent_check_exists ... ok +test core::self_update::tests::touch_creates_parent_and_writes_marker ... ok +test core::self_update::tests::warn_cargo_conflict_runs_without_panic ... ok +test daemon::runtime::tests::runtime_module_builds_without_warnings_when_unix_code_is_disabled ... ok +test daemon::spawn::tests::spawn_detached_starts_the_command ... ok +test daemon::spawn::tests::spawn_module_builds_for_windows_without_warnings ... ok +test daemon::spawn::tests::spawned_child_does_not_hold_the_callers_stdout_pipe ... ok +test daemon::unityd::tests::daemon_call_error_classification ... ok +test daemon::unityd::tests::daemon_request_batch_round_trip ... ok +test daemon::unityd::tests::daemon_request_ping_round_trip ... ok +test daemon::unityd::tests::daemon_request_status_round_trip ... ok +test daemon::unityd::tests::daemon_request_stop_round_trip ... ok +test daemon::unityd::tests::daemon_request_tool_round_trip ... ok +test daemon::unityd::tests::daemon_response_error_round_trip ... ok +test daemon::unityd::tests::daemon_response_round_trip ... ok +test daemon::unityd::tests::daemon_response_round_trip_preserves_timing ... ok +test daemon::unityd::tests::idle_timeout_default ... ok +test daemon::unityd::tests::pid_file_path_is_under_tools_dir ... ok +test daemon::unityd::tests::pooled_connection_closed_by_editor_restart_is_reconnected_before_sending ... ok +test daemon::unityd::tests::pooled_connection_uses_each_requests_timeout ... ok +test daemon::unityd::tests::request_lost_after_sending_is_reported_and_not_resent ... ok +test daemon::unityd::tests::startup_lock_times_out_and_is_reusable_after_release ... ok +test daemon::unityd::tests::tools_dir_creates_directory ... ok +test lsp::client::tests::collect_document_symbols_flattens_nested_symbols ... ok +test lsp::client::tests::get_apply_defaults_to_false ... ok +test lsp::client::tests::id_matches_accepts_number_and_string_id ... ok +test lsp::client::tests::kind_from_lsp_maps_known_values ... ok +test lsp::client::tests::normalize_lsp_write_result_adds_contract_fields ... ok +test lsp::client::tests::normalize_rel_path_accepts_assets_packages_and_library ... ok +test lsp::client::tests::normalize_rel_path_extracts_supported_prefix_from_absolute_like_input ... ok +test lsp::client::tests::normalize_rel_path_rejects_parent_traversal ... ok +test lsp::client::tests::path_matches_scope_filters_paths ... ok +test lsp::client::tests::remove_symbol_request_includes_fail_on_references_when_set ... ok +test lsp::client::tests::remove_symbol_request_omits_fail_on_references_when_unset ... ok +test lsp::client::tests::require_helpers_validate_expected_fields ... ok +test lsp::client::tests::retryable_session_error_detects_transport_failures ... ok +test lsp::client::tests::retryable_session_error_ignores_argument_errors ... ok +test lsp::client::tests::to_project_relative_or_raw_returns_relative_for_absolute_under_root ... ok +test lsp::client::tests::uri_and_ref_path_helpers_resolve_project_relative_paths ... ok +test lsp::client::tests::uri_to_rel_path_rejects_non_file_uris ... ok +test lsp::daemon::tests::daemon_idle_timeout_uses_env_override ... ok +test lsp::daemon::tests::handle_request_handles_ping_status_and_stop ... ok +test lsp::daemon::tests::is_would_block_checks_error_kind ... ok +test lsp::daemon::tests::write_all_with_retry_handles_would_block_and_partial_writes ... ok +test lsp::daemon::tests::write_all_with_retry_rejects_zero_byte_progress ... ok +test lsp::daemon::tests::write_pid_file_and_cleanup_manage_files_under_tools_root ... ok +test mcp::configure::tests::custom_root_may_have_missing_ancestors_without_creating_them ... ok +test mcp::configure::tests::invalid_config_is_never_overwritten_and_preview_creates_nothing ... ok +test mcp::configure::tests::malformed_shapes_and_http_name_collisions_are_rejected ... ok +test mcp::configure::tests::merges_inline_toml_without_losing_other_servers_or_options ... ok +test mcp::configure::tests::windows_and_local_paths ... ok +test mcp::tests::projects_owned_custom_descriptor_without_an_mcp_specific_schema ... ok +test reference::cache::tests::gc_empty_root_returns_empty ... ok +test reference::cache::tests::gc_keep_zero_removes_all_versions ... ok +test reference::cache::tests::gc_keeps_n_newest_and_returns_removed ... ok +test reference::cache::tests::gc_skips_non_directory_entries ... ok +test reference::cache::tests::list_versions_empty_when_root_missing ... ok +test reference::cache::tests::list_versions_returns_existing_dirs ... ok +test reference::cache::tests::list_versions_skips_files_in_root ... ok +test reference::cache::tests::meta_roundtrip ... ok +test reference::cache::tests::read_meta_returns_error_for_invalid_json ... ok +test reference::cache::tests::read_meta_returns_error_when_missing ... ok +test reference::cache::tests::version_dir_rejects_empty ... ok +test reference::cache::tests::version_dir_rejects_paths_outside_single_cache_entry ... ok +test reference::cache::tests::version_dir_under_cache_root ... ok +test reference::diff::tests::compute_line_diff_empty_for_identical_lines ... ok +test reference::diff::tests::compute_line_diff_for_deletes_only_returns_removal_hunk ... ok +test reference::diff::tests::compute_line_diff_for_inserts_only_returns_addition_hunk ... ok +test reference::diff::tests::compute_line_diff_for_separate_changes_produces_multiple_hunks ... ok +test reference::diff::tests::compute_line_diff_replacement_isolates_changed_lines ... ok +test reference::diff::tests::compute_path_diff_can_be_truncated ... ok +test reference::diff::tests::compute_path_diff_categorises_runtime_export ... ok +test reference::diff::tests::compute_symbol_diff_detects_changed_animator ... ok +test reference::diff::tests::compute_symbol_diff_returns_diff_when_only_one_side_has_symbol ... ok +test reference::diff::tests::compute_symbol_diff_returns_none_for_missing_in_both ... ok +test reference::diff::tests::ensure_cache_dir_errors_on_missing ... ok +test reference::diff::tests::split_fqn_separates_namespace_and_name ... ok +test reference::embed::tests::build_embedding_index_handles_empty_symbol_index ... ok +test reference::embed::tests::build_embedding_index_with_mock_embedder ... ok +test reference::embed::tests::cosine_similarity_handles_zero_vectors ... ok +test reference::embed::tests::embedding_roundtrip_via_bincode ... ok +test reference::embed::tests::resolve_onnxruntime_dylib_explains_how_to_install_when_missing ... ok +test reference::embed::tests::resolve_onnxruntime_dylib_falls_back_to_first_existing_candidate ... ok +test reference::embed::tests::resolve_onnxruntime_dylib_prefers_existing_env_path ... ok +test reference::embed::tests::resolve_onnxruntime_dylib_rejects_missing_env_path ... ok +test reference::embed::tests::search_ranks_by_cosine_similarity ... ok +test reference::embed::tests::search_returns_empty_for_empty_index ... ok +test reference::embed::tests::search_returns_empty_for_empty_query ... ok +test reference::embed::tests::symbol_to_text_includes_namespace_and_kind ... ok +test reference::embed::tests::symbol_to_text_without_namespace_omits_dot ... ok +test reference::fetcher::tests::api_discovery_paginates_branches_and_includes_tags ... ok +test reference::fetcher::tests::api_discovery_surfaces_http_errors ... ok +test reference::fetcher::tests::archive_url_uses_unity_cs_reference_org ... ok +test reference::fetcher::tests::build_clone_args_emits_shallow_single_branch ... ok +test reference::fetcher::tests::ensure_git_available_succeeds_in_test_env ... ok +test reference::fetcher::tests::extract_zip_to_rejects_entries_with_parent_segments ... ok +test reference::fetcher::tests::extract_zip_to_strips_top_level_prefix_and_writes_files ... ok +test reference::fetcher::tests::fetch_selected_checks_out_long_windows_paths_without_global_configuration ... ok +test reference::fetcher::tests::fetch_selected_pins_commit_after_branch_advances ... ok +test reference::fetcher::tests::fetch_selected_rejects_invalid_commit_before_creating_destination ... ok +test reference::fetcher::tests::github_token_returns_none_when_env_unset ... ok +test reference::fetcher::tests::github_token_skips_empty_and_picks_first_non_empty ... ok +test reference::fetcher::tests::license_ok_when_env_set ... ok +test reference::fetcher::tests::license_ok_when_flag_true ... ok +test reference::fetcher::tests::license_rejects_zero_value ... ok +test reference::fetcher::tests::license_required_when_flag_false_and_env_unset ... ok +test reference::fetcher::tests::list_public_refs_discovers_branches_and_tags ... ok +test reference::fetcher::tests::list_public_refs_preserves_transport_error ... ok +test reference::fetcher::tests::public_refs_use_basic_authentication_for_git_http ... ok +test reference::fetcher::tests::run_clone_rejects_when_license_not_accepted ... ok +test reference::index::tests::build_or_update_index_handles_existing_fixture ... ok +test reference::index::tests::build_or_update_index_persists_signature ... ok +test reference::index::tests::build_or_update_index_skips_already_indexed_files_until_change ... ok +test reference::index::tests::extract_symbols_from_text_captures_namespace ... ok +test reference::index::tests::extract_symbols_from_text_does_not_double_capture_class_name ... ok +test reference::index::tests::extract_symbols_from_text_finds_class ... ok +test reference::index::tests::extract_symbols_from_text_finds_methods ... ok +test reference::index::tests::extract_symbols_from_text_finds_property ... ok +test reference::index::tests::extract_symbols_from_text_finds_struct_and_interface ... ok +test reference::index::tests::file_signature_changes_when_content_changes ... ok +test reference::index::tests::find_symbol_filters_by_kind_and_namespace ... ok +test reference::index::tests::validate_kind_accepts_known_and_rejects_unknown ... ok +test reference::search::tests::grep_filters_by_filename_glob ... ok +test reference::search::tests::grep_finds_class_animator_with_line_numbers ... ok +test reference::search::tests::grep_returns_context_lines ... ok +test reference::search::tests::view_rejects_parent_traversal ... ok +test reference::search::tests::view_returns_requested_line_range ... ok +test reference::tests::cached_fetch_and_status_report_stored_provenance ... ok +test reference::tests::cached_unknown_version_can_be_used_without_branch_resolution ... ok +test reference::tests::dir_size_empty_returns_zero ... ok +test reference::tests::dir_size_sums_file_lengths ... ok +test reference::tests::execute_clean_dry_run_false_actually_removes ... ok +test reference::tests::execute_clean_dry_run_on_empty_cache_returns_empty_removed ... ok +test reference::tests::execute_diff_errors_when_cache_missing ... ok +test reference::tests::execute_diff_path_mode_returns_added_removed_changed ... ok +test reference::tests::execute_diff_requires_from_and_to ... ok +test reference::tests::execute_diff_requires_symbol_or_path ... ok +test reference::tests::execute_diff_symbol_mode_returns_diffs ... ok +test reference::tests::execute_embed_build_errors_when_cache_missing ... ok +test reference::tests::execute_embed_search_errors_when_index_missing ... ok +test reference::tests::execute_embed_search_requires_query ... ok +test reference::tests::execute_fetch_force_preserves_existing_on_transport_failure ... ok +test reference::tests::execute_fetch_skips_when_destination_exists_without_force ... ok +test reference::tests::execute_find_symbol_empty_hits_for_unknown_name ... ok +test reference::tests::execute_find_symbol_filters_namespace ... ok +test reference::tests::execute_find_symbol_rejects_unknown_kind ... ok +test reference::tests::execute_find_symbol_requires_name ... ok +test reference::tests::execute_find_symbol_returns_error_when_cache_missing ... ok +test reference::tests::execute_find_symbol_returns_hits_from_fixture ... ok +test reference::tests::execute_grep_invalid_regex_returns_error ... ok +test reference::tests::execute_grep_requires_pattern ... ok +test reference::tests::execute_grep_supports_file_glob_filter ... ok +test reference::tests::execute_grep_via_dispatcher_returns_hits ... ok +test reference::tests::execute_resolve_symbol_at_empty_token_for_blank_position ... ok +test reference::tests::execute_resolve_symbol_at_finds_token_via_fixture ... ok +test reference::tests::execute_resolve_symbol_at_requires_path_line_column ... ok +test reference::tests::execute_resolve_symbol_at_requires_project_prefix ... ok +test reference::tests::execute_search_requires_pattern ... ok +test reference::tests::execute_search_via_dispatcher_truncates_max_results ... ok +test reference::tests::execute_search_without_max_results_returns_all_hits ... ok +test reference::tests::execute_status_includes_size_bytes ... ok +test reference::tests::execute_status_returns_versions_list ... ok +test reference::tests::execute_view_rejects_parent_traversal_via_dispatcher ... ok +test reference::tests::execute_view_requires_path_param ... ok +test reference::tests::execute_view_via_dispatcher_returns_lines ... ok +test reference::tests::extract_token_at_cursor_handles_edge_cases ... ok +test reference::tests::extract_token_at_cursor_handles_escaped_quote_in_string ... ok +test reference::tests::extract_token_at_cursor_returns_ident_after_closed_string ... ok +test reference::tests::extract_token_at_cursor_skips_line_comment ... ok +test reference::tests::extract_token_at_cursor_skips_string_literal ... ok +test reference::tests::fetch_resolves_project_and_explicit_refs_and_records_actual_commit ... ok +test reference::tests::legacy_metadata_keeps_unknown_match_instead_of_claiming_exact ... ok +test reference::tests::maybe_execute_returns_none_for_unknown_tool ... ok +test reference::tests::now_unix_seconds_string_is_decimal ... ok +test reference::tests::resolve_version_falls_back_to_project_detection ... ok +test reference::tests::resolve_version_uses_explicit_param ... ok +test reference::version::tests::ambiguous_auto_candidates_and_unknown_versions_return_candidates ... ok +test reference::version::tests::detect_returns_error_when_editor_version_line_absent ... ok +test reference::version::tests::detect_returns_error_when_editor_version_value_empty ... ok +test reference::version::tests::detect_returns_error_when_project_version_missing ... ok +test reference::version::tests::exact_tag_precedes_minor_but_version_named_head_is_not_exact ... ok +test reference::version::tests::explicit_ref_has_priority_and_ambiguous_short_names_require_full_ref ... ok +test reference::version::tests::minor_version_key_rejects_invalid_inputs ... ok +test reference::version::tests::parse_editor_version_returns_value_directly ... ok +test reference::version::tests::parses_remote_refs_with_peeled_tag_commits_in_any_order ... ok +test reference::version::tests::public_resolver_handles_previously_supported_minors ... ok +test reference::version::tests::reads_known_project_version ... ok +test reference::version::tests::reads_unknown_minor_without_static_mapping ... ok +test reference::version::tests::selects_new_and_existing_minor_branches_without_claiming_exact_match ... ok +test skills::loader::tests::load_skills_handles_missing_root_and_skips_non_skill_entries ... ok +test skills::loader::tests::load_skills_supports_single_skill_root_and_dir_name_fallback ... ok +test skills::loader::tests::parse_frontmatter_and_collect_references_cover_optional_branches ... ok +test skills::loader::tests::parse_frontmatter_extracts_metadata ... ok +test skills::loader::tests::split_frontmatter_and_parse_frontmatter_cover_edge_cases ... ok +test skills::loader::tests::split_frontmatter_handles_basic_skill ... ok +test skills::tests::good_skill_passes_all_rules ... ok +test skills::tests::model_helpers_cover_skill_accessors_and_tool_sets ... ok +test skills::tests::r01_missing_description_fires ... ok +test skills::tests::r01_missing_multiple_required_fields_fire ... ok +test skills::tests::r02_name_mismatch_fires ... ok +test skills::tests::r03_disallowed_tool_fires ... ok +test skills::tests::r03_legacy_bare_bash_fires ... ok +test skills::tests::r04_unknown_category_fires ... ok +test skills::tests::r05_empty_and_duplicate_triggers_fire ... ok +test skills::tests::r05_uppercase_trigger_fires ... ok +test skills::tests::r06_unknown_sibling_fires ... ok +test skills::tests::r07_too_long_description_fires ... ok +test skills::tests::r08_missing_front_trigger_fires ... ok +test skills::tests::r09_first_person_fires ... ok +test skills::tests::r10_missing_use_when_fires ... ok +test skills::tests::r11_missing_sibling_mention_fires ... ok +test skills::tests::r12_unidirectional_sibling_fires ... ok +test skills::tests::r13_too_long_body_fires ... ok +test skills::tests::r14_missing_heading_fires ... ok +test skills::tests::r15_references_without_link_fires ... ok +test skills::tests::r16_time_sensitive_phrase_fires ... ok +test skills::tests::r17_missing_runtime_checklist_fires ... ok +test skills::tests::r18_long_reference_without_toc_fires ... ok +test skills::tests::r19_reference_link_to_reference_fires ... ok +test skills::tests::r20_and_r21_validate_windows_git_symlink_placeholders ... ok +test skills::tests::r22_collision_without_cross_listing_fires ... ok +test skills::tests::report_and_runner_cover_text_json_discovery_and_error_paths ... ok +test test_env::isolated_runtime_restores_inherited_environment_after_unwind ... ok +test tooling::discovery::tests::bridge_reserved_names_match_the_cli_catalog_including_local_tools ... ok +test tooling::discovery::tests::builtin_descriptors_keep_schemas_and_mark_their_source ... ok +test tooling::discovery::tests::custom_descriptor_roundtrips_owned_names_and_schema ... ok +test tooling::discovery::tests::list_tools_is_a_read_only_remote_builtin ... ok +test tooling::local_tools::tests::build_index_and_find_symbol_roundtrip ... ok +test tooling::local_tools::tests::collect_cs_files_and_index_helpers_cover_readiness_branches ... ok +test tooling::local_tools::tests::create_class_generates_simple_class ... ok +test tooling::local_tools::tests::create_class_rejects_existing_file ... ok +test tooling::local_tools::tests::create_class_rejects_invalid_name ... ok +test tooling::local_tools::tests::create_class_with_namespace_and_inherits ... ok +test tooling::local_tools::tests::default_runtime_config_falls_back_to_ipv4_loopback ... ok +test tooling::local_tools::tests::extract_symbols_from_text_covers_major_symbol_kinds ... ok +test tooling::local_tools::tests::find_refs_supports_cursor_paging ... ok +test tooling::local_tools::tests::find_symbol_returns_index_not_ready_before_build ... ok +test tooling::local_tools::tests::get_symbols_extracts_class_and_method ... ok +test tooling::local_tools::tests::helper_comment_and_snippet_processing_works ... ok +test tooling::local_tools::tests::helper_path_normalization_and_resolution_cover_edge_cases ... ok +test tooling::local_tools::tests::helper_symbol_and_scope_predicates_work ... ok +test tooling::local_tools::tests::list_packages_lists_package_dirs ... ok +test tooling::local_tools::tests::lsp_write_tools_require_lsp_mode ... ok +test tooling::local_tools::tests::post_write_refresh_failure_preserves_applied_files_without_runtime_panic ... ok +test tooling::local_tools::tests::read_returns_file_slice ... ok +test tooling::local_tools::tests::requires_unityengine_using_only_for_monobehaviour ... ok +test tooling::local_tools::tests::search_finds_matching_lines ... ok +test tooling::local_tools::tests::update_index_refreshes_symbol_names ... ok +test tooling::os_capture::tests::capture_fails_when_no_candidate_exists ... ok +test tooling::os_capture::tests::detects_daemon_stringified_timeouts ... ok +test tooling::os_capture::tests::disabled_fallback_returns_the_timeout_error ... ok +test tooling::os_capture::tests::failed_os_capture_keeps_both_errors ... ok +test tooling::os_capture::tests::fallback_flag_defaults_on_and_is_stripped ... ok +test tooling::os_capture::tests::non_timeout_errors_are_not_recovered ... ok +test tooling::os_capture::tests::output_path_follows_bridge_capture_directory ... ok +test tooling::os_capture::tests::timeout_is_recovered_with_os_fallback_marker ... ok +test tooling::os_capture::tests::verbatim_prefix_is_dropped_before_the_path_reaches_os_tools ... ok +test tooling::tool_catalog::tests::action_enum_schemas_use_composite_variants ... ok +test tooling::tool_catalog::tests::addressables_analyze_schema_uses_action_specific_variants ... ok +test tooling::tool_catalog::tests::addressables_manage_schema_has_manage_actions ... ok +test tooling::tool_catalog::tests::all_tools_e2e_covers_catalog_or_documents_exclusion ... ok +test tooling::tool_catalog::tests::analyze_asset_dependencies_schema_has_expected_actions ... ok +test tooling::tool_catalog::tests::animation_curve_tools_advertise_strict_unity_contracts ... ok +test tooling::tool_catalog::tests::baking_tools_have_explicit_target_and_polling_contracts ... ok +test tooling::tool_catalog::tests::build_index_schema_allows_output_path ... ok +test tooling::tool_catalog::tests::build_player_schema_requires_explicit_safe_build_inputs ... ok +test tooling::tool_catalog::tests::capture_video_start_schema_restricts_mode_and_format ... ok +test tooling::tool_catalog::tests::clear_logs_schema_is_strict_empty_object ... ok +test tooling::tool_catalog::tests::create_animation_clip_schema_requires_clip_and_sprite_paths ... ok +test tooling::tool_catalog::tests::create_animator_controller_schema_is_strict_and_nested ... ok +test tooling::tool_catalog::tests::create_prefab_schema_allows_template_mode_without_source_object ... ok +test tooling::tool_catalog::tests::create_sprite_atlas_schema_is_strict_and_nested ... ok +test tooling::tool_catalog::tests::csharp_file_write_schemas_are_local_and_strict ... ok +test tooling::tool_catalog::tests::delete_gameobject_schema_uses_any_of_targets ... ok +test tooling::tool_catalog::tests::execute_menu_item_schema_supports_default_and_action_variants ... ok +test tooling::tool_catalog::tests::get_build_status_is_read_only_and_requires_build_id ... ok +test tooling::tool_catalog::tests::get_gameobject_details_schema_uses_any_of_identifiers ... ok +test tooling::tool_catalog::tests::get_index_status_schema_is_strict_empty_object ... ok +test tooling::tool_catalog::tests::hot_reload_tools_expose_explicit_preview_and_recovery_contract ... ok +test tooling::tool_catalog::tests::input_keyboard_schema_uses_any_of_for_action_or_actions ... ok +test tooling::tool_catalog::tests::known_tool_lookup_works ... ok +test tooling::tool_catalog::tests::load_scene_schema_uses_one_of_identifier_variants ... ok +test tooling::tool_catalog::tests::local_executor_tools_are_marked ... ok +test tooling::tool_catalog::tests::manage_asset_database_schema_uses_action_specific_variants ... ok +test tooling::tool_catalog::tests::manage_layers_schema_requires_action_enum ... ok +test tooling::tool_catalog::tests::modify_gameobject_schema_requires_path ... ok +test tooling::tool_catalog::tests::package_manager_schema_has_required_action ... ok +test tooling::tool_catalog::tests::ping_schema_is_strict_object ... ok +test tooling::tool_catalog::tests::prefab_override_tools_have_strict_discoverable_schemas ... ok +test tooling::tool_catalog::tests::quit_editor_exposes_optional_scene_protection_parameter ... ok +test tooling::tool_catalog::tests::remote_tools_have_unity_bridge_dispatch_cases ... ok +test tooling::tool_catalog::tests::rename_symbol_schema_is_strict_and_requires_name_path ... ok +test tooling::tool_catalog::tests::run_tests_schema_allows_test_mode_enum ... ok +test tooling::tool_catalog::tests::set_component_field_schema_requires_component_and_field ... ok +test tooling::tool_catalog::tests::timeline_schema_exposes_actions_and_stale_clip_guard ... ok +test tooling::tool_catalog::tests::timeline_tools_are_discoverable_with_correct_mutation_flags ... ok +test tooling::tool_catalog::tests::tool_catalog_avoids_default_params_schema_for_known_tools ... ok +test tooling::tool_catalog::tests::tool_catalog_keeps_manifest_parity_count ... ok +test tooling::tool_catalog::tests::tool_specs_cover_catalog ... ok +test tooling::tool_catalog::tests::tools_doc_matches_registered_catalog ... ok +test tooling::tool_catalog::tests::vfx_apply_is_mutating_and_requires_op ... ok +test tooling::tool_catalog::tests::vfx_describe_graph_is_read_only_and_requires_asset_path ... ok +test tooling::tool_catalog::tests::vfx_runtime_is_mutating_and_requires_op_and_game_object ... ok +test tooling::tool_catalog::tests::vfx_settings_is_mutating_and_requires_op ... ok +test tooling::tool_index::tests::category_accepts_heading_or_slug ... ok +test tooling::tool_index::tests::every_tool_has_exactly_one_index_entry_with_a_short_summary ... ok +test tooling::tool_index::tests::query_matches_name_or_summary_case_insensitively ... ok +test tooling::tool_index::tests::tool_index_matches_docs_headings ... ok +test tooling::tool_index::tests::unknown_category_lists_valid_slugs ... ok +test unity::auth::tests::credentials_are_endpoint_scoped_and_absent_from_discovery_output ... ok +test unity::auth::tests::explicit_mounted_lockfile_and_invalid_file_errors_do_not_expose_token ... ok +test unity::auth::tests::only_exact_one_enables_legacy_opt_out ... ok +test unity::transport::tests::call_tool_returns_error_on_failure_response ... ok +test unity::transport::tests::call_tool_returns_result_on_success ... ok +test unity::transport::tests::call_tool_with_timing_reports_non_negative_durations ... ok +test unity::transport::tests::every_request_carries_token_from_private_lockfile ... ok +test unity::transport::tests::normalize_failure_preserves_complete_error_envelope ... ok +test unity::transport::tests::normalize_response_handles_success_and_error_shapes ... ok +test unity::transport::tests::parse_embedded_json_keeps_plain_strings ... ok +test unity::transport::tests::parse_json_accepts_trimmed_json ... ok +test unity::transport::tests::parse_json_rejects_empty_and_non_utf8_payload ... ok +test unity::transport::tests::ping_backfills_bridge_version_from_editor_state_envelope ... ok + +test result: ok. 558 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 69.01s + + Running tests\auth_warning.rs (target\debug\deps\auth_warning-c35c20bac6c142a9.exe) + +running 1 test +test legacy_opt_out_warns_on_stderr_only_for_exact_one ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 11.83s + + Running tests\bridge_package_dependencies.rs (target\debug\deps\bridge_package_dependencies-c22ae8298886d006.exe) + +running 1 test +test bridge_declares_ugui_when_sources_use_it ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s + + Running tests\build_failure_output.rs (target\debug\deps\build_failure_output-1ea8e89b85e8d186.exe) + +running 1 test +test failed_build_status_keeps_json_report_and_nonzero_exit ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.51s + + Running tests\ci_tests.rs (target\debug\deps\ci_tests-0a59ca143bc1adb3.exe) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests\csharp_post_write.rs (target\debug\deps\csharp_post_write-132f286b429372c3.exe) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests\custom_tools.rs (target\debug\deps\custom_tools-f6cf3b643480b090.exe) + +running 10 tests +test batch_validates_all_custom_arguments_before_any_side_effect ... ok +test custom_method_is_not_retried_after_lost_response ... ok +test custom_numeric_ranges_and_nullable_defaults_are_validated_before_execution ... ok +test discovery_merges_schemas_and_sources_and_filters_custom_tools ... ok +test discovery_rejects_conflicting_or_malformed_editor_catalogs ... ok +test dry_run_and_unknown_tools_never_invoke_a_custom_method ... ok +test invalid_custom_arguments_never_reach_the_method ... ok +test names_only_and_compact_preserve_small_list_shapes ... ok +test old_bridges_keep_the_builtin_catalog_but_auth_errors_are_visible ... ok +test schema_and_all_call_spellings_support_custom_names ... ok + +test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.85s + + Running tests\editor_lifecycle.rs (target\debug\deps\editor_lifecycle-84c3f58d5f45f2e9.exe) + +running 4 tests +test close_requires_bridge_scene_protection_before_sending_quit ... ok +test editor_lifecycle_commands_are_available ... ok +test missing_editor_explains_official_install_and_returns_precondition ... ok +test status_reports_compilation_from_the_selected_project ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.72s + + Running tests\install_script.rs (target\debug\deps\install_script-a3d362ab68edd4d9.exe) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests\json_envelope.rs (target\debug\deps\json_envelope-6eaad9084b5bdd8a.exe) + +running 15 tests +test batch_with_failed_operation_does_not_exit_zero ... ok +test bridge_errors_preserve_codes_and_authentication_exit ... ok +test bridge_warnings_reach_the_public_envelope ... ok +test clap_usage_error_has_json_envelope ... ok +test direct_authentication_and_bridge_failures_match_daemon ... ok +test invalid_batch_is_usage_error ... ok +test invalid_json_is_usage_error ... ok +test invalid_port_list_is_usage_error ... ok +test invalid_tool_routes_are_usage_errors ... ok +test local_success_uses_single_envelope ... ok +test nested_bridge_failure_is_not_reported_as_success ... ok +test response_timeout_is_retryable_operation_failure ... ok +test skills_show_and_lint_use_envelopes ... ok +test test_completion_distinguishes_failed_and_passed ... ok +test unreachable_editor_is_exit_seven ... ok + +test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 21.77s + + Running tests\mcp.rs (target\debug\deps\mcp-9035db26334793d1.exe) + +running 3 tests +test configure_all_clients_preserves_other_servers_and_dry_run ... ok +test malformed_requests_do_not_end_session_or_execute_tools_before_initialization ... ok +test stdio_catalog_and_failure_contract_without_editor ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 18.04s + + Running tests\mcp_dynamic.rs (target\debug\deps\mcp_dynamic-5e938b67940e38e9.exe) + +running 1 test +test custom_catalog_calls_and_live_removal_share_cli_discovery_and_validation ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.11s + + Running tests\setup_dry_run.rs (target\debug\deps\setup_dry_run-7097af0dc1444163.exe) + +running 2 tests +test setup_dry_run_prints_plan_without_connections_writes_or_launches ... ok +test setup_launch_returns_output_while_editor_is_still_running ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.14s + + Running tests\skills_install.rs (target\debug\deps\skills_install-7ac81df839f43c4f.exe) + +running 7 tests +test all_clients_install_embedded_references_and_show_works_outside_repository ... ok +test dry_run_prints_only_paths_without_creating_files ... ok +test global_dry_run_flag_also_prevents_installation ... ok +test install_protects_unowned_directory_and_force_keeps_unrelated_files ... ok +test invalid_ledger_paths_are_rejected_even_with_force ... ok +test refresh_does_not_install_clients_without_a_ledger ... ok +test refresh_syncs_an_older_owned_version_and_protects_local_edits ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.75s + + Running tests\tool_list_filters.rs (target\debug\deps\tool_list_filters-6faf0e078f88be27.exe) + +running 7 tests +test category_returns_only_that_docs_section ... ok +test compact_is_name_and_description_only_and_at_most_half_of_full_catalog ... ok +test limit_and_offset_page_the_filtered_list ... ok +test offline_default_list_has_schemas_and_names_only_is_compatible ... ok +test query_returns_only_matching_tools ... ok +test unknown_category_is_rejected ... ok +test unopened_project_still_exposes_the_offline_builtin_catalog ... ok + +test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 15.26s + + Running tests\unityd_autostart.rs (target\debug\deps\unityd_autostart-6dcacab8badb9285.exe) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s diff --git a/docs/verification/issue-386/resume/cargo-test-inventory.json b/docs/verification/issue-386/resume/cargo-test-inventory.json new file mode 100644 index 00000000..bc920d2e --- /dev/null +++ b/docs/verification/issue-386/resume/cargo-test-inventory.json @@ -0,0 +1,3057 @@ +{ + "total": 610, + "passed": 610, + "failed": 0, + "tests": [ + { + "suite": "unittests src\\main.rs", + "name": "app::editor::tests::editor_launch_uses_paths_supported_by_unity", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::ambiguous_editor_fails_before_contacting_any_editor", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::animation_curve_edits_accept_operations_and_tangent_modes", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::animation_curve_edits_reject_missing_identifiers_and_invalid_nested_fields", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::animation_curve_queries_validate_complete_binding_filters", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::audio_mixer_arguments_are_action_specific", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::augment_command_stats_inserts_cli_snapshot", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::baking_invalid_target_missing_scene_and_missing_job_are_rejected", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::baking_surface_requires_path_before_contacting_editor", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::baking_valid_targets_and_polling_are_accepted", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::bridge_commands_resolve_explicit_project_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_clean_defaults", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_clean_with_version", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_diff_path_mode_with_limit", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_diff_symbol_mode", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_embed_build_includes_version", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_embed_build_omits_optional_version", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_embed_search_omits_optional_top_k", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_embed_search_with_top_k", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_fetch_carries_all_flags", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_fetch_defaults_without_overrides", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_find_symbol_minimal", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_find_symbol_with_filters", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_grep_defaults_context_to_zero", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_grep_with_file_glob_and_context", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_resolve_symbol_at_minimal", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_resolve_symbol_at_with_version", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_search_minimal_pattern", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_search_with_all_options", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_status_includes_explicit_version", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_status_omits_optional_version", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_view_omits_optional_lines", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::build_reference_call_view_with_range", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::capture_screenshot_timeout_respects_os_fallback_flag", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::env_var_guard_restores_previous_value", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::eval_cli_accepts_code_and_rejects_invalid_mode", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::eval_dry_run_does_not_execute_arbitrary_code", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::eval_schemas_require_code_and_status_id", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::eval_transport_error_keeps_generated_request_id", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::execute_tool_skips_mutating_tool_in_dry_run_mode", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::hot_reload_requires_revision_and_explicit_action", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::init_tracing_accepts_verbose_levels", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::instances_list_defaults_host_to_ipv4_loopback", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::load_params_defaults_to_empty_object", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::load_params_reads_inline_json", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::load_params_reads_json_from_file", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::load_params_rejects_when_json_and_params_file_are_both_set", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::parse_external_tool_command_accepts_json_flag", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::parse_external_tool_command_rejects_unknown_flag", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::parse_external_tool_command_requires_tool_name", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::parse_external_tool_command_requires_values_for_flags", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::parse_external_tool_command_supports_equals_forms", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::parse_json_object_accepts_object", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::parse_json_object_rejects_non_object", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::parse_ports_deduplicates_values", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::parse_ports_rejects_invalid_values", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::parse_ports_returns_empty_for_none", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::parse_ports_with_diagnostics_reports_duplicate_values", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::ping_version_check_reports_mismatch_and_unknown", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::prefab_override_validation_requires_explicit_scope_and_apply_target", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::print_value_text_handles_string_and_object", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::project_path_flag_is_global_and_feeds_runtime_overrides", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::run_with_cli_batch_marks_skipped_items_in_dry_run_mode", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::run_with_cli_exercises_remote_command_error_paths", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::run_with_cli_handles_instances_and_daemon_commands_without_server", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::run_with_cli_handles_local_tool_and_batch_paths", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::run_with_cli_rejects_unknown_external_tool", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::run_with_cli_requires_batch_input_source", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::run_with_cli_set_active_text_output_when_reachable", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::run_with_cli_supports_tool_schema_command", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::runtime_overrides_are_derived_from_cli_at_app_boundary", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::setup_and_bridge_cli_arguments_parse", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::timeline_manage_is_skipped_in_dry_run", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::timeline_validation_requires_target_and_valid_action", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_add_component_payload", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_addressables_manage_add_entry", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_analyze_asset_dependencies_get_dependencies", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_build_index_output_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_create_animation_clip_payload", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_create_animator_controller_payload", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_create_gameobject_with_vector_fields", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_create_sprite_atlas_payload", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_delete_gameobject_with_path_and_paths", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_execute_menu_item_get_available_menus", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_execute_menu_item_without_action", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_get_input_actions_state_with_asset_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_input_keyboard_batch_actions", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_load_scene_by_name", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_lsp_write_payload_with_path_alias", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_manage_layers_get_by_index", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_package_manager_list_action", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_profiler_start_payload", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_valid_payload", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_accepts_write_csharp_file_payload", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_addressables_analyze_dependencies_without_asset_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_addressables_manage_move_entry_without_target_group", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_analyze_asset_dependencies_get_dependencies_without_asset_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_analyze_asset_dependencies_invalid_action", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_analyze_screenshot_without_source", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_create_animation_clip_without_sprite_paths", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_create_package_setting_without_value", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_delete_gameobject_without_target", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_execute_menu_item_without_action_or_menu_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_execute_menu_item_without_menu_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_invalid_animator_condition_mode", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_invalid_sprite_atlas_filter_mode", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_load_scene_with_both_identifiers", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_manage_asset_database_move_without_to_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_manage_layers_add_without_layer_name", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_manage_layers_invalid_action", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_manage_selection_set_without_object_paths", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_manage_tools_activate_without_tool_name", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_manage_windows_focus_without_window_type", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_missing_required_property", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_package_manager_search_without_keyword", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_registry_config_add_scope_without_scope", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_remove_input_binding_without_selector", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_set_component_field_missing_required", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_unknown_field_for_clear_logs", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_unknown_property_when_schema_is_strict", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::runner::tests::validate_tool_params_rejects_unknown_run_tests_property", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::setup::tests::hub_paths_for_windows_and_linux_do_not_depend_on_test_host", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::setup::tests::launch_editor_skips_when_project_is_locked_and_errors_without_editor", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::setup::tests::project_unity_version_and_hub_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::setup::tests::setup_dry_run_leaves_editor_unchecked_and_skips_writes", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::setup::tests::setup_flags_editor_serving_another_project", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::setup::tests::setup_installs_bridge_and_confirms_matching_editor", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::setup::tests::setup_reports_version_mismatch_as_json", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::setup::tests::setup_without_dry_run_reports_unreachable_editor", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::test_report::tests::github_annotations_extract_unity_location_and_escape_injection", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::test_report::tests::junit_preserves_failed_skipped_and_escaped_details", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::test_report::tests::junit_time_is_millisecond_precision_for_xunit_schema", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::test_report::tests::nunit_nests_test_cases_in_a_suite_and_preserves_details", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::test_report::tests::parent_suite_rollups_do_not_duplicate_leaf_failures", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "app::test_report::tests::suite_failure_is_reported_even_without_failed_leaves", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "cli::test_command_tests::test_command_accepts_report_output_without_changing_global_output", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::bridge::tests::dry_run_reports_change_without_writing", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::bridge::tests::embedded_package_is_reported_and_not_duplicated", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::bridge::tests::input_backends_untouched_when_setting_absent_or_already_enabled", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::bridge::tests::install_adds_openupm_registry_and_cli_version", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::bridge::tests::install_adds_scope_to_existing_openupm_registry", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::bridge::tests::install_enables_input_system_backends_while_editor_is_closed", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::bridge::tests::install_is_noop_when_already_configured_by_hand", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::bridge::tests::install_keeps_other_version_and_upgrade_pins_cli_version", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::bridge::tests::install_leaves_input_backends_when_editor_is_open_or_dry_run", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::bridge::tests::install_twice_leaves_manifest_byte_identical", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::bridge::tests::rejects_malformed_manifest", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::bridge::tests::resolve_project_root_walks_up_and_validates_explicit_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::bridge::tests::status_prefers_lock_resolution_and_reports_missing", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::bridge::tests::upgrade_leaves_custom_sources_alone", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::bridge::tests::version_check_classifies_versions", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::command_stats::tests::snapshot_groups_calls_by_tool_and_route", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::config::tests::default_host_returns_ipv4_loopback_without_env", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::config::tests::default_port_returns_6400_without_env", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::config::tests::default_timeout_returns_30000_without_env", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::config::tests::empty_value_is_ignored", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::config::tests::execution_context_uses_defaults", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::config::tests::fails_when_legacy_alias_is_set", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::config::tests::fails_when_removed_unityd_env_is_set", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::config::tests::returns_none_when_no_keys_set", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::config::tests::u16_env_parses_correctly", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::config::tests::u16_env_rejects_zero", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::config::tests::u64_env_parses_correctly", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::config::tests::u64_env_rejects_zero", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::doctor::tests::classification_priority", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::doctor::tests::editor_import_workers_are_not_reusable_editors", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::doctor::tests::parses_safe_mode_and_latest_compile_errors", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::doctor::tests::reads_bridge_version_from_local_file_dependency", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::doctor::tests::reads_project_bridge_port", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::doctor::tests::recognizes_editor_command_lines_only", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::doctor::tests::reports_editor_not_running", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::doctor::tests::reports_port_in_use_with_owner_pid", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::doctor::tests::safe_mode_exit_clears_flag", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::editor_discovery::tests::ambiguous_error_json_lists_candidates", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::editor_discovery::tests::dead_pid_marks_lockfile_stale", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::editor_discovery::tests::discover_reads_lockfiles_and_skips_garbage", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::editor_discovery::tests::expired_heartbeat_marks_lockfile_stale", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::editor_discovery::tests::pid_zero_is_never_alive", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::editor_discovery::tests::select_for_path_ignores_stale_editors_and_sibling_prefixes", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::editor_discovery::tests::select_for_path_prefers_deepest_live_project", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::endpoint::tests::active_instance_keeps_priority_over_lockfile_discovery", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::endpoint::tests::cli_override_wins_over_active_instance", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::endpoint::tests::cwd_inside_project_selects_that_editor", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::endpoint::tests::cwd_outside_projects_with_two_editors_is_ambiguous", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::endpoint::tests::env_port_wins_when_no_cli_override", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::endpoint::tests::explicit_port_wins_over_project_path_and_lockfiles", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::endpoint::tests::no_lockfiles_keeps_legacy_default", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::endpoint::tests::project_command_targets_its_own_editor_among_several", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::endpoint::tests::project_command_without_its_editor_uses_default_endpoint", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::endpoint::tests::project_path_selects_matching_editor", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::endpoint::tests::project_path_without_running_editor_is_not_found", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::endpoint::tests::project_root_env_falls_back_to_default_without_any_lockfile", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::endpoint::tests::single_running_editor_is_used_from_anywhere", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::endpoint::tests::stale_editors_do_not_cause_ambiguity", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::endpoint::tests::unity_project_root_env_acts_as_project_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::failure::tests::failed_batch_preserves_first_failure_message_and_all_results", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::instances::tests::authenticated_health_checks_support_listing_and_selection", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::instances::tests::list_instances_adds_default_port_when_no_entries_exist", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::instances::tests::list_instances_enumerates_lockfiles_without_ports", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::instances::tests::list_instances_keeps_explicit_ports_next_to_lockfiles", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::instances::tests::list_instances_reports_down_for_tcp_listener_that_is_not_unity_bridge", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::instances::tests::list_instances_reports_up_for_reachable_port", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::instances::tests::load_registry_reconstructs_missing_ids", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::instances::tests::parse_id_validates_shape", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::instances::tests::registry_path_uses_env_and_creates_parent_directory", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::instances::tests::registry_round_trip_serialization_shape_is_supported", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::instances::tests::set_active_fails_for_unreachable_instance", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::instances::tests::set_active_succeeds_for_reachable_instance_and_tracks_previous", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::cache_root_falls_back_to_home_unity_cache", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::cache_root_prefers_unity_cli_cache_root_env", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::detect_rid_returns_known_target_triple", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::download_latest_binary_applies_matching_checksum", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::download_latest_binary_rejects_checksum_mismatch_and_keeps_existing_install", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::ensure_latest_for_can_skip_remote_checks_in_tests", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::ensure_local_uses_existing_binary_without_download", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::get_json_fails_with_status_and_body", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::get_json_parses_http_body", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::get_json_retries_transient_server_error", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::get_optional_text_returns_body_for_success", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::get_optional_text_returns_none_for_not_found", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::get_response_includes_authorization_header", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::get_response_reports_http_status_errors", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::parse_sha256sums_reads_text_and_binary_mode_entries", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::read_local_version_returns_none_for_missing_or_blank_file", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::replace_file_atomic_overwrites_destination", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::sha256_file_matches_known_hash", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::tools_root_falls_back_to_home_unity_tools_when_env_unset", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::tools_root_prefers_unity_cli_tools_root_env", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::unity_cli_status_uses_managed_install_layout", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::verify_manifest_against_checksums_requires_matching_entry", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::managed_binaries::tests::write_and_read_local_version_round_trip", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::runtime_paths::tests::daemon_dir_is_under_run_root", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::self_update::tests::is_recent_returns_false_for_missing_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::self_update::tests::is_recent_returns_true_for_freshly_touched_file", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::self_update::tests::last_check_path_uses_unity_cli_tools_root_env", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::self_update::tests::maybe_self_update_skipped_when_opt_out_env_set", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::self_update::tests::maybe_self_update_skips_when_recent_check_exists", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::self_update::tests::touch_creates_parent_and_writes_marker", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "core::self_update::tests::warn_cargo_conflict_runs_without_panic", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::runtime::tests::runtime_module_builds_without_warnings_when_unix_code_is_disabled", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::spawn::tests::spawn_detached_starts_the_command", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::spawn::tests::spawn_module_builds_for_windows_without_warnings", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::spawn::tests::spawned_child_does_not_hold_the_callers_stdout_pipe", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::unityd::tests::daemon_call_error_classification", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::unityd::tests::daemon_request_batch_round_trip", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::unityd::tests::daemon_request_ping_round_trip", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::unityd::tests::daemon_request_status_round_trip", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::unityd::tests::daemon_request_stop_round_trip", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::unityd::tests::daemon_request_tool_round_trip", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::unityd::tests::daemon_response_error_round_trip", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::unityd::tests::daemon_response_round_trip", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::unityd::tests::daemon_response_round_trip_preserves_timing", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::unityd::tests::idle_timeout_default", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::unityd::tests::pid_file_path_is_under_tools_dir", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::unityd::tests::pooled_connection_closed_by_editor_restart_is_reconnected_before_sending", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::unityd::tests::pooled_connection_uses_each_requests_timeout", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::unityd::tests::request_lost_after_sending_is_reported_and_not_resent", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::unityd::tests::startup_lock_times_out_and_is_reusable_after_release", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "daemon::unityd::tests::tools_dir_creates_directory", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::client::tests::collect_document_symbols_flattens_nested_symbols", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::client::tests::get_apply_defaults_to_false", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::client::tests::id_matches_accepts_number_and_string_id", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::client::tests::kind_from_lsp_maps_known_values", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::client::tests::normalize_lsp_write_result_adds_contract_fields", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::client::tests::normalize_rel_path_accepts_assets_packages_and_library", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::client::tests::normalize_rel_path_extracts_supported_prefix_from_absolute_like_input", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::client::tests::normalize_rel_path_rejects_parent_traversal", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::client::tests::path_matches_scope_filters_paths", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::client::tests::remove_symbol_request_includes_fail_on_references_when_set", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::client::tests::remove_symbol_request_omits_fail_on_references_when_unset", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::client::tests::require_helpers_validate_expected_fields", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::client::tests::retryable_session_error_detects_transport_failures", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::client::tests::retryable_session_error_ignores_argument_errors", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::client::tests::to_project_relative_or_raw_returns_relative_for_absolute_under_root", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::client::tests::uri_and_ref_path_helpers_resolve_project_relative_paths", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::client::tests::uri_to_rel_path_rejects_non_file_uris", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::daemon::tests::daemon_idle_timeout_uses_env_override", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::daemon::tests::handle_request_handles_ping_status_and_stop", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::daemon::tests::is_would_block_checks_error_kind", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::daemon::tests::write_all_with_retry_handles_would_block_and_partial_writes", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::daemon::tests::write_all_with_retry_rejects_zero_byte_progress", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "lsp::daemon::tests::write_pid_file_and_cleanup_manage_files_under_tools_root", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "mcp::configure::tests::custom_root_may_have_missing_ancestors_without_creating_them", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "mcp::configure::tests::invalid_config_is_never_overwritten_and_preview_creates_nothing", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "mcp::configure::tests::malformed_shapes_and_http_name_collisions_are_rejected", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "mcp::configure::tests::merges_inline_toml_without_losing_other_servers_or_options", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "mcp::configure::tests::windows_and_local_paths", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "mcp::tests::projects_owned_custom_descriptor_without_an_mcp_specific_schema", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::cache::tests::gc_empty_root_returns_empty", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::cache::tests::gc_keep_zero_removes_all_versions", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::cache::tests::gc_keeps_n_newest_and_returns_removed", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::cache::tests::gc_skips_non_directory_entries", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::cache::tests::list_versions_empty_when_root_missing", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::cache::tests::list_versions_returns_existing_dirs", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::cache::tests::list_versions_skips_files_in_root", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::cache::tests::meta_roundtrip", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::cache::tests::read_meta_returns_error_for_invalid_json", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::cache::tests::read_meta_returns_error_when_missing", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::cache::tests::version_dir_rejects_empty", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::cache::tests::version_dir_rejects_paths_outside_single_cache_entry", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::cache::tests::version_dir_under_cache_root", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::diff::tests::compute_line_diff_empty_for_identical_lines", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::diff::tests::compute_line_diff_for_deletes_only_returns_removal_hunk", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::diff::tests::compute_line_diff_for_inserts_only_returns_addition_hunk", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::diff::tests::compute_line_diff_for_separate_changes_produces_multiple_hunks", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::diff::tests::compute_line_diff_replacement_isolates_changed_lines", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::diff::tests::compute_path_diff_can_be_truncated", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::diff::tests::compute_path_diff_categorises_runtime_export", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::diff::tests::compute_symbol_diff_detects_changed_animator", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::diff::tests::compute_symbol_diff_returns_diff_when_only_one_side_has_symbol", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::diff::tests::compute_symbol_diff_returns_none_for_missing_in_both", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::diff::tests::ensure_cache_dir_errors_on_missing", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::diff::tests::split_fqn_separates_namespace_and_name", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::embed::tests::build_embedding_index_handles_empty_symbol_index", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::embed::tests::build_embedding_index_with_mock_embedder", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::embed::tests::cosine_similarity_handles_zero_vectors", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::embed::tests::embedding_roundtrip_via_bincode", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::embed::tests::resolve_onnxruntime_dylib_explains_how_to_install_when_missing", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::embed::tests::resolve_onnxruntime_dylib_falls_back_to_first_existing_candidate", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::embed::tests::resolve_onnxruntime_dylib_prefers_existing_env_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::embed::tests::resolve_onnxruntime_dylib_rejects_missing_env_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::embed::tests::search_ranks_by_cosine_similarity", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::embed::tests::search_returns_empty_for_empty_index", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::embed::tests::search_returns_empty_for_empty_query", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::embed::tests::symbol_to_text_includes_namespace_and_kind", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::embed::tests::symbol_to_text_without_namespace_omits_dot", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::api_discovery_paginates_branches_and_includes_tags", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::api_discovery_surfaces_http_errors", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::archive_url_uses_unity_cs_reference_org", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::build_clone_args_emits_shallow_single_branch", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::ensure_git_available_succeeds_in_test_env", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::extract_zip_to_rejects_entries_with_parent_segments", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::extract_zip_to_strips_top_level_prefix_and_writes_files", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::fetch_selected_checks_out_long_windows_paths_without_global_configuration", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::fetch_selected_pins_commit_after_branch_advances", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::fetch_selected_rejects_invalid_commit_before_creating_destination", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::github_token_returns_none_when_env_unset", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::github_token_skips_empty_and_picks_first_non_empty", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::license_ok_when_env_set", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::license_ok_when_flag_true", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::license_rejects_zero_value", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::license_required_when_flag_false_and_env_unset", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::list_public_refs_discovers_branches_and_tags", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::list_public_refs_preserves_transport_error", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::public_refs_use_basic_authentication_for_git_http", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::fetcher::tests::run_clone_rejects_when_license_not_accepted", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::index::tests::build_or_update_index_handles_existing_fixture", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::index::tests::build_or_update_index_persists_signature", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::index::tests::build_or_update_index_skips_already_indexed_files_until_change", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::index::tests::extract_symbols_from_text_captures_namespace", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::index::tests::extract_symbols_from_text_does_not_double_capture_class_name", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::index::tests::extract_symbols_from_text_finds_class", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::index::tests::extract_symbols_from_text_finds_methods", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::index::tests::extract_symbols_from_text_finds_property", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::index::tests::extract_symbols_from_text_finds_struct_and_interface", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::index::tests::file_signature_changes_when_content_changes", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::index::tests::find_symbol_filters_by_kind_and_namespace", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::index::tests::validate_kind_accepts_known_and_rejects_unknown", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::search::tests::grep_filters_by_filename_glob", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::search::tests::grep_finds_class_animator_with_line_numbers", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::search::tests::grep_returns_context_lines", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::search::tests::view_rejects_parent_traversal", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::search::tests::view_returns_requested_line_range", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::cached_fetch_and_status_report_stored_provenance", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::cached_unknown_version_can_be_used_without_branch_resolution", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::dir_size_empty_returns_zero", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::dir_size_sums_file_lengths", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_clean_dry_run_false_actually_removes", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_clean_dry_run_on_empty_cache_returns_empty_removed", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_diff_errors_when_cache_missing", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_diff_path_mode_returns_added_removed_changed", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_diff_requires_from_and_to", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_diff_requires_symbol_or_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_diff_symbol_mode_returns_diffs", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_embed_build_errors_when_cache_missing", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_embed_search_errors_when_index_missing", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_embed_search_requires_query", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_fetch_force_preserves_existing_on_transport_failure", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_fetch_skips_when_destination_exists_without_force", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_find_symbol_empty_hits_for_unknown_name", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_find_symbol_filters_namespace", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_find_symbol_rejects_unknown_kind", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_find_symbol_requires_name", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_find_symbol_returns_error_when_cache_missing", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_find_symbol_returns_hits_from_fixture", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_grep_invalid_regex_returns_error", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_grep_requires_pattern", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_grep_supports_file_glob_filter", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_grep_via_dispatcher_returns_hits", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_resolve_symbol_at_empty_token_for_blank_position", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_resolve_symbol_at_finds_token_via_fixture", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_resolve_symbol_at_requires_path_line_column", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_resolve_symbol_at_requires_project_prefix", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_search_requires_pattern", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_search_via_dispatcher_truncates_max_results", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_search_without_max_results_returns_all_hits", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_status_includes_size_bytes", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_status_returns_versions_list", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_view_rejects_parent_traversal_via_dispatcher", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_view_requires_path_param", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::execute_view_via_dispatcher_returns_lines", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::extract_token_at_cursor_handles_edge_cases", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::extract_token_at_cursor_handles_escaped_quote_in_string", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::extract_token_at_cursor_returns_ident_after_closed_string", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::extract_token_at_cursor_skips_line_comment", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::extract_token_at_cursor_skips_string_literal", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::fetch_resolves_project_and_explicit_refs_and_records_actual_commit", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::legacy_metadata_keeps_unknown_match_instead_of_claiming_exact", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::maybe_execute_returns_none_for_unknown_tool", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::now_unix_seconds_string_is_decimal", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::resolve_version_falls_back_to_project_detection", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::tests::resolve_version_uses_explicit_param", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::version::tests::ambiguous_auto_candidates_and_unknown_versions_return_candidates", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::version::tests::detect_returns_error_when_editor_version_line_absent", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::version::tests::detect_returns_error_when_editor_version_value_empty", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::version::tests::detect_returns_error_when_project_version_missing", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::version::tests::exact_tag_precedes_minor_but_version_named_head_is_not_exact", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::version::tests::explicit_ref_has_priority_and_ambiguous_short_names_require_full_ref", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::version::tests::minor_version_key_rejects_invalid_inputs", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::version::tests::parse_editor_version_returns_value_directly", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::version::tests::parses_remote_refs_with_peeled_tag_commits_in_any_order", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::version::tests::public_resolver_handles_previously_supported_minors", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::version::tests::reads_known_project_version", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::version::tests::reads_unknown_minor_without_static_mapping", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "reference::version::tests::selects_new_and_existing_minor_branches_without_claiming_exact_match", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::loader::tests::load_skills_handles_missing_root_and_skips_non_skill_entries", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::loader::tests::load_skills_supports_single_skill_root_and_dir_name_fallback", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::loader::tests::parse_frontmatter_and_collect_references_cover_optional_branches", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::loader::tests::parse_frontmatter_extracts_metadata", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::loader::tests::split_frontmatter_and_parse_frontmatter_cover_edge_cases", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::loader::tests::split_frontmatter_handles_basic_skill", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::good_skill_passes_all_rules", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::model_helpers_cover_skill_accessors_and_tool_sets", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r01_missing_description_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r01_missing_multiple_required_fields_fire", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r02_name_mismatch_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r03_disallowed_tool_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r03_legacy_bare_bash_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r04_unknown_category_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r05_empty_and_duplicate_triggers_fire", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r05_uppercase_trigger_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r06_unknown_sibling_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r07_too_long_description_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r08_missing_front_trigger_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r09_first_person_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r10_missing_use_when_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r11_missing_sibling_mention_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r12_unidirectional_sibling_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r13_too_long_body_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r14_missing_heading_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r15_references_without_link_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r16_time_sensitive_phrase_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r17_missing_runtime_checklist_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r18_long_reference_without_toc_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r19_reference_link_to_reference_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r20_and_r21_validate_windows_git_symlink_placeholders", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::r22_collision_without_cross_listing_fires", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "skills::tests::report_and_runner_cover_text_json_discovery_and_error_paths", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "test_env::isolated_runtime_restores_inherited_environment_after_unwind", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::discovery::tests::bridge_reserved_names_match_the_cli_catalog_including_local_tools", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::discovery::tests::builtin_descriptors_keep_schemas_and_mark_their_source", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::discovery::tests::custom_descriptor_roundtrips_owned_names_and_schema", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::discovery::tests::list_tools_is_a_read_only_remote_builtin", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::build_index_and_find_symbol_roundtrip", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::collect_cs_files_and_index_helpers_cover_readiness_branches", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::create_class_generates_simple_class", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::create_class_rejects_existing_file", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::create_class_rejects_invalid_name", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::create_class_with_namespace_and_inherits", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::default_runtime_config_falls_back_to_ipv4_loopback", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::extract_symbols_from_text_covers_major_symbol_kinds", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::find_refs_supports_cursor_paging", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::find_symbol_returns_index_not_ready_before_build", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::get_symbols_extracts_class_and_method", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::helper_comment_and_snippet_processing_works", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::helper_path_normalization_and_resolution_cover_edge_cases", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::helper_symbol_and_scope_predicates_work", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::list_packages_lists_package_dirs", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::lsp_write_tools_require_lsp_mode", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::post_write_refresh_failure_preserves_applied_files_without_runtime_panic", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::read_returns_file_slice", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::requires_unityengine_using_only_for_monobehaviour", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::search_finds_matching_lines", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::local_tools::tests::update_index_refreshes_symbol_names", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::os_capture::tests::capture_fails_when_no_candidate_exists", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::os_capture::tests::detects_daemon_stringified_timeouts", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::os_capture::tests::disabled_fallback_returns_the_timeout_error", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::os_capture::tests::failed_os_capture_keeps_both_errors", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::os_capture::tests::fallback_flag_defaults_on_and_is_stripped", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::os_capture::tests::non_timeout_errors_are_not_recovered", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::os_capture::tests::output_path_follows_bridge_capture_directory", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::os_capture::tests::timeout_is_recovered_with_os_fallback_marker", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::os_capture::tests::verbatim_prefix_is_dropped_before_the_path_reaches_os_tools", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::action_enum_schemas_use_composite_variants", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::addressables_analyze_schema_uses_action_specific_variants", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::addressables_manage_schema_has_manage_actions", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::all_tools_e2e_covers_catalog_or_documents_exclusion", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::analyze_asset_dependencies_schema_has_expected_actions", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::animation_curve_tools_advertise_strict_unity_contracts", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::baking_tools_have_explicit_target_and_polling_contracts", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::build_index_schema_allows_output_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::build_player_schema_requires_explicit_safe_build_inputs", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::capture_video_start_schema_restricts_mode_and_format", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::clear_logs_schema_is_strict_empty_object", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::create_animation_clip_schema_requires_clip_and_sprite_paths", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::create_animator_controller_schema_is_strict_and_nested", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::create_prefab_schema_allows_template_mode_without_source_object", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::create_sprite_atlas_schema_is_strict_and_nested", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::csharp_file_write_schemas_are_local_and_strict", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::delete_gameobject_schema_uses_any_of_targets", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::execute_menu_item_schema_supports_default_and_action_variants", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::get_build_status_is_read_only_and_requires_build_id", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::get_gameobject_details_schema_uses_any_of_identifiers", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::get_index_status_schema_is_strict_empty_object", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::hot_reload_tools_expose_explicit_preview_and_recovery_contract", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::input_keyboard_schema_uses_any_of_for_action_or_actions", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::known_tool_lookup_works", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::load_scene_schema_uses_one_of_identifier_variants", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::local_executor_tools_are_marked", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::manage_asset_database_schema_uses_action_specific_variants", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::manage_layers_schema_requires_action_enum", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::modify_gameobject_schema_requires_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::package_manager_schema_has_required_action", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::ping_schema_is_strict_object", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::prefab_override_tools_have_strict_discoverable_schemas", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::quit_editor_exposes_optional_scene_protection_parameter", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::remote_tools_have_unity_bridge_dispatch_cases", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::rename_symbol_schema_is_strict_and_requires_name_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::run_tests_schema_allows_test_mode_enum", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::set_component_field_schema_requires_component_and_field", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::timeline_schema_exposes_actions_and_stale_clip_guard", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::timeline_tools_are_discoverable_with_correct_mutation_flags", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::tool_catalog_avoids_default_params_schema_for_known_tools", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::tool_catalog_keeps_manifest_parity_count", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::tool_specs_cover_catalog", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::tools_doc_matches_registered_catalog", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::vfx_apply_is_mutating_and_requires_op", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::vfx_describe_graph_is_read_only_and_requires_asset_path", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::vfx_runtime_is_mutating_and_requires_op_and_game_object", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_catalog::tests::vfx_settings_is_mutating_and_requires_op", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_index::tests::category_accepts_heading_or_slug", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_index::tests::every_tool_has_exactly_one_index_entry_with_a_short_summary", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_index::tests::query_matches_name_or_summary_case_insensitively", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_index::tests::tool_index_matches_docs_headings", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "tooling::tool_index::tests::unknown_category_lists_valid_slugs", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "unity::auth::tests::credentials_are_endpoint_scoped_and_absent_from_discovery_output", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "unity::auth::tests::explicit_mounted_lockfile_and_invalid_file_errors_do_not_expose_token", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "unity::auth::tests::only_exact_one_enables_legacy_opt_out", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "unity::transport::tests::call_tool_returns_error_on_failure_response", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "unity::transport::tests::call_tool_returns_result_on_success", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "unity::transport::tests::call_tool_with_timing_reports_non_negative_durations", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "unity::transport::tests::every_request_carries_token_from_private_lockfile", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "unity::transport::tests::normalize_failure_preserves_complete_error_envelope", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "unity::transport::tests::normalize_response_handles_success_and_error_shapes", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "unity::transport::tests::parse_embedded_json_keeps_plain_strings", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "unity::transport::tests::parse_json_accepts_trimmed_json", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "unity::transport::tests::parse_json_rejects_empty_and_non_utf8_payload", + "result": "ok" + }, + { + "suite": "unittests src\\main.rs", + "name": "unity::transport::tests::ping_backfills_bridge_version_from_editor_state_envelope", + "result": "ok" + }, + { + "suite": "tests\\auth_warning.rs", + "name": "legacy_opt_out_warns_on_stderr_only_for_exact_one", + "result": "ok" + }, + { + "suite": "tests\\bridge_package_dependencies.rs", + "name": "bridge_declares_ugui_when_sources_use_it", + "result": "ok" + }, + { + "suite": "tests\\build_failure_output.rs", + "name": "failed_build_status_keeps_json_report_and_nonzero_exit", + "result": "ok" + }, + { + "suite": "tests\\custom_tools.rs", + "name": "batch_validates_all_custom_arguments_before_any_side_effect", + "result": "ok" + }, + { + "suite": "tests\\custom_tools.rs", + "name": "custom_method_is_not_retried_after_lost_response", + "result": "ok" + }, + { + "suite": "tests\\custom_tools.rs", + "name": "custom_numeric_ranges_and_nullable_defaults_are_validated_before_execution", + "result": "ok" + }, + { + "suite": "tests\\custom_tools.rs", + "name": "discovery_merges_schemas_and_sources_and_filters_custom_tools", + "result": "ok" + }, + { + "suite": "tests\\custom_tools.rs", + "name": "discovery_rejects_conflicting_or_malformed_editor_catalogs", + "result": "ok" + }, + { + "suite": "tests\\custom_tools.rs", + "name": "dry_run_and_unknown_tools_never_invoke_a_custom_method", + "result": "ok" + }, + { + "suite": "tests\\custom_tools.rs", + "name": "invalid_custom_arguments_never_reach_the_method", + "result": "ok" + }, + { + "suite": "tests\\custom_tools.rs", + "name": "names_only_and_compact_preserve_small_list_shapes", + "result": "ok" + }, + { + "suite": "tests\\custom_tools.rs", + "name": "old_bridges_keep_the_builtin_catalog_but_auth_errors_are_visible", + "result": "ok" + }, + { + "suite": "tests\\custom_tools.rs", + "name": "schema_and_all_call_spellings_support_custom_names", + "result": "ok" + }, + { + "suite": "tests\\editor_lifecycle.rs", + "name": "close_requires_bridge_scene_protection_before_sending_quit", + "result": "ok" + }, + { + "suite": "tests\\editor_lifecycle.rs", + "name": "editor_lifecycle_commands_are_available", + "result": "ok" + }, + { + "suite": "tests\\editor_lifecycle.rs", + "name": "missing_editor_explains_official_install_and_returns_precondition", + "result": "ok" + }, + { + "suite": "tests\\editor_lifecycle.rs", + "name": "status_reports_compilation_from_the_selected_project", + "result": "ok" + }, + { + "suite": "tests\\json_envelope.rs", + "name": "batch_with_failed_operation_does_not_exit_zero", + "result": "ok" + }, + { + "suite": "tests\\json_envelope.rs", + "name": "bridge_errors_preserve_codes_and_authentication_exit", + "result": "ok" + }, + { + "suite": "tests\\json_envelope.rs", + "name": "bridge_warnings_reach_the_public_envelope", + "result": "ok" + }, + { + "suite": "tests\\json_envelope.rs", + "name": "clap_usage_error_has_json_envelope", + "result": "ok" + }, + { + "suite": "tests\\json_envelope.rs", + "name": "direct_authentication_and_bridge_failures_match_daemon", + "result": "ok" + }, + { + "suite": "tests\\json_envelope.rs", + "name": "invalid_batch_is_usage_error", + "result": "ok" + }, + { + "suite": "tests\\json_envelope.rs", + "name": "invalid_json_is_usage_error", + "result": "ok" + }, + { + "suite": "tests\\json_envelope.rs", + "name": "invalid_port_list_is_usage_error", + "result": "ok" + }, + { + "suite": "tests\\json_envelope.rs", + "name": "invalid_tool_routes_are_usage_errors", + "result": "ok" + }, + { + "suite": "tests\\json_envelope.rs", + "name": "local_success_uses_single_envelope", + "result": "ok" + }, + { + "suite": "tests\\json_envelope.rs", + "name": "nested_bridge_failure_is_not_reported_as_success", + "result": "ok" + }, + { + "suite": "tests\\json_envelope.rs", + "name": "response_timeout_is_retryable_operation_failure", + "result": "ok" + }, + { + "suite": "tests\\json_envelope.rs", + "name": "skills_show_and_lint_use_envelopes", + "result": "ok" + }, + { + "suite": "tests\\json_envelope.rs", + "name": "test_completion_distinguishes_failed_and_passed", + "result": "ok" + }, + { + "suite": "tests\\json_envelope.rs", + "name": "unreachable_editor_is_exit_seven", + "result": "ok" + }, + { + "suite": "tests\\mcp.rs", + "name": "configure_all_clients_preserves_other_servers_and_dry_run", + "result": "ok" + }, + { + "suite": "tests\\mcp.rs", + "name": "malformed_requests_do_not_end_session_or_execute_tools_before_initialization", + "result": "ok" + }, + { + "suite": "tests\\mcp.rs", + "name": "stdio_catalog_and_failure_contract_without_editor", + "result": "ok" + }, + { + "suite": "tests\\mcp_dynamic.rs", + "name": "custom_catalog_calls_and_live_removal_share_cli_discovery_and_validation", + "result": "ok" + }, + { + "suite": "tests\\setup_dry_run.rs", + "name": "setup_dry_run_prints_plan_without_connections_writes_or_launches", + "result": "ok" + }, + { + "suite": "tests\\setup_dry_run.rs", + "name": "setup_launch_returns_output_while_editor_is_still_running", + "result": "ok" + }, + { + "suite": "tests\\skills_install.rs", + "name": "all_clients_install_embedded_references_and_show_works_outside_repository", + "result": "ok" + }, + { + "suite": "tests\\skills_install.rs", + "name": "dry_run_prints_only_paths_without_creating_files", + "result": "ok" + }, + { + "suite": "tests\\skills_install.rs", + "name": "global_dry_run_flag_also_prevents_installation", + "result": "ok" + }, + { + "suite": "tests\\skills_install.rs", + "name": "install_protects_unowned_directory_and_force_keeps_unrelated_files", + "result": "ok" + }, + { + "suite": "tests\\skills_install.rs", + "name": "invalid_ledger_paths_are_rejected_even_with_force", + "result": "ok" + }, + { + "suite": "tests\\skills_install.rs", + "name": "refresh_does_not_install_clients_without_a_ledger", + "result": "ok" + }, + { + "suite": "tests\\skills_install.rs", + "name": "refresh_syncs_an_older_owned_version_and_protects_local_edits", + "result": "ok" + }, + { + "suite": "tests\\tool_list_filters.rs", + "name": "category_returns_only_that_docs_section", + "result": "ok" + }, + { + "suite": "tests\\tool_list_filters.rs", + "name": "compact_is_name_and_description_only_and_at_most_half_of_full_catalog", + "result": "ok" + }, + { + "suite": "tests\\tool_list_filters.rs", + "name": "limit_and_offset_page_the_filtered_list", + "result": "ok" + }, + { + "suite": "tests\\tool_list_filters.rs", + "name": "offline_default_list_has_schemas_and_names_only_is_compatible", + "result": "ok" + }, + { + "suite": "tests\\tool_list_filters.rs", + "name": "query_returns_only_matching_tools", + "result": "ok" + }, + { + "suite": "tests\\tool_list_filters.rs", + "name": "unknown_category_is_rejected", + "result": "ok" + }, + { + "suite": "tests\\tool_list_filters.rs", + "name": "unopened_project_still_exposes_the_offline_builtin_catalog", + "result": "ok" + } + ] +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/clippy-all-features-final.txt b/docs/verification/issue-386/resume/clippy-all-features-final.txt new file mode 100644 index 00000000..cecc522b --- /dev/null +++ b/docs/verification/issue-386/resume/clippy-all-features-final.txt @@ -0,0 +1 @@ + Finished `dev` profile [unoptimized + debuginfo] target(s) in 4.77s diff --git a/docs/verification/issue-386/resume/clippy.txt b/docs/verification/issue-386/resume/clippy.txt new file mode 100644 index 00000000..40132944 --- /dev/null +++ b/docs/verification/issue-386/resume/clippy.txt @@ -0,0 +1,2 @@ + Checking unity-cli v0.18.1 () + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.80s diff --git a/docs/verification/issue-386/resume/comparison-historical-linux.txt b/docs/verification/issue-386/resume/comparison-historical-linux.txt new file mode 100644 index 00000000..d478dc5e --- /dev/null +++ b/docs/verification/issue-386/resume/comparison-historical-linux.txt @@ -0,0 +1,10 @@ +test_all_readmes_link_comparison_and_relative_sources_exist (test_comparison_evidence.ComparisonEvidenceTests.test_all_readmes_link_comparison_and_relative_sources_exist) ... ok +test_document_tables_match_each_published_measurement (test_comparison_evidence.ComparisonEvidenceTests.test_document_tables_match_each_published_measurement) ... ok +test_each_feature_row_has_sources_in_both_languages (test_comparison_evidence.ComparisonEvidenceTests.test_each_feature_row_has_sources_in_both_languages) ... ok +test_four_runs_have_complete_raw_samples_and_correct_percentiles (test_comparison_evidence.ComparisonEvidenceTests.test_four_runs_have_complete_raw_samples_and_correct_percentiles) ... ok +test_identical_versions_and_script_and_quiet_host_are_recorded (test_comparison_evidence.ComparisonEvidenceTests.test_identical_versions_and_script_and_quiet_host_are_recorded) ... ok + +---------------------------------------------------------------------- +Ran 5 tests in 0.415s + +OK diff --git a/docs/verification/issue-386/resume/comparison-unit-linux.txt b/docs/verification/issue-386/resume/comparison-unit-linux.txt new file mode 100644 index 00000000..ccfad5af --- /dev/null +++ b/docs/verification/issue-386/resume/comparison-unit-linux.txt @@ -0,0 +1,20 @@ +test_benchmark_does_not_reuse_another_projects_daemon_or_host (test_compare_official.CompareTests.test_benchmark_does_not_reuse_another_projects_daemon_or_host) ... ok +test_coexistence_rejects_a_different_editor_version (test_compare_official.CompareTests.test_coexistence_rejects_a_different_editor_version) ... ok +test_coexistence_rejects_a_different_project (test_compare_official.CompareTests.test_coexistence_rejects_a_different_project) ... ok +test_empty_read_and_unapplied_material_are_not_success (test_compare_official.CompareTests.test_empty_read_and_unapplied_material_are_not_success) ... ok +test_eval_must_report_completed (test_compare_official.CompareTests.test_eval_must_report_completed) ... ok +test_failed_create_is_not_a_measurement (test_compare_official.CompareTests.test_failed_create_is_not_a_measurement) ... ok +test_official_nested_failure_is_rejected (test_compare_official.CompareTests.test_official_nested_failure_is_rejected) ... ok +test_process_checks_accept_the_shared_cli_envelope (test_compare_official.CompareTests.test_process_checks_accept_the_shared_cli_envelope) ... ok +test_read_uses_same_asset_within_official_authoring_root (test_compare_official.CompareTests.test_read_uses_same_asset_within_official_authoring_root) ... ok +test_resident_operations_match_all_23_staff_operations (test_compare_official.CompareTests.test_resident_operations_match_all_23_staff_operations) ... ok +test_shell_rejects_in_band_failure (test_compare_official.CompareTests.test_shell_rejects_in_band_failure) ... ok +test_shell_rejects_mismatched_id (test_compare_official.CompareTests.test_shell_rejects_mismatched_id) ... ok +test_shell_reuses_process_and_correlates_responses (test_compare_official.CompareTests.test_shell_reuses_process_and_correlates_responses) ... ok +test_shell_timeout_is_bounded (test_compare_official.CompareTests.test_shell_timeout_is_bounded) ... ok +test_transition_waits_for_completed_state (test_compare_official.CompareTests.test_transition_waits_for_completed_state) ... ok + +---------------------------------------------------------------------- +Ran 15 tests in 0.948s + +OK diff --git a/docs/verification/issue-386/resume/derived-lib-error.txt b/docs/verification/issue-386/resume/derived-lib-error.txt new file mode 100644 index 00000000..7a9388c1 --- /dev/null +++ b/docs/verification/issue-386/resume/derived-lib-error.txt @@ -0,0 +1 @@ +error: no library targets found in package `unity-cli` diff --git a/docs/verification/issue-386/resume/derived-lib-final.json b/docs/verification/issue-386/resume/derived-lib-final.json new file mode 100644 index 00000000..1687142b --- /dev/null +++ b/docs/verification/issue-386/resume/derived-lib-final.json @@ -0,0 +1,18 @@ +{ + "argv": [ + "cargo", + "test", + "--workspace", + "--lib", + "--all-features", + "--", + "--test-threads=1" + ], + "started_at": "2026-10-04T00:59:42.307486+00:00", + "source_commit": "d0c5ce21d85d171b285162b06edff03acdef53c9", + "canonical": false, + "exit_code": 101, + "finished_at": "2026-10-04T00:59:43.857498+00:00", + "stdout": "", + "stderr": "error: no library targets found in package `unity-cli`\n" +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/derived-plan-final.json b/docs/verification/issue-386/resume/derived-plan-final.json new file mode 100644 index 00000000..78299429 --- /dev/null +++ b/docs/verification/issue-386/resume/derived-plan-final.json @@ -0,0 +1 @@ +{"exit_code":0,"ok":true,"operation":"verify.plan","output":"verify: derived matrix from changed surfaces [rust(workspace), other, docs(6)]\n - cargo fmt --all -- --check\n - cargo clippy --workspace --all-targets --all-features -- -D warnings\n - RUSTDOCFLAGS=\"-D warnings\" cargo doc --workspace --no-deps --document-private-items\n - cargo test --workspace --lib --all-features -- --test-threads=1\n - bunx markdownlint-cli2 \"docs/comparison.md\" \"docs/hot-reload.md\" \"docs/verification/issue-386/README.md\" \"docs/verification/issue-386/resume/README.md\" \"docs/verification/issue-386/resume/staff-scope-reconstruction.md\" \"packaging/winget/README.md\"\nverify: plan registered — 5 command(s) for session 58337a13-2327-417b-b9f2-9b4b847857c4 (owner #386, derived)\n"} diff --git a/docs/verification/issue-386/resume/domain-reload.json b/docs/verification/issue-386/resume/domain-reload.json new file mode 100644 index 00000000..21d54f7e --- /dev/null +++ b/docs/verification/issue-386/resume/domain-reload.json @@ -0,0 +1,347 @@ +{ + "cases": [ + { + "domainReloadEnabled": true, + "settings": { + "assetNamingUsesSpace": true, + "defaultBehaviorMode": "Mode3D", + "enterPlayModeOptions": "None", + "enterPlayModeOptionsEnabled": false, + "prefabModeRegularEnvironment": "None", + "prefabModeUIEnvironment": "None", + "serializationMode": "ForceText", + "unityRemote": "", + "unityRemoteCompression": "", + "unityRemoteResolution": "" + }, + "runId": "85eea27b-fe0d-40b6-ae10-d2c7b829cdeb", + "status": "pass", + "passed": 2, + "failed": 0, + "result": { + "failedTests": 0, + "failures": [], + "inconclusiveTests": 0, + "latestResult": { + "fileContent": "{\r\n \"generatedAt\": \"2026-10-03T21:25:37.6564561Z\",\r\n \"runStartedAt\": \"2026-10-03T21:25:37.4176270Z\",\r\n \"durationSeconds\": 0.1734297,\r\n \"testMode\": \"PlayMode\",\r\n \"totalTests\": 2,\r\n \"passed\": 2,\r\n \"failed\": 0,\r\n \"skipped\": 0,\r\n \"inconclusive\": 0,\r\n \"status\": \"passed\",\r\n \"failures\": [],\r\n \"tests\": [\r\n {\r\n \"name\": \"FrameAdvances\",\r\n \"fullName\": \"UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\",\r\n \"status\": \"Passed\",\r\n \"duration\": 0.0218017,\r\n \"message\": null,\r\n \"stackTrace\": null,\r\n \"output\": \"[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\\r\\n\"\r\n },\r\n {\r\n \"name\": \"RigidbodyFalls\",\r\n \"fullName\": \"UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\",\r\n \"status\": \"Passed\",\r\n \"duration\": 0.1025816,\r\n \"message\": null,\r\n \"stackTrace\": null,\r\n \"output\": \"[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\\r\\n\"\r\n }\r\n ]\r\n}", + "generatedAt": "2026-10-03T21:25:37.6671220Z", + "path": "\\.cache\\issue-386\\staff-project\\.unity\\test-results\\TestResults_PlayMode_20261003_212530.json", + "status": "available", + "summary": { + "durationSeconds": 0.1734297, + "failed": 0, + "failures": [], + "generatedAt": "2026-10-03T21:25:37.6564561Z", + "inconclusive": 0, + "passed": 2, + "runStartedAt": "2026-10-03T21:25:37.4176270Z", + "skipped": 0, + "status": "passed", + "testMode": "PlayMode", + "tests": [ + { + "duration": 0.0218017, + "fullName": "UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances", + "message": null, + "name": "FrameAdvances", + "output": "[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\r\n", + "stackTrace": null, + "status": "Passed" + }, + { + "duration": 0.1025816, + "fullName": "UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls", + "message": null, + "name": "RigidbodyFalls", + "output": "[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\r\n", + "stackTrace": null, + "status": "Passed" + } + ], + "totalTests": 2 + } + }, + "passedTests": 2, + "runId": "85eea27b-fe0d-40b6-ae10-d2c7b829cdeb", + "skippedTests": 0, + "status": "completed", + "success": true, + "testMode": "PlayMode", + "tests": [ + { + "duration": 0.0218017, + "fullName": "UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances", + "message": null, + "name": "FrameAdvances", + "output": "[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\r\n", + "status": "Passed" + }, + { + "duration": 0.1025816, + "fullName": "UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls", + "message": null, + "name": "RigidbodyFalls", + "output": "[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\r\n", + "status": "Passed" + } + ], + "totalTests": 2 + } + }, + { + "domainReloadEnabled": false, + "settings": { + "assetNamingUsesSpace": true, + "defaultBehaviorMode": "Mode3D", + "enterPlayModeOptions": "DisableDomainReload", + "enterPlayModeOptionsEnabled": true, + "prefabModeRegularEnvironment": "None", + "prefabModeUIEnvironment": "None", + "serializationMode": "ForceText", + "unityRemote": "", + "unityRemoteCompression": "", + "unityRemoteResolution": "" + }, + "runId": "707b27fd-ae6a-4eb0-8e9f-f41b8430ce07", + "status": "pass", + "passed": 2, + "failed": 0, + "result": { + "failedTests": 0, + "failures": [], + "inconclusiveTests": 0, + "latestResult": { + "fileContent": "{\r\n \"generatedAt\": \"2026-10-03T21:25:41.7656478Z\",\r\n \"runStartedAt\": \"2026-10-03T21:25:41.6407521Z\",\r\n \"durationSeconds\": 0.1093431,\r\n \"testMode\": \"PlayMode\",\r\n \"totalTests\": 2,\r\n \"passed\": 2,\r\n \"failed\": 0,\r\n \"skipped\": 0,\r\n \"inconclusive\": 0,\r\n \"status\": \"passed\",\r\n \"failures\": [],\r\n \"tests\": [\r\n {\r\n \"name\": \"FrameAdvances\",\r\n \"fullName\": \"UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\",\r\n \"status\": \"Passed\",\r\n \"duration\": 0.0044743,\r\n \"message\": null,\r\n \"stackTrace\": null,\r\n \"output\": \"[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\\r\\n\"\r\n },\r\n {\r\n \"name\": \"RigidbodyFalls\",\r\n \"fullName\": \"UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\",\r\n \"status\": \"Passed\",\r\n \"duration\": 0.08695,\r\n \"message\": null,\r\n \"stackTrace\": null,\r\n \"output\": \"[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\\r\\n\"\r\n }\r\n ]\r\n}", + "generatedAt": "2026-10-03T21:25:41.7661521Z", + "path": "\\.cache\\issue-386\\staff-project\\.unity\\test-results\\TestResults_PlayMode_20261003_212540.json", + "status": "available", + "summary": { + "durationSeconds": 0.1093431, + "failed": 0, + "failures": [], + "generatedAt": "2026-10-03T21:25:41.7656478Z", + "inconclusive": 0, + "passed": 2, + "runStartedAt": "2026-10-03T21:25:41.6407521Z", + "skipped": 0, + "status": "passed", + "testMode": "PlayMode", + "tests": [ + { + "duration": 0.0044743, + "fullName": "UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances", + "message": null, + "name": "FrameAdvances", + "output": "[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\r\n", + "stackTrace": null, + "status": "Passed" + }, + { + "duration": 0.08695, + "fullName": "UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls", + "message": null, + "name": "RigidbodyFalls", + "output": "[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\r\n", + "stackTrace": null, + "status": "Passed" + } + ], + "totalTests": 2 + } + }, + "passedTests": 2, + "runId": "707b27fd-ae6a-4eb0-8e9f-f41b8430ce07", + "skippedTests": 0, + "status": "completed", + "success": true, + "testMode": "PlayMode", + "tests": [ + { + "duration": 0.0044743, + "fullName": "UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances", + "message": null, + "name": "FrameAdvances", + "output": "[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\r\n", + "status": "Passed" + }, + { + "duration": 0.08695, + "fullName": "UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls", + "message": null, + "name": "RigidbodyFalls", + "output": "[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\r\n", + "status": "Passed" + } + ], + "totalTests": 2 + } + } + ], + "calls": [ + { + "tool": "ping", + "parameters": {}, + "returncode": 0, + "stdout": "{\"command\":\"raw ping\",\"data\":{\"bridgeVersion\":\"0.18.1\",\"echo\":null,\"message\":\"pong\",\"projectPath\":\"E:\\\\unity-cli\\\\work\\\\issue-386\\\\.cache\\\\issue-386\\\\staff-project\",\"supportsSafeClose\":true,\"timestamp\":\"2026-10-03T21:25:30.1959524Z\"},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "" + }, + { + "tool": "get_project_settings", + "parameters": { + "includePlayer": false, + "includeEditor": true + }, + "returncode": 0, + "stdout": "{\"command\":\"raw get_project_settings\",\"data\":{\"editor\":{\"assetNamingUsesSpace\":true,\"defaultBehaviorMode\":\"Mode3D\",\"enterPlayModeOptions\":\"DisableDomainReload\",\"enterPlayModeOptionsEnabled\":true,\"prefabModeRegularEnvironment\":\"None\",\"prefabModeUIEnvironment\":\"None\",\"serializationMode\":\"ForceText\",\"unityRemote\":\"\",\"unityRemoteCompression\":\"\",\"unityRemoteResolution\":\"\"}},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "" + }, + { + "tool": "execute_menu_item", + "parameters": { + "action": "execute", + "menuPath": "Tools/Unity CLI/Test Runner E2E/Enable Domain Reload" + }, + "returncode": 0, + "stdout": "{\"command\":\"raw execute_menu_item\",\"data\":{\"executed\":true,\"executionTime\":1,\"menuExists\":true,\"menuPath\":\"Tools/Unity CLI/Test Runner E2E/Enable Domain Reload\",\"message\":\"Menu item executed successfully\",\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "" + }, + { + "tool": "get_project_settings", + "parameters": { + "includePlayer": false, + "includeEditor": true + }, + "returncode": 0, + "stdout": "{\"command\":\"raw get_project_settings\",\"data\":{\"editor\":{\"assetNamingUsesSpace\":true,\"defaultBehaviorMode\":\"Mode3D\",\"enterPlayModeOptions\":\"None\",\"enterPlayModeOptionsEnabled\":false,\"prefabModeRegularEnvironment\":\"None\",\"prefabModeUIEnvironment\":\"None\",\"serializationMode\":\"ForceText\",\"unityRemote\":\"\",\"unityRemoteCompression\":\"\",\"unityRemoteResolution\":\"\"}},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "" + }, + { + "tool": "run_tests", + "parameters": { + "testMode": "PlayMode", + "filter": "DomainReloadResultTests", + "includeDetails": true + }, + "returncode": 0, + "stdout": "{\"command\":\"raw run_tests\",\"data\":{\"message\":\"Test execution started. Use get_test_status to check progress.\",\"runId\":\"85eea27b-fe0d-40b6-ae10-d2c7b829cdeb\",\"status\":\"running\"},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "" + }, + { + "tool": "get_test_status", + "parameters": { + "includeTestResults": true, + "includeFileContent": true + }, + "returncode": 0, + "stdout": "{\"command\":\"raw get_test_status\",\"data\":{\"elapsedSeconds\":6.8131452999999995,\"message\":\"Test execution in progress\",\"runId\":\"85eea27b-fe0d-40b6-ae10-d2c7b829cdeb\",\"source\":\"run_tests\",\"status\":\"running\",\"testMode\":\"PlayMode\"},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "" + }, + { + "tool": "get_test_status", + "parameters": { + "includeTestResults": true, + "includeFileContent": true + }, + "returncode": 0, + "stdout": "{\"command\":\"raw get_test_status\",\"data\":{\"failedTests\":0,\"failures\":[],\"inconclusiveTests\":0,\"latestResult\":{\"fileContent\":\"{\\r\\n \\\"generatedAt\\\": \\\"2026-10-03T21:25:37.6564561Z\\\",\\r\\n \\\"runStartedAt\\\": \\\"2026-10-03T21:25:37.4176270Z\\\",\\r\\n \\\"durationSeconds\\\": 0.1734297,\\r\\n \\\"testMode\\\": \\\"PlayMode\\\",\\r\\n \\\"totalTests\\\": 2,\\r\\n \\\"passed\\\": 2,\\r\\n \\\"failed\\\": 0,\\r\\n \\\"skipped\\\": 0,\\r\\n \\\"inconclusive\\\": 0,\\r\\n \\\"status\\\": \\\"passed\\\",\\r\\n \\\"failures\\\": [],\\r\\n \\\"tests\\\": [\\r\\n {\\r\\n \\\"name\\\": \\\"FrameAdvances\\\",\\r\\n \\\"fullName\\\": \\\"UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\\\",\\r\\n \\\"status\\\": \\\"Passed\\\",\\r\\n \\\"duration\\\": 0.0218017,\\r\\n \\\"message\\\": null,\\r\\n \\\"stackTrace\\\": null,\\r\\n \\\"output\\\": \\\"[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\\\\r\\\\n\\\"\\r\\n },\\r\\n {\\r\\n \\\"name\\\": \\\"RigidbodyFalls\\\",\\r\\n \\\"fullName\\\": \\\"UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\\\",\\r\\n \\\"status\\\": \\\"Passed\\\",\\r\\n \\\"duration\\\": 0.1025816,\\r\\n \\\"message\\\": null,\\r\\n \\\"stackTrace\\\": null,\\r\\n \\\"output\\\": \\\"[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\\\\r\\\\n\\\"\\r\\n }\\r\\n ]\\r\\n}\",\"generatedAt\":\"2026-10-03T21:25:37.6671220Z\",\"path\":\"E:\\\\unity-cli\\\\work\\\\issue-386\\\\.cache\\\\issue-386\\\\staff-project\\\\.unity\\\\test-results\\\\TestResults_PlayMode_20261003_212530.json\",\"status\":\"available\",\"summary\":{\"durationSeconds\":0.1734297,\"failed\":0,\"failures\":[],\"generatedAt\":\"2026-10-03T21:25:37.6564561Z\",\"inconclusive\":0,\"passed\":2,\"runStartedAt\":\"2026-10-03T21:25:37.4176270Z\",\"skipped\":0,\"status\":\"passed\",\"testMode\":\"PlayMode\",\"tests\":[{\"duration\":0.0218017,\"fullName\":\"UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\",\"message\":null,\"name\":\"FrameAdvances\",\"output\":\"[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\\r\\n\",\"stackTrace\":null,\"status\":\"Passed\"},{\"duration\":0.1025816,\"fullName\":\"UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\",\"message\":null,\"name\":\"RigidbodyFalls\",\"output\":\"[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\\r\\n\",\"stackTrace\":null,\"status\":\"Passed\"}],\"totalTests\":2}},\"passedTests\":2,\"runId\":\"85eea27b-fe0d-40b6-ae10-d2c7b829cdeb\",\"skippedTests\":0,\"status\":\"completed\",\"success\":true,\"testMode\":\"PlayMode\",\"tests\":[{\"duration\":0.0218017,\"fullName\":\"UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\",\"message\":null,\"name\":\"FrameAdvances\",\"output\":\"[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\\r\\n\",\"status\":\"Passed\"},{\"duration\":0.1025816,\"fullName\":\"UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\",\"message\":null,\"name\":\"RigidbodyFalls\",\"output\":\"[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\\r\\n\",\"status\":\"Passed\"}],\"totalTests\":2},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "" + }, + { + "tool": "get_editor_state", + "parameters": {}, + "returncode": 0, + "stdout": "{\"command\":\"raw get_editor_state\",\"data\":{\"state\":{\"applicationContentsPath\":\"C:/Program Files/Unity/Hub/Editor/6000.4.4f1/Editor/Data\",\"applicationPath\":\"C:/Program Files/Unity/Hub/Editor/6000.4.4f1/Editor/Unity.exe\",\"isCompiling\":false,\"isPaused\":false,\"isPlaying\":false,\"isUpdating\":false,\"playability\":{\"compilation\":null,\"lastPlayRequestTime\":null,\"playRequested\":false,\"reason\":\"ready\"},\"timeSinceStartup\":1278.6441159},\"status\":\"success\"},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "" + }, + { + "tool": "execute_menu_item", + "parameters": { + "action": "execute", + "menuPath": "Tools/Unity CLI/Test Runner E2E/Disable Domain Reload" + }, + "returncode": 0, + "stdout": "{\"command\":\"raw execute_menu_item\",\"data\":{\"executed\":true,\"executionTime\":43,\"menuExists\":true,\"menuPath\":\"Tools/Unity CLI/Test Runner E2E/Disable Domain Reload\",\"message\":\"Menu item executed successfully\",\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "" + }, + { + "tool": "get_project_settings", + "parameters": { + "includePlayer": false, + "includeEditor": true + }, + "returncode": 0, + "stdout": "{\"command\":\"raw get_project_settings\",\"data\":{\"editor\":{\"assetNamingUsesSpace\":true,\"defaultBehaviorMode\":\"Mode3D\",\"enterPlayModeOptions\":\"DisableDomainReload\",\"enterPlayModeOptionsEnabled\":true,\"prefabModeRegularEnvironment\":\"None\",\"prefabModeUIEnvironment\":\"None\",\"serializationMode\":\"ForceText\",\"unityRemote\":\"\",\"unityRemoteCompression\":\"\",\"unityRemoteResolution\":\"\"}},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "" + }, + { + "tool": "run_tests", + "parameters": { + "testMode": "PlayMode", + "filter": "DomainReloadResultTests", + "includeDetails": true + }, + "returncode": 0, + "stdout": "{\"command\":\"raw run_tests\",\"data\":{\"message\":\"Test execution started. Use get_test_status to check progress.\",\"runId\":\"707b27fd-ae6a-4eb0-8e9f-f41b8430ce07\",\"status\":\"running\"},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "" + }, + { + "tool": "get_test_status", + "parameters": { + "includeTestResults": true, + "includeFileContent": true + }, + "returncode": 0, + "stdout": "{\"command\":\"raw get_test_status\",\"data\":{\"failedTests\":0,\"failures\":[],\"inconclusiveTests\":0,\"latestResult\":{\"fileContent\":\"{\\r\\n \\\"generatedAt\\\": \\\"2026-10-03T21:25:41.7656478Z\\\",\\r\\n \\\"runStartedAt\\\": \\\"2026-10-03T21:25:41.6407521Z\\\",\\r\\n \\\"durationSeconds\\\": 0.1093431,\\r\\n \\\"testMode\\\": \\\"PlayMode\\\",\\r\\n \\\"totalTests\\\": 2,\\r\\n \\\"passed\\\": 2,\\r\\n \\\"failed\\\": 0,\\r\\n \\\"skipped\\\": 0,\\r\\n \\\"inconclusive\\\": 0,\\r\\n \\\"status\\\": \\\"passed\\\",\\r\\n \\\"failures\\\": [],\\r\\n \\\"tests\\\": [\\r\\n {\\r\\n \\\"name\\\": \\\"FrameAdvances\\\",\\r\\n \\\"fullName\\\": \\\"UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\\\",\\r\\n \\\"status\\\": \\\"Passed\\\",\\r\\n \\\"duration\\\": 0.0044743,\\r\\n \\\"message\\\": null,\\r\\n \\\"stackTrace\\\": null,\\r\\n \\\"output\\\": \\\"[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\\\\r\\\\n\\\"\\r\\n },\\r\\n {\\r\\n \\\"name\\\": \\\"RigidbodyFalls\\\",\\r\\n \\\"fullName\\\": \\\"UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\\\",\\r\\n \\\"status\\\": \\\"Passed\\\",\\r\\n \\\"duration\\\": 0.08695,\\r\\n \\\"message\\\": null,\\r\\n \\\"stackTrace\\\": null,\\r\\n \\\"output\\\": \\\"[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\\\\r\\\\n\\\"\\r\\n }\\r\\n ]\\r\\n}\",\"generatedAt\":\"2026-10-03T21:25:41.7661521Z\",\"path\":\"E:\\\\unity-cli\\\\work\\\\issue-386\\\\.cache\\\\issue-386\\\\staff-project\\\\.unity\\\\test-results\\\\TestResults_PlayMode_20261003_212540.json\",\"status\":\"available\",\"summary\":{\"durationSeconds\":0.1093431,\"failed\":0,\"failures\":[],\"generatedAt\":\"2026-10-03T21:25:41.7656478Z\",\"inconclusive\":0,\"passed\":2,\"runStartedAt\":\"2026-10-03T21:25:41.6407521Z\",\"skipped\":0,\"status\":\"passed\",\"testMode\":\"PlayMode\",\"tests\":[{\"duration\":0.0044743,\"fullName\":\"UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\",\"message\":null,\"name\":\"FrameAdvances\",\"output\":\"[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\\r\\n\",\"stackTrace\":null,\"status\":\"Passed\"},{\"duration\":0.08695,\"fullName\":\"UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\",\"message\":null,\"name\":\"RigidbodyFalls\",\"output\":\"[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\\r\\n\",\"stackTrace\":null,\"status\":\"Passed\"}],\"totalTests\":2}},\"passedTests\":2,\"runId\":\"707b27fd-ae6a-4eb0-8e9f-f41b8430ce07\",\"skippedTests\":0,\"status\":\"completed\",\"success\":true,\"testMode\":\"PlayMode\",\"tests\":[{\"duration\":0.0044743,\"fullName\":\"UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\",\"message\":null,\"name\":\"FrameAdvances\",\"output\":\"[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.FrameAdvances\\r\\n\",\"status\":\"Passed\"},{\"duration\":0.08695,\"fullName\":\"UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\",\"message\":null,\"name\":\"RigidbodyFalls\",\"output\":\"[unity-cli-bridge][TestExecutionHandler] Test started: UnityCliBridge.Tests.PlayMode.DomainReloadResultTests.RigidbodyFalls\\r\\n\",\"status\":\"Passed\"}],\"totalTests\":2},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "" + }, + { + "tool": "get_editor_state", + "parameters": {}, + "returncode": 0, + "stdout": "{\"command\":\"raw get_editor_state\",\"data\":{\"state\":{\"applicationContentsPath\":\"C:/Program Files/Unity/Hub/Editor/6000.4.4f1/Editor/Data\",\"applicationPath\":\"C:/Program Files/Unity/Hub/Editor/6000.4.4f1/Editor/Unity.exe\",\"isCompiling\":false,\"isPaused\":false,\"isPlaying\":false,\"isUpdating\":false,\"playability\":{\"compilation\":null,\"lastPlayRequestTime\":null,\"playRequested\":false,\"reason\":\"ready\"},\"timeSinceStartup\":1282.8478036},\"status\":\"success\"},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "" + }, + { + "tool": "execute_menu_item", + "parameters": { + "action": "execute", + "menuPath": "Tools/Unity CLI/Test Runner E2E/Restore Settings" + }, + "returncode": 0, + "stdout": "{\"command\":\"raw execute_menu_item\",\"data\":{\"executed\":true,\"executionTime\":0,\"menuExists\":true,\"menuPath\":\"Tools/Unity CLI/Test Runner E2E/Restore Settings\",\"message\":\"Menu item executed successfully\",\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "" + }, + { + "tool": "get_project_settings", + "parameters": { + "includePlayer": false, + "includeEditor": true + }, + "returncode": 0, + "stdout": "{\"command\":\"raw get_project_settings\",\"data\":{\"editor\":{\"assetNamingUsesSpace\":true,\"defaultBehaviorMode\":\"Mode3D\",\"enterPlayModeOptions\":\"DisableDomainReload\",\"enterPlayModeOptionsEnabled\":true,\"prefabModeRegularEnvironment\":\"None\",\"prefabModeUIEnvironment\":\"None\",\"serializationMode\":\"ForceText\",\"unityRemote\":\"\",\"unityRemoteCompression\":\"\",\"unityRemoteResolution\":\"\"}},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "" + } + ], + "ping": { + "bridgeVersion": "0.18.1", + "echo": null, + "message": "pong", + "projectPath": "\\.cache\\issue-386\\staff-project", + "supportsSafeClose": true, + "timestamp": "2026-10-03T21:25:30.1959524Z" + }, + "originalSettings": { + "assetNamingUsesSpace": true, + "defaultBehaviorMode": "Mode3D", + "enterPlayModeOptions": "DisableDomainReload", + "enterPlayModeOptionsEnabled": true, + "prefabModeRegularEnvironment": "None", + "prefabModeUIEnvironment": "None", + "serializationMode": "ForceText", + "unityRemote": "", + "unityRemoteCompression": "", + "unityRemoteResolution": "" + }, + "settingsRestored": true, + "status": "pass" +} diff --git a/docs/verification/issue-386/resume/domain-reload.txt b/docs/verification/issue-386/resume/domain-reload.txt new file mode 100644 index 00000000..c6c82a25 --- /dev/null +++ b/docs/verification/issue-386/resume/domain-reload.txt @@ -0,0 +1,3 @@ +PASS domainReloadEnabled=True: 2 passed, 0 failed +PASS domainReloadEnabled=False: 2 passed, 0 failed +Evidence: \.cache\issue-386\resume\domain-reload.json; pass diff --git a/docs/verification/issue-386/resume/eval.txt b/docs/verification/issue-386/resume/eval.txt new file mode 100644 index 00000000..f4ff1399 --- /dev/null +++ b/docs/verification/issue-386/resume/eval.txt @@ -0,0 +1,21 @@ +{"assetsPath": "/.cache/issue-386/staff-project/Assets", "codeIndexRoot": "/.cache/issue-386/staff-project/.unity/cache/code-index", "packagesPath": "/.cache/issue-386/staff-project/Packages", "projectRoot": "/.cache/issue-386/staff-project", "unity": {"platform": "WindowsEditor", "productName": "staff-project", "unityVersion": "6000.4.4f1"}} +PASS AC-1 numeric expression +PASS AC-3 create +PASS AC-2 read scene object +PASS Unity Object descriptor +PASS AC-3 modify +PASS requestId deduplication and status +PASS AC-4 compile diagnostics +PASS AC-4 runtime exception +PASS captured logs +PASS JSON array +PASS statements without return +PASS unknown status +PASS #391 identical source reuses its compilation +PASS #391 AC-3 newly loaded assembly resolves +PASS #391 AC-3 types resolve across Domain Reload +soak {"iterations": 1000, "evaluations": 1000, "emittedAssemblies": 4, "loadedAssemblies": 4, "managedMemoryGrowthBytes": 2658304, "storedResults": 256} +PASS #391 AC-4 1000 consecutive evaluations stay within bounds +PASS AC-5 no persistent C# files +PASS Play Mode expression +Eval E2E: 18 passed, 0 failed diff --git a/docs/verification/issue-386/resume/final-checks.json b/docs/verification/issue-386/resume/final-checks.json new file mode 100644 index 00000000..d3feb0a8 --- /dev/null +++ b/docs/verification/issue-386/resume/final-checks.json @@ -0,0 +1,58 @@ +[ + { + "argv": [ + "cargo", + "fmt", + "--all", + "--", + "--check" + ], + "started_at": "2026-10-03T22:03:49.943444+00:00", + "finished_at": "2026-10-03T22:03:50.756622+00:00", + "exit_code": 0, + "log": "fmt.log" + }, + { + "argv": [ + "cargo", + "clippy", + "--all-targets", + "--", + "-D", + "warnings" + ], + "started_at": "2026-10-03T22:03:50.757030+00:00", + "finished_at": "2026-10-03T22:03:52.010330+00:00", + "exit_code": 0, + "log": "clippy.log" + }, + { + "argv": [ + "cargo", + "test", + "--all-targets", + "--no-fail-fast", + "--", + "--test-threads=1" + ], + "started_at": "2026-10-03T22:03:52.010738+00:00", + "finished_at": "2026-10-03T22:06:31.762136+00:00", + "exit_code": 0, + "log": "cargo-all-final.log" + }, + { + "argv": [ + "cargo", + "run", + "--", + "skills", + "lint", + "--severity", + "error" + ], + "started_at": "2026-10-03T22:06:32.769563+00:00", + "finished_at": "2026-10-03T22:06:46.527203+00:00", + "exit_code": 0, + "log": "skills-lint-final.log" + } +] \ No newline at end of file diff --git a/docs/verification/issue-386/resume/final-doc-checks.json b/docs/verification/issue-386/resume/final-doc-checks.json new file mode 100644 index 00000000..11178def --- /dev/null +++ b/docs/verification/issue-386/resume/final-doc-checks.json @@ -0,0 +1,45 @@ +[ + { + "argv": [ + "cargo", + "clippy", + "--workspace", + "--all-targets", + "--all-features", + "--", + "-D", + "warnings" + ], + "started_at": "2026-10-03T22:56:01.133701+00:00", + "log": "clippy-all-features-final.txt", + "exit_code": 0, + "finished_at": "2026-10-03T22:56:06.120231+00:00" + }, + { + "argv": [ + "cargo", + "doc", + "--workspace", + "--no-deps", + "--document-private-items" + ], + "started_at": "2026-10-03T22:56:06.120677+00:00", + "log": "rustdoc-final.txt", + "exit_code": 0, + "finished_at": "2026-10-03T22:56:15.763277+00:00" + }, + { + "argv": [ + "bunx", + "markdownlint-cli2", + "docs/comparison.md", + "docs/verification/issue-386/README.md", + "docs/verification/issue-386/resume/README.md", + "packaging/winget/README.md" + ], + "started_at": "2026-10-03T22:56:15.763736+00:00", + "log": "markdownlint-final.txt", + "exit_code": 0, + "finished_at": "2026-10-03T22:56:18.391255+00:00" + } +] \ No newline at end of file diff --git a/docs/verification/issue-386/resume/final-gui-results.json b/docs/verification/issue-386/resume/final-gui-results.json new file mode 100644 index 00000000..8952be0a --- /dev/null +++ b/docs/verification/issue-386/resume/final-gui-results.json @@ -0,0 +1,72 @@ +[ + { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--port", + "6487", + "test", + "--project-path", + "\\.cache\\issue-386\\staff-project", + "--mode", + "playmode", + "--filter", + "TouchGesturePlayModeTests", + "--disable-domain-reload", + "--timeout", + "240", + "--report", + "junit", + "--output", + "\\.cache\\issue-386\\resume\\TouchGesturePlayModeTests-gui-final.xml" + ], + "name": "TouchGesturePlayModeTests", + "source_hashes": { + "Editor/Handlers/InputSystemHandler.cs": "7ac08b4f3d6ae849269707f7d7db32cbdbe287617003705272e767864e6b2434", + "Tests/PlayMode/InputSimulationAutomationPlayModeTests.cs": "a2dc48d02587b040e1356ebded544702a5d847ad1bb454db71bc09b39e16a44b", + "Tests/PlayMode/TouchGesturePlayModeTests.cs": "c23e5769c36205ef9fbb41d13be465deab504a8d2aa312b30788928f5884a69e" + }, + "started_at": "2026-10-04T01:31:29.965189+00:00", + "editor": "native Windows GUI Unity 6000.4.4f1", + "exit_code": 0, + "tests": 15, + "failed": 0, + "errors": 0, + "skipped": 0, + "finished_at": "2026-10-04T01:31:54.269500+00:00" + }, + { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--port", + "6487", + "test", + "--project-path", + "\\.cache\\issue-386\\staff-project", + "--mode", + "playmode", + "--filter", + "InputSimulationAutomationPlayModeTests", + "--disable-domain-reload", + "--timeout", + "240", + "--report", + "junit", + "--output", + "\\.cache\\issue-386\\resume\\InputSimulationAutomationPlayModeTests-gui-final.xml" + ], + "name": "InputSimulationAutomationPlayModeTests", + "source_hashes": { + "Editor/Handlers/InputSystemHandler.cs": "7ac08b4f3d6ae849269707f7d7db32cbdbe287617003705272e767864e6b2434", + "Tests/PlayMode/InputSimulationAutomationPlayModeTests.cs": "a2dc48d02587b040e1356ebded544702a5d847ad1bb454db71bc09b39e16a44b", + "Tests/PlayMode/TouchGesturePlayModeTests.cs": "c23e5769c36205ef9fbb41d13be465deab504a8d2aa312b30788928f5884a69e" + }, + "started_at": "2026-10-04T01:31:54.270009+00:00", + "editor": "native Windows GUI Unity 6000.4.4f1", + "exit_code": 0, + "tests": 11, + "failed": 0, + "errors": 0, + "skipped": 0, + "finished_at": "2026-10-04T01:32:06.230517+00:00" + } +] \ No newline at end of file diff --git a/docs/verification/issue-386/resume/final-markdown-check.json b/docs/verification/issue-386/resume/final-markdown-check.json new file mode 100644 index 00000000..de5a04cf --- /dev/null +++ b/docs/verification/issue-386/resume/final-markdown-check.json @@ -0,0 +1,16 @@ +{ + "argv": [ + "bunx", + "markdownlint-cli2", + "docs/comparison.md", + "docs/hot-reload.md", + "docs/verification/issue-386/README.md", + "docs/verification/issue-386/resume/*.md", + "packaging/winget/README.md", + "tasks/lessons.md" + ], + "started_at": "2026-10-04T01:33:52.717106+00:00", + "exit_code": 0, + "finished_at": "2026-10-04T01:33:53.455473+00:00", + "log": "markdownlint-final.txt" +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/fmt.txt b/docs/verification/issue-386/resume/fmt.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/docs/verification/issue-386/resume/fmt.txt @@ -0,0 +1 @@ + diff --git a/docs/verification/issue-386/resume/fresh-play-results.json b/docs/verification/issue-386/resume/fresh-play-results.json new file mode 100644 index 00000000..ed730f1a --- /dev/null +++ b/docs/verification/issue-386/resume/fresh-play-results.json @@ -0,0 +1,56 @@ +[ + { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--port", + "6487", + "test", + "--project-path", + "\\.cache\\issue-386\\staff-project", + "--mode", + "playmode", + "--filter", + "TouchGesturePlayModeTests", + "--disable-domain-reload", + "--timeout", + "240", + "--report", + "junit", + "--output", + "\\.cache\\issue-386\\resume\\TouchGesturePlayModeTests-fresh.xml" + ], + "name": "TouchGesturePlayModeTests", + "started_at": "2026-10-03T22:56:41.476870+00:00", + "exit_code": 0, + "tests": 15, + "failed": 0, + "finished_at": "2026-10-03T22:57:03.993174+00:00" + }, + { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--port", + "6487", + "test", + "--project-path", + "\\.cache\\issue-386\\staff-project", + "--mode", + "playmode", + "--filter", + "InputSimulationAutomationPlayModeTests", + "--disable-domain-reload", + "--timeout", + "240", + "--report", + "junit", + "--output", + "\\.cache\\issue-386\\resume\\InputSimulationAutomationPlayModeTests-fresh.xml" + ], + "name": "InputSimulationAutomationPlayModeTests", + "started_at": "2026-10-03T22:57:03.993573+00:00", + "exit_code": 8, + "tests": 7, + "failed": 2, + "finished_at": "2026-10-03T22:57:18.660143+00:00" + } +] \ No newline at end of file diff --git a/docs/verification/issue-386/resume/fsr-package.json b/docs/verification/issue-386/resume/fsr-package.json new file mode 100644 index 00000000..f73b66cd --- /dev/null +++ b/docs/verification/issue-386/resume/fsr-package.json @@ -0,0 +1,9 @@ +{ + "url": "https://codeload.github.com/handzlikchris/FastScriptReload/zip/51140b71d9e5df1de231b33ec20ee089b18bebec", + "commit": "51140b71d9e5df1de231b33ec20ee089b18bebec", + "version": "1.8.0", + "package": "com.handzlikchris.fastscriptreload", + "archive_bytes": 14083364, + "archive_sha256": "5f04d854dd63bf7e6c285476e2d725cba0694b284cc2d82390b345d88b1f4435", + "assets": "\\.cache\\issue-386\\fsr-pinned\\FastScriptReload-51140b71d9e5df1de231b33ec20ee089b18bebec\\Assets" +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/hot-reload-results.txt b/docs/verification/issue-386/resume/hot-reload-results.txt new file mode 100644 index 00000000..863dc582 --- /dev/null +++ b/docs/verification/issue-386/resume/hot-reload-results.txt @@ -0,0 +1,28 @@ +Unity: 6000.4.4f1 architecture: X64 mode: supported +PASS Editor process architecture is X64 +Backend: {"applied": [], "appliedRevision": null, "available": true, "backend": "FastScriptReload", "baselineRevision": null, "code": null, "failed": [], "limitation": null, "path": null, "platformSupported": true, "recovery": null, "recoveryRequired": false, "requestedRevision": null, "state": "idle", "supported": true, "transaction": null, "unverified": []} +PASS baseline calculation runs in real Play Mode +PASS Editor update observer records runtime and backend status without a queued request +PASS backend supports this actual Editor +PASS recovery stops Play without restarting +PASS recovery records compiled source checksum for next session +PASS recovery checksum matches actual compiled assembly +PASS new Play session executes original disk baseline after recovery +PASS hot_reload rejects: STALE / +PASS hot_reload rejects: SYNTAX / +PASS hot_reload rejects: UNSUPPORTED / +PASS preflight failures preserve verified revision +PASS Play continues with expected calculation +PASS scene/object identity, position, HP, score, static and nonserialized state preserved +PASS new revision follows verified natural execution +PASS Play continues with expected calculation +PASS scene/object identity, position, HP, score, static and nonserialized state preserved +PASS successful preview leaves disk source unchanged +PASS partially executing preview clears whole-version claim while verification is pending +PASS hot_reload rejects: HOT_RELOAD_VERIFICATION_FAILED / +PASS unverified partial transaction clears whole-version claim and requires recovery +PASS recovery stops Play without restarting +PASS recovery records compiled source checksum for next session +PASS recovery checksum matches actual compiled assembly +PASS new Play session executes original disk baseline after recovery +RESULT pass=25 fail=0 diff --git a/docs/verification/issue-386/resume/hot-reload-summary.json b/docs/verification/issue-386/resume/hot-reload-summary.json new file mode 100644 index 00000000..b39c00de --- /dev/null +++ b/docs/verification/issue-386/resume/hot-reload-summary.json @@ -0,0 +1,49 @@ +{ + "editor": "6000.4.4f1 Windows x64", + "port": "6492", + "project": "\\.cache\\issue-386\\resume\\hot-reload-windows\\Project", + "command": [ + "C:/Program Files/Unity/Hub/Editor/6000.4.4f1/Editor/Unity.exe", + "-batchmode", + "-nographics", + "-projectPath", + "\\.cache\\issue-386\\resume\\hot-reload-windows\\Project", + "-executeMethod", + "UnityCliBridge.TestScenes.UnityCliInputBatchHost.Run", + "-logFile", + "\\.cache\\issue-386\\resume\\hot-reload-windows\\editor.log" + ], + "fsr": { + "url": "https://codeload.github.com/handzlikchris/FastScriptReload/zip/51140b71d9e5df1de231b33ec20ee089b18bebec", + "commit": "51140b71d9e5df1de231b33ec20ee089b18bebec", + "version": "1.8.0", + "package": "com.handzlikchris.fastscriptreload", + "archive_bytes": 14083364, + "archive_sha256": "5f04d854dd63bf7e6c285476e2d725cba0694b284cc2d82390b345d88b1f4435", + "assets": "\\.cache\\issue-386\\fsr-pinned\\FastScriptReload-51140b71d9e5df1de231b33ec20ee089b18bebec\\Assets" + }, + "started_at": "2026-10-03T23:03:53.394825+00:00", + "cli_sha256": "087d057cd62483c3c0aa64ceb85a77421349f2ace1ba236a13c1ddcffe909d35", + "pid": 5188, + "test_command": [ + "py", + "-3", + "-X", + "utf8", + "-B", + "\\scripts\\e2e-hot-reload.py", + "--project", + "\\.cache\\issue-386\\resume\\hot-reload-windows\\Project", + "--port", + "6492", + "--unity-cli", + "\\target\\debug\\unity-cli.exe", + "--expect", + "supported", + "--require-arch", + "X64" + ], + "exit_code": 0, + "editor_exit_code": 4294967295, + "finished_at": "2026-10-03T23:08:21.043376+00:00" +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/input-actions-persistence.txt b/docs/verification/issue-386/resume/input-actions-persistence.txt new file mode 100644 index 00000000..a395091c --- /dev/null +++ b/docs/verification/issue-386/resume/input-actions-persistence.txt @@ -0,0 +1,54 @@ +Unity 6000.4.4f1; port 6489; artifacts \AppData\Local\Temp\input-actions-persistence-oyi524qv +Unity host 1 ready: \AppData\Local\Temp\input-actions-persistence-oyi524qv\unity-1.log +PASS create_action_map: source map/action/binding contents and IDs match memory +PASS create_action_map: source control schemes match memory +PASS create_action_map: reimport preserves structure and IDs +PASS add_input_action: source map/action/binding contents and IDs match memory +PASS add_input_action: source control schemes match memory +PASS add_input_action: reimport preserves structure and IDs +PASS add_input_binding: source map/action/binding contents and IDs match memory +PASS add_input_binding: source control schemes match memory +PASS add_input_binding: reimport preserves structure and IDs +PASS remove_input_binding: source map/action/binding contents and IDs match memory +PASS remove_input_binding: source control schemes match memory +PASS remove_input_binding: reimport preserves structure and IDs +PASS create_composite_binding: source map/action/binding contents and IDs match memory +PASS create_composite_binding: source control schemes match memory +PASS create_composite_binding: reimport preserves structure and IDs +PASS remove_all_bindings: source map/action/binding contents and IDs match memory +PASS remove_all_bindings: source control schemes match memory +PASS remove_all_bindings: reimport preserves structure and IDs +PASS add_input_binding: source map/action/binding contents and IDs match memory +PASS add_input_binding: source control schemes match memory +PASS add_input_binding: reimport preserves structure and IDs +PASS remove_input_action: source map/action/binding contents and IDs match memory +PASS remove_input_action: source control schemes match memory +PASS remove_input_action: reimport preserves structure and IDs +PASS create_action_map: source map/action/binding contents and IDs match memory +PASS create_action_map: source control schemes match memory +PASS create_action_map: reimport preserves structure and IDs +PASS remove_action_map: source map/action/binding contents and IDs match memory +PASS remove_action_map: source control schemes match memory +PASS remove_action_map: reimport preserves structure and IDs +PASS manage_control_schemes: source map/action/binding contents and IDs match memory +PASS manage_control_schemes: source control schemes match memory +PASS manage_control_schemes: reimport preserves structure and IDs +PASS manage_control_schemes: source map/action/binding contents and IDs match memory +PASS manage_control_schemes: source control schemes match memory +PASS manage_control_schemes: reimport preserves structure and IDs +PASS manage_control_schemes: source map/action/binding contents and IDs match memory +PASS manage_control_schemes: source control schemes match memory +PASS manage_control_schemes: reimport preserves structure and IDs +PASS add_input_binding: source map/action/binding contents and IDs match memory +PASS add_input_binding: source control schemes match memory +PASS add_input_binding: reimport preserves structure and IDs +Unity host 2 ready: \AppData\Local\Temp\input-actions-persistence-oyi524qv\unity-2.log +PASS Editor restart preserves maps/actions/bindings/schemes and IDs +PASS Editor restart preserves source JSON +PASS remove_action_map: source map/action/binding contents and IDs match memory +PASS remove_action_map: source control schemes match memory +PASS remove_action_map: reimport preserves structure and IDs +PASS manage_control_schemes: source map/action/binding contents and IDs match memory +PASS manage_control_schemes: source control schemes match memory +PASS manage_control_schemes: reimport preserves structure and IDs +{"unity_version": "6000.4.4f1", "passed": 50, "failed": 0, "editor_starts": 2, "artifacts": "\\AppData\\Local\\Temp\\input-actions-persistence-oyi524qv"} diff --git a/docs/verification/issue-386/resume/input-counter-green.json b/docs/verification/issue-386/resume/input-counter-green.json new file mode 100644 index 00000000..a3253c8d --- /dev/null +++ b/docs/verification/issue-386/resume/input-counter-green.json @@ -0,0 +1,25 @@ +{ + "command": [ + "\\target\\debug\\unity-cli.exe", + "--port", + "6493", + "test", + "--project-path", + "\\.cache\\issue-386\\resume\\hot-reload-windows\\Project", + "--mode", + "playmode", + "--filter", + "InputSimulationAutomationPlayModeTests", + "--disable-domain-reload", + "--timeout", + "240", + "--report", + "junit", + "--output", + "\\.cache\\issue-386\\resume\\InputSimulationAutomationPlayModeTests-counter-green.xml" + ], + "mode": "native Windows headless / isolated minimal fixture", + "exit_code": 0, + "tests": 11, + "failed": 0 +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/input-counter-green.txt b/docs/verification/issue-386/resume/input-counter-green.txt new file mode 100644 index 00000000..c9467322 --- /dev/null +++ b/docs/verification/issue-386/resume/input-counter-green.txt @@ -0,0 +1,2 @@ +Started headless Editor (pid 34888) +11 tests, 0 failed; report: \.cache\issue-386\resume\InputSimulationAutomationPlayModeTests-counter-green.xml diff --git a/docs/verification/issue-386/resume/input-counter-red.json b/docs/verification/issue-386/resume/input-counter-red.json new file mode 100644 index 00000000..007910e5 --- /dev/null +++ b/docs/verification/issue-386/resume/input-counter-red.json @@ -0,0 +1,25 @@ +{ + "command": [ + "\\target\\debug\\unity-cli.exe", + "--port", + "6493", + "test", + "--project-path", + "\\.cache\\issue-386\\resume\\hot-reload-windows\\Project", + "--mode", + "playmode", + "--filter", + "InputSimulationAutomationPlayModeTests", + "--disable-domain-reload", + "--timeout", + "240", + "--report", + "junit", + "--output", + "\\.cache\\issue-386\\resume\\InputSimulationAutomationPlayModeTests-counter-red.xml" + ], + "mode": "native Windows headless / isolated minimal fixture", + "exit_code": 8, + "tests": 11, + "failed": 3 +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/input-counter-red.txt b/docs/verification/issue-386/resume/input-counter-red.txt new file mode 100644 index 00000000..21dd5bd1 --- /dev/null +++ b/docs/verification/issue-386/resume/input-counter-red.txt @@ -0,0 +1,3 @@ +Started headless Editor (pid 26584) +11 tests, 3 failed; report: \.cache\issue-386\resume\InputSimulationAutomationPlayModeTests-counter-red.xml +TEST_FAILED: Unity command failed (code: UNKNOWN_ERROR) diff --git a/docs/verification/issue-386/resume/linux-gnome-fallback-result.json b/docs/verification/issue-386/resume/linux-gnome-fallback-result.json new file mode 100644 index 00000000..4f2d12d2 --- /dev/null +++ b/docs/verification/issue-386/resume/linux-gnome-fallback-result.json @@ -0,0 +1,34 @@ +{ + "started_at": "2026-10-03T20:40:53.902978+00:00", + "real_editor": false, + "compositor": "GNOME Shell 46 nested Wayland", + "shell_pid": 1506028, + "exit_code": 0, + "stdout": { + "command": "raw capture_screenshot", + "data": { + "captureMode": "game", + "fallback": "os", + "fallbackTool": "gnome-screenshot", + "fileSize": 16225, + "height": 600, + "message": "Desktop screenshot captured by the OS (Unity Editor did not respond)", + "note": "Unity Editor did not respond (OPERATION_FAILED: Timed out while waiting for Unity response header: deadline has elapsed (code: TIMEOUT)); captured the whole desktop with an OS screenshot instead. The Editor main thread may be blocked by a modal dialog. Pass \"osFallback\": false to get the timeout error instead.", + "path": "/tmp/issue386-gnome-ssj55wmm/CaptureProject/.unity/capture/image_os_1791060058291.png", + "width": 800 + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stderr": "\u001b[2m2026-10-03T20:40:58.289725Z\u001b[0m \u001b[33m WARN\u001b[0m Unity did not respond; falling back to OS screenshot \u001b[3merror\u001b[0m\u001b[2m=\u001b[0mOPERATION_FAILED: Timed out while waiting for Unity response header: deadline has elapsed (code: TIMEOUT)\n", + "png": { + "size": [ + 800, + 600 + ], + "sha256": "bb8d1f1f9236430fc6567fa822e63e04ef5cd0d9747ad66c346d20d9e1766f26" + }, + "passed": true, + "finished_at": "2026-10-03T20:41:01.353274+00:00" +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/linux-license.json b/docs/verification/issue-386/resume/linux-license.json new file mode 100644 index 00000000..0803b857 --- /dev/null +++ b/docs/verification/issue-386/resume/linux-license.json @@ -0,0 +1,7 @@ +{ + "editor": "6000.4.4f1 Linux x64", + "exit_code": 198, + "result": "No valid Unity Editor license found. Please activate your license.", + "hub": "3.22.2 official package installed and sign-in window started", + "real_editor_verified": false +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/linux-wayland-extra-results.json b/docs/verification/issue-386/resume/linux-wayland-extra-results.json new file mode 100644 index 00000000..b422fae7 --- /dev/null +++ b/docs/verification/issue-386/resume/linux-wayland-extra-results.json @@ -0,0 +1,35 @@ +[ + { + "tool": "spectacle", + "started_at": "2026-10-03T20:55:11.313451+00:00", + "real_editor": false, + "exit_code": 0, + "stdout": { + "command": "raw capture_screenshot", + "data": { + "captureMode": "game", + "fallback": "os", + "fallbackTool": "spectacle", + "fileSize": 5327, + "height": 720, + "message": "Desktop screenshot captured by the OS (Unity Editor did not respond)", + "note": "Unity Editor did not respond (OPERATION_FAILED: Timed out while waiting for Unity response header: deadline has elapsed (code: TIMEOUT)); captured the whole desktop with an OS screenshot instead. The Editor main thread may be blocked by a modal dialog. Pass \"osFallback\": false to get the timeout error instead.", + "path": "/tmp/issue386-spectacle-9wpjr84r/CaptureProject/.unity/capture/image_os_1791060914678.png", + "width": 1280 + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stderr": "\u001b[2m2026-10-03T20:55:14.676790Z\u001b[0m \u001b[33m WARN\u001b[0m Unity did not respond; falling back to OS screenshot \u001b[3merror\u001b[0m\u001b[2m=\u001b[0mOPERATION_FAILED: Timed out while waiting for Unity response header: deadline has elapsed (code: TIMEOUT)\n", + "png": { + "size": [ + 1280, + 720 + ], + "sha256": "8dc98e7f34604d19f8d0c2e0654c36e47ebd63193de9da301fe395df74969b26" + }, + "passed": true, + "finished_at": "2026-10-03T20:55:15.796264+00:00" + } +] \ No newline at end of file diff --git a/docs/verification/issue-386/resume/linux-wayland-first-results.json b/docs/verification/issue-386/resume/linux-wayland-first-results.json new file mode 100644 index 00000000..577acb16 --- /dev/null +++ b/docs/verification/issue-386/resume/linux-wayland-first-results.json @@ -0,0 +1,60 @@ +[ + { + "tool": "grim", + "started_at": "2026-10-03T20:53:36.396523+00:00", + "real_editor": false, + "exit_code": 0, + "stdout": { + "command": "raw capture_screenshot", + "data": { + "captureMode": "game", + "fallback": "os", + "fallbackTool": "grim", + "fileSize": 4319, + "height": 720, + "message": "Desktop screenshot captured by the OS (Unity Editor did not respond)", + "note": "Unity Editor did not respond (OPERATION_FAILED: Timed out while waiting for Unity response header: deadline has elapsed (code: TIMEOUT)); captured the whole desktop with an OS screenshot instead. The Editor main thread may be blocked by a modal dialog. Pass \"osFallback\": false to get the timeout error instead.", + "path": "/tmp/issue386-grim-hycf6y8w/CaptureProject/.unity/capture/image_os_1791060819733.png", + "width": 1280 + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stderr": "\u001b[2m2026-10-03T20:53:39.731779Z\u001b[0m \u001b[33m WARN\u001b[0m Unity did not respond; falling back to OS screenshot \u001b[3merror\u001b[0m\u001b[2m=\u001b[0mOPERATION_FAILED: Timed out while waiting for Unity response header: deadline has elapsed (code: TIMEOUT)\n", + "png": { + "size": [ + 1280, + 720 + ], + "sha256": "b4d1a3754933377521fe5c694fb1f6275e229cba8fa5db7b4ea4f9fb51e5e9e4" + }, + "passed": true, + "finished_at": "2026-10-03T20:53:39.789517+00:00" + }, + { + "tool": "spectacle", + "started_at": "2026-10-03T20:53:39.793108+00:00", + "real_editor": false, + "exit_code": 6, + "stdout": { + "command": "raw capture_screenshot", + "data": { + "code": "TIMEOUT", + "error": "OPERATION_FAILED: Timed out while waiting for Unity response header: deadline has elapsed", + "status": "error" + }, + "errors": [ + { + "code": "TIMEOUT", + "message": "OS screenshot fallback also failed: No OS screenshot tool succeeded (grim: No such file or directory (os error 2); gnome-screenshot: No such file or directory (os error 2); spectacle: exited with exit status: 1: On Wayland, Spectacle requires KDE Plasma's KWin compositor, which does not seem to be available. Use Spectacle on KDE Plasma, or use a different screenshot tool.; import: No such file or directory (os error 2); scrot: No such file or directory (os error 2); maim: No such file or directory (os error 2)): OPERATION_FAILED: Timed out while waiting for Unity response header: deadline has elapsed (code: TIMEOUT)" + } + ], + "success": false, + "warnings": [] + }, + "stderr": "\u001b[2m2026-10-03T20:53:43.042585Z\u001b[0m \u001b[33m WARN\u001b[0m Unity did not respond; falling back to OS screenshot \u001b[3merror\u001b[0m\u001b[2m=\u001b[0mOPERATION_FAILED: Timed out while waiting for Unity response header: deadline has elapsed (code: TIMEOUT)\n", + "passed": false, + "finished_at": "2026-10-03T20:53:43.687922+00:00" + } +] \ No newline at end of file diff --git a/docs/verification/issue-386/resume/linux-x11-platform.txt b/docs/verification/issue-386/resume/linux-x11-platform.txt new file mode 100644 index 00000000..b26f7f50 --- /dev/null +++ b/docs/verification/issue-386/resume/linux-x11-platform.txt @@ -0,0 +1,14 @@ +unity-cli: unity-cli 0.18.1 (linux, home=/tmp/unity-cli-platform-checks-acyvccna/home) +[PASS] discovery: instances list succeeds: exit=0 +[PASS] discovery: live PID is discovered from its lockfile: {"active": false, "host": "127.0.0.1", "id": "127.0.0.1:59475", "last_checked_at": "1791059172", "lockfile": "/tmp/unity-cli-platform-checks-acyvccna/home/.unity-cli/editors/1492255.json", "pid": 1492255, "port": 59475, "project_path": "/tmp/unity-cli-platform-checks-acyvccna/LiveProject", "source": "lockfile", "state": "ready", "status": "down", "unity_version": "6000.3.25f1"} +[PASS] discovery: exited PID is listed as unreachable: {"active": false, "host": "127.0.0.1", "id": "127.0.0.1:34399", "last_checked_at": "1791059172", "lockfile": "/tmp/unity-cli-platform-checks-acyvccna/home/.unity-cli/editors/1492256.json", "pid": 1492256, "port": 34399, "project_path": "/tmp/unity-cli-platform-checks-acyvccna/DeadProject", "source": "lockfile", "stale_reason": "process 1492256 is not running", "state": "ready", "status": "unreachable", "unity_version": "6000.3.25f1"} +[PASS] discovery: exited PID is excluded from target selection: exit=7 codes=['EDITOR_NOT_FOUND'] candidates=[1492255] live=1492255 +[PASS] setup: --dry-run succeeds: exit=0 +[PASS] setup: plan lists binary, bridge, launch and wait steps: ["binary", "bridge", "launch", "wait"] +[PASS] setup: plan installs the Bridge into the project manifest: {"action": "install", "declared": "0.18.1", "dryRun": true, "inputBackends": {"changed": true, "previous": 0}, "installed": true, "manifestChanged": true, "manifestPath": "/tmp/unity-cli-platform-checks-acyvccna/Setup Project/Packages/manifest.json", "notes": ["Set PlayerSettings activeInputHandler to Both (2) so the Input System dependency imports without a restart prompt"], "package": "com.akiojin.unity-cli-bridge", "projectPath": "/tmp/unity-cli-platform-checks-acyvccna/Setup Project", "registry": true, "resolvedVersion": null, "source": "registry", "versionCheck": {"bridgeVersion": "0.18.1", "cliVersion": "0.18.1", "message": "CLI and bridge are both 0.18.1", "status": "match"}} +[PASS] setup: no Editor is contacted: {"checked": false, "endpoint": "127.0.0.1:59131"} +[PASS] setup: the manifest is left untouched +[PASS] screenshot: import writes a PNG after the Editor times out: exit=0 size=(1280, 720) bytes=250 path=/tmp/unity-cli-platform-checks-acyvccna/CaptureProject/.unity/capture/image_os_1791059176319.png +[PASS] screenshot: scrot writes a PNG after the Editor times out: exit=0 size=(1280, 720) bytes=2774 path=/tmp/unity-cli-platform-checks-acyvccna/CaptureProject/.unity/capture/image_os_1791059179434.png +[PASS] screenshot: maim writes a PNG after the Editor times out: exit=0 size=(1280, 720) bytes=5446 path=/tmp/unity-cli-platform-checks-acyvccna/CaptureProject/.unity/capture/image_os_1791059182508.png +12/12 checks passed diff --git a/docs/verification/issue-386/resume/markdownlint-final.txt b/docs/verification/issue-386/resume/markdownlint-final.txt new file mode 100644 index 00000000..8a831d38 --- /dev/null +++ b/docs/verification/issue-386/resume/markdownlint-final.txt @@ -0,0 +1,4 @@ +markdownlint-cli2 v0.23.3 (markdownlint v0.41.1) +Finding: docs/comparison.md docs/hot-reload.md docs/verification/issue-386/README.md docs/verification/issue-386/resume/*.md packaging/winget/README.md tasks/lessons.md +Linting: 8 files +Summary: 0 issues in 0 files diff --git a/docs/verification/issue-386/resume/mcp-live-editor-green.txt b/docs/verification/issue-386/resume/mcp-live-editor-green.txt new file mode 100644 index 00000000..03340507 --- /dev/null +++ b/docs/verification/issue-386/resume/mcp-live-editor-green.txt @@ -0,0 +1,10 @@ + Compiling unity-cli v0.18.1 () + Finished `test` profile [unoptimized + debuginfo] target(s) in 1.08s + Running tests\mcp.rs (target\debug\deps\mcp-9035db26334793d1.exe) + +running 3 tests +test configure_all_clients_preserves_other_servers_and_dry_run ... ok +test malformed_requests_do_not_end_session_or_execute_tools_before_initialization ... ok +test stdio_catalog_and_failure_contract_without_editor ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 13.71s diff --git a/docs/verification/issue-386/resume/modal-summary.json b/docs/verification/issue-386/resume/modal-summary.json new file mode 100644 index 00000000..037becef --- /dev/null +++ b/docs/verification/issue-386/resume/modal-summary.json @@ -0,0 +1,49 @@ +{ + "started_at": "2026-10-03T20:33:31.809137+00:00", + "source_commit": "0458d7fa83d55a3e77cb833ba74c705b65927a30", + "binary_sha256": "0038934812c1881055a67f05e463719dac55813293402991e78ba75aa63dfd7a", + "cases": { + "modal-os-fallback": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "1000", + "raw", + "capture_screenshot", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 2.712, + "success": true + }, + "modal-fallback-disabled": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "1000", + "raw", + "capture_screenshot", + "--json", + "{\"osFallback\":false}" + ], + "exit_code": 6, + "elapsed_seconds": 1.381, + "success": false + } + }, + "png": { + "width": 1512, + "height": 949, + "sha256": "031d61efffff00d2c99dc2539edde622facb7bfb63ee0d7ef99592d5a1aee438" + }, + "finished_at": "2026-10-03T20:33:36.765486+00:00" +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/more-e2e-results.json b/docs/verification/issue-386/resume/more-e2e-results.json new file mode 100644 index 00000000..7ed29c7d --- /dev/null +++ b/docs/verification/issue-386/resume/more-e2e-results.json @@ -0,0 +1,255 @@ +[ + { + "name": "bake-fixed", + "argv": [ + "py", + "-3", + "-X", + "utf8", + "-B", + "scripts/e2e-bake.py", + "--unity-cli", + "\\target\\debug\\unity-cli.exe", + "--port", + "6487", + "--project-root", + "\\.cache\\issue-386\\staff-project" + ], + "started_at": "2026-10-03T21:54:38.678106+00:00", + "exit_code": 1, + "finished_at": "2026-10-03T21:57:28.578724+00:00" + }, + { + "name": "reference-longpath-fixed", + "argv": [ + "py", + "-3", + "-X", + "utf8", + "-B", + ".cache/issue-386/run-reference-native.py" + ], + "started_at": "2026-10-03T21:57:28.579122+00:00", + "exit_code": 1, + "finished_at": "2026-10-03T21:58:33.942750+00:00" + }, + { + "name": "BakeHandlerTests", + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--port", + "6487", + "test", + "--project-path", + "\\.cache\\issue-386\\staff-project", + "--mode", + "editmode", + "--filter", + "BakeHandlerTests", + "--timeout", + "180", + "--report", + "junit", + "--output", + "\\.cache\\issue-386\\resume\\BakeHandlerTests.xml" + ], + "started_at": "2026-10-03T21:58:33.943118+00:00", + "exit_code": 0, + "tests": 15, + "failed": 0, + "skipped": 0, + "finished_at": "2026-10-03T21:59:01.501715+00:00" + }, + { + "name": "InputActionsHandlerTests", + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--port", + "6487", + "test", + "--project-path", + "\\.cache\\issue-386\\staff-project", + "--mode", + "editmode", + "--filter", + "InputActionsHandlerTests", + "--timeout", + "180", + "--report", + "junit", + "--output", + "\\.cache\\issue-386\\resume\\InputActionsHandlerTests.xml" + ], + "started_at": "2026-10-03T21:59:01.502095+00:00", + "exit_code": 0, + "tests": 12, + "failed": 0, + "skipped": 0, + "finished_at": "2026-10-03T21:59:07.499792+00:00" + }, + { + "name": "InputActionNotificationTests", + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--port", + "6487", + "test", + "--project-path", + "\\.cache\\issue-386\\staff-project", + "--mode", + "editmode", + "--filter", + "InputActionNotificationTests", + "--timeout", + "180", + "--report", + "junit", + "--output", + "\\.cache\\issue-386\\resume\\InputActionNotificationTests.xml" + ], + "started_at": "2026-10-03T21:59:07.500173+00:00", + "exit_code": 0, + "tests": 4, + "failed": 0, + "skipped": 0, + "finished_at": "2026-10-03T21:59:15.275551+00:00" + }, + { + "name": "AnimationCurveHandlerTests", + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--port", + "6487", + "test", + "--project-path", + "\\.cache\\issue-386\\staff-project", + "--mode", + "editmode", + "--filter", + "AnimationCurveHandlerTests", + "--timeout", + "180", + "--report", + "junit", + "--output", + "\\.cache\\issue-386\\resume\\AnimationCurveHandlerTests.xml" + ], + "started_at": "2026-10-03T21:59:15.275874+00:00", + "exit_code": 0, + "tests": 26, + "failed": 0, + "skipped": 0, + "finished_at": "2026-10-03T21:59:24.666670+00:00" + }, + { + "name": "SceneHandlerTests", + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--port", + "6487", + "test", + "--project-path", + "\\.cache\\issue-386\\staff-project", + "--mode", + "editmode", + "--filter", + "SceneHandlerTests", + "--timeout", + "180", + "--report", + "junit", + "--output", + "\\.cache\\issue-386\\resume\\SceneHandlerTests.xml" + ], + "started_at": "2026-10-03T21:59:24.667026+00:00", + "exit_code": 0, + "tests": 11, + "failed": 0, + "skipped": 0, + "finished_at": "2026-10-03T21:59:31.323415+00:00" + }, + { + "name": "InputSimulationAutomationPlayModeTests", + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--port", + "6487", + "test", + "--project-path", + "\\.cache\\issue-386\\staff-project", + "--mode", + "playmode", + "--filter", + "InputSimulationAutomationPlayModeTests", + "--disable-domain-reload", + "--timeout", + "240", + "--report", + "junit", + "--output", + "\\.cache\\issue-386\\resume\\InputSimulationAutomationPlayModeTests.xml" + ], + "started_at": "2026-10-03T21:59:31.323762+00:00", + "exit_code": 8, + "tests": 7, + "failed": 2, + "skipped": 0, + "finished_at": "2026-10-03T21:59:44.010030+00:00" + }, + { + "name": "GamepadStickInputPlayModeTests", + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--port", + "6487", + "test", + "--project-path", + "\\.cache\\issue-386\\staff-project", + "--mode", + "playmode", + "--filter", + "GamepadStickInputPlayModeTests", + "--disable-domain-reload", + "--timeout", + "240", + "--report", + "junit", + "--output", + "\\.cache\\issue-386\\resume\\GamepadStickInputPlayModeTests.xml" + ], + "started_at": "2026-10-03T21:59:44.010397+00:00", + "exit_code": 0, + "tests": 2, + "failed": 0, + "skipped": 0, + "finished_at": "2026-10-03T21:59:47.331843+00:00" + }, + { + "name": "TouchGesturePlayModeTests", + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--port", + "6487", + "test", + "--project-path", + "\\.cache\\issue-386\\staff-project", + "--mode", + "playmode", + "--filter", + "TouchGesturePlayModeTests", + "--disable-domain-reload", + "--timeout", + "240", + "--report", + "junit", + "--output", + "\\.cache\\issue-386\\resume\\TouchGesturePlayModeTests.xml" + ], + "started_at": "2026-10-03T21:59:47.332206+00:00", + "exit_code": 8, + "tests": 15, + "failed": 14, + "skipped": 0, + "finished_at": "2026-10-03T22:00:09.232996+00:00" + } +] \ No newline at end of file diff --git a/docs/verification/issue-386/resume/official-windows-binary.json b/docs/verification/issue-386/resume/official-windows-binary.json new file mode 100644 index 00000000..2479c1a0 --- /dev/null +++ b/docs/verification/issue-386/resume/official-windows-binary.json @@ -0,0 +1,11 @@ +{ + "url": "https://public-cdn.cloud.unity3d.com/hub/prod/cli/1.0.0-beta.11/unity-windows-x64.exe", + "manifest_url": "https://public-cdn.cloud.unity3d.com/hub/prod/cli/1.0.0-beta.11/latest.json", + "version": "1.0.0-beta.11", + "sha256": "4cad9230dd98cc8d123d3ef9d18fef5e7ee65f353814c3cf9d94d9129293dda3", + "official_sha256_matched": true, + "bytes": 26154920, + "binary": "\\.cache\\issue-386\\resume\\official-windows\\unity.exe", + "version_exit": 0, + "version_stdout": "{\n \"success\": true,\n \"command\": \"version\",\n \"data\": {\n \"version\": \"1.0.0-beta.11\",\n \"channel\": \"beta\",\n \"commit\": null,\n \"platform\": \"win32\",\n \"arch\": \"x64\",\n \"runtime\": \".NET 10.0.12\"\n },\n \"errors\": [],\n \"warnings\": []\n}\n" +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/official-windows-comparison-before-minimized.txt b/docs/verification/issue-386/resume/official-windows-comparison-before-minimized.txt new file mode 100644 index 00000000..1a295378 --- /dev/null +++ b/docs/verification/issue-386/resume/official-windows-comparison-before-minimized.txt @@ -0,0 +1,9 @@ +done: create_gameobject +done: hierarchy +done: eval +process frontmost PASS +process background FAIL Unable to establish actual Windows background focus +Traceback (most recent call last): + File "\.cache\issue-386\windows-comparison.py", line 159, in + raise RuntimeError(report['error']) +RuntimeError: Unable to establish actual Windows background focus diff --git a/docs/verification/issue-386/resume/official-windows-comparison-first-focus-failure.txt b/docs/verification/issue-386/resume/official-windows-comparison-first-focus-failure.txt new file mode 100644 index 00000000..8001b4b6 --- /dev/null +++ b/docs/verification/issue-386/resume/official-windows-comparison-first-focus-failure.txt @@ -0,0 +1,5 @@ +process frontmost FAIL Unable to establish actual Windows frontmost focus +Traceback (most recent call last): + File "\.cache\issue-386\windows-comparison.py", line 151, in + raise RuntimeError(report['error']) +RuntimeError: Unable to establish actual Windows frontmost focus diff --git a/docs/verification/issue-386/resume/official-windows-comparison-resident.txt b/docs/verification/issue-386/resume/official-windows-comparison-resident.txt new file mode 100644 index 00000000..dac073bb --- /dev/null +++ b/docs/verification/issue-386/resume/official-windows-comparison-resident.txt @@ -0,0 +1,208 @@ +resident frontmost: cycle 1/103 +resident frontmost: cycle 2/103 +resident frontmost: cycle 3/103 +resident frontmost: cycle 4/103 +resident frontmost: cycle 5/103 +resident frontmost: cycle 6/103 +resident frontmost: cycle 7/103 +resident frontmost: cycle 8/103 +resident frontmost: cycle 9/103 +resident frontmost: cycle 10/103 +resident frontmost: cycle 11/103 +resident frontmost: cycle 12/103 +resident frontmost: cycle 13/103 +resident frontmost: cycle 14/103 +resident frontmost: cycle 15/103 +resident frontmost: cycle 16/103 +resident frontmost: cycle 17/103 +resident frontmost: cycle 18/103 +resident frontmost: cycle 19/103 +resident frontmost: cycle 20/103 +resident frontmost: cycle 21/103 +resident frontmost: cycle 22/103 +resident frontmost: cycle 23/103 +resident frontmost: cycle 24/103 +resident frontmost: cycle 25/103 +resident frontmost: cycle 26/103 +resident frontmost: cycle 27/103 +resident frontmost: cycle 28/103 +resident frontmost: cycle 29/103 +resident frontmost: cycle 30/103 +resident frontmost: cycle 31/103 +resident frontmost: cycle 32/103 +resident frontmost: cycle 33/103 +resident frontmost: cycle 34/103 +resident frontmost: cycle 35/103 +resident frontmost: cycle 36/103 +resident frontmost: cycle 37/103 +resident frontmost: cycle 38/103 +resident frontmost: cycle 39/103 +resident frontmost: cycle 40/103 +resident frontmost: cycle 41/103 +resident frontmost: cycle 42/103 +resident frontmost: cycle 43/103 +resident frontmost: cycle 44/103 +resident frontmost: cycle 45/103 +resident frontmost: cycle 46/103 +resident frontmost: cycle 47/103 +resident frontmost: cycle 48/103 +resident frontmost: cycle 49/103 +resident frontmost: cycle 50/103 +resident frontmost: cycle 51/103 +resident frontmost: cycle 52/103 +resident frontmost: cycle 53/103 +resident frontmost: cycle 54/103 +resident frontmost: cycle 55/103 +resident frontmost: cycle 56/103 +resident frontmost: cycle 57/103 +resident frontmost: cycle 58/103 +resident frontmost: cycle 59/103 +resident frontmost: cycle 60/103 +resident frontmost: cycle 61/103 +resident frontmost: cycle 62/103 +resident frontmost: cycle 63/103 +resident frontmost: cycle 64/103 +resident frontmost: cycle 65/103 +resident frontmost: cycle 66/103 +resident frontmost: cycle 67/103 +resident frontmost: cycle 68/103 +resident frontmost: cycle 69/103 +resident frontmost: cycle 70/103 +resident frontmost: cycle 71/103 +resident frontmost: cycle 72/103 +resident frontmost: cycle 73/103 +resident frontmost: cycle 74/103 +resident frontmost: cycle 75/103 +resident frontmost: cycle 76/103 +resident frontmost: cycle 77/103 +resident frontmost: cycle 78/103 +resident frontmost: cycle 79/103 +resident frontmost: cycle 80/103 +resident frontmost: cycle 81/103 +resident frontmost: cycle 82/103 +resident frontmost: cycle 83/103 +resident frontmost: cycle 84/103 +resident frontmost: cycle 85/103 +resident frontmost: cycle 86/103 +resident frontmost: cycle 87/103 +resident frontmost: cycle 88/103 +resident frontmost: cycle 89/103 +resident frontmost: cycle 90/103 +resident frontmost: cycle 91/103 +resident frontmost: cycle 92/103 +resident frontmost: cycle 93/103 +resident frontmost: cycle 94/103 +resident frontmost: cycle 95/103 +resident frontmost: cycle 96/103 +resident frontmost: cycle 97/103 +resident frontmost: cycle 98/103 +resident frontmost: cycle 99/103 +resident frontmost: cycle 100/103 +resident frontmost: cycle 101/103 +resident frontmost: cycle 102/103 +resident frontmost: cycle 103/103 +resident frontmost PASS +resident background: cycle 1/103 +resident background: cycle 2/103 +resident background: cycle 3/103 +resident background: cycle 4/103 +resident background: cycle 5/103 +resident background: cycle 6/103 +resident background: cycle 7/103 +resident background: cycle 8/103 +resident background: cycle 9/103 +resident background: cycle 10/103 +resident background: cycle 11/103 +resident background: cycle 12/103 +resident background: cycle 13/103 +resident background: cycle 14/103 +resident background: cycle 15/103 +resident background: cycle 16/103 +resident background: cycle 17/103 +resident background: cycle 18/103 +resident background: cycle 19/103 +resident background: cycle 20/103 +resident background: cycle 21/103 +resident background: cycle 22/103 +resident background: cycle 23/103 +resident background: cycle 24/103 +resident background: cycle 25/103 +resident background: cycle 26/103 +resident background: cycle 27/103 +resident background: cycle 28/103 +resident background: cycle 29/103 +resident background: cycle 30/103 +resident background: cycle 31/103 +resident background: cycle 32/103 +resident background: cycle 33/103 +resident background: cycle 34/103 +resident background: cycle 35/103 +resident background: cycle 36/103 +resident background: cycle 37/103 +resident background: cycle 38/103 +resident background: cycle 39/103 +resident background: cycle 40/103 +resident background: cycle 41/103 +resident background: cycle 42/103 +resident background: cycle 43/103 +resident background: cycle 44/103 +resident background: cycle 45/103 +resident background: cycle 46/103 +resident background: cycle 47/103 +resident background: cycle 48/103 +resident background: cycle 49/103 +resident background: cycle 50/103 +resident background: cycle 51/103 +resident background: cycle 52/103 +resident background: cycle 53/103 +resident background: cycle 54/103 +resident background: cycle 55/103 +resident background: cycle 56/103 +resident background: cycle 57/103 +resident background: cycle 58/103 +resident background: cycle 59/103 +resident background: cycle 60/103 +resident background: cycle 61/103 +resident background: cycle 62/103 +resident background: cycle 63/103 +resident background: cycle 64/103 +resident background: cycle 65/103 +resident background: cycle 66/103 +resident background: cycle 67/103 +resident background: cycle 68/103 +resident background: cycle 69/103 +resident background: cycle 70/103 +resident background: cycle 71/103 +resident background: cycle 72/103 +resident background: cycle 73/103 +resident background: cycle 74/103 +resident background: cycle 75/103 +resident background: cycle 76/103 +resident background: cycle 77/103 +resident background: cycle 78/103 +resident background: cycle 79/103 +resident background: cycle 80/103 +resident background: cycle 81/103 +resident background: cycle 82/103 +resident background: cycle 83/103 +resident background: cycle 84/103 +resident background: cycle 85/103 +resident background: cycle 86/103 +resident background: cycle 87/103 +resident background: cycle 88/103 +resident background: cycle 89/103 +resident background: cycle 90/103 +resident background: cycle 91/103 +resident background: cycle 92/103 +resident background: cycle 93/103 +resident background: cycle 94/103 +resident background: cycle 95/103 +resident background: cycle 96/103 +resident background: cycle 97/103 +resident background: cycle 98/103 +resident background: cycle 99/103 +resident background: cycle 100/103 +resident background: cycle 101/103 +resident background: cycle 102/103 +resident background: cycle 103/103 +resident background PASS diff --git a/docs/verification/issue-386/resume/official-windows-comparison.txt b/docs/verification/issue-386/resume/official-windows-comparison.txt new file mode 100644 index 00000000..1f14b2e0 --- /dev/null +++ b/docs/verification/issue-386/resume/official-windows-comparison.txt @@ -0,0 +1,9 @@ +done: create_gameobject +done: hierarchy +done: eval +process background PASS +resident frontmost FAIL Invalid official NDJSON response: {'id': '15', 'exitCode': 6, 'envelope': {'success': False, 'command': 'unity command find_assets', 'data': None, 'errors': [{'code': 'COMMAND_FAILED', 'message': 'Pipeline server returned 400 Bad Request: Parameter Validation Failed. Illegal characters in path.'}], 'warnings': []}} +Traceback (most recent call last): + File "\.cache\issue-386\windows-comparison.py", line 168, in + raise RuntimeError(report['error']) +RuntimeError: Invalid official NDJSON response: {'id': '15', 'exitCode': 6, 'envelope': {'success': False, 'command': 'unity command find_assets', 'data': None, 'errors': [{'code': 'COMMAND_FAILED', 'message': 'Pipeline server returned 400 Bad Request: Parameter Validation Failed. Illegal characters in path.'}], 'warnings': []}} diff --git a/docs/verification/issue-386/resume/official-windows-process-background.json b/docs/verification/issue-386/resume/official-windows-process-background.json new file mode 100644 index 00000000..368adad7 --- /dev/null +++ b/docs/verification/issue-386/resume/official-windows-process-background.json @@ -0,0 +1,725 @@ +{ + "mode": "process", + "focus": "background", + "started_at": "2026-10-03T23:33:33.671584+00:00", + "conditions": { + "started_at": "2026-10-03T23:33:26.503448+00:00", + "os": "Windows-11-10.0.26300-SP0", + "arch": "AMD64", + "logical_cpus": 32, + "unity": "6000.4.4f1", + "editor_pid": 34324, + "iterations": 100, + "warmup": 3, + "unity_cli_build": "native Windows debug 0.18.1", + "official_cli_version": "1.0.0-beta.11", + "pipeline_version": "0.8.0-exp.1", + "unity_cli_sha256": "087d057cd62483c3c0aa64ceb85a77421349f2ace1ba236a13c1ddcffe909d35", + "official_cli_sha256": "4cad9230dd98cc8d123d3ef9d18fef5e7ee65f353814c3cf9d94d9129293dda3", + "benchmark_sha256": "857569c8c542221f43a27423ecfa8fce3d11a690ed979985ebc670a56912f372", + "windows_adapter_sha256": "1d72ca848808f1fcce45a46b133691c7c6119f908e67e9519f72759a19d5af7b", + "windows_adapter": "Original benchmark operations, validation, focus-discard and alternating order; Windows HWND foreground inspection and bounded reader thread replace macOS focus and POSIX select. No platform spoofing.", + "background_condition": "Owned Editor minimized, because Windows refused activation of the existing GWT background window. This differs from macOS visible-background measurements.", + "host_contention": "Other project canonical verification was active on this host; results are observations, no Windows budget or prior baseline was enforced.", + "coexistence": { + "same_project": true, + "unity_version": "6000.4.4f1", + "official_state": "ready", + "project_identity_sha256": "f87f40b8af586b040ebc3f0d64bf076a0bebf421cd38cb9af459bc31f2a0c69a" + }, + "play_settings": { + "assetNamingUsesSpace": true, + "defaultBehaviorMode": "Mode3D", + "enterPlayModeOptions": "DisableDomainReload", + "enterPlayModeOptionsEnabled": true, + "prefabModeRegularEnvironment": "None", + "prefabModeUIEnvironment": "None", + "serializationMode": "ForceText", + "unityRemote": "", + "unityRemoteCompression": "", + "unityRemoteResolution": "" + }, + "unityd_pid": 52020 + }, + "status": "PASS", + "samples_ms": { + "unity-cli": { + "create_gameobject": [ + 605.6073000072502, + 328.3432000025641, + 52.89600000833161, + 323.1718000024557, + 269.5679000171367, + 328.02190000074916, + 272.35279997694306, + 873.4148999792524, + 280.29410002636723, + 108.38699998566881, + 271.4110999950208, + 1298.708100017393, + 262.3355000105221, + 646.5700000117067, + 163.0806000030134, + 324.06559999799356, + 911.1498999991454, + 107.37559999688528, + 394.60900000995025, + 324.73530000424944, + 166.38619999866933, + 551.3350999972317, + 60.97220000810921, + 108.35530000622384, + 380.8351999905426, + 107.689800002845, + 253.52009999915026, + 108.23890002211556, + 257.7762999862898, + 320.421600015834, + 379.545900010271, + 107.77209998923354, + 57.62800000957213, + 109.61210000095889, + 62.73849998251535, + 109.10699999658391, + 55.765500001143664, + 109.06109999632463, + 713.6243999993894, + 325.06450000801124, + 67.57169999764301, + 111.10899999039248, + 52.06960000214167, + 108.84870000882074, + 168.52589999325573, + 108.78359997877851, + 272.3863999999594, + 109.1415999981109, + 161.0631000075955, + 115.54700002307072, + 56.088399986037984, + 108.2559000060428, + 46.24559998046607, + 437.0536000060383, + 374.8059999779798, + 869.6661000140011, + 151.6811999899801, + 431.5096000209451, + 258.46380001166835, + 106.35400001774542, + 382.7330000058282, + 106.9609000114724, + 46.803199977148324, + 326.51099999202415, + 52.639400004409254, + 108.92790000070818, + 381.78339999285527, + 109.50960000627674, + 67.00179999461398, + 106.6378999967128, + 375.56829999084584, + 323.965199990198, + 173.64809999708086, + 324.5712999778334, + 53.623099985998124, + 323.34350000019185, + 367.6952999958303, + 109.92699998314492, + 54.16410000179894, + 538.1455000024289, + 279.6530000050552, + 106.7754999967292, + 164.15779999806546, + 107.20610001590103, + 169.57410000031814, + 106.03469997295178, + 277.19079999951646, + 111.10420001205057, + 54.99590002000332, + 107.77100000996143, + 271.4088000066113, + 871.121200005291, + 63.99480000254698, + 109.75269999471493, + 63.85119998594746, + 107.80530000920407, + 161.35559999383986, + 108.49320000852458, + 161.89449999365024, + 106.42229998484254 + ], + "hierarchy": [ + 50.26459999498911, + 109.1106999956537, + 271.0017999925185, + 109.17839998728596, + 262.58599999709986, + 650.4975999996532, + 146.37719999882393, + 327.8392999782227, + 57.53109999932349, + 328.0473000195343, + 269.3594000011217, + 328.48680001916364, + 707.0984999882057, + 1302.6483000139706, + 45.62580000492744, + 330.20440000109375, + 271.6000999789685, + 326.31190001848154, + 379.9581999774091, + 1195.2394999971148, + 161.05850000167266, + 449.62490000762045, + 270.31689998693764, + 449.05490000382997, + 152.98000001348555, + 322.588100010762, + 483.69360002106987, + 542.783499986399, + 369.3881000217516, + 108.12339998665266, + 276.10489999642596, + 323.7198000133503, + 52.696699975058436, + 109.29719998966902, + 267.73380002123304, + 109.5729999942705, + 166.59330000402406, + 105.71440000785515, + 48.77149997628294, + 326.49430001038127, + 382.93459999840707, + 107.09000000497326, + 56.64659998728894, + 108.36559999734163, + 378.2704000186641, + 106.21359999640845, + 278.1216000148561, + 325.0322999956552, + 392.92380001279525, + 107.24150002351962, + 156.76719998009503, + 107.28349999408238, + 265.5679000017699, + 112.07970001851209, + 380.36949999514036, + 323.34169998648576, + 1138.9557000075001, + 1093.0855000042357, + 49.35829999158159, + 108.73649999848567, + 379.45330000366084, + 324.04249999672174, + 265.04019999993034, + 106.39000000082888, + 166.0803999984637, + 109.55309998826124, + 378.9260999765247, + 649.7044999850914, + 248.00099999993108, + 107.48690000036731, + 372.2241999930702, + 109.1018000151962, + 492.05169998458587, + 1193.699800001923, + 58.659100002842024, + 331.50020000175573, + 270.3670000191778, + 328.31790001364425, + 50.01879998599179, + 107.97829998773523, + 273.0763999861665, + 108.96979999961331, + 380.0825000216719, + 654.2654999939259, + 157.72129999822937, + 107.55720001179725, + 274.3408000096679, + 216.09370000078343, + 385.3168000059668, + 537.2032000159379, + 52.93219999293797, + 110.05720001412556, + 58.168500021565706, + 436.8937000108417, + 1009.9586000142153, + 654.7008999914397, + 38.89840000192635, + 328.5396999854129, + 61.23490000027232, + 110.3706999856513 + ], + "eval": [ + 2339.5842000027187, + 4569.908800011035, + 1476.8792999966536, + 1519.1033000010066, + 2864.2985000042245, + 3047.111199994106, + 1683.7008999718819, + 2586.835699999938, + 2659.78589997394, + 2396.2425000208896, + 2995.506299979752, + 1525.5285000021104, + 3227.094900008524, + 1516.777099983301, + 2020.1173000095878, + 1731.1214999936055, + 2464.2919000179972, + 2160.475399985444, + 1488.6460999841802, + 1639.367299998412, + 1705.481899989536, + 2602.5162000150885, + 2112.8054999862798, + 1413.7207999883685, + 2234.1053999844007, + 1407.2282999986783, + 1920.039699994959, + 1628.7469000089914, + 1695.9859999769833, + 1627.3355000012089, + 1469.2592999781482, + 2819.4982999993954, + 1357.7188999915961, + 3256.913099990925, + 3542.0168999989983, + 1624.201600003289, + 2668.820199993206, + 1843.1704000104219, + 2996.5378000051714, + 1736.7984000011347, + 3553.7040999915916, + 1625.1032000000123, + 1373.6894000030588, + 2061.9820000138134, + 1592.7552999928594, + 1851.4304000127595, + 1492.5052000035066, + 3483.3035999909043, + 1260.4530999960843, + 2278.4625999920536, + 1267.0261999883223, + 2823.883500008378, + 1153.1535000249278, + 2823.89269999112, + 1687.7078000106849, + 2053.788099990925, + 1915.517200017348, + 2386.4805000193883, + 1472.3100000119302, + 1518.2515000051353, + 1700.7666999998037, + 1194.7454999899492, + 2894.102800026303, + 1635.5786999920383, + 1373.7651999981608, + 1414.3711000215262, + 1259.7027999872807, + 1634.8997000022791, + 2247.151899995515, + 1636.8799000047147, + 2894.4030000129715, + 1634.0859000047203, + 1575.139200023841, + 1413.0486999929417, + 1689.5557999960147, + 1740.3607000014745, + 1161.2214000197127, + 2076.0534000000916, + 1708.2287999801338, + 2710.64900001511, + 2039.9032999994233, + 1407.839099992998, + 2454.226200003177, + 2271.4825000148267, + 1365.3761000023223, + 2938.633000012487, + 1706.4500999986194, + 2387.900300003821, + 1374.623799987603, + 1960.1432000054047, + 2471.7923999996856, + 1632.8779000032227, + 1385.0200999877416, + 2059.381700004451, + 2134.0354999992996, + 1516.9847000215668, + 2781.4854999887757, + 1519.804400013527, + 1373.7229999969713, + 1191.391800006386 + ] + }, + "official": { + "create_gameobject": [ + 1692.9628000070807, + 607.91479999898, + 1141.0181999963243, + 596.7518000106793, + 926.2150000140537, + 1134.8158000037074, + 596.7947000171989, + 596.035100024892, + 807.0727000012994, + 597.3430999729317, + 813.3095999946818, + 597.0667999936268, + 932.9488000075798, + 1459.9370999785606, + 592.8506999916863, + 912.9013000056148, + 825.062899995828, + 920.4994999745395, + 905.9628999966662, + 598.6591000109911, + 806.9105000176933, + 804.8545999918133, + 591.0880999872461, + 592.5738999794703, + 809.1336000070442, + 600.3899999777786, + 832.4640999780968, + 586.9321000063792, + 609.3196000147145, + 595.2139000000898, + 1684.8775999969803, + 607.6966999971773, + 812.0400000188965, + 817.9273999994621, + 592.3167000000831, + 920.105400000466, + 596.0520000080578, + 587.9471999942325, + 811.6549999976996, + 596.1275000008754, + 698.5706000123173, + 815.9800999856088, + 817.6630999951158, + 598.8053000182845, + 593.50029999041, + 590.6177000142634, + 598.3680000063032, + 595.4998999950476, + 814.4608000002336, + 617.3426999885123, + 594.9384999985341, + 927.6695000007749, + 1691.1054000083823, + 591.1487999837846, + 602.5730000110343, + 603.9135000028182, + 599.5295000029728, + 816.0808999964502, + 603.949400014244, + 601.9237000145949, + 920.4767000046559, + 594.2809000262059, + 602.4394000123721, + 919.4945000053849, + 595.7070000004023, + 595.2001999830827, + 813.4987000084948, + 594.0910000063013, + 586.8322999740485, + 586.6260000038892, + 814.2831000150181, + 925.4302000044845, + 586.2817000015639, + 583.2201999728568, + 922.7895999792963, + 815.3183999820612, + 2013.6338000011165, + 581.0649000050034, + 924.2710999969859, + 923.1608000118285, + 590.269200009061, + 927.7079000021331, + 924.0717000211589, + 597.1237999910954, + 806.5069000003859, + 607.7913000190165, + 808.94580000313, + 592.0111000014003, + 596.323100005975, + 605.3160000010394, + 814.7871000110172, + 812.6983999973163, + 912.0663999929093, + 594.1832000098657, + 589.7402999980841, + 914.1923999995925, + 815.0052000128198, + 593.1709000142291, + 596.9922000076622, + 922.7933999791276 + ], + "hierarchy": [ + 628.257800010033, + 940.1053999899887, + 1057.5743000081275, + 594.4877000001725, + 653.7952999933623, + 1137.9101000202354, + 882.8850999998394, + 613.2660000002943, + 851.8154000048526, + 595.3104999789502, + 862.18260001624, + 913.5425999993458, + 762.9336999962106, + 586.4815999811981, + 883.6370999924839, + 611.025200021686, + 848.8696999847889, + 912.9889000032563, + 653.2727000012528, + 2115.616700000828, + 685.815700009698, + 608.068599976832, + 874.8232000216376, + 909.0695999911986, + 760.7724000117742, + 922.3499000072479, + 980.4536000010557, + 591.6617000184488, + 661.6693999967538, + 918.2953999843448, + 654.102900007274, + 807.4274999962654, + 1203.740500001004, + 608.6874000029638, + 636.6551999817602, + 600.6510999868624, + 644.3772000202443, + 817.6723000069614, + 979.86699998728, + 904.2066000110935, + 1750.249900011113, + 599.9688000010792, + 648.0336999811698, + 589.4606999936514, + 662.133800011361, + 811.5841000108048, + 646.9280000019353, + 1131.2644999998156, + 1192.7020000002813, + 590.2479000214953, + 661.5108999831136, + 917.1131999755744, + 657.4228999961633, + 817.2909999848343, + 641.9102999789175, + 935.9372000035364, + 1180.208199977642, + 578.4156000008807, + 669.708899979014, + 801.8150000134483, + 883.7103999976534, + 1134.4650000100955, + 870.5675999808591, + 596.9829999958165, + 646.5061999915633, + 932.8165999904741, + 748.7123000028078, + 1138.1800999806728, + 661.954200011678, + 598.480999993626, + 656.4611999783665, + 817.8262999863364, + 860.0339999829885, + 1145.6196999934036, + 647.0373999909498, + 593.7463000009302, + 865.344499994535, + 808.6051999998745, + 659.268899995368, + 599.5751000009477, + 644.9228000128642, + 799.860200000694, + 663.7532000022475, + 584.7528000012971, + 665.450200001942, + 916.1342000006698, + 754.4052999874111, + 812.1136000263505, + 862.4981000029948, + 1327.8749999881256, + 555.3261000022758, + 836.2561000103597, + 839.1202999919187, + 811.0423999896739, + 788.1098999932874, + 630.4722000204492, + 888.235699996585, + 602.4147999996785, + 638.2593000016641, + 811.0922999912873 + ], + "eval": [ + 663.7462000071537, + 590.5653999943752, + 559.6364999946672, + 803.1189999892376, + 1445.2729999902658, + 705.0703999993857, + 770.6877000164241, + 702.1824000112247, + 896.6027999995276, + 711.8371000105981, + 769.8750000272412, + 586.1918999871705, + 884.8713999905158, + 600.5400999856647, + 556.0431999911088, + 704.0178000170272, + 767.9735000128858, + 945.643499988364, + 1475.7234000135213, + 1354.0219999849796, + 555.2402999892365, + 920.9975999838207, + 783.4385000169277, + 704.422800015891, + 558.7172000086866, + 1310.3668999974616, + 712.0451999944635, + 1375.5561000143643, + 658.3643000049051, + 586.3456999941263, + 571.4160999923479, + 597.9102000128478, + 561.1664000025485, + 919.8132999881636, + 669.2735999822617, + 833.8019000075292, + 650.4381999839097, + 605.5811999831349, + 765.5293000279926, + 916.0731000010855, + 1004.6139000041876, + 926.5944000217132, + 883.6087000090629, + 1026.8939999805298, + 565.6873999978416, + 715.2320999884978, + 645.3178999945521, + 705.7334999844898, + 567.1363000001293, + 593.8037000014447, + 560.1671000185888, + 590.4756000090856, + 563.6312999995425, + 593.5501999920234, + 666.8066000274848, + 719.3939999851864, + 651.7794999817852, + 578.1452000082936, + 587.3210999998264, + 607.6965999964159, + 856.2536999816075, + 1140.2960999985225, + 773.8606999919284, + 600.5978000175674, + 664.0113999892492, + 708.3361000113655, + 556.5513999899849, + 1133.3578000194393, + 669.0946999879088, + 921.0164999822155, + 890.4925999813713, + 1139.2439000192098, + 581.3706000044476, + 1372.0850000099745, + 661.5189000149257, + 590.1499000028707, + 571.277100010775, + 612.2273000073619, + 643.242599995574, + 592.188000009628, + 550.8354000048712, + 588.0965999967884, + 895.3768000064883, + 1157.5292000197805, + 647.8508999862242, + 702.0497000194155, + 775.2321999869309, + 608.0096999939997, + 652.281699993182, + 819.7941000107676, + 667.3832999949809, + 1151.0103999753483, + 655.0244000100065, + 802.7354000078049, + 566.9175999937579, + 596.5594000008423, + 668.505700014066, + 610.5440999963321, + 1194.983900000807, + 607.7109000179917 + ] + } + }, + "details": { + "discarded_focus_pairs": { + "create_gameobject": 0, + "hierarchy": 0, + "eval": 0 + } + }, + "results": { + "unity-cli": { + "create_gameobject": { + "n": 100, + "p50_ms": 161.36, + "p95_ms": 713.62, + "mean_ms": 244.51, + "min_ms": 46.25, + "max_ms": 1298.71 + }, + "hierarchy": { + "n": 100, + "p50_ms": 270.32, + "p95_ms": 1009.96, + "mean_ms": 305.49, + "min_ms": 38.9, + "max_ms": 1302.65 + }, + "eval": { + "n": 100, + "p50_ms": 1708.23, + "p95_ms": 3227.09, + "mean_ms": 2008.18, + "min_ms": 1153.15, + "max_ms": 4569.91 + } + }, + "official": { + "create_gameobject": { + "n": 100, + "p50_ms": 607.91, + "p95_ms": 1141.02, + "mean_ms": 770.05, + "min_ms": 581.06, + "max_ms": 2013.63 + }, + "hierarchy": { + "n": 100, + "p50_ms": 788.11, + "p95_ms": 1180.21, + "mean_ms": 806.58, + "min_ms": 555.33, + "max_ms": 2115.62 + }, + "eval": { + "n": 100, + "p50_ms": 668.51, + "p95_ms": 1310.37, + "mean_ms": 760.99, + "min_ms": 550.84, + "max_ms": 1475.72 + } + } + }, + "finished_at": "2026-10-03T23:42:59.192326+00:00" +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/official-windows-process-frontmost.json b/docs/verification/issue-386/resume/official-windows-process-frontmost.json new file mode 100644 index 00000000..f8a39dc3 --- /dev/null +++ b/docs/verification/issue-386/resume/official-windows-process-frontmost.json @@ -0,0 +1,724 @@ +{ + "mode": "process", + "focus": "frontmost", + "started_at": "2026-10-03T23:20:37.824904+00:00", + "conditions": { + "started_at": "2026-10-03T23:20:30.496681+00:00", + "os": "Windows-11-10.0.26300-SP0", + "arch": "AMD64", + "logical_cpus": 32, + "unity": "6000.4.4f1", + "editor_pid": 34324, + "iterations": 100, + "warmup": 3, + "unity_cli_build": "native Windows debug 0.18.1", + "official_cli_version": "1.0.0-beta.11", + "pipeline_version": "0.8.0-exp.1", + "unity_cli_sha256": "087d057cd62483c3c0aa64ceb85a77421349f2ace1ba236a13c1ddcffe909d35", + "official_cli_sha256": "4cad9230dd98cc8d123d3ef9d18fef5e7ee65f353814c3cf9d94d9129293dda3", + "benchmark_sha256": "857569c8c542221f43a27423ecfa8fce3d11a690ed979985ebc670a56912f372", + "windows_adapter_sha256": "dbe8d15ea394b39cea39f92764a45fbedaeae0b7fa8219061d0c2b281946a99c", + "windows_adapter": "Original benchmark operations, validation, focus-discard and alternating order; Windows HWND foreground inspection and bounded reader thread replace macOS focus and POSIX select. No platform spoofing.", + "host_contention": "Other project canonical verification was active on this host; results are observations, no Windows budget or prior baseline was enforced.", + "coexistence": { + "same_project": true, + "unity_version": "6000.4.4f1", + "official_state": "ready", + "project_identity_sha256": "f87f40b8af586b040ebc3f0d64bf076a0bebf421cd38cb9af459bc31f2a0c69a" + }, + "play_settings": { + "assetNamingUsesSpace": true, + "defaultBehaviorMode": "Mode3D", + "enterPlayModeOptions": "DisableDomainReload", + "enterPlayModeOptionsEnabled": true, + "prefabModeRegularEnvironment": "None", + "prefabModeUIEnvironment": "None", + "serializationMode": "ForceText", + "unityRemote": "", + "unityRemoteCompression": "", + "unityRemoteResolution": "" + }, + "unityd_pid": 52020 + }, + "status": "PASS", + "samples_ms": { + "unity-cli": { + "create_gameobject": [ + 379.23620000947267, + 37.30220001307316, + 335.3181999991648, + 882.032599998638, + 43.45240001566708, + 44.612100027734414, + 119.85630000708625, + 46.17310001049191, + 477.07680001622066, + 40.632099990034476, + 193.04980000015348, + 62.874099996406585, + 251.00659998133779, + 1155.2138000261039, + 39.59599998779595, + 341.106400010176, + 47.12979999021627, + 42.41690001799725, + 181.321600015508, + 41.80400000768714, + 284.74149998510256, + 40.00030001043342, + 49.26150001119822, + 39.183200016850606, + 780.3609000111464, + 48.15170000074431, + 46.72099999152124, + 335.5914000130724, + 40.955200005555525, + 321.9041000120342, + 655.4335999826435, + 40.12510000029579, + 242.90069998824038, + 40.53659999044612, + 696.1764000006951, + 53.91079999390058, + 304.8699999926612, + 45.51309999078512, + 226.86130000511184, + 596.4386999839917, + 38.439399999333546, + 41.08940000878647, + 49.95689998031594, + 40.89929998735897, + 164.59599998779595, + 47.68290001084097, + 206.7834000044968, + 306.14780000178143, + 45.76819998328574, + 324.079600017285, + 454.7598999924958, + 41.45720001542941, + 466.12610001466237, + 854.4175999995787, + 36.36860000551678, + 339.08119998523034, + 38.971400004811585, + 52.21159997745417, + 772.0032000215724, + 39.19340000720695, + 307.40369998966344, + 310.92819999321364, + 37.96320001129061, + 40.92449997551739, + 259.25559998722747, + 924.9335000058636, + 41.59189999336377, + 322.91820002137683, + 73.3089999994263, + 43.23459998704493, + 217.73919998668134, + 567.6209000230301, + 37.50490001402795, + 344.2325000069104, + 157.09059999790043, + 37.61990001657978, + 162.66659999382682, + 290.41180000058375, + 185.68559997947887, + 312.15769998379983, + 35.77200000290759, + 43.68169998633675, + 90.67809997941367, + 42.41959998034872, + 312.2000999865122, + 594.0995999844745, + 300.993600016227, + 295.7701999985147, + 38.33480001776479, + 320.61399999656714, + 657.2042999905534, + 41.391000006115064, + 152.55790000082925, + 37.30120000545867, + 245.4913999827113, + 292.1578000241425, + 322.10039999336004, + 38.996599992970005, + 88.3077000034973, + 39.900400006445125 + ], + "hierarchy": [ + 35.91460001189262, + 46.82280000997707, + 292.7416999882553, + 36.95459998562001, + 80.3691000037361, + 34.123599994927645, + 241.17589998058975, + 36.039099999470636, + 35.7273000117857, + 35.09639998083003, + 259.5468999934383, + 39.4316999881994, + 383.55569998384453, + 40.131600020686164, + 38.082600018242374, + 38.202499999897555, + 140.82349999807775, + 316.81509999907576, + 658.1195000035223, + 40.71450000628829, + 267.08300001337193, + 38.2147999771405, + 375.2803999814205, + 873.3879999781493, + 308.37850001989864, + 41.16180000710301, + 677.9377000057139, + 604.5374000095762, + 944.425699999556, + 1349.0058000024874, + 45.71770000620745, + 40.753600012976676, + 433.2070000236854, + 1433.735800004797, + 58.318299998063594, + 35.479400015901774, + 82.23610001732595, + 36.680699995486066, + 146.22359999339096, + 35.92319999006577, + 146.84299999498762, + 43.738200009102, + 182.11900000460446, + 554.9292000068817, + 36.86230001039803, + 35.96760000800714, + 188.1160000048112, + 1126.1574999953154, + 36.91900000558235, + 33.44689999357797, + 187.06879997625947, + 320.30700001632795, + 619.1199000168126, + 549.8272999830078, + 38.657299999613315, + 36.97319998173043, + 264.25899998866953, + 300.6753000081517, + 247.43370001669973, + 37.76619999553077, + 41.150899982312694, + 39.282499987166375, + 39.28119997726753, + 36.48260000045411, + 100.0726000056602, + 315.3327999752946, + 36.09750000759959, + 36.20470000896603, + 269.0707999863662, + 36.95259999949485, + 256.4090999949258, + 308.8982999906875, + 37.397800013422966, + 37.53520001191646, + 37.593299988657236, + 39.553900016471744, + 37.36260000732727, + 37.19969998928718, + 37.394999992102385, + 36.273299978347495, + 261.4248000027146, + 36.116500006755814, + 36.45039998809807, + 36.28709999611601, + 282.69409999484196, + 38.638199999695644, + 671.4688999927603, + 39.14710000390187, + 165.4227999970317, + 36.0538000240922, + 118.26560000190511, + 294.553999992786, + 86.02170000085607, + 36.87150002224371, + 35.68099997937679, + 315.6048000091687, + 663.403799990192, + 37.68599999602884, + 36.411300010513514, + 37.10190000128932 + ], + "eval": [ + 1122.2228000115138, + 2184.8367999773473, + 1465.3466999880038, + 3199.8299000260886, + 1283.9716000016779, + 2758.778200019151, + 1332.5039999908768, + 2451.4867999823764, + 1481.917600001907, + 2240.3870999987703, + 1869.3315999989863, + 1335.664899990661, + 2084.36380000785, + 1195.9346000221558, + 4447.494099993492, + 1690.1799999759533, + 2740.0732999958564, + 1484.3457999813836, + 1044.3052999908105, + 1349.8792000173125, + 2596.7012999753933, + 1334.2152000113856, + 1453.9805999957025, + 2240.8099000167567, + 1236.6826000215951, + 3058.8268999999855, + 2382.3672000144143, + 2617.990300001111, + 2798.078199994052, + 2361.4052000048105, + 1702.6805999921635, + 1595.0356999819633, + 2431.8580999970436, + 1819.6503999934066, + 3780.548600014299, + 2939.343700010795, + 1330.7397000025958, + 2531.5621999907307, + 2186.5448000025935, + 1224.6409000072163, + 2775.6010000011884, + 1427.3137999989558, + 1655.0097000144888, + 2386.183099995833, + 1509.4224999775179, + 1537.9924000008032, + 1948.7420999794267, + 2618.6880999885034, + 1465.4988000111189, + 2778.2095999864396, + 2688.282600021921, + 1638.9205000014044, + 2430.2959000051487, + 1900.2047999820206, + 1841.9775000074878, + 3523.7804999924265, + 2766.7572000063956, + 1517.3430000140797, + 2501.9542000081856, + 1417.5220000033733, + 2784.905100008473, + 2166.4723999856506, + 1617.452400008915, + 1307.3021000018343, + 1611.870499997167, + 1475.8675999764819, + 1263.3239999995567, + 3636.337800009642, + 1281.7352999991272, + 2034.6357999951579, + 1568.691199994646, + 1212.3496999847703, + 2449.4135999993887, + 1410.7231000089087, + 2064.1815999988467, + 2032.3689999931958, + 2764.947200019378, + 1749.753200012492, + 2212.8204999899026, + 1284.6533000119962, + 1444.8642999923322, + 2228.0969999847002, + 1871.8006999988575, + 2242.743700015126, + 1291.015700000571, + 1271.8228999874555, + 1699.9154999793973, + 1531.1534999927972, + 1520.1436000061221, + 1175.5138000007719, + 1318.5999999986961, + 1372.12390001514, + 1438.1820000126027, + 3522.4537999893073, + 1503.9091000217013, + 1806.5246999904048, + 3674.8812000150792, + 1873.7338000210002, + 1485.005899972748, + 1335.8233000035398 + ] + }, + "official": { + "create_gameobject": [ + 836.8951999873389, + 552.3287999967579, + 837.0877999986988, + 1400.4030999785755, + 571.9647000078112, + 841.7656000237912, + 824.8915000003763, + 572.2386999987066, + 539.7041999967769, + 561.3454999984242, + 537.6740999927279, + 555.9048000141047, + 550.6917999882717, + 543.282900005579, + 533.4060000022873, + 850.2990000124555, + 558.1093000073452, + 869.3073999893386, + 837.1387999795843, + 556.1094000004232, + 552.4989999830723, + 554.1457000072114, + 551.212000020314, + 536.4024000009522, + 811.7838999896776, + 559.122299979208, + 551.1394999921322, + 823.489200003678, + 548.9821000082884, + 566.9062999950256, + 841.8235999997705, + 574.5290000049863, + 549.0537000005133, + 835.4294000018854, + 1755.6846000079531, + 582.0211000100244, + 801.0702999890782, + 541.0677999898326, + 555.3280999884009, + 1928.0552999989595, + 548.4133999852929, + 801.7754000029527, + 555.5991999863181, + 537.9204000055324, + 798.4765000001062, + 556.074299995089, + 859.1498000023421, + 1385.6996999820694, + 598.7552999868058, + 564.0027000044938, + 847.1705999982078, + 554.4733999995515, + 816.8571999995038, + 555.1908000197727, + 806.4855000120588, + 1420.810799987521, + 558.8617000030354, + 824.25519998651, + 835.7659000030253, + 553.0859999998938, + 821.3891000195872, + 814.9581000034232, + 559.5436999865342, + 539.7870000160765, + 633.4399999759626, + 1410.4073000198696, + 536.7832999909297, + 544.8117000050843, + 547.1652999985963, + 853.8895000237972, + 550.6004999915604, + 1606.1584999843035, + 830.6690999888815, + 550.6563999806531, + 1373.1058000121266, + 542.3157000041101, + 549.7940999921411, + 1374.5527999999467, + 579.1980000212789, + 812.7319999912288, + 543.7557999975979, + 846.5046000201255, + 1124.6145000040997, + 548.5615000070538, + 1240.6709999777377, + 1085.980700008804, + 535.2843999862671, + 548.5031999996863, + 549.704400007613, + 549.726199998986, + 814.5881000091322, + 566.8900000164285, + 557.2279999905732, + 561.8774000031408, + 813.0667000077665, + 1032.941999990726, + 544.0036999934819, + 820.9096000064164, + 1380.4475000069942, + 553.1272999942303 + ], + "hierarchy": [ + 616.3446000136901, + 549.2249999952037, + 539.2072000249755, + 803.4602999978233, + 645.9189000015613, + 813.637999992352, + 592.8158999886364, + 557.9418999841437, + 534.359699988272, + 538.6368999897968, + 561.0653999901842, + 546.9243999978062, + 647.0127999782562, + 544.7272000019439, + 650.0313000287861, + 542.985400010366, + 552.3729999840725, + 815.803200006485, + 1426.5312000061385, + 604.1093000094406, + 849.5179000019561, + 837.1186000003945, + 684.860999986995, + 576.269199984381, + 553.750899998704, + 826.0745999868959, + 719.1768000193406, + 815.6349999771919, + 887.2531999950297, + 552.3322999943048, + 695.4934000095818, + 532.5211999879684, + 803.5999999847263, + 1074.8677000228781, + 558.1949999905191, + 823.4121999994386, + 952.8983999916818, + 555.181600007927, + 537.8537999931723, + 551.6974999918602, + 607.1682999900077, + 556.682099995669, + 802.9559999995399, + 1360.6298999802675, + 551.541199994972, + 545.5173999944236, + 771.6000000073109, + 1084.4878999923822, + 738.5234999819659, + 561.5104000025894, + 772.8671999939252, + 804.5443000155501, + 906.0814999975264, + 1109.0810999739915, + 523.7291000084952, + 544.0490999899339, + 813.1792999920435, + 1082.5282000005245, + 1652.0352000079583, + 547.4735000170767, + 542.4660000135191, + 544.3130000203382, + 620.8670999913011, + 810.3768000146374, + 809.3845999974292, + 798.1396999966819, + 840.8345999778248, + 550.7075999921653, + 557.234799984144, + 553.5084000148345, + 554.8393999924883, + 823.5937999852467, + 1288.4242000000086, + 559.2820000019856, + 548.7732000183314, + 833.1147000135388, + 995.9725000080653, + 549.4322000013199, + 546.4693999965675, + 541.5608000184875, + 809.7404000000097, + 787.1995999885257, + 1144.8302999779116, + 547.3175999941304, + 838.9052999846172, + 833.1672000058461, + 742.3469999921508, + 541.562200000044, + 720.5833999905735, + 538.4854000003543, + 732.0183000119869, + 1063.097000005655, + 578.3069000171963, + 545.0112000107765, + 530.7324999885168, + 531.1866000120062, + 919.9921000108588, + 541.1679999961052, + 615.2790999913123, + 557.1909999998752 + ], + "eval": [ + 565.0669999886304, + 597.505599987926, + 577.5711000023875, + 563.0882999976166, + 564.7161000233609, + 837.112100009108, + 693.5228999936953, + 586.3650999963284, + 841.7087999987416, + 703.9086000004318, + 573.1265000067651, + 736.3982000097167, + 791.0812000045553, + 750.2384999825153, + 614.4908000133, + 579.6021000132896, + 924.4792999816127, + 565.2177000010852, + 643.8489000138361, + 785.3359000000637, + 675.6101000064518, + 602.0863000012469, + 1271.797699999297, + 593.0282999761403, + 585.741799994139, + 635.1495999842882, + 754.5419000089169, + 836.9341999932658, + 822.8387999988627, + 1111.6669999901205, + 1857.4872000026517, + 887.4290000239853, + 653.2504000060726, + 579.2431000154465, + 1000.8786999969743, + 1046.1273999826517, + 605.2696999977343, + 705.4572999768425, + 822.3813999793492, + 578.8104999810457, + 840.723999979673, + 820.0598999974318, + 936.073100019712, + 1368.6808999918867, + 584.868700010702, + 1417.5548999919556, + 587.5485999858938, + 741.7023000016343, + 600.949399988167, + 768.2687999913469, + 859.1997000039555, + 854.229899996426, + 696.2045000109356, + 895.1268999953754, + 1584.0171000163537, + 744.9928999994881, + 549.8604000022169, + 733.0984000000171, + 573.3010999974795, + 618.986399989808, + 978.1365999951959, + 1374.5965999842156, + 1187.5701999815647, + 598.1797999993432, + 1011.0834999941289, + 1083.71609999449, + 722.6399000210222, + 872.9446000070311, + 559.9683999898843, + 664.1824999824166, + 771.752300002845, + 558.3886000094935, + 958.1169000011869, + 572.7062999794725, + 898.2803000253625, + 763.5088999813888, + 575.7658999937121, + 577.8483999893069, + 991.2758999853395, + 1401.742899994133, + 561.7801999906078, + 1907.7893999929074, + 554.6922999783419, + 1371.8016000057105, + 563.3891000179574, + 553.3252999885008, + 1005.0155000062659, + 830.1905999833252, + 929.3857000011485, + 1032.1992999815848, + 552.6748000120278, + 1365.6160999962594, + 754.2814999760594, + 542.9434000106994, + 568.88269999763, + 866.9413000170607, + 623.1765999982599, + 595.4669000057038, + 1834.5123000035528, + 563.4424999880139 + ] + } + }, + "details": { + "discarded_focus_pairs": { + "create_gameobject": 0, + "hierarchy": 0, + "eval": 0 + } + }, + "results": { + "unity-cli": { + "create_gameobject": { + "n": 100, + "p50_ms": 152.56, + "p95_ms": 772.0, + "mean_ms": 226.76, + "min_ms": 35.77, + "max_ms": 1155.21 + }, + "hierarchy": { + "n": 100, + "p50_ms": 41.16, + "p95_ms": 677.94, + "mean_ms": 207.26, + "min_ms": 33.45, + "max_ms": 1433.74 + }, + "eval": { + "n": 100, + "p50_ms": 1749.75, + "p95_ms": 3522.45, + "mean_ms": 1982.54, + "min_ms": 1044.31, + "max_ms": 4447.49 + } + }, + "official": { + "create_gameobject": { + "n": 100, + "p50_ms": 566.91, + "p95_ms": 1400.4, + "mean_ms": 751.79, + "min_ms": 533.41, + "max_ms": 1928.06 + }, + "hierarchy": { + "n": 100, + "p50_ms": 616.34, + "p95_ms": 1109.08, + "mean_ms": 717.94, + "min_ms": 523.73, + "max_ms": 1652.04 + }, + "eval": { + "n": 100, + "p50_ms": 736.4, + "p95_ms": 1401.74, + "mean_ms": 815.95, + "min_ms": 542.94, + "max_ms": 1907.79 + } + } + }, + "finished_at": "2026-10-03T23:29:28.578618+00:00" +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/official-windows-resident-background.json b/docs/verification/issue-386/resume/official-windows-resident-background.json new file mode 100644 index 00000000..a1bd9338 --- /dev/null +++ b/docs/verification/issue-386/resume/official-windows-resident-background.json @@ -0,0 +1,5512 @@ +{ + "mode": "resident", + "focus": "background", + "started_at": "2026-10-04T00:43:08.818390+00:00", + "conditions": { + "started_at": "2026-10-04T00:00:25.043499+00:00", + "os": "Windows-11-10.0.26300-SP0", + "arch": "AMD64", + "logical_cpus": 32, + "unity": "6000.4.4f1", + "editor_pid": 34324, + "iterations": 100, + "warmup": 3, + "unity_cli_build": "native Windows debug 0.18.1", + "official_cli_version": "1.0.0-beta.11", + "pipeline_version": "0.8.0-exp.1", + "unity_cli_sha256": "087d057cd62483c3c0aa64ceb85a77421349f2ace1ba236a13c1ddcffe909d35", + "official_cli_sha256": "4cad9230dd98cc8d123d3ef9d18fef5e7ee65f353814c3cf9d94d9129293dda3", + "benchmark_sha256": "8b4a77c97260fec724a5d1187c1561a7a0f25d9c3734fe8eada1c0a3ca4bc1e6", + "windows_adapter_sha256": "c47d896f41e81c6db8ba63ced94e927388b55cc81796b54578b3135685929c8a", + "windows_adapter": "Original benchmark operations, validation, focus-discard and alternating order; Windows HWND foreground inspection and bounded reader thread replace macOS focus and POSIX select. No platform spoofing.", + "background_condition": "Owned Editor minimized, because Windows refused activation of the existing GWT background window. This differs from macOS visible-background measurements.", + "host_contention": "Other project canonical verification was active on this host; results are observations, no Windows budget or prior baseline was enforced.", + "coexistence": { + "same_project": true, + "unity_version": "6000.4.4f1", + "official_state": "ready", + "project_identity_sha256": "f87f40b8af586b040ebc3f0d64bf076a0bebf421cd38cb9af459bc31f2a0c69a" + }, + "play_settings": { + "assetNamingUsesSpace": true, + "defaultBehaviorMode": "Mode3D", + "enterPlayModeOptions": "DisableDomainReload", + "enterPlayModeOptionsEnabled": true, + "prefabModeRegularEnvironment": "None", + "prefabModeUIEnvironment": "None", + "serializationMode": "ForceText", + "unityRemote": "", + "unityRemoteCompression": "", + "unityRemoteResolution": "" + }, + "unityd_pid": 56288 + }, + "status": "PASS", + "samples_ms": { + "unity-cli": { + "editor_state": [ + 123.60029999399558, + 102.08609999972396, + 230.93380001955666, + 201.9631000002846, + 348.2147000031546, + 36.12179998890497, + 546.7104999988806, + 48.864099982893094, + 116.34619999676943, + 105.47999999835156, + 631.9852999877185, + 310.12499998905696, + 113.92219999106601, + 405.79609997803345, + 135.29840001137927, + 307.83570001949556, + 232.27939999196678, + 210.46930001466535, + 426.05599999660626, + 105.5552999896463, + 826.8361999944318, + 100.06399999838322, + 41.035300004296005, + 38.13699999591336, + 411.32719998131506, + 202.55630000610836, + 118.45999999786727, + 305.99870000150986, + 122.31000000610948, + 101.03740001795813, + 434.4320000091102, + 204.70150001347065, + 108.3890000008978, + 1004.0328000031877, + 207.55159997497685, + 307.5640000170097, + 315.4836999892723, + 307.14270001044497, + 127.64470002730377, + 204.88860001205467, + 220.03600001335144, + 307.9353999928571, + 816.7226999939885, + 706.6772999824025, + 541.3767000136431, + 634.8133999854326, + 323.97280001896434, + 306.2294999836013, + 128.26729999505915, + 309.74299999070354, + 128.4289000032004, + 307.13359999936074, + 368.8362000102643, + 335.3606000018772, + 431.2031999870669, + 307.1084000112023, + 40.15759998583235, + 305.90550001943484, + 127.68760000471957, + 105.26739998022094, + 421.18780000600964, + 406.46500000730157, + 218.977000011364, + 104.82730000512674, + 219.77669998886995, + 105.40490000857972, + 1820.3703999752179, + 203.5557999915909, + 126.28090000362135, + 104.12129998439923, + 348.7765000027139, + 302.5478000054136, + 41.54899998684414, + 37.588999985018745, + 128.12060001306236, + 99.71449998556636, + 430.2912999992259, + 97.6678000006359, + 120.71659998036921, + 100.09329998865724, + 123.14320000587031, + 103.43759998795576, + 116.20940000284463, + 95.72529999422841, + 45.07680001552217, + 106.62659999798052, + 127.7952000091318, + 105.20610000821762, + 215.84920000168495, + 203.10579999932088, + 123.61180002335459, + 104.44590001134202, + 138.09690001653507, + 608.8491999835242, + 121.22879998059943, + 38.94820000277832, + 120.4804000153672, + 105.63569999067113, + 154.4869000208564, + 807.3340999835636 + ], + "hierarchy": [ + 40.62980000162497, + 400.83870000671595, + 312.7403999969829, + 100.14110000338405, + 40.91770001105033, + 39.27239999757148, + 595.601999986684, + 41.038099996512756, + 104.14589999709278, + 402.4109000165481, + 1398.2180999882985, + 299.8669999942649, + 102.35320002539083, + 101.83030000189319, + 39.516699995147064, + 300.4413999733515, + 398.81539999623783, + 291.692900005728, + 101.88659999403171, + 401.2229999934789, + 599.7502999962308, + 101.195800001733, + 40.463400015141815, + 39.606799982720986, + 401.8139000108931, + 103.45439999946393, + 304.5890999783296, + 399.4356999755837, + 299.5958999963477, + 101.56700000516139, + 600.3965999989305, + 899.072400003206, + 397.5194999948144, + 100.66759999608621, + 103.09839999536052, + 97.9100999829825, + 105.03790000802837, + 901.5735999855679, + 102.0313999906648, + 100.90609997860156, + 301.5443999902345, + 897.3343000106979, + 901.423999981489, + 702.6830999820959, + 52.35949999769218, + 582.5834000133909, + 401.6002000134904, + 304.32110000401735, + 100.56520000216551, + 299.0621000062674, + 100.03289999440312, + 602.075100003276, + 39.446900016628206, + 40.63299999688752, + 700.9872999915387, + 101.37560000293888, + 309.08910001744516, + 399.5456999982707, + 105.0344999821391, + 101.86490000342019, + 101.12159998971038, + 598.7063000211492, + 101.96810000343248, + 101.34039999684319, + 101.36269999202341, + 100.55149998515844, + 101.99899997678585, + 602.3709000146482, + 299.7660999826621, + 899.0093999891542, + 651.2907999858726, + 396.3183999876492, + 36.341700004413724, + 39.99290001229383, + 300.0861000036821, + 100.7347000122536, + 294.1988999955356, + 100.96619999967515, + 101.01439998834394, + 102.42080001626164, + 400.7695999753196, + 101.47850000066683, + 100.58520000893623, + 400.64649999840185, + 335.6610999908298, + 103.10869998647831, + 101.8671999918297, + 99.07599998405203, + 599.1988999885507, + 101.22559999581426, + 101.67279999586754, + 102.32879998511635, + 102.42480001761578, + 100.85240000626072, + 100.51769998972304, + 100.79850000329316, + 101.04619999765418, + 400.30880001722835, + 798.7540999893099, + 1300.2698000054806 + ], + "find_gameobject": [ + 40.198200003942475, + 100.68329999921843, + 885.5191000038758, + 100.70119998999871, + 38.42719999374822, + 328.20939997327514, + 100.8375000092201, + 39.87249999772757, + 99.37129999161698, + 405.4533999878913, + 105.44370001298375, + 603.5632000130136, + 303.500800015172, + 305.54540001321584, + 36.491000006208196, + 306.9202999759, + 605.7727999868803, + 406.2995999993291, + 104.80900001130067, + 306.4591999864206, + 106.73249998944812, + 304.6070999989752, + 45.28399999253452, + 39.58149999380112, + 302.734099997906, + 399.7999000130221, + 100.9292000089772, + 303.8511000049766, + 103.94030000315979, + 105.37390000536107, + 603.3592000021599, + 901.3418999966234, + 407.3291000095196, + 105.60619999887422, + 107.76879999320954, + 405.75090001220815, + 307.74699998437427, + 106.5822999808006, + 99.33500000624917, + 99.38070000498556, + 403.6199999973178, + 606.2966999888886, + 106.90869999234565, + 1507.4157000053674, + 71.94009999511763, + 320.1118000142742, + 409.7769999934826, + 403.96419999888167, + 101.7602999927476, + 405.82200000062585, + 304.42510001012124, + 604.6766999934334, + 37.8117999935057, + 365.11099999188446, + 106.71950000687502, + 305.6073999905493, + 316.2331000203267, + 307.1023999946192, + 103.63089997554198, + 104.61139999097213, + 100.1111000077799, + 604.3709999939892, + 405.2559999981895, + 105.58750000200234, + 108.3255999838002, + 407.2836000123061, + 99.70320001593791, + 305.32709998078644, + 102.8655000263825, + 803.1798000156414, + 37.83180000027642, + 303.04349999642, + 38.92049999558367, + 39.34649997972883, + 305.91190000995994, + 105.61599998618476, + 106.4343000180088, + 105.94749997835606, + 403.9273999806028, + 105.34420001204126, + 98.24620001018047, + 103.32229998311959, + 100.66979998373426, + 101.2674999947194, + 356.0213000164367, + 102.12510000565089, + 99.24209999735467, + 105.31970000010915, + 103.96020000916906, + 306.30769999697804, + 100.25519999908283, + 104.07820000546053, + 105.04319999017753, + 105.2227999898605, + 106.38189999735914, + 101.14390001399443, + 100.25899999891408, + 104.34299998451024, + 803.783499985002, + 707.9525999724865 + ], + "transform": [ + 39.7542999999132, + 107.24769998341799, + 44.56070001469925, + 308.7140000134241, + 46.28079998656176, + 43.5025000188034, + 408.1057999865152, + 41.89120000228286, + 306.6924000158906, + 401.7249000025913, + 103.65179998916574, + 1004.0961999911815, + 302.95479999040253, + 403.23029999854043, + 41.6992999962531, + 698.1608000060078, + 301.30089999875054, + 302.64849998638965, + 103.27089999918826, + 405.24309998727404, + 102.83209997578524, + 103.25350001221523, + 331.1952000076417, + 40.530099999159575, + 701.1148000019602, + 304.9190000165254, + 110.21699997945689, + 602.1996999916155, + 400.3030000021681, + 401.29770000930876, + 300.7623000012245, + 104.35619999771006, + 401.1291000060737, + 103.9677000080701, + 103.25139999622479, + 306.0777000209782, + 101.09139999258332, + 102.48089997912757, + 108.4415000223089, + 317.8937000047881, + 701.9722999830265, + 102.8445000119973, + 103.19329999038018, + 105.20819999510422, + 52.74540002574213, + 596.1354999744799, + 300.7194999954663, + 305.6116999941878, + 305.20909998449497, + 599.7762999904808, + 101.77989999647252, + 103.27639998286031, + 39.574299997184426, + 757.1615000197198, + 101.73939997912385, + 103.39000000385568, + 330.22959998925216, + 103.95970000536181, + 108.44559999532066, + 300.6034999853, + 308.353399974294, + 600.1191000104882, + 302.4143000075128, + 101.89250000985339, + 115.81859999569133, + 104.08170000300743, + 107.83789999550208, + 101.90159999183379, + 104.5565000094939, + 599.3805000034627, + 41.79419999127276, + 300.2093999821227, + 39.149200019892305, + 40.29649999574758, + 902.0781999861356, + 100.82170000532642, + 102.31419999036007, + 102.27649999433197, + 403.75079997465946, + 102.94000001158565, + 106.41780000878498, + 104.04160001780838, + 106.82600000291131, + 106.83929998776875, + 340.9603000036441, + 103.52800000691786, + 109.0680000197608, + 104.61170002236031, + 103.08059997623786, + 103.75520001980476, + 107.57720001856796, + 102.99479999230243, + 402.36549999099225, + 103.87590000755154, + 301.1547999922186, + 406.6471000260208, + 107.5309999869205, + 101.6685999929905, + 1203.6513999919407, + 106.05280002346262 + ], + "position": [ + 35.420000000158325, + 99.55889999400824, + 45.34559999592602, + 97.92150001158006, + 40.07109999656677, + 337.3796000087168, + 103.0505999806337, + 311.55139999464154, + 100.10569999576546, + 400.40919999592006, + 401.97550001903437, + 101.76660001161508, + 313.2374999986496, + 1300.1204999745823, + 39.77050000685267, + 1201.072199997725, + 604.0420999925118, + 399.79290001792833, + 103.86940001626499, + 301.66929998085834, + 402.233900007559, + 106.4615000213962, + 47.131900006206706, + 39.30259999469854, + 603.533299989067, + 399.8783999995794, + 302.2039999777917, + 103.7679000000935, + 302.2851999849081, + 101.32769998745061, + 1197.8272999986075, + 103.22039999300614, + 603.5846000013407, + 300.62190000899136, + 299.3315000203438, + 300.00429999199696, + 401.2265999917872, + 102.60209999978542, + 98.62030000658706, + 88.06330000516027, + 1102.6618999894708, + 100.01509997528046, + 101.80750000290573, + 102.4152000027243, + 370.54709999938495, + 51.60559999058023, + 406.46579998428933, + 399.69719998771325, + 100.96489998977631, + 301.2450000096578, + 98.63490000134334, + 100.51970000495203, + 35.66990001127124, + 1200.7422000169754, + 104.5559000049252, + 405.07849998539314, + 894.3173000006936, + 102.31069999281317, + 96.80150001076981, + 101.94469999987632, + 99.68650000519119, + 101.09199999715202, + 403.1803000252694, + 103.13110001152381, + 290.0886999850627, + 301.01310001919046, + 100.55649999412708, + 99.14200002094731, + 102.16910002054647, + 99.75900000426918, + 38.360899983672425, + 600.7325999962632, + 37.203999992925674, + 38.221800001338124, + 599.7836999886204, + 102.49800002202392, + 104.2306000017561, + 103.76579998410307, + 399.7271000116598, + 104.9166000157129, + 100.88579999865033, + 99.76139999344014, + 302.2373999992851, + 100.52880001603626, + 340.90770001057535, + 104.26009999355301, + 403.33209998789243, + 101.69400001177564, + 103.13190001761541, + 303.9760999963619, + 98.52189998491667, + 103.44430000986904, + 99.31930000311695, + 100.84110000752844, + 101.60840000025928, + 102.91180000058375, + 99.47469999315217, + 102.3849000048358, + 1207.9634999972768, + 97.94730000430718 + ], + "create_cube": [ + 39.79899999103509, + 103.87079999782145, + 44.9320999905467, + 106.5111999923829, + 36.671899986686185, + 41.287300002295524, + 102.21630000160076, + 37.993400008417666, + 104.69090001424775, + 401.59210001002066, + 102.9121000028681, + 99.39909999957308, + 590.3271000133827, + 902.3022000037599, + 36.29659998114221, + 600.9425999945961, + 601.9402999954764, + 805.070300004445, + 404.8966000264045, + 1197.73090002127, + 400.87809998658486, + 301.1482000001706, + 60.441099980380386, + 40.251700003864244, + 102.96709998510778, + 302.48260000371374, + 102.66010000486858, + 103.65959999035113, + 401.40199998859316, + 103.76249998807907, + 903.8210999860894, + 101.8692999787163, + 100.88270000414923, + 100.92229998554103, + 102.76529999100603, + 400.0710000109393, + 304.65959999128245, + 102.18990000430495, + 103.93300000578165, + 106.51400001370348, + 1401.4146000263281, + 103.87370001990348, + 403.1805999984499, + 406.9229000015184, + 60.19859999651089, + 53.692599991336465, + 306.0857000236865, + 599.702100007562, + 107.13899999973364, + 800.1347999961581, + 406.296500004828, + 109.15500001283363, + 37.583099998300895, + 100.32860000501387, + 100.70550002274103, + 299.8313000134658, + 37.38400002475828, + 103.62939999322407, + 102.54009999334812, + 303.61589998938143, + 105.50550001789816, + 105.94910001964308, + 400.3001000091899, + 100.23310000542551, + 100.0173999927938, + 100.94910001498647, + 105.1986999809742, + 406.786400009878, + 103.48180000437424, + 106.46279997308739, + 49.93179999291897, + 101.80420000688173, + 38.91239999211393, + 41.042700002435595, + 103.67630000109784, + 101.75199998775497, + 101.6024999844376, + 103.30220000469126, + 305.3999000112526, + 98.74929999932647, + 105.13840001658536, + 102.0561000041198, + 101.18950001196936, + 105.24219999206252, + 969.094000000041, + 100.24940001312643, + 103.56710001360625, + 99.92519998922944, + 99.60699998191558, + 400.6021000095643, + 103.84160000830889, + 399.01930000633, + 105.60789998271503, + 103.74149997369386, + 403.84959999937564, + 402.7038000058383, + 106.88120001577772, + 403.03729998413473, + 1209.8664999939501, + 406.0569000139367 + ], + "add_component": [ + 37.187299982178956, + 100.77670001192018, + 38.52360000018962, + 301.9837999891024, + 40.58979998808354, + 312.20500002382323, + 101.2674999947194, + 38.052800024161115, + 403.45569999772124, + 301.18450001464225, + 108.27160000917502, + 404.1586999956053, + 900.5166999995708, + 300.22679999819957, + 39.82850001193583, + 104.83789999852888, + 1197.8219999873545, + 898.7537999928463, + 104.28470000624657, + 600.9563999832608, + 401.36139999958687, + 102.37939999205992, + 38.602599990554154, + 338.06139999069273, + 100.94289999688044, + 600.1351999875624, + 303.5737999889534, + 101.53780001564883, + 1196.9687000091653, + 102.06820000894368, + 100.97550001228228, + 102.69480000715703, + 99.9456999998074, + 100.53009999683127, + 102.2145000169985, + 299.221099994611, + 98.42359999311157, + 301.32950001279823, + 101.38649999862537, + 327.1169999788981, + 1197.999299998628, + 101.65440000128001, + 101.99380002450198, + 98.77490001963452, + 58.5838999832049, + 44.99080000096001, + 600.4723000223748, + 702.8290000162087, + 301.6279000148643, + 99.76330000790767, + 399.86199999111705, + 99.70290001365356, + 38.75750000588596, + 102.70759998820722, + 403.5390999924857, + 403.2352000067476, + 40.549400000600144, + 100.92870000516996, + 403.45730000990443, + 400.82059998530895, + 299.85179999493994, + 103.75430001295172, + 300.7725000206847, + 102.86270000506192, + 101.57309999340214, + 305.5932999996003, + 102.03089998685755, + 99.72280001966283, + 102.10009998991154, + 99.74609999335371, + 46.21899998164736, + 101.93630002322607, + 37.20769999199547, + 38.538900000276044, + 101.3395999907516, + 307.36249999608845, + 101.15659999428317, + 100.761900015641, + 598.8934000197332, + 401.51049999985844, + 101.70400000060908, + 101.79830002016388, + 100.6995000061579, + 402.39829997881316, + 621.871800016379, + 100.40540000773035, + 99.31160000269301, + 300.7447000127286, + 100.97280002082698, + 300.3292000212241, + 300.70409999461845, + 100.47480001230724, + 102.00749998330139, + 97.9695999994874, + 99.87010000622831, + 299.6143999916967, + 115.54240001714788, + 400.2794999978505, + 297.2506000078283, + 100.77920000185259 + ], + "remove_component": [ + 327.7241000032518, + 100.59079999336973, + 40.58450000593439, + 400.2089999848977, + 36.418900010176, + 348.1616000062786, + 300.52690001321025, + 332.7139999892097, + 399.05360000557266, + 400.89969997643493, + 395.92670000274666, + 98.20209999452345, + 301.7684000078589, + 102.96819999348372, + 37.0489000051748, + 99.72189998370595, + 101.17650000029244, + 601.5674000082072, + 96.10019999672659, + 99.86410001874901, + 903.0206000024918, + 99.40750000532717, + 36.974099988583475, + 37.89190002135001, + 402.0085000083782, + 900.1072999963071, + 99.95720000006258, + 101.86779999639839, + 1196.3960000139195, + 299.4272999931127, + 100.84990001632832, + 99.83560000546277, + 104.04910001670942, + 102.09110000869259, + 299.60399999981746, + 701.346799993189, + 304.429900017567, + 100.72899999795482, + 299.51720000826754, + 101.77360000670888, + 102.19450001022778, + 302.4305999861099, + 99.86029998981394, + 98.87770001660101, + 403.3482999948319, + 344.6281999931671, + 700.4455999995116, + 603.7608000042383, + 101.27559999818914, + 100.88470001937822, + 1000.1589999883436, + 100.71960001369007, + 37.560900003882125, + 103.51570000057109, + 102.44260000763461, + 801.5567999973428, + 41.74429998965934, + 103.71610001311637, + 103.02959999535233, + 599.8547000053804, + 100.20809998968616, + 98.74290000880137, + 1198.8955999840982, + 99.40679999999702, + 101.1309000023175, + 897.0888000039849, + 298.6908000020776, + 104.20310002518818, + 101.09609999926761, + 98.37420002440922, + 37.289899977622554, + 100.89589998824522, + 36.564000009093434, + 36.77299999981187, + 108.60659999889322, + 94.78670000680722, + 398.9544000069145, + 402.35479999682866, + 1001.5232000150718, + 102.60859999107197, + 304.91219999385066, + 101.81140000349842, + 104.72079997998662, + 101.66499999468215, + 35.57810001075268, + 100.06180001073517, + 403.1321999791544, + 104.24420001800172, + 99.33170001022518, + 702.0825000072364, + 100.9974000044167, + 401.9918999983929, + 102.4877000018023, + 102.12270001647994, + 301.7366999993101, + 1005.607200000668, + 87.82860002247617, + 300.68310000933707, + 305.12309999903664, + 402.3002000176348 + ], + "delete_gameobject": [ + 36.689799977466464, + 99.36759999254718, + 43.62250000122003, + 598.9119999867398, + 342.2073000110686, + 630.0147000001743, + 101.04989999672398, + 38.999400014290586, + 906.1779000039678, + 599.9389000062365, + 99.59140000864863, + 400.40980000048876, + 99.18579997611232, + 99.81410001637414, + 305.4317999922205, + 100.29400000348687, + 99.25589998601936, + 100.65870001562871, + 101.76040002261288, + 100.91290000127628, + 602.9228999977931, + 399.4168999779504, + 40.02580000087619, + 39.82720000203699, + 100.31949999392964, + 102.96829999424517, + 300.646699994104, + 303.16120001953095, + 498.61799998325296, + 102.06810000818223, + 103.98729998269118, + 401.16489998763427, + 98.719900008291, + 303.05950000183657, + 101.61330000846647, + 302.5993999908678, + 405.47300002072006, + 101.12139998818748, + 100.47500001383014, + 101.87019998556934, + 99.00509999715723, + 103.75070001464337, + 400.096700002905, + 399.20519999577664, + 67.95619998592883, + 49.575099983485416, + 598.1172999890987, + 100.4831999889575, + 302.9911999765318, + 100.83359997952357, + 698.880999989342, + 301.2787999759894, + 44.36689999420196, + 101.0950000199955, + 100.98580000340007, + 102.26700000930578, + 39.8847000033129, + 101.1587000102736, + 100.39810001035221, + 598.2980000262614, + 298.51150000467896, + 300.8638999890536, + 597.3147999902721, + 101.04370000772178, + 299.5932000048924, + 900.848200020846, + 106.92590000689961, + 402.7912000019569, + 302.7623000089079, + 101.05510000721551, + 37.53100000903942, + 102.83210000488907, + 37.97149998717941, + 37.67099999822676, + 93.92730001127347, + 100.12310001184233, + 99.59950001211837, + 101.51999999652617, + 300.1896000059787, + 99.73700001137331, + 100.03119998145849, + 101.06759998598136, + 303.02980000851676, + 99.72170001128688, + 37.33230000943877, + 102.38520000712015, + 98.92040002159774, + 100.30920000281185, + 102.45460001169704, + 100.72550000040792, + 100.51880002720281, + 602.3324000125285, + 101.14799998700619, + 100.72279997984879, + 102.65739998430945, + 600.700200011488, + 98.95859999232925, + 599.3761999998242, + 95.77820001868531, + 100.87880000355653 + ], + "scene_info": [ + 35.99999999278225, + 99.8437000089325, + 35.36609999719076, + 600.1475999946706, + 41.482900007395074, + 318.7142999959178, + 102.92190001928248, + 316.97000001440756, + 1392.768599995179, + 1199.2457000014838, + 311.55320000834763, + 99.3568999983836, + 102.33339999103919, + 100.7650000101421, + 43.63279999233782, + 101.25779997906648, + 300.8153999981005, + 100.93039998901077, + 101.1620000062976, + 99.19040001113899, + 98.86009999900125, + 100.38740001618862, + 332.7312999754213, + 36.46030000527389, + 99.75839999970049, + 98.32059999462217, + 99.70190000603907, + 100.26209999341518, + 99.69959998852573, + 101.62870000931434, + 98.70919998502359, + 100.75320000760257, + 100.02799998619594, + 99.1879999928642, + 99.8216999869328, + 100.8053999976255, + 299.8260000022128, + 301.83969999779947, + 100.41929999715649, + 302.7830000210088, + 100.15790001489222, + 99.14869998465292, + 100.52629999700002, + 401.9583000044804, + 361.79639998590574, + 45.914199989056215, + 1198.2205999956932, + 400.4202000214718, + 300.7668999780435, + 99.93160000885837, + 100.92460000305437, + 99.91620000801049, + 39.42389998701401, + 297.78380002244376, + 101.3544000161346, + 101.23460000613704, + 41.601299977628514, + 101.61730000982061, + 100.43799999402836, + 300.37380001158454, + 100.71510000852868, + 99.10339998896234, + 103.33419998642057, + 405.4930999991484, + 101.51010000845417, + 100.75109999161214, + 96.6906999819912, + 97.73540002061054, + 100.42780000367202, + 300.66269999952056, + 38.37810002733022, + 99.83970000757836, + 36.70529997907579, + 38.11310001765378, + 99.12730002542958, + 100.9382999909576, + 101.17100001662038, + 101.02649999316782, + 98.82070001913235, + 102.79249999439344, + 99.681599996984, + 110.20870000356808, + 99.49839999899268, + 299.14689998258837, + 39.45489999023266, + 99.24499999033287, + 301.24490000889637, + 99.98620001715608, + 98.84239998064004, + 99.41309998976067, + 299.55719999270514, + 1296.1942999972962, + 100.0476999906823, + 100.39199999300763, + 299.493500002427, + 598.7959999765735, + 399.5164000079967, + 101.00760002387688, + 402.8188000083901, + 301.95299998740666 + ], + "scene_save": [ + 132.17749999603257, + 193.31600001896732, + 428.46749999444, + 193.78349999897182, + 131.20050000725314, + 682.3491000104696, + 490.1704999792855, + 131.9301999756135, + 993.4669999929611, + 192.1740000252612, + 491.4901999873109, + 495.9699000173714, + 490.0637000100687, + 196.19660000898875, + 125.83920001634397, + 189.29790001129732, + 190.7651999790687, + 490.653899993049, + 490.89819999062456, + 497.07880002097227, + 200.56490000570193, + 393.38819999829866, + 124.36300000990741, + 129.77739999769256, + 393.2660999998916, + 192.95309999142773, + 388.2580000208691, + 195.39599999552593, + 189.26859999191947, + 506.44800000009127, + 394.69119999557734, + 193.5360000061337, + 218.06930002640001, + 198.00440000835806, + 393.7745000002906, + 195.2521000057459, + 389.6106000174768, + 193.98869998985901, + 187.49929999466985, + 187.12200000300072, + 410.1538000104483, + 197.73249997524545, + 494.2217000061646, + 499.285099998815, + 148.12980001443066, + 130.42939998558722, + 195.98830002360046, + 198.06840000092052, + 785.9466999943834, + 191.3326999929268, + 189.80930000543594, + 190.66229998134077, + 130.35089999902993, + 198.90670001041144, + 189.87420000485145, + 189.18340001255274, + 143.79159998497926, + 492.63279998558573, + 189.29609999759123, + 689.5213999960106, + 386.2346000096295, + 192.62599997455254, + 191.56989999464713, + 187.5020999868866, + 487.53729998134077, + 193.7939000199549, + 188.77159999101423, + 391.7449999717064, + 487.66399998567067, + 191.0356000007596, + 127.26750000729226, + 493.31920000258833, + 125.23570001940243, + 130.6336999987252, + 190.33240000135265, + 489.8179000010714, + 188.1860000139568, + 491.06250001932494, + 192.7422999870032, + 188.8866999943275, + 493.7853000010364, + 179.46469999151304, + 185.92209997586906, + 195.58419997338206, + 126.98280002223328, + 189.1666999727022, + 193.8166000181809, + 191.59880001097918, + 189.35940001392737, + 193.73949998407625, + 488.0047999904491, + 192.4377999966964, + 189.3598999886308, + 197.83879999886267, + 1108.4847999736667, + 193.73840000480413, + 191.15070000407286, + 190.93420001445338, + 191.97309997980483, + 486.36459998670034 + ], + "console": [ + 43.66480000317097, + 220.38139999494888, + 46.33020001347177, + 322.7513000019826, + 370.41990002035163, + 38.655700016533956, + 324.79079999029636, + 282.3078000219539, + 119.79870000504889, + 124.43250001524575, + 618.8563000177965, + 321.64899999042973, + 122.62740000733174, + 422.4091999931261, + 44.22570002498105, + 221.92700000596233, + 120.50989997806028, + 321.86840000213124, + 121.81450001662597, + 119.12600000505336, + 123.20980001823045, + 318.00480000674725, + 315.6443999905605, + 39.46530001121573, + 122.1322999917902, + 219.48229998815805, + 621.0262000095099, + 421.29870000644587, + 121.69850000645965, + 322.2419999947306, + 120.87789998622611, + 320.88839999050833, + 221.09969999291934, + 323.1306000088807, + 118.40810001012869, + 124.83280000742525, + 219.40939998603426, + 317.5792999973055, + 318.3541000180412, + 222.0188999781385, + 421.0696999798529, + 223.0795999930706, + 423.3342000225093, + 320.30910000321455, + 296.5007000020705, + 257.8194999950938, + 323.9303000154905, + 327.11789998575114, + 820.6079000083264, + 327.444700000342, + 119.20320001081564, + 423.74180001206696, + 44.84219997539185, + 418.8913000107277, + 222.26680000312626, + 323.69169997400604, + 339.2939000041224, + 120.55779999354854, + 324.56940002157353, + 121.41009999322705, + 527.7233999804594, + 118.65419999230653, + 119.93480002274737, + 118.48929998814128, + 219.10749998642132, + 119.60500001441687, + 120.03280001226813, + 320.18030001199804, + 217.44209999451414, + 120.8121000090614, + 43.91380000743084, + 117.50719998963177, + 289.8288000142202, + 39.836700016167015, + 120.82860001828521, + 121.30959998467006, + 120.13990001287311, + 322.2124000021722, + 121.52430001879111, + 321.3248000247404, + 319.73079999443144, + 220.3690999886021, + 119.44300000322983, + 219.77029999834485, + 38.299800013192, + 120.78870000550523, + 422.51890001352876, + 119.58050000248477, + 119.2692999902647, + 120.70289999246597, + 318.55840000207536, + 119.90349998814054, + 320.747100020526, + 420.0321999960579, + 118.26109999674372, + 121.5037000074517, + 119.00560001959093, + 119.32290002005175, + 328.0365999962669, + 622.7534999779891 + ], + "screenshot": [ + 441.7319999774918, + 189.7171000018716, + 134.0924999967683, + 206.1833000043407, + 497.19569997978397, + 147.27670000866055, + 393.6245999939274, + 124.1104000073392, + 205.15490000252612, + 203.3872000174597, + 1081.1282999929972, + 480.2447999827564, + 500.32829999690875, + 204.8410999996122, + 134.1670000110753, + 188.59340000199154, + 425.5270000139717, + 501.61360000493005, + 204.03490000171587, + 389.714399992954, + 196.92779998877086, + 707.944599998882, + 150.17459998489358, + 429.16880000848323, + 403.0449999845587, + 207.42389999213628, + 1502.0467000140343, + 198.8466999900993, + 189.0930999943521, + 493.47459999262355, + 410.4325999796856, + 201.70419997884892, + 204.02920001652092, + 404.7468999924604, + 404.07640000921674, + 401.33310001692735, + 399.3010000267532, + 503.8839999760967, + 199.628100002883, + 489.0634999901522, + 489.9792000069283, + 187.9526000120677, + 1386.5692999970634, + 487.8661000111606, + 831.2114000145812, + 156.89829998882487, + 195.94799997867085, + 190.32870000228286, + 197.0028999785427, + 195.74090000241995, + 206.82570000644773, + 491.7637999751605, + 150.85070001077838, + 193.2133999944199, + 201.5559999854304, + 192.46409999323077, + 141.42589998664334, + 199.98899998608977, + 207.69070001551881, + 201.99960001627915, + 695.3800999908708, + 383.6359999841079, + 202.8569999965839, + 185.8883999811951, + 484.85780000919476, + 526.6219999757595, + 511.16860000183806, + 493.22650002432056, + 481.129099993268, + 180.67359999986365, + 151.30389999831095, + 203.7253999733366, + 141.65350000257604, + 133.53139997343533, + 403.51750000263564, + 391.2113000114914, + 208.41630001086742, + 1692.372699995758, + 506.9377000036184, + 491.4926000055857, + 191.10060000093654, + 188.7319999805186, + 493.97969999699853, + 491.4641999930609, + 131.32039998890832, + 499.7531999833882, + 496.43210001522675, + 379.74859998212196, + 489.262899995083, + 200.76009997865185, + 694.4402999943122, + 195.85260000894777, + 192.0776000188198, + 188.96749999839813, + 194.986999995308, + 195.72180000250228, + 204.87560000037774, + 203.53850000537932, + 498.04669999866746, + 1699.840499990387 + ], + "material_search": [ + 45.293400005903095, + 110.77959998510778, + 213.32720000646077, + 297.53049998544157, + 198.34390000323765, + 305.8346000034362, + 193.74849999439903, + 199.55960000515915, + 297.6196999952663, + 389.79240000480786, + 1602.8014000039548, + 493.90160001348704, + 99.21980000217445, + 105.00020001200028, + 204.38410001224838, + 100.07309998036362, + 294.1751999896951, + 297.1293999871705, + 201.9202000228688, + 405.71799999452196, + 192.39179999567568, + 1096.6773000254761, + 261.6083000029903, + 290.355000004638, + 295.8578999969177, + 109.11910000140779, + 102.41619998123497, + 190.3656999929808, + 193.01869999617338, + 296.86910001328215, + 310.56809998699464, + 399.5772000052966, + 102.46870000264607, + 197.2877000225708, + 187.89259999175556, + 106.52269999263808, + 194.56519998493604, + 200.25389999500476, + 390.3072999964934, + 399.8012999945786, + 199.50960000278428, + 300.57099999976344, + 1399.7795000032056, + 293.5744999849703, + 563.1939000159036, + 236.8586999946274, + 199.45970000117086, + 200.56729999487288, + 295.14539998490363, + 104.98650002409704, + 297.4687999812886, + 192.35520000802353, + 350.20000001532026, + 391.65109998430125, + 290.4446000175085, + 294.1203999798745, + 41.516700002830476, + 105.80029999255203, + 291.3107999775093, + 97.00039998278953, + 110.40130001492798, + 99.64520001085475, + 290.94749997602776, + 199.51669999863952, + 697.5136999972165, + 296.7408999975305, + 389.30840001557954, + 199.84360001399182, + 390.62449999619275, + 298.8830000103917, + 296.46620000130497, + 100.58579998440109, + 46.02720000548288, + 40.413200011244044, + 102.43790000095032, + 101.9840000080876, + 387.90569998673163, + 204.19540000148118, + 102.02350001782179, + 193.80849998560734, + 190.20039998576976, + 98.32190000452101, + 496.4756999979727, + 799.5377999905031, + 40.92899998067878, + 99.152500013588, + 203.27480000560172, + 95.49529998912476, + 101.79350001271814, + 298.691299976781, + 492.65159998321906, + 194.1219000145793, + 96.4648999797646, + 90.01280000666156, + 93.77989999484271, + 198.05910001741722, + 97.1049000218045, + 100.13209999306127, + 306.58500001300126, + 200.8891000004951 + ], + "asset_copy": [ + 378.4809999924619, + 175.94819999067113, + 98.93320000264794, + 460.4628999950364, + 358.5282000130974, + 107.38529998343438, + 660.8035999815911, + 948.1113999790978, + 166.20089998468757, + 159.52350001316518, + 168.84939998271875, + 1067.3654999991413, + 359.34500000439584, + 360.45199999352917, + 100.44270000071265, + 159.58469998440705, + 157.8741999983322, + 360.3984999936074, + 161.95999999763444, + 159.50619999784976, + 161.83150000870228, + 161.48729997803457, + 110.86539999814704, + 101.42680001445115, + 158.99759999592789, + 457.5298000127077, + 188.0687999946531, + 161.65940000792034, + 162.04519997700118, + 358.0794000008609, + 459.64859999367036, + 168.01110000233166, + 155.67740000551566, + 760.3306000237353, + 358.3117999951355, + 362.0277000009082, + 959.5750999869779, + 363.0659999907948, + 159.75900000194088, + 760.1419000129681, + 666.1326000175904, + 360.24050001287833, + 166.41440000967123, + 458.28410002286546, + 1055.4461000137962, + 108.74130000593141, + 162.42710000369698, + 162.18880002270453, + 161.41329999663867, + 159.8013000038918, + 152.38009998574853, + 659.8703000054229, + 100.21920001599938, + 466.73099999316037, + 159.0165000234265, + 156.92330000456423, + 110.13800001819618, + 357.80299999169074, + 163.0081000039354, + 158.4203999955207, + 162.55979999550618, + 461.3690999976825, + 157.2976000024937, + 162.26710000773892, + 358.03969998960383, + 357.0850999967661, + 160.2607000095304, + 364.32930000592023, + 1557.0047999790404, + 160.49179999390617, + 102.96129999915138, + 456.38630000757985, + 94.2808999971021, + 96.1640999885276, + 160.29040000285022, + 367.63510000309907, + 162.73839998757467, + 162.62400001869537, + 159.96990000712685, + 461.17900000535883, + 459.0106999967247, + 159.49910000199452, + 960.3646000032313, + 162.22639998886734, + 97.7405000012368, + 161.0694999981206, + 159.13380001438782, + 159.93049999815412, + 159.95370000018738, + 158.26369999558665, + 163.607199996477, + 161.50590000324883, + 159.01690002647229, + 159.7862999769859, + 176.3760000176262, + 162.3375000199303, + 159.47440001764335, + 159.2833999893628, + 1166.5054000040982, + 163.8671999971848 + ], + "asset_move": [ + 92.43910000077449, + 167.01309999916703, + 88.86099999654107, + 382.2436999762431, + 365.1279999758117, + 90.49760000198148, + 1251.6909999831114, + 603.0769000062719, + 160.2818999963347, + 163.81519997958094, + 473.4611000167206, + 172.96080000232905, + 464.16179998777807, + 163.88460001326166, + 87.01930000097491, + 362.2928000113461, + 365.0192000204697, + 365.363899996737, + 165.71580001618713, + 165.66759999841452, + 473.39140000985935, + 164.30030000628904, + 591.2602999887895, + 377.2033000132069, + 374.6857999940403, + 171.40249998192303, + 165.17710001789965, + 267.0520000101533, + 176.73330000252463, + 264.1750999900978, + 368.83679998572916, + 170.31580000184476, + 263.79899997846223, + 571.0292000148911, + 300.2184000215493, + 167.44409999228083, + 271.2469999969471, + 365.09920001844876, + 362.60970000876114, + 171.80030001327395, + 667.3908999946434, + 366.25820002518594, + 167.11920002126135, + 667.917499988107, + 668.0934999894816, + 359.4124999945052, + 365.89180000009947, + 270.721400011098, + 177.45129999821074, + 362.8593999892473, + 174.9098000000231, + 663.5187000210863, + 90.92479999526404, + 366.3980000128504, + 366.74739999580197, + 361.6821000177879, + 114.44030000711791, + 183.82330000167713, + 366.2177999794949, + 361.3649000180885, + 166.4786999754142, + 178.19159998907708, + 176.0587000171654, + 363.03120001684874, + 199.5662999979686, + 366.55430000973865, + 263.9587000012398, + 1139.0324999811128, + 270.14400000916794, + 365.484199981438, + 93.27149999444373, + 163.48429999197833, + 87.73619998828508, + 88.45039998413995, + 163.50920000695623, + 465.19960000296123, + 163.42609998537228, + 465.2242000156548, + 365.9561999957077, + 1151.2416999903508, + 362.4947000062093, + 161.60459999809973, + 164.4073999777902, + 167.62749999179505, + 136.4070000126958, + 164.97919999528676, + 463.04040000541136, + 162.00539999408647, + 163.76180000952445, + 364.39960001735017, + 164.92370000923984, + 164.86200000508688, + 165.5687000020407, + 481.2067000020761, + 170.49190000398085, + 168.9930999709759, + 165.28409998863935, + 189.12510000518523, + 402.3074999859091, + 168.08420000597835 + ], + "asset_delete": [ + 335.01469998736866, + 360.4163999843877, + 365.27399998158216, + 460.84960000007413, + 1450.4981000209227, + 362.00960000860505, + 91.34670000639744, + 88.29330001026392, + 359.61939999833703, + 362.6242999744136, + 164.86170000280254, + 164.36580001027323, + 361.3744000031147, + 361.664700001711, + 81.57460001530126, + 161.17350000422448, + 361.03519998141564, + 261.4124000247102, + 261.7933999863453, + 359.58749998826534, + 161.58409998752177, + 261.28520001657307, + 1205.9608999988995, + 369.4521999859717, + 462.60410000104457, + 357.99170000245795, + 362.93259999365546, + 662.5012999866158, + 366.00690000341274, + 661.0960999969393, + 361.0301000007894, + 257.8452000161633, + 161.74409998347983, + 658.2609000033699, + 359.47460000170395, + 261.0512999817729, + 163.98700000718236, + 373.138499999186, + 360.02449999796227, + 178.0311000184156, + 558.7736000015866, + 375.8032999758143, + 477.1084999956656, + 1211.895699991146, + 1185.0417999958154, + 368.86950000189245, + 363.6518999992404, + 462.35499999602325, + 362.9926999856252, + 163.51990000111982, + 159.84029998071492, + 276.1500999913551, + 85.00719998846762, + 662.0652999845333, + 359.44849997758865, + 460.6267999915872, + 328.78439998603426, + 359.06960000284016, + 358.8045999931637, + 158.63670001272112, + 157.42269999464042, + 357.01599999447353, + 258.60289999400266, + 457.6541999995243, + 160.30239997780882, + 358.03660002420656, + 158.78550001070835, + 305.8450999960769, + 165.56340001989156, + 357.22000000532717, + 88.54450000217184, + 356.7717999976594, + 83.06740000261925, + 86.7947000078857, + 360.46019999776036, + 556.6843999840785, + 158.61889999359846, + 161.34250001050532, + 160.86279999581166, + 331.1460000113584, + 362.11260000709444, + 159.8033000191208, + 160.44750000583008, + 364.29309999221005, + 85.15980001538992, + 164.06179999466985, + 459.513900015736, + 157.54680000827648, + 158.7837999977637, + 162.72600000957027, + 161.56389997922815, + 459.1925000131596, + 259.3485999968834, + 161.36990001541562, + 162.61430000304244, + 162.01030000229366, + 158.68660001433454, + 156.37189999688417, + 180.42340001557022, + 365.520799998194 + ], + "import_settings": [ + 574.0902000106871, + 115.95889998716302, + 41.5095999778714, + 813.6405999830458, + 870.8809999807272, + 35.57939999154769, + 46.46280000451952, + 35.877899994375184, + 112.95829998562112, + 116.53410000144504, + 313.71889999718405, + 211.95510000688955, + 313.38220002362505, + 117.26919998181984, + 326.56789998873137, + 311.30319999647327, + 615.8383000001777, + 311.295199993765, + 113.03519998909906, + 114.3671999743674, + 213.22730000247248, + 116.25709998770617, + 38.76599998329766, + 37.89829998277128, + 914.8994999995921, + 114.78530001477338, + 111.43000001902692, + 613.6683000077028, + 114.42490000627004, + 1619.4430000032298, + 613.8136000081431, + 118.9306000014767, + 314.55939999432303, + 1122.817199997371, + 313.51180002093315, + 416.5396000025794, + 115.68710001301952, + 514.528599975165, + 313.1885000038892, + 115.04220002098009, + 1525.3739000181668, + 310.9076999826357, + 120.67150001530536, + 2713.0612999899313, + 604.6422999934293, + 313.7882000009995, + 415.44929999508895, + 318.23330000042915, + 113.39169999700971, + 312.80359998345375, + 313.0278999742586, + 114.56770001677796, + 36.32149999612011, + 510.6509999895934, + 313.63199997576885, + 313.51760000688955, + 37.516500015044585, + 113.32639999454841, + 1122.541499993531, + 111.1951999773737, + 114.74459999590181, + 112.35350000788458, + 113.12720002024435, + 314.81119999079965, + 110.92680000001565, + 310.0560000166297, + 212.57730000070296, + 47.28239998803474, + 116.24920001486316, + 313.1495999987237, + 39.33250001864508, + 311.784700024873, + 38.356600009137765, + 39.036500005749986, + 114.57919998792931, + 511.3091999955941, + 412.6027000020258, + 313.6880999954883, + 114.70030000782572, + 39.07460000482388, + 213.31130000180565, + 115.48760000732727, + 110.91439999290742, + 115.12160001439042, + 38.641200022539124, + 113.6306999833323, + 310.93890001648106, + 313.8604999985546, + 111.50510000879876, + 311.78959997487254, + 115.12699999730103, + 112.97790001844987, + 114.7894999885466, + 115.56020000716671, + 112.96260001836345, + 413.3543999923859, + 213.8383999990765, + 111.74570000730455, + 418.0421000055503, + 113.64180000964552 + ], + "material_modify": [ + 351.816799986409, + 421.64889999548905, + 338.202499988256, + 932.1974999911617, + 68.74230000539683, + 63.45430001965724, + 70.25940000312403, + 64.27350000012666, + 325.39519999409094, + 334.1153999790549, + 124.75170000107028, + 128.59469998511486, + 937.6907999976538, + 325.64060000004247, + 60.977799992542714, + 126.19129999075085, + 835.338300006697, + 432.7358999871649, + 126.4394000172615, + 323.5865000169724, + 131.00270001450554, + 125.41480001527816, + 58.63600000157021, + 375.6258999928832, + 124.4814999809023, + 324.5131000003312, + 126.29719998221844, + 636.308299988741, + 425.89910002425313, + 120.8514999889303, + 635.3557000111323, + 430.1712000160478, + 124.93069999618456, + 127.09910000558011, + 622.1982999995816, + 332.2010999836493, + 324.5935999730136, + 935.6838999956381, + 624.3509000050835, + 324.8913999996148, + 139.27730001159944, + 634.8944999917876, + 326.47619998897426, + 1718.3381000068039, + 79.71849999739788, + 364.9046000209637, + 935.2078000083566, + 323.56059999438, + 325.01430000411347, + 425.317899993388, + 124.80370001867414, + 123.7459999974817, + 66.52139997459017, + 326.3048999942839, + 423.1107000086922, + 323.2570000109263, + 62.749800010351464, + 422.591900016414, + 622.1623000164982, + 126.03879999369383, + 123.04330000188202, + 323.18629999645054, + 124.62210000376217, + 624.6190000092611, + 323.6619000090286, + 323.79240001318976, + 935.9594999987166, + 64.84069998259656, + 129.19869998586364, + 623.4460000123363, + 63.459400000283495, + 123.50940000033006, + 60.45980000635609, + 333.7778999994043, + 326.6801999998279, + 633.8652999838814, + 124.69409999903291, + 444.8926000040956, + 326.45449999836273, + 73.80460001877509, + 425.184799998533, + 124.22040000092238, + 125.75109998579137, + 123.28630001866259, + 62.16380000114441, + 125.8969999908004, + 324.6283000044059, + 123.49420000100508, + 125.5282000056468, + 127.62640000437386, + 128.41229999321513, + 124.53140001161955, + 125.31070000841282, + 437.17740001739, + 126.17010000394657, + 124.31859999196604, + 126.25770000158809, + 126.26230000751093, + 124.03939999057911, + 131.62269999156706 + ], + "time_settings": [ + 355.43690001941286, + 417.4910000001546, + 321.74650000524707, + 1533.4181000071112, + 47.91640001349151, + 38.13900001114234, + 343.15000000060536, + 38.112200010800734, + 418.1080000125803, + 413.5205000056885, + 314.76279997150414, + 116.13730000681244, + 1123.5101000056602, + 113.02869999781251, + 36.28589998697862, + 313.91560001065955, + 115.32830001669936, + 816.9607000018004, + 313.58560000080615, + 113.94779998227023, + 314.91009998717345, + 316.92400001338683, + 36.26819999772124, + 354.56540001905523, + 117.56990000139922, + 313.6755999876186, + 114.33420001412742, + 113.48359999828972, + 315.3691000188701, + 117.8424000099767, + 118.24129999149591, + 216.0579999908805, + 317.6997999835294, + 116.55060001066886, + 618.4747999941465, + 1229.6041000226978, + 117.01129999710247, + 920.5764000071213, + 618.2411999907345, + 111.36270000133663, + 124.7086999937892, + 815.8373999758624, + 118.99149999953806, + 39.40470001543872, + 54.9821000022348, + 331.6962000099011, + 118.72099997708574, + 612.8883000055794, + 415.7940000004601, + 617.0339999953285, + 112.57900000782683, + 112.13039999711327, + 39.455799997085705, + 115.64030000590719, + 914.8963000043295, + 615.4202000179794, + 36.05749999405816, + 314.7684000141453, + 113.97779997787438, + 112.92479999247007, + 310.7691000041086, + 114.38699997961521, + 313.7253999884706, + 117.4483000067994, + 110.22649999358691, + 614.1808000102174, + 1212.4933000013698, + 40.701999998418614, + 311.42819998785853, + 813.9237000141293, + 38.08050000225194, + 312.8179000050295, + 39.03379998519085, + 36.78199998103082, + 116.43140000524, + 114.60519998217933, + 312.67810001736507, + 320.65229999716394, + 112.64420000952668, + 35.919099987950176, + 315.2795999776572, + 112.58360001374967, + 113.72059999848716, + 116.02090002270415, + 35.78030000790022, + 311.27780000679195, + 415.79760002787225, + 114.46620000060648, + 110.87619999307208, + 314.2232999962289, + 112.45379998581484, + 112.10460000438616, + 114.43849999341182, + 111.46099999314174, + 116.60680000204593, + 113.14190001576208, + 118.9322000136599, + 113.63680000067689, + 419.7801999980584, + 113.14080000738613 + ], + "read_csharp": [ + 859.1591999866068, + 284.9821999843698, + 326.2768000131473, + 37.57680000853725, + 34.591699979500845, + 313.53859999217093, + 48.579399997834116, + 36.845399998128414, + 248.45470002037473, + 289.2431999789551, + 40.46819999348372, + 34.02940000523813, + 1139.6377000201028, + 316.23559998115525, + 34.94420001516119, + 314.08849998842925, + 49.313099996652454, + 1170.5191000073683, + 35.773999989032745, + 268.3653999993112, + 333.0813000211492, + 35.71369999554008, + 35.19550000783056, + 319.17329999851063, + 35.89180001290515, + 332.6729999971576, + 36.528099997667596, + 32.44320000521839, + 550.6504999939352, + 35.78949999064207, + 37.443699984578416, + 329.3718000059016, + 314.7857000003569, + 286.9007999834139, + 34.941199992317706, + 35.62090001651086, + 36.31110000424087, + 1124.9854000052437, + 815.6552000145894, + 31.847500009462237, + 255.578099982813, + 32.938299991656095, + 351.9345999811776, + 35.96469998592511, + 349.5706999965478, + 297.5195999897551, + 331.07479999307543, + 548.6546000174712, + 295.29849998652935, + 580.0455999851692, + 34.91950000170618, + 34.42509999149479, + 37.02810002141632, + 33.63220000755973, + 34.78389998781495, + 34.051399998134, + 34.07069999957457, + 322.7301000151783, + 33.520600001793355, + 282.44189999531955, + 36.096900003030896, + 277.8666000231169, + 34.45899998769164, + 34.203599992906675, + 36.48320000502281, + 32.652399997459725, + 34.72009999677539, + 33.16009999252856, + 31.964599998900667, + 529.3628000072204, + 33.9469000173267, + 310.87980000302196, + 34.31540000019595, + 31.679000006988645, + 294.79720001108944, + 33.39200001209974, + 290.75850002118386, + 536.1588000087067, + 258.9356999960728, + 35.89800000190735, + 574.3953000055626, + 34.02199997799471, + 33.6890000035055, + 315.4746999789495, + 32.55360000184737, + 36.2044999783393, + 317.3229999956675, + 36.16039999178611, + 34.38999998616055, + 507.5899999937974, + 32.970900007057935, + 329.42150000599213, + 35.66950000822544, + 33.90499998931773, + 48.388399998657405, + 32.02010001405142, + 34.62530000251718, + 40.85039999336004, + 425.9609000000637, + 335.47180000459775 + ], + "play_until_ready": [ + 1881.1181000201032, + 850.8548000245355, + 1841.9109999958891, + 840.4517000017222, + 815.4221000149846, + 781.8409999890719, + 781.4288999943528, + 792.111599992495, + 1401.2156999961007, + 1409.5045999856666, + 831.7513999936637, + 819.701400003396, + 807.7850999834482, + 1466.4381000038702, + 813.9654000115115, + 829.5113000203855, + 796.610099991085, + 927.9164999898057, + 801.5133000153583, + 877.113599999575, + 817.0916000090074, + 815.1889000146184, + 767.2004000050947, + 1354.4474999944214, + 816.1939000128768, + 1419.2680999985896, + 807.3737999948207, + 817.1751000045333, + 1148.151000001235, + 818.9774000202306, + 829.5080999960192, + 831.6269999777433, + 820.8744000003207, + 871.760500012897, + 822.0104000065476, + 822.2166000050493, + 813.7068999931216, + 1409.459099988453, + 1962.3946999781765, + 806.9775000039954, + 796.5517000120599, + 838.7724999920465, + 789.9322000157554, + 797.0010999997612, + 790.1977000001352, + 1526.2862000090536, + 830.530400009593, + 1090.7686999998987, + 856.5762999933213, + 878.0122000025585, + 1211.2598000094295, + 804.5028999913484, + 811.9336000236217, + 818.7733000086155, + 811.022799985949, + 825.963099981891, + 1047.4256000015885, + 1023.2937000109814, + 804.9873000127263, + 856.54139998951, + 796.9301999837626, + 1066.6341000178363, + 1101.3904999999795, + 805.5284000001848, + 812.2918000153732, + 815.1272999821231, + 821.4273999910802, + 783.7242000096012, + 815.7671000226401, + 822.8745000087656, + 776.8795000156388, + 854.0618999977596, + 756.0319999756757, + 753.2034999749158, + 1039.992700010771, + 813.3346000104211, + 1151.3738999783527, + 1418.249599984847, + 878.8890000141691, + 769.2048999888357, + 1665.499099995941, + 1103.8736999907997, + 1119.512900011614, + 838.570299994899, + 773.0282999982592, + 1217.088600009447, + 1120.0480999832507, + 802.8253000229597, + 808.5042999882717, + 832.445199979702, + 808.3641999983229, + 827.6324000034947, + 810.4952999856323, + 809.8535999888554, + 838.2763999979943, + 827.3023000219837, + 817.6856999925803, + 800.7673000101931, + 1259.3414000002667, + 815.8469999907538 + ], + "stop_until_ready": [ + 643.8065000111237, + 840.6592000101227, + 1158.618599991314, + 770.5230999854393, + 946.1123999790289, + 621.2129999767058, + 737.0272999978624, + 812.1531000069808, + 950.222199986456, + 1737.5974000024144, + 652.1316000143997, + 851.8291999935172, + 952.2095999855082, + 642.9132999910507, + 586.0776999907102, + 838.504000013927, + 662.2585000004619, + 686.2025999871548, + 837.0467000058852, + 654.003500007093, + 1541.7626000125892, + 638.8774999941234, + 574.0714000130538, + 600.1164999906905, + 769.0760999976192, + 738.1536000175402, + 854.0485999837983, + 850.634300004458, + 1347.0112000068184, + 751.8810000037774, + 1161.8556000175886, + 1241.7416000098456, + 1553.4978000214323, + 652.5712999864481, + 679.3545999971684, + 951.6385000024457, + 977.4285000166856, + 848.4098999761045, + 648.7275999970734, + 657.3881000222173, + 861.0023000219371, + 657.8124999941792, + 940.6302999996115, + 789.4452000036836, + 755.6770999799483, + 607.2669000132009, + 662.9857000079937, + 2275.1172999851406, + 738.9941000146791, + 970.8306000102311, + 638.270299998112, + 645.0284000020474, + 595.9507999941707, + 655.6438000116032, + 742.6067000196781, + 664.4221999740694, + 949.3801000062376, + 669.1808000032324, + 651.2798999901861, + 947.1278999990318, + 673.1025999761187, + 1428.6546000221279, + 838.2126000069547, + 741.3567999901716, + 841.4533000031952, + 688.6248999799136, + 951.3059000018984, + 571.4535000151955, + 662.0842000120319, + 645.194899989292, + 833.4023999923375, + 847.6889999874402, + 564.2403999809176, + 635.8059999765828, + 1233.9158999966457, + 650.1101999892853, + 644.096099975286, + 847.7308000146877, + 950.2465999976266, + 575.92519998434, + 634.6712000085972, + 936.7084999976214, + 661.8625999835785, + 646.3319000031333, + 572.1782999753486, + 1544.3340000056196, + 641.0626999859232, + 646.5462000051048, + 848.1153000029735, + 640.0495999841951, + 664.1281000047456, + 665.2354999969248, + 670.699100010097, + 666.1617999779992, + 669.2022000206634, + 885.1299000089057, + 662.3255000158679, + 658.7356000090949, + 1059.6731000114232, + 839.1197999881115 + ] + }, + "official": { + "editor_state": [ + 597.3320000048261, + 586.3020000106189, + 950.7696999935433, + 772.6898000109941, + 795.8606999891344, + 959.7544000134803, + 599.111300020013, + 781.1711000103969, + 803.126400016481, + 779.2495000176132, + 614.0141999931075, + 572.1398000023328, + 555.1306999986991, + 876.3387000071816, + 608.3178000117186, + 677.6222000189591, + 871.559100021841, + 794.0587000048254, + 989.1562999982852, + 785.6836999999359, + 711.6510999912862, + 674.101900018286, + 1195.4103999887593, + 592.1543000149541, + 532.7690000121947, + 676.8314000219107, + 578.5713999939617, + 571.6371999878902, + 695.2138000051491, + 884.9656000093091, + 802.9129999922588, + 597.3534000222571, + 793.1100999994669, + 882.7077000169083, + 782.9386999947019, + 889.1425000037998, + 600.0016999896616, + 793.0058000201825, + 601.9960999838077, + 590.6383999972604, + 1188.3649000083096, + 802.7151999995112, + 593.515499989735, + 781.0484999790788, + 896.2423999910243, + 848.8914000045042, + 705.1149000180885, + 575.4371999937575, + 899.4782000081614, + 797.0853000006173, + 809.4153999991249, + 587.3002000153065, + 694.8114999977406, + 774.6751999948174, + 895.0425999937579, + 591.3979999895673, + 904.2730000219308, + 577.2268000000622, + 614.503099990543, + 1370.1807000034023, + 905.9248999983538, + 1095.766199985519, + 609.2775999859441, + 582.8708999906667, + 1008.0596999905538, + 678.687900013756, + 893.4624000103213, + 544.9351000133902, + 885.3362000081688, + 871.9281000085175, + 789.0314999967813, + 566.6139000095427, + 714.9068000144325, + 589.817200001562, + 1094.7684999846388, + 876.3442999916151, + 598.52420000243, + 682.53759999061, + 691.6074999899138, + 857.4473000189755, + 598.7469000101555, + 771.7732999881264, + 602.8548000031151, + 675.1780000049621, + 702.4606000049971, + 581.0679999995045, + 597.6115000084974, + 891.4476999780163, + 781.076800019946, + 879.2202000040561, + 595.2875000075437, + 689.139800000703, + 610.2752999868244, + 588.1144000159111, + 596.9659000111278, + 1472.7497000130825, + 907.0889999857172, + 585.1888000033796, + 610.11460001464, + 598.220100015169 + ], + "hierarchy": [ + 608.4141999890562, + 582.8692000068258, + 554.8596000007819, + 1113.7873000116087, + 1282.1937999979127, + 1816.3681000005454, + 598.2035000051837, + 939.6684999810532, + 588.0236999946646, + 592.5061000161804, + 891.3855999999214, + 1000.229400000535, + 834.9758999829646, + 611.3834999850951, + 889.7809000045527, + 618.4686000051443, + 702.8300999954809, + 983.1547000212595, + 712.3601000057533, + 687.7360000216868, + 697.7857000019867, + 1498.4377999790013, + 598.1673000205774, + 844.0508999919984, + 719.8122999980114, + 607.708299998194, + 723.7471000116784, + 920.9944999893196, + 1216.7487999831792, + 692.2341999888886, + 601.2970000156201, + 579.1079000046011, + 1816.4755000034347, + 593.8315000094008, + 912.1613999886904, + 908.8076000043657, + 603.9357999979984, + 593.6597000109032, + 780.5656999989878, + 890.3575000003912, + 600.0174999935552, + 1371.1859000031836, + 888.6765000061132, + 1245.9740999911446, + 801.1685999808833, + 820.01590001164, + 718.1289000145625, + 811.3643000251614, + 802.5256000109948, + 988.3459999982733, + 690.3897000011057, + 889.6359000063967, + 617.4208999727853, + 800.8249999838881, + 599.2247999820393, + 800.7627000042703, + 550.0301000138279, + 599.0954000153579, + 824.6120999974664, + 607.9499999759719, + 890.9501999733038, + 587.0479999866802, + 579.5351999986451, + 594.721200002823, + 595.6116000015754, + 687.3417999886442, + 796.796299982816, + 618.4474999899976, + 604.14129999117, + 690.862699993886, + 600.2171000000089, + 806.2786000082269, + 1271.79790000082, + 601.3785999966785, + 611.2908000068273, + 706.3515999761876, + 595.486299978802, + 607.1879000228364, + 605.3377999924123, + 650.4337000078522, + 615.15500000678, + 611.2441000004765, + 582.9467999865301, + 906.3048000098206, + 919.5497999899089, + 594.743900001049, + 695.581600011792, + 885.5671999917831, + 713.3347000053618, + 605.783299979521, + 602.804299996933, + 592.2900000005029, + 587.1970999869518, + 886.6291999875102, + 716.9651999720372, + 592.4948000174481, + 1272.5940000091214, + 590.5395000008866, + 599.1428000270389, + 691.8831999937538 + ], + "find_gameobject": [ + 683.7852000026032, + 606.6578000027221, + 582.71539999987, + 985.623399988981, + 587.7690000052098, + 604.779299988877, + 594.7111999848858, + 670.9323999821208, + 903.1882999988738, + 807.1974999911617, + 892.615199991269, + 801.3341999903787, + 731.3837999827228, + 789.6925000241026, + 1800.1506000000518, + 584.7955000062939, + 1006.2900000193622, + 1042.8230999968946, + 799.5777999749407, + 617.5288000085857, + 1203.6456000059843, + 811.1371999839321, + 598.4763999877032, + 929.4232000247575, + 1238.6527999769896, + 690.2551999955904, + 685.2248000213876, + 677.84320001374, + 586.925199982943, + 1198.5204000084195, + 594.75580000435, + 903.8778000103775, + 701.3925000210293, + 711.8037000182085, + 881.2329999927897, + 998.349400004372, + 1511.8709999951534, + 595.5998999997973, + 601.8930000136606, + 1292.2444999858271, + 875.7200000109151, + 611.4131000067573, + 708.5208999924362, + 2392.8032999974675, + 1498.7578000000212, + 704.595600022003, + 872.525000013411, + 899.7459000092931, + 712.9590999975335, + 598.9517999987584, + 702.9890000121668, + 692.4518999876454, + 595.100199978333, + 1001.7169000057038, + 594.699799985392, + 897.9230999830179, + 530.961100012064, + 615.8124000066891, + 869.4946000177879, + 692.184699990321, + 912.7879999869037, + 595.4629000043496, + 606.304499990074, + 893.7001999875065, + 598.8676999986637, + 799.6362000121735, + 1214.7488000045996, + 633.8687999814283, + 679.9093000008725, + 908.4030999802053, + 1699.8817999847233, + 695.6646999751683, + 620.8959000068717, + 687.5337000237778, + 612.2806000057608, + 994.0152999770362, + 610.4304000036791, + 595.6953999993857, + 701.5745000098832, + 551.1612999835052, + 592.8053999959957, + 589.21159998863, + 597.6616999832913, + 589.8082000203431, + 689.6629999973811, + 810.4381000157446, + 697.0158999902196, + 1003.5421999928076, + 910.363300004974, + 785.3630000026897, + 597.7741000242531, + 608.8890999963041, + 618.135099997744, + 895.2332999906503, + 594.6587999933399, + 616.0365999967325, + 614.3486000073608, + 606.2103000003844, + 587.2201999882236, + 591.4440999913495 + ], + "transform": [ + 994.7742000222206, + 893.974899983732, + 738.5940999956802, + 895.4892999900039, + 731.8196999840438, + 1072.4995999771636, + 1098.2706000213511, + 925.1986999879591, + 1094.8155999940354, + 1092.8985999780707, + 989.0982999932021, + 1098.763299989514, + 1456.283599982271, + 2303.6476999986917, + 792.334400000982, + 991.3875999918673, + 1692.819399992004, + 754.5410000020638, + 779.719699989073, + 796.5945999894757, + 894.1119999799412, + 768.0578999861609, + 785.9261999838054, + 824.9066999997012, + 1391.7804000084288, + 893.1827000051271, + 793.2029000076, + 1411.5581999940332, + 992.3610999830998, + 988.8515000056941, + 986.930700019002, + 1723.0510000081267, + 881.8393000110518, + 1081.6816000151448, + 1110.1149000169244, + 884.1768999991473, + 790.1848999899812, + 1169.422199978726, + 1091.2203000043519, + 792.2509000054561, + 917.3989999981131, + 786.826800002018, + 1197.3134000145365, + 865.4419999802485, + 777.8011000191327, + 1197.7360000018962, + 1090.5752000107896, + 983.6764000065159, + 771.1229000124149, + 803.8255000137724, + 798.5879999760073, + 1387.3359000135679, + 790.399100020295, + 1029.0773999877274, + 802.807899977779, + 1383.3063000056427, + 750.1702999870759, + 1058.8218999910168, + 731.3541000185069, + 914.805799984606, + 1112.9284999915399, + 1092.7407999988645, + 1087.9835999803618, + 814.0726999845356, + 778.1721999926958, + 894.8575000104029, + 1086.5412999992259, + 967.8502999886405, + 794.261800008826, + 791.7939999897499, + 821.8041000072844, + 993.2147999934386, + 801.95090000052, + 1287.5706999911927, + 788.5172000096645, + 828.9962999988347, + 1282.6870999997482, + 987.4934999970719, + 1187.8931999963243, + 1132.900900003733, + 819.752100011101, + 895.8447000186425, + 995.2962000097614, + 1100.9913999878336, + 775.9250000235625, + 794.8728000046685, + 789.0969000000041, + 795.8358000032604, + 780.0046000047587, + 990.8277000067756, + 796.286600001622, + 797.3495000042021, + 789.6955000178423, + 1104.33020000346, + 998.4551999950781, + 1080.8758000202943, + 799.7123999812175, + 787.9264999937732, + 788.4927999984939, + 1018.4689000016078 + ], + "position": [ + 993.2963000028394, + 601.9613000098616, + 841.4555999916047, + 889.6749999839813, + 1489.6904999914113, + 610.1966999995057, + 612.4800000106916, + 860.8714999863878, + 806.9852000044193, + 697.1040999924298, + 1305.4324999975506, + 603.3755999815185, + 560.2972999913618, + 792.1042000234593, + 908.6057000095025, + 989.6379999991041, + 708.5521999979392, + 605.9011000033934, + 621.0120000177994, + 597.7837000100408, + 596.0555000056047, + 809.865000017453, + 604.9682999728248, + 541.3897999969777, + 608.1972999963909, + 1014.208900014637, + 1801.9281000015326, + 606.6420999995898, + 809.9851000006311, + 618.2275000028312, + 1410.5079000000842, + 582.4878999846987, + 603.950699995039, + 696.6269999975339, + 832.1569000254385, + 795.4363999888301, + 591.9959000020754, + 623.4786999993958, + 1316.503100009868, + 724.3807000049856, + 797.5626999977976, + 613.256700016791, + 1010.8136000053491, + 695.8990999846719, + 811.911600001622, + 1816.6032999870367, + 1300.3674000210594, + 888.443300005747, + 600.8968999958597, + 810.397399996873, + 804.1873000038322, + 617.0912999950815, + 608.7525000039022, + 601.6749999835156, + 609.9080000130925, + 703.586500021629, + 561.9377000257373, + 1175.4459000076167, + 547.9125000128988, + 690.3843999898527, + 797.8447999921627, + 795.346700004302, + 1000.2348000125494, + 595.9455000120215, + 619.769399985671, + 794.5145000121556, + 593.8554999884218, + 757.6997999858577, + 723.09069999028, + 592.0303000020795, + 596.7145999893546, + 1293.2950000104029, + 793.3845999941695, + 610.9645999968052, + 1214.064400002826, + 573.9158999931533, + 1302.6936000096612, + 1618.3074000000488, + 604.5317999960389, + 531.5076000115369, + 913.3835999818984, + 600.782599998638, + 604.2292999918573, + 602.4501999781933, + 817.5860000192188, + 592.8654999879654, + 900.653400021838, + 625.2585000183899, + 603.2922000158578, + 596.2747999874409, + 580.060800013598, + 708.4670000185724, + 896.4135999849532, + 593.0002999957651, + 888.1813999905717, + 694.6513000002597, + 582.5428999960423, + 604.3522999971174, + 624.9406000133604, + 561.1065000121016 + ], + "create_cube": [ + 1121.9517000135966, + 806.8807999952696, + 924.9765000131447, + 822.4828999955207, + 705.3747000172734, + 897.6508000050671, + 600.6644000008237, + 885.9324999793898, + 590.5405000085011, + 681.4095000154339, + 697.3860000143759, + 809.422899998026, + 581.3142999832053, + 903.2088000094518, + 990.8703000110108, + 919.2464000079781, + 602.097800001502, + 804.9054000002798, + 1309.8275999946054, + 605.2223999868147, + 704.4539999915287, + 1003.9053000218701, + 999.7418000129983, + 742.3477999982424, + 601.6982000146527, + 791.1887000082061, + 611.690699995961, + 608.0246999918018, + 780.2607999765314, + 608.4813999768812, + 901.8706000060774, + 915.7171999977436, + 891.3968999986537, + 818.2755000016186, + 1482.7448999858461, + 599.9688000010792, + 608.290499978466, + 605.7504999917, + 603.1487000000197, + 600.3225999884307, + 617.0376999943983, + 802.1800999995321, + 704.6811000036541, + 806.1158000200521, + 606.2536000099499, + 609.6647000231314, + 812.6579999807291, + 830.1159999973606, + 996.0660999931861, + 1286.9345000071917, + 888.2122999930289, + 599.7366000083275, + 596.9533000024967, + 697.0788999751676, + 701.2336000043433, + 906.7527999868616, + 1228.3356999978423, + 829.09089999157, + 548.4321999829262, + 615.2606000250671, + 801.3193999940995, + 996.2529999902472, + 614.2392000183463, + 615.3888000117149, + 703.360600018641, + 613.8002999941818, + 614.4265999901108, + 862.3063999984879, + 592.4820999789517, + 819.8310000007041, + 601.4234999893233, + 882.1585000259802, + 801.5873999975156, + 593.6958999955095, + 904.8126999987289, + 721.4231999823824, + 887.2141000174452, + 803.3279999799561, + 599.3611000012606, + 555.1483000162989, + 602.5418999779504, + 597.843900002772, + 611.533999996027, + 605.7454000110738, + 700.0815999926999, + 593.6341999913566, + 594.8486000124831, + 580.2179999882355, + 597.4349999742117, + 600.5493999982718, + 610.2886000007857, + 597.413499985123, + 614.6991999994498, + 595.7304000039585, + 590.1028999942355, + 906.5530000079889, + 605.2610999904573, + 889.0040000260342, + 1376.1536999954842, + 809.2022999771871 + ], + "add_component": [ + 972.4719000223558, + 1077.5065000052564, + 930.6556000083219, + 992.7311999781523, + 801.9073000177741, + 790.0359999912325, + 792.9201000079047, + 922.14119998971, + 809.8023000056855, + 902.715200005332, + 809.4665999815334, + 881.6465999989305, + 793.33470002166, + 1798.9843000250403, + 920.8031000162009, + 784.6583000209648, + 786.8283000134397, + 2914.332699991064, + 769.7641999984626, + 994.0109000017401, + 1192.2603000130039, + 1398.6998999898788, + 798.3827999851201, + 1009.9099999933969, + 781.3313999795355, + 798.7079000158701, + 1081.7801999801304, + 957.8153000038583, + 1193.1444000219926, + 969.2950999888126, + 782.0391999848653, + 890.9838999970816, + 802.9110000061337, + 890.3305999992881, + 796.3217000069562, + 807.360399980098, + 1088.8665999809746, + 967.9480999766383, + 812.1773000166286, + 992.4909999826923, + 1084.257099981187, + 767.487400007667, + 889.9613000103272, + 1204.9659000185784, + 973.8145000010263, + 1097.1448999771383, + 979.2815999826416, + 970.1797000016086, + 1015.806600014912, + 999.5763000042643, + 800.4558999964502, + 911.3681000017095, + 896.340200008126, + 1199.0027999854647, + 898.8340999931097, + 786.46909998497, + 852.1438000025228, + 877.0764999790117, + 1100.5883000034373, + 791.4923999924213, + 1086.6965999884997, + 785.3000000177417, + 793.3766999922227, + 892.4694999877829, + 881.3430999871343, + 869.6235999814235, + 1000.2127999905497, + 722.3270999966189, + 777.1123000129592, + 1065.0337999977637, + 783.4261000098195, + 826.8430999887642, + 1385.4868999915197, + 787.7500000176951, + 906.5038999833632, + 904.027499986114, + 797.9251000215299, + 789.5056999986991, + 785.3401000029407, + 726.1574000003748, + 785.6326999899466, + 790.7863000000361, + 785.9829000080936, + 978.7423999805469, + 791.0236000025179, + 917.8856999787968, + 1003.2192000071518, + 977.7979000064079, + 883.8860999967437, + 792.5818999938201, + 807.620700012194, + 997.6697000092827, + 1088.5684000095353, + 803.02959997789, + 810.4540999920573, + 1192.6392000168562, + 796.0727000026964, + 1205.1792000129353, + 810.118399997009, + 1086.769399989862 + ], + "remove_component": [ + 1002.0370999991428, + 993.8217000162695, + 776.7312000214588, + 997.2038999840152, + 884.8778000101447, + 883.2053000223823, + 783.9127999905031, + 779.4922000030056, + 999.1118000179995, + 796.9272999907844, + 981.2044999853242, + 797.0003999944311, + 781.2085999757983, + 915.2061000058893, + 1089.6192000072915, + 875.3717000072356, + 788.9374000078533, + 1131.0899999807589, + 1097.965299995849, + 1104.8372999939602, + 813.6724999931175, + 798.4959000023082, + 794.2169999878388, + 1530.3887000191025, + 1094.0336000057869, + 995.0456999940798, + 1015.7554000033997, + 1603.5618000023533, + 908.9984000020195, + 1187.4085000017658, + 1092.7491000038572, + 1100.0256999977864, + 1089.4717000192031, + 1511.4843999908771, + 986.6409999958705, + 899.8856999969576, + 1212.815300008515, + 1924.1670000192244, + 779.9197999993339, + 1277.182999998331, + 791.2195000099018, + 907.0069000008516, + 898.9176999893971, + 797.9833999997936, + 2204.1289000189863, + 1063.260299997637, + 1088.0352000240237, + 1921.3834000111092, + 787.0628999953624, + 796.774499991443, + 788.2879999815486, + 866.9444000115618, + 780.2222000027541, + 788.441899989266, + 994.7611000097822, + 798.8981999806128, + 878.7413999962155, + 889.2569000017829, + 1086.4624000096228, + 1078.2477000029758, + 1268.133100005798, + 785.7010000152513, + 1043.2479999726638, + 1189.0193999861367, + 780.5922999978065, + 1000.9409000049345, + 800.9512000135146, + 865.0115999917034, + 889.7876999981236, + 809.6966999873985, + 1398.853799997596, + 789.565200015204, + 788.1750999949872, + 982.9392000101507, + 1275.964299973566, + 1274.9881999916397, + 890.811199991731, + 979.9485000257846, + 790.8722000138368, + 931.0077000118326, + 1095.7635999948252, + 790.6129000184592, + 807.9482000030112, + 1200.5262000020593, + 793.2566999807023, + 771.2329000059981, + 776.4380000007804, + 799.960700009251, + 1201.4189999899827, + 913.3271999889985, + 772.0634000143036, + 986.6402999905404, + 1119.2743999999948, + 1081.5572999999858, + 1089.8839999863412, + 803.7021000054665, + 774.3214000074659, + 814.4387000065763, + 790.3149999910966, + 1001.4116000093054 + ], + "delete_gameobject": [ + 610.2610999951139, + 702.7273999992758, + 806.4143999945372, + 812.4498999968637, + 699.2929999832995, + 700.735500024166, + 920.6881000136491, + 602.2727999952622, + 697.6694000186399, + 793.2474999979604, + 596.9544000108726, + 604.2345000023488, + 712.4447000096552, + 799.2155999818351, + 815.8004000142682, + 1097.6513999921735, + 1904.8468999972101, + 596.6214999789372, + 881.9023999967612, + 693.7340000004042, + 587.8069000027608, + 596.7484999855515, + 905.9707999986131, + 891.8407000019215, + 1099.6560000057798, + 588.1924999994226, + 574.5835999841802, + 581.6084000107367, + 599.4534000055864, + 613.6878000106663, + 783.0426000000443, + 675.9957999747712, + 701.945800014073, + 603.9241999969818, + 612.0717000158038, + 897.276800009422, + 801.0406999965198, + 587.0916999992914, + 690.9891999966931, + 607.9279000114184, + 1195.746900019003, + 920.0820999976713, + 981.1174999922514, + 896.3303999917116, + 597.642899985658, + 1085.962400014978, + 1002.740800002357, + 796.6213999898173, + 696.4046999928541, + 805.7165000063833, + 777.3771999927703, + 607.2588000097312, + 885.990100010531, + 611.0013999859802, + 900.2035000012256, + 1099.8016000085045, + 901.8470000009984, + 598.9129000226967, + 583.0283999966923, + 1113.5141999984626, + 600.9367000078782, + 802.488599991193, + 1088.510799978394, + 610.8907000161707, + 600.46039998997, + 606.9625000236556, + 602.2075999935623, + 544.7107000218239, + 807.3303999844939, + 594.9426000006497, + 606.3243999960832, + 791.183599998476, + 616.7538999870885, + 703.0303000065032, + 917.8530999924988, + 594.5940000237897, + 705.0583999953233, + 1307.5479999824893, + 1402.4920999945607, + 547.9979999945499, + 1501.486399996793, + 601.7900999868289, + 584.1788000252564, + 894.0075999998953, + 594.1596000047866, + 704.2883000103757, + 1118.7352999986615, + 595.7977999933064, + 605.0632999977097, + 780.1382999750786, + 914.7076999943238, + 704.3670999992173, + 1080.3412000241224, + 597.2982000093907, + 706.8075000133831, + 895.3497000038624, + 630.0234000082128, + 1299.190699995961, + 593.3277999865822, + 582.4731000175234 + ], + "scene_info": [ + 899.3580999958795, + 694.5449000049848, + 585.0236999976914, + 593.7695000029635, + 592.8591999982018, + 722.9509000026155, + 1176.8539999902714, + 778.6865999805741, + 703.151700028684, + 590.2245999895968, + 991.8010999972466, + 582.6571999932639, + 597.9651999950875, + 716.609499999322, + 891.6330999927595, + 597.3135999811348, + 600.2350999915507, + 983.6991000047419, + 595.9299000096507, + 993.0908000096679, + 590.6863999844063, + 591.6280999954324, + 697.2045000002254, + 602.3786000150722, + 891.9779999996535, + 907.2687000152655, + 1017.5191999878734, + 611.964599986095, + 604.12480001105, + 616.7448000051081, + 622.0141999947373, + 798.5511000151746, + 703.568400000222, + 587.6905999903101, + 1586.615799984429, + 1173.4147999959532, + 907.459200010635, + 583.0819000257179, + 709.4250999798533, + 583.728900004644, + 2002.0653999818023, + 1099.0352000226267, + 893.4324000147171, + 903.174700011732, + 623.0218000127934, + 1508.5163000039756, + 896.7165999929421, + 1592.1486000006553, + 685.7763000007253, + 602.1301000146195, + 610.3207000123803, + 597.5153000035789, + 598.1370999943465, + 686.5873000060674, + 787.6799000077881, + 797.3122999828774, + 587.5023999833502, + 698.795499978587, + 699.9097999942023, + 583.561000006739, + 609.0940999856684, + 589.3494000192732, + 599.0939999755938, + 588.7518000090495, + 594.6210999973118, + 1105.8556000061799, + 586.8971000018064, + 868.8045000017155, + 579.9125999910757, + 594.0892999933567, + 584.8858999961521, + 1784.4194000062998, + 590.1987999968696, + 1000.912600022275, + 902.2488999762572, + 617.3381000116933, + 1179.6627000148874, + 696.8845999799669, + 604.2700999823865, + 741.9005999981891, + 584.4709999801125, + 686.2249000114389, + 789.9271000060253, + 600.9527000132948, + 616.9784999801777, + 992.1210000175051, + 584.6208999864757, + 799.0337000228465, + 607.9530999995768, + 597.1774000208825, + 1287.2644000162836, + 596.1992000229657, + 596.2832999939565, + 593.1360000104178, + 886.8970999901649, + 691.6600000113249, + 875.7240000122692, + 804.9823000037577, + 579.5826000103261, + 702.7476000075694 + ], + "scene_save": [ + 996.7073000152595, + 899.002299993299, + 1347.744500002591, + 897.8242000157479, + 715.080099995248, + 691.3921000086702, + 719.1449000092689, + 1319.4696999853477, + 906.783499987796, + 898.8735000020824, + 727.9976999852806, + 831.4667999802623, + 807.711700006621, + 1310.8500000089407, + 809.9283000046853, + 732.7975999796763, + 725.0048000132665, + 995.5678000114858, + 822.8919999965001, + 721.2808000040241, + 909.0519000019412, + 718.2811000093352, + 1092.772200005129, + 1107.7240000013262, + 729.9673999950755, + 684.586000017589, + 830.2229000255466, + 1016.0824000195134, + 801.0818999900948, + 701.4185999869369, + 897.2527000005357, + 1021.6043000109494, + 1389.163699990604, + 892.7364999835845, + 826.2839999806602, + 920.9185000217985, + 796.9309999898542, + 712.4078999913763, + 704.1002000041772, + 1005.3155000205152, + 1011.7792999953963, + 993.5810000170022, + 715.3511999931652, + 1016.2476999976207, + 911.045999993803, + 898.8491000200156, + 814.5985000010114, + 819.4032000028528, + 1701.9459000148345, + 797.0736999996006, + 909.259900014149, + 696.62880001124, + 711.1197999911383, + 813.9995999808889, + 1009.5056999998633, + 813.594799983548, + 1027.1175000234507, + 1113.2768999959808, + 695.3781000047456, + 887.8925000026356, + 727.3889000061899, + 1011.4224000135437, + 711.3717999891378, + 923.3876999933273, + 721.8090000096709, + 682.4573999911081, + 922.2149999986868, + 856.7017000168562, + 807.5862999830861, + 817.4746000149753, + 817.2197999956552, + 717.7738000173122, + 704.3210999981966, + 855.0780000223313, + 716.8009000015445, + 809.7287000273354, + 806.3155000272673, + 709.0805000043474, + 696.4338000107091, + 910.3391999960877, + 805.921599996509, + 732.5622999924235, + 805.9621999855153, + 695.1700999925379, + 692.2990999883041, + 702.5993000133894, + 701.4544999983627, + 995.3339000057895, + 703.4054000105243, + 910.2674000023399, + 704.958499991335, + 716.4035000023432, + 690.9953000140376, + 907.8111000126228, + 700.0119000149425, + 788.8601000013296, + 919.2948999989312, + 1596.715799998492, + 719.9701000063214, + 716.7695999960415 + ], + "console": [ + 538.1819999893196, + 1033.2717999990564, + 535.6994000030681, + 848.8897000206634, + 714.1890999919269, + 711.6475999937393, + 700.2256999840029, + 557.2017000231426, + 1423.4979000175372, + 922.9436999885365, + 539.5805000152905, + 673.4396999818273, + 541.1718000250403, + 530.293999996502, + 839.2102000070736, + 540.768200007733, + 552.6199000014458, + 776.2138999823947, + 1341.6229999857023, + 540.0842999806628, + 553.1174999778159, + 545.3074999968521, + 537.9316000035033, + 1065.4184999875724, + 717.7380000066478, + 539.4623000174761, + 560.3456000098959, + 1146.3131000055, + 531.2852000060957, + 648.3435000118334, + 535.1899999950547, + 532.1054000232834, + 623.7581000023056, + 583.7255999795161, + 536.5015999996103, + 856.1744000180624, + 805.9652999800164, + 791.4096000022255, + 746.2061999831349, + 1216.9588999822736, + 825.6298000051174, + 570.8300999831408, + 547.9191000049468, + 1378.1672999903094, + 755.2136999729555, + 682.377599994652, + 1400.5059999763034, + 823.031899984926, + 689.3839999975171, + 532.3561999830417, + 534.2989999917336, + 571.2647000036668, + 528.3516000199597, + 750.3432999947108, + 618.1793000141624, + 817.453999974532, + 583.6062000016682, + 545.4152000020258, + 767.2554000164382, + 537.048500002129, + 558.8206999818794, + 826.2640000029933, + 716.34039998753, + 778.6296000122093, + 655.4245000006631, + 555.4299000068568, + 537.1645000122953, + 791.529799986165, + 647.3338999785483, + 729.2787999904249, + 628.7775000091642, + 732.4490000028163, + 536.533899983624, + 998.6223000159953, + 542.165799997747, + 537.0762000093237, + 567.8678000112996, + 773.6507999943569, + 612.3074000061024, + 552.4503999913577, + 831.4533999946434, + 537.8414999868255, + 542.0857999997679, + 536.1099999863654, + 733.6708000220824, + 544.0830000152346, + 543.57050001272, + 536.4628999959677, + 546.3734999939334, + 860.2109999919776, + 539.3235000083223, + 792.2815000056289, + 539.3997000064701, + 973.0871999927331, + 599.6248000010382, + 534.8056000075303, + 625.2232999831904, + 795.1311999931931, + 541.3717000046745, + 737.4844999867491 + ], + "screenshot": [ + 634.3149000022095, + 718.2983999955468, + 822.663900005864, + 1032.086099992739, + 946.2496000051033, + 843.1126999785192, + 757.0436999958474, + 807.8026000002865, + 656.32799998275, + 1859.2339000024367, + 720.115000003716, + 966.308700008085, + 1008.8307000114582, + 646.3742000050843, + 734.0631000115536, + 729.8439999867696, + 1002.7247000252828, + 795.5019999935757, + 925.6226000143215, + 919.2075000028126, + 1320.4069999919739, + 607.1059000096284, + 856.6452999948524, + 824.4972999964375, + 849.6300999831874, + 641.2806999869645, + 614.1414000012446, + 613.4177999920212, + 832.3765000095591, + 1610.5271000124048, + 1355.403399997158, + 740.0375000142958, + 760.0550999923144, + 887.0223999838345, + 828.0888000153936, + 926.5595999895595, + 1571.8316000129562, + 867.5948000163771, + 816.5857999993023, + 758.2382999826223, + 861.3645999867003, + 699.7769000008702, + 610.309400013648, + 682.9336000082549, + 810.7979000196792, + 1091.3222999952268, + 657.4887000024319, + 640.0875999825075, + 885.3372000157833, + 722.8324999741744, + 642.5350999925286, + 594.5089000160806, + 851.1924000049476, + 1017.7931000071112, + 761.9459000125062, + 1366.1029000068083, + 1801.2912000122014, + 618.2534999970812, + 705.6880000163801, + 934.0276999864727, + 1105.3530999924988, + 648.771799984388, + 969.4098000181839, + 692.6035000069533, + 1007.8074999910314, + 715.0028000178281, + 634.8248000140302, + 1137.6848999934737, + 645.5584999930579, + 1041.1654000054114, + 731.6468000062741, + 638.6346000072081, + 637.1618999983184, + 1117.0880000281613, + 601.4354999933857, + 619.6204999869224, + 619.3288999784272, + 1093.7927000049967, + 656.2182999914512, + 780.9187000093516, + 734.0232999995351, + 720.1683000021148, + 624.424799985718, + 746.1946000112221, + 625.6930999807082, + 627.9409999842755, + 626.6118000203278, + 649.6231000055559, + 619.6772000112105, + 625.2976999967359, + 627.9101000109222, + 668.2749000028707, + 633.8028000027407, + 604.5053999987431, + 664.1211000096519, + 642.6286000059918, + 623.4459999832325, + 689.9471000069752, + 739.7157000086736, + 609.6416000218596 + ], + "material_search": [ + 608.208999998169, + 715.9241999906953, + 610.4060000216123, + 697.7578999940306, + 808.4140999999363, + 906.2289999856148, + 811.5044000151101, + 622.0498000038788, + 623.6662000010256, + 608.0069000017829, + 606.6920000012033, + 603.2417000096757, + 618.7120999966282, + 1318.5595000104513, + 598.7781999865547, + 897.1331999928225, + 806.6173999977764, + 814.570399990771, + 999.078399996506, + 809.2896000016481, + 801.7507999902591, + 818.8529000035487, + 899.2999999900348, + 587.6044000033289, + 797.7334999886807, + 620.0660999747925, + 899.2638999770861, + 803.9535999996588, + 1722.3003999970388, + 907.4224999931175, + 603.0967000115197, + 793.9120999944862, + 607.0269999909215, + 604.2045000067446, + 1498.303100001067, + 594.2450000147801, + 607.1053999767173, + 603.5487999906763, + 1099.4759000022896, + 942.0519000268541, + 1490.1528999907896, + 792.4874000018463, + 915.1476000261027, + 596.6952000162564, + 902.6509000104852, + 699.9978999956511, + 733.1037999829277, + 697.8717999882065, + 721.485100017162, + 604.2231000028551, + 599.0035000140779, + 611.9872000126634, + 584.8636000009719, + 898.2242000056431, + 600.230800017016, + 699.9978999956511, + 815.5113999964669, + 802.0983999886084, + 801.1006999877281, + 910.5912999948487, + 610.48919998575, + 608.5848000075202, + 1418.6954000033438, + 700.0463999866042, + 903.4913000068627, + 814.3061000155285, + 806.1811000225134, + 591.489599988563, + 794.3873000040185, + 892.654199997196, + 715.5561000108719, + 698.31529998919, + 609.0622999763582, + 821.513100003358, + 711.7579999903683, + 903.0779000022449, + 912.7013999968767, + 1205.6107000098564, + 1018.2340999890584, + 1014.5779000013135, + 1521.0930000175722, + 584.9991999857593, + 608.1510999938473, + 1107.0015000004787, + 607.7619999996386, + 897.3865000007208, + 600.5073999986053, + 601.8452999996953, + 697.5289999973029, + 588.7534999928903, + 904.981300001964, + 1396.9213000091258, + 622.7572000061627, + 580.7158999959938, + 603.7424000096507, + 609.8028999986127, + 602.6919000141788, + 891.7339000036009, + 601.1725999996997, + 635.445299994899 + ], + "asset_copy": [ + 750.6895999831613, + 654.3161000008695, + 859.0132000099402, + 658.4037999855354, + 769.0219000214711, + 1576.5289000119083, + 867.4529000127222, + 849.1038999927696, + 642.6140000112355, + 681.744700006675, + 767.9398999898694, + 680.8970000129193, + 664.1221000172663, + 949.6509000018705, + 980.3842999972403, + 1064.02170000365, + 881.9561999989673, + 964.2529999837279, + 649.2863000021316, + 664.597800001502, + 871.9016999821179, + 957.0243000052869, + 645.6756000116002, + 863.7954000150785, + 766.5691000001971, + 753.8318999868352, + 956.4613000256941, + 860.4203000140842, + 843.0924999993294, + 855.9367999841925, + 652.2027000028174, + 874.2018999764696, + 851.5600999817252, + 865.3916000039317, + 1271.8600999796763, + 674.6149999962654, + 945.811199984746, + 675.3039000032004, + 662.1702999982517, + 926.3718000147492, + 1294.583800015971, + 1060.126800002763, + 1059.168799984036, + 856.8056999938563, + 1285.1376000035089, + 1265.6968999945093, + 1044.9378000048455, + 1278.053700021701, + 843.3543000137433, + 871.8969999754336, + 766.8783999979496, + 959.1655000112951, + 976.7606999957934, + 1265.001799998572, + 1356.5098000108264, + 648.7768999941181, + 650.2128999854904, + 967.3032000137027, + 765.8562999858987, + 666.8604000005871, + 654.7633000009228, + 766.6446000221185, + 668.4260999900289, + 770.7968000031542, + 664.5533999835607, + 1560.352000000421, + 1367.8686000057496, + 879.8690999974497, + 673.0416000063997, + 884.5382000145037, + 858.0128999892622, + 1061.931000003824, + 757.0145000063349, + 655.4105999821331, + 1562.4725999950897, + 771.1757000070065, + 662.5617000099737, + 671.152599999914, + 954.6602999907918, + 1465.3654999856371, + 745.0812000024598, + 658.838499977719, + 663.8378000061493, + 656.521500000963, + 970.344200002728, + 769.5791999867652, + 662.7275999926496, + 953.3447999856435, + 667.0419999863952, + 664.6431999979541, + 968.662300001597, + 651.4224999991711, + 843.4857000247575, + 664.7807999979705, + 871.9137000152841, + 665.9231999947224, + 689.1920999914873, + 678.9280000084545, + 655.4589000006672, + 667.7487000124529 + ], + "asset_move": [ + 1520.0544999970589, + 983.8464999920689, + 666.762499982724, + 777.3471999971662, + 1277.851599996211, + 684.0219000005163, + 669.7100000164937, + 754.7771999961697, + 681.5754999988712, + 657.5297999952454, + 994.1634999995586, + 865.9637999953702, + 668.2865000038873, + 773.114199982956, + 1105.0955999817234, + 675.5360999959521, + 652.0336999965366, + 968.5540999926161, + 883.8890999904834, + 667.5043000141159, + 963.0490000126883, + 898.6854999966454, + 789.2291999887675, + 1448.4041999967303, + 692.9278000025079, + 662.9405000130646, + 662.2657999978401, + 663.2873000053223, + 674.1105999972206, + 663.0540000041947, + 768.8770999957342, + 1779.362300003413, + 2125.8502999844495, + 655.0679999927524, + 669.5973000023514, + 663.089299981948, + 890.847800008487, + 957.8618999803439, + 690.2423000137787, + 665.2018000022508, + 682.4882999935653, + 681.9134999823291, + 660.5818999814801, + 791.9350000156555, + 957.6710999826901, + 680.6372000137344, + 984.9608999793418, + 873.3250999939628, + 673.0518999975175, + 663.8739999907557, + 666.5024000103585, + 781.428499991307, + 1121.0021000006236, + 660.2238999912515, + 857.0659999968484, + 894.329699978698, + 771.3460000231862, + 1069.4508999877144, + 671.3693999918178, + 759.487800009083, + 680.1112999964971, + 652.2092999948654, + 666.2574999791104, + 662.9775000037625, + 768.8922000234015, + 883.275300002424, + 777.9787000035867, + 668.4632999822497, + 664.382300019497, + 666.9715000025462, + 1200.3708999836817, + 657.7551000227686, + 653.0392999993637, + 653.104600001825, + 986.1139999993611, + 643.6466999875847, + 751.1058000090998, + 653.7194999982603, + 853.7979999964591, + 669.7140999895055, + 685.0183999922592, + 688.2373999978881, + 668.9960000221618, + 645.9895999869332, + 660.4321000049822, + 875.6930999807082, + 679.7527000016998, + 1682.7547999855597, + 672.7007000008598, + 658.540099975653, + 960.9932999883313, + 684.1391999914777, + 973.4601000091061, + 682.5539999990724, + 665.8762999868486, + 663.8505000155419, + 666.1255000217352, + 760.8882999920752, + 674.0024999890011, + 670.7297999819275 + ], + "asset_delete": [ + 583.6189000110608, + 1402.9772999929264, + 1183.97690000711, + 1192.2694999957457, + 634.0008999977726, + 653.3519999939017, + 657.4080000282265, + 965.6760999932885, + 854.9798000021838, + 640.4645000002347, + 1673.468299995875, + 1058.1945999874733, + 852.2064000135288, + 754.0225000120699, + 702.9515999893192, + 661.9701000163332, + 647.0976999844424, + 641.4347999962047, + 760.693899996113, + 740.9128000144847, + 660.5802999984007, + 838.4420000074897, + 1449.3899999943096, + 594.4670999888331, + 758.8717000035103, + 657.8983999788761, + 669.3047000153456, + 960.0529999879654, + 681.3409999886062, + 761.2257000000682, + 679.1308000101708, + 764.4203999952879, + 933.0140000092797, + 671.7576999799348, + 689.9297999916598, + 748.5717999807093, + 862.4958999862429, + 863.016899995273, + 656.5188000095077, + 758.3124000229873, + 950.8356000005733, + 662.8660999995191, + 672.6214000082109, + 926.0127999878023, + 1060.91749999905, + 844.5291999960318, + 965.0659000035375, + 673.3035999932326, + 861.2359999970067, + 684.141500008991, + 857.8732000023592, + 749.0661999909207, + 601.9517999957316, + 659.1554000042379, + 680.514999985462, + 1440.0457000010647, + 1478.990400006296, + 601.36479997891, + 657.1157000144012, + 652.5659999751952, + 852.7877000160515, + 968.0483000120148, + 934.9704000051133, + 645.6410000100732, + 776.3048999768216, + 655.9042999870144, + 953.9465999987442, + 668.922000011662, + 668.870399997104, + 846.3288999919314, + 792.2400000097696, + 660.4197999986354, + 1067.971899989061, + 779.0776999900118, + 661.1944000178482, + 872.031800012337, + 674.5479000092018, + 764.2712999950163, + 793.8464999897406, + 652.3714999784715, + 650.1819999830332, + 641.5377999946941, + 660.0828999944497, + 664.3229000037536, + 1071.2069000001065, + 677.0848000014666, + 661.6081999964081, + 673.7644000095315, + 663.2869000022765, + 664.4222000031732, + 682.7515999902971, + 647.3289999994449, + 665.5286999884993, + 662.2632999788038, + 870.1116000011098, + 647.136399988085, + 659.1666000022087, + 684.0764000080526, + 771.3447000132874, + 955.6980000052135 + ], + "import_settings": [ + 539.5012999942992, + 642.2049000102561, + 602.5634999969043, + 837.8584000165574, + 645.6074999878183, + 601.0403000109363, + 609.6813000040129, + 805.7436000090092, + 1130.9814999985974, + 717.0780000160448, + 596.5983000060078, + 1348.8434000173584, + 921.8048000184353, + 1524.3501999939326, + 721.5671000012662, + 604.0475000045262, + 622.6497999741696, + 902.0648000005167, + 800.4871000011917, + 1426.6638999979477, + 605.1475000276696, + 604.3517000216525, + 810.7668999873567, + 830.0755000091158, + 797.4399999948218, + 712.6547000079881, + 598.8048999861348, + 605.5381000041962, + 697.6775999937672, + 617.6616000011563, + 899.306000006618, + 625.3940000024159, + 601.8535000039265, + 986.1192000098526, + 781.3486999948509, + 913.8314000156242, + 601.1500000022352, + 910.6784999894444, + 599.5701999927405, + 1016.0878999740817, + 1321.808799984865, + 808.8316000066698, + 702.7291999838781, + 933.7872999894898, + 926.822200010065, + 711.2291000084952, + 596.9095999898855, + 804.8950000084005, + 797.5539999897592, + 603.7929999874905, + 1128.1242000113707, + 599.6259000094142, + 654.4534000277054, + 607.0543999958318, + 901.4106999966316, + 538.1051999866031, + 554.7541000123601, + 550.4178999981377, + 1121.0382000135724, + 622.958899999503, + 802.7087999798823, + 617.7927999815438, + 617.8222000016831, + 615.1453000202309, + 707.365199981723, + 619.8248000000603, + 931.6653999849223, + 607.0318999991287, + 899.6809000091162, + 1133.4399999759626, + 619.1400000243448, + 612.6960999972653, + 538.7825999932829, + 710.219300002791, + 598.6562000180129, + 611.7411999730393, + 612.150400003884, + 1833.3564999920782, + 700.436199986143, + 710.5760000122245, + 708.0469999928027, + 628.7924000062048, + 595.6483999907505, + 617.7131000149529, + 551.4249000116251, + 888.4507000038866, + 599.0315000235569, + 725.1252999994904, + 802.9137999983504, + 600.7575999828987, + 896.1013999942224, + 620.1459000003524, + 608.6596999957692, + 595.2820999955293, + 1111.666899989359, + 611.9616999931168, + 608.1535999837797, + 595.0680000241846, + 617.8108000021894, + 616.8097000045236 + ], + "material_modify": [ + 564.0371000044979, + 720.7459000055678, + 847.246899997117, + 793.4411999885924, + 823.1932999915443, + 811.5575000119861, + 642.1417999954429, + 846.3225000014063, + 628.1491999980062, + 850.7560999714769, + 978.4029999864288, + 565.9826000046451, + 613.6349999869708, + 639.2120000091381, + 622.5779999804217, + 626.9698000105564, + 641.1250999954063, + 760.6507000164129, + 945.7001000118908, + 625.2158999850508, + 632.627400016645, + 637.8956999978982, + 649.4014000054449, + 983.5191000020131, + 643.6293000006117, + 1155.3158000169788, + 839.4651999988127, + 637.2760999947786, + 1345.3829999780282, + 835.1271999999881, + 1236.6053000150714, + 853.9638000074774, + 659.6366000012495, + 960.8156000031158, + 948.1093999929726, + 936.4100999955554, + 826.7352000111714, + 747.4277000001166, + 765.607600013027, + 637.3149999999441, + 648.0343999864999, + 714.7291000001132, + 1543.369499995606, + 620.6911000190303, + 613.4722999995574, + 747.4692999967374, + 1683.5961999895517, + 632.6914000092074, + 1244.5449999941047, + 629.3975999869872, + 640.1780999731272, + 647.6911000208929, + 562.8273999900557, + 752.6532000047155, + 638.8322999991942, + 562.6346000062767, + 605.1092999987304, + 653.4708999970462, + 623.693400004413, + 740.8272000029683, + 1133.4624999726657, + 622.6633000187576, + 964.408799976809, + 635.5143999971915, + 1331.6494000027888, + 1041.6916999965906, + 713.5507000202779, + 631.9354000152089, + 833.3036999974865, + 630.8302999823354, + 651.9175999856088, + 828.324900008738, + 583.7125000252854, + 633.1540999817662, + 1033.8666000170633, + 737.0990999916103, + 810.7025999925099, + 631.0659000009764, + 940.6980999920052, + 640.574299992295, + 734.3101000005845, + 625.4381999897305, + 859.637899993686, + 646.0555999947246, + 578.3903000119608, + 636.6524999903049, + 838.8433000072837, + 629.0627999987919, + 628.430099983234, + 642.8881000028923, + 741.7438999982551, + 936.6866999771446, + 639.6961999998894, + 637.8895999805536, + 1231.2282999919262, + 636.2948000023607, + 1375.5616999987978, + 751.9529999990482, + 640.0536999863107, + 638.1388999870978 + ], + "time_settings": [ + 537.9902000131551, + 547.1441999834497, + 1035.364200011827, + 529.1296000068542, + 1653.0216000101063, + 1029.38669998548, + 629.4214999943506, + 611.8300999805797, + 623.0830000131391, + 1104.1878999967594, + 587.0566999947187, + 535.2040999860037, + 611.7927999875974, + 776.159800007008, + 540.4469999775756, + 613.0190000112634, + 909.141100011766, + 693.94860000466, + 598.775000020396, + 805.1470000064, + 819.5064000028651, + 901.6801999823656, + 552.9937999963295, + 541.5426999970805, + 608.7955000111833, + 595.7461000070907, + 708.3205000089947, + 624.4697000074666, + 807.4504999967758, + 623.1858999817632, + 619.8043999902438, + 895.7482000114396, + 816.8479000160005, + 814.4049000111409, + 622.6025999931153, + 807.4913000164088, + 926.4014000073075, + 706.58729999559, + 618.6949000111781, + 615.8109999960288, + 592.8815000224859, + 633.5485000163317, + 601.9720000040252, + 647.3458999826107, + 788.966399995843, + 703.0490000033751, + 593.2801999733783, + 918.7930999905802, + 615.5843999877106, + 817.054500017548, + 588.7889000005089, + 613.7414000113495, + 842.3821000033058, + 1197.132800007239, + 612.0716999867, + 544.9658000143245, + 562.0993000047747, + 554.5318000076804, + 613.8904000108596, + 604.6281000017188, + 609.3887999886647, + 614.9381999857724, + 907.3842999932822, + 804.3116999906488, + 606.8085999868345, + 602.5440999947023, + 614.5239000034053, + 621.6423999867402, + 1234.341300005326, + 596.5986999799497, + 836.5603999991436, + 609.2848999833222, + 549.1062999935821, + 812.8815999953076, + 618.4106000000611, + 897.5106000143569, + 727.632199996151, + 610.4779000161216, + 596.8566999945324, + 793.1908000027761, + 716.3173999870196, + 625.8963000145741, + 1007.1587999991607, + 622.7400999923702, + 666.0472999792546, + 830.031899997266, + 712.1272000076715, + 601.2580000096932, + 1038.7255999958143, + 716.7727000196464, + 1305.5580999935046, + 1206.4910000190139, + 600.8473999972921, + 627.7859000256285, + 605.7930999959353, + 610.7516999763902, + 1166.500499995891, + 1328.345600020839, + 598.5129000036977, + 619.0461999794934 + ], + "read_csharp": [ + 543.6951999727171, + 532.6700000150595, + 542.3259999952279, + 1374.4025999912992, + 765.451999992365, + 595.0807000044733, + 771.3784000079613, + 798.0659999884665, + 585.0280000013299, + 588.2870999921579, + 813.1598000181839, + 775.3751999989618, + 902.4732999969274, + 626.4520999975502, + 733.9809999975841, + 800.2451999927871, + 598.6673000152223, + 917.4294000258669, + 613.900399999693, + 712.7600000239909, + 897.7623000100721, + 600.6281999871135, + 525.3937000234146, + 566.7840999958571, + 909.4539000070654, + 706.0148000018671, + 915.6861999945249, + 1198.0629000172485, + 598.6581000033766, + 893.9822999818716, + 601.903200004017, + 902.6541000057478, + 885.4914999974426, + 894.5758000190835, + 686.1560999823269, + 703.0914000060875, + 605.9223999909591, + 603.9326000027359, + 881.2782999884803, + 579.7599999932572, + 807.458700001007, + 1494.6010999847203, + 605.6656000146177, + 566.791799996281, + 736.9370999804232, + 1522.8940999950282, + 801.8354999949224, + 622.1350000123493, + 601.324699993711, + 1302.497399999993, + 825.3796999924816, + 602.2356000030413, + 543.280500016408, + 913.9362999994773, + 796.1871000006795, + 692.3172999813687, + 1094.5469999860507, + 534.7867000091355, + 602.9477999836672, + 898.6417000123765, + 595.0365000171587, + 615.2924000052735, + 701.9098000018857, + 906.8093999812845, + 703.6360000201967, + 711.7892999958713, + 715.6952999939676, + 894.4460999919102, + 592.0772999816108, + 892.4872000061441, + 813.367399998242, + 920.5688999791164, + 554.7418000060134, + 694.9158000061288, + 598.9038999832701, + 910.2826999733225, + 1308.294599992223, + 600.0031000003219, + 620.0935000088066, + 712.2437999933027, + 787.2577999951318, + 586.2796000146773, + 608.798500004923, + 600.5310000036843, + 539.1870000166818, + 604.8817000119016, + 1304.4697000004817, + 610.45620002551, + 608.4480999852531, + 899.3594000057783, + 604.4399000238627, + 591.1018000042532, + 595.503499993356, + 597.5564999971539, + 607.2306999994908, + 705.8813000039663, + 599.4482999958564, + 578.301499976078, + 705.9045999776572, + 586.2899000057951 + ], + "play_until_ready": [ + 1705.9480999887455, + 1911.8404000182636, + 1153.117799985921, + 1125.8492000051774, + 1495.6642999895848, + 1255.016200011596, + 1853.1225000042468, + 1614.0771000063978, + 1435.692500002915, + 1248.2060999900568, + 1850.8969999966212, + 1616.5366000204813, + 1949.176299996907, + 1432.906500005629, + 1759.7871999896597, + 1165.9034000185784, + 2542.974599986337, + 1618.8832999905571, + 1134.7146999905817, + 1319.4474000192713, + 1440.0252999912482, + 1226.7955999996047, + 1111.7640000011306, + 1805.1375999930315, + 1928.5761000064667, + 1210.9993000049144, + 1157.210400007898, + 1525.970699993195, + 2114.39380000229, + 1419.0230999956839, + 2218.272700003581, + 1432.6417999982368, + 1532.3200999991968, + 2057.930800016038, + 1445.3144999861252, + 2034.2477000085637, + 1164.9417000007816, + 1619.321599981049, + 1559.595900005661, + 1441.1436000082176, + 1728.0432999832556, + 1637.529200001154, + 1429.6551999868825, + 1713.280299998587, + 2099.777900002664, + 1465.5587999732234, + 1731.8807000119705, + 1334.4930000021122, + 1410.4109999898355, + 1228.1818999908864, + 2232.3720000276808, + 1427.4619999923743, + 1201.648899994325, + 1241.934499994386, + 1637.2780999809038, + 1088.5283999959938, + 1454.402300005313, + 1917.703100014478, + 1451.5300000202842, + 1532.146899990039, + 1449.0259000158403, + 2096.2653999740724, + 1431.994799990207, + 1326.9444999750704, + 1712.7862999914214, + 1747.9590000002645, + 1614.9956000153907, + 1634.9535000044852, + 1464.6865999966394, + 1320.1826000004075, + 1074.8539000051096, + 1422.6161999977194, + 1120.378299994627, + 1729.8210999870207, + 1458.5957000090275, + 1419.9029000010341, + 1228.871600003913, + 1225.9942000091542, + 2424.7805000049993, + 1142.7996999991592, + 1353.4741000039503, + 1926.178699999582, + 1312.656699999934, + 1300.773199996911, + 1396.1841999844182, + 1128.7404000177048, + 1864.3201000231784, + 1344.1834000113886, + 1146.59760001814, + 1235.4249999916647, + 1235.6674000038765, + 1456.7906000011135, + 1242.5987000169698, + 1522.2018000204116, + 1186.4480999938678, + 1342.8120000171475, + 1243.651900003897, + 1266.12259997637, + 1384.5485000056215, + 1227.4882999772672 + ], + "stop_until_ready": [ + 1916.460400010692, + 1345.062100008363, + 1088.7899000081234, + 1431.450500007486, + 2350.344899983611, + 1853.048499993747, + 1729.745599994203, + 1985.0293999770656, + 1752.099300007103, + 1317.5493000017013, + 1570.0654999818653, + 1485.6774999934714, + 1369.2173000017647, + 2241.719399986323, + 1848.414700012654, + 1242.175599996699, + 1223.325200000545, + 1749.671199999284, + 1441.3326999929268, + 1232.3570000007749, + 1446.5441000065766, + 1342.6743000163697, + 1997.1369999984745, + 1715.008500003023, + 1280.089499981841, + 1758.6893000116106, + 1734.2704999900889, + 1449.08089999808, + 1229.036000004271, + 2158.0108999914955, + 1343.0013000033796, + 1452.060600015102, + 1192.1631000004709, + 1459.395100013353, + 1954.8354000144172, + 1249.6847999864258, + 1471.6062000079546, + 1871.403700002702, + 1945.4194999998435, + 1656.8000999977812, + 1241.5735999820754, + 2351.4475999982096, + 1558.9386000065133, + 1909.195499989437, + 1775.626899994677, + 1551.6711999953259, + 2169.9892999895383, + 1625.150100007886, + 1443.4840000176337, + 1145.086899981834, + 1375.175000022864, + 1534.3547000084072, + 1629.0469999948982, + 1330.1279000006616, + 1635.5754999967758, + 2040.9754999855068, + 1144.8165999900084, + 1139.4290999742225, + 1739.078900020104, + 1434.4270000001416, + 1920.4492999997456, + 1638.0260000005364, + 2063.3429999870714, + 1358.6083000118379, + 1262.1859999781009, + 1248.7869999895338, + 1839.941899990663, + 1167.8303999942727, + 1430.7148999942, + 1243.0275000224356, + 1399.3319000001065, + 1412.8692999947816, + 1955.225400015479, + 1452.240200014785, + 1145.0364000047557, + 1345.0056000147015, + 2238.7201999954414, + 1348.99949998362, + 1238.1664999993518, + 1219.49659998063, + 1540.7543999899644, + 1167.9620000068098, + 1256.4046999905258, + 1133.6532999994233, + 1426.4445999870077, + 1327.1540999994613, + 1139.1213999886531, + 1132.6802000112366, + 1565.9596000041347, + 1162.8092000028118, + 1432.6138999895193, + 1929.122900008224, + 1253.8932999887038, + 1216.0526000079699, + 1177.2490000003017, + 1230.1964000216685, + 1236.9926999963354, + 1847.590699995635, + 1581.2800000130665, + 1344.8530999885406 + ] + } + }, + "details": { + "official_shell_pid": 57316, + "discarded_focus_cycles": 0, + "operations": [ + { + "name": "editor_state", + "unity_cli": { + "tool": "get_editor_state", + "params": {} + }, + "official": { + "tool": "editor_status", + "params": {} + } + }, + { + "name": "hierarchy", + "unity_cli": { + "tool": "get_hierarchy", + "params": {} + }, + "official": { + "tool": "get_scene_hierarchy", + "params": {} + } + }, + { + "name": "find_gameobject", + "unity_cli": { + "tool": "find_gameobject", + "params": { + "name": "Perf394Target", + "exactMatch": true + } + }, + "official": { + "tool": "find_gameobjects", + "params": { + "name": "Perf394Target" + } + } + }, + { + "name": "transform", + "unity_cli": { + "tool": "get_component_values", + "params": { + "gameObjectName": "Perf394Target", + "componentType": "Transform" + } + }, + "official": { + "tool": "get_component_properties", + "params": { + "target": { + "hierarchyPath": "/Perf394Target" + }, + "type": "Transform" + } + } + }, + { + "name": "position", + "unity_cli": { + "tool": "modify_gameobject", + "params": { + "path": "/Perf394Target", + "position": { + "x": 1, + "y": 2, + "z": 3 + } + } + }, + "official": { + "tool": "set_transform", + "params": { + "target": { + "hierarchyPath": "/Perf394Target" + }, + "position": [ + 1, + 2, + 3 + ] + } + } + }, + { + "name": "create_cube", + "unity_cli": { + "tool": "create_gameobject", + "params": { + "name": "Perf394Cube", + "primitiveType": "cube" + } + }, + "official": { + "tool": "create_gameobject", + "params": { + "name": "Perf394Cube", + "primitive": "Cube" + } + } + }, + { + "name": "add_component", + "unity_cli": { + "tool": "add_component", + "params": { + "gameObjectPath": "/Perf394Cube", + "componentType": "Rigidbody" + } + }, + "official": { + "tool": "add_component", + "params": { + "target": { + "hierarchyPath": "/Perf394Cube" + }, + "type": "Rigidbody" + } + } + }, + { + "name": "remove_component", + "unity_cli": { + "tool": "remove_component", + "params": { + "gameObjectPath": "/Perf394Cube", + "componentType": "Rigidbody" + } + }, + "official": { + "tool": "remove_component", + "params": { + "target": { + "hierarchyPath": "/Perf394Cube" + }, + "type": "Rigidbody" + } + } + }, + { + "name": "delete_gameobject", + "unity_cli": { + "tool": "delete_gameobject", + "params": { + "path": "/Perf394Cube" + } + }, + "official": { + "tool": "delete_gameobject", + "params": { + "target": { + "hierarchyPath": "/Perf394Cube" + } + } + } + }, + { + "name": "scene_info", + "unity_cli": { + "tool": "get_scene_info", + "params": {} + }, + "official": { + "tool": "list_open_scenes", + "params": {} + } + }, + { + "name": "scene_save", + "unity_cli": { + "tool": "save_scene", + "params": {} + }, + "official": { + "tool": "save_scene", + "params": {} + } + }, + { + "name": "console", + "unity_cli": { + "tool": "read_console", + "params": { + "count": 20 + } + }, + "official": { + "tool": "console", + "params": { + "tail": 20, + "level": "log" + } + } + }, + { + "name": "screenshot", + "unity_cli": { + "tool": "capture_screenshot", + "params": { + "captureMode": "game", + "width": 1280, + "height": 720, + "includeUI": false, + "encodeAsBase64": false, + "osFallback": false + } + }, + "official": { + "tool": "screenshot", + "params": { + "view": "game", + "width": 1280, + "height": 720 + } + } + }, + { + "name": "material_search", + "unity_cli": { + "tool": "manage_asset_database", + "params": { + "action": "find_assets", + "filter": "t:Material", + "searchInFolders": [ + "Assets/Scenes/Generated/E2E/Performance" + ] + } + }, + "official": { + "tool": "find_assets", + "params": { + "type": "Material", + "search_in": "Assets/Scenes/Generated/E2E/Performance" + } + } + }, + { + "name": "asset_copy", + "unity_cli": { + "tool": "manage_asset_database", + "params": { + "action": "copy_asset", + "fromPath": "Assets/Scenes/Generated/E2E/Performance/PerfSource.mat", + "toPath": "Assets/Scenes/Generated/E2E/Performance/PerfCopy.mat" + } + }, + "official": { + "tool": "copy_asset", + "params": { + "asset": "Assets/Scenes/Generated/E2E/Performance/PerfSource.mat", + "destination": "Assets/Scenes/Generated/E2E/Performance/PerfCopy.mat" + } + } + }, + { + "name": "asset_move", + "unity_cli": { + "tool": "manage_asset_database", + "params": { + "action": "move_asset", + "fromPath": "Assets/Scenes/Generated/E2E/Performance/PerfCopy.mat", + "toPath": "Assets/Scenes/Generated/E2E/Performance/PerfMoved.mat" + } + }, + "official": { + "tool": "move_asset", + "params": { + "asset": "Assets/Scenes/Generated/E2E/Performance/PerfCopy.mat", + "destination": "Assets/Scenes/Generated/E2E/Performance/PerfMoved.mat" + } + } + }, + { + "name": "asset_delete", + "unity_cli": { + "tool": "manage_asset_database", + "params": { + "action": "delete_asset", + "assetPath": "Assets/Scenes/Generated/E2E/Performance/PerfMoved.mat" + } + }, + "official": { + "tool": "delete_asset", + "params": { + "asset": "Assets/Scenes/Generated/E2E/Performance/PerfMoved.mat", + "confirm": true + } + } + }, + { + "name": "import_settings", + "unity_cli": { + "tool": "manage_asset_import_settings", + "params": { + "action": "get", + "assetPath": "Assets/Scenes/Generated/E2E/Performance/PerfSource.mat" + } + }, + "official": { + "tool": "get_import_settings", + "params": { + "asset": "Assets/Scenes/Generated/E2E/Performance/PerfSource.mat" + } + } + }, + { + "name": "material_modify", + "unity_cli": { + "tool": "modify_material", + "params": { + "materialPath": "Assets/Scenes/Generated/E2E/Performance/PerfSource.mat", + "properties": { + "_Color": [ + 0.2, + 0.4, + 0.8, + 1 + ] + } + } + }, + "official": { + "tool": "set_material_properties", + "params": { + "material": "Assets/Scenes/Generated/E2E/Performance/PerfSource.mat", + "properties": { + "_Color": [ + 0.2, + 0.4, + 0.8, + 1 + ] + } + } + } + }, + { + "name": "time_settings", + "unity_cli": { + "tool": "get_project_settings", + "params": { + "includeTime": true, + "includePlayer": false + } + }, + "official": { + "tool": "get_time_settings", + "params": {} + } + }, + { + "name": "read_csharp", + "unity_cli": { + "tool": "read", + "params": { + "path": "Assets/HotReloadProbe.cs", + "maxLines": 50 + } + }, + "official": { + "tool": "read_text_file", + "params": { + "path": "Assets/HotReloadProbe.cs" + } + } + }, + { + "name": "play_until_ready", + "unity_cli": { + "tool": "play_game", + "params": {} + }, + "official": { + "tool": "editor_play", + "params": {} + } + }, + { + "name": "stop_until_ready", + "unity_cli": { + "tool": "stop_game", + "params": {} + }, + "official": { + "tool": "editor_stop", + "params": {} + } + } + ] + }, + "results": { + "unity-cli": { + "editor_state": { + "n": 100, + "p50_ms": 201.96, + "p95_ms": 706.68, + "mean_ms": 259.85, + "min_ms": 36.12, + "max_ms": 1820.37 + }, + "hierarchy": { + "n": 100, + "p50_ms": 103.11, + "p95_ms": 899.01, + "mean_ms": 290.41, + "min_ms": 36.34, + "max_ms": 1398.22 + }, + "find_gameobject": { + "n": 100, + "p50_ms": 106.43, + "p95_ms": 707.95, + "mean_ms": 254.84, + "min_ms": 36.49, + "max_ms": 1507.42 + }, + "transform": { + "n": 100, + "p50_ms": 107.25, + "p95_ms": 701.11, + "mean_ms": 245.0, + "min_ms": 39.15, + "max_ms": 1203.65 + }, + "position": { + "n": 100, + "p50_ms": 103.13, + "p95_ms": 1102.66, + "mean_ms": 263.24, + "min_ms": 35.42, + "max_ms": 1300.12 + }, + "create_cube": { + "n": 100, + "p50_ms": 103.87, + "p95_ms": 902.3, + "mean_ms": 249.64, + "min_ms": 36.3, + "max_ms": 1401.41 + }, + "add_component": { + "n": 100, + "p50_ms": 102.21, + "p95_ms": 702.83, + "mean_ms": 245.54, + "min_ms": 37.19, + "max_ms": 1198.0 + }, + "remove_component": { + "n": 100, + "p50_ms": 102.97, + "p95_ms": 903.02, + "mean_ms": 273.51, + "min_ms": 35.58, + "max_ms": 1198.9 + }, + "delete_gameobject": { + "n": 100, + "p50_ms": 101.15, + "p95_ms": 602.33, + "mean_ms": 218.97, + "min_ms": 36.69, + "max_ms": 906.18 + }, + "scene_info": { + "n": 100, + "p50_ms": 100.75, + "p95_ms": 598.8, + "mean_ms": 202.4, + "min_ms": 35.37, + "max_ms": 1392.77 + }, + "scene_save": { + "n": 100, + "p50_ms": 193.74, + "p95_ms": 506.45, + "mean_ms": 294.34, + "min_ms": 124.36, + "max_ms": 1108.48 + }, + "console": { + "n": 100, + "p50_ms": 219.77, + "p95_ms": 423.74, + "mean_ms": 235.08, + "min_ms": 38.3, + "max_ms": 820.61 + }, + "screenshot": { + "n": 100, + "p50_ms": 206.83, + "p95_ms": 831.21, + "mean_ms": 375.57, + "min_ms": 124.11, + "max_ms": 1699.84 + }, + "material_search": { + "n": 100, + "p50_ms": 200.25, + "p95_ms": 563.19, + "mean_ms": 265.63, + "min_ms": 40.41, + "max_ms": 1602.8 + }, + "asset_copy": { + "n": 100, + "p50_ms": 162.34, + "p95_ms": 959.58, + "mean_ms": 304.38, + "min_ms": 94.28, + "max_ms": 1557.0 + }, + "asset_move": { + "n": 100, + "p50_ms": 263.8, + "p95_ms": 667.39, + "mean_ms": 305.59, + "min_ms": 87.02, + "max_ms": 1251.69 + }, + "asset_delete": { + "n": 100, + "p50_ms": 335.01, + "p95_ms": 662.07, + "mean_ms": 330.62, + "min_ms": 81.57, + "max_ms": 1450.5 + }, + "import_settings": { + "n": 100, + "p50_ms": 118.93, + "p95_ms": 914.9, + "mean_ms": 303.97, + "min_ms": 35.58, + "max_ms": 2713.06 + }, + "material_modify": { + "n": 100, + "p50_ms": 139.28, + "p95_ms": 932.2, + "mean_ms": 305.86, + "min_ms": 58.64, + "max_ms": 1718.34 + }, + "time_settings": { + "n": 100, + "p50_ms": 117.84, + "p95_ms": 914.9, + "mean_ms": 283.46, + "min_ms": 35.78, + "max_ms": 1533.42 + }, + "read_csharp": { + "n": 100, + "p50_ms": 37.44, + "p95_ms": 580.05, + "mean_ms": 208.51, + "min_ms": 31.68, + "max_ms": 1170.52 + }, + "play_until_ready": { + "n": 100, + "p50_ms": 822.01, + "p95_ms": 1466.44, + "mean_ms": 949.0, + "min_ms": 753.2, + "max_ms": 1962.39 + }, + "stop_until_ready": { + "n": 100, + "p50_ms": 737.03, + "p95_ms": 1428.65, + "mean_ms": 820.75, + "min_ms": 564.24, + "max_ms": 2275.12 + } + }, + "official": { + "editor_state": { + "n": 100, + "p50_ms": 705.11, + "p95_ms": 1094.77, + "mean_ms": 751.96, + "min_ms": 532.77, + "max_ms": 1472.75 + }, + "hierarchy": { + "n": 100, + "p50_ms": 691.88, + "p95_ms": 1272.59, + "mean_ms": 774.0, + "min_ms": 550.03, + "max_ms": 1816.48 + }, + "find_gameobject": { + "n": 100, + "p50_ms": 692.45, + "p95_ms": 1292.24, + "mean_ms": 797.85, + "min_ms": 530.96, + "max_ms": 2392.8 + }, + "transform": { + "n": 100, + "p50_ms": 895.84, + "p95_ms": 1391.78, + "mean_ms": 977.21, + "min_ms": 731.35, + "max_ms": 2303.65 + }, + "position": { + "n": 100, + "p50_ms": 694.65, + "p95_ms": 1316.5, + "mean_ms": 785.53, + "min_ms": 531.51, + "max_ms": 1816.6 + }, + "create_cube": { + "n": 100, + "p50_ms": 701.23, + "p95_ms": 1121.95, + "mean_ms": 756.86, + "min_ms": 548.43, + "max_ms": 1482.74 + }, + "add_component": { + "n": 100, + "p50_ms": 890.33, + "p95_ms": 1204.97, + "mean_ms": 944.28, + "min_ms": 722.33, + "max_ms": 2914.33 + }, + "remove_component": { + "n": 100, + "p50_ms": 909.0, + "p95_ms": 1511.48, + "mean_ms": 992.02, + "min_ms": 771.23, + "max_ms": 2204.13 + }, + "delete_gameobject": { + "n": 100, + "p50_ms": 702.73, + "p95_ms": 1195.75, + "mean_ms": 781.43, + "min_ms": 544.71, + "max_ms": 1904.85 + }, + "scene_info": { + "n": 100, + "p50_ms": 686.22, + "p95_ms": 1287.26, + "mean_ms": 776.22, + "min_ms": 579.58, + "max_ms": 2002.07 + }, + "scene_save": { + "n": 100, + "p50_ms": 813.59, + "p95_ms": 1310.85, + "mean_ms": 861.25, + "min_ms": 682.46, + "max_ms": 1701.95 + }, + "console": { + "n": 100, + "p50_ms": 618.18, + "p95_ms": 1146.31, + "mean_ms": 695.6, + "min_ms": 528.35, + "max_ms": 1423.5 + }, + "screenshot": { + "n": 100, + "p50_ms": 734.02, + "p95_ms": 1355.4, + "mean_ms": 819.6, + "min_ms": 594.51, + "max_ms": 1859.23 + }, + "material_search": { + "n": 100, + "p50_ms": 715.92, + "p95_ms": 1396.92, + "mean_ms": 793.89, + "min_ms": 580.72, + "max_ms": 1722.3 + }, + "asset_copy": { + "n": 100, + "p50_ms": 843.09, + "p95_ms": 1356.51, + "mean_ms": 863.13, + "min_ms": 642.61, + "max_ms": 1576.53 + }, + "asset_move": { + "n": 100, + "p50_ms": 682.49, + "p95_ms": 1277.85, + "mean_ms": 809.49, + "min_ms": 643.65, + "max_ms": 2125.85 + }, + "asset_delete": { + "n": 100, + "p50_ms": 684.14, + "p95_ms": 1192.27, + "mean_ms": 795.63, + "min_ms": 583.62, + "max_ms": 1673.47 + }, + "import_settings": { + "n": 100, + "p50_ms": 642.2, + "p95_ms": 1133.44, + "mean_ms": 756.03, + "min_ms": 538.11, + "max_ms": 1833.36 + }, + "material_modify": { + "n": 100, + "p50_ms": 653.47, + "p95_ms": 1244.54, + "mean_ms": 780.64, + "min_ms": 562.63, + "max_ms": 1683.6 + }, + "time_settings": { + "n": 100, + "p50_ms": 623.08, + "p95_ms": 1197.13, + "mean_ms": 733.17, + "min_ms": 529.13, + "max_ms": 1653.02 + }, + "read_csharp": { + "n": 100, + "p50_ms": 694.92, + "p95_ms": 1302.5, + "mean_ms": 746.98, + "min_ms": 525.39, + "max_ms": 1522.89 + }, + "play_until_ready": { + "n": 100, + "p50_ms": 1435.69, + "p95_ms": 2099.78, + "mean_ms": 1507.64, + "min_ms": 1074.85, + "max_ms": 2542.97 + }, + "stop_until_ready": { + "n": 100, + "p50_ms": 1441.33, + "p95_ms": 2158.01, + "mean_ms": 1526.86, + "min_ms": 1088.79, + "max_ms": 2351.45 + } + } + }, + "finished_at": "2026-10-04T01:30:32.840294+00:00" +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/official-windows-resident-frontmost-search-array-failure.json b/docs/verification/issue-386/resume/official-windows-resident-frontmost-search-array-failure.json new file mode 100644 index 00000000..5a8202b3 --- /dev/null +++ b/docs/verification/issue-386/resume/official-windows-resident-frontmost-search-array-failure.json @@ -0,0 +1,47 @@ +{ + "mode": "resident", + "focus": "frontmost", + "started_at": "2026-10-03T23:42:59.193309+00:00", + "conditions": { + "started_at": "2026-10-03T23:33:26.503448+00:00", + "os": "Windows-11-10.0.26300-SP0", + "arch": "AMD64", + "logical_cpus": 32, + "unity": "6000.4.4f1", + "editor_pid": 34324, + "iterations": 100, + "warmup": 3, + "unity_cli_build": "native Windows debug 0.18.1", + "official_cli_version": "1.0.0-beta.11", + "pipeline_version": "0.8.0-exp.1", + "unity_cli_sha256": "087d057cd62483c3c0aa64ceb85a77421349f2ace1ba236a13c1ddcffe909d35", + "official_cli_sha256": "4cad9230dd98cc8d123d3ef9d18fef5e7ee65f353814c3cf9d94d9129293dda3", + "benchmark_sha256": "857569c8c542221f43a27423ecfa8fce3d11a690ed979985ebc670a56912f372", + "windows_adapter_sha256": "1d72ca848808f1fcce45a46b133691c7c6119f908e67e9519f72759a19d5af7b", + "windows_adapter": "Original benchmark operations, validation, focus-discard and alternating order; Windows HWND foreground inspection and bounded reader thread replace macOS focus and POSIX select. No platform spoofing.", + "background_condition": "Owned Editor minimized, because Windows refused activation of the existing GWT background window. This differs from macOS visible-background measurements.", + "host_contention": "Other project canonical verification was active on this host; results are observations, no Windows budget or prior baseline was enforced.", + "coexistence": { + "same_project": true, + "unity_version": "6000.4.4f1", + "official_state": "ready", + "project_identity_sha256": "f87f40b8af586b040ebc3f0d64bf076a0bebf421cd38cb9af459bc31f2a0c69a" + }, + "play_settings": { + "assetNamingUsesSpace": true, + "defaultBehaviorMode": "Mode3D", + "enterPlayModeOptions": "DisableDomainReload", + "enterPlayModeOptionsEnabled": true, + "prefabModeRegularEnvironment": "None", + "prefabModeUIEnvironment": "None", + "serializationMode": "ForceText", + "unityRemote": "", + "unityRemoteCompression": "", + "unityRemoteResolution": "" + }, + "unityd_pid": 52020 + }, + "status": "FAIL", + "error": "Invalid official NDJSON response: {'id': '15', 'exitCode': 6, 'envelope': {'success': False, 'command': 'unity command find_assets', 'data': None, 'errors': [{'code': 'COMMAND_FAILED', 'message': 'Pipeline server returned 400 Bad Request: Parameter Validation Failed. Illegal characters in path.'}], 'warnings': []}}", + "finished_at": "2026-10-03T23:43:15.759312+00:00" +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/official-windows-resident-frontmost.json b/docs/verification/issue-386/resume/official-windows-resident-frontmost.json new file mode 100644 index 00000000..7ea68731 --- /dev/null +++ b/docs/verification/issue-386/resume/official-windows-resident-frontmost.json @@ -0,0 +1,5512 @@ +{ + "mode": "resident", + "focus": "frontmost", + "started_at": "2026-10-04T00:00:36.400701+00:00", + "conditions": { + "started_at": "2026-10-04T00:00:25.043499+00:00", + "os": "Windows-11-10.0.26300-SP0", + "arch": "AMD64", + "logical_cpus": 32, + "unity": "6000.4.4f1", + "editor_pid": 34324, + "iterations": 100, + "warmup": 3, + "unity_cli_build": "native Windows debug 0.18.1", + "official_cli_version": "1.0.0-beta.11", + "pipeline_version": "0.8.0-exp.1", + "unity_cli_sha256": "087d057cd62483c3c0aa64ceb85a77421349f2ace1ba236a13c1ddcffe909d35", + "official_cli_sha256": "4cad9230dd98cc8d123d3ef9d18fef5e7ee65f353814c3cf9d94d9129293dda3", + "benchmark_sha256": "8b4a77c97260fec724a5d1187c1561a7a0f25d9c3734fe8eada1c0a3ca4bc1e6", + "windows_adapter_sha256": "c47d896f41e81c6db8ba63ced94e927388b55cc81796b54578b3135685929c8a", + "windows_adapter": "Original benchmark operations, validation, focus-discard and alternating order; Windows HWND foreground inspection and bounded reader thread replace macOS focus and POSIX select. No platform spoofing.", + "background_condition": "Owned Editor minimized, because Windows refused activation of the existing GWT background window. This differs from macOS visible-background measurements.", + "host_contention": "Other project canonical verification was active on this host; results are observations, no Windows budget or prior baseline was enforced.", + "coexistence": { + "same_project": true, + "unity_version": "6000.4.4f1", + "official_state": "ready", + "project_identity_sha256": "f87f40b8af586b040ebc3f0d64bf076a0bebf421cd38cb9af459bc31f2a0c69a" + }, + "play_settings": { + "assetNamingUsesSpace": true, + "defaultBehaviorMode": "Mode3D", + "enterPlayModeOptions": "DisableDomainReload", + "enterPlayModeOptionsEnabled": true, + "prefabModeRegularEnvironment": "None", + "prefabModeUIEnvironment": "None", + "serializationMode": "ForceText", + "unityRemote": "", + "unityRemoteCompression": "", + "unityRemoteResolution": "" + }, + "unityd_pid": 56288 + }, + "status": "PASS", + "samples_ms": { + "unity-cli": { + "editor_state": [ + 41.870899993227795, + 414.5974999992177, + 303.7406999792438, + 235.111699992558, + 341.67039999738336, + 210.3310000093188, + 645.070799975656, + 34.11390000837855, + 218.5532000148669, + 692.228800005978, + 70.38509999983944, + 344.71669999766164, + 368.15789999673143, + 158.3845000131987, + 42.02750002150424, + 105.06389997317456, + 57.44939998839982, + 33.94009999465197, + 308.98279999382794, + 271.8653999909293, + 401.8985999864526, + 675.3657000081148, + 449.05819999985397, + 259.9427000095602, + 242.54010000731796, + 1160.0046000094153, + 40.070700022624806, + 215.27459999197163, + 42.14430000865832, + 304.3216000078246, + 927.3754000023473, + 237.5389999942854, + 272.49139998457395, + 400.5980000074487, + 287.02619997784495, + 187.9921999934595, + 109.39019999932498, + 37.47539999312721, + 41.19560000253841, + 294.34790002414957, + 94.03060001204722, + 36.27419998520054, + 48.6525000014808, + 414.91059999680147, + 39.11129999323748, + 438.198799995007, + 426.2561000068672, + 357.4425000115298, + 417.64499997952953, + 328.1507999927271, + 64.39240000327118, + 318.1615999783389, + 300.4252999962773, + 262.59830000344664, + 281.6244999994524, + 33.446600020397455, + 41.515399992931634, + 207.6836999913212, + 231.79809999419376, + 104.13249998237006, + 223.44160001375712, + 37.46039999532513, + 250.97640001331456, + 197.05509999766946, + 1246.8755999871064, + 183.09199999202974, + 43.117099994560704, + 863.6865000007674, + 700.7428999932017, + 567.4403000157326, + 39.17110001202673, + 34.72840000176802, + 41.2740999890957, + 99.04639999149367, + 279.27299999282695, + 275.01469998969696, + 37.938699999358505, + 35.63890000805259, + 151.4813999820035, + 331.7735999880824, + 70.57029998395592, + 34.15059999679215, + 141.03450000402518, + 151.70700001181103, + 47.12060000747442, + 37.938800000119954, + 715.67179998965, + 35.772800008999184, + 177.9130999930203, + 606.9908999779727, + 1030.7083999796305, + 38.26949998619966, + 40.10090001975186, + 267.5229999877047, + 309.85960000543855, + 47.50350001268089, + 329.9047999898903, + 669.5058999757748, + 122.39369997405447, + 276.5275999845471 + ], + "hierarchy": [ + 39.515000011306256, + 579.8937999934424, + 348.0917999986559, + 338.707599992631, + 334.68580001499504, + 611.7119999835268, + 828.9419999928214, + 41.0756999917794, + 36.09040001174435, + 34.810899989679456, + 38.076700002420694, + 340.40610000374727, + 39.08269997918978, + 313.22159999399446, + 37.60569999576546, + 40.881299995817244, + 37.27109997998923, + 38.01220000605099, + 328.7737999926321, + 37.51260001445189, + 324.80619999114424, + 585.6596999801695, + 42.59269998874515, + 39.70160000608303, + 307.99699999624863, + 881.6889000008814, + 37.58950001792982, + 315.71870000334457, + 35.913499974412844, + 41.05790000176057, + 559.9666000052821, + 35.83439998328686, + 350.8166999963578, + 588.663100003032, + 35.581400006776676, + 43.16390000167303, + 39.84360001049936, + 310.16409999574535, + 36.51390000595711, + 35.06510000443086, + 35.478299978422, + 317.2931000008248, + 307.7126999851316, + 861.0879000043496, + 326.94769999943674, + 913.335300021572, + 569.9660000100266, + 582.7127999800723, + 1425.056100008078, + 37.17299998970702, + 35.85020001628436, + 35.61910000280477, + 39.40779998083599, + 38.955199997872114, + 40.72779999114573, + 321.12760000745766, + 39.62970001157373, + 326.1190000048373, + 313.9303000061773, + 329.09519999520853, + 35.38399998797104, + 37.16030000941828, + 40.04320001695305, + 42.561200010823086, + 36.02939998381771, + 39.063099975464866, + 40.663299994776025, + 36.32159999688156, + 40.8830999804195, + 40.68059998098761, + 37.867599981836975, + 36.113399983150885, + 35.369499993976206, + 36.160599993309006, + 322.74400000460446, + 41.231000010157004, + 36.2604999972973, + 36.31560000940226, + 39.41810000105761, + 36.7289999849163, + 38.52189998724498, + 37.9428000014741, + 590.1367999904323, + 336.7106000077911, + 38.78850000910461, + 36.53649997431785, + 37.95110000646673, + 35.7357999891974, + 38.6313000053633, + 1172.6027999829967, + 41.9572000100743, + 320.0490999734029, + 37.243800004944205, + 299.68860000371933, + 40.24659999413416, + 68.43450001906604, + 35.49670000211336, + 303.9885000034701, + 36.74519999185577, + 344.7236999927554 + ], + "find_gameobject": [ + 37.886899983277544, + 38.732700020773336, + 328.01759999711066, + 35.49439998460002, + 296.6399000142701, + 1169.4147000089288, + 38.059999991673976, + 35.135000012815, + 35.26330000022426, + 34.967899991897866, + 36.932699993485585, + 1558.0541999952402, + 38.192199979675934, + 573.1814999890048, + 37.125199974980205, + 37.40200001630001, + 38.778899994213134, + 313.1682999955956, + 318.42100000358187, + 313.693299976876, + 319.79259999934584, + 36.35410001152195, + 38.431900000432506, + 328.02410001750104, + 562.6106999989133, + 37.448099988978356, + 37.82950001186691, + 592.3000999900978, + 37.076500011608005, + 314.67270001303405, + 34.34830001788214, + 36.96779999881983, + 598.6518999852706, + 34.80399999534711, + 35.0633000198286, + 36.926899978425354, + 39.63620000286028, + 35.296799993375316, + 35.08999999030493, + 326.15989999612793, + 307.83259999589063, + 34.84430001117289, + 323.4969000041019, + 37.09210001397878, + 305.7662000064738, + 613.9419999963138, + 569.2071000230499, + 546.0933999856934, + 37.66729999915697, + 39.16919999755919, + 37.80739998910576, + 38.65169998607598, + 318.1526999978814, + 320.64650001120754, + 39.026300015393645, + 36.50849999394268, + 35.78389997710474, + 888.605699990876, + 284.346899978118, + 301.657099975273, + 35.8921000151895, + 34.6074000117369, + 39.174400008050725, + 34.673500020289794, + 52.27830001967959, + 35.43749998789281, + 46.054800011916086, + 36.102899990510195, + 36.47369999089278, + 34.82030000304803, + 34.72029999829829, + 37.97810000833124, + 38.13949998584576, + 36.39569997903891, + 862.069299997529, + 37.497000012081116, + 35.79809999791905, + 35.35239998018369, + 37.294100009603426, + 35.817099997075275, + 34.54910000436939, + 35.42699999525212, + 899.4540999992751, + 332.1969000098761, + 37.497300014365464, + 35.66480000154115, + 36.5307999891229, + 35.89589998591691, + 38.432900008047, + 1671.6810000070836, + 38.13189998618327, + 34.28930000518449, + 36.18379999534227, + 307.58849999983795, + 360.7186000153888, + 50.981199980014935, + 312.83320000511594, + 33.79049999057315, + 38.205899996683, + 356.0767000017222 + ], + "transform": [ + 40.07270000874996, + 38.20350000751205, + 321.28480001119897, + 333.7552000011783, + 596.10760002397, + 39.08970000338741, + 39.54310002154671, + 40.051400021184236, + 39.16430001845583, + 36.5610999870114, + 38.97950000828132, + 602.4519999918994, + 42.592599987983704, + 610.609099996509, + 40.81189999124035, + 40.15450002043508, + 358.5597999917809, + 40.71270002168603, + 291.58280001138337, + 39.30669999681413, + 297.27140002069063, + 38.48190000280738, + 40.55609999340959, + 351.6356000036467, + 40.2472999994643, + 36.267399991629645, + 323.1740999908652, + 564.8399000056088, + 320.7506000180729, + 326.3376999821048, + 37.23000001627952, + 42.60769998654723, + 1156.4983999996912, + 40.85180000402033, + 41.082599986111745, + 39.119699998991564, + 40.38379999110475, + 37.72560000652447, + 40.78010001103394, + 353.14049999578856, + 37.562399986200035, + 42.09849998005666, + 329.5211999793537, + 40.44060001615435, + 312.9711999790743, + 39.134600025136024, + 38.56449999148026, + 37.17190001043491, + 46.80219999863766, + 37.98240001196973, + 327.56659999722615, + 41.02020000573248, + 330.81480002147146, + 39.37919999589212, + 42.07419999875128, + 318.09240000438876, + 40.78840001602657, + 37.321100011467934, + 327.77050000731833, + 924.2165999894496, + 42.82019997481257, + 38.57969999080524, + 40.75029998784885, + 38.89029999845661, + 37.88409999106079, + 39.258900011191145, + 41.577700001653284, + 37.10109999519773, + 38.529699988430366, + 39.98610001872294, + 38.18070000852458, + 38.55540000949986, + 38.814400002593175, + 41.974499996285886, + 1094.802500010701, + 310.8240999863483, + 38.24749999330379, + 39.08789998968132, + 40.217500005383044, + 328.9972000056878, + 41.19749998790212, + 324.6355000010226, + 40.054400014923885, + 318.73450000421144, + 341.8481000117026, + 37.32910001417622, + 36.163799988571554, + 36.731300002429634, + 41.24010002124123, + 37.50700000091456, + 38.12569999718107, + 334.98020001570694, + 332.78619998600334, + 316.525999980513, + 325.0590999959968, + 43.767499999376014, + 340.0516999827232, + 42.38710002391599, + 39.26540000247769, + 642.0820000057574 + ], + "position": [ + 36.698399984743446, + 36.309000017354265, + 591.3062999898102, + 38.65329999825917, + 862.5418999872636, + 35.52760000457056, + 36.309099989011884, + 319.13259997963905, + 36.77189999143593, + 37.83290000865236, + 35.67529999418184, + 591.2406999850646, + 42.548099998384714, + 560.9172999975272, + 45.46929997741245, + 39.723900001263246, + 37.03700000187382, + 41.04810001445003, + 556.7994000157341, + 281.1683999898378, + 841.1450000130571, + 38.057400000980124, + 34.07839999999851, + 334.25489999353886, + 36.76000001723878, + 36.888400005409494, + 40.2786000049673, + 40.20970000419766, + 36.683599988464266, + 318.3001999859698, + 36.37220000382513, + 38.605599984293804, + 37.34629999962635, + 36.50499999639578, + 37.375699990661815, + 41.125699994154274, + 39.67180001200177, + 36.064600019017234, + 329.4615999911912, + 327.8373000212014, + 322.866200003773, + 290.6636999978218, + 305.7975999836344, + 34.6533999836538, + 598.9335000049323, + 35.174100019503385, + 36.25639999518171, + 35.09779999149032, + 37.978699983796105, + 37.365299998782575, + 35.697200015420094, + 307.8710999980103, + 596.9620999821927, + 39.61759997764602, + 37.91700000874698, + 874.3407000147272, + 38.44440000830218, + 35.28609999921173, + 313.3281999907922, + 608.5784000169951, + 36.91369999432936, + 302.664899994852, + 38.33969999686815, + 37.741800013463944, + 40.6735000142362, + 347.50809997785836, + 39.208400005009025, + 36.158000002615154, + 37.57529999711551, + 43.41810001642443, + 38.28469998552464, + 34.66479998314753, + 37.111100013135, + 335.485100018559, + 589.1995999845676, + 34.20160000678152, + 36.44860000349581, + 289.9990000005346, + 36.79280000505969, + 37.30550000909716, + 36.92900002351962, + 35.13619999284856, + 35.75260000070557, + 560.4364999744575, + 36.59709999919869, + 35.80250000231899, + 35.566800012020394, + 36.65660001570359, + 35.94669999438338, + 37.80269998242147, + 39.404099981766194, + 1190.9095000009984, + 38.552099984372035, + 326.1410999984946, + 326.8174000259023, + 349.97870001825504, + 327.9954000026919, + 36.704500002088025, + 38.13510001054965, + 332.76190000469796 + ], + "create_cube": [ + 37.55680000176653, + 36.960899975383654, + 572.7349999942817, + 329.96360000106506, + 36.82880001724698, + 37.732800003141165, + 36.69489998719655, + 41.19560000253841, + 295.7668000017293, + 33.80460001062602, + 38.737399998353794, + 1221.477400016738, + 319.6381999878213, + 1179.7187999763992, + 37.59920000447892, + 36.36560001177713, + 320.9721999883186, + 39.67840000404976, + 35.43349998653866, + 313.97370001650415, + 589.344500011066, + 39.12189998663962, + 36.103099992033094, + 898.571500001708, + 34.29650000180118, + 36.71519999625161, + 36.99240001151338, + 41.20490001514554, + 33.47130000474863, + 312.33690000954084, + 34.747500001685694, + 38.41180002200417, + 38.33199999644421, + 38.40810002293438, + 39.71280000405386, + 39.33899998082779, + 40.48650001641363, + 37.81639999942854, + 34.21519999392331, + 627.5565000250936, + 314.0723000105936, + 587.6298999937717, + 301.49410001467913, + 36.84860002249479, + 1136.5763999929186, + 36.906099994666874, + 35.93469999032095, + 36.243899987312034, + 36.40729998005554, + 303.4077000047546, + 310.84210000699386, + 37.26660000393167, + 591.3092000118922, + 305.30710000311956, + 42.918299994198605, + 39.691399986622855, + 302.4227000132669, + 34.19410000788048, + 277.50100000412203, + 41.05100000742823, + 38.62940001999959, + 46.86040000524372, + 39.0594000054989, + 37.66800000448711, + 323.27389999409206, + 42.09200001787394, + 40.514099993743, + 36.826199997449294, + 39.371599996229634, + 36.322299973107874, + 36.88729999703355, + 363.29189999378286, + 315.27349998941645, + 39.9875000002794, + 38.535700005013496, + 327.62900000670925, + 37.72490000119433, + 40.37380000227131, + 36.84169999905862, + 37.89790000882931, + 36.37159999925643, + 40.17220000969246, + 42.54160000709817, + 1432.581700006267, + 37.72600000957027, + 37.488500005565584, + 36.75010000006296, + 37.82840000349097, + 324.6229000214953, + 39.38679999555461, + 41.883999976562336, + 282.5903000193648, + 40.07640000781976, + 891.9233000196982, + 954.3236000172328, + 51.038899982813746, + 334.9289000034332, + 38.811399979749694, + 378.0935000104364, + 328.55919998837635 + ], + "add_component": [ + 48.40959998546168, + 54.748900001868606, + 53.48130001220852, + 583.9697000046726, + 50.828500010538846, + 53.33049999899231, + 55.46279999543913, + 58.80970001453534, + 51.19790000026114, + 50.45270000118762, + 297.9291999945417, + 55.10409999988042, + 52.49669999466278, + 878.837999975076, + 64.72239998402074, + 53.84559999220073, + 324.0691999963019, + 53.65310001070611, + 49.15700000128709, + 48.11329999938607, + 50.69329999969341, + 58.78260001190938, + 48.9755000162404, + 332.53030001651496, + 47.619499993743375, + 49.330800015013665, + 49.94389999774285, + 56.03700000210665, + 47.529199975542724, + 304.35079999733716, + 48.85160000412725, + 49.68100000405684, + 53.3661000081338, + 47.92949999682605, + 49.46069998550229, + 327.107299992349, + 320.3395000018645, + 50.348599994322285, + 49.77290000533685, + 49.979900009930134, + 561.9261999963783, + 1121.364699996775, + 325.0537000130862, + 50.34529999829829, + 908.1306000007316, + 49.79099999764003, + 46.917200001189485, + 48.561599978711456, + 50.184099993202835, + 51.85200000414625, + 51.23120002099313, + 329.23719999962486, + 52.76309998589568, + 309.9942000117153, + 51.79679999127984, + 58.56380000477657, + 50.55059998994693, + 47.764599992660806, + 902.2018999967258, + 55.96299999160692, + 49.311299982946366, + 42.28329999023117, + 49.641799996607006, + 49.22450002050027, + 50.72299999301322, + 53.224500006763265, + 49.914499977603555, + 48.20660001132637, + 48.79939998500049, + 53.79850001190789, + 49.638900003628805, + 56.10390001675114, + 49.47719999472611, + 321.18179998360574, + 53.72329999227077, + 51.01919997832738, + 49.09280000720173, + 47.47690001386218, + 48.872999992454425, + 304.2511999956332, + 51.54600000241771, + 49.255099991569296, + 48.52119999122806, + 64.2029000155162, + 48.221000004559755, + 53.19419997977093, + 57.97210001037456, + 50.20840000361204, + 51.90459999721497, + 52.82939999597147, + 49.113100016256794, + 280.97449999768287, + 296.9343999866396, + 1177.7949999959674, + 66.80159998359159, + 66.71039998764172, + 897.8495999763254, + 51.62070001824759, + 55.852599994977936, + 587.4634000065271 + ], + "remove_component": [ + 42.20249998616055, + 48.00410001189448, + 41.56189999775961, + 594.6005999867339, + 45.80829999758862, + 54.23420001170598, + 332.427799992729, + 328.6140999989584, + 299.43280000588857, + 41.99639998842031, + 39.855799986980855, + 53.06239999481477, + 52.457100013270974, + 43.894899979932234, + 43.67179999826476, + 45.15630000969395, + 581.2745000002906, + 69.718799990369, + 44.25400000764057, + 304.5951999956742, + 39.77499998291023, + 42.49839999829419, + 44.06769998604432, + 48.924700007773936, + 41.41659999731928, + 41.13259998848662, + 311.21250000433065, + 48.01890000817366, + 48.991299991030246, + 564.6597000013571, + 40.37559998687357, + 45.9848000027705, + 45.97399997874163, + 44.011599995428696, + 43.78040001029149, + 41.88499998417683, + 46.9149999844376, + 43.30250000930391, + 301.6069000004791, + 52.0128000061959, + 592.2122999909334, + 38.4071999869775, + 276.583800005028, + 41.548000008333474, + 51.24280002200976, + 46.29019999993034, + 42.37559999455698, + 47.14740000781603, + 44.82280000229366, + 43.23640000075102, + 307.6615000027232, + 38.507500023115426, + 46.822500007692724, + 612.6014000037685, + 329.3765000125859, + 44.26719999173656, + 44.68549997545779, + 46.2822999979835, + 62.844600004609674, + 42.14109998429194, + 313.60890000360087, + 38.780300004873425, + 51.82779999449849, + 45.85470000165515, + 45.01600001822226, + 44.50990000623278, + 319.60909999907017, + 43.025099992519245, + 39.90999999223277, + 42.41670001647435, + 48.167800006922334, + 50.37910002283752, + 43.82710001664236, + 334.5837999950163, + 43.616100010694936, + 304.68909998307936, + 45.475499995518476, + 42.474100016988814, + 327.3157000076026, + 36.98500001337379, + 302.5869999837596, + 291.5237999986857, + 44.186599989188835, + 53.411200002301484, + 331.0324999911245, + 324.80869998107664, + 46.814900008030236, + 41.24349998892285, + 44.04790000990033, + 49.22149999765679, + 44.90340000484139, + 40.626500005600974, + 38.17600000184029, + 837.4936000036541, + 51.0824000230059, + 354.588899994269, + 1192.2685999888927, + 50.7406999822706, + 47.51199999009259, + 927.8035000024829 + ], + "delete_gameobject": [ + 36.50479999487288, + 36.6554000065662, + 38.93660000176169, + 38.32429999602027, + 39.64060000726022, + 39.57340001943521, + 36.21359998942353, + 40.94889998668805, + 317.453800002113, + 39.4903999986127, + 41.639900009613484, + 38.13239998999052, + 305.000199994538, + 39.94899999815971, + 42.87939998903312, + 282.17030002269894, + 42.80250001465902, + 40.7532999815885, + 43.650200008414686, + 303.8521000125911, + 38.504700001794845, + 324.22939999378286, + 40.43870000168681, + 51.37449997710064, + 40.64039999502711, + 40.869300020858645, + 34.554499987279996, + 39.799700025469065, + 301.1813999910373, + 578.1389999901876, + 328.87769999797456, + 314.87299999571405, + 41.46399997989647, + 38.70430000824854, + 39.47010001866147, + 42.99149999860674, + 40.934699994977564, + 39.9221999978181, + 44.5385999919381, + 39.04020000481978, + 37.865999998757616, + 37.90680001839064, + 320.9068000141997, + 38.895800011232495, + 42.09850000916049, + 40.94109998550266, + 38.01600000588223, + 48.24259999440983, + 41.33720000390895, + 317.75289998040535, + 323.2253000023775, + 37.541500001680106, + 37.37020000698976, + 811.2898000108544, + 41.804200009210035, + 37.59160000481643, + 38.34130000905134, + 38.71710001840256, + 41.469399991910905, + 37.36630000639707, + 37.02619997784495, + 302.01519999536686, + 37.69100000499748, + 40.43480000109412, + 39.488300011726096, + 328.3804999955464, + 48.32799997529946, + 293.9386999933049, + 39.12649999256246, + 36.48479998810217, + 297.51850001048297, + 314.9167000083253, + 37.74639999028295, + 316.2674000195693, + 46.245900011854246, + 332.2623999847565, + 310.4221999819856, + 318.5158000269439, + 35.82810002262704, + 338.74579999246635, + 38.855799997691065, + 35.19900000537746, + 39.780399994924664, + 40.961300022900105, + 38.28490001615137, + 39.070800004992634, + 309.9800999916624, + 37.61340002529323, + 325.93169997562654, + 39.55180000048131, + 40.96620000200346, + 37.46339998906478, + 38.338900019880384, + 39.22850001254119, + 43.79000002518296, + 43.13700000056997, + 43.31639999873005, + 327.59420000365935, + 43.4123000013642, + 602.2783000080381 + ], + "scene_info": [ + 36.20919998502359, + 36.498700006632134, + 37.67669998342171, + 35.08999999030493, + 37.23590000299737, + 36.33690002607182, + 35.06120000383817, + 35.212699993280694, + 319.9536000029184, + 315.3634000045713, + 40.777500020340085, + 34.64240001630969, + 37.61659999145195, + 38.799600006313995, + 349.9365999887232, + 36.60009999293834, + 35.31589999329299, + 38.242599985096604, + 39.43900001468137, + 548.8862999773119, + 34.84169999137521, + 38.033599994378164, + 38.51110002142377, + 48.223899997537956, + 35.1743999926839, + 35.987500014016405, + 326.41200002399273, + 40.08320000139065, + 320.81360000302084, + 36.526599986245856, + 37.04329999163747, + 37.461800005985424, + 36.054299998795614, + 35.82850002567284, + 35.830300010275096, + 38.258900021901354, + 38.41090001515113, + 36.3567000022158, + 581.3395000004675, + 41.174400015734136, + 35.142799984896556, + 36.95380000863224, + 278.5141000058502, + 297.4546999903396, + 40.22969998186454, + 38.108999986434355, + 36.1581000033766, + 36.44259998691268, + 312.212399992859, + 38.017300015781075, + 315.6681000255048, + 296.4270999946166, + 37.6168999937363, + 36.7545000044629, + 37.78390001389198, + 35.2024000021629, + 297.36070000217296, + 37.93179997592233, + 38.553399994270876, + 35.31750000547618, + 37.47260000091046, + 34.46980001172051, + 334.25610000267625, + 44.283099996391684, + 324.62969998596236, + 37.80920000281185, + 37.178800004767254, + 36.97069999179803, + 38.431900000432506, + 35.75899999123067, + 40.607100003398955, + 35.83670000080019, + 36.28610001760535, + 302.2911000007298, + 38.38240000186488, + 887.1838999912143, + 35.99709999980405, + 39.65029999380931, + 35.15389998210594, + 331.95699998759665, + 35.46820001793094, + 36.99960000813007, + 34.313400014070794, + 37.57499999483116, + 36.79129999363795, + 35.52760000457056, + 38.37819999898784, + 35.73649999452755, + 36.25659999670461, + 34.341299993684515, + 36.19679997791536, + 45.903899997938424, + 330.5199999886099, + 36.938600009307265, + 45.884599996497855, + 48.22629998670891, + 38.61089999554679, + 41.276600008131936, + 377.5235000066459, + 37.646799988579005 + ], + "scene_save": [ + 125.06640001083724, + 130.85549999959767, + 128.68180000805296, + 127.56619998253882, + 131.44530000863597, + 131.36389999999665, + 126.45939999492839, + 402.2368000005372, + 971.4472999912687, + 126.63729998166673, + 128.47460000193678, + 132.93409999459982, + 423.5200000111945, + 129.31030002073385, + 127.1032000076957, + 127.94229999417439, + 124.97949998942204, + 420.23009998956695, + 125.03620001371019, + 659.6465999900829, + 126.15070000174455, + 128.99260001722723, + 125.79259998165071, + 187.0037000044249, + 129.70900000073016, + 144.32650001253933, + 127.83710000803694, + 130.6285000173375, + 698.2169999973848, + 124.53120001009665, + 134.98770000296645, + 126.51249999180436, + 395.33729999675415, + 123.66410001413897, + 127.59379998897202, + 131.9233999820426, + 148.45839998451993, + 398.23240000987425, + 698.8112999824807, + 129.57089999690652, + 135.42819998110645, + 127.69049999769777, + 373.2714999932796, + 127.24520001211204, + 145.2172999852337, + 132.03019998036325, + 126.45020001218654, + 125.04100002115592, + 133.2639000029303, + 125.7016999879852, + 689.2747999809217, + 124.64630001340993, + 124.93940000422299, + 132.66730000032112, + 131.63550000172108, + 125.50079997163266, + 126.47109999670647, + 125.1271000073757, + 130.1779999921564, + 130.05629999679513, + 128.8263000024017, + 127.20149999950081, + 131.91709999227896, + 406.1738000018522, + 128.96130001172423, + 424.4294000091031, + 134.94380001793616, + 126.59960001474246, + 122.29289999231696, + 131.6633000096772, + 136.8922000110615, + 125.42710002162494, + 129.73519999650307, + 397.8184000006877, + 411.48470001644455, + 647.3336000053678, + 138.77059999504127, + 129.62819999665953, + 123.9140999969095, + 137.79239999712445, + 419.1190999990795, + 398.4173000208102, + 402.53190000657924, + 132.60209999862127, + 405.9214000008069, + 139.03099999879487, + 130.5374999938067, + 127.19169998308644, + 407.57599999778904, + 135.21869998658076, + 455.6270999892149, + 154.24550001625903, + 126.52260001050308, + 130.1042000122834, + 131.46870001219213, + 458.0558000016026, + 135.32820000546053, + 132.59290001587942, + 139.08699998864904, + 135.7354000210762 + ], + "console": [ + 38.78540001460351, + 233.99009997956455, + 38.63249998539686, + 41.4984000090044, + 39.419300010195, + 37.541600002441555, + 297.1436000079848, + 265.2055000071414, + 40.12499999953434, + 314.5348999823909, + 223.09290000703186, + 43.03450000588782, + 263.800100015942, + 272.5170999765396, + 40.2194999915082, + 39.427599986083806, + 41.53809999115765, + 41.389399993931875, + 231.58160000457428, + 191.74829998519272, + 311.1736999999266, + 41.85040001175366, + 273.6942000046838, + 47.62130000744946, + 39.60439999355003, + 271.3530999899376, + 226.4611999853514, + 241.7360999970697, + 194.52740001725033, + 42.24020001129247, + 40.59119999874383, + 40.15469999285415, + 39.07599998638034, + 237.62410000199452, + 278.1097000115551, + 303.04649999015965, + 217.19149997807108, + 40.296099992701784, + 37.876499991398305, + 40.41950000100769, + 36.51740000350401, + 40.018899977440014, + 36.755000008270144, + 38.90370001317933, + 40.739100018981844, + 342.5221999932546, + 295.77600001357496, + 239.04119999497198, + 37.65479999128729, + 232.54490000545047, + 796.6768000042066, + 218.9238999853842, + 260.2949000138324, + 37.72910000407137, + 306.8435000022873, + 39.817200013203546, + 269.92590000736527, + 218.00100000109524, + 309.0948000026401, + 39.328299986664206, + 297.5815999961924, + 213.13789999112487, + 39.14070001337677, + 40.09340002085082, + 44.3000000086613, + 297.1733000013046, + 229.3599999975413, + 41.14109999500215, + 39.38420000486076, + 227.11949999211356, + 39.39630000968464, + 261.8769000109751, + 235.69649999262765, + 790.8317999972496, + 41.225099994335324, + 40.78170002321713, + 39.267599990125746, + 239.90230000345036, + 284.8995999956969, + 49.55130000598729, + 41.691699996590614, + 238.5884000104852, + 38.88489998644218, + 236.53250001370907, + 289.08030001912266, + 40.755399997578934, + 38.62399997888133, + 211.71860001049936, + 281.72560001257807, + 301.2888999946881, + 37.39680000580847, + 52.29510000208393, + 254.70569997560233, + 37.39539999514818, + 264.6361999795772, + 323.92029999755323, + 319.23429999733344, + 342.80389998457395, + 309.1372999770101, + 42.44089999701828 + ], + "screenshot": [ + 375.46629999997094, + 90.45340001466684, + 372.7182000002358, + 95.22680001100525, + 378.77660000231117, + 352.15019999304786, + 96.06860001804307, + 380.53579998086207, + 97.13539999211207, + 95.45629998319782, + 96.89850002177991, + 96.5215000032913, + 366.2430999975186, + 98.11809999519028, + 91.75540000433102, + 96.0561000101734, + 94.6125999907963, + 94.86159999505617, + 91.1437000031583, + 93.02509998087771, + 95.36480001406744, + 94.07950000604615, + 103.41099998913705, + 102.25540000828914, + 371.35899998247623, + 91.36429999489337, + 366.13580002449453, + 98.30290000536479, + 90.81239998340607, + 92.5606999953743, + 388.31529999151826, + 364.8652999836486, + 94.76330000325106, + 91.68539999518543, + 94.04610001365654, + 97.01879997737706, + 95.91189998900518, + 95.52209998946637, + 93.59000000404194, + 97.67810002085753, + 93.73779999441467, + 92.56740001728758, + 95.05910001462325, + 97.40699999383651, + 93.0027999856975, + 93.76150000025518, + 92.51429999130778, + 99.28609998314641, + 93.06489999289624, + 97.59109999868087, + 648.0173000018112, + 362.40250000264496, + 92.9898000031244, + 95.94379999907687, + 97.22440000041388, + 381.62590001593344, + 355.0443999993149, + 93.69660000083968, + 95.47429997473955, + 96.30929998820648, + 93.1198000034783, + 91.96759999031201, + 94.88000001874752, + 92.07890002289787, + 340.28720000060275, + 695.9296000131872, + 100.39260002668016, + 382.15930000296794, + 380.5008000053931, + 91.31859999615699, + 108.73149998951703, + 93.99380002287216, + 90.94600001117215, + 629.7910000139382, + 390.34660000470467, + 92.45360002387315, + 377.2997999913059, + 378.99040000047535, + 95.66789999371395, + 98.38300000410527, + 92.02129999175668, + 595.8465999865439, + 92.83559999312274, + 91.61689999746159, + 411.6284000047017, + 99.39849999500439, + 96.58690000651404, + 91.56760000041686, + 404.13229999830946, + 101.5283000015188, + 101.90459998557344, + 93.80069997860119, + 362.8043000062462, + 352.06319999997504, + 98.84059999603778, + 84.05660002608784, + 95.6047999789007, + 94.67200000653975, + 96.03859999333508, + 100.50430000410415 + ], + "material_search": [ + 40.57549999561161, + 39.938900008564815, + 39.91019999375567, + 39.17340000043623, + 45.33130000345409, + 38.534399995114654, + 301.34049998014234, + 262.437500001397, + 39.91929997573607, + 279.17900000466034, + 44.47760002221912, + 288.14540000166744, + 244.40120000508614, + 44.558599998708814, + 40.24589998880401, + 40.8315000240691, + 39.297499984968454, + 257.0881000137888, + 41.8727999785915, + 37.23750001518056, + 39.44630001205951, + 263.06470000417903, + 41.4357999979984, + 395.3738999844063, + 41.41850001178682, + 44.1012000082992, + 534.867900016252, + 42.905000009341165, + 38.12709997873753, + 42.444299993803725, + 41.696000000229105, + 313.5447000095155, + 38.5977000114508, + 40.00339997583069, + 42.919900006381795, + 40.01789999892935, + 319.9274999788031, + 295.25009999633767, + 39.10349999205209, + 277.3862999747507, + 39.01030000997707, + 320.60370000544935, + 39.40589999547228, + 313.678800011985, + 304.8416000092402, + 39.52000002027489, + 43.157000007340685, + 40.29239999363199, + 288.30879999441095, + 290.55040000821464, + 42.07709999172948, + 800.2530999947339, + 42.26580000249669, + 274.9031000130344, + 315.3471000259742, + 38.94279999076389, + 586.8780999735463, + 40.847099997336045, + 43.32309999153949, + 275.90409998083487, + 300.2118999720551, + 279.0986000036355, + 40.987899992614985, + 41.690000012749806, + 42.64510000939481, + 845.3479000017978, + 292.63779998291284, + 43.8752000045497, + 42.37529999227263, + 38.882399996509776, + 41.492999996989965, + 284.9500000011176, + 39.49370002374053, + 40.93920000013895, + 60.20039998111315, + 38.967100001173094, + 40.65999999875203, + 548.9902999834158, + 309.67600000440143, + 40.61360002378933, + 339.41880002385005, + 805.4647000099067, + 316.86669998453, + 40.712299989536405, + 329.1789999930188, + 362.403400009498, + 309.2912999854889, + 48.945000016829, + 860.0042999896687, + 39.97179999714717, + 39.48889998719096, + 40.27480000513606, + 284.06780000659637, + 54.676300002029166, + 72.32559999101795, + 327.0884999947157, + 43.825200002174824, + 42.64530001091771, + 347.83519999473356, + 43.35139997419901 + ], + "asset_copy": [ + 94.01229998911731, + 100.44969999580644, + 105.03229999449104, + 97.42850001202896, + 101.67199998977594, + 97.43949997937307, + 93.95080001559108, + 367.20469998545013, + 96.18479997152463, + 350.1633999985643, + 116.73089998657815, + 109.78969998541288, + 930.5650000169408, + 381.93350000074133, + 97.16520001529716, + 367.9247999971267, + 95.4251000075601, + 105.33160000341013, + 100.81259999424219, + 96.02909997920506, + 94.93570000631735, + 103.25819998979568, + 98.35660000680946, + 111.72889999579638, + 98.21219998411834, + 95.73900001123548, + 622.9656999930739, + 97.43980001076125, + 95.71090000099503, + 93.84340001270175, + 96.11620000214316, + 106.09880002448335, + 97.44189999764785, + 98.41530001722276, + 103.4745000069961, + 103.6374999966938, + 99.19520001858473, + 93.13689998816699, + 95.39299999596551, + 111.60750000271946, + 100.89569998672232, + 97.06979998736642, + 93.72970002004877, + 97.56610001204535, + 104.19059998821467, + 99.4840000057593, + 101.42099999939092, + 99.40879998612218, + 99.85640001832508, + 99.05059999437071, + 102.78240000479855, + 97.81589999329299, + 99.1910999873653, + 100.33120002481155, + 391.4777000027243, + 115.39719998836517, + 362.590500008082, + 106.45350001868792, + 96.93940001307055, + 96.88209998421371, + 374.0640999749303, + 366.7383000138216, + 374.63239999487996, + 378.23740000021644, + 383.80740000866354, + 108.55189998983406, + 98.33210002398118, + 337.9633000004105, + 97.38980000838637, + 105.17260001506656, + 376.01100001484156, + 391.4461999956984, + 372.89440000313334, + 98.45520000089891, + 400.1026999903843, + 96.53509999043308, + 360.0262000109069, + 624.8748000070918, + 408.95429998636246, + 100.4432000045199, + 98.27799999038689, + 361.41710000811145, + 97.50859998166561, + 99.09930001595058, + 655.8224000036716, + 103.84880000492558, + 97.72980000707321, + 106.61070002242923, + 650.6231000239495, + 97.4856999819167, + 376.5012999938335, + 100.28499999316409, + 368.79889998817816, + 94.77250001509674, + 111.4938999817241, + 394.0631999867037, + 106.26790000242181, + 95.41799998260103, + 101.99230001308024, + 99.82949998811819 + ], + "asset_move": [ + 89.2036999866832, + 92.32240001438186, + 93.62450000480749, + 88.4422000090126, + 87.29149997816421, + 89.68360000289977, + 299.61440002080053, + 295.66060000797734, + 324.9044000112917, + 600.4698000033386, + 366.45560001488775, + 90.68900000420399, + 1113.7559000053443, + 94.09870000672527, + 394.78080000844784, + 91.73109999392182, + 88.26429999317043, + 590.6715999881271, + 89.35629998450167, + 88.49219998228364, + 89.86549999099225, + 379.3571999995038, + 372.65460001071915, + 108.0997999815736, + 372.21069997758605, + 346.47839999524876, + 114.31319999974221, + 331.4417999936268, + 90.42729999055155, + 344.9278000043705, + 338.3036000013817, + 313.621500012232, + 315.7477999920957, + 371.66969999088906, + 356.38189999735914, + 380.06930000847206, + 304.1769999836106, + 343.13490000204183, + 86.25789999496192, + 85.703899996588, + 111.6735000105109, + 90.12460001395084, + 310.5824000085704, + 89.7918000118807, + 92.58320002118126, + 87.6212999864947, + 90.94950000871904, + 335.4622999904677, + 380.4451999894809, + 343.8638999941759, + 87.80829998431727, + 86.21000000857748, + 372.77159999939613, + 96.60039999289438, + 332.1614000014961, + 91.2959000270348, + 556.3496999966446, + 89.7668999969028, + 88.3021000190638, + 89.0427999838721, + 591.918899997836, + 866.6172999946866, + 87.67599999555387, + 87.30250000371598, + 327.49160000821576, + 90.44170001288876, + 334.2337000067346, + 370.21090000052936, + 90.72589999414049, + 369.13360000471584, + 89.31229999870993, + 593.5245000000577, + 353.03379999822937, + 88.87080001295544, + 347.24760000244714, + 357.842699973844, + 89.80019998853095, + 90.28069998021238, + 907.0800999761559, + 91.36120000039227, + 342.75650000199676, + 85.9780999890063, + 362.6384999952279, + 351.9981999997981, + 90.1515000150539, + 425.2429000043776, + 89.04409999377094, + 87.07470001536421, + 97.88119999575429, + 87.48930000001565, + 93.77189999213442, + 289.69429997960106, + 311.2287000112701, + 87.82469999277964, + 374.2281000013463, + 639.8443999933079, + 402.8686000092421, + 89.51339998748153, + 398.51900000940077, + 320.76930001494475 + ], + "asset_delete": [ + 84.24679999006912, + 384.07749999896623, + 340.0588000076823, + 371.94010001257993, + 331.48299998720177, + 82.96299999346957, + 328.0289999966044, + 1146.7624999932013, + 83.42660000198521, + 1138.8433999964036, + 351.9310000119731, + 85.11029998771846, + 575.2232999948319, + 352.2131000063382, + 83.97039998089895, + 84.50990001438186, + 84.33040001546033, + 575.3312000015285, + 282.4409999884665, + 83.64739999524318, + 327.43160001700744, + 81.82220000890084, + 86.01369999814779, + 445.6525999994483, + 81.89550001407042, + 85.52910000435077, + 85.10180001030676, + 84.02379998005927, + 82.67219999106601, + 94.2485999839846, + 81.42450000741519, + 313.0382999952417, + 82.20409997738898, + 84.43879999686033, + 82.04920002026483, + 81.11050000297837, + 341.01689999806695, + 594.0162999904715, + 295.21899999235757, + 82.13580001029186, + 333.28849999816157, + 83.99330000975169, + 85.46350002870895, + 82.53020001575351, + 95.83629999542609, + 86.4401999861002, + 336.69969998300076, + 86.68790000956506, + 82.4688000138849, + 359.9467000167351, + 83.79939998849295, + 82.83109997864813, + 84.81239998945966, + 377.2785000037402, + 591.9770000036806, + 84.04740001424216, + 1140.207400021609, + 326.8015999929048, + 319.8395000072196, + 88.53099998668768, + 891.7608000047039, + 290.4735000047367, + 82.8689000045415, + 85.88400000007823, + 333.40389997465536, + 91.95719999843277, + 86.35489997686818, + 346.79029998369515, + 79.67949999147095, + 88.67430000100285, + 82.94480000040494, + 580.5130999942776, + 343.86789999553, + 373.28230001730844, + 350.78719997545704, + 81.57749997917563, + 347.3674999841023, + 82.38799998071045, + 923.2098999782465, + 376.1653999972623, + 362.7451999927871, + 97.82589998212643, + 351.94930000579916, + 89.08619999419898, + 87.62890001526102, + 82.0743000076618, + 289.7133999795187, + 84.65440000873059, + 86.09509997768328, + 299.42910000681877, + 84.59519999451004, + 82.07669999683276, + 549.2752999998629, + 325.88160000159405, + 411.2279999826569, + 625.8572000078857, + 83.46650001476519, + 85.1771000016015, + 384.7492999921087, + 86.5825000219047 + ], + "import_settings": [ + 306.47930002305657, + 327.69450001069345, + 36.16629997850396, + 35.76559998327866, + 39.632200001506135, + 255.28149999445304, + 274.23489998909645, + 54.226200008997694, + 35.6900000188034, + 270.06840001558885, + 601.1574000003748, + 275.1015000103507, + 44.921600027009845, + 38.47930001211353, + 38.541799993254244, + 310.89210000936873, + 276.3845999725163, + 1073.0720999999903, + 37.48749999795109, + 259.3973999901209, + 40.17190000740811, + 293.96490001818165, + 36.865900008706376, + 41.59740000613965, + 39.550799992866814, + 305.57579998276196, + 36.148899991530925, + 318.3605000085663, + 310.09939999785274, + 38.52019997430034, + 278.32739998120815, + 835.7946999894921, + 36.39610001118854, + 39.09120001480915, + 295.1484000077471, + 292.7704000030644, + 281.83500000159256, + 555.6537999946158, + 37.451100011821836, + 304.3090999999549, + 36.61829998600297, + 37.26949999690987, + 38.76029999810271, + 37.66040000482462, + 38.46079998766072, + 339.90689998609014, + 35.79749999335036, + 315.7131999905687, + 283.16700001596473, + 284.78739998536184, + 37.205200002063066, + 37.774299999000505, + 35.14799999538809, + 38.67629999876954, + 530.1795999985188, + 314.96590000460856, + 513.0836999742314, + 36.49750002659857, + 39.61489998619072, + 36.8192000023555, + 548.1975000002421, + 35.80470001907088, + 325.1450000097975, + 248.28129998059012, + 578.6435999907553, + 286.57890000613406, + 261.0018000123091, + 610.2238000021316, + 37.27319999597967, + 274.17450002394617, + 324.51450001099147, + 37.14790000231005, + 295.2753000135999, + 43.964299984509125, + 556.3800999952946, + 36.83289999025874, + 314.38149997848086, + 37.78670000610873, + 37.208399997325614, + 35.972800018498674, + 575.0077000120655, + 38.208499987376854, + 561.8407000147272, + 335.0792000128422, + 37.49080002307892, + 277.89060000213794, + 36.985899991123006, + 352.7083999942988, + 38.48650000873022, + 37.16450001229532, + 38.214500003959984, + 38.979000004474074, + 270.70210000965744, + 39.580099983140826, + 42.404200008604676, + 288.27299998374656, + 325.42670000111684, + 344.0357999934349, + 590.2645000023767, + 37.99429998616688 + ], + "material_modify": [ + 62.346499995328486, + 61.68389998492785, + 63.790999993216246, + 62.85989997559227, + 62.44660000083968, + 63.005999982124195, + 314.5780000195373, + 66.49369999649934, + 62.74419999681413, + 58.79420001292601, + 336.6542000148911, + 61.96529997396283, + 85.59699999750592, + 63.05749999592081, + 61.71459998586215, + 72.39590000244789, + 60.92910000006668, + 63.87780001387, + 75.08949999464676, + 65.6244000128936, + 61.23039999511093, + 62.92659998871386, + 62.27460000081919, + 69.08089999342337, + 333.39780001551844, + 60.57440000586212, + 315.9532999852672, + 76.64529999601655, + 61.014800012344494, + 61.3084000069648, + 340.53069999208674, + 64.66649999492802, + 315.8490000059828, + 61.428099987097085, + 59.758300019893795, + 73.50650001899339, + 331.0211999923922, + 61.06470001395792, + 61.16769998334348, + 60.48919999739155, + 60.981999995419756, + 78.02929999888875, + 59.5988999994006, + 322.35729999956675, + 384.3487999984063, + 60.44949998613447, + 58.569899993017316, + 59.64389999280684, + 338.7702999752946, + 608.6052000173368, + 327.3478999908548, + 61.20920000830665, + 62.103500007651746, + 59.45229998906143, + 620.1980000187177, + 59.77680001524277, + 63.0951999919489, + 62.98350001452491, + 57.31110001215711, + 64.9078999995254, + 61.31869999808259, + 60.251500020967796, + 65.78909998643212, + 59.06109997886233, + 942.1556999732275, + 60.96370000159368, + 62.83739997888915, + 639.9489999748766, + 345.1463999808766, + 347.77130000293255, + 72.19579999218695, + 68.6643999943044, + 1164.0103999816347, + 62.3327000066638, + 603.9804999891203, + 61.58919999143109, + 62.337600014870986, + 66.42759998794645, + 65.25689997943118, + 69.9787000194192, + 590.6538999988697, + 63.646099995821714, + 62.27580000995658, + 58.92960002529435, + 61.81499999365769, + 67.86970002576709, + 342.0560999948066, + 61.6654000186827, + 351.73339999164455, + 61.53679999988526, + 337.3014999961015, + 59.964400017634034, + 647.0305000257213, + 65.66680001560599, + 399.03110000886954, + 613.1648999871686, + 61.137599986977875, + 60.245900007430464, + 1244.1977999988012, + 65.478999982588 + ], + "time_settings": [ + 38.28159999102354, + 324.86570000764914, + 318.82769998628646, + 38.886899972567335, + 36.10529997968115, + 38.765300007071346, + 540.1905999751762, + 39.22589999274351, + 39.81399998883717, + 35.820000019157305, + 931.5254999964964, + 37.35920001054183, + 50.455299991881475, + 293.80590000073425, + 307.8379000071436, + 36.59860001062043, + 36.33520001312718, + 40.29499998432584, + 37.14039997430518, + 37.93630001018755, + 35.928299999795854, + 312.2544000216294, + 39.067500008968636, + 342.8289000003133, + 33.86629998567514, + 39.71610000007786, + 38.42660001828335, + 36.993400019127876, + 37.427700008265674, + 37.094100000103936, + 295.65839999122545, + 39.68330001225695, + 34.20130000449717, + 318.5829999856651, + 41.91560001345351, + 290.53660001954995, + 298.71859998092987, + 39.09809998003766, + 35.35950000514276, + 36.93919998477213, + 47.59089997969568, + 300.94079999253154, + 299.94120000628754, + 36.90050001023337, + 36.79519999423064, + 36.349000001791865, + 314.65089999255724, + 37.35389999928884, + 851.1580000049435, + 37.72759999264963, + 39.107799995690584, + 35.36730000632815, + 280.7413999980781, + 38.05959998862818, + 40.4432000068482, + 35.72300000814721, + 42.22140001365915, + 36.239400011254475, + 281.67699999175966, + 36.67370000039227, + 36.19740001158789, + 35.96429998287931, + 308.7707000086084, + 333.2769999979064, + 581.1278999899514, + 36.997799994423985, + 339.5684999995865, + 600.7520999992266, + 42.966000008163974, + 306.0217000020202, + 36.19440001784824, + 42.111100017791614, + 40.64500000094995, + 37.34089998761192, + 38.65220001898706, + 35.88989999843761, + 858.4068000200205, + 36.42119999858551, + 39.8200000054203, + 346.09359997557476, + 35.078999993856996, + 36.46030000527389, + 41.52659999090247, + 55.252900026971474, + 39.67709999415092, + 315.478999982588, + 333.39370001340285, + 34.70230000675656, + 36.70080000301823, + 37.231800000881776, + 35.42950001428835, + 34.679200005484745, + 529.8215000075288, + 40.749199979472905, + 345.3540000191424, + 1148.6052999971434, + 35.122100001899526, + 36.502999981166795, + 37.732900003902614, + 51.39430001145229 + ], + "read_csharp": [ + 33.510400011437014, + 298.32870000973344, + 32.07789998850785, + 31.48830001009628, + 31.950000004144385, + 36.10719999414869, + 1120.630200020969, + 30.382900004042313, + 307.5654999993276, + 32.295100012561306, + 645.4327999963425, + 31.795999995665625, + 34.809700009645894, + 34.56400000141002, + 36.01659997366369, + 34.03070001513697, + 33.413900004234165, + 33.09740000986494, + 32.47930001816712, + 34.22060000593774, + 33.82770001189783, + 33.053799998015165, + 37.49319998314604, + 35.55739999865182, + 33.4529000101611, + 34.22170001431368, + 33.7534999998752, + 316.62209998467006, + 32.661100005498156, + 31.775099982041866, + 871.957499999553, + 38.9347999880556, + 32.533999998122454, + 30.351299996254966, + 293.07970000081696, + 585.2115000016056, + 299.6356000076048, + 37.13169999537058, + 35.87719998904504, + 32.441800023661926, + 30.5950999900233, + 31.52399999089539, + 33.16150000318885, + 31.99060002225451, + 33.49179998622276, + 31.674700003350154, + 30.779099994106218, + 316.74029998248443, + 306.01909998222254, + 32.2796999826096, + 32.31799998320639, + 32.902600010856986, + 31.13320001284592, + 289.45819998625666, + 36.53169999597594, + 35.90680001070723, + 30.60389999882318, + 31.031099992105737, + 40.873599995393306, + 32.64749998925254, + 37.05889999400824, + 33.32439999212511, + 31.705700006568804, + 304.0739000134636, + 32.852300006197765, + 32.97339999699034, + 328.65049998508766, + 288.8896999938879, + 80.33680001972243, + 309.3640000151936, + 318.98730000830255, + 306.3192999979947, + 66.82590002310462, + 33.20309999980964, + 34.9114999989979, + 32.40009999717586, + 592.4911000183783, + 33.433199976570904, + 35.908799996832386, + 35.4415999900084, + 32.49769998365082, + 33.34649998578243, + 29.569199978141114, + 327.99260001047514, + 30.64839998842217, + 32.96820001560263, + 596.2721999967471, + 35.231700021540746, + 33.24590000556782, + 33.72289999970235, + 31.957699975464493, + 30.42460000142455, + 31.464200001209974, + 305.69710000418127, + 614.8668999958318, + 599.3605999974534, + 32.49260000302456, + 31.09900001436472, + 32.09609998157248, + 34.22050000517629 + ], + "play_until_ready": [ + 776.1259000108112, + 1056.1597000050824, + 798.2197999954224, + 768.9478000102099, + 790.1528000074904, + 778.5156999889296, + 770.869700005278, + 783.2177000236697, + 768.8572999904864, + 765.8959999971557, + 1078.4048000059556, + 1058.1110999919474, + 1060.9829000022728, + 786.5181000088342, + 781.2352000037208, + 778.9756999991369, + 786.3647000049241, + 778.7737000035122, + 1043.9920999924652, + 1050.632600003155, + 1017.8690000029746, + 1035.7866999984253, + 1078.111999988323, + 798.6061999981757, + 763.5284000134561, + 1055.9554000210483, + 799.8087999876589, + 772.5963999982923, + 768.5589999891818, + 768.3637000154704, + 1627.604200009955, + 772.8662000154145, + 1047.2135999880265, + 778.3001000061631, + 1036.0304999921937, + 1650.4163999925368, + 1312.1219000022393, + 771.2619999947492, + 792.229699989548, + 769.1625999868847, + 766.7821999930311, + 780.2572000073269, + 762.1469000005163, + 784.6652000152972, + 781.3241000112612, + 770.2653000014834, + 776.3721999945119, + 798.3030999894254, + 807.1965999843087, + 786.1398999812081, + 770.1664000051096, + 772.0153999980539, + 772.8325000207406, + 771.1963999900036, + 796.5591999818571, + 785.379799985094, + 789.3266000028234, + 775.3191000083461, + 1036.6214999812655, + 1095.3041999891866, + 780.4219000099692, + 765.8930999750737, + 1078.9205000037327, + 1515.7237999956124, + 786.1293000169098, + 796.8871000048239, + 879.7678999835625, + 1646.6183999727946, + 1052.8291999944486, + 1341.2113999947906, + 771.8804999894928, + 772.4179999786429, + 770.994199992856, + 784.6160999906715, + 795.8273000258487, + 768.986799987033, + 775.0047000008635, + 1060.5851000000257, + 790.0372000003699, + 784.3509999802336, + 781.1594000086188, + 1029.6912000048906, + 785.3311999933794, + 1058.9227000018582, + 779.4146999949589, + 778.9217999961693, + 1403.3910999714863, + 788.1508999853395, + 789.3767000059597, + 783.3173999970313, + 782.5945999938995, + 771.8787999765482, + 784.4427000090946, + 772.9196000145748, + 2425.4110000038054, + 820.1107000058983, + 1045.9907999902498, + 772.6112000236753, + 797.1764999965671, + 777.4846999964211 + ], + "stop_until_ready": [ + 666.0737000056542, + 881.3310999830719, + 619.6244999882765, + 576.1473999882583, + 657.8888999938499, + 705.6300000112969, + 570.6181999994442, + 599.3947999959346, + 788.6318999808282, + 657.4725000245962, + 920.0701000227127, + 625.2200999879278, + 771.2505999952555, + 591.7769000225235, + 883.2258000038564, + 570.6454000028316, + 582.3070000042208, + 850.4972000082489, + 724.7526999854017, + 1207.176800002344, + 624.2176000087056, + 1395.457400009036, + 811.9503000052646, + 825.2270999946631, + 1555.0643999886233, + 683.7703000055626, + 649.9949999852106, + 578.0854999902658, + 742.1820999879856, + 728.033499995945, + 982.0122000237461, + 576.5786999836564, + 575.7588999986183, + 660.5035999964457, + 1037.8680999856442, + 870.3122999868356, + 575.653300009435, + 588.8772000034805, + 832.1194000018295, + 790.7101000018883, + 700.3718000196386, + 583.9492999948561, + 868.3906999940518, + 568.3272999885958, + 893.3086000033654, + 803.1402000051457, + 571.4417000126559, + 855.6565000035334, + 620.7436000113375, + 835.9147000010125, + 572.2964000015054, + 776.2062000110745, + 592.1367999981157, + 689.242499996908, + 613.7567999830935, + 572.7493999875151, + 774.9099999782629, + 665.6693000113592, + 848.47479997552, + 589.8377999837976, + 819.2133000120521, + 591.8059999821708, + 1034.0367000026163, + 590.8826000231784, + 874.627099983627, + 731.281599990325, + 1488.533700001426, + 581.6255999961868, + 924.2403999960516, + 1160.0200000102632, + 1206.5791000204626, + 883.4061000088695, + 797.0650999923237, + 837.5149999919813, + 660.7805999810807, + 596.1411999887787, + 634.5429999928456, + 576.5906999877188, + 584.2359000234865, + 602.2082999988925, + 570.7630999968387, + 574.3063999980222, + 730.255100002978, + 758.7235999817494, + 586.9180999870878, + 1164.4037000078242, + 1347.627899987856, + 597.5784999900497, + 672.1106999902986, + 619.2284999997355, + 583.4699000115506, + 725.5108999961521, + 848.5106999869458, + 706.8412000080571, + 1878.9602000033483, + 629.4358000159264, + 647.0384999993257, + 660.3433999989647, + 582.4753000051714, + 598.5055000055581 + ] + }, + "official": { + "editor_state": [ + 849.948699993547, + 794.7263999958523, + 721.1353000020608, + 807.639399979962, + 764.2949000000954, + 789.20639998978, + 731.6922000027262, + 771.4471000072081, + 554.8866000026464, + 556.8094000045676, + 889.1331999911927, + 653.353400004562, + 590.825399995083, + 947.0201999938581, + 595.1984999992419, + 618.9355999813415, + 542.6065000065137, + 541.7978000186849, + 1004.8364000103902, + 1118.5356999922078, + 1172.31989998254, + 529.2124999978114, + 1570.941000012681, + 550.1691999961622, + 545.8092000044417, + 729.3399999907706, + 580.3908999951091, + 889.9442999972962, + 987.8942999930587, + 758.7005999812391, + 816.1590000090655, + 834.7418000048492, + 538.1852999853436, + 1171.826100006001, + 964.9606999882963, + 794.4766000146046, + 732.3604999983218, + 717.3097000049893, + 590.6844999990426, + 752.1385000145528, + 740.1917999959551, + 718.4760999807622, + 790.3661000018474, + 638.6378000024706, + 672.7382999961264, + 765.7809999946039, + 712.2359999921173, + 560.7547999825329, + 898.4380000038072, + 542.8519000124652, + 879.3056999857072, + 840.0116999982856, + 750.5997999978717, + 1097.3953999928199, + 1443.035600008443, + 546.2743999960367, + 772.6282000076026, + 739.143899991177, + 767.1429000038188, + 851.6374000173528, + 752.985200000694, + 544.5360000012442, + 549.1862999915611, + 542.7027000114322, + 818.4225999866612, + 748.5956000164151, + 620.473100017989, + 640.2986000175588, + 620.7020999863744, + 564.3539000011515, + 647.819999983767, + 839.2021000036038, + 532.4072000221349, + 543.834699987201, + 744.1572000097949, + 775.3219000005629, + 917.1645000169519, + 539.1839999938384, + 545.0101000024006, + 684.3510000035167, + 777.5822000112385, + 573.1465999851935, + 549.108699982753, + 552.8073000023142, + 875.4773999971803, + 782.3419000196736, + 772.0921000000089, + 555.7076999975834, + 611.2726000137627, + 766.9380999868736, + 538.1285000185017, + 1048.1641000078525, + 651.8521000107285, + 1275.5186000140384, + 671.4848999981768, + 561.0493999847677, + 689.7042999917176, + 735.6801999849267, + 967.5021000148263, + 809.2223999847192 + ], + "hierarchy": [ + 1050.577300018631, + 774.3120000232011, + 670.5628999916371, + 629.0565999806859, + 1446.6705000086222, + 691.2689000018872, + 1210.8156000031158, + 541.39669999131, + 825.9652999986429, + 540.0687000073958, + 689.8191999935079, + 1151.760100008687, + 777.8413000050932, + 903.5683999827597, + 558.7993999943137, + 570.6432999868412, + 537.562200013781, + 781.6473999992013, + 1719.7590999712702, + 544.4539000163786, + 550.6487999809906, + 649.8270999873057, + 830.8065999881364, + 820.9757000149693, + 552.9750999994576, + 657.8470999957062, + 532.6216000248678, + 878.9043000142556, + 959.876200009603, + 879.8218999872915, + 880.7548000186216, + 796.3569999847095, + 670.6521000014618, + 558.7997999973595, + 1401.618600008078, + 962.0593000145163, + 849.1322000045329, + 691.4848999876995, + 563.7561000185087, + 694.4235999835655, + 577.9051000135951, + 973.443099996075, + 932.0885999768507, + 880.1071000052616, + 530.9845999872778, + 1178.2122000004165, + 719.8497999925166, + 572.1488000126556, + 655.3904000029434, + 538.1317000137642, + 816.9160000106785, + 665.5550999857951, + 860.3135999874212, + 1457.1122000052128, + 538.1278000131715, + 803.054299991345, + 598.6880999989808, + 650.9327000239864, + 636.28430000972, + 747.3622999968939, + 589.6817999891937, + 803.2654999988154, + 820.4296999901999, + 533.4577000176068, + 741.5757000271697, + 1774.2298000084702, + 758.1227000046056, + 550.4140999983065, + 770.7208999781869, + 658.5433000000194, + 920.2310999971814, + 1200.4941999912262, + 547.4112000083551, + 729.7178999870084, + 922.794599988265, + 801.2321999995038, + 1182.2907999739982, + 785.4397000046447, + 535.7652999809943, + 1231.3772999914363, + 1889.918500004569, + 541.2645999749657, + 542.2621999750845, + 610.2616999996826, + 603.6946999956854, + 737.3192999802995, + 767.3020999936853, + 741.7973999981768, + 554.2436999967322, + 918.7160999863409, + 804.8973999975715, + 754.9286000139546, + 594.1497999883723, + 1212.5889000017196, + 914.1316000022925, + 547.2647999995388, + 770.7564000156708, + 1508.7793999991845, + 595.807200006675, + 587.7431999833789 + ], + "find_gameobject": [ + 548.2817000010982, + 652.7319999877363, + 1173.586399992928, + 577.926900004968, + 543.710199999623, + 867.138800007524, + 533.6146000190638, + 655.3099000011571, + 681.6019999969285, + 653.6705999751575, + 813.2053000153974, + 592.1954999794252, + 688.4460000146646, + 792.5889999896754, + 550.0054000003729, + 574.1027999902144, + 711.1975000007078, + 679.3973000021651, + 812.546500004828, + 546.1354999861214, + 807.8851999889594, + 646.6883000102825, + 543.6592999903951, + 620.8278999838512, + 549.9703999958001, + 986.5406999888364, + 724.8016000085045, + 810.8417999756057, + 903.3949000004213, + 717.8416999813635, + 553.1073000165634, + 684.6015999908559, + 860.7097000058275, + 548.018499976024, + 535.9684999857564, + 722.839699999895, + 852.1881999913603, + 535.249600012321, + 594.6003000135534, + 888.4410999889951, + 806.7270000174176, + 1131.0366000107024, + 672.62159998063, + 765.3817000100389, + 827.8303999977652, + 527.7859000198077, + 896.1700999934692, + 735.4297999991104, + 583.0340000102296, + 750.4428999964148, + 743.2011000055354, + 845.2860999968834, + 600.294700008817, + 849.8816000064835, + 544.1937000141479, + 739.3261999823153, + 1693.841300002532, + 883.2825999998022, + 726.3759000052232, + 664.0230999910273, + 715.4805999889504, + 1207.1046000055503, + 668.5710999881849, + 715.6294000160415, + 1213.3863000199199, + 1154.7445000032894, + 909.0498999867123, + 558.6951000150293, + 580.3919000027236, + 712.4029999831691, + 855.5250999925192, + 744.7759000060614, + 778.1285000091884, + 903.8270000019111, + 592.5379999971483, + 1233.0708999943454, + 561.9752999919001, + 740.315200004261, + 746.3914999971166, + 623.6395000014454, + 688.355699996464, + 653.273400006583, + 2252.906099980464, + 546.7514999909326, + 670.9589999809396, + 543.9421999908518, + 929.9401000025682, + 889.6293000143487, + 545.4156000050716, + 551.0210000211373, + 668.9587000000756, + 1371.7578999930993, + 1016.1123999860138, + 553.9600999909453, + 1209.852400003001, + 817.2953999892343, + 600.5147999967448, + 537.8698999993503, + 533.039900008589, + 532.4661999766249 + ], + "transform": [ + 730.5274000100326, + 898.2036999950651, + 896.978599979775, + 1387.4762000050396, + 731.6066999919713, + 981.4435000007506, + 1007.9749000142328, + 1652.0594999892637, + 758.5052000067662, + 848.9786999998614, + 929.9848999944516, + 965.9302999789361, + 732.46040000231, + 959.7341000044253, + 867.9211999988183, + 714.5453999983147, + 818.6389000038616, + 1079.0264000243042, + 759.130999998888, + 720.1967999862973, + 941.3644000014756, + 728.2459999842104, + 795.0445000024047, + 1014.4340999831911, + 915.9777000022586, + 981.9052000239026, + 897.2906999988481, + 849.2612999980338, + 750.52540001343, + 912.6316999900155, + 727.8533999924548, + 1079.8998999816831, + 1001.1753000144381, + 975.3482000087388, + 739.3031999818049, + 732.7476000064053, + 948.9162000245415, + 729.1472000069916, + 844.231299997773, + 1030.8571999776177, + 1100.5408000200987, + 728.2859999977518, + 850.1393999904394, + 800.5615000147372, + 837.6054000109434, + 977.9641999921296, + 1065.8370000019204, + 986.8398999969941, + 731.7522000230383, + 1059.24679999589, + 1100.9648999897763, + 1071.0248000104912, + 758.3728000172414, + 729.2228000005707, + 993.8953000237234, + 1348.2189999776892, + 726.6720999905374, + 918.4232999978121, + 1654.1146999807097, + 731.3914000114892, + 809.020499989856, + 1048.3564999885857, + 807.6356999808922, + 740.4841000097804, + 785.2803000132553, + 762.9478000162635, + 776.9250999845099, + 1121.3954999984708, + 987.3474999913014, + 725.9557999786921, + 1595.385599997826, + 765.7408000086434, + 898.6134000006132, + 1631.0022000106983, + 730.2000999916345, + 2171.7729999800213, + 737.7636000164784, + 1078.8674000068568, + 1669.2462000064552, + 844.2192999937106, + 842.8114999842364, + 1084.5861000125296, + 1098.529899987625, + 743.0281999986619, + 736.5016000112519, + 1004.0891999960877, + 738.015600014478, + 1074.5838999864645, + 728.2688999839593, + 851.6024999844376, + 1454.359299998032, + 740.2005999756511, + 786.8492999987211, + 745.9671999968123, + 824.3786000239197, + 921.6832000238355, + 980.9920999978203, + 727.0487000059802, + 912.8143999841996, + 734.4890999956988 + ], + "position": [ + 553.8321000058204, + 541.8114000058267, + 543.8771999906749, + 569.5726999838371, + 553.722500015283, + 761.3651000137907, + 732.2218999906909, + 543.8537000154611, + 712.156599998707, + 972.532499989029, + 983.4454999945592, + 999.1095000004862, + 683.1297999888193, + 1008.8996000122279, + 728.7803000072017, + 545.9808000014164, + 542.9753999924287, + 543.0889000126626, + 677.0583000034094, + 547.7843999979086, + 1097.08999999566, + 557.7789999952074, + 584.225400001742, + 539.2658000055235, + 845.3871999809053, + 532.5964000076056, + 698.355000000447, + 550.5230000126176, + 566.0937000066042, + 820.382600009907, + 542.3465000058059, + 905.5274999991525, + 555.5929999973159, + 547.3880999779794, + 551.7446000012569, + 790.1676000037696, + 551.1086999904364, + 537.6518000266515, + 994.0100999956485, + 838.549799984321, + 763.6333999980707, + 536.8517999886535, + 804.3903000070713, + 540.0684000051115, + 1006.0193999961484, + 1664.5390000194311, + 546.1155000084545, + 758.4337999869604, + 1069.8750000155997, + 1261.4952999865636, + 969.7345999884419, + 580.6069999816827, + 778.0590000038501, + 574.9929999874439, + 692.4685999983922, + 533.5101000091527, + 668.6524999968242, + 541.1051999835763, + 557.8016999934334, + 566.2636000197381, + 638.4928000043146, + 529.3765000242274, + 557.1368999953847, + 583.2732999988366, + 548.3800999936648, + 754.1758000152186, + 558.3524999965448, + 542.8019999817479, + 1635.4250999866053, + 530.6052999803796, + 762.9773000080604, + 756.3701999897603, + 531.3518999901135, + 716.3427000050433, + 548.289800004568, + 548.860999988392, + 592.8109000087716, + 552.039700007299, + 594.3461999995634, + 544.274999992922, + 638.1250999984331, + 563.3384000102524, + 554.2477999988478, + 1671.0510999837425, + 571.2178999965545, + 538.0099999892991, + 536.2642999971285, + 552.4587999971118, + 652.8640999749769, + 708.8651999947615, + 558.3214000216685, + 577.2689000004902, + 560.5427999980748, + 699.9878000060562, + 545.9588000085205, + 1012.5043999869376, + 550.3656000073534, + 794.5586999994703, + 836.4551000122447, + 554.2740999953821 + ], + "create_cube": [ + 681.0668999969494, + 601.0893000056967, + 601.7714000190608, + 753.4476000000723, + 794.1862999869045, + 936.9287000154145, + 1018.9156999986153, + 557.8867999720387, + 734.3666999950074, + 630.888200015761, + 543.4626000060234, + 703.7849000189453, + 551.5889000089373, + 773.358400008874, + 546.1606000026222, + 651.5273999830242, + 544.3187000055332, + 681.1073000135366, + 996.3935999840032, + 835.1295000175014, + 576.4675000100397, + 725.1987000054214, + 960.5340999842156, + 617.5921999965794, + 591.351199982455, + 823.9518000045791, + 759.4766999827698, + 1005.8344999852125, + 703.7893999950029, + 783.8973000179976, + 554.4100999832153, + 589.0213999955449, + 541.3594999990892, + 630.9869999822695, + 546.5272000001278, + 677.7236000052653, + 725.3183999855537, + 1186.841499991715, + 638.904299994465, + 796.7161999840755, + 543.5931000101846, + 551.9047999987379, + 837.8241999889724, + 749.1981000057422, + 547.8530999971554, + 746.8496000219602, + 551.3801999913994, + 551.6574000066612, + 1187.272800016217, + 747.936200001277, + 631.0000999947079, + 601.3492999773007, + 550.1149999909103, + 628.1058999884408, + 792.1689999930095, + 632.8863000089768, + 538.0428000062238, + 723.6695000028703, + 752.8470999968704, + 549.2283000203315, + 561.109399975976, + 562.9052000003867, + 601.8700000131503, + 1207.3787999979686, + 826.4029000129085, + 537.5789999961853, + 608.6316999862902, + 557.4082999955863, + 1954.5146999880672, + 542.5495999807026, + 760.0823999964632, + 666.2243999890052, + 554.6189000015147, + 549.5111999916844, + 661.2826000200585, + 544.6150999923702, + 558.2075999991503, + 556.207000016002, + 639.285999990534, + 548.5751999949571, + 721.9686000025831, + 535.3238999960013, + 545.4092000145465, + 1425.8201999764424, + 644.2083999863826, + 740.8135999867227, + 541.1284000147134, + 536.419299984118, + 694.4511999899987, + 792.1312999969814, + 588.2136000145692, + 542.7102000103332, + 545.2308999956585, + 1291.1631999886595, + 553.3246000122745, + 849.9721999978647, + 540.8865000063088, + 817.7759999816772, + 738.5932999895886, + 585.083099984331 + ], + "add_component": [ + 1260.3723999927752, + 723.0771000031382, + 748.2688000018243, + 751.3178000226617, + 798.5438999894541, + 916.9285999960266, + 1365.3038000047673, + 732.756099983817, + 1101.601499976823, + 1004.030900017824, + 738.467999995919, + 732.6598000072408, + 839.3926999997348, + 773.2746000110637, + 746.1437000019941, + 822.1446000097785, + 1053.6983000056352, + 805.1277000049595, + 966.416199982632, + 839.0493000042625, + 830.4176999954507, + 1762.6479000027757, + 1128.867999999784, + 724.6608000132255, + 1019.4475000025705, + 840.5877999903169, + 1309.9003999959677, + 1104.0639999846462, + 1055.522699985886, + 1095.8774000173435, + 885.0864999985788, + 950.823399994988, + 828.820499998983, + 751.7124000005424, + 1019.0232000022661, + 1659.532699995907, + 829.0937999845482, + 737.3309999820776, + 729.6123999985866, + 2513.514499994926, + 746.1209000030067, + 745.9913000056986, + 841.1269999924116, + 1398.6396999971475, + 976.6423999972176, + 777.4602999852505, + 722.1500000159722, + 1017.8637999924831, + 843.1556999858003, + 846.5224000101443, + 787.8870000131428, + 718.7844999716617, + 927.3713000002317, + 969.0272999869194, + 1353.0125000106636, + 714.7151000099257, + 959.1687000065576, + 1101.1651000007987, + 908.3833000040613, + 728.9501000195742, + 726.5274999954272, + 1011.8940999964252, + 732.5496000121348, + 736.5185999951791, + 720.2114000101574, + 1107.7187999908347, + 1017.7138000144623, + 968.8145999971312, + 739.1600999981165, + 978.4678999858443, + 734.1593999881297, + 1071.5758000151254, + 724.2628999811132, + 725.2435999980662, + 844.3273000011686, + 772.3910000058822, + 728.4650999936275, + 726.993999996921, + 944.1957999952137, + 964.7248999972362, + 769.7851000120863, + 737.0839999930467, + 908.5825000074692, + 797.2386999754235, + 885.216800001217, + 814.8270999954548, + 736.4564999879804, + 742.4863000051118, + 1101.9363999948837, + 976.9635999982711, + 957.102299988037, + 739.4071000162512, + 743.0098000040743, + 754.6621000219602, + 989.0137999900617, + 760.0863999978174, + 935.2779999899212, + 795.1821000024211, + 1131.3010999874678, + 734.8965000128374 + ], + "remove_component": [ + 745.0596999842674, + 846.1352000012994, + 993.4893999889027, + 854.5456000138074, + 2001.5022000006866, + 742.5385000242386, + 730.2834000147413, + 732.9284999868833, + 751.8114999984391, + 1266.3334000098985, + 874.1077000158839, + 770.3729000058956, + 914.5353999920189, + 853.6040000035428, + 865.4749999986961, + 904.6219000010751, + 786.8934000143781, + 996.6948000073899, + 725.4525999887846, + 739.8374000040349, + 844.9051000061445, + 738.3574999985285, + 746.7538999917451, + 1826.6246999846771, + 800.7314999995288, + 720.1635999954306, + 829.1904000216164, + 722.2236999950837, + 757.5490000017453, + 1971.3040000060573, + 2349.9595999892335, + 1008.1209999916609, + 1186.5370000014082, + 727.1265999879688, + 1475.9115999913774, + 741.0726000089198, + 769.5009000017308, + 741.8233000207692, + 726.2134000193328, + 733.0623999878298, + 871.2999999988824, + 916.0768000001553, + 734.9565000040457, + 1016.738800011808, + 921.9389000209048, + 916.1123000085354, + 751.2398000108078, + 784.2378999921493, + 968.5460999899078, + 766.5543000039179, + 955.7772999978624, + 897.2194000089075, + 730.177299992647, + 923.4746000147425, + 740.207199996803, + 787.3017999809235, + 1807.2819999943022, + 899.7489000030328, + 955.6876999849919, + 929.7008000139613, + 742.0220000203699, + 787.0080000138842, + 947.1464999951422, + 741.7279999936, + 785.9438000014052, + 1039.362000010442, + 954.504099994665, + 911.9261000014376, + 1006.5427999943495, + 1804.6735000098124, + 1420.9979000152089, + 1128.0968000064604, + 716.603299981216, + 729.4815999921411, + 895.15900000697, + 740.9271999786142, + 887.9797999979928, + 1035.4790999845136, + 1199.727700004587, + 1226.5025999804493, + 887.0127000263892, + 837.174899992533, + 741.8945000099484, + 1009.0633000072557, + 1167.4569999740925, + 1011.5470000018831, + 1311.1556000076234, + 823.1402999954298, + 735.9135999868158, + 1163.5764999955427, + 1811.9032999966294, + 751.7873000178952, + 933.3341999736149, + 759.7917000239249, + 1904.0703999926336, + 868.5568000073545, + 721.6072999872267, + 730.7297000079416, + 982.7877999923658, + 718.1673999875784 + ], + "delete_gameobject": [ + 701.1334999988321, + 896.1819999967702, + 703.6509999888949, + 550.7984999858309, + 551.6726000059862, + 547.4021999980323, + 738.9589000085834, + 785.299799987115, + 538.1901999935508, + 749.8045999964233, + 826.0056000144687, + 809.3454000190832, + 1846.3176999939606, + 633.2677000027616, + 987.7335999917705, + 599.5606000069529, + 965.616899979068, + 553.9130000106525, + 545.6262999796309, + 539.6944000094663, + 800.6323000008706, + 543.2657000201289, + 555.2050999831408, + 739.4666000036523, + 1643.1845000188332, + 552.6142999879085, + 796.9586999970488, + 555.8997000043746, + 767.8268000017852, + 599.1685999906622, + 691.1047000030521, + 714.565100002801, + 687.691500002984, + 551.8848999927286, + 548.3744999801274, + 541.8835000018589, + 532.0095999923069, + 662.1184000105131, + 1006.1718000215478, + 536.428400024306, + 993.2758999930229, + 722.1124000207055, + 776.6613999847323, + 542.3879000009038, + 584.5025000162423, + 665.4912999947555, + 1585.0789000105578, + 538.5110000206623, + 612.6202000014018, + 544.5389999949839, + 1297.3504000110552, + 1287.6911999774165, + 1090.9337000048254, + 812.5227999989875, + 567.4042000027839, + 1063.5223000135738, + 572.5949000043329, + 1252.0396999898367, + 653.7140999862459, + 795.8722999901511, + 1648.9090000104625, + 606.6928000072949, + 538.6989999969956, + 550.856499990914, + 547.5590999994893, + 741.0199999867473, + 636.6940000152681, + 544.240199989872, + 545.9802000259515, + 551.5067999949679, + 1286.2583999813069, + 553.1198999960907, + 584.744599997066, + 762.0346999901813, + 1105.0401999964379, + 1966.602900007274, + 535.1309000106994, + 723.032299982151, + 584.0361999871675, + 554.1339000046719, + 593.1717999919783, + 543.8560000038706, + 543.5834999952931, + 877.329600014491, + 535.8097999996971, + 536.6623000008985, + 805.0659000000451, + 583.5636999981944, + 543.9990000159014, + 681.3740000070538, + 577.2569999971893, + 731.170100014424, + 1333.8635000109207, + 548.0855999921914, + 543.2706999999937, + 818.960300006438, + 618.5807999863755, + 544.6296000154689, + 843.2306000031531, + 551.2583999952767 + ], + "scene_info": [ + 682.2050999908242, + 593.4522999741603, + 552.7206999831833, + 874.6867000008933, + 560.6209999823477, + 536.9653000088874, + 797.768599994015, + 535.4504999995697, + 593.9575000084005, + 552.9118999838829, + 1438.6273999989498, + 1153.3289999933913, + 600.5105999938678, + 923.7145000079181, + 908.1817999831401, + 614.9075999855995, + 835.9499000071082, + 1155.4868000093848, + 810.1071999990381, + 789.3815999850631, + 534.5155999821145, + 552.2254999959841, + 852.2035999922082, + 626.4239000156522, + 799.1916000028141, + 535.7015999907162, + 971.6081999940798, + 832.4933999974746, + 774.3590000027325, + 576.3981000054628, + 568.4669000038411, + 763.8411999796517, + 777.543300006073, + 927.8554000193253, + 560.5393000005279, + 539.3279999843799, + 553.402699995786, + 711.7138999747112, + 847.5722000002861, + 555.7532999955583, + 790.2107000118122, + 1162.3914000228979, + 558.2294999912847, + 749.0194000129122, + 536.0877999919467, + 1164.282199984882, + 543.6803000047803, + 1224.2674000153784, + 899.6946999977808, + 601.6958999971393, + 538.2358000206295, + 551.7570000083651, + 560.1688000024296, + 1297.7463999995962, + 667.3966000089422, + 540.9828000119887, + 544.376400008332, + 598.1574000034016, + 696.8796000001021, + 546.2729999853764, + 555.53549999604, + 880.3982000099495, + 550.0757999834605, + 678.4531000012066, + 664.7815999749582, + 602.5956000084989, + 546.0689999745227, + 552.5507999991532, + 591.3678999932017, + 671.9578999909572, + 829.8769000102766, + 556.8050000001676, + 701.343499997165, + 593.9574000076391, + 823.8784999994095, + 543.1193999829702, + 550.7479000079911, + 1165.0831000006292, + 717.8070000081789, + 542.6711000036448, + 603.8084999890998, + 958.7112999870442, + 753.3169999951497, + 1186.4823000214528, + 547.2048999799881, + 904.1555000003427, + 541.374899999937, + 597.2198999952525, + 692.3614999977872, + 731.3387999893166, + 662.524499988649, + 809.924899978796, + 544.5166999998037, + 558.6872999847401, + 593.0641000159085, + 936.778899980709, + 1008.0438999866601, + 528.3791999972891, + 835.1979000144638, + 535.0469000113662 + ], + "scene_save": [ + 646.4404999860562, + 635.8284000016283, + 661.0638999845833, + 640.8171000075527, + 921.677100006491, + 642.4103000026662, + 731.0270000016317, + 650.7503000029828, + 642.7547999774106, + 645.9209999884479, + 841.5556999971159, + 896.9091000035405, + 628.3373000042047, + 840.7716999936383, + 653.0660999997053, + 684.9612999940291, + 817.6181000017095, + 851.0158999997657, + 1040.5214999918826, + 647.8541000105906, + 629.1873999871314, + 644.1073999740183, + 1118.060200009495, + 917.9541999765206, + 722.9700000025332, + 850.105400022585, + 659.924499981571, + 1058.8725999987219, + 859.8313000111375, + 681.1075999867171, + 668.2599000050686, + 1586.4801999996416, + 707.9919000098016, + 1572.923300002003, + 639.3386999843642, + 834.3188999861013, + 825.5616000096779, + 747.3142000089865, + 634.6104999829549, + 877.3286000068765, + 872.0418000011705, + 643.9164000039455, + 1375.6916999991518, + 787.4640999943949, + 763.4885000006761, + 819.5690999855287, + 912.7950000111014, + 854.4194999849424, + 950.3007000021171, + 658.3208999945782, + 719.7291000047699, + 660.5276999762282, + 648.7462999939453, + 665.7236999890301, + 640.1647999882698, + 638.1801000097767, + 640.8531999913976, + 651.1267999885604, + 653.6290999792982, + 746.0208999982569, + 785.5189999972936, + 632.8164000005927, + 649.4105999881867, + 867.7698000101373, + 646.58369999961, + 942.6935000228696, + 944.125099980738, + 650.0137000111863, + 844.7021000029054, + 1220.7405999943148, + 660.323200019775, + 879.5558999991044, + 734.5948999864049, + 652.3651999887079, + 741.7905000038445, + 680.8561999932863, + 818.4735999966506, + 706.9578999944497, + 640.5338000040501, + 777.3091999988537, + 640.6917000131216, + 955.9442999889143, + 896.1641999776475, + 1011.187099997187, + 738.727399992058, + 679.8182999773417, + 644.6599000191782, + 819.6540000208188, + 655.194399994798, + 650.6182999874, + 966.2954999948852, + 1067.556499998318, + 892.9491000017151, + 876.1949999898206, + 764.7945999924559, + 648.1793000129983, + 1322.9425000026822, + 648.0095000006258, + 802.5609999895096, + 655.8231000090018 + ], + "console": [ + 878.8335999997798, + 544.4022000010591, + 549.9015999957919, + 552.0763999957126, + 553.2633999828249, + 654.6709000249393, + 566.9008999830112, + 539.8568999953568, + 647.7355000097305, + 537.4379000277258, + 547.6250000065193, + 555.2980000211392, + 538.4752999816556, + 545.914599992102, + 629.0659999940544, + 883.4832000138704, + 549.7665000148118, + 566.7251999839209, + 542.9474000120535, + 614.1736000136007, + 665.1161000190768, + 749.7381999855861, + 804.2377999809105, + 569.241699995473, + 526.8982000125106, + 597.2422999911942, + 678.7798999866936, + 1057.6248000143096, + 539.0008999966085, + 828.3578999980818, + 790.9564999863505, + 704.7050000110175, + 842.3263000149745, + 643.1448000075761, + 729.195299994899, + 530.0132999836933, + 566.917000018293, + 1897.8484999970533, + 642.0046999992337, + 575.1177999773063, + 547.851500014076, + 524.2871000082232, + 582.6134000089951, + 589.5886000071187, + 553.8249000092037, + 541.021200013347, + 1117.9745999979787, + 810.1989999995567, + 620.6057000090368, + 538.8090000196826, + 741.0237999865785, + 541.1044999782462, + 567.8895000019111, + 547.9303999745753, + 759.6683999872766, + 766.0537000047043, + 540.0734999857377, + 764.5779000013135, + 600.0410999986343, + 828.8538999913726, + 563.5193000198342, + 651.2500999961048, + 644.543500005966, + 629.78370001656, + 803.4325999906287, + 608.5142999945674, + 842.1901999972761, + 537.4235999770463, + 779.6542000141926, + 764.8561999958474, + 688.7135999859311, + 585.2188000280876, + 708.1500999920536, + 539.2202999792062, + 554.1697000153363, + 763.654200010933, + 1417.1644000161905, + 640.1604000129737, + 538.0229000002146, + 544.0806999977212, + 549.7190999740269, + 841.2239000026602, + 827.1825999836437, + 756.1808000027668, + 844.5682000019588, + 734.149099997012, + 597.4882000009529, + 529.4629999843892, + 704.2493000044487, + 764.8680999991484, + 873.5732999921311, + 547.8664999827743, + 534.7407000081148, + 1139.8110000009183, + 756.1724999977741, + 552.8234000084922, + 545.4046000086237, + 553.759300004458, + 548.3135000104085, + 767.728700011503 + ], + "screenshot": [ + 585.7669000106398, + 783.8432000135072, + 835.8427000057418, + 596.1582000018097, + 928.0180000059772, + 725.8557000022847, + 651.7537999898195, + 587.9699000215624, + 1003.9685000083409, + 818.0680999939796, + 884.8537000012584, + 887.4417999759316, + 831.5045000053942, + 679.7457000066061, + 885.5116000049748, + 670.4961000068579, + 586.7657999915536, + 608.4954999969341, + 722.6425999833737, + 664.777400001185, + 820.5545999808237, + 1340.6722999934573, + 631.6273999982513, + 620.9578000125475, + 788.9481000020169, + 662.3613999981899, + 587.5432999746408, + 967.6849000097718, + 662.4212999886367, + 1333.5681000025943, + 1820.822399982717, + 590.7888999790885, + 1004.3862999882549, + 666.3667999964673, + 1036.4010000193957, + 591.6182000073604, + 697.5883000122849, + 582.7340999967419, + 696.9859999953769, + 920.7855999993626, + 593.7504000030458, + 596.1905000149272, + 662.3477000102866, + 659.5152000081725, + 845.2055999950971, + 601.550599996699, + 688.0041999975219, + 1262.8552000096533, + 715.6925000017509, + 870.1135000155773, + 1010.8125999977347, + 584.8742999951355, + 584.2650999838952, + 614.2165000201203, + 1212.6144999929238, + 975.7241999905091, + 600.5348999751732, + 1029.0832999744453, + 584.8770999873523, + 663.2709999976214, + 592.6484999945387, + 792.8537999978289, + 588.518499978818, + 583.2287000084762, + 725.483099988196, + 949.7593000123743, + 598.2782000210136, + 579.1115000029095, + 748.7527999910526, + 597.774699999718, + 640.0828000041656, + 644.3713000044227, + 584.9255000066478, + 791.7543000075966, + 837.3762000119314, + 600.0433999870438, + 605.9214000124484, + 601.0429000016302, + 798.4271000023, + 783.6737000034191, + 943.0223999952432, + 596.3820999895688, + 591.2518999830354, + 710.8528999960981, + 949.341799976537, + 710.4281000210904, + 841.7197999951895, + 602.6293000031728, + 709.7522999974899, + 1005.8579000178725, + 974.2059000127483, + 832.0647999935318, + 1092.5332000188064, + 621.9719999935478, + 703.7700999935623, + 606.0410000209231, + 891.9825999764726, + 593.71449999162, + 608.8771000213455, + 748.0339000176173 + ], + "material_search": [ + 775.7461000001058, + 592.4690999963786, + 555.7724999962375, + 789.2133000132162, + 789.2251999874134, + 835.0195999955758, + 687.3590000031982, + 672.4890999903437, + 1428.0893999966793, + 754.4191000051796, + 723.0263999954332, + 683.1285000080243, + 666.0026999888942, + 742.0894999813754, + 850.8775000227615, + 806.7008000216447, + 544.129999994766, + 678.9344000280835, + 666.1644999985583, + 541.6499999992084, + 637.3116000031587, + 1439.6140000026207, + 809.5478000177536, + 554.3605000129901, + 633.2304000097793, + 1435.7323999865912, + 793.9698999980465, + 565.2843000134453, + 776.6739000217058, + 549.1069999989122, + 578.1395999947563, + 634.608099993784, + 895.8433000079822, + 761.2613999808673, + 569.1185999894515, + 561.9865999906324, + 637.9727000021376, + 596.0597000084817, + 1376.5546999929938, + 541.0714999889024, + 729.8990999988746, + 547.5996000168379, + 748.2424000045285, + 548.9840999944136, + 879.2561000154819, + 859.4631000014488, + 542.5425000139512, + 542.4035000032745, + 813.0952999927104, + 700.6205999932718, + 556.5543999837246, + 545.4695000080392, + 718.3936999936122, + 560.741399996914, + 765.7325000036508, + 810.1583999814466, + 551.15929999738, + 841.6511999967042, + 541.3830000034068, + 553.6321999970824, + 567.6330999995116, + 797.4296000029426, + 741.7978000012226, + 722.7053000242449, + 624.6197999862488, + 555.1566000212915, + 546.5564000187442, + 739.1568000020925, + 610.0791999779176, + 563.8212999911048, + 800.4671999951825, + 773.2550000073388, + 544.0535999950953, + 664.3980999942869, + 670.5614999809768, + 601.0911999910604, + 549.0758999949321, + 733.7668999971356, + 1402.7813999855425, + 882.6287999982014, + 556.6532000084408, + 644.6892999811098, + 548.0456000077538, + 571.8536000058521, + 555.0035999913234, + 557.7142999973148, + 805.286899994826, + 741.5034000005107, + 724.2291999864392, + 1105.4730999749154, + 884.3123000115156, + 548.1665999977849, + 556.0980000009295, + 779.56350002205, + 1168.8887999916915, + 674.036900018109, + 1200.971100013703, + 786.121400014963, + 640.0682000094093, + 671.343900001375 + ], + "asset_copy": [ + 822.118500014767, + 929.5513999823015, + 601.03010002058, + 1505.7557999971323, + 628.4563999797683, + 791.9009999895934, + 996.8610999931116, + 1803.0127999954857, + 769.2643999762367, + 706.8051999958698, + 704.3335000053048, + 660.3705000015907, + 952.1615999983624, + 778.9737000130117, + 1274.8168999969494, + 805.7226999953855, + 622.9949000116903, + 595.6001000013202, + 669.9363999941852, + 594.5425000099931, + 720.1446999970358, + 967.7538999821991, + 1031.965100002708, + 613.9860000112094, + 668.7779000203591, + 642.7978000137955, + 773.6461000167765, + 840.262999990955, + 1052.2629999904893, + 616.2152000179049, + 885.3926000010688, + 762.9237999790348, + 1176.3876999903005, + 991.4286000130232, + 666.4329000050202, + 776.2765999941621, + 862.5018000020646, + 595.0753000215627, + 697.7216999803204, + 602.1766999911051, + 978.445599990664, + 674.5011000020895, + 1283.729199989466, + 585.969700012356, + 653.8296999933664, + 1207.4743999983184, + 891.4312999986578, + 752.5086999812629, + 773.7505000259262, + 1007.8442000085488, + 800.3298999974504, + 723.9907000039238, + 749.9422999972012, + 588.8279000064358, + 745.963200024562, + 620.7300999958534, + 850.4921999992803, + 638.3784000063315, + 883.8623999909032, + 602.0834000082687, + 672.3519999941345, + 1015.0422999868169, + 1285.0552999880165, + 1257.288199994946, + 641.4347999962047, + 621.4041000057478, + 618.7313999980688, + 707.0684999926016, + 940.2514999965206, + 600.5171000142582, + 902.4960999959148, + 791.3870000047609, + 614.8010000179056, + 991.7665999964811, + 978.4995000227354, + 1504.335199977504, + 598.7125000101514, + 712.5559000123758, + 713.6813999968581, + 1201.7408999963664, + 693.6264999967534, + 1840.747400012333, + 826.9493000116199, + 613.1290999765042, + 616.6343000077177, + 743.0310000199825, + 1008.3046000218019, + 1077.5414000090677, + 782.059199991636, + 835.1950999931432, + 803.0288000009023, + 602.6315999915823, + 807.9446000047028, + 732.7490999887232, + 994.1092999943066, + 790.213300002506, + 616.3817000051495, + 890.5115000088699, + 1279.8100000072736, + 613.2409000128973 + ], + "asset_move": [ + 870.7744999846909, + 1127.318999991985, + 685.291599977063, + 603.8341000094078, + 598.4455999860074, + 591.6826000029687, + 909.137800015742, + 1120.8624000137206, + 687.4274000001606, + 1158.1800999992993, + 609.5239999995101, + 588.3743999875151, + 1407.869499991648, + 602.6462000154424, + 591.913200012641, + 595.8421000104863, + 679.2122999904677, + 668.0206000164617, + 659.8153999948408, + 806.473200005712, + 1117.6611999981105, + 611.2858999986202, + 928.6878999846522, + 783.9221000031102, + 791.1160000076052, + 593.713200010825, + 1191.1211000115145, + 1006.289699987974, + 642.1931999793742, + 586.1778999969829, + 709.1261000023223, + 903.1979999854229, + 587.6917999994475, + 876.7524999857415, + 692.1589999983553, + 597.769000014523, + 768.8815000001341, + 868.1427999981679, + 581.200299988268, + 594.7485999786295, + 855.949699995108, + 817.676400009077, + 994.185399991693, + 745.9392999880947, + 879.1920999938156, + 605.967800016515, + 949.5554000022821, + 593.5170000011567, + 591.9919000007212, + 851.153700001305, + 614.6984999941196, + 886.2794999731705, + 1432.2549999924377, + 848.2630999933463, + 810.5564000143204, + 602.9257999907713, + 903.88980001444, + 774.2666999984067, + 978.3577999914996, + 603.8967000204138, + 583.5611000075005, + 593.5623000259511, + 795.9934999817051, + 591.9370999909006, + 883.1559999962337, + 896.2283000000753, + 692.784600018058, + 919.0281000046525, + 844.0293000021484, + 722.3949999897741, + 1281.8591999821365, + 592.8925000189338, + 765.0847999902908, + 882.6849999895785, + 753.9530000067316, + 863.9357999782078, + 604.2261999973562, + 889.4683999824338, + 717.1885000134353, + 599.3446999927983, + 631.0793999873567, + 685.4029000096489, + 1481.7879000038374, + 590.3645000071265, + 790.2804000186734, + 1201.1959000083152, + 616.367500013439, + 624.8286000045482, + 1189.083600009326, + 630.2312999905553, + 597.0167000195943, + 783.8935000181664, + 836.0889999894425, + 683.947999990778, + 623.4104000031948, + 880.0580999813974, + 861.9634000060614, + 650.2509000129066, + 963.0248000030406, + 646.4054000098258 + ], + "asset_delete": [ + 696.1257999937516, + 1150.5938000045717, + 898.6761999840382, + 606.474000000162, + 650.5525999818929, + 875.2378999779467, + 596.3301000010688, + 594.7087999957148, + 811.1338999879081, + 651.2425999972038, + 664.3013000139035, + 753.8629999908153, + 646.383200015407, + 776.9742000091355, + 786.1631000123452, + 573.5609999974258, + 829.191400000127, + 614.0652000030968, + 909.6483000030275, + 734.9953000084497, + 893.5643000004347, + 586.2149999884423, + 775.4899999999907, + 713.9599999936763, + 591.6576999879908, + 805.860099993879, + 1435.3728000132833, + 887.5819999957457, + 607.0816999999806, + 733.2650999887846, + 722.7804000140168, + 586.0639999737032, + 590.9188000077847, + 751.2526999926195, + 2212.986500002444, + 755.244700005278, + 943.2393999886699, + 902.2197999875061, + 581.1573999817483, + 593.221299990546, + 838.5357999941334, + 893.5154000064358, + 586.0529000055976, + 960.7263000216335, + 585.367200023029, + 592.0095999899786, + 1127.3789999831934, + 591.4977999927942, + 592.7872000029311, + 781.4828999980818, + 893.1324000004679, + 679.1728000098374, + 608.0081999825779, + 593.8317000109237, + 1037.0423000131268, + 597.3287000088021, + 596.4494999789167, + 941.8052000110038, + 589.812999998685, + 1086.9558000122197, + 579.3552999966778, + 772.1794999961276, + 582.0203999755904, + 589.5141000219155, + 1191.8276000069454, + 713.6066999810282, + 615.0020000059158, + 592.7238000149373, + 604.662500001723, + 743.8428000023123, + 782.3501999955624, + 965.1153000013437, + 901.4229999738745, + 890.4058999905828, + 780.3210999991279, + 857.3161999811418, + 1312.3553000041284, + 593.2508999831043, + 797.133300016867, + 698.5656000033487, + 591.437600000063, + 595.8466999873053, + 585.0539999955799, + 681.4590999856591, + 973.6612999986392, + 591.8992999941111, + 825.8540999959223, + 683.750099997269, + 594.5184000011068, + 727.8934000059962, + 875.8270000107586, + 841.1474000022281, + 786.268600000767, + 892.4533999816049, + 939.7979999775998, + 865.3782000183128, + 586.9642000179738, + 863.6136999994051, + 675.5152000114322, + 638.4147999924608 + ], + "import_settings": [ + 545.1917999889702, + 802.2437999898102, + 572.5775999890175, + 692.3321000067517, + 918.1628999940585, + 938.7074000260327, + 541.8632999935653, + 532.4744999816176, + 1373.5160999931395, + 541.029600019101, + 535.2160999900661, + 546.7988000018522, + 529.1220999788493, + 684.350000025006, + 699.8927000095136, + 1154.657600010978, + 1192.0811000163667, + 808.405199990375, + 890.1700999995228, + 833.1980000075419, + 547.0082000247203, + 528.7378999928478, + 670.2956999943126, + 895.7647999923211, + 769.6146999951452, + 781.8023000145331, + 812.3101000091992, + 634.1642999905162, + 802.2977999935392, + 855.136099999072, + 929.0727000043262, + 716.4177000231575, + 587.6121000037529, + 545.6819999963045, + 1083.4361000161152, + 672.5731000187807, + 545.9328999859281, + 537.917399982689, + 730.7714000053238, + 749.9318000045605, + 560.6165999779478, + 583.1032999849413, + 529.3635000125505, + 842.1356999897398, + 559.246599994367, + 690.3800000145566, + 591.4844000071753, + 747.239799995441, + 657.860300008906, + 540.4782999830786, + 690.3346999897622, + 847.4462000012863, + 819.4517999945674, + 663.7440999911632, + 758.7773999839555, + 547.4931999924593, + 536.27390001202, + 865.9047999826726, + 775.2117000054568, + 550.5452000070363, + 701.3395999965724, + 697.8719000180718, + 1165.8877999871038, + 661.6359000036027, + 548.892299993895, + 900.47950000735, + 872.8139000013471, + 550.4427000123542, + 774.621799995657, + 820.4719999921508, + 830.1428000268061, + 584.7094999917317, + 549.7652000049129, + 611.9347999920137, + 598.9503000164405, + 643.1737999955658, + 1051.3027000124566, + 538.7544000113849, + 1140.5786000250373, + 652.8177000000142, + 801.4742000086699, + 795.7204999984242, + 549.6110999956727, + 581.7583999887574, + 540.8404000045266, + 645.8887999760918, + 642.8570999996737, + 611.0610000032466, + 547.772799996892, + 555.163300014101, + 677.555600006599, + 1136.8454000039492, + 674.1760000004433, + 793.2109999819659, + 986.8536999856587, + 691.737799992552, + 535.3619999950752, + 795.2656999987084, + 888.9543999976013, + 630.6965999829117 + ], + "material_modify": [ + 573.1580999854486, + 792.9915000277106, + 596.909300016705, + 1494.452699989779, + 558.6438999744132, + 807.4541999958456, + 771.4343999978155, + 566.4905000012368, + 562.0939000218641, + 548.9882999972906, + 825.1445000059903, + 718.1772999756504, + 608.0620999855455, + 605.8551000023726, + 1513.74590001069, + 551.9783000054304, + 857.9181999957655, + 917.325400019763, + 562.3070000146981, + 851.0517999820877, + 795.7490000117105, + 575.3542000020389, + 574.2544999811798, + 566.3237000117078, + 667.5604000047315, + 917.9459000006318, + 581.3262999872677, + 596.2110999971628, + 738.8873000163585, + 614.7190000046976, + 686.6610000142828, + 637.4451000010595, + 835.648799984483, + 579.0755999914836, + 868.805899983272, + 636.0185999947134, + 640.8784000086598, + 707.7211000141688, + 690.526399994269, + 941.5528999816161, + 569.7799999907147, + 568.8241999887396, + 582.368100003805, + 634.6202999993693, + 652.967300004093, + 626.9353999814484, + 607.2918999998365, + 795.6061000004411, + 676.4931999787223, + 853.9393999963067, + 1576.9549999968149, + 633.3309999899939, + 842.5417999969795, + 933.8951000245288, + 733.3613999944646, + 781.7368999822065, + 644.4094000034966, + 563.2479999912903, + 666.8505000125151, + 753.5650999925565, + 1219.394599989755, + 796.6502000053879, + 574.9572000058834, + 566.6885999962687, + 670.5134999938309, + 924.9471000221092, + 546.6169000137597, + 844.1831000091042, + 846.8853000085801, + 657.4355000047944, + 854.6272999956273, + 565.3889000241179, + 574.6896000055131, + 582.600800000364, + 968.5549999994691, + 564.5459000079427, + 620.7914000260644, + 687.9446000093594, + 608.4513000096194, + 582.862200011732, + 676.6316999855917, + 829.4447000080254, + 855.0785999977961, + 845.6682999967597, + 651.5591000206769, + 797.5830000068527, + 1281.9728000031319, + 701.9766999874264, + 645.4442999965977, + 710.8767000027001, + 967.5787000160199, + 547.092499997234, + 651.8279000010807, + 653.7131000077352, + 1771.4797999942675, + 1022.4052999983542, + 796.9970000267494, + 939.972599997418, + 885.2636000083294, + 615.2060000167694 + ], + "time_settings": [ + 532.6948000001721, + 637.3549999843817, + 572.5793000019621, + 548.4812000067905, + 528.3443999942392, + 545.8195999963209, + 724.6720000111964, + 831.3446999818552, + 543.2362999999896, + 820.1014999940526, + 661.5344999881927, + 892.3912000027485, + 522.107099997811, + 720.8696999878157, + 690.5942999874242, + 527.0225999993272, + 546.1614000087138, + 545.5169999913778, + 533.775699994294, + 801.7503999872133, + 793.8303999835625, + 783.8919000059832, + 541.3877000100911, + 533.6037999950349, + 825.898099981714, + 616.5817999863066, + 545.2493000193499, + 819.061199988937, + 614.8437000229023, + 714.8589999997057, + 534.2132000077982, + 534.8727999953553, + 535.5304999975488, + 545.0852999929339, + 538.2072999782395, + 1751.5967999934219, + 579.3723000097089, + 528.7063000141643, + 873.1741999799851, + 874.6978999988642, + 542.7694000245538, + 690.6526999955531, + 700.7423000177369, + 818.5364000091795, + 564.9977999855764, + 675.5223000072874, + 773.5950000060257, + 891.4649000216741, + 1140.7944999809843, + 870.3730000124779, + 553.2199000008404, + 546.3301999843679, + 881.6261000174563, + 530.062400008319, + 546.6147999977693, + 933.0570999882184, + 530.3608999820426, + 542.648000002373, + 540.7925999897998, + 681.0873999784235, + 538.1628000177443, + 870.7705999840982, + 751.2909999932162, + 1034.5755000016652, + 836.3315000024159, + 768.0035999801476, + 563.7145999935456, + 623.2667999865953, + 665.9784000075888, + 531.2314000038896, + 953.0935000220779, + 763.8810000207741, + 558.8931999809574, + 805.159299983643, + 787.6077000109944, + 900.4580000182614, + 748.1490000209305, + 551.3158999965526, + 543.5593999864068, + 779.1426999901887, + 548.3342999941669, + 967.5533999979962, + 774.6706000179984, + 1510.3321000060532, + 539.7051000036299, + 592.2458000131883, + 1451.3333999784663, + 776.7257000086829, + 694.8417000239715, + 900.7915999973193, + 555.5246000003535, + 536.067400011234, + 552.9206999926828, + 782.4499999987893, + 1158.4746000007726, + 1194.490299996687, + 696.3033999782056, + 539.9503000080585, + 722.1543999912683, + 719.4713000208139 + ], + "read_csharp": [ + 540.8406000060495, + 950.6618999876082, + 692.4594999873079, + 555.9422000078484, + 549.0502000029664, + 542.8105999890249, + 868.2162000040989, + 661.1139999877196, + 629.3369999912102, + 1273.4977999934927, + 556.872499990277, + 598.4230000176467, + 783.5773999977391, + 548.1946999789216, + 630.6247000175063, + 811.4283999893814, + 590.2499000076205, + 606.5602999879047, + 766.7604000016581, + 546.5068999910727, + 2094.029700005194, + 981.8681000033394, + 548.8415000145324, + 657.4543000024278, + 541.1346000037156, + 545.9634999861009, + 685.8502999821212, + 708.8863000099082, + 556.5216999966651, + 681.5713999967556, + 798.8588000007439, + 815.5928000051063, + 780.3771000180859, + 641.7212999949697, + 539.282900019316, + 558.4131999930833, + 801.2604000105057, + 764.9144000024535, + 546.2969999935012, + 624.1807000187691, + 682.0226000272669, + 920.9528999926988, + 1480.2965999988373, + 781.2573999981396, + 603.8526000047568, + 636.9153999839909, + 1189.9990999954753, + 711.262099997839, + 1109.8311000096146, + 672.5537000165787, + 530.5065999855287, + 805.2061999915168, + 706.7762000078801, + 623.9041999797337, + 697.8639999870211, + 543.3907999831717, + 764.7678999928758, + 656.6015999997035, + 688.9809999847785, + 656.5028000040911, + 829.5128000027034, + 544.8719999985769, + 581.2258000078145, + 858.1987000070512, + 655.0779999815859, + 692.369399999734, + 527.2931999934372, + 828.6611000075936, + 542.0171999721788, + 538.8914000068326, + 650.7282999809831, + 1218.4204999939539, + 546.3463999913074, + 1478.82569997455, + 760.131499991985, + 1462.976200011326, + 618.8069999916479, + 670.6286999979056, + 542.480300005991, + 737.4194000149146, + 837.9917000129353, + 535.2193000144325, + 674.1791999957059, + 889.5738999999594, + 542.5600000016857, + 800.222300022142, + 536.7021999845747, + 952.2088999801781, + 557.8709999972489, + 594.1412000101991, + 536.8792999943253, + 541.0161000036169, + 556.5251000225544, + 1245.1212000160012, + 793.6111000017263, + 563.6801999935415, + 1181.248399981996, + 555.4078999848571, + 655.9885000169743, + 677.2036999755073 + ], + "play_until_ready": [ + 1139.074700011406, + 2092.5883000018075, + 1584.3199000228196, + 1140.9246000112034, + 2701.1799000028986, + 1900.1964000053704, + 1360.3705000132322, + 1386.148299992783, + 1086.7105000070296, + 1142.6039999932982, + 1487.6037999929395, + 1194.9569999997038, + 1236.473199998727, + 1948.6815000127535, + 1109.7463000041898, + 1988.7098000035621, + 2111.916800000472, + 1566.776400024537, + 1977.6595000002999, + 1463.3998000063002, + 1119.4409999880008, + 2054.356699984055, + 1103.950300021097, + 1111.257000011392, + 1092.3945999820717, + 1293.724299990572, + 1488.721000001533, + 2533.746000000974, + 1703.9536999945994, + 1519.69069999177, + 1407.9996999935247, + 2037.3575999983586, + 1860.660700011067, + 1820.6596999953035, + 1083.2998999976553, + 1358.6594999942463, + 1666.3934999960475, + 1635.4793999926187, + 1678.4608000016306, + 1984.8585999861825, + 1511.97449999745, + 1083.925300015835, + 1278.2444000185933, + 1163.1796999718063, + 1074.0731000259984, + 1815.4316000000108, + 1100.4288999829441, + 1138.073500012979, + 1402.575300016906, + 1101.7607999965549, + 1404.0001000103075, + 1349.222799995914, + 1102.1529999852646, + 1158.8859999901615, + 1370.3320999920834, + 1503.276699979324, + 2040.9462999959942, + 1353.59059998882, + 1769.5459999958985, + 1220.571799989557, + 1276.975400018273, + 1381.9693999830633, + 1382.9173000121955, + 1188.2276000105776, + 1536.5774999954738, + 1716.136600007303, + 1548.3464999997523, + 2143.5466000111774, + 1221.9705000170507, + 1394.4328999787103, + 1185.1773000089452, + 1115.2985999942757, + 1579.8076000064611, + 1081.4293999865185, + 1432.055199984461, + 1473.5769999970216, + 1372.7790999982972, + 1528.5825000028126, + 1275.7348000013735, + 1162.4703999841586, + 1291.6710999852512, + 1077.4740999913774, + 1081.6038999764714, + 1112.543299997924, + 1548.2946000120137, + 1531.9680999964476, + 1090.5377000162844, + 1155.1445000222884, + 1924.5447000139393, + 1095.1355999859516, + 1289.968700002646, + 1936.6979000042193, + 2199.8904999927618, + 1320.2087999961805, + 1153.7225999927614, + 1110.2382999961264, + 1321.5262000157963, + 1572.7306000189856, + 2023.8087000034284, + 1084.4191999931354 + ], + "stop_until_ready": [ + 1674.8637999990024, + 1122.6185999985319, + 1263.5947999951895, + 1397.8052999882493, + 1206.672600004822, + 1132.9588000080548, + 1501.5477999986615, + 1083.9925999753177, + 2392.99399999436, + 2444.052000006195, + 1519.8491000046488, + 1544.4753999763634, + 1269.7051000141073, + 1390.9950999950524, + 1963.7266999925487, + 1152.931799995713, + 1407.5596000184305, + 1366.6416999767534, + 1092.9048999969382, + 1369.7937999968417, + 1629.3047000071965, + 1351.0392000025604, + 1544.5819000015035, + 1461.0991000081412, + 1139.3514999945182, + 1391.2322000251152, + 1232.6950000133365, + 1363.4711999911815, + 1897.6919999986421, + 1132.0367999724112, + 2159.8048000014387, + 1255.6085000105668, + 1449.6202000009362, + 1278.7196999997832, + 1543.7051999906544, + 1266.9027000083588, + 1520.1249000092503, + 1819.859000010183, + 1401.528899994446, + 1146.6243999893777, + 1213.8398000097368, + 1080.3345999738667, + 1491.5877000021283, + 1338.8757000211626, + 1171.3799000135623, + 1117.4681999837048, + 1356.7886000091676, + 1872.429999988526, + 1337.9192000138573, + 2143.834499991499, + 2630.343400000129, + 1697.2714000148699, + 1233.7044999876525, + 1366.8276999960653, + 1083.8651999947615, + 1177.4955000146292, + 1079.504099994665, + 1890.639299992472, + 1210.8038000005763, + 1466.4274000097066, + 1317.3333999875467, + 1402.9812999942806, + 1872.0934999873862, + 2525.4806999873836, + 1343.8341000000946, + 1347.766299993964, + 1533.4868999780156, + 1411.1532999959309, + 1234.2049999861047, + 1397.0714999886695, + 1836.7847999907099, + 1109.7188999992795, + 1214.1844000143465, + 1151.1428999947384, + 1308.4219000011217, + 1129.7676999820396, + 1531.4635999966413, + 1179.660200024955, + 2300.941599998623, + 1343.3866999985185, + 1805.2405999915209, + 2487.8479999897536, + 1276.4403000182938, + 1763.092199980747, + 2116.104600019753, + 1110.6390000204556, + 1278.2934000133537, + 1593.7137999862898, + 1333.104999997886, + 1105.6476999947336, + 1283.5908999841195, + 1223.1151000014506, + 1617.173400009051, + 1345.1492000021972, + 1126.866600010544, + 1252.81969999196, + 1532.839999999851, + 1351.7906999913976, + 1392.6620999991428, + 1661.9418000045698 + ] + } + }, + "details": { + "official_shell_pid": 34664, + "discarded_focus_cycles": 0, + "operations": [ + { + "name": "editor_state", + "unity_cli": { + "tool": "get_editor_state", + "params": {} + }, + "official": { + "tool": "editor_status", + "params": {} + } + }, + { + "name": "hierarchy", + "unity_cli": { + "tool": "get_hierarchy", + "params": {} + }, + "official": { + "tool": "get_scene_hierarchy", + "params": {} + } + }, + { + "name": "find_gameobject", + "unity_cli": { + "tool": "find_gameobject", + "params": { + "name": "Perf394Target", + "exactMatch": true + } + }, + "official": { + "tool": "find_gameobjects", + "params": { + "name": "Perf394Target" + } + } + }, + { + "name": "transform", + "unity_cli": { + "tool": "get_component_values", + "params": { + "gameObjectName": "Perf394Target", + "componentType": "Transform" + } + }, + "official": { + "tool": "get_component_properties", + "params": { + "target": { + "hierarchyPath": "/Perf394Target" + }, + "type": "Transform" + } + } + }, + { + "name": "position", + "unity_cli": { + "tool": "modify_gameobject", + "params": { + "path": "/Perf394Target", + "position": { + "x": 1, + "y": 2, + "z": 3 + } + } + }, + "official": { + "tool": "set_transform", + "params": { + "target": { + "hierarchyPath": "/Perf394Target" + }, + "position": [ + 1, + 2, + 3 + ] + } + } + }, + { + "name": "create_cube", + "unity_cli": { + "tool": "create_gameobject", + "params": { + "name": "Perf394Cube", + "primitiveType": "cube" + } + }, + "official": { + "tool": "create_gameobject", + "params": { + "name": "Perf394Cube", + "primitive": "Cube" + } + } + }, + { + "name": "add_component", + "unity_cli": { + "tool": "add_component", + "params": { + "gameObjectPath": "/Perf394Cube", + "componentType": "Rigidbody" + } + }, + "official": { + "tool": "add_component", + "params": { + "target": { + "hierarchyPath": "/Perf394Cube" + }, + "type": "Rigidbody" + } + } + }, + { + "name": "remove_component", + "unity_cli": { + "tool": "remove_component", + "params": { + "gameObjectPath": "/Perf394Cube", + "componentType": "Rigidbody" + } + }, + "official": { + "tool": "remove_component", + "params": { + "target": { + "hierarchyPath": "/Perf394Cube" + }, + "type": "Rigidbody" + } + } + }, + { + "name": "delete_gameobject", + "unity_cli": { + "tool": "delete_gameobject", + "params": { + "path": "/Perf394Cube" + } + }, + "official": { + "tool": "delete_gameobject", + "params": { + "target": { + "hierarchyPath": "/Perf394Cube" + } + } + } + }, + { + "name": "scene_info", + "unity_cli": { + "tool": "get_scene_info", + "params": {} + }, + "official": { + "tool": "list_open_scenes", + "params": {} + } + }, + { + "name": "scene_save", + "unity_cli": { + "tool": "save_scene", + "params": {} + }, + "official": { + "tool": "save_scene", + "params": {} + } + }, + { + "name": "console", + "unity_cli": { + "tool": "read_console", + "params": { + "count": 20 + } + }, + "official": { + "tool": "console", + "params": { + "tail": 20, + "level": "log" + } + } + }, + { + "name": "screenshot", + "unity_cli": { + "tool": "capture_screenshot", + "params": { + "captureMode": "game", + "width": 1280, + "height": 720, + "includeUI": false, + "encodeAsBase64": false, + "osFallback": false + } + }, + "official": { + "tool": "screenshot", + "params": { + "view": "game", + "width": 1280, + "height": 720 + } + } + }, + { + "name": "material_search", + "unity_cli": { + "tool": "manage_asset_database", + "params": { + "action": "find_assets", + "filter": "t:Material", + "searchInFolders": [ + "Assets/Scenes/Generated/E2E/Performance" + ] + } + }, + "official": { + "tool": "find_assets", + "params": { + "type": "Material", + "search_in": "Assets/Scenes/Generated/E2E/Performance" + } + } + }, + { + "name": "asset_copy", + "unity_cli": { + "tool": "manage_asset_database", + "params": { + "action": "copy_asset", + "fromPath": "Assets/Scenes/Generated/E2E/Performance/PerfSource.mat", + "toPath": "Assets/Scenes/Generated/E2E/Performance/PerfCopy.mat" + } + }, + "official": { + "tool": "copy_asset", + "params": { + "asset": "Assets/Scenes/Generated/E2E/Performance/PerfSource.mat", + "destination": "Assets/Scenes/Generated/E2E/Performance/PerfCopy.mat" + } + } + }, + { + "name": "asset_move", + "unity_cli": { + "tool": "manage_asset_database", + "params": { + "action": "move_asset", + "fromPath": "Assets/Scenes/Generated/E2E/Performance/PerfCopy.mat", + "toPath": "Assets/Scenes/Generated/E2E/Performance/PerfMoved.mat" + } + }, + "official": { + "tool": "move_asset", + "params": { + "asset": "Assets/Scenes/Generated/E2E/Performance/PerfCopy.mat", + "destination": "Assets/Scenes/Generated/E2E/Performance/PerfMoved.mat" + } + } + }, + { + "name": "asset_delete", + "unity_cli": { + "tool": "manage_asset_database", + "params": { + "action": "delete_asset", + "assetPath": "Assets/Scenes/Generated/E2E/Performance/PerfMoved.mat" + } + }, + "official": { + "tool": "delete_asset", + "params": { + "asset": "Assets/Scenes/Generated/E2E/Performance/PerfMoved.mat", + "confirm": true + } + } + }, + { + "name": "import_settings", + "unity_cli": { + "tool": "manage_asset_import_settings", + "params": { + "action": "get", + "assetPath": "Assets/Scenes/Generated/E2E/Performance/PerfSource.mat" + } + }, + "official": { + "tool": "get_import_settings", + "params": { + "asset": "Assets/Scenes/Generated/E2E/Performance/PerfSource.mat" + } + } + }, + { + "name": "material_modify", + "unity_cli": { + "tool": "modify_material", + "params": { + "materialPath": "Assets/Scenes/Generated/E2E/Performance/PerfSource.mat", + "properties": { + "_Color": [ + 0.2, + 0.4, + 0.8, + 1 + ] + } + } + }, + "official": { + "tool": "set_material_properties", + "params": { + "material": "Assets/Scenes/Generated/E2E/Performance/PerfSource.mat", + "properties": { + "_Color": [ + 0.2, + 0.4, + 0.8, + 1 + ] + } + } + } + }, + { + "name": "time_settings", + "unity_cli": { + "tool": "get_project_settings", + "params": { + "includeTime": true, + "includePlayer": false + } + }, + "official": { + "tool": "get_time_settings", + "params": {} + } + }, + { + "name": "read_csharp", + "unity_cli": { + "tool": "read", + "params": { + "path": "Assets/HotReloadProbe.cs", + "maxLines": 50 + } + }, + "official": { + "tool": "read_text_file", + "params": { + "path": "Assets/HotReloadProbe.cs" + } + } + }, + { + "name": "play_until_ready", + "unity_cli": { + "tool": "play_game", + "params": {} + }, + "official": { + "tool": "editor_play", + "params": {} + } + }, + { + "name": "stop_until_ready", + "unity_cli": { + "tool": "stop_game", + "params": {} + }, + "official": { + "tool": "editor_stop", + "params": {} + } + } + ] + }, + "results": { + "unity-cli": { + "editor_state": { + "n": 100, + "p50_ms": 223.44, + "p95_ms": 715.67, + "mean_ms": 267.21, + "min_ms": 33.45, + "max_ms": 1246.88 + }, + "hierarchy": { + "n": 100, + "p50_ms": 40.66, + "p95_ms": 828.94, + "mean_ms": 209.29, + "min_ms": 34.81, + "max_ms": 1425.06 + }, + "find_gameobject": { + "n": 100, + "p50_ms": 38.06, + "p95_ms": 862.07, + "mean_ms": 202.51, + "min_ms": 33.79, + "max_ms": 1671.68 + }, + "transform": { + "n": 100, + "p50_ms": 40.79, + "p95_ms": 602.45, + "mean_ms": 173.05, + "min_ms": 36.16, + "max_ms": 1156.5 + }, + "position": { + "n": 100, + "p50_ms": 38.34, + "p95_ms": 598.93, + "mean_ms": 179.26, + "min_ms": 34.08, + "max_ms": 1190.91 + }, + "create_cube": { + "n": 100, + "p50_ms": 39.69, + "p95_ms": 898.57, + "mean_ms": 202.01, + "min_ms": 33.47, + "max_ms": 1432.58 + }, + "add_component": { + "n": 100, + "p50_ms": 51.85, + "p95_ms": 878.84, + "mean_ms": 157.4, + "min_ms": 42.28, + "max_ms": 1177.79 + }, + "remove_component": { + "n": 100, + "p50_ms": 46.29, + "p95_ms": 592.21, + "mean_ms": 152.19, + "min_ms": 36.99, + "max_ms": 1192.27 + }, + "delete_gameobject": { + "n": 100, + "p50_ms": 40.93, + "p95_ms": 328.88, + "mean_ms": 124.7, + "min_ms": 34.55, + "max_ms": 811.29 + }, + "scene_info": { + "n": 100, + "p50_ms": 37.65, + "p95_ms": 334.26, + "mean_ms": 104.6, + "min_ms": 34.31, + "max_ms": 887.18 + }, + "scene_save": { + "n": 100, + "p50_ms": 131.45, + "p95_ms": 647.33, + "mean_ms": 214.7, + "min_ms": 122.29, + "max_ms": 971.45 + }, + "console": { + "n": 100, + "p50_ms": 194.53, + "p95_ms": 319.23, + "mean_ms": 167.32, + "min_ms": 36.52, + "max_ms": 796.68 + }, + "screenshot": { + "n": 100, + "p50_ms": 96.07, + "p95_ms": 404.13, + "mean_ms": 181.16, + "min_ms": 84.06, + "max_ms": 695.93 + }, + "material_search": { + "n": 100, + "p50_ms": 43.35, + "p95_ms": 548.99, + "mean_ms": 174.78, + "min_ms": 37.24, + "max_ms": 860.0 + }, + "asset_copy": { + "n": 100, + "p50_ms": 100.9, + "p95_ms": 408.95, + "mean_ms": 190.57, + "min_ms": 93.14, + "max_ms": 930.57 + }, + "asset_move": { + "n": 100, + "p50_ms": 289.69, + "p95_ms": 593.52, + "mean_ms": 255.9, + "min_ms": 85.7, + "max_ms": 1113.76 + }, + "asset_delete": { + "n": 100, + "p50_ms": 89.09, + "p95_ms": 625.86, + "mean_ms": 256.25, + "min_ms": 79.68, + "max_ms": 1146.76 + }, + "import_settings": { + "n": 100, + "p50_ms": 248.28, + "p95_ms": 578.64, + "mean_ms": 213.08, + "min_ms": 35.15, + "max_ms": 1073.07 + }, + "material_modify": { + "n": 100, + "p50_ms": 63.1, + "p95_ms": 620.2, + "mean_ms": 181.07, + "min_ms": 57.31, + "max_ms": 1244.2 + }, + "time_settings": { + "n": 100, + "p50_ms": 39.11, + "p95_ms": 581.13, + "mean_ms": 159.04, + "min_ms": 33.87, + "max_ms": 1148.61 + }, + "read_csharp": { + "n": 100, + "p50_ms": 33.51, + "p95_ms": 596.27, + "mean_ms": 131.54, + "min_ms": 29.57, + "max_ms": 1120.63 + }, + "play_until_ready": { + "n": 100, + "p50_ms": 785.33, + "p95_ms": 1403.39, + "mean_ms": 903.03, + "min_ms": 762.15, + "max_ms": 2425.41 + }, + "stop_until_ready": { + "n": 100, + "p50_ms": 672.11, + "p95_ms": 1207.18, + "mean_ms": 761.89, + "min_ms": 568.33, + "max_ms": 1878.96 + } + }, + "official": { + "editor_state": { + "n": 100, + "p50_ms": 735.68, + "p95_ms": 1118.54, + "mean_ms": 747.35, + "min_ms": 529.21, + "max_ms": 1570.94 + }, + "hierarchy": { + "n": 100, + "p50_ms": 741.8, + "p95_ms": 1446.67, + "mean_ms": 803.88, + "min_ms": 530.98, + "max_ms": 1889.92 + }, + "find_gameobject": { + "n": 100, + "p50_ms": 711.2, + "p95_ms": 1209.85, + "mean_ms": 760.51, + "min_ms": 527.79, + "max_ms": 2252.91 + }, + "transform": { + "n": 100, + "p50_ms": 851.6, + "p95_ms": 1595.39, + "mean_ms": 936.28, + "min_ms": 714.55, + "max_ms": 2171.77 + }, + "position": { + "n": 100, + "p50_ms": 571.22, + "p95_ms": 1069.88, + "mean_ms": 694.68, + "min_ms": 529.38, + "max_ms": 1671.05 + }, + "create_cube": { + "n": 100, + "p50_ms": 631.0, + "p95_ms": 1186.84, + "mean_ms": 702.18, + "min_ms": 535.32, + "max_ms": 1954.51 + }, + "add_component": { + "n": 100, + "p50_ms": 839.05, + "p95_ms": 1353.01, + "mean_ms": 915.66, + "min_ms": 714.72, + "max_ms": 2513.51 + }, + "remove_component": { + "n": 100, + "p50_ms": 865.47, + "p95_ms": 1811.9, + "mean_ms": 963.6, + "min_ms": 716.6, + "max_ms": 2349.96 + }, + "delete_gameobject": { + "n": 100, + "p50_ms": 618.58, + "p95_ms": 1333.86, + "mean_ms": 749.76, + "min_ms": 532.01, + "max_ms": 1966.6 + }, + "scene_info": { + "n": 100, + "p50_ms": 626.42, + "p95_ms": 1164.28, + "mean_ms": 719.91, + "min_ms": 528.38, + "max_ms": 1438.63 + }, + "scene_save": { + "n": 100, + "p50_ms": 731.03, + "p95_ms": 1118.06, + "mean_ms": 790.75, + "min_ms": 628.34, + "max_ms": 1586.48 + }, + "console": { + "n": 100, + "p50_ms": 608.51, + "p95_ms": 883.48, + "mean_ms": 677.94, + "min_ms": 524.29, + "max_ms": 1897.85 + }, + "screenshot": { + "n": 100, + "p50_ms": 696.99, + "p95_ms": 1092.53, + "mean_ms": 762.98, + "min_ms": 579.11, + "max_ms": 1820.82 + }, + "material_search": { + "n": 100, + "p50_ms": 672.49, + "p95_ms": 1200.97, + "mean_ms": 722.98, + "min_ms": 541.07, + "max_ms": 1439.61 + }, + "asset_copy": { + "n": 100, + "p50_ms": 773.65, + "p95_ms": 1283.73, + "mean_ms": 837.09, + "min_ms": 585.97, + "max_ms": 1840.75 + }, + "asset_move": { + "n": 100, + "p50_ms": 745.94, + "p95_ms": 1191.12, + "mean_ms": 787.75, + "min_ms": 581.2, + "max_ms": 1481.79 + }, + "asset_delete": { + "n": 100, + "p50_ms": 727.89, + "p95_ms": 1127.38, + "mean_ms": 770.42, + "min_ms": 573.56, + "max_ms": 2212.99 + }, + "import_settings": { + "n": 100, + "p50_ms": 677.56, + "p95_ms": 1136.85, + "mean_ms": 720.65, + "min_ms": 528.74, + "max_ms": 1373.52 + }, + "material_modify": { + "n": 100, + "p50_ms": 670.51, + "p95_ms": 1219.39, + "mean_ms": 749.42, + "min_ms": 546.62, + "max_ms": 1771.48 + }, + "time_settings": { + "n": 100, + "p50_ms": 675.52, + "p95_ms": 1140.79, + "mean_ms": 715.55, + "min_ms": 522.11, + "max_ms": 1751.6 + }, + "read_csharp": { + "n": 100, + "p50_ms": 657.45, + "p95_ms": 1245.12, + "mean_ms": 735.52, + "min_ms": 527.29, + "max_ms": 2094.03 + }, + "play_until_ready": { + "n": 100, + "p50_ms": 1372.78, + "p95_ms": 2092.59, + "mean_ms": 1460.37, + "min_ms": 1074.07, + "max_ms": 2701.18 + }, + "stop_until_ready": { + "n": 100, + "p50_ms": 1356.79, + "p95_ms": 2300.94, + "mean_ms": 1463.95, + "min_ms": 1079.5, + "max_ms": 2630.34 + } + } + }, + "finished_at": "2026-10-04T00:43:08.815130+00:00" +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/official-windows-summary.json b/docs/verification/issue-386/resume/official-windows-summary.json new file mode 100644 index 00000000..e5e9d9ce --- /dev/null +++ b/docs/verification/issue-386/resume/official-windows-summary.json @@ -0,0 +1,67 @@ +{ + "conditions": { + "started_at": "2026-10-04T00:00:25.043499+00:00", + "os": "Windows-11-10.0.26300-SP0", + "arch": "AMD64", + "logical_cpus": 32, + "unity": "6000.4.4f1", + "editor_pid": 34324, + "iterations": 100, + "warmup": 3, + "unity_cli_build": "native Windows debug 0.18.1", + "official_cli_version": "1.0.0-beta.11", + "pipeline_version": "0.8.0-exp.1", + "unity_cli_sha256": "087d057cd62483c3c0aa64ceb85a77421349f2ace1ba236a13c1ddcffe909d35", + "official_cli_sha256": "4cad9230dd98cc8d123d3ef9d18fef5e7ee65f353814c3cf9d94d9129293dda3", + "benchmark_sha256": "8b4a77c97260fec724a5d1187c1561a7a0f25d9c3734fe8eada1c0a3ca4bc1e6", + "windows_adapter_sha256": "c47d896f41e81c6db8ba63ced94e927388b55cc81796b54578b3135685929c8a", + "windows_adapter": "Original benchmark operations, validation, focus-discard and alternating order; Windows HWND foreground inspection and bounded reader thread replace macOS focus and POSIX select. No platform spoofing.", + "background_condition": "Owned Editor minimized, because Windows refused activation of the existing GWT background window. This differs from macOS visible-background measurements.", + "host_contention": "Other project canonical verification was active on this host; results are observations, no Windows budget or prior baseline was enforced.", + "coexistence": { + "same_project": true, + "unity_version": "6000.4.4f1", + "official_state": "ready", + "project_identity_sha256": "f87f40b8af586b040ebc3f0d64bf076a0bebf421cd38cb9af459bc31f2a0c69a" + }, + "play_settings": { + "assetNamingUsesSpace": true, + "defaultBehaviorMode": "Mode3D", + "enterPlayModeOptions": "DisableDomainReload", + "enterPlayModeOptionsEnabled": true, + "prefabModeRegularEnvironment": "None", + "prefabModeUIEnvironment": "None", + "serializationMode": "ForceText", + "unityRemote": "", + "unityRemoteCompression": "", + "unityRemoteResolution": "" + }, + "unityd_pid": 56288 + }, + "runs": [ + { + "mode": "process", + "focus": "frontmost", + "status": "PASS", + "source": "previous completed run, original conditions preserved" + }, + { + "mode": "process", + "focus": "background", + "status": "PASS", + "source": "previous completed run, original conditions preserved" + }, + { + "mode": "resident", + "focus": "frontmost", + "status": "PASS", + "error": null + }, + { + "mode": "resident", + "focus": "background", + "status": "PASS", + "error": null + } + ] +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/prefab-results.json b/docs/verification/issue-386/resume/prefab-results.json new file mode 100644 index 00000000..d1e32549 --- /dev/null +++ b/docs/verification/issue-386/resume/prefab-results.json @@ -0,0 +1,17 @@ +{ + "started_at": "2026-10-03T21:05:33.051246+00:00", + "editors": [ + { + "version": "6000.4.4f1", + "status": "PASS", + "passed": 45, + "failed": 0, + "artifacts": "\\.cache\\issue-386\\resume\\prefab-final\\existing", + "editmode": { + "passed": 22, + "failed": 0, + "runId": "2dcd238f-7de3-4150-96d2-619a59fd3afb" + } + } + ] +} diff --git a/docs/verification/issue-386/resume/prefab.txt b/docs/verification/issue-386/resume/prefab.txt new file mode 100644 index 00000000..a23600d9 --- /dev/null +++ b/docs/verification/issue-386/resume/prefab.txt @@ -0,0 +1,65 @@ +Evidence: \.cache\issue-386\resume\prefab-final +Unity 6000.4.4f1 +PASS existing create_prefab creates inherited Variant: expected 'Variant', got 'Variant' +PASS Variant and base are explicit apply targets +PASS Variant apply leaves base unchanged: expected 1, got 1.0 +PASS base edit propagates to Variant: expected 7, got 7.0 +PASS Variant override survives base edit: expected 3, got 3.0 +PASS individual property applies to base through Variant: expected 2.5, got 2.5 +PASS individual property reverts: expected 7, got 7.0 +PASS revert preserves unrelated override: expected 4, got 4.0 +PASS object override reverts: expected 2.5, got 2.5 +PASS object override applies to Variant: expected 5, got 5.0 +PASS structured property override +PASS structured added and removed components +PASS revert added component: expected False, got False +PASS revert removed component: expected True, got True +PASS structured property override +PASS structured added and removed components +PASS apply added component: expected True, got True +PASS apply removed component: expected False, got False +PASS component apply to Variant leaves base intact: expected True, got True +PASS manage_prefab_overrides rejects INVALID_APPLY_TARGET +PASS ineligible base apply fails before other overrides change: expected False, got False +PASS existing create_prefab creates inherited Variant: expected 'Variant', got 'Variant' +PASS all properties applied to Variant: expected 11, got 11.0 +PASS all addition applied to Variant: expected True, got True +PASS all removal applied to Variant: expected True, got True +PASS all property overrides reverted: expected 11, got 11.0 +PASS all removed components restored: expected True, got True +PASS all added components reverted: expected True, got True +PASS existing create_prefab creates inherited Variant: expected 'Variant', got 'Variant' +PASS all properties applied to Base: expected 11, got 11.0 +PASS all addition applied to Base: expected True, got True +PASS all removal applied to Base: expected True, got True +PASS all property overrides reverted: expected 11, got 11.0 +PASS all removed components restored: expected True, got True +PASS all added components reverted: expected True, got True +PASS Variant override persists after reload: expected 3, got 3.0 +PASS base apply persists after reload: expected 11, got 11.0 +PASS Outermost disconnects outer root +PASS Outermost reports nested connections accurately +PASS Outermost nested connection verified independently: expected True, got True +PASS Completely disconnects outer root +PASS Completely reports nested connections accurately +PASS Completely nested connection verified independently: expected False, got False +PASS unpack_prefab rejects NOT_PREFAB_INSTANCE_ROOT +PASS inactive Prefab root can be inspected +PASS focused EditMode: 22 passed, 0 failed +{ + "started_at": "2026-10-03T21:05:33.051246+00:00", + "editors": [ + { + "version": "6000.4.4f1", + "status": "PASS", + "passed": 45, + "failed": 0, + "artifacts": "\\.cache\\issue-386\\resume\\prefab-final\\existing", + "editmode": { + "passed": 22, + "failed": 0, + "runId": "2dcd238f-7de3-4150-96d2-619a59fd3afb" + } + } + ] +} diff --git a/docs/verification/issue-386/resume/process-liveness-final.txt b/docs/verification/issue-386/resume/process-liveness-final.txt new file mode 100644 index 00000000..a949810d --- /dev/null +++ b/docs/verification/issue-386/resume/process-liveness-final.txt @@ -0,0 +1,9 @@ +test_exit_code_still_active_does_not_mean_process_is_running (test_process_liveness.ProcessLivenessTests.test_exit_code_still_active_does_not_mean_process_is_running) ... ok +test_exited_process_is_not_alive_or_eligible_for_authentication (test_process_liveness.ProcessLivenessTests.test_exited_process_is_not_alive_or_eligible_for_authentication) ... ok +test_invalid_process_ids_are_not_alive_or_eligible_for_authentication (test_process_liveness.ProcessLivenessTests.test_invalid_process_ids_are_not_alive_or_eligible_for_authentication) ... ok +test_live_process_survives_authentication_and_lifecycle_probes (test_process_liveness.ProcessLivenessTests.test_live_process_survives_authentication_and_lifecycle_probes) ... ok + +---------------------------------------------------------------------- +Ran 4 tests in 0.782s + +OK diff --git a/docs/verification/issue-386/resume/python-linux.txt b/docs/verification/issue-386/resume/python-linux.txt new file mode 100644 index 00000000..1e17cc78 --- /dev/null +++ b/docs/verification/issue-386/resume/python-linux.txt @@ -0,0 +1,9 @@ +test_exit_code_still_active_does_not_mean_process_is_running (test_process_liveness.ProcessLivenessTests.test_exit_code_still_active_does_not_mean_process_is_running) ... skipped 'Windows process exit code contract' +test_exited_process_is_not_alive_or_eligible_for_authentication (test_process_liveness.ProcessLivenessTests.test_exited_process_is_not_alive_or_eligible_for_authentication) ... ok +test_invalid_process_ids_are_not_alive_or_eligible_for_authentication (test_process_liveness.ProcessLivenessTests.test_invalid_process_ids_are_not_alive_or_eligible_for_authentication) ... ok +test_live_process_survives_authentication_and_lifecycle_probes (test_process_liveness.ProcessLivenessTests.test_live_process_survives_authentication_and_lifecycle_probes) ... ok + +---------------------------------------------------------------------- +Ran 4 tests in 0.486s + +OK (skipped=1) diff --git a/docs/verification/issue-386/resume/python-windows.txt b/docs/verification/issue-386/resume/python-windows.txt new file mode 100644 index 00000000..e6967764 --- /dev/null +++ b/docs/verification/issue-386/resume/python-windows.txt @@ -0,0 +1,9 @@ +test_exit_code_still_active_does_not_mean_process_is_running (test_process_liveness.ProcessLivenessTests.test_exit_code_still_active_does_not_mean_process_is_running) ... ok +test_exited_process_is_not_alive_or_eligible_for_authentication (test_process_liveness.ProcessLivenessTests.test_exited_process_is_not_alive_or_eligible_for_authentication) ... ok +test_invalid_process_ids_are_not_alive_or_eligible_for_authentication (test_process_liveness.ProcessLivenessTests.test_invalid_process_ids_are_not_alive_or_eligible_for_authentication) ... ok +test_live_process_survives_authentication_and_lifecycle_probes (test_process_liveness.ProcessLivenessTests.test_live_process_survives_authentication_and_lifecycle_probes) ... ok + +---------------------------------------------------------------------- +Ran 4 tests in 1.493s + +OK diff --git a/docs/verification/issue-386/resume/reference-auth-green.txt b/docs/verification/issue-386/resume/reference-auth-green.txt new file mode 100644 index 00000000..46308604 --- /dev/null +++ b/docs/verification/issue-386/resume/reference-auth-green.txt @@ -0,0 +1,9 @@ + Compiling base64 v0.22.1 + Compiling unity-cli v0.18.1 () + Finished `test` profile [unoptimized + debuginfo] target(s) in 20.56s + Running unittests src\main.rs (target\debug\deps\unity_cli-6f9d4071c936636c.exe) + +running 1 test +test reference::fetcher::tests::public_refs_use_basic_authentication_for_git_http ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 555 filtered out; finished in 0.14s diff --git a/docs/verification/issue-386/resume/reference-auth-probe.json b/docs/verification/issue-386/resume/reference-auth-probe.json new file mode 100644 index 00000000..0b355727 --- /dev/null +++ b/docs/verification/issue-386/resume/reference-auth-probe.json @@ -0,0 +1,27 @@ +[ + { + "mode": "anonymous", + "exit_code": 0, + "found_branch": true + }, + { + "mode": "current-token", + "exit_code": 128, + "found_branch": false + }, + { + "mode": "current-basic", + "exit_code": 0, + "found_branch": true + }, + { + "mode": "gh-token", + "exit_code": 128, + "found_branch": false + }, + { + "mode": "gh-basic", + "exit_code": 0, + "found_branch": true + } +] \ No newline at end of file diff --git a/docs/verification/issue-386/resume/reference-auth-red.txt b/docs/verification/issue-386/resume/reference-auth-red.txt new file mode 100644 index 00000000..d7139392 --- /dev/null +++ b/docs/verification/issue-386/resume/reference-auth-red.txt @@ -0,0 +1,21 @@ + Finished `test` profile [unoptimized + debuginfo] target(s) in 0.47s + Running unittests src\main.rs (target\debug\deps\unity_cli-66a997df271e997b.exe) + +running 1 test +test reference::fetcher::tests::public_refs_use_basic_authentication_for_git_http ... FAILED + +failures: + +---- reference::fetcher::tests::public_refs_use_basic_authentication_for_git_http stdout ---- + +thread 'reference::fetcher::tests::public_refs_use_basic_authentication_for_git_http' (47892) panicked at src\reference\fetcher.rs:630:9: +Git HTTP must authenticate with username and token credentials +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + reference::fetcher::tests::public_refs_use_basic_authentication_for_git_http + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 555 filtered out; finished in 0.43s + +error: test failed, to rerun pass `--bin unity-cli` diff --git a/docs/verification/issue-386/resume/reference-fetch-summary.json b/docs/verification/issue-386/resume/reference-fetch-summary.json new file mode 100644 index 00000000..ebd9e979 --- /dev/null +++ b/docs/verification/issue-386/resume/reference-fetch-summary.json @@ -0,0 +1,26 @@ +{ + "passed": 5, + "failed": 0, + "results": [ + { + "name": "live Editor readiness", + "passed": true + }, + { + "name": "branch-only real fetch", + "passed": true + }, + { + "name": "branch-only cache reuse", + "passed": true + }, + { + "name": "omitted branch preserves cached provenance", + "passed": true + }, + { + "name": "explicit version and branch", + "passed": true + } + ] +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/reference-fetch.txt b/docs/verification/issue-386/resume/reference-fetch.txt new file mode 100644 index 00000000..a8c6a8ad --- /dev/null +++ b/docs/verification/issue-386/resume/reference-fetch.txt @@ -0,0 +1,8 @@ +Editor: {"assetsPath": "/.cache/issue-386/staff-project/Assets", "codeIndexRoot": "/.cache/issue-386/staff-project/.unity/cache/code-index", "packagesPath": "/.cache/issue-386/staff-project/Packages", "projectRoot": "/.cache/issue-386/staff-project", "unity": {"platform": "WindowsEditor", "productName": "staff-project", "unityVersion": "6000.4.4f1"}} +PASS: live Editor readiness +PASS: branch-only real fetch +PASS: branch-only cache reuse +PASS: omitted branch preserves cached provenance +PASS: explicit version and branch +Passed: 5; Failed: 0; Total: 5 +Artifacts: \.cache\issue-386\resume\reference-fixed\reference-fetch diff --git a/docs/verification/issue-386/resume/reference-longpath-green.txt b/docs/verification/issue-386/resume/reference-longpath-green.txt new file mode 100644 index 00000000..a8dec01c --- /dev/null +++ b/docs/verification/issue-386/resume/reference-longpath-green.txt @@ -0,0 +1,8 @@ + Compiling unity-cli v0.18.1 () + Finished `test` profile [unoptimized + debuginfo] target(s) in 9.02s + Running unittests src\main.rs (target\debug\deps\unity_cli-6f9d4071c936636c.exe) + +running 1 test +test reference::fetcher::tests::fetch_selected_checks_out_long_windows_paths_without_global_configuration ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 557 filtered out; finished in 2.91s diff --git a/docs/verification/issue-386/resume/reference-longpath-red.txt b/docs/verification/issue-386/resume/reference-longpath-red.txt new file mode 100644 index 00000000..9ba5ca67 --- /dev/null +++ b/docs/verification/issue-386/resume/reference-longpath-red.txt @@ -0,0 +1,22 @@ + Compiling unity-cli v0.18.1 () + Finished `test` profile [unoptimized + debuginfo] target(s) in 9.86s + Running unittests src\main.rs (target\debug\deps\unity_cli-6f9d4071c936636c.exe) + +running 1 test +test reference::fetcher::tests::fetch_selected_checks_out_long_windows_paths_without_global_configuration ... FAILED + +failures: + +---- reference::fetcher::tests::fetch_selected_checks_out_long_windows_paths_without_global_configuration stdout ---- + +thread 'reference::fetcher::tests::fetch_selected_checks_out_long_windows_paths_without_global_configuration' (24288) panicked at src\reference\fetcher.rs:564:80: +called `Result::unwrap()` on an `Err` value: git checkout failed (exit code: 128): fatal: cannot create directory at 'ModuleModuleModuleModuleModuleModuleModule/GraphToolkitGraphToolkitGraphToolkitGraphToolkit/CommandStateObserverCommandStateObserverCommandStateObserver': Filename too long +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + reference::fetcher::tests::fetch_selected_checks_out_long_windows_paths_without_global_configuration + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 557 filtered out; finished in 1.92s + +error: test failed, to rerun pass `--bin unity-cli` diff --git a/docs/verification/issue-386/resume/reference-resolution-summary.json b/docs/verification/issue-386/resume/reference-resolution-summary.json new file mode 100644 index 00000000..b9ff1516 --- /dev/null +++ b/docs/verification/issue-386/resume/reference-resolution-summary.json @@ -0,0 +1,22 @@ +{ + "passed": 4, + "failed": 0, + "results": [ + { + "name": "live Editor readiness", + "passed": true + }, + { + "name": "real project automatic fetch/status/grep", + "passed": true + }, + { + "name": "6000.4.12f1 automatic exact tag/status/grep", + "passed": true + }, + { + "name": "6000.4 explicit public ref/status/grep", + "passed": true + } + ] +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/reference-resolution.txt b/docs/verification/issue-386/resume/reference-resolution.txt new file mode 100644 index 00000000..c67a2650 --- /dev/null +++ b/docs/verification/issue-386/resume/reference-resolution.txt @@ -0,0 +1,6 @@ +PASS: live Editor readiness +PASS: real project automatic fetch/status/grep +PASS: 6000.4.12f1 automatic exact tag/status/grep +PASS: 6000.4 explicit public ref/status/grep +Passed: 4; Failed: 0; Total: 4 +Artifacts: \.cache\issue-386\resume\reference-fixed\reference-resolution diff --git a/docs/verification/issue-386/resume/rustdoc-final.txt b/docs/verification/issue-386/resume/rustdoc-final.txt new file mode 100644 index 00000000..e2bb95ea --- /dev/null +++ b/docs/verification/issue-386/resume/rustdoc-final.txt @@ -0,0 +1,3 @@ + Documenting unity-cli v0.18.1 () + Finished `dev` profile [unoptimized + debuginfo] target(s) in 9.06s + Generated \target\doc\unity_cli\index.html diff --git a/docs/verification/issue-386/resume/skills-lint-final.txt b/docs/verification/issue-386/resume/skills-lint-final.txt new file mode 100644 index 00000000..71751944 --- /dev/null +++ b/docs/verification/issue-386/resume/skills-lint-final.txt @@ -0,0 +1,5 @@ + Blocking waiting for file lock on package cache + Finished `dev` profile [unoptimized + debuginfo] target(s) in 12.26s + Running `target\debug\unity-cli.exe skills lint --severity error` + +23 skills checked, 0 violations diff --git a/docs/verification/issue-386/resume/source-snapshot.json b/docs/verification/issue-386/resume/source-snapshot.json new file mode 100644 index 00000000..5f268fca --- /dev/null +++ b/docs/verification/issue-386/resume/source-snapshot.json @@ -0,0 +1,35 @@ +{ + "recorded_at": "2026-10-04T01:35:08.912579+00:00", + "source_git_head_before_evidence_commit": "d0c5ce21d85d171b285162b06edff03acdef53c9", + "working_file_hashes": { + "Cargo.lock": "0189b962ae9a4c0d8cbf492b3994ddc964a61b7fb3684b1bda27bc5b463d887f", + "Cargo.toml": "d701e98bf9734c3bddea1f3f3bfdf49617141e598982bc09f309d09e6fe662bc", + "UnityCliBridge/Packages/unity-cli-bridge/Editor/Handlers/BakeHandler.cs": "fcec0685c04aca0a16f4151a60433f0201c5a751676733bee7f95b2f24b66ec6", + "UnityCliBridge/Packages/unity-cli-bridge/Editor/Handlers/SceneHandler.cs": "3d44351bdbeda87ffb1a432f3ac013e6c86f2709935bbc7462e01e057a3cc2f9", + "UnityCliBridge/Packages/unity-cli-bridge/Tests/Editor/Handlers/BakeHandlerTests.cs": "0297a5ce0d0679fe02a0f5108e6aded7b053978765c34d975d6d15d4df9c8673", + "UnityCliBridge/Packages/unity-cli-bridge/Tests/Editor/Handlers/SceneHandlerTests.cs": "381ffee4c4341d6ab7442523ff4e4cec82ae3d9fe8d8239de1edfbbb7bda4717", + "UnityCliBridge/Packages/unity-cli-bridge/Tests/PlayMode/InputSimulationAutomationPlayModeTests.cs": "a2dc48d02587b040e1356ebded544702a5d847ad1bb454db71bc09b39e16a44b", + "UnityCliBridge/Packages/unity-cli-bridge/Tests/PlayMode/TouchGesturePlayModeTests.cs": "c23e5769c36205ef9fbb41d13be465deab504a8d2aa312b30788928f5884a69e", + "scripts/bench-compare-official.py": "8b4a77c97260fec724a5d1187c1561a7a0f25d9c3734fe8eada1c0a3ca4bc1e6", + "scripts/bridge_auth.py": "132e3e36c2eb79e2983bdfdfdeb4d125d7b6cd8476ffaee7e85b91fdef13bf36", + "scripts/e2e-editor-lifecycle.py": "6436af1cdd7c36a40fe0d60fef708fcd07a10ad4b2ada7d6b80a1242b3596fff", + "src/app/editor.rs": "12ea2e975445003f9f47e5a8b9e62bbf9c5c7be5ca5e1393ef6bfab022c67199", + "src/app/setup.rs": "eab8bdf7cd59500812ac40c9acc104cf5a6c2c35140733e23571583a0829aa1f", + "src/app/test_runner.rs": "f8023e20459795926704614160cbb05b782f1fdc8b32e6c196d7695b38ae5691", + "src/core/failure.rs": "388e1cdd98d840f80d2bba9097ddb498ad14faf30d1c449ac633571e0c1970e5", + "src/daemon/unityd.rs": "3cbc5499fc3edb1b8ad3422a864e2e64c94a8f2be4f73f98513a4e5df55d629d", + "src/lsp/client.rs": "7c676ee0a967f79f6914140c1e147d29b58100ac5ec4fa41829b32563bbfd838", + "src/lsp/daemon.rs": "581ac8fd1f9df763069df66c0ed17d6507919ee63c52afff9741aa452f49fc7b", + "src/mcp/configure.rs": "eced95030b0b011ae2a661b4b8cec1420549064c4945aa74242cc6e38523be64", + "src/reference/fetcher.rs": "2b93e07601dae574b04ba45d7078ea68af4957dc0fc2145c6025b813617b75ba", + "src/skills/rules.rs": "8cd1c7333df34993769ec87c1fdafbb39f7a72072ef8a1ecc0c1eb04a17b6ce4", + "src/skills/tests.rs": "13a3b18495a14eec6b41cad87492481db7aa191ec963ba3651be785cbfb6a52b", + "tests/auth_warning.rs": "f777f9a364bc69a09c48b77f46a20a3eefdb2aef93e252658ec3e0c1fddaa348", + "tests/mcp.rs": "366a12d5cd72f856fe5318dc406dc020d59e0ec443313f2e5ef6ffb7e0c6f828", + "tests/scripts/test_process_liveness.py": "d6d4c51423dfee7d677c2e42922ed03bccc45c2bf9605c73f7ce7860c5634bf2", + "tests/setup_dry_run.rs": "b833e5151da71df57eba9770fa88d446a6142c605c5c56a94ae76f0e64344ea8" + }, + "latest_windows_cli_sha256": "087d057cd62483c3c0aa64ceb85a77421349f2ace1ba236a13c1ddcffe909d35", + "public_linux_cli_sha256": "f0b12f5e4815e77a7c71098903ff9e1dd86ca350dd59e06f50fa27fd256b0a8e", + "source_note": "Native working-file hashes identify the tested source plus reviewable source changes; functional suite records preserve their earlier binary hashes separately. The evidence commit is created after collection." +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/staff-binary-environment.json b/docs/verification/issue-386/resume/staff-binary-environment.json new file mode 100644 index 00000000..d77c84e2 --- /dev/null +++ b/docs/verification/issue-386/resume/staff-binary-environment.json @@ -0,0 +1,26 @@ +{ + "head": "342f499fffba1d28c6e0839cd3c109b595083841", + "source_file_sha256": { + "UnityCliBridge/Packages/unity-cli-bridge/Editor/Handlers/SceneHandler.cs": "3d44351bdbeda87ffb1a432f3ac013e6c86f2709935bbc7462e01e057a3cc2f9", + "UnityCliBridge/Packages/unity-cli-bridge/Tests/Editor/Handlers/SceneHandlerTests.cs": "381ffee4c4341d6ab7442523ff4e4cec82ae3d9fe8d8239de1edfbbb7bda4717", + "src/app/editor.rs": "12ea2e975445003f9f47e5a8b9e62bbf9c5c7be5ca5e1393ef6bfab022c67199", + "src/app/setup.rs": "02f1150b2f6bccf6e77e2b2de772190f28dfd0b7c569c3a3d6b75a405c949228", + "src/app/test_runner.rs": "f8023e20459795926704614160cbb05b782f1fdc8b32e6c196d7695b38ae5691", + "src/daemon/unityd.rs": "15b55ff881abdd288d86ab0f05dc8762bf4d8f748c8176d2b002503930b419e4", + "src/lsp/client.rs": "3986aee934cb3ef91456bc309e3414d84b58450889c14728f6e5117103f6ea04", + "src/lsp/daemon.rs": "e9dddc765c4d0ee1f464919586bf68d7e121f16f307760ffd8cae9c41f43c154", + "src/skills/tests.rs": "047a67747538d40f650a88286d31c79592a50f9b8c5262ad2093f84445821ccd", + "tests/setup_dry_run.rs": "b833e5151da71df57eba9770fa88d446a6142c605c5c56a94ae76f0e64344ea8", + "src/mcp/configure.rs": "1c9b0401180bd9f560e074cfe686af17d752e613e58df3fcec6ff48d6ad78154", + "tests/mcp.rs": "bcecb2c5333ddff5d980c9d8f62bfcd6a0e802bda8b8e18b04e213ad7c73a9c8", + "src/skills/rules.rs": "8cd1c7333df34993769ec87c1fdafbb39f7a72072ef8a1ecc0c1eb04a17b6ce4", + "src/skills/distribution.rs": "6780927176d77454bdc6a35b4ba86759ce6a3c17a21806580a70bb728c52463f", + "scripts/bridge_auth.py": "8db17ca2a62d196462d87f7c0496401864963a0e00ebc39b56a154c53f3cad2c", + "scripts/e2e-editor-lifecycle.py": "1c9dabc140a843f687c2ae38aa8828a25dd0ec6dd9c4aed41a464369e8ca5be6", + "src/reference/fetcher.rs": "6462cd154d02efb70ede92b580c96a42fe58494d6718baeba4e0436e70bcf21e", + "Cargo.toml": "dd4620b7ab39892cba9ee092439762ce98231f10fa41b8f477a67f60f9c764e0", + "Cargo.lock": "71cdc258ee55f9e495ad99b150b95b3a2da0a83c79bb55e27f822631bb2142cd" + }, + "binary_sha256": "f51a12aa3ec63237a3185dceb4635758b35f4c9f4a37884c2a05a04d6a74998b", + "note": "The running staff suites use the binary built from this committed source. The later Git HTTP authentication fix is being validated separately; unsuccessful rebuilds did not replace this binary." +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/staff-extra-results.json b/docs/verification/issue-386/resume/staff-extra-results.json new file mode 100644 index 00000000..ca473d1a --- /dev/null +++ b/docs/verification/issue-386/resume/staff-extra-results.json @@ -0,0 +1,126 @@ +[ + { + "name": "prefab", + "command": [ + "py", + "-3", + "-X", + "utf8", + "-B", + "scripts/e2e-prefab.py", + "--unity-cli", + "\\target\\debug\\unity-cli.exe", + "--project-root", + "\\.cache\\issue-386\\staff-project", + "--port", + "6487", + "--output", + "\\.cache\\issue-386\\resume\\prefab-final", + "--editmode" + ], + "started_at": "2026-10-03T21:05:32.803502+00:00", + "exit_code": 0, + "finished_at": "2026-10-03T21:07:27.701078+00:00" + }, + { + "name": "timeline", + "command": [ + "py", + "-3", + "-X", + "utf8", + "-B", + "scripts/e2e-timeline.py", + "--unity-cli", + "\\target\\debug\\unity-cli.exe", + "--port", + "6487" + ], + "started_at": "2026-10-03T21:07:27.701498+00:00", + "exit_code": 0, + "finished_at": "2026-10-03T21:07:38.628970+00:00" + }, + { + "name": "eval", + "command": [ + "py", + "-3", + "-X", + "utf8", + "scripts/e2e-eval.py", + "--unity-cli", + "\\target\\debug\\unity-cli.exe", + "--port", + "6487", + "--soak-iterations", + "1000" + ], + "started_at": "2026-10-03T21:07:38.629402+00:00", + "exit_code": 0, + "finished_at": "2026-10-03T21:25:25.741501+00:00" + }, + { + "name": "bake", + "command": [ + "py", + "-3", + "-X", + "utf8", + "-B", + "scripts/e2e-bake.py", + "--unity-cli", + "\\target\\debug\\unity-cli.exe", + "--port", + "6487", + "--project-root", + "\\.cache\\issue-386\\staff-project" + ], + "started_at": "2026-10-03T21:25:25.741912+00:00", + "exit_code": 1, + "finished_at": "2026-10-03T21:25:28.565921+00:00" + }, + { + "name": "domain-reload", + "command": [ + "py", + "-3", + "-X", + "utf8", + "-B", + "scripts/e2e-test-domain-reload.py", + "--cli", + "\\target\\debug\\unity-cli.exe", + "--port", + "6487", + "--output", + "\\.cache\\issue-386\\resume\\domain-reload.json" + ], + "started_at": "2026-10-03T21:25:28.566314+00:00", + "exit_code": 0, + "finished_at": "2026-10-03T21:25:44.845566+00:00" + }, + { + "name": "player-build", + "command": [ + "py", + "-3", + "-X", + "utf8", + "-B", + "scripts/e2e-player-build.py", + "--cli", + "\\target\\debug\\unity-cli.exe", + "--unity", + "C:/Program Files/Unity/Hub/Editor/6000.4.4f1/Editor/Unity.exe", + "--project-path", + "\\.cache\\issue-386\\staff-project", + "--port", + "6487", + "--target", + "StandaloneWindows64" + ], + "started_at": "2026-10-03T21:25:44.846047+00:00", + "exit_code": 1, + "finished_at": "2026-10-03T21:25:55.110575+00:00" + } +] \ No newline at end of file diff --git a/docs/verification/issue-386/resume/staff-final-operations.json b/docs/verification/issue-386/resume/staff-final-operations.json new file mode 100644 index 00000000..7edc3aa3 --- /dev/null +++ b/docs/verification/issue-386/resume/staff-final-operations.json @@ -0,0 +1,140 @@ +[ + { + "name": "editor_state", + "tool": "get_editor_state", + "status": "PASS", + "elapsed_seconds": 0.268 + }, + { + "name": "hierarchy", + "tool": "get_hierarchy", + "status": "PASS", + "elapsed_seconds": 0.038 + }, + { + "name": "find_gameobject", + "tool": "find_gameobject", + "status": "PASS", + "elapsed_seconds": 0.036 + }, + { + "name": "transform", + "tool": "get_component_values", + "status": "PASS", + "elapsed_seconds": 0.039 + }, + { + "name": "position", + "tool": "modify_gameobject", + "status": "PASS", + "elapsed_seconds": 0.039 + }, + { + "name": "create_cube", + "tool": "create_gameobject", + "status": "PASS", + "elapsed_seconds": 0.063 + }, + { + "name": "add_component", + "tool": "add_component", + "status": "PASS", + "elapsed_seconds": 0.049 + }, + { + "name": "remove_component", + "tool": "remove_component", + "status": "PASS", + "elapsed_seconds": 0.045 + }, + { + "name": "delete_gameobject", + "tool": "delete_gameobject", + "status": "PASS", + "elapsed_seconds": 0.039 + }, + { + "name": "scene_info", + "tool": "get_scene_info", + "status": "PASS", + "elapsed_seconds": 0.038 + }, + { + "name": "scene_save", + "tool": "save_scene", + "status": "PASS", + "elapsed_seconds": 0.325 + }, + { + "name": "console", + "tool": "read_console", + "status": "PASS", + "elapsed_seconds": 0.046 + }, + { + "name": "screenshot", + "tool": "capture_screenshot", + "status": "PASS", + "elapsed_seconds": 0.099 + }, + { + "name": "material_search", + "tool": "manage_asset_database", + "status": "PASS", + "elapsed_seconds": 0.043 + }, + { + "name": "asset_copy", + "tool": "manage_asset_database", + "status": "PASS", + "elapsed_seconds": 0.07 + }, + { + "name": "asset_move", + "tool": "manage_asset_database", + "status": "PASS", + "elapsed_seconds": 0.063 + }, + { + "name": "asset_delete", + "tool": "manage_asset_database", + "status": "PASS", + "elapsed_seconds": 0.305 + }, + { + "name": "import_settings", + "tool": "manage_asset_import_settings", + "status": "PASS", + "elapsed_seconds": 0.04 + }, + { + "name": "material_modify", + "tool": "modify_material", + "status": "PASS", + "elapsed_seconds": 0.055 + }, + { + "name": "time_settings", + "tool": "get_project_settings", + "status": "PASS", + "elapsed_seconds": 0.038 + }, + { + "name": "read_csharp", + "tool": "read", + "status": "PASS", + "elapsed_seconds": 0.06 + }, + { + "name": "play_until_ready", + "tool": "play_game", + "status": "PASS", + "elapsed_seconds": 0.739 + }, + { + "name": "stop_until_ready", + "tool": "stop_game", + "status": "PASS", + "elapsed_seconds": 0.429 + } +] \ No newline at end of file diff --git a/docs/verification/issue-386/resume/staff-final-summary.json b/docs/verification/issue-386/resume/staff-final-summary.json new file mode 100644 index 00000000..7f2b0e4b --- /dev/null +++ b/docs/verification/issue-386/resume/staff-final-summary.json @@ -0,0 +1,646 @@ +{ + "started_at": "2026-10-03T20:31:49.968912+00:00", + "source_commit": "0458d7fa83d55a3e77cb833ba74c705b65927a30", + "binary_sha256": "0038934812c1881055a67f05e463719dac55813293402991e78ba75aa63dfd7a", + "cases": { + "staff-play-settings": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "editor", + "eval", + "\nvar before = new { enabled = UnityEditor.EditorSettings.enterPlayModeOptionsEnabled,\n options = UnityEditor.EditorSettings.enterPlayModeOptions.ToString() };\nUnityEditor.EditorSettings.enterPlayModeOptionsEnabled = true;\nUnityEditor.EditorSettings.enterPlayModeOptions = UnityEditor.EnterPlayModeOptions.DisableDomainReload;\nvar assembly = typeof(UnityEditor.EditorWindow).Assembly;\nvar game = assembly.GetType(\"UnityEditor.GameView\", true);\nUnityEditor.EditorWindow.GetWindow(game, false, \"Game\", false);\nvar type = assembly.GetType(\"UnityEditor.PlayModeView\", true);\nvar property = type.GetProperty(\"enterPlayModeBehavior\");\nforeach (var view in UnityEngine.Resources.FindObjectsOfTypeAll(type))\n property.SetValue(view, System.Enum.Parse(property.PropertyType, \"PlayUnfocused\"));\nreturn before;\n", + "--mode", + "statements" + ], + "exit_code": 0, + "elapsed_seconds": 0.56, + "success": true + }, + "staff-get_editor_state-1": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_editor_state", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.081, + "success": true + }, + "staff-create_scene-2": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "create_scene", + "--json", + "{\"sceneName\": \"Issue386_Staff_1791059510766711200\", \"path\": \"Assets/Scenes/Generated/E2E/Performance\", \"loadScene\": true}" + ], + "exit_code": 0, + "elapsed_seconds": 0.143, + "success": true + }, + "staff-create_gameobject-3": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "create_gameobject", + "--json", + "{\"name\": \"Perf394Target\", \"primitiveType\": \"cube\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.18, + "success": true + }, + "staff-create_material-4": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "create_material", + "--json", + "{\"materialPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfSource.mat\", \"shader\": \"Unlit/Color\", \"overwrite\": true}" + ], + "exit_code": 0, + "elapsed_seconds": 0.074, + "success": true + }, + "staff-save_scene-5": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "save_scene", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.293, + "success": true + }, + "staff-get_editor_state-6": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_editor_state", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.267, + "success": true + }, + "staff-get_hierarchy-7": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_hierarchy", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.038, + "success": true + }, + "staff-find_gameobject-8": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "find_gameobject", + "--json", + "{\"name\": \"Perf394Target\", \"exactMatch\": true}" + ], + "exit_code": 0, + "elapsed_seconds": 0.036, + "success": true + }, + "staff-get_component_values-9": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_component_values", + "--json", + "{\"gameObjectName\": \"Perf394Target\", \"componentType\": \"Transform\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.039, + "success": true + }, + "staff-modify_gameobject-10": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "modify_gameobject", + "--json", + "{\"path\": \"/Perf394Target\", \"position\": {\"x\": 1, \"y\": 2, \"z\": 3}}" + ], + "exit_code": 0, + "elapsed_seconds": 0.039, + "success": true + }, + "staff-create_gameobject-11": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "create_gameobject", + "--json", + "{\"name\": \"Perf394Cube\", \"primitiveType\": \"cube\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.063, + "success": true + }, + "staff-add_component-12": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "add_component", + "--json", + "{\"gameObjectPath\": \"/Perf394Cube\", \"componentType\": \"Rigidbody\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.049, + "success": true + }, + "staff-remove_component-13": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "remove_component", + "--json", + "{\"gameObjectPath\": \"/Perf394Cube\", \"componentType\": \"Rigidbody\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.044, + "success": true + }, + "staff-delete_gameobject-14": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "delete_gameobject", + "--json", + "{\"path\": \"/Perf394Cube\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.039, + "success": true + }, + "staff-get_scene_info-15": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_scene_info", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.038, + "success": true + }, + "staff-save_scene-16": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "save_scene", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.325, + "success": true + }, + "staff-read_console-17": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "read_console", + "--json", + "{\"count\": 20}" + ], + "exit_code": 0, + "elapsed_seconds": 0.045, + "success": true + }, + "staff-capture_screenshot-18": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "capture_screenshot", + "--json", + "{\"captureMode\": \"game\", \"width\": 1280, \"height\": 720, \"includeUI\": false, \"encodeAsBase64\": false, \"osFallback\": false}" + ], + "exit_code": 0, + "elapsed_seconds": 0.098, + "success": true + }, + "staff-manage_asset_database-19": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "manage_asset_database", + "--json", + "{\"action\": \"find_assets\", \"filter\": \"t:Material\", \"searchInFolders\": [\"Assets/Scenes/Generated/E2E/Performance\"]}" + ], + "exit_code": 0, + "elapsed_seconds": 0.042, + "success": true + }, + "staff-manage_asset_database-20": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "manage_asset_database", + "--json", + "{\"action\": \"copy_asset\", \"fromPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfSource.mat\", \"toPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfCopy.mat\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.069, + "success": true + }, + "staff-manage_asset_database-21": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "manage_asset_database", + "--json", + "{\"action\": \"move_asset\", \"fromPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfCopy.mat\", \"toPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfMoved.mat\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.063, + "success": true + }, + "staff-manage_asset_database-22": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "manage_asset_database", + "--json", + "{\"action\": \"delete_asset\", \"assetPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfMoved.mat\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.305, + "success": true + }, + "staff-manage_asset_import_settings-23": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "manage_asset_import_settings", + "--json", + "{\"action\": \"get\", \"assetPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfSource.mat\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.039, + "success": true + }, + "staff-modify_material-24": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "modify_material", + "--json", + "{\"materialPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfSource.mat\", \"properties\": {\"_Color\": [0.2, 0.4, 0.8, 1]}}" + ], + "exit_code": 0, + "elapsed_seconds": 0.054, + "success": true + }, + "staff-get_project_settings-25": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_project_settings", + "--json", + "{\"includeTime\": true, \"includePlayer\": false}" + ], + "exit_code": 0, + "elapsed_seconds": 0.037, + "success": true + }, + "staff-read-26": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "read", + "--json", + "{\"path\": \"Packages/com.akiojin.unity-cli-bridge/Editor/Core/UnityCliBridgeHost.cs\", \"maxLines\": 50}" + ], + "exit_code": 0, + "elapsed_seconds": 0.059, + "success": true + }, + "staff-play_game-27": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "play_game", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.3, + "success": true + }, + "staff-get_editor_state-28": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_editor_state", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.043, + "success": true + }, + "staff-get_editor_state-29": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_editor_state", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.035, + "success": true + }, + "staff-get_editor_state-30": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_editor_state", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.036, + "success": true + }, + "staff-get_editor_state-31": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_editor_state", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.293, + "success": true + }, + "staff-stop_game-32": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "stop_game", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.042, + "success": true + }, + "staff-get_editor_state-33": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_editor_state", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.142, + "success": true + }, + "staff-get_editor_state-34": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_editor_state", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.233, + "success": true + } + }, + "play_settings": { + "enterPlayModeOptionsEnabled": true, + "enterPlayModeOptions": "DisableDomainReload", + "enterPlayModeBehavior": "PlayUnfocused", + "previous": { + "enabled": true, + "options": "DisableDomainReload" + } + }, + "finished_at": "2026-10-03T20:31:54.429601+00:00" +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/staff-scope-reconstruction.md b/docs/verification/issue-386/resume/staff-scope-reconstruction.md new file mode 100644 index 00000000..00c38caf --- /dev/null +++ b/docs/verification/issue-386/resume/staff-scope-reconstruction.md @@ -0,0 +1,144 @@ +# Issue #386: reconstructed staff coverage and Windows execution entrypoints + +Read-only scope investigation, 2026-10-04. The original +`project-state/pm-scratch/staff-report.md` has **not been obtained**. Its text, +original row order, precise ○/△/— marks, all positive scenarios, and attachment +identity cannot be guaranteed by this reconstruction. Do not mark AC-5 complete +solely because the rows below pass. + +The following **13 verification categories** consolidate primary Issues +[#243–260](https://github.com/akiojin/unity-cli/issues/243), plus +[#390–395](https://github.com/akiojin/unity-cli/issues/390). This grouping is an +inference for managing coverage, not a claim to reproduce the original report's +13 rows. #393 explicitly says the report had 13 △/— rows, of which 12 had been +implemented by v0.13–v0.15. Original issues record the actual Windows investigation +on 2026-09-26; #390–395 describe the report received on 2026-09-30. Both dates +belong in provenance, rather than silently treating them as the same event. + +| Reconstructed category | Primary source and original expected behavior | Current verification entrypoint | Windows fixture/package/module requirements | Coverage beyond the public 23 operations | +| --- | --- | --- | --- | --- | +| 1. Keyboard / gamepad / touch simulation | #243: keyboard hold duration uses elapsed seconds at 30/60/120/unlimited fps; original measurement also compared physical-priority and isolated Keyboard, absent/0.2/1/2-second holds, three repeats (72 trials). #245: tap/swipe occupy multiple game frames without blocking Update. #246: processed individual stick axes match zero, single-axis, diagonal and maximum requests. #393 names this combined feature row. | Real PlayMode fixtures `InputSimulationAutomationPlayModeTests` (including four fps hold cases), `TouchGesturePlayModeTests`, `GamepadStickInputPlayModeTests`; `scripts/e2e-input-tools.sh` for TCP input calls. The original observation C# source is embedded verbatim in fetched `243.md`/`244.md`/`245.md`/`246.md`; use its `Issue Repro/Setup`, Configure, Reset, Snapshot and Positive menus to reproduce original trials. | `com.unity.inputsystem` 1.19.0 for the reported stream, activeInputHandler Both or Input System, game Update running, InputSystem focus routing. Input UI script additionally needs UGUI, `UnityCliInputTestSceneGenerator.cs`, `UnityCliInputSimulationTestBootstrap.cs`, `InputStateDisplay.cs`; generated scenes remain inside the disposable project's `Assets/Scenes/Generated/E2E`. | None of the input variants is among the 23 benchmark operations. Basic command success alone does not prove the original 72 duration trials or game-frame observations. | +| 2. InputAction callback notification | #244: pre-enabled PassThrough actions must receive both press=1 and release=0 for keyboard, mouse and gamepad, regardless of Editor/Dynamic update timing. Positive QueueStateEvent control must still notify. | `InputActionNotificationTests` real EditMode suite; original `IssueInputProbe` records callbacks with frame, time and InputState currentUpdateType. The Input Tools script observes device states but is not a replacement for callback evidence. | Input System; observer must be active before the CLI input. Test 30/120/unlimited fps and compare positive controls. | Not measured by the 23 operations. | +| 3. Input Actions type and persistence | #247: both create_action_map and add_input_action preserve Button/PassThrough/Value. #248: JSON source, memory state, reimport and full Editor restart agree. | `InputActionsHandlerTests` has all type cases for both creation paths; `InputActionsPersistenceTests` checks 10 edit variants and negative cases. `scripts/e2e-input-actions-persistence.py` performs disk/reimport/restart verification (50 assertions in macOS evidence). | Input System, Newtonsoft.Json, package listed in manifest testables. Standalone dedicated fixture with `UnityCliInputBatchHost.cs`; **no live Editor already using that project or its selected port**. Supply --unity-path and --project-path explicitly. | Asset copy/move/delete benchmarks do not exercise .inputactions source rewriting. Persistence E2E adds Button on map creation and Value via add; also run full type cases to cover PassThrough. | +| 4. Video recording formats | #249: mp4/webm/png_sequence must correspond to actual file headers; returned outputPath exists, PNG sequence contains multiple frames. | Python payload embedded in `scripts/e2e-video-formats.sh`, six named tests, validates MP4/WebM/PNG signatures and session lifecycle. | `com.unity.recorder` 5.1.6 for Unity 6000.4, Game View with a rendered Camera, graphics-enabled real Editor. Native Python extraction of the heredoc is appropriate; Linux Python plus Windows CLI cannot use Linux params-file paths. | Screenshot benchmark does not prove recording or any video format. | +| 5. PlayMode test results and Domain Reload | #250: two real FrameAdvances/RigidbodyFalls tests finish with Domain Reload enabled and disabled, with Scene Reload preserved. #251: totals count exactly two leaf tests, not fixture/assembly/root suites. | `scripts/e2e-test-domain-reload.py` against existing listener, **without --batch-host on Windows**; it exercises both settings and checks leaf counts. Focused real tests: `DomainReloadResultTests`, `TestResultCountingPlayModeTests`; collector/persistence unit tests separately. | `com.unity.test-framework`, package in `testables`, `DomainReloadE2ESettings.cs` menus available. Existing listener mode avoids lsof. The script restores settings. Do not run the full Bridge EditMode suite through the Bridge's own TestExecutionHandler: handler tests deliberately replace/reset the same static state. Use Unity's external native test runner for that suite. | Benchmark Play/Stop readiness is not run_tests/get_test_status and does not prove Domain Reload result recovery or counts. | +| 6. C# reference source resolution | #252: project version 6000.4.12f1 plus explicit branch 6000.4 works. #254: discover exact public tag / explicit branch, retain ref/commit provenance, never silently substitute an unrelated minor. | Python payloads embedded in `scripts/e2e-reference-fetch.sh` (5 checks) and `scripts/e2e-reference-resolution.sh` (4 checks), real Editor readiness plus isolated project-version fixtures and caches. | Network, native Git, license acceptance already requested by these suites; scratch cache only. Native Python must own the temp files supplied to the Windows CLI. No extra Unity package required. | `read_csharp` benchmark is local file reading; it does not exercise reference source acquisition, public ref selection or provenance. | +| 7. unityd on-demand / idle recovery and latency | #253: ordinary operations start a stopped daemon; recover after idle exit; concurrent first calls start only one daemon; preserve endpoint and report cold/warm costs. #394 adds performance regression coverage. | `scripts/e2e-unityd.py` owns its Editor but hardcodes the repository UnityCliBridge project: use its logic in a dedicated copied fixture, not that launch entrypoint against the live checkout. `scripts/bench-eval.py` can run native Windows without --require-frontmost/--activate; use 100 samples and explicit CLI/port. | Dedicated tools root; normal CLI daemon path; own project/port. Windows foreground observation requires a Windows implementation rather than the script's macOS osascript/lsof checks. | Existing 23 calls demonstrate successful ordinary operations, not concurrent cold-start / idle recovery. One sample per operation is not a performance comparison. | +| 8. Animation numeric curves | #255: localPosition.x keys 0s=0 and 1s=2, interpolation, key editing/removal, reject unsupported bindings, saved asset persists. | `scripts/e2e-animation-curves.sh` against existing listener; `AnimationCurveHandlerTests`. Port its shell assertions or run Git Bash with jq and native paths; its launch wrapper is macOS oriented. | Animation module, Newtonsoft.Json, disposable asset path. No optional package; jq required by shell runner. | Not covered by the 23 operations. | +| 9. Timeline track / clip / binding editing | #256: Animation Track with start/duration/binding, save/reload persistence, PlayableDirector evaluation reaches expected Animator pose, explicit unsupported-track/package errors. | `scripts/e2e-timeline.py` is native Windows compatible with existing listener and explicit --unity-cli / --port. `TimelineHandlerTests` separately. | `com.unity.timeline` 1.8.12, animation/director modules, `UnityCliTimelineE2EFixture.cs` copied into isolated Assets/Editor. Current full suite also calls capture_video_status, so Recorder is needed; --without-timeline expects both Timeline and Recorder missing. | Not covered by the 23 operations. | +| 10. In-Editor C# eval and caching | #257: numeric3, scene object read/create/modify, syntax error vs runtime exception, no persistent .cs file required. #391: correct reference invalidation across domain/new assembly and 1000 evals within memory/assembly bounds, plus 100-sample latency. | `scripts/e2e-eval.py` is native Windows compatible; default --soak-iterations1000, explicit CLI/port. `scripts/bench-eval.py` measures 100 samples; omit macOS-only focus flags. | Roslyn bundled with Bridge, graphics or batch listener. Set UNITY_PROJECT_ROOT to owned fixture. Its no-source-write assertion snapshots repository UnityCliBridge, so independently inspect the actual selected fixture when claiming AC-5 no persistent C# writes. | Benchmark eval1+2 is only one successful sample, not error contracts, objects, invalidation, soak or performance. | +| 11. Play Mode method hot reload | #258/#390: change existing calculation without stopping Play or losing scene/object/HP/score/state; invalid source, stale revision and partial/unobserved patch must not be successful. | `scripts/e2e-hot-reload.py --project ... --unity-cli ... --port ... --expect supported --require-arch X64`; prepare an isolated fixture from the existing batch-host wrapper. | **FastScriptReload 1.8.0**, separately installed at pinned commit `51140b71d9e5df1de231b33ec20ee089b18bebec`, plus copied `tests/fixtures/hot-reload/HotReloadProbe.cs` and `HotReloadE2EFixture.cs`. Disable FSR automatic/on-demand reload as documented. Adapter code allows X64 on Windows; ARM64 is limited to macOS. | Missing-package or unsupported-platform error-contract PASS does not prove real method replacement. No benchmark coverage. | +| 12. Lighting / navigation / occlusion bake | #259/#392: actual lightmap data plus saved scene references; legacy NavMesh and NavMeshSurface distinct; SamplePosition / path usable; Occlusion data assigned; failed/empty/no-output cases cannot report success. | `scripts/e2e-bake.py --unity-cli ... --project-root ... --port ... --targets lighting,navmesh-legacy,navmesh-surface,occlusion`; `UnityCliBakeE2EFixture.cs` creates/validates isolated bake scenes. | `com.unity.ai.navigation` 2.0.13, AI/terrain/lighting modules, fixture Editor source. **Graphics enabled** for real lightmap bake, not -nographics. Test legacy support for selected Unity; an UNSUPPORTED error is separate from a successful bake. | No benchmark coverage. Job acceptance alone is not generated/persisted artifact proof. | +| 13. Windows Player build / launch | #260/#392: .exe, _Data and BuildReport paths agree; execute generated Player; distinguish headless process from actual rendered game/input; preserve settings; errors are failures. | `scripts/e2e-player-build.py --cli ... --unity ... --project-path ... --target StandaloneWindows64` on existing listener; dedicated --launch --isolated-project mode adds compiler/build-failure/interruption cases. Safe Windows auth helper has been fixed in this worktree. | Windows Standalone Build Support for selected Editor, writable scratch output, saved minimal scene. Use --isolated-project with --launch to avoid Unix fcntl branch. Existing module probing looks under editor.parent.parent/PlaybackEngines; audit native Hub Editor/Data layout. | Script validates Windows artifacts but currently only launches the generated Player for StandaloneOSX. Windows headless and graphical/input launch observations require additional actual execution; script's final "Windows hardware pending" must not be misreported as verified. | + +## Additional known original positive row + +Issue #395 explicitly quotes the original report's **Prefab creation/placement/editing** +row as ○ for both products, with only direct editing/Prefab Mode save verified on +unity-cli and Variant/Overrides/Unpack verified on official CLI. This row is +outside the inferred 13 △/— categories above and illustrates why the missing +complete report still matters. Native existing-listener `scripts/e2e-prefab.py` +adds 45 meaningful runtime assertions plus 22 focused EditMode tests, covering +Variant inheritance, preserved overrides, apply destinations, individual/whole +revert/apply, and Outermost/Completely semantics. No optional Unity package is +needed. Supply --project-root, --unity-cli, --port and new --output; omit --launch +because its launch path and ownership lsof are macOS specific. + +## Native Windows commands for an already prepared owned listener + +These are reviewable commands, **not evidence that they have been executed**. +The owner must set the process-local UNITY_PROJECT_ROOT, UNITY_CLI_TOOLS_ROOT, +UNITY_CLI_NO_AUTO_UPDATE and any owned lockfile directory consistently. Invoke +all shell wrappers using `bash -lc` and the repository workdir as required. + +```text +py.exe -3 -X utf8 -B scripts/e2e-prefab.py --unity-cli /target/debug/unity-cli.exe --project-root /.cache/issue-386/red-project --port 6487 --output /.cache/issue-386/staff-prefab-final --editmode + +py.exe -3 -X utf8 -B scripts/e2e-eval.py --unity-cli /target/debug/unity-cli.exe --port 6487 --soak-iterations 1000 + +py.exe -3 -X utf8 -B scripts/e2e-timeline.py --unity-cli /target/debug/unity-cli.exe --port 6487 + +py.exe -3 -X utf8 -B scripts/e2e-bake.py --unity-cli /target/debug/unity-cli.exe --project-root /.cache/issue-386/red-project --port 6487 --targets lighting,navmesh-legacy,navmesh-surface,occlusion + +py.exe -3 -X utf8 -B scripts/e2e-test-domain-reload.py --cli /target/debug/unity-cli.exe --port 6487 --output /.cache/issue-386/staff-domain-reload.json + +py.exe -3 -X utf8 -B scripts/bench-eval.py --unity-cli /target/debug/unity-cli.exe --port 6487 --iterations 100 --warmup 3 --out /.cache/issue-386/staff-eval-100.json + +py.exe -3 -X utf8 -B scripts/e2e-player-build.py --cli /target/debug/unity-cli.exe --unity C:/Program\ Files/Unity/Hub/Editor/6000.4.4f1/Editor/Unity.exe --project-path /.cache/issue-386/red-project --port 6487 --target StandaloneWindows64 +``` + +For Input Actions restart E2E, close any Editor using **that dedicated copied +fixture only**, then call: + +```text +py.exe -3 -X utf8 -B scripts/e2e-input-actions-persistence.py --unity-cli /target/debug/unity-cli.exe --unity-path "C:/Program Files/Unity/Hub/Editor/6000.4.4f1/Editor/Unity.exe" --project-path /.cache/issue-386/staff-persistence-project --port 6489 +``` + +Use the actual installed Editor path; the path above is illustrative. The owner +uses a process argument array, so shell backslash escaping is unnecessary there. +For video/reference scripts whose Python bodies are heredocs, extract the body +without changing assertions, set UNITY_CLI_BIN, and run it through native Python +with native Windows artifact/project/CLI paths. Keep original source hash and +extraction hash in the evidence. Running Linux Python with native CLI params-file +paths creates false failures. The macOS e2e-matrix entrypoint cannot be directly +claimed Windows-compatible: Hub layout, lsof, osascript and os.killpg are embedded. + +## Safety repair performed during this investigation + +`scripts/bridge_auth.py` now shares `process_alive()` with +`scripts/e2e-editor-lifecycle.py`. Windows uses OpenProcess with SYNCHRONIZE, +WaitForSingleObject(timeout0) and closes the handle. Unix preserves signal-zero +existence behavior, with invalid/out-of-range PID rejection. + +The original Windows Python signal-zero path is **not an observation**: +CPython 3.14 maps zero to CTRL_C_EVENT and calls GenerateConsoleCtrlEvent; with +nonzero target PID it can succeed without observing the process. It therefore +reported already exited children as alive and selected stale credentials. +PID zero broadcasts a console event. The first exploratory RED was interrupted +by that behavior; the formal safe RED uses only already exited owned child PIDs. +No Editor PID was passed to these regression tests. + +- Formal RED: `process-liveness-exited-red.txt`, child-based authentication and + lifecycle checks both fail because an exited child is considered live, exit1. +- Windows GREEN: `process-liveness-green.txt`, 4/4 tests; existing auth tests + `bridge-auth-green.txt`, 3/3. +- Linux regression: `process-liveness-linux.txt`, 3 PASS / 1 Windows-specific + exit-code skip; existing auth3/3 PASS. +- New tests cover a live child surviving both probes, exited child rejection, + zero/negative/nonrepresentable IDs, and Windows child exit259, which must not be + confused with STILL_ACTIVE. No source commit was made by this investigator. + +Primary runtime references: +[CPython os.kill implementation](https://github.com/python/cpython/blob/3.14/Modules/posixmodule.c#L9067) +and [Microsoft GenerateConsoleCtrlEvent semantics](https://learn.microsoft.com/en-us/windows/console/generateconsolectrlevent). + +## Canonical verification / PM handoff ruling provenance + +The exact clause "canonical verify.run が他の holder のホスト排他で待たされる場合は +待たず、PR の CI を最終確認とする。push したら Board で『PR作成可』と引き継ぐ。 +PR は PM が作成する" appears in the live owner-authored **Issue bodies #390–395**, +under Notes. #390/#391/#393 comments explicitly applied it to their own work. +Issue #392 author is akiojin; body last updated 2026-09-30T11:48:06Z in this snapshot. + +This proves a ruling shared by that Issue batch. It does **not** establish a +project-wide permanent override, and #386's current body has no such clause. +It does not authorize bypassing #386's blocked execution.reopen or protected +verification records. Ask the PM for a #386-specific ruling if needed; preserve +direct local PASS evidence while canonical tooling recovery is coordinated. + +## Original-report search result + +Parent's filename searches covered the worktree, E:/unity-cli, E:/gwt and user +home. Additional investigation found no matching tracked file in `git log --all +-- '*staff*report*' '*pm-scratch*' '*project-state*'`. GitHub code search for +staff-report in akiojin/unity-cli found only `scripts/bench-editor-ops.py`, not the +report. Issue-body search found references, not an attached complete report. +Fetched primary issue snapshots and complete comments remain in this directory +as `.json` / `.md`, and the pre-implementation scenario summaries +are in `original-scenarios.md`. + +Next verification should run the portable focused suites on prepared isolated +Windows fixtures and record each category's actual PASS/FAIL/UNSUPPORTED plus +raw evidence. Keep the completeness comparison and original positive feature +rows pending until the original report is supplied or the owner explicitly +rules that a reconstructed scope replaces it. diff --git a/docs/verification/issue-386/resume/timeline.txt b/docs/verification/issue-386/resume/timeline.txt new file mode 100644 index 00000000..3cc6ab31 --- /dev/null +++ b/docs/verification/issue-386/resume/timeline.txt @@ -0,0 +1,42 @@ +PASS get_editor_info {"assetsPath": "/.cache/issue-386/staff-project/Assets", "codeIndexRoot": "/.cache/issue-386/staff-project/.unity/cache/code-index", "packagesPath": "/.cache/issue-386/staff-project/Packages", "projectRoot": "/.cache/issue-386/staff-project", "unity": {"platform": "WindowsEditor", "productName": "staff-project", "unityVersion": "6000.4.4f1"}} +Unity version: 6000.4.4f1 +PASS capture_video_status {"isRecording": false} +PASS execute_menu_item {"executed": true, "executionTime": 403, "menuExists": true, "menuPath": "Tools/Unity CLI/Timeline/Generate E2E Fixture", "message": "Menu item executed successfully", "success": true} +PASS fixture menu executed +PASS manage_timeline {"action": "create_asset", "assetPath": "Assets/Scenes/Generated/E2E/Timeline/Sequence-78b703c10f90467aa56906709bbbbd94.playable", "directorPath": null, "tracks": []} +PASS manage_timeline {"action": "assign_director", "assetPath": "Assets/Scenes/Generated/E2E/Timeline/Sequence-78b703c10f90467aa56906709bbbbd94.playable", "directorPath": "/TimelineDirector", "tracks": []} +PASS manage_timeline {"action": "create_track", "assetPath": "Assets/Scenes/Generated/E2E/Timeline/Sequence-78b703c10f90467aa56906709bbbbd94.playable", "directorPath": null, "trackId": "9e72b0320f47758408c175009c832bea:-8359094986150629512", "tracks": [{"binding": null, "clips": [], "name": "Motion", "trackId": "9e72b0320f47758408c175009c832bea:-8359094986150629512", "type": "AnimationTrack"}]} +PASS manage_timeline {"action": "add_clip", "assetPath": "Assets/Scenes/Generated/E2E/Timeline/Sequence-78b703c10f90467aa56906709bbbbd94.playable", "clipIndex": 0, "directorPath": null, "tracks": [{"binding": null, "clips": [{"animationClipPath": "Assets/Scenes/Generated/E2E/Timeline/Motion.anim", "duration": 2.0, "index": 0, "start": 1.0}], "name": "Motion", "trackId": "9e72b0320f47758408c175009c832bea:-8359094986150629512", "type": "AnimationTrack"}]} +PASS manage_timeline {"action": "set_binding", "assetPath": "Assets/Scenes/Generated/E2E/Timeline/Sequence-78b703c10f90467aa56906709bbbbd94.playable", "directorPath": "/TimelineDirector", "tracks": [{"binding": "/TimelineActor", "clips": [{"animationClipPath": "Assets/Scenes/Generated/E2E/Timeline/Motion.anim", "duration": 2.0, "index": 0, "start": 1.0}], "name": "Motion", "trackId": "9e72b0320f47758408c175009c832bea:-8359094986150629512", "type": "AnimationTrack"}]} +PASS get_timeline {"assetPath": "Assets/Scenes/Generated/E2E/Timeline/Sequence-78b703c10f90467aa56906709bbbbd94.playable", "directorPath": "/TimelineDirector", "tracks": [{"binding": "/TimelineActor", "clips": [{"animationClipPath": "Assets/Scenes/Generated/E2E/Timeline/Motion.anim", "duration": 2.0, "index": 0, "start": 1.0}], "name": "Motion", "trackId": "9e72b0320f47758408c175009c832bea:-8359094986150629512", "type": "AnimationTrack"}]} +PASS AC-1 timing and Animator binding readback +PASS manage_timeline INVALID +PASS manage_timeline $.trackType must be one of +PASS execute_menu_item {"executed": true, "executionTime": 115, "menuExists": true, "menuPath": "Tools/Unity CLI/Timeline/Generate Unsupported Track", "message": "Menu item executed successfully", "success": true} +PASS unsupported fixture menu executed +PASS get_timeline {"assetPath": "Assets/Scenes/Generated/E2E/Timeline/Unsupported.playable", "directorPath": null, "tracks": [{"binding": null, "clips": [], "name": "Audio", "trackId": "9aa7d0e7c0f043944b5d21e90044712e:-7584492291630700093", "type": "AudioTrack"}]} +PASS manage_timeline UNSUPPORTED_TRACK +PASS manage_timeline STALE_CLIP +PASS get_timeline {"assetPath": "Assets/Scenes/Generated/E2E/Timeline/Sequence-78b703c10f90467aa56906709bbbbd94.playable", "directorPath": "/TimelineDirector", "tracks": [{"binding": "/TimelineActor", "clips": [{"animationClipPath": "Assets/Scenes/Generated/E2E/Timeline/Motion.anim", "duration": 2.0, "index": 0, "start": 1.0}], "name": "Motion", "trackId": "9e72b0320f47758408c175009c832bea:-8359094986150629512", "type": "AnimationTrack"}]} +PASS invalid operations leave Timeline unchanged +PASS save_scene {"isDirty": false, "originalPath": null, "saved": true, "sceneName": "TimelineTest", "scenePath": "Assets/Scenes/Generated/E2E/Timeline/TimelineTest.unity", "summary": "Saved scene \"TimelineTest\" to \"Assets/Scenes/Generated/E2E/Timeline/TimelineTest.unity\""} +PASS execute_menu_item {"executed": true, "executionTime": 602, "menuExists": true, "menuPath": "Tools/Unity CLI/Timeline/Reload E2E Assets", "message": "Menu item executed successfully", "success": true} +PASS asset unloaded, reimported and scene reopened +PASS get_timeline {"assetPath": "Assets/Scenes/Generated/E2E/Timeline/Sequence-78b703c10f90467aa56906709bbbbd94.playable", "directorPath": "/TimelineDirector", "tracks": [{"binding": "/TimelineActor", "clips": [{"animationClipPath": "Assets/Scenes/Generated/E2E/Timeline/Motion.anim", "duration": 2.0, "index": 0, "start": 1.0}], "name": "Motion", "trackId": "9e72b0320f47758408c175009c832bea:-8359094986150629512", "type": "AnimationTrack"}]} +PASS AC-2 saved scene/asset reload roundtrip +PASS manage_timeline {"action": "evaluate", "assetPath": "Assets/Scenes/Generated/E2E/Timeline/Sequence-78b703c10f90467aa56906709bbbbd94.playable", "directorPath": "/TimelineDirector", "time": 2.0, "tracks": [{"binding": "/TimelineActor", "clips": [{"animationClipPath": "Assets/Scenes/Generated/E2E/Timeline/Motion.anim", "duration": 2.0, "index": 0, "start": 1.0}], "name": "Motion", "trackId": "9e72b0320f47758408c175009c832bea:-8359094986150629512", "type": "AnimationTrack"}]} +PASS get_gameobject_details {"components": [{"enabled": true, "properties": {"position": {"x": 5.0, "y": 0.0, "z": 0.0}, "rotation": {"x": 0.0, "y": 0.0, "z": 0.0}, "scale": {"x": 1.0, "y": 1.0, "z": 1.0}}, "type": "Transform"}, {"enabled": true, "properties": {"angularVelocity": {"x": 0.0, "y": 0.0, "z": 0.0}, "deltaPosition": {"x": 0.0, "y": 0.0, "z": 0.0}, "deltaRotation": {"eulerAngles": {"x": 0.0, "y": 0.0, "z": 0.0}, "w": 1.0, "x": 0.0, "y": 0.0, "z": 0.0}, "hasRootMotion": false, "humanScale": 1.0, "isHuman": false, "isInitialized": true, "isOptimizable": false, "rootPosition": {"x": 5.0, "y": 0.0, "z": 0.0}, "velocity": {"x": 0.0, "y": 0.0, "z": 0.0}}, "type": "Animator"}], "isActive": true, "isStatic": false, "layer": "Default", "name": "TimelineActor", "path": "/TimelineActor", "prefabInfo": {"isInstance": false, "isPrefab": false}, "summary": "GameObject \"TimelineActor\" with 2 components at /TimelineActor", "tag": "Untagged", "transform": {"position": {"x": 5.0, "y": 0.0, "z": 0.0}, "rotation": {"x": 0.0, "y": 0.0, "z": 0.0}, "scale": {"x": 1.0, "y": 1.0, "z": 1.0}, "worldPosition": {"x": 5.0, "y": 0.0, "z": 0.0}}} +PASS AC-3 PlayableDirector evaluation animates Transform.x=5 +PASS manage_timeline {"action": "update_clip", "assetPath": "Assets/Scenes/Generated/E2E/Timeline/Sequence-78b703c10f90467aa56906709bbbbd94.playable", "clipIndex": 0, "directorPath": null, "tracks": [{"binding": null, "clips": [{"animationClipPath": "Assets/Scenes/Generated/E2E/Timeline/Motion.anim", "duration": 3.0, "index": 0, "start": 2.0}], "name": "Motion", "trackId": "9e72b0320f47758408c175009c832bea:-8359094986150629512", "type": "AnimationTrack"}]} +PASS get_timeline {"assetPath": "Assets/Scenes/Generated/E2E/Timeline/Sequence-78b703c10f90467aa56906709bbbbd94.playable", "directorPath": null, "tracks": [{"binding": null, "clips": [{"animationClipPath": "Assets/Scenes/Generated/E2E/Timeline/Motion.anim", "duration": 3.0, "index": 0, "start": 2.0}], "name": "Motion", "trackId": "9e72b0320f47758408c175009c832bea:-8359094986150629512", "type": "AnimationTrack"}]} +PASS clip timing update +PASS manage_timeline {"action": "remove_clip", "assetPath": "Assets/Scenes/Generated/E2E/Timeline/Sequence-78b703c10f90467aa56906709bbbbd94.playable", "directorPath": null, "tracks": [{"binding": null, "clips": [], "name": "Motion", "trackId": "9e72b0320f47758408c175009c832bea:-8359094986150629512", "type": "AnimationTrack"}]} +PASS get_timeline {"assetPath": "Assets/Scenes/Generated/E2E/Timeline/Sequence-78b703c10f90467aa56906709bbbbd94.playable", "directorPath": null, "tracks": [{"binding": null, "clips": [], "name": "Motion", "trackId": "9e72b0320f47758408c175009c832bea:-8359094986150629512", "type": "AnimationTrack"}]} +PASS clip removal +PASS manage_timeline {"action": "clear_binding", "assetPath": "Assets/Scenes/Generated/E2E/Timeline/Sequence-78b703c10f90467aa56906709bbbbd94.playable", "directorPath": "/TimelineDirector", "tracks": [{"binding": null, "clips": [], "name": "Motion", "trackId": "9e72b0320f47758408c175009c832bea:-8359094986150629512", "type": "AnimationTrack"}]} +PASS get_timeline {"assetPath": "Assets/Scenes/Generated/E2E/Timeline/Sequence-78b703c10f90467aa56906709bbbbd94.playable", "directorPath": "/TimelineDirector", "tracks": [{"binding": null, "clips": [], "name": "Motion", "trackId": "9e72b0320f47758408c175009c832bea:-8359094986150629512", "type": "AnimationTrack"}]} +PASS binding clear +PASS manage_timeline {"action": "delete_track", "assetPath": "Assets/Scenes/Generated/E2E/Timeline/Sequence-78b703c10f90467aa56906709bbbbd94.playable", "directorPath": "/TimelineDirector", "tracks": []} +PASS get_timeline {"assetPath": "Assets/Scenes/Generated/E2E/Timeline/Sequence-78b703c10f90467aa56906709bbbbd94.playable", "directorPath": null, "tracks": []} +PASS track deletion +Timeline E2E: passed=40 failed=0 diff --git a/docs/verification/issue-386/resume/video-formats.txt b/docs/verification/issue-386/resume/video-formats.txt new file mode 100644 index 00000000..7769575d --- /dev/null +++ b/docs/verification/issue-386/resume/video-formats.txt @@ -0,0 +1,13 @@ +Video format E2E: 127.0.0.1:6487; artifacts=\.cache\issue-386\resume\video-final +PASS recording outside Play Mode returns error +PASS invalid format returns error +Output mp4: \.cache\issue-386\staff-project\.unity\capture\video_game_2026-10-04_06-46-00_b4345be096744e71a48455453419794c.mp4 (83309 bytes, header=00000018667479706d703432000000006d70343169736f6d0000002875756964) +PASS mp4 file format and session lifecycle +Output webm: \.cache\issue-386\staff-project\.unity\capture\video_game_2026-10-04_06-46-03_68bdf052a04c45adae01da6c6126430d.webm (6079 bytes, header=1a45dfa39f4286810142f7810142f2810442f381084282847765626d42878102) +PASS webm file format and session lifecycle +PNG sequence: 24 frames in \.cache\issue-386\staff-project\.unity\capture\video_game_2026-10-04_06-46-07_389fff53335e4bbab47ba05c8a6eec8f +Output png_sequence: \.cache\issue-386\staff-project\.unity\capture\video_game_2026-10-04_06-46-07_389fff53335e4bbab47ba05c8a6eec8f\frame_0000.png (22843 bytes, header=89504e470d0a1a0a0000000d4948445200000140000000b40806000000e5e4f5) +PASS png_sequence file format and session lifecycle +Output mp4: \.cache\issue-386\staff-project\.unity\capture\video_game_2026-10-04_06-46-10_40e3f4e2d6e94e8c86b32cff6a25d3f7.mp4 (71048 bytes, header=00000018667479706d703432000000006d70343169736f6d0000002875756964) +PASS mp4 file format and session lifecycle +Passed: 6; Failed: 0; Total: 6 diff --git a/docs/verification/issue-386/resume/video-summary.json b/docs/verification/issue-386/resume/video-summary.json new file mode 100644 index 00000000..615d88df --- /dev/null +++ b/docs/verification/issue-386/resume/video-summary.json @@ -0,0 +1,8 @@ +{ + "passed": 6, + "failed": 0, + "total": 6, + "artifacts": "\\.cache\\issue-386\\resume\\video-final", + "host": "127.0.0.1", + "port": "6487" +} diff --git a/docs/verification/issue-386/resume/windows-comparison-adapter.py b/docs/verification/issue-386/resume/windows-comparison-adapter.py new file mode 100644 index 00000000..31839d06 --- /dev/null +++ b/docs/verification/issue-386/resume/windows-comparison-adapter.py @@ -0,0 +1,177 @@ +import ctypes +from ctypes import wintypes +import hashlib +import importlib.util +import json +import os +from pathlib import Path +import platform +import queue +import subprocess +import sys +import threading +import time +from datetime import datetime, timezone +from types import SimpleNamespace + +root = Path(__file__).resolve().parents[2] +cache = root / '.cache/issue-386' +out = cache / 'resume/official-windows' +project = cache / 'staff-project' +assert project.resolve().is_relative_to(cache.resolve()) +sys.path.insert(0, str(root / 'scripts')) +sys.dont_write_bytecode = True +spec = importlib.util.spec_from_file_location('comparison', root / 'scripts/bench-compare-official.py') +comparison = importlib.util.module_from_spec(spec) +spec.loader.exec_module(comparison) +bench = comparison.load_editor_bench() +comparison.load_editor_bench = lambda: bench +bench.READ_PATH = 'Packages/com.akiojin.unity-cli-bridge/Editor/Core/UnityCliBridgeHost.cs' +args = SimpleNamespace(project=project.resolve(), port=6487, unity_cli=str(root / 'target/debug/unity-cli.exe'), official=str(out / 'unity.exe'), timeout=60, iterations=100, warmup=3, focus='frontmost') +env = comparison.benchmark_environment(args.project, args.port) +env['UNITY_CLI_HOME'] = str(out / 'install') +env['PYTHONUTF8'] = '1' +(project / '.unity/perf-owned-project').write_text('Issue386-owned Windows comparison fixture\n', encoding='utf-8') +editor_pid = json.loads((cache / 'resume/staff-editor-open.json').read_text(encoding='utf-8'))['data']['pid'] +observed = subprocess.check_output(['powershell', '-NoProfile', '-Command', 'Get-NetTCPConnection -LocalPort 6487 -State Listen | Select-Object -ExpandProperty OwningProcess'], encoding='utf-8').split() +assert set(observed) == {str(editor_pid)}, 'Actual Bridge listener must be the owned Editor' +user = ctypes.WinDLL('user32', use_last_error=True) +user.GetForegroundWindow.restype = wintypes.HWND +user.GetWindowThreadProcessId.argtypes = [wintypes.HWND, ctypes.POINTER(wintypes.DWORD)] +user.SetForegroundWindow.argtypes = [wintypes.HWND] +user.SwitchToThisWindow.argtypes = [wintypes.HWND, wintypes.BOOL] +user.IsWindowVisible.argtypes = [wintypes.HWND] +user.IsWindow.argtypes = [wintypes.HWND] +user.ShowWindow.argtypes = [wintypes.HWND, ctypes.c_int] +user.ShowWindowAsync.argtypes = [wintypes.HWND, ctypes.c_int] +user.GetWindowTextW.argtypes = [wintypes.HWND, wintypes.LPWSTR, ctypes.c_int] +user.BringWindowToTop.argtypes = [wintypes.HWND] +user.AttachThreadInput.argtypes = [wintypes.DWORD, wintypes.DWORD, wintypes.BOOL] +user.SetWindowPos.argtypes = [wintypes.HWND, wintypes.HWND, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, wintypes.UINT] +original_window = user.GetForegroundWindow() + +def pid_for_window(window): + pid = wintypes.DWORD() + user.GetWindowThreadProcessId(window, ctypes.byref(pid)) + return pid.value + +def foreground_pid(): + return pid_for_window(user.GetForegroundWindow()) + +callback_type = ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM) +windows = [] +background_windows = [] +@callback_type +def collect(window, parameter): + if user.IsWindowVisible(window): + title = ctypes.create_unicode_buffer(512) + user.GetWindowTextW(window, title, len(title)) + if pid_for_window(window) == editor_pid and 'staff-project' in title.value: + windows.append(window) + elif pid_for_window(window) != editor_pid and 'gwt' in title.value.lower(): + background_windows.append(window) + return True +user.EnumWindows(collect, 0) +assert windows, 'Owned graphical Editor window must exist' +editor_window = windows[0] +if pid_for_window(original_window) == editor_pid and background_windows: + original_window = background_windows[0] +assert original_window and pid_for_window(original_window) != editor_pid, 'Need a real background window distinct from Editor' + +def activate_window(window): + user.ShowWindowAsync(window, 9) + user.SwitchToThisWindow(window, True) + user.SetForegroundWindow(window) + +def ensure_focus(focus, pid): + assert pid == editor_pid + deadline = time.monotonic() + 5 + while not bench.focus_matches(focus, pid, foreground_pid()): + if time.monotonic() >= deadline: + raise RuntimeError('Unable to establish actual Windows ' + focus + ' focus') + if focus == 'frontmost': + activate_window(editor_window) + else: + user.ShowWindowAsync(editor_window, 6) + time.sleep(0.05) + +bench.ensure_focus = ensure_focus +bench._focus.frontmost_pid = foreground_pid + +class WindowsOfficialShell(comparison.OfficialShell): + def __init__(self, argv, environment, timeout): + super().__init__(argv, environment, timeout) + self.lines = queue.Queue() + def read(): + for line in iter(self.process.stdout.readline, b''): + self.lines.put(line) + self.lines.put(None) + self.reader = threading.Thread(target=read, daemon=True) + self.reader.start() + + def request(self, argv): + self.sequence += 1 + identity = str(self.sequence) + self.process.stdin.write((json.dumps({'id': identity, 'argv': argv}) + '\n').encode()) + self.process.stdin.flush() + try: + line = self.lines.get(timeout=self.timeout) + except queue.Empty: + raise TimeoutError('Official native Windows NDJSON timed out') + if line is None: + raise RuntimeError('Official native Windows NDJSON closed') + result = json.loads(line) + if result.get('id') != identity or result.get('exitCode') != 0: + raise ValueError('Invalid official NDJSON response: ' + str(result)) + envelope = result.get('envelope', {}) + if envelope.get('success') is not True: + raise ValueError('Official request failed: ' + str(envelope)) + return envelope + +comparison.OfficialShell = WindowsOfficialShell +editor = bench.Editor(args, env) +metadata = {'started_at': datetime.now(timezone.utc).isoformat(), 'os': platform.platform(), 'arch': platform.machine(), 'logical_cpus': os.cpu_count(), 'unity': '6000.4.4f1', 'editor_pid': editor_pid, 'iterations': 100, 'warmup': 3, 'unity_cli_build': 'native Windows debug 0.18.1', 'official_cli_version': '1.0.0-beta.11', 'pipeline_version': '0.8.0-exp.1', 'unity_cli_sha256': hashlib.sha256(Path(args.unity_cli).read_bytes()).hexdigest(), 'official_cli_sha256': hashlib.sha256(Path(args.official).read_bytes()).hexdigest(), 'benchmark_sha256': hashlib.sha256((root / 'scripts/bench-compare-official.py').read_bytes()).hexdigest(), 'windows_adapter_sha256': hashlib.sha256(Path(__file__).read_bytes()).hexdigest(), 'windows_adapter': 'Original benchmark operations, validation, focus-discard and alternating order; Windows HWND foreground inspection and bounded reader thread replace macOS focus and POSIX select. No platform spoofing.', 'background_condition': 'Owned Editor minimized, because Windows refused activation of the existing GWT background window. This differs from macOS visible-background measurements.', 'host_contention': 'Other project canonical verification was active on this host; results are observations, no Windows budget or prior baseline was enforced.'} +reports = [] +try: + info = editor.setup() + result = subprocess.run([args.official, 'command', 'editor_status', '--project-path', str(project), '--format', 'json'], cwd=root, env=env, capture_output=True, text=True, encoding='utf-8', timeout=60) + assert result.returncode == 0, result.stdout + result.stderr + comparison.check_official('editor_status', result.stdout) + metadata['coexistence'] = comparison.verify_coexistence(args.project, info, json.loads(result.stdout)['data']['result']) + metadata['play_settings'] = editor.raw('get_project_settings', {'includeEditor': True})['editor'] + daemon_before = editor.command(['unityd', 'status']) + assert daemon_before['running'] and daemon_before.get('connections', 0) > 0 + metadata['unityd_pid'] = daemon_before['pid'] + for mode in ['process', 'resident']: + for focus in ['frontmost', 'background']: + if mode == 'process': + previous = json.loads((out / (mode + '-' + focus + '.json')).read_text(encoding='utf-8')) + assert previous['status'] == 'PASS' + reports.append({'mode': mode, 'focus': focus, 'status': 'PASS', 'source': 'previous completed run, original conditions preserved'}) + continue + args.focus = focus + report = {'mode': mode, 'focus': focus, 'started_at': datetime.now(timezone.utc).isoformat(), 'conditions': metadata} + try: + measure = comparison.measure_process if mode == 'process' else comparison.measure_resident + samples, details = measure(args, env, editor, bench, editor_pid) + assert editor.command(['unityd', 'status'])['pid'] == daemon_before['pid'], 'Same warm unityd must survive' + assert all(len(values) == 100 for by_operation in samples.values() for values in by_operation.values()) + report.update(status='PASS', samples_ms=samples, details=details, results={name: {operation: comparison.summarize(values) for operation, values in operations.items()} for name, operations in samples.items()}) + except Exception as error: + report.update(status='FAIL', error=str(error)) + report['finished_at'] = datetime.now(timezone.utc).isoformat() + (out / (mode + '-' + focus + '.json')).write_text(json.dumps(report, indent=2), encoding='utf-8') + reports.append({'mode': mode, 'focus': focus, 'status': report['status'], 'error': report.get('error')}) + (out / 'summary.json').write_text(json.dumps({'conditions': metadata, 'runs': reports}, indent=2), encoding='utf-8') + print(mode, focus, report['status'], report.get('error', ''), flush=True) + if report['status'] != 'PASS': + raise RuntimeError(report['error']) +finally: + try: + if editor.raw('get_editor_state', {})['state']['isPlaying']: + bench.transition(editor.raw, False) + editor.restore_play_focus() + finally: + user.ShowWindowAsync(editor_window, 9) + if user.IsWindow(original_window): + activate_window(original_window) diff --git a/docs/verification/issue-386/resume/windows-comparison.md b/docs/verification/issue-386/resume/windows-comparison.md new file mode 100644 index 00000000..621c6c87 --- /dev/null +++ b/docs/verification/issue-386/resume/windows-comparison.md @@ -0,0 +1,89 @@ +# Windows 公式CLI比較の計測値 + +Windows 11 x64 / Unity6000.4.4f1 / unity-cli・Bridge0.18.1 debug / official1.0.0-beta.11 / Pipeline0.8.0-exp.1。 + +各操作は3回のwarmup後に100回、両ツールの順を交互にした。背景はEditorの最小化条件であり、macOSの表示した背景とは異なる。 +ほかのプロジェクトの正式検証がhostで稼働中だった。性能予算への合格や過去のbaselineとの同一条件比較ではない。 + +プロセス方式は呼出ごとに起動、常駐方式は同じunitydと同じ公式NDJSON shellを保持する。 +全条件で同一プロジェクトとEditorを確認した。バイナリ・scriptのSHA256とfocusによる除外数は各JSONに保持する。 + +## process / 前面 + +[全サンプル・条件JSON](official-windows-process-frontmost.json)。単位: ms。 + +| 操作 | unity-cli p50 | unity-cli p95 | 公式 p50 | 公式 p95 | +| --- | ---: | ---: | ---: | ---: | +| `create_gameobject` | 152.56 | 772.00 | 566.91 | 1400.40 | +| `hierarchy` | 41.16 | 677.94 | 616.34 | 1109.08 | +| `eval` | 1749.75 | 3522.45 | 736.40 | 1401.74 | + +## process / 最小化 + +[全サンプル・条件JSON](official-windows-process-background.json)。単位: ms。 + +| 操作 | unity-cli p50 | unity-cli p95 | 公式 p50 | 公式 p95 | +| --- | ---: | ---: | ---: | ---: | +| `create_gameobject` | 161.36 | 713.62 | 607.91 | 1141.02 | +| `hierarchy` | 270.32 | 1009.96 | 788.11 | 1180.21 | +| `eval` | 1708.23 | 3227.09 | 668.51 | 1310.37 | + +## resident / 前面 + +[全サンプル・条件JSON](official-windows-resident-frontmost.json)。単位: ms。 + +| 操作 | unity-cli p50 | unity-cli p95 | 公式 p50 | 公式 p95 | +| --- | ---: | ---: | ---: | ---: | +| `editor_state` | 223.44 | 715.67 | 735.68 | 1118.54 | +| `hierarchy` | 40.66 | 828.94 | 741.80 | 1446.67 | +| `find_gameobject` | 38.06 | 862.07 | 711.20 | 1209.85 | +| `transform` | 40.79 | 602.45 | 851.60 | 1595.39 | +| `position` | 38.34 | 598.93 | 571.22 | 1069.88 | +| `create_cube` | 39.69 | 898.57 | 631.00 | 1186.84 | +| `add_component` | 51.85 | 878.84 | 839.05 | 1353.01 | +| `remove_component` | 46.29 | 592.21 | 865.47 | 1811.90 | +| `delete_gameobject` | 40.93 | 328.88 | 618.58 | 1333.86 | +| `scene_info` | 37.65 | 334.26 | 626.42 | 1164.28 | +| `scene_save` | 131.45 | 647.33 | 731.03 | 1118.06 | +| `console` | 194.53 | 319.23 | 608.51 | 883.48 | +| `screenshot` | 96.07 | 404.13 | 696.99 | 1092.53 | +| `material_search` | 43.35 | 548.99 | 672.49 | 1200.97 | +| `asset_copy` | 100.90 | 408.95 | 773.65 | 1283.73 | +| `asset_move` | 289.69 | 593.52 | 745.94 | 1191.12 | +| `asset_delete` | 89.09 | 625.86 | 727.89 | 1127.38 | +| `import_settings` | 248.28 | 578.64 | 677.56 | 1136.85 | +| `material_modify` | 63.10 | 620.20 | 670.51 | 1219.39 | +| `time_settings` | 39.11 | 581.13 | 675.52 | 1140.79 | +| `read_csharp` | 33.51 | 596.27 | 657.45 | 1245.12 | +| `play_until_ready` | 785.33 | 1403.39 | 1372.78 | 2092.59 | +| `stop_until_ready` | 672.11 | 1207.18 | 1356.79 | 2300.94 | + +## resident / 最小化 + +[全サンプル・条件JSON](official-windows-resident-background.json)。単位: ms。 + +| 操作 | unity-cli p50 | unity-cli p95 | 公式 p50 | 公式 p95 | +| --- | ---: | ---: | ---: | ---: | +| `editor_state` | 201.96 | 706.68 | 705.11 | 1094.77 | +| `hierarchy` | 103.11 | 899.01 | 691.88 | 1272.59 | +| `find_gameobject` | 106.43 | 707.95 | 692.45 | 1292.24 | +| `transform` | 107.25 | 701.11 | 895.84 | 1391.78 | +| `position` | 103.13 | 1102.66 | 694.65 | 1316.50 | +| `create_cube` | 103.87 | 902.30 | 701.23 | 1121.95 | +| `add_component` | 102.21 | 702.83 | 890.33 | 1204.97 | +| `remove_component` | 102.97 | 903.02 | 909.00 | 1511.48 | +| `delete_gameobject` | 101.15 | 602.33 | 702.73 | 1195.75 | +| `scene_info` | 100.75 | 598.80 | 686.22 | 1287.26 | +| `scene_save` | 193.74 | 506.45 | 813.59 | 1310.85 | +| `console` | 219.77 | 423.74 | 618.18 | 1146.31 | +| `screenshot` | 206.83 | 831.21 | 734.02 | 1355.40 | +| `material_search` | 200.25 | 563.19 | 715.92 | 1396.92 | +| `asset_copy` | 162.34 | 959.58 | 843.09 | 1356.51 | +| `asset_move` | 263.80 | 667.39 | 682.49 | 1277.85 | +| `asset_delete` | 335.01 | 662.07 | 684.14 | 1192.27 | +| `import_settings` | 118.93 | 914.90 | 642.20 | 1133.44 | +| `material_modify` | 139.28 | 932.20 | 653.47 | 1244.54 | +| `time_settings` | 117.84 | 914.90 | 623.08 | 1197.13 | +| `read_csharp` | 37.44 | 580.05 | 694.92 | 1302.50 | +| `play_until_ready` | 822.01 | 1466.44 | 1435.69 | 2099.78 | +| `stop_until_ready` | 737.03 | 1428.65 | 1441.33 | 2158.01 | diff --git a/docs/verification/issue-386/resume/windows-player-graphical.json b/docs/verification/issue-386/resume/windows-player-graphical.json new file mode 100644 index 00000000..94c7e24a --- /dev/null +++ b/docs/verification/issue-386/resume/windows-player-graphical.json @@ -0,0 +1,26 @@ +{ + "started_at": "2026-10-03T21:56:57.372479+00:00", + "argv": [ + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player.exe", + "-screen-fullscreen", + "0", + "-screen-width", + "640", + "-screen-height", + "360", + "-logFile", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\graphical-launch.txt" + ], + "exe_sha256": "413a04009d5fc13e03fe4e5c6941a8606c63c103edd08853efc6c9bd57e6151b", + "passed": true, + "player_pid": 14980, + "visible_owned_window": true, + "pixels": { + "width": 640, + "height": 360, + "sampledChannelRange": 164 + }, + "png_sha256": "5680ebd152535218ac43870615c74e4ec0ea185751d762043176312b3cd5b32e", + "observation": "Windows Player rendered varying pixels in its visible client area; gameplay input was not tested", + "finished_at": "2026-10-03T21:57:03.031333+00:00" +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/windows-player-result.json b/docs/verification/issue-386/resume/windows-player-result.json new file mode 100644 index 00000000..f45d2a18 --- /dev/null +++ b/docs/verification/issue-386/resume/windows-player-result.json @@ -0,0 +1,231 @@ +{ + "started_at": "2026-10-03T21:43:12.770455+00:00", + "binary_sha256": "1d176023f684dbe5fb3f0ae8d23222960d5618c4e3a8a03ae3535994891a8d72", + "passed": true, + "target": "StandaloneWindows64", + "build": { + "artifacts": [ + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\globalgamemanagers", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\globalgamemanagers.assets", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\globalgamemanagers.assets.resS", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\level0", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\resources.assets", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\resources.assets.resS", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Resources\\unity_builtin_extra", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\RuntimeInitializeOnLoads.json", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\ScriptingAssemblies.json", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\sharedassets0.assets", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\sharedassets0.assets.resS", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\boot.config", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Assembly-CSharp.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Mono.Security.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\mscorlib.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\netstandard.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Newtonsoft.Json.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.ComponentModel.Composition.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.Configuration.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.Core.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.Data.DataSetExtensions.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.Data.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.Drawing.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.EnterpriseServices.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.IO.Compression.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.IO.Compression.FileSystem.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.IO.Hashing.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.Memory.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.Net.Http.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.Numerics.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.Runtime.CompilerServices.Unsafe.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.Runtime.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.Runtime.Serialization.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.Security.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.ServiceModel.Internals.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.Transactions.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.Xml.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\System.Xml.Linq.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.Addressables.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.AI.Navigation.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.Burst.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.Burst.Unsafe.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.Collections.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.Collections.LowLevel.ILSupport.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.InputSystem.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.InputSystem.ForUI.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.InternalAPIEngineBridge.004.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.InternalAPIEngineBridge.RenderPipelines.Core.Runtime.Shared.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.Mathematics.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.PathTracing.Runtime.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.Profiling.Core.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.Recorder.Base.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.Recorder.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.RenderPipeline.Universal.ShaderLibrary.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.RenderPipelines.Core.Runtime.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.RenderPipelines.Core.Runtime.Shared.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.RenderPipelines.Core.ShaderLibrary.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.RenderPipelines.GPUDriven.Runtime.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.RenderPipelines.Universal.2D.Runtime.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.RenderPipelines.Universal.Config.Runtime.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.RenderPipelines.Universal.Runtime.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.RenderPipelines.Universal.Shaders.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.ResourceManager.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.ScriptableBuildPipeline.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.Scripting.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.SurfaceCache.Runtime.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.TextMeshPro.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.Timeline.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.UnifiedRayTracing.Runtime.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\Unity.VisualEffectGraph.Runtime.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityCliBridge.Runtime.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.AccessibilityModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.AdaptivePerformanceModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.AIModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.AMDModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.AndroidJNIModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.AnimationModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.ARModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.AssetBundleModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.AudioModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.ClothModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.ClusterInputModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.ClusterRendererModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.ContentLoadModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.CoreModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.CrashReportingModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.DirectorModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.DSPGraphModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.GameCenterModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.GIModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.GraphicsStateCollectionSerializerModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.GridModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.HierarchyCoreModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.HierarchyModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.HotReloadModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.IdentifiersModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.ImageConversionModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.IMGUIModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.InputForUIModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.InputLegacyModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.InputModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.InsightsModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.JSONSerializeModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.LocalizationModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.MarshallingModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.MultiplayerModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.NVIDIAModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.ParticleSystemModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.PerformanceReportingModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.Physics2DModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.PhysicsBackendPhysXModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.PhysicsModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.PropertiesModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.RenderAs2DModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.ScreenCaptureModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.ScriptingModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.ShaderVariantAnalyticsModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.SharedInternalsModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.SpriteMaskModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.SpriteShapeModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.StreamingModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.SubstanceModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.SubsystemsModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.TerrainModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.TerrainPhysicsModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.TextCoreFontEngineModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.TextCoreTextEngineModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.TextRenderingModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.TilemapModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.TLSModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.UI.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.UIElementsModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.UIModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.UmbraModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.UnityAnalyticsCommonModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.UnityAnalyticsModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.UnityConnectModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.UnityConsentModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.UnityCurlModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.UnityWebRequestAssetBundleModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.UnityWebRequestAudioModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.UnityWebRequestModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.UnityWebRequestTextureModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.UnityWebRequestWWWModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.VectorGraphicsModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.VehiclesModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.VFXModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.VideoModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.VirtualTexturingModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.VRModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.WindModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Managed\\UnityEngine.XRModule.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Plugins\\x86_64\\lib_burst_generated.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\app.info", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player_Data\\Resources\\unity default resources", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player.exe", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\AMDUnityPlugin.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\dstorage.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\dstoragecore.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\EmbedRuntime\\mono-2.0-bdwgc.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\EmbedRuntime\\MonoPosixHelper.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\2.0\\Browsers\\Compat.browser", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\2.0\\DefaultWsdlHelpGenerator.aspx", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\2.0\\machine.config", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\2.0\\settings.map", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\2.0\\web.config", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\4.0\\Browsers\\Compat.browser", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\4.0\\DefaultWsdlHelpGenerator.aspx", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\4.0\\machine.config", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\4.0\\settings.map", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\4.0\\web.config", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\4.5\\Browsers\\Compat.browser", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\4.5\\DefaultWsdlHelpGenerator.aspx", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\4.5\\machine.config", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\4.5\\settings.map", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\4.5\\web.config", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\browscap.ini", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\config", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\MonoBleedingEdge\\etc\\mono\\mconfig\\config.xml", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\nvngx_dlss.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\NVUnityPlugin.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\UnityCrashHandler64.exe", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\UnityPlayer.dll", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\D3D12\\D3D12Core.dll" + ], + "buildId": "775f6d4a8e374694be6bb3f948c7d451", + "changedProjectSettings": [], + "durationSeconds": 104.8804861, + "errors": [], + "outputPath": "/.cache/issue-386/resume/player-output/WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d/Player.exe", + "reportResult": "Succeeded", + "scenes": [ + "Assets/Scenes/Generated/E2E/WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d.unity" + ], + "startedAt": "2026-10-03T21:43:14.0725935Z", + "state": "succeeded", + "target": "StandaloneWindows64", + "totalErrors": 0, + "totalWarnings": 6, + "warnings": [ + "Assets\\Scripts\\UnityCliUiTest\\UnityCliUGuiTestSceneController.cs(31,31): warning CS0618: 'Object.FindFirstObjectByType()' is obsolete: 'FindFirstObjectByType has been deprecated because it relies on instance ID ordering. Use FindAnyObjectByType instead, which does not depend on ordering.'", + "Assets\\Scripts\\UnityCliUiTest\\UnityCliAllUiSystemsTestBootstrap.cs(39,31): warning CS0618: 'Object.FindFirstObjectByType()' is obsolete: 'FindFirstObjectByType has been deprecated because it relies on instance ID ordering. Use FindAnyObjectByType instead, which does not depend on ordering.'", + "Assets\\Scripts\\UnityCliPerfScenarioController.cs(190,30): warning CS0618: 'Object.FindFirstObjectByType()' is obsolete: 'FindFirstObjectByType has been deprecated because it relies on instance ID ordering. Use FindAnyObjectByType instead, which does not depend on ordering.'", + "Assets\\Scripts\\UnityCliUiTest\\UnityCliAllUiSystemsTestBootstrap.cs(66,17): warning CS0618: 'Object.FindFirstObjectByType()' is obsolete: 'FindFirstObjectByType has been deprecated because it relies on instance ID ordering. Use FindAnyObjectByType instead, which does not depend on ordering.'", + "Assets\\Scripts\\UnityCliUiTest\\UnityCliAllUiSystemsTestBootstrap.cs(301,17): warning CS0618: 'Object.FindFirstObjectByType()' is obsolete: 'FindFirstObjectByType has been deprecated because it relies on instance ID ordering. Use FindAnyObjectByType instead, which does not depend on ordering.'", + "Assets\\Scripts\\UnityCliUiTest\\UnityCliInputSimulationTestBootstrap.cs(530,31): warning CS0618: 'Object.FindFirstObjectByType()' is obsolete: 'FindFirstObjectByType has been deprecated because it relies on instance ID ordering. Use FindAnyObjectByType instead, which does not depend on ordering.'" + ] + }, + "player_pid": 49272, + "player_command": [ + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\Player.exe", + "-batchmode", + "-nographics", + "-logFile", + "\\.cache\\issue-386\\resume\\player-output\\WindowsPlayer_4b6c2fee84804da0a39f64ddb4dc292d\\player-launch.txt" + ], + "launch": "Windows headless Player remained alive for 5 seconds and emitted the expected engine version", + "player_log_sha256": "77db497c5cf1b497e7c753cdd202be851ade74ea9c61cf92726c500bc07fabf1", + "finished_at": "2026-10-03T21:45:05.142170+00:00" +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/winget-manifest-validate.txt b/docs/verification/issue-386/resume/winget-manifest-validate.txt new file mode 100644 index 00000000..a35d5e6d --- /dev/null +++ b/docs/verification/issue-386/resume/winget-manifest-validate.txt @@ -0,0 +1 @@ +マニフェストの検証は成功しました。 diff --git a/docs/verification/issue-386/resume/winget-secret-state.json b/docs/verification/issue-386/resume/winget-secret-state.json new file mode 100644 index 00000000..371179c7 --- /dev/null +++ b/docs/verification/issue-386/resume/winget-secret-state.json @@ -0,0 +1,5 @@ +{ + "WINGET_TOKEN_name_present": false, + "secret_values_read": false, + "source": "gh secret list --repo akiojin/unity-cli --json name" +} \ No newline at end of file diff --git a/docs/verification/issue-386/resume/winget-source-final.txt b/docs/verification/issue-386/resume/winget-source-final.txt new file mode 100644 index 00000000..bba90bf4 --- /dev/null +++ b/docs/verification/issue-386/resume/winget-source-final.txt @@ -0,0 +1 @@ +入力条件に一致するパッケージが見つかりませんでした。 diff --git a/docs/verification/issue-386/setup.stdout.json b/docs/verification/issue-386/setup.stdout.json new file mode 100644 index 00000000..fae3bc2c --- /dev/null +++ b/docs/verification/issue-386/setup.stdout.json @@ -0,0 +1,57 @@ +{ + "command": "setup", + "data": { + "binary": { + "ok": true, + "onPath": null, + "path": "\\target\\debug\\unity-cli.exe", + "version": "0.18.1" + }, + "bridge": { + "action": "install", + "declared": "0.18.1", + "dryRun": false, + "inputBackends": null, + "installed": true, + "manifestChanged": true, + "manifestPath": "\\.cache\\issue-386\\fresh-setup-project\\Packages\\manifest.json", + "notes": [], + "package": "com.akiojin.unity-cli-bridge", + "projectPath": "\\.cache\\issue-386\\fresh-setup-project", + "registry": true, + "resolvedVersion": null, + "source": "registry", + "versionCheck": { + "bridgeVersion": "0.18.1", + "cliVersion": "0.18.1", + "message": "CLI and bridge are both 0.18.1", + "status": "match" + } + }, + "editor": { + "bridgeVersion": "0.18.1", + "endpoint": "127.0.0.1:6488", + "projectMatches": true, + "projectPath": "\\.cache\\issue-386\\fresh-setup-project", + "reachable": true, + "versionCheck": { + "bridgeVersion": "0.18.1", + "cliVersion": "0.18.1", + "message": "CLI and bridge are both 0.18.1", + "status": "match" + } + }, + "launch": { + "editorPath": "C:\\Program Files\\Unity\\Hub\\Editor\\6000.4.4f1\\Editor\\Unity.exe", + "launched": true, + "pid": 14140, + "port": 6488, + "unityVersion": "6000.4.4f1" + }, + "ok": true, + "warnings": [] + }, + "errors": [], + "success": true, + "warnings": [] +} diff --git a/docs/verification/issue-386/skills-lint-final.txt b/docs/verification/issue-386/skills-lint-final.txt new file mode 100644 index 00000000..a635c6bd --- /dev/null +++ b/docs/verification/issue-386/skills-lint-final.txt @@ -0,0 +1,51 @@ + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.48s + Running `target\debug\unity-cli.exe skills lint --severity error` +\.claude/skills\unity-2d-sprite-tilemap: error [R20] symlink `\.claude/skills\unity-2d-sprite-tilemap` points to `\\?\\.claude\skills\unity-2d-sprite-tilemap` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-2d-sprite-tilemap` +\.agents/skills\unity-2d-sprite-tilemap: error [R21] symlink `\.agents/skills\unity-2d-sprite-tilemap` points to `\\?\\.agents\skills\unity-2d-sprite-tilemap` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-2d-sprite-tilemap` +\.claude/skills\unity-addressables: error [R20] symlink `\.claude/skills\unity-addressables` points to `\\?\\.claude\skills\unity-addressables` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-addressables` +\.agents/skills\unity-addressables: error [R21] symlink `\.agents/skills\unity-addressables` points to `\\?\\.agents\skills\unity-addressables` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-addressables` +\.claude/skills\unity-asset-management: error [R20] symlink `\.claude/skills\unity-asset-management` points to `\\?\\.claude\skills\unity-asset-management` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-asset-management` +\.agents/skills\unity-asset-management: error [R21] symlink `\.agents/skills\unity-asset-management` points to `\\?\\.agents\skills\unity-asset-management` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-asset-management` +\.claude/skills\unity-audio-setup: error [R20] symlink `\.claude/skills\unity-audio-setup` points to `\\?\\.claude\skills\unity-audio-setup` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-audio-setup` +\.agents/skills\unity-audio-setup: error [R21] symlink `\.agents/skills\unity-audio-setup` points to `\\?\\.agents\skills\unity-audio-setup` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-audio-setup` +\.claude/skills\unity-cli-usage: error [R20] symlink `\.claude/skills\unity-cli-usage` points to `\\?\\.claude\skills\unity-cli-usage` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-cli-usage` +\.agents/skills\unity-cli-usage: error [R21] symlink `\.agents/skills\unity-cli-usage` points to `\\?\\.agents\skills\unity-cli-usage` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-cli-usage` +\.claude/skills\unity-csharp-edit: error [R20] symlink `\.claude/skills\unity-csharp-edit` points to `\\?\\.claude\skills\unity-csharp-edit` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-csharp-edit` +\.agents/skills\unity-csharp-edit: error [R21] symlink `\.agents/skills\unity-csharp-edit` points to `\\?\\.agents\skills\unity-csharp-edit` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-csharp-edit` +\.claude/skills\unity-csharp-navigate: error [R20] symlink `\.claude/skills\unity-csharp-navigate` points to `\\?\\.claude\skills\unity-csharp-navigate` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-csharp-navigate` +\.agents/skills\unity-csharp-navigate: error [R21] symlink `\.agents/skills\unity-csharp-navigate` points to `\\?\\.agents\skills\unity-csharp-navigate` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-csharp-navigate` +\.claude/skills\unity-csharp-reference: error [R20] symlink `\.claude/skills\unity-csharp-reference` points to `\\?\\.claude\skills\unity-csharp-reference` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-csharp-reference` +\.agents/skills\unity-csharp-reference: error [R21] symlink `\.agents/skills\unity-csharp-reference` points to `\\?\\.agents\skills\unity-csharp-reference` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-csharp-reference` +\.claude/skills\unity-development-loop: error [R20] symlink `\.claude/skills\unity-development-loop` points to `\\?\\.claude\skills\unity-development-loop` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-development-loop` +\.agents/skills\unity-development-loop: error [R21] symlink `\.agents/skills\unity-development-loop` points to `\\?\\.agents\skills\unity-development-loop` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-development-loop` +\.claude/skills\unity-editor-tools: error [R20] symlink `\.claude/skills\unity-editor-tools` points to `\\?\\.claude\skills\unity-editor-tools` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-editor-tools` +\.agents/skills\unity-editor-tools: error [R21] symlink `\.agents/skills\unity-editor-tools` points to `\\?\\.agents\skills\unity-editor-tools` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-editor-tools` +\.claude/skills\unity-gameobject-edit: error [R20] symlink `\.claude/skills\unity-gameobject-edit` points to `\\?\\.claude\skills\unity-gameobject-edit` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-gameobject-edit` +\.agents/skills\unity-gameobject-edit: error [R21] symlink `\.agents/skills\unity-gameobject-edit` points to `\\?\\.agents\skills\unity-gameobject-edit` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-gameobject-edit` +\.claude/skills\unity-input-system: error [R20] symlink `\.claude/skills\unity-input-system` points to `\\?\\.claude\skills\unity-input-system` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-input-system` +\.agents/skills\unity-input-system: error [R21] symlink `\.agents/skills\unity-input-system` points to `\\?\\.agents\skills\unity-input-system` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-input-system` +\.claude/skills\unity-localization: error [R20] symlink `\.claude/skills\unity-localization` points to `\\?\\.claude\skills\unity-localization` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-localization` +\.agents/skills\unity-localization: error [R21] symlink `\.agents/skills\unity-localization` points to `\\?\\.agents\skills\unity-localization` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-localization` +\.claude/skills\unity-package-management: error [R20] symlink `\.claude/skills\unity-package-management` points to `\\?\\.claude\skills\unity-package-management` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-package-management` +\.agents/skills\unity-package-management: error [R21] symlink `\.agents/skills\unity-package-management` points to `\\?\\.agents\skills\unity-package-management` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-package-management` +\.claude/skills\unity-playmode-testing: error [R20] symlink `\.claude/skills\unity-playmode-testing` points to `\\?\\.claude\skills\unity-playmode-testing` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-playmode-testing` +\.agents/skills\unity-playmode-testing: error [R21] symlink `\.agents/skills\unity-playmode-testing` points to `\\?\\.agents\skills\unity-playmode-testing` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-playmode-testing` +\.claude/skills\unity-prefab-workflow: error [R20] symlink `\.claude/skills\unity-prefab-workflow` points to `\\?\\.claude\skills\unity-prefab-workflow` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-prefab-workflow` +\.agents/skills\unity-prefab-workflow: error [R21] symlink `\.agents/skills\unity-prefab-workflow` points to `\\?\\.agents\skills\unity-prefab-workflow` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-prefab-workflow` +\.claude/skills\unity-project-bootstrap: error [R20] symlink `\.claude/skills\unity-project-bootstrap` points to `\\?\\.claude\skills\unity-project-bootstrap` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-project-bootstrap` +\.agents/skills\unity-project-bootstrap: error [R21] symlink `\.agents/skills\unity-project-bootstrap` points to `\\?\\.agents\skills\unity-project-bootstrap` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-project-bootstrap` +\.claude/skills\unity-scene-create: error [R20] symlink `\.claude/skills\unity-scene-create` points to `\\?\\.claude\skills\unity-scene-create` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-scene-create` +\.agents/skills\unity-scene-create: error [R21] symlink `\.agents/skills\unity-scene-create` points to `\\?\\.agents\skills\unity-scene-create` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-scene-create` +\.claude/skills\unity-scene-inspect: error [R20] symlink `\.claude/skills\unity-scene-inspect` points to `\\?\\.claude\skills\unity-scene-inspect` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-scene-inspect` +\.agents/skills\unity-scene-inspect: error [R21] symlink `\.agents/skills\unity-scene-inspect` points to `\\?\\.agents\skills\unity-scene-inspect` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-scene-inspect` +\.claude/skills\unity-ui-automation: error [R20] symlink `\.claude/skills\unity-ui-automation` points to `\\?\\.claude\skills\unity-ui-automation` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-ui-automation` +\.agents/skills\unity-ui-automation: error [R21] symlink `\.agents/skills\unity-ui-automation` points to `\\?\\.agents\skills\unity-ui-automation` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-ui-automation` +\.claude/skills\unity-ui-toolkit-build: error [R20] symlink `\.claude/skills\unity-ui-toolkit-build` points to `\\?\\.claude\skills\unity-ui-toolkit-build` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-ui-toolkit-build` +\.agents/skills\unity-ui-toolkit-build: error [R21] symlink `\.agents/skills\unity-ui-toolkit-build` points to `\\?\\.agents\skills\unity-ui-toolkit-build` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-ui-toolkit-build` +\.claude/skills\unity-urp-setup: error [R20] symlink `\.claude/skills\unity-urp-setup` points to `\\?\\.claude\skills\unity-urp-setup` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-urp-setup` +\.agents/skills\unity-urp-setup: error [R21] symlink `\.agents/skills\unity-urp-setup` points to `\\?\\.agents\skills\unity-urp-setup` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-urp-setup` +\.claude/skills\unity-vfx-graph: error [R20] symlink `\.claude/skills\unity-vfx-graph` points to `\\?\\.claude\skills\unity-vfx-graph` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-vfx-graph` +\.agents/skills\unity-vfx-graph: error [R21] symlink `\.agents/skills\unity-vfx-graph` points to `\\?\\.agents\skills\unity-vfx-graph` but expected `\\?\\.claude-plugin\plugins\unity-cli\skills\unity-vfx-graph` + +23 skills checked, 46 violations +error: process didn't exit successfully: `target\debug\unity-cli.exe skills lint --severity error` (exit code: 1) diff --git a/docs/verification/issue-386/staff-final-operations.json b/docs/verification/issue-386/staff-final-operations.json new file mode 100644 index 00000000..962ee9f0 --- /dev/null +++ b/docs/verification/issue-386/staff-final-operations.json @@ -0,0 +1,140 @@ +[ + { + "name": "editor_state", + "tool": "get_editor_state", + "status": "PASS", + "elapsed_seconds": 0.809 + }, + { + "name": "hierarchy", + "tool": "get_hierarchy", + "status": "PASS", + "elapsed_seconds": 0.428 + }, + { + "name": "find_gameobject", + "tool": "find_gameobject", + "status": "PASS", + "elapsed_seconds": 0.056 + }, + { + "name": "transform", + "tool": "get_component_values", + "status": "PASS", + "elapsed_seconds": 0.064 + }, + { + "name": "position", + "tool": "modify_gameobject", + "status": "PASS", + "elapsed_seconds": 0.049 + }, + { + "name": "create_cube", + "tool": "create_gameobject", + "status": "PASS", + "elapsed_seconds": 0.04 + }, + { + "name": "add_component", + "tool": "add_component", + "status": "PASS", + "elapsed_seconds": 0.055 + }, + { + "name": "remove_component", + "tool": "remove_component", + "status": "PASS", + "elapsed_seconds": 0.049 + }, + { + "name": "delete_gameobject", + "tool": "delete_gameobject", + "status": "PASS", + "elapsed_seconds": 0.054 + }, + { + "name": "scene_info", + "tool": "get_scene_info", + "status": "PASS", + "elapsed_seconds": 0.042 + }, + { + "name": "scene_save", + "tool": "save_scene", + "status": "PASS", + "elapsed_seconds": 0.059 + }, + { + "name": "console", + "tool": "read_console", + "status": "PASS", + "elapsed_seconds": 0.047 + }, + { + "name": "screenshot", + "tool": "capture_screenshot", + "status": "PASS", + "elapsed_seconds": 0.113 + }, + { + "name": "material_search", + "tool": "manage_asset_database", + "status": "PASS", + "elapsed_seconds": 0.223 + }, + { + "name": "asset_copy", + "tool": "manage_asset_database", + "status": "PASS", + "elapsed_seconds": 0.07 + }, + { + "name": "asset_move", + "tool": "manage_asset_database", + "status": "PASS", + "elapsed_seconds": 0.089 + }, + { + "name": "asset_delete", + "tool": "manage_asset_database", + "status": "PASS", + "elapsed_seconds": 0.271 + }, + { + "name": "import_settings", + "tool": "manage_asset_import_settings", + "status": "PASS", + "elapsed_seconds": 0.047 + }, + { + "name": "material_modify", + "tool": "modify_material", + "status": "PASS", + "elapsed_seconds": 0.084 + }, + { + "name": "time_settings", + "tool": "get_project_settings", + "status": "PASS", + "elapsed_seconds": 0.247 + }, + { + "name": "read_csharp", + "tool": "read", + "status": "PASS", + "elapsed_seconds": 0.036 + }, + { + "name": "play_until_ready", + "tool": "play_game", + "status": "PASS", + "elapsed_seconds": 0.979 + }, + { + "name": "stop_until_ready", + "tool": "stop_game", + "status": "PASS", + "elapsed_seconds": 0.893 + } +] diff --git a/docs/verification/issue-386/staff-final-summary.json b/docs/verification/issue-386/staff-final-summary.json new file mode 100644 index 00000000..50dba718 --- /dev/null +++ b/docs/verification/issue-386/staff-final-summary.json @@ -0,0 +1,610 @@ +{ + "started_at": "2026-10-03T14:58:11.479989+00:00", + "source_commit": "338f426119b61123567b74028e7e8fe3bd99caa5", + "binary_sha256": "abb04eca3cee68b3260c4701f6a10b2b053c87c1eaef95423117143cf4288eeb", + "cases": { + "staff-play-settings": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "editor", + "eval", + "\nvar before = new { enabled = UnityEditor.EditorSettings.enterPlayModeOptionsEnabled,\n options = UnityEditor.EditorSettings.enterPlayModeOptions.ToString() };\nUnityEditor.EditorSettings.enterPlayModeOptionsEnabled = true;\nUnityEditor.EditorSettings.enterPlayModeOptions = UnityEditor.EnterPlayModeOptions.DisableDomainReload;\nvar assembly = typeof(UnityEditor.EditorWindow).Assembly;\nvar game = assembly.GetType(\"UnityEditor.GameView\", true);\nUnityEditor.EditorWindow.GetWindow(game, false, \"Game\", false);\nvar type = assembly.GetType(\"UnityEditor.PlayModeView\", true);\nvar property = type.GetProperty(\"enterPlayModeBehavior\");\nforeach (var view in UnityEngine.Resources.FindObjectsOfTypeAll(type))\n property.SetValue(view, System.Enum.Parse(property.PropertyType, \"PlayUnfocused\"));\nreturn before;\n", + "--mode", + "statements" + ], + "exit_code": 0, + "elapsed_seconds": 1.635, + "success": true + }, + "staff-get_editor_state-1": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_editor_state", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.046, + "success": true + }, + "staff-create_scene-2": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "create_scene", + "--json", + "{\"sceneName\": \"Issue386_Staff_1791039493306097700\", \"path\": \"Assets/Scenes/Generated/E2E/Performance\", \"loadScene\": true}" + ], + "exit_code": 0, + "elapsed_seconds": 0.44, + "success": true + }, + "staff-create_gameobject-3": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "create_gameobject", + "--json", + "{\"name\": \"Perf394Target\", \"primitiveType\": \"cube\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.114, + "success": true + }, + "staff-create_material-4": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "create_material", + "--json", + "{\"materialPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfSource.mat\", \"shader\": \"Unlit/Color\", \"overwrite\": true}" + ], + "exit_code": 0, + "elapsed_seconds": 0.392, + "success": true + }, + "staff-save_scene-5": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "save_scene", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.314, + "success": true + }, + "staff-get_editor_state-6": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_editor_state", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.808, + "success": true + }, + "staff-get_hierarchy-7": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_hierarchy", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.427, + "success": true + }, + "staff-find_gameobject-8": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "find_gameobject", + "--json", + "{\"name\": \"Perf394Target\", \"exactMatch\": true}" + ], + "exit_code": 0, + "elapsed_seconds": 0.056, + "success": true + }, + "staff-get_component_values-9": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_component_values", + "--json", + "{\"gameObjectName\": \"Perf394Target\", \"componentType\": \"Transform\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.064, + "success": true + }, + "staff-modify_gameobject-10": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "modify_gameobject", + "--json", + "{\"path\": \"/Perf394Target\", \"position\": {\"x\": 1, \"y\": 2, \"z\": 3}}" + ], + "exit_code": 0, + "elapsed_seconds": 0.048, + "success": true + }, + "staff-create_gameobject-11": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "create_gameobject", + "--json", + "{\"name\": \"Perf394Cube\", \"primitiveType\": \"cube\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.039, + "success": true + }, + "staff-add_component-12": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "add_component", + "--json", + "{\"gameObjectPath\": \"/Perf394Cube\", \"componentType\": \"Rigidbody\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.055, + "success": true + }, + "staff-remove_component-13": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "remove_component", + "--json", + "{\"gameObjectPath\": \"/Perf394Cube\", \"componentType\": \"Rigidbody\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.048, + "success": true + }, + "staff-delete_gameobject-14": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "delete_gameobject", + "--json", + "{\"path\": \"/Perf394Cube\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.053, + "success": true + }, + "staff-get_scene_info-15": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_scene_info", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.042, + "success": true + }, + "staff-save_scene-16": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "save_scene", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.059, + "success": true + }, + "staff-read_console-17": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "read_console", + "--json", + "{\"count\": 20}" + ], + "exit_code": 0, + "elapsed_seconds": 0.046, + "success": true + }, + "staff-capture_screenshot-18": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "capture_screenshot", + "--json", + "{\"captureMode\": \"game\", \"width\": 1280, \"height\": 720, \"includeUI\": false, \"encodeAsBase64\": false, \"osFallback\": false}" + ], + "exit_code": 0, + "elapsed_seconds": 0.113, + "success": true + }, + "staff-manage_asset_database-19": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "manage_asset_database", + "--json", + "{\"action\": \"find_assets\", \"filter\": \"t:Material\", \"searchInFolders\": [\"Assets/Scenes/Generated/E2E/Performance\"]}" + ], + "exit_code": 0, + "elapsed_seconds": 0.223, + "success": true + }, + "staff-manage_asset_database-20": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "manage_asset_database", + "--json", + "{\"action\": \"copy_asset\", \"fromPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfSource.mat\", \"toPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfCopy.mat\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.07, + "success": true + }, + "staff-manage_asset_database-21": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "manage_asset_database", + "--json", + "{\"action\": \"move_asset\", \"fromPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfCopy.mat\", \"toPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfMoved.mat\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.088, + "success": true + }, + "staff-manage_asset_database-22": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "manage_asset_database", + "--json", + "{\"action\": \"delete_asset\", \"assetPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfMoved.mat\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.271, + "success": true + }, + "staff-manage_asset_import_settings-23": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "manage_asset_import_settings", + "--json", + "{\"action\": \"get\", \"assetPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfSource.mat\"}" + ], + "exit_code": 0, + "elapsed_seconds": 0.047, + "success": true + }, + "staff-modify_material-24": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "modify_material", + "--json", + "{\"materialPath\": \"Assets/Scenes/Generated/E2E/Performance/PerfSource.mat\", \"properties\": {\"_Color\": [0.2, 0.4, 0.8, 1]}}" + ], + "exit_code": 0, + "elapsed_seconds": 0.083, + "success": true + }, + "staff-get_project_settings-25": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_project_settings", + "--json", + "{\"includeTime\": true, \"includePlayer\": false}" + ], + "exit_code": 0, + "elapsed_seconds": 0.246, + "success": true + }, + "staff-read-26": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "read", + "--json", + "{\"path\": \"Packages/com.akiojin.unity-cli-bridge/Editor/Core/UnityCliBridgeHost.cs\", \"maxLines\": 50}" + ], + "exit_code": 0, + "elapsed_seconds": 0.036, + "success": true + }, + "staff-play_game-27": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "play_game", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.05, + "success": true + }, + "staff-get_editor_state-28": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_editor_state", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.219, + "success": true + }, + "staff-get_editor_state-29": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_editor_state", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.224, + "success": true + }, + "staff-get_editor_state-30": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_editor_state", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.463, + "success": true + }, + "staff-stop_game-31": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "stop_game", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.463, + "success": true + }, + "staff-get_editor_state-32": { + "argv": [ + "\\target\\debug\\unity-cli.exe", + "--output", + "json", + "--project-path", + "\\.cache\\issue-386\\red-project", + "--timeout-ms", + "60000", + "raw", + "get_editor_state", + "--json", + "{}" + ], + "exit_code": 0, + "elapsed_seconds": 0.429, + "success": true + } + }, + "play_settings": { + "enterPlayModeOptionsEnabled": true, + "enterPlayModeOptions": "DisableDomainReload", + "enterPlayModeBehavior": "PlayUnfocused", + "previous": { + "enabled": false, + "options": "None" + } + }, + "finished_at": "2026-10-03T14:58:19.377632+00:00" +} diff --git a/docs/verification/issue-386/staff-play-settings.stdout.json b/docs/verification/issue-386/staff-play-settings.stdout.json new file mode 100644 index 00000000..de04d7f7 --- /dev/null +++ b/docs/verification/issue-386/staff-play-settings.stdout.json @@ -0,0 +1,25 @@ +{ + "command": "editor eval", + "data": { + "diagnostics": [ + { + "column": 1, + "id": "CS0162", + "line": 19, + "message": "Unreachable code detected", + "severity": "warning" + } + ], + "exception": null, + "logs": [], + "requestId": "cli-23136-18db0ceda6f62ce8-0", + "state": "completed", + "value": { + "enabled": false, + "options": "None" + } + }, + "errors": [], + "success": true, + "warnings": [] +} diff --git a/docs/verification/issue-386/tasklist-14140.json b/docs/verification/issue-386/tasklist-14140.json new file mode 100644 index 00000000..4fa1eaa1 --- /dev/null +++ b/docs/verification/issue-386/tasklist-14140.json @@ -0,0 +1,14 @@ +{ + "argv": [ + "tasklist", + "/FI", + "PID eq 14140", + "/FO", + "CSV", + "/NH" + ], + "exit_code": 0, + "stdout": "\"Unity.exe\",\"14140\",\"RDP-Tcp#0\",\"2\",\"1,638,552 K\"\n", + "stderr": "", + "observed_at": "2026-10-03T15:01:17.338442+00:00" +} diff --git a/docs/verification/issue-386/tasklist-44232.json b/docs/verification/issue-386/tasklist-44232.json new file mode 100644 index 00000000..26a04578 --- /dev/null +++ b/docs/verification/issue-386/tasklist-44232.json @@ -0,0 +1,14 @@ +{ + "argv": [ + "tasklist", + "/FI", + "PID eq 44232", + "/FO", + "CSV", + "/NH" + ], + "exit_code": 0, + "stdout": "\"Unity.exe\",\"44232\",\"RDP-Tcp#0\",\"2\",\"1,648,308 K\"\n", + "stderr": "", + "observed_at": "2026-10-03T15:01:17.661572+00:00" +} diff --git a/docs/verification/issue-386/tasklist-52408.json b/docs/verification/issue-386/tasklist-52408.json new file mode 100644 index 00000000..7f00a5c6 --- /dev/null +++ b/docs/verification/issue-386/tasklist-52408.json @@ -0,0 +1,14 @@ +{ + "argv": [ + "tasklist", + "/FI", + "PID eq 52408", + "/FO", + "CSV", + "/NH" + ], + "exit_code": 0, + "stdout": "\"Unity.exe\",\"52408\",\"RDP-Tcp#0\",\"2\",\"2,026,148 K\"\n", + "stderr": "", + "observed_at": "2026-10-03T15:01:18.042840+00:00" +} diff --git a/docs/verification/issue-386/unity-final.txt b/docs/verification/issue-386/unity-final.txt new file mode 100644 index 00000000..5956fa55 --- /dev/null +++ b/docs/verification/issue-386/unity-final.txt @@ -0,0 +1,2 @@ +Started headless Editor (pid 44188) +11 tests, 0 failed; report: \.cache\issue-386\green-results.xml diff --git a/docs/verification/issue-386/verify-run-second.json b/docs/verification/issue-386/verify-run-second.json new file mode 100644 index 00000000..48622d60 --- /dev/null +++ b/docs/verification/issue-386/verify-run-second.json @@ -0,0 +1 @@ +{"error":"unexpected server response: verify: deferred — host busy for 1500s (budget 1500s): verification lease held by verification 99a8660247f5bc49--verification--8955c99b1a861e67 (pid 49800 alive, job running, nice unknown, spawn-host inherit, 2338s left, 6 batches ≈ 5389s); holder stalled: held 66m13s, its 3 processes gained no CPU time beyond scheduler noise (< 0.5% of one core) over the last 2.7s and none started or exited — it is blocked waiting (I/O, a lock or a prompt) and may be hung; next_turn_reserved: yes; queue_position: 2; rerun `verify.run` in about 5389s (timing hint only; a progressing holder renews its TTL) — a deferral is not a failure and there is no attempt cap: your turn stays reserved, so keep rerunning `verify.run` while the holder makes progress","exit_code":1,"ok":false,"operation":"verify.run"} diff --git a/docs/verification/issue-386/verify-run.json b/docs/verification/issue-386/verify-run.json new file mode 100644 index 00000000..9e397532 --- /dev/null +++ b/docs/verification/issue-386/verify-run.json @@ -0,0 +1 @@ +{"error":"unexpected server response: verify: deferred — host busy for 300s (budget 300s): verification lease held by verification 99a8660247f5bc49--verification--8955c99b1a861e67 (pid 49800 alive, job running, nice unknown, spawn-host inherit, 2694s left, 7 batches ≈ 43s); holder progressing: held 37m01s, its 3 working processes gained 516ms of CPU over the last 1.8s (29.3% of one core); next_turn_reserved: yes; queue_position: 2; rerun `verify.run` in about 43s (timing hint only; a progressing holder renews its TTL) — a deferral is not a failure and there is no attempt cap: your turn stays reserved, so keep rerunning `verify.run` while the holder makes progress","exit_code":1,"ok":false,"operation":"verify.run"} diff --git a/docs/verification/issue-386/winget.json b/docs/verification/issue-386/winget.json new file mode 100644 index 00000000..b59f4a40 --- /dev/null +++ b/docs/verification/issue-386/winget.json @@ -0,0 +1,17 @@ +{ + "argv": [ + "winget", + "show", + "--id", + "akiojin.unity-cli", + "--exact", + "--source", + "winget", + "--accept-source-agreements", + "--disable-interactivity" + ], + "exit_code": 2316632084, + "stdout": "入力条件に一致するパッケージが見つかりませんでした。\n", + "stderr": "", + "observed_at": "2026-10-03T15:01:20.627834+00:00" +} diff --git a/docs/verification/issue-504/README.md b/docs/verification/issue-504/README.md new file mode 100644 index 00000000..f61c9f2a --- /dev/null +++ b/docs/verification/issue-504/README.md @@ -0,0 +1,70 @@ +# Issue #504 — Windows lspd cold-start latency + +Launch mode: autonomous + +User Verification Result: n/a (autonomous) + +Agent Visual Check: n/a (no UI surface) + +## Cause and regression proof + +The Windows client used `TcpStream::connect` without a connection deadline. +The initial tool request, status check, stale-file cleanup probes and readiness +polling repeatedly waited for Windows TCP retries when lspd was absent. +The ten-second read/write timeouts were set only after connecting. + +On Windows 11, a closed loopback port took 2025ms to reject a connection; +a 100ms deadline returned in 110ms. The new production-path regression test +failed before the fix after 2.027s, while the running-listener test passed. +Both tests passed after the fix in 0.11s total. + +Use the same 100ms local connection deadline as unityd. This limits only the +TCP handshake; daemon startup and tool response deadlines remain independent. +Tests use ephemeral ports, avoiding the shared Windows lspd port 6421. + +## Measured results + +The same Windows host and measurement runner used a real CLI and LSP. +`before.json` and `after.json` retain hashes, responses, differences and timings. + +| Condition / write_file | Before n / p50 / p95 (ms) | After n / p50 / p95 (ms) | +| --- | --- | --- | +| daemon_stopped | 3 / 13183.299 / 15134.534 | 5 / 5517.880 / 9375.031 | +| first_download | — | 3 / 6632.017 / 7675.544 | +| warm_indexed | — | 2 / 216.366 / 220.186 | +| unindexed | — | 2 / 712.967 / 719.874 | + +The original CI report in #504 measured about 43 seconds on its Windows host. +The local baseline differs; the PR's existing three-OS LSP Write Reliability +workflow supplies a separate CI comparison. Local cold-start p50 is below 10s. + +All twelve after-fix tool calls returned a successful LSP edit. Published LSP +0.18.1 still added a BOM (#498); byte equality therefore failed in every sample. +These defects remain in the JSON and are accepted only by the existing +version-scoped regression baseline. This report proves latency improvement, +not qualification for prohibiting direct editing. + +## Reproduce + +```bash +cargo test --bin unity-cli lsp::daemon::tests::tcp_connect -- --test-threads=1 +cargo build --bin unity-cli +dotnet publish lsp/Server.csproj -c Release -r win-x64 --self-contained true -o .cache/lsp-reliability-publish +python -B scripts/lsp-write-reliability.py --unity-cli target/debug/unity-cli.exe --lsp-publish .cache/lsp-reliability-publish --out .cache/issue-504-verified --conditions daemon_stopped --scenarios write_file --cold-repetitions 5 --baseline tests/fixtures/lsp-write-baseline.json +python -B docs/verification/issue-504/check-evidence.py .cache/issue-504-verified/results.json +``` + +The evidence checker requires at least three completed Windows cold samples, +successful real LSP responses, no new write defect, and p50 strictly below 10s. + +## Unrelated baseline check + +An additional Windows `dotnet test lsp/Server.Tests.csproj` run produced +54 passes and two failures in the existing +`RequestRouterTests.SymbolQueries_RespectAssetsScopeBeforeScanningPackages` +theory (`workspace/symbol` and `unitycli/referencesByName`): both returned an +empty array instead of `Asset.cs`. No C# source changed in this fix. +`Uri2Path` in `LspRequestRouter.cs` strips `file://` from the test's standard +`file:///C:/...` URI, leaving a Windows path starting with `/C:/...`. +This separate finding was reported to the PM. The full C# suite is verified on +Linux, matching the repository's required `LSP Tests` CI environment. diff --git a/docs/verification/issue-504/after.json b/docs/verification/issue-504/after.json new file mode 100644 index 00000000..55722b1b --- /dev/null +++ b/docs/verification/issue-504/after.json @@ -0,0 +1,597 @@ +{ + "schema_version": 1, + "os": "Windows", + "rid": "win-x64", + "started_at": "2026-10-13T11:44:34.733438+00:00", + "cli_sha256": "37d014406f92518c1b5a019d4ff6e7d4646bcc1f6c1c7ddbd5ddb2150a901ca8", + "runner_sha256": "21d102a80b2be31514117df4e7f10d252a6320c5e6fe4254da4295b08c26898d", + "requested_conditions": [ + "daemon_stopped", + "warm_indexed", + "unindexed", + "first_download" + ], + "repetitions": 2, + "cold_repetitions": 5, + "download_repetitions": 3, + "rows": [ + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "daemon_stopped", + "sample": 0, + "direct_ms": 0.4454000008990988, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 2023.329300001933, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 6411.945699997887, + "lsp_version": "0.18.1", + "lsp_sha256": "255da253cca997a38c2ee4d9daefe1ce843e1ff901c411dbef350b6280291927" + }, + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "daemon_stopped", + "sample": 1, + "direct_ms": 0.5148999989614822, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 2032.4424999998882, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 5262.767399999575, + "lsp_version": "0.18.1", + "lsp_sha256": "255da253cca997a38c2ee4d9daefe1ce843e1ff901c411dbef350b6280291927" + }, + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "daemon_stopped", + "sample": 2, + "direct_ms": 0.49109999963548034, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 2022.2695999982534, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 5517.880100000184, + "lsp_version": "0.18.1", + "lsp_sha256": "255da253cca997a38c2ee4d9daefe1ce843e1ff901c411dbef350b6280291927" + }, + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "daemon_stopped", + "sample": 3, + "direct_ms": 0.9161999987554736, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 2054.629099999147, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 9375.031100000342, + "lsp_version": "0.18.1", + "lsp_sha256": "255da253cca997a38c2ee4d9daefe1ce843e1ff901c411dbef350b6280291927" + }, + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "daemon_stopped", + "sample": 4, + "direct_ms": 0.5122000002302229, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 2045.9140999992087, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 5283.347100001265, + "lsp_version": "0.18.1", + "lsp_sha256": "255da253cca997a38c2ee4d9daefe1ce843e1ff901c411dbef350b6280291927" + }, + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "warm_indexed", + "sample": 0, + "direct_ms": 0.46749999819439836, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 2958.607499997015, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 216.36579999903915, + "lsp_version": "checkout", + "lsp_sha256": "cb04b88cff09ced980c422499010b6986a0af00f8e3473c17b6350c74b1428b9" + }, + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "warm_indexed", + "sample": 1, + "direct_ms": 0.450999999884516, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 2975.8909000011045, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 220.18570000000182, + "lsp_version": "checkout", + "lsp_sha256": "cb04b88cff09ced980c422499010b6986a0af00f8e3473c17b6350c74b1428b9" + }, + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "unindexed", + "sample": 0, + "direct_ms": 0.45089999912306666, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 2272.84729999883, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 712.9674999996496, + "lsp_version": "checkout", + "lsp_sha256": "cb04b88cff09ced980c422499010b6986a0af00f8e3473c17b6350c74b1428b9" + }, + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "unindexed", + "sample": 1, + "direct_ms": 0.4530000005615875, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 2268.4746000013547, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 719.8742000000493, + "lsp_version": "checkout", + "lsp_sha256": "cb04b88cff09ced980c422499010b6986a0af00f8e3473c17b6350c74b1428b9" + }, + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "first_download", + "sample": 0, + "direct_ms": 0.4700999998021871, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 2020.7783000005293, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 6356.362900001841, + "lsp_version": "0.18.1", + "lsp_sha256": "255da253cca997a38c2ee4d9daefe1ce843e1ff901c411dbef350b6280291927" + }, + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "first_download", + "sample": 1, + "direct_ms": 0.5388999998103827, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 2017.9347999983293, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 7675.544499998068, + "lsp_version": "0.18.1", + "lsp_sha256": "255da253cca997a38c2ee4d9daefe1ce843e1ff901c411dbef350b6280291927" + }, + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "first_download", + "sample": 2, + "direct_ms": 0.4291000004741363, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 2031.0315000024275, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 6632.016700001259, + "lsp_version": "0.18.1", + "lsp_sha256": "255da253cca997a38c2ee4d9daefe1ce843e1ff901c411dbef350b6280291927" + } + ], + "summary": { + "attempts": 12, + "successes": 0, + "success_rate": 0.0, + "failure_types": { + "bom_added": 12 + }, + "p50_ms": 5283.347, + "p95_ms": 9375.031, + "direct_p50_ms": 0.467, + "direct_p95_ms": 0.916 + }, + "regressions": [], + "finished_at": "2026-10-13T11:46:02.271422+00:00" +} \ No newline at end of file diff --git a/docs/verification/issue-504/before.json b/docs/verification/issue-504/before.json new file mode 100644 index 00000000..67753944 --- /dev/null +++ b/docs/verification/issue-504/before.json @@ -0,0 +1,193 @@ +{ + "schema_version": 1, + "os": "Windows", + "rid": "win-x64", + "started_at": "2026-10-13T11:38:57.334878+00:00", + "cli_sha256": "380e45c77eafce19fc82f35cade8f18073f9621bb3596250a4ebf89859080117", + "runner_sha256": "21d102a80b2be31514117df4e7f10d252a6320c5e6fe4254da4295b08c26898d", + "requested_conditions": [ + "daemon_stopped" + ], + "repetitions": 5, + "cold_repetitions": 3, + "download_repetitions": 1, + "rows": [ + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "daemon_stopped", + "sample": 0, + "direct_ms": 0.4284999995434191, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 2042.874300001131, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 15134.534499997244, + "lsp_version": "0.18.1", + "lsp_sha256": "255da253cca997a38c2ee4d9daefe1ce843e1ff901c411dbef350b6280291927" + }, + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "daemon_stopped", + "sample": 1, + "direct_ms": 0.44689999776892364, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 2026.9910999995773, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 13183.299099997384, + "lsp_version": "0.18.1", + "lsp_sha256": "255da253cca997a38c2ee4d9daefe1ce843e1ff901c411dbef350b6280291927" + }, + { + "scenario": "write_file", + "tool": "write_csharp_file", + "condition": "daemon_stopped", + "sample": 2, + "direct_ms": 0.45089999912306666, + "failures": [ + "bom_added" + ], + "differences": [ + { + "path": "Assets/Sample.cs", + "direct_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_sha256": "0a376c7da796e5991b0510d7f09bfb751199bb5d4702c07a61ac84cb74ecf34e", + "direct_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "lsp_text_sha256": "908fcb643b9e33e9f39a7a2c816f90d968c11209a0d79441e6a7ce197e2d3cfa", + "direct_bytes": 51, + "lsp_bytes": 54, + "diff": "--- direct/Assets/Sample.cs\n+++ lsp/Assets/Sample.cs\n@@ -1 +1 @@\n-public class Sample { public int Run(){return 2;}}\n+public class Sample { public int Run(){return 2;}}\n" + } + ], + "setup_ms": 2033.2515000009153, + "returncode": 0, + "response": { + "command": "raw write_csharp_file", + "data": { + "applied": true, + "backend": "lsp", + "changedFiles": [ + "Assets/Sample.cs" + ], + "changedSymbols": [], + "diagnostics": [], + "diffPreview": [], + "reason": null, + "success": true + }, + "errors": [], + "success": true, + "warnings": [] + }, + "stdout": "{\"command\":\"raw write_csharp_file\",\"data\":{\"applied\":true,\"backend\":\"lsp\",\"changedFiles\":[\"Assets/Sample.cs\"],\"changedSymbols\":[],\"diagnostics\":[],\"diffPreview\":[],\"reason\":null,\"success\":true},\"errors\":[],\"success\":true,\"warnings\":[]}\n", + "stderr": "", + "elapsed_ms": 13125.072800001362, + "lsp_version": "0.18.1", + "lsp_sha256": "255da253cca997a38c2ee4d9daefe1ce843e1ff901c411dbef350b6280291927" + } + ], + "summary": { + "attempts": 3, + "successes": 0, + "success_rate": 0.0, + "failure_types": { + "bom_added": 3 + }, + "p50_ms": 13183.299, + "p95_ms": 15134.534, + "direct_p50_ms": 0.447, + "direct_p95_ms": 0.451 + }, + "regressions": [ + { + "scenario": "write_file", + "condition": "daemon_stopped", + "new_failures": [ + "bom_added" + ] + }, + { + "scenario": "write_file", + "condition": "daemon_stopped", + "new_failures": [ + "bom_added" + ] + }, + { + "scenario": "write_file", + "condition": "daemon_stopped", + "new_failures": [ + "bom_added" + ] + } + ], + "finished_at": "2026-10-13T11:39:47.394484+00:00" +} \ No newline at end of file diff --git a/docs/verification/issue-504/check-evidence.py b/docs/verification/issue-504/check-evidence.py new file mode 100644 index 00000000..df000c93 --- /dev/null +++ b/docs/verification/issue-504/check-evidence.py @@ -0,0 +1,28 @@ +"""Check the Windows cold-start latency AC without hiding write failures.""" +import importlib.util +import json +from pathlib import Path +import sys + +ROOT = Path(__file__).resolve().parents[3] +SPEC = importlib.util.spec_from_file_location("reliability", ROOT / "scripts/lsp-write-reliability.py") +reliability = importlib.util.module_from_spec(SPEC) +SPEC.loader.exec_module(reliability) + +report_path = Path(sys.argv[1]) if len(sys.argv) > 1 else Path(__file__).with_name("after.json") +report = json.loads(report_path.read_text(encoding="utf-8")) +assert report["os"] == "Windows" and report["rid"] == "win-x64" +assert report.get("finished_at"), "measurement is incomplete" +rows = [row for row in report["rows"] + if row["condition"] == "daemon_stopped" and row["scenario"] == "write_file"] +assert len(rows) >= 3, "at least three independent cold starts are required" +assert len({row["sample"] for row in rows}) == len(rows), "duplicate samples" +for row in rows: + assert row["returncode"] == 0 and not reliability.response_failures(row["returncode"], row["response"]) +baseline = json.loads((ROOT / "tests/fixtures/lsp-write-baseline.json").read_text(encoding="utf-8")) +assert not reliability.regressions(rows, baseline), "a new write defect must not count as a latency pass" +summary = reliability.summarize(rows) +assert summary["p50_ms"] < 10_000, f"Windows daemon_stopped p50 exceeds the AC: {summary}" +print(f"PASS: Windows daemon_stopped/write_file n={len(rows)}, " + f"p50={summary['p50_ms']}ms, p95={summary['p95_ms']}ms; " + f"recorded write defects={summary['failure_types']}") diff --git a/lsp/EditServiceTests.cs b/lsp/EditServiceTests.cs index aaa2109f..2f955732 100644 --- a/lsp/EditServiceTests.cs +++ b/lsp/EditServiceTests.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Text; using System.Text.Json; using System.Threading.Tasks; using UnityCli.Lsp.Core; @@ -163,4 +164,36 @@ public async Task RemoveSymbolAsync_PreviewsWithReferenceCheckWithoutReenteringF } } } + + [Theory] + [InlineData( + "public class Sample { public int Run(){return 1;} // 日本語の説明を保持\npublic int Next(){return 3;} }\n", + "public class Sample { public int Run(){return 2;} // 日本語の説明を保持\npublic int Next(){return 3;} }\n")] + [InlineData( + "public class Sample {\r\n // leading\r\n public int Run()\r\n {\r\n return 1;\r\n } /* tail */\r\n public int Next() => 3;\r\n}\r\n", + "public class Sample {\r\n // leading\r\n public int Run()\r\n {return 2;} /* tail */\r\n public int Next() => 3;\r\n}\r\n")] + [InlineData( + "public class Sample { public int Run() => 1; // expr\npublic int Next(){return 3;} }\n", + "public class Sample { public int Run() {return 2;} // expr\npublic int Next(){return 3;} }\n")] + public async Task ReplaceSymbolBodyAsync_PreservesTrailingTriviaOfReplacedBody(string original, string expected) + { + var root = Path.Combine(Path.GetTempPath(), "unity-cli-replace-body-" + Path.GetRandomFileName()); + Directory.CreateDirectory(Path.Combine(root, "Assets")); + var scriptPath = Path.Combine(root, "Assets", "Sample.cs"); + await File.WriteAllBytesAsync(scriptPath, Encoding.UTF8.GetBytes(original)); + try + { + var service = new LspEditService(root, new LspFileLockProvider()); + + var result = await service.ReplaceSymbolBodyAsync("Assets/Sample.cs", "Sample/Run", "{return 2;}", apply: true); + + using var response = JsonDocument.Parse(JsonSerializer.Serialize(result)); + Assert.True(response.RootElement.GetProperty("applied").GetBoolean()); + Assert.Equal(Encoding.UTF8.GetBytes(expected), await File.ReadAllBytesAsync(scriptPath)); + } + finally + { + Directory.Delete(root, recursive: true); + } + } } diff --git a/lsp/PathUtilitiesTests.cs b/lsp/PathUtilitiesTests.cs index 23fcb635..826500ab 100644 --- a/lsp/PathUtilitiesTests.cs +++ b/lsp/PathUtilitiesTests.cs @@ -50,4 +50,43 @@ public void Path2Uri_UsesFilePrefix() { Assert.Equal("file:///repo/Assets/Scripts/Player.cs", LspPathUtilities.Path2Uri("/repo/Assets/Scripts/Player.cs")); } + + [Theory] + [InlineData(@"C:\repo\Assets\Player.cs", "file:///C:/repo/Assets/Player.cs")] + [InlineData("C:/repo/Assets/Player.cs", "file:///C:/repo/Assets/Player.cs")] + [InlineData(@"\\server\share\Assets\Player.cs", "file://server/share/Assets/Player.cs")] + [InlineData(@"C:\my project\Assets\日本語 #%.cs", "file:///C:/my%20project/Assets/%E6%97%A5%E6%9C%AC%E8%AA%9E%20%23%25.cs")] + [InlineData("/my project/Assets/日本語 #%.cs", "file:///my%20project/Assets/%E6%97%A5%E6%9C%AC%E8%AA%9E%20%23%25.cs")] + [InlineData(@"\\server\my share\Assets\A #%.cs", "file://server/my%20share/Assets/A%20%23%25.cs")] + public void Path2Uri_ProducesCanonicalEscapedFileUris(string path, string expected) + { + Assert.Equal(expected, LspPathUtilities.Path2Uri(path)); + } + + [Theory] + [InlineData(@"C:\repo\Assets\Player.cs", "file:///C:/repo/Assets/Player.cs")] + [InlineData(@"d:\my project\Assets\日本語 #%.cs", "file:///d:/my%20project/Assets/%E6%97%A5%E6%9C%AC%E8%AA%9E%20%23%25.cs")] + [InlineData("/repo/Assets/Player.cs", "file:///repo/Assets/Player.cs")] + [InlineData("/my project/Assets/日本語 #%.cs", "file:///my%20project/Assets/%E6%97%A5%E6%9C%AC%E8%AA%9E%20%23%25.cs")] + [InlineData(@"\\server\share\Assets\Player.cs", "file://server/share/Assets/Player.cs")] + [InlineData(@"\\server\my share\Assets\A #%.cs", "file://server/my%20share/Assets/A%20%23%25.cs")] + [InlineData("/repo/Assets/A %20.cs", "file:///repo/Assets/A%20%2520.cs")] + [InlineData(@"C:\repo\Assets\A %20.cs", "file:///C:/repo/Assets/A%20%2520.cs")] + [InlineData(@"C:\repo\Assets\日本語 # %20.cs", "file:///C:/repo/Assets/%E6%97%A5%E6%9C%AC%E8%AA%9E%20%23%20%2520.cs")] + [InlineData("/repo/Assets/日本語 # %20.cs", "file:///repo/Assets/%E6%97%A5%E6%9C%AC%E8%AA%9E%20%23%20%2520.cs")] + [InlineData(@"\\server\share\Assets\日本語 # %20.cs", "file://server/share/Assets/%E6%97%A5%E6%9C%AC%E8%AA%9E%20%23%20%2520.cs")] + [InlineData("/repo/Assets/A?.cs", "file:///repo/Assets/A%3F.cs")] + public void FileUris_RoundTripPathsAndUris(string path, string uri) + { + Assert.Equal(path, LspPathUtilities.Uri2Path(uri)); + Assert.Equal(path, LspPathUtilities.Uri2Path(LspPathUtilities.Path2Uri(path))); + Assert.Equal(uri, LspPathUtilities.Path2Uri(LspPathUtilities.Uri2Path(uri))); + } + + [Fact] + public void FileUriConversions_RejectNonFileUris() + { + Assert.Throws(() => LspPathUtilities.Uri2Path("https://example.com/Asset.cs")); + Assert.Throws(() => LspPathUtilities.Path2Uri("https://example.com/Asset.cs")); + } } diff --git a/lsp/RequestRouterTests.cs b/lsp/RequestRouterTests.cs index 39ff6adc..2067176b 100644 --- a/lsp/RequestRouterTests.cs +++ b/lsp/RequestRouterTests.cs @@ -10,7 +10,7 @@ public sealed class RequestRouterTests [InlineData("unitycli/referencesByName", "name")] public async Task SymbolQueries_RespectAssetsScopeBeforeScanningPackages(string method, string key) { - var root = Path.Combine(Path.GetTempPath(), "lsp-scope-" + Path.GetRandomFileName()); + var root = Path.Combine(Path.GetTempPath(), "lsp scope 日本語 #%-" + Path.GetRandomFileName()); Directory.CreateDirectory(Path.Combine(root, "Assets")); Directory.CreateDirectory(Path.Combine(root, "Packages")); File.WriteAllText(Path.Combine(root, "Assets", "Asset.cs"), "class ScopeProbe {}"); @@ -31,6 +31,19 @@ public async Task SymbolQueries_RespectAssetsScopeBeforeScanningPackages(string var json = JsonSerializer.Serialize(response.Payload); Assert.Contains("Asset.cs", json); Assert.DoesNotContain("Package.cs", json); + if (method == "workspace/symbol") + { + using var payload = JsonDocument.Parse(json); + var symbol = Assert.Single(payload.RootElement.GetProperty("result").EnumerateArray()); + var uri = symbol.GetProperty("location").GetProperty("uri").GetString(); + Assert.Equal(new System.Uri(Path.Combine(root, "Assets", "Asset.cs")).AbsoluteUri, uri); + using var documentRequest = JsonDocument.Parse(JsonSerializer.Serialize(new { + id = 3, method = "textDocument/documentSymbol", + @params = new { textDocument = new { uri } } + })); + var documentResponse = await router.HandleAsync(documentRequest.RootElement); + Assert.Contains("ScopeProbe", JsonSerializer.Serialize(documentResponse.Payload)); + } } finally { Directory.Delete(root, recursive: true); } } @@ -48,6 +61,7 @@ public async Task HandleAsync_Ping_ReturnsJsonRpcResponsePayload() Assert.False(result.ShouldExit); Assert.Contains("\"id\":7", json); Assert.Contains("\"ok\":true", json); + Assert.Contains("\"fileUriEncoding\":true", json); } [Fact] diff --git a/lsp/Server.Core/LspEditService.cs b/lsp/Server.Core/LspEditService.cs index 1756888e..cc299e22 100644 --- a/lsp/Server.Core/LspEditService.cs +++ b/lsp/Server.Core/LspEditService.cs @@ -35,7 +35,7 @@ public async Task RenameByNamePathAsync(string relative, string namePath var handle = await AcquireFileLockAsync(full); try { - var text = await File.ReadAllTextAsync(full); + var (text, format) = await LspSourceFile.ReadAsync(full); var tree = CSharpSyntaxTree.ParseText(text); var root = await tree.GetRootAsync(); var normalizedNamePath = NormalizeNamePath(namePath); @@ -147,7 +147,7 @@ public async Task RenameByNamePathAsync(string relative, string namePath if (newText == text) return EditResult(false, false, reason: "no_change"); if (apply) { - await File.WriteAllTextAsync(full, newText, Encoding.UTF8); + await LspSourceFile.WriteAsync(full, newText, format); return EditResult( true, true, @@ -169,6 +169,7 @@ public async Task RenameByNamePathAsync(string relative, string namePath var rewrittenFullText = newRoot.ToFullString(); var updatedFiles = new Dictionary(StringComparer.OrdinalIgnoreCase) { [full] = rewrittenFullText }; var originalByFile = new Dictionary(StringComparer.OrdinalIgnoreCase) { [full] = text }; + var formatByFile = new Dictionary(StringComparer.OrdinalIgnoreCase) { [full] = format }; void TrackRenameChanges(string file, string originalSrc, SyntaxNode currentRoot) { var tokens = currentRoot.DescendantTokens().Where(tk => tk.IsKind(SyntaxKind.IdentifierToken) && tk.ValueText == oldName).ToArray(); @@ -221,7 +222,8 @@ void TrackRenameChanges(string file, string originalSrc, SyntaxNode currentRoot) var fileHandle = await AcquireFileLockAsync(file); try { - var src = await File.ReadAllTextAsync(file); + var (src, fileFormat) = await LspSourceFile.ReadAsync(file); + formatByFile[file] = fileFormat; var t = CSharpSyntaxTree.ParseText(src); var r = await t.GetRootAsync(); TrackRenameChanges(file, src, r); @@ -255,7 +257,7 @@ void TrackRenameChanges(string file, string originalSrc, SyntaxNode currentRoot) locks.Add(await AcquireFileLockAsync(file)); } foreach (var kv in updatedFiles) - await File.WriteAllTextAsync(kv.Key, kv.Value, Encoding.UTF8); + await LspSourceFile.WriteAsync(kv.Key, kv.Value, formatByFile[kv.Key]); } finally { @@ -371,8 +373,8 @@ public async Task WriteCSharpFileAsync(string relative, string newText, var handle = await AcquireFileLockAsync(full); try { - var original = await File.ReadAllTextAsync(full); - var updated = MaybeFormatText(newText ?? string.Empty, format); + var (original, fileFormat) = await LspSourceFile.ReadAsync(full); + var updated = fileFormat.ApplyNewlines(MaybeFormatText(newText ?? string.Empty, format)); var diagnostics = validate ? CollectSyntaxDiagnostics(updated).Cast().ToArray() : Array.Empty(); if (validate && HasErrorDiagnostics(diagnostics.Cast>())) { @@ -393,7 +395,7 @@ public async Task WriteCSharpFileAsync(string relative, string newText, reason: "preview_only"); } - await File.WriteAllTextAsync(full, updated, Encoding.UTF8); + await LspSourceFile.WriteAsync(full, updated, fileFormat); return EditResult( true, true, @@ -412,8 +414,8 @@ public async Task CreateCSharpFileAsync(string relative, string text, bo var exists = File.Exists(full); if (exists && !overwrite) return EditResult(false, false, reason: "file_exists"); - var original = exists ? await File.ReadAllTextAsync(full) : string.Empty; - var normalizedText = MaybeFormatText(text ?? string.Empty, format); + var (original, fileFormat) = exists ? await LspSourceFile.ReadAsync(full) : (string.Empty, LspSourceFileFormat.NewFile); + var normalizedText = fileFormat.ApplyNewlines(MaybeFormatText(text ?? string.Empty, format)); var diagnostics = validate ? CollectSyntaxDiagnostics(normalizedText).Cast().ToArray() : Array.Empty(); if (validate && HasErrorDiagnostics(diagnostics.Cast>())) { @@ -435,7 +437,7 @@ public async Task CreateCSharpFileAsync(string relative, string text, bo } Directory.CreateDirectory(Path.GetDirectoryName(full)!); - await File.WriteAllTextAsync(full, normalizedText, Encoding.UTF8); + await LspSourceFile.WriteAsync(full, normalizedText, fileFormat); return EditResult( true, true, @@ -447,6 +449,7 @@ public async Task ApplyCSharpEditsAsync(JsonElement files, bool validate { var desired = new Dictionary(StringComparer.OrdinalIgnoreCase); var originals = new Dictionary(StringComparer.OrdinalIgnoreCase); + var formats = new Dictionary(StringComparer.OrdinalIgnoreCase); var diagnostics = new List(); foreach (var item in files.EnumerateArray()) @@ -463,8 +466,8 @@ public async Task ApplyCSharpEditsAsync(JsonElement files, bool validate return EditResult(false, false, reason: "duplicate_path"); } - originals[full] = await File.ReadAllTextAsync(full); - var formatted = MaybeFormatText(newText, format); + (originals[full], formats[full]) = await LspSourceFile.ReadAsync(full); + var formatted = formats[full].ApplyNewlines(MaybeFormatText(newText, format)); desired[full] = formatted; if (validate) { @@ -513,7 +516,7 @@ public async Task ApplyCSharpEditsAsync(JsonElement files, bool validate } foreach (var file in changed) { - await File.WriteAllTextAsync(file, desired[file], Encoding.UTF8); + await LspSourceFile.WriteAsync(file, desired[file], formats[file]); } } finally @@ -532,12 +535,18 @@ public async Task ReplaceSymbolBodyAsync(string relative, string namePat var handle = await AcquireFileLockAsync(full); try { - var text = await File.ReadAllTextAsync(full); + var (text, format) = await LspSourceFile.ReadAsync(full); var tree = CSharpSyntaxTree.ParseText(text); var root = await tree.GetRootAsync(); var (_, last) = FindNodeByNamePath(root, normalizedPath); if (last is not MethodDeclarationSyntax method) return EditResult(false, false, reason: "symbol_not_found"); var block = ParseBlock(bodyText); + // keep the trivia around the replaced body (e.g. a trailing comment and the newline after `}`) + var (leading, trailing) = method.Body is { } oldBody + ? (oldBody.GetLeadingTrivia(), oldBody.GetTrailingTrivia()) + : (method.ExpressionBody?.GetLeadingTrivia() ?? default, + method.SemicolonToken.TrailingTrivia); + block = block.WithLeadingTrivia(leading).WithTrailingTrivia(trailing); // handle expression-bodied to block conversion var m2 = method.WithExpressionBody(null).WithSemicolonToken(default).WithBody(block); var newRoot = root.ReplaceNode(method, m2); @@ -545,7 +554,7 @@ public async Task ReplaceSymbolBodyAsync(string relative, string namePat if (newText == text) return EditResult(false, false, reason: "no_change"); if (apply) { - await File.WriteAllTextAsync(full, newText, Encoding.UTF8); + await LspSourceFile.WriteAsync(full, newText, format); return EditResult( true, true, @@ -574,7 +583,7 @@ public async Task InsertAroundSymbolAsync(string relative, string namePa var handle = await AcquireFileLockAsync(full); try { - var original = await File.ReadAllTextAsync(full); + var (original, format) = await LspSourceFile.ReadAsync(full); var tree = CSharpSyntaxTree.ParseText(original); var root = await tree.GetRootAsync(); var (_, last) = FindNodeByNamePath(root, normalizedPath); @@ -589,7 +598,7 @@ public async Task InsertAroundSymbolAsync(string relative, string namePa if (newText0 == original) return EditResult(false, false, reason: "no_change"); if (apply) { - await File.WriteAllTextAsync(full, newText0, Encoding.UTF8); + await LspSourceFile.WriteAsync(full, newText0, format); return EditResult( true, true, @@ -627,7 +636,7 @@ public async Task InsertAroundSymbolAsync(string relative, string namePa if (newText1 == original) return EditResult(false, false, reason: "no_change"); if (apply) { - await File.WriteAllTextAsync(full, newText1, Encoding.UTF8); + await LspSourceFile.WriteAsync(full, newText1, format); return EditResult( true, true, @@ -646,7 +655,7 @@ public async Task InsertAroundSymbolAsync(string relative, string namePa if (newText == original) return EditResult(false, false, reason: "no_change"); if (apply) { - await File.WriteAllTextAsync(full, newText, Encoding.UTF8); + await LspSourceFile.WriteAsync(full, newText, format); return EditResult( true, true, @@ -857,7 +866,7 @@ public async Task RemoveSymbolAsync(string relative, string namePath, bo try { // Locate target declaration first - var original = await File.ReadAllTextAsync(full); + var (original, format) = await LspSourceFile.ReadAsync(full); var tree0 = CSharpSyntaxTree.ParseText(original); var root0 = await tree0.GetRootAsync(); var (_, targetNode) = FindNodeByNamePath(root0, normalizedPath); @@ -942,7 +951,7 @@ void CollectReferences(string file, SyntaxNode syntaxRoot) changedFiles: new[] { NormalizeRelative(relative) }, changedSymbols: new[] { normalizedPath }); } - await File.WriteAllTextAsync(full, newText, Encoding.UTF8); + await LspSourceFile.WriteAsync(full, newText, format); return EditResult( true, true, diff --git a/lsp/Server.Core/LspPathUtilities.cs b/lsp/Server.Core/LspPathUtilities.cs index 13484265..e77a0ce4 100644 --- a/lsp/Server.Core/LspPathUtilities.cs +++ b/lsp/Server.Core/LspPathUtilities.cs @@ -7,8 +7,41 @@ public static class LspPathUtilities public static string NormalizeRelative(string relative) => (relative ?? string.Empty).Replace('\\', '/'); - public static string Path2Uri(string path) => - "file://" + path.Replace('\\', '/'); + public static string Path2Uri(string path) + { + var normalized = path.Replace('\\', '/'); + // Escape raw path segments before parsing so literal % sequences survive. + if (normalized.Length >= 3 && char.IsAsciiLetter(normalized[0]) + && normalized[1] == ':' && normalized[2] == '/') + { + return FileUri("file:///" + normalized[..2] + EscapePath(normalized[2..])).AbsoluteUri; + } + + if (!normalized.StartsWith("/", StringComparison.Ordinal)) + { + throw new ArgumentException("Expected an absolute file path.", nameof(path)); + } + + var prefix = normalized.StartsWith("//", StringComparison.Ordinal) ? "file:" : "file://"; + return FileUri(prefix + EscapePath(normalized)).AbsoluteUri; + } + + private static string EscapePath(string path) => + string.Join('/', path.Split('/').Select(Uri.EscapeDataString)); + + public static string Uri2Path(string uri) => + FileUri(uri).LocalPath; + + private static Uri FileUri(string value) + { + var uri = new Uri(value, UriKind.Absolute); + if (!uri.IsFile) + { + throw new ArgumentException("Expected an absolute file path or file URI.", nameof(value)); + } + + return uri; + } public static string ToRel(string fullPath, string root) { diff --git a/lsp/Server.Core/LspRequestRouter.cs b/lsp/Server.Core/LspRequestRouter.cs index 03017845..7ac87279 100644 --- a/lsp/Server.Core/LspRequestRouter.cs +++ b/lsp/Server.Core/LspRequestRouter.cs @@ -124,7 +124,7 @@ public async Task HandleAsync(JsonElement root) if (method == "unitycli/ping") { - return Response(id, new { ok = true }); + return Response(id, new { ok = true, fileUriEncoding = true }); } if (method == "unitycli/referencesByName") @@ -264,15 +264,8 @@ private static LspRouterResult Response(JsonElement id, object? result) => _ => null }; - private static string Uri2Path(string uri) - { - if (uri.StartsWith("file://", StringComparison.Ordinal)) - { - uri = uri.Substring("file://".Length); - } - - return uri.Replace('/', Path.DirectorySeparatorChar); - } + private static string Uri2Path(string uri) => + LspPathUtilities.Uri2Path(uri); private static string Path2Uri(string path) => LspPathUtilities.Path2Uri(path); diff --git a/lsp/Server.Core/LspSourceFile.cs b/lsp/Server.Core/LspSourceFile.cs new file mode 100644 index 00000000..ef6e5bd1 --- /dev/null +++ b/lsp/Server.Core/LspSourceFile.cs @@ -0,0 +1,444 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Text; + +namespace UnityCli.Lsp.Core; + +/// +/// On-disk shape of a C# source file that LSP writes must keep: the encoding (and whether it +/// carries a BOM) and the newline convention. New files are UTF-8 without a BOM. +/// +public readonly record struct LspSourceFileFormat(Encoding Encoding, string? NewLine) +{ + private static readonly Encoding Utf8NoBom = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false); + + public static LspSourceFileFormat NewFile { get; } = new(Utf8NoBom, null); + + public static LspSourceFileFormat Detect(byte[] bytes) => Decode(bytes).Format; + + public static (string Text, LspSourceFileFormat Format) Decode(byte[] bytes) + { + var encoding = DetectEncoding(bytes); + var preamble = encoding.GetPreamble().Length; + var text = encoding.GetString(bytes, preamble, bytes.Length - preamble); + return (text, new LspSourceFileFormat(encoding, DetectNewLine(text))); + } + + /// + /// Rewrites line breaks (CRLF, LF, and a lone CR, which C# also treats as a line terminator) to the + /// file's convention; mixed or unknown conventions are left as given. A lone CR inside a string + /// literal is part of the string's value and is kept. + /// + public string ApplyNewlines(string text) => ApplyNewlines(text, MaxScanStates); + + internal string ApplyNewlines(string text, int maxScanStates) + { + if (NewLine is null) return text; + var hasLoneCr = HasLoneCr(text); + var literalCrs = hasLoneCr ? FindLoneCrsInStringLiterals(text, maxScanStates) : null; + // A scan over its state budget keeps every lone CR: rewriting one inside a string changes its value. + var keepAll = hasLoneCr && literalCrs is null; + var result = new StringBuilder(text.Length); + for (var i = 0; i < text.Length; i++) + { + var c = text[i]; + if (c == '\n') result.Append(NewLine); + else if (c != '\r') result.Append(c); + else if (i + 1 < text.Length && text[i + 1] == '\n') { result.Append(NewLine); i++; } + else result.Append(keepAll || literalCrs?.Contains(i) == true ? "\r" : NewLine); + } + return result.ToString(); + } + + // Plain CRLF input has no lone CR to classify, so it skips parsing. + private static bool HasLoneCr(string text) + { + for (var i = text.IndexOf('\r'); i >= 0; i = text.IndexOf('\r', i + 1)) + { + if (i + 1 >= text.Length || text[i + 1] != '\n') return true; + } + return false; + } + + private const int MaxScanStates = 200_000; + + // Returns null when the scan exceeds maxStates. + private static HashSet? FindLoneCrsInStringLiterals(string text, int maxStates) => new LiteralCrScan(text, maxStates).Run(); + + private enum DirectiveKind { Other, If, Elif, Else, EndIf } + + // Walks every lexer state that some preprocessor configuration reaches, independent of the current + // project's symbols: each #if/#elif condition may be true or false. Code is lexed only from the line + // after a directive, where the lexer state is fresh, so an unterminated comment or string in one + // branch never decides how another branch is lexed. A skipped branch is scanned line by line as + // Roslyn does, so a directive-looking line inside its strings ends the branch, while the same line + // lexed as active code is string content. A lone CR is kept when any reached state reads it inside + // a well-formed string; an unterminated string token is not valid C# in that configuration and keeps + // nothing. + // + // A state is the innermost open #if group, a position at its level, and whether the group has passed + // its #else; nothing below the innermost group decides what happens at that level. Each group is + // solved once: the positions after its #endif are its exits, and every caller resumes at each exit + // with its own state. The cost therefore follows the directive count rather than the number of + // configurations or the nesting depth. + private sealed class LiteralCrScan + { + private const int Root = -1; + private static readonly CSharpParseOptions Options = CSharpParseOptions.Default.WithPreprocessorSymbols(Lines.TakenSymbol); + private readonly string _text; + private readonly string _lexText; + private readonly int _lastCommentEnd; + private readonly int _maxStates; + private readonly HashSet _positions = new(); + private readonly Dictionary _nextDirective = new(); + private readonly Lines _lines; + private readonly HashSet<(int Group, int Position, bool AfterElse)> _active = new(); + private readonly Stack<(int Group, int Position, bool AfterElse)> _pending = new(); + private readonly Dictionary> _exits = new(); + private readonly Dictionary> _callers = new(); + + public LiteralCrScan(string text, int maxStates) + { + _text = text; + _maxStates = maxStates; + _lines = new Lines(text); + _lexText = _lines.WithTakenConditions(); + _lastCommentEnd = text.LastIndexOf("*/", StringComparison.Ordinal); + } + + public HashSet? Run() + { + Active(Root, 0, afterElse: false); + while (_pending.TryPop(out var state)) + { + if (_active.Count + _exits.Count > _maxStates) return null; + ScanActive(state.Group, state.Position, state.AfterElse); + } + return _positions; + } + + // Group is the position after the innermost open #if, or Root at the file level. + private void Active(int group, int position, bool afterElse) + { + if (_active.Add((group, position, afterElse))) _pending.Push((group, position, afterElse)); + } + + // Roslyn reports a stray #elif/#else/#endif, or an #elif/#else after the group's #else, as a bad + // directive and keeps lexing in the same state. + private void ScanActive(int group, int position, bool afterElse) + { + if (NextDirective(position) is not var (kind, end)) return; + var inGroup = group != Root; + switch (kind) + { + case DirectiveKind.If: + Enter(end, group, afterElse); + break; + case DirectiveKind.Elif or DirectiveKind.Else when inGroup && !afterElse: + // The rest of the group is skipped; only its #endif matters. + if (_lines.MatchingEndIf(end) is { } endIf) Exit(group, _lines.LineEnd(endIf)); + break; + case DirectiveKind.EndIf when inGroup: + Exit(group, end); + break; + default: + Active(group, end, afterElse); + break; + } + } + + // Opens the group whose #if ends at start; the caller resumes after each of its exits. + private void Enter(int start, int caller, bool callerAfterElse) + { + var isNew = !_exits.TryGetValue(start, out var exits); + if (isNew) _exits[start] = exits = new List(); + if (!_callers.TryGetValue(start, out var callers)) _callers[start] = callers = new List<(int, bool)>(); + if (callers.Contains((caller, callerAfterElse))) return; + callers.Add((caller, callerAfterElse)); + foreach (var exit in exits!) Active(caller, exit, callerAfterElse); + if (!isNew) return; + + // Taken: the #if branch. Skipped: each later #elif may be the first branch taken, and an #else is + // taken once every earlier condition is false. + Active(start, start, afterElse: false); + foreach (var (kind, line) in _lines.Branches(start)) + { + var next = _lines.LineEnd(line); + if (kind == DirectiveKind.Elif) Active(start, next, afterElse: false); + else if (kind == DirectiveKind.Else) + { + Active(start, next, afterElse: true); + return; + } + else Exit(start, next); + } + } + + private void Exit(int group, int position) + { + var exits = _exits[group]; + if (exits.Contains(position)) return; + exits.Add(position); + foreach (var (caller, afterElse) in _callers[group]) Active(caller, position, afterElse); + } + + // Lexes active code from a line start up to the next directive and records the CRs of the + // well-formed strings on the way. Lexing is independent of the group, so it runs once per start. + // The lexer reads a token's whole leading trivia before returning it, so it lexes a window that + // doubles until the next directive's line is inside it; tokens before that line end before it, + // so the window does not change them. + private (DirectiveKind Kind, int End)? NextDirective(int position) + { + if (_nextDirective.TryGetValue(position, out var cached)) return cached; + for (var length = 512; ; length *= 2) + { + var end = (int)Math.Min(_text.Length, (long)position + length); + var complete = end == _text.Length; + var strings = new List(); + (DirectiveKind, int)? next = null; + var found = false; + foreach (var token in SyntaxFactory.ParseTokens(_lexText.Substring(position, end - position), 0, position, Options)) + { + var directive = token.LeadingTrivia.FirstOrDefault(trivia => trivia.IsDirective); + if (directive.IsDirective) + { + var start = directive.SpanStart; + while (start > 0 && !SyntaxFacts.IsNewLine(_text[start - 1])) start--; + var lineEnd = _lines.LineEnd(start); + found = complete || lineEnd < end; + next = (_lines.Classify(start), lineEnd); + break; + } + if (token.IsKind(SyntaxKind.EndOfFileToken)) + { + found = complete || IsUnterminatedComment(token.LeadingTrivia.LastOrDefault()); + break; + } + strings.Add(token); + } + if (!found) continue; + foreach (var token in strings) CollectString(token); + _nextDirective[position] = next; + return next; + } + } + + // A block comment with no "*/" after its opening runs to the end of the file, hiding everything after it. + private bool IsUnterminatedComment(SyntaxTrivia trivia) => + trivia.IsKind(SyntaxKind.MultiLineCommentTrivia) && _lastCommentEnd < trivia.SpanStart + 2; + + private void CollectString(SyntaxToken token, int offset = 0) + { + if (token.IsKind(SyntaxKind.InterpolatedStringToken)) + { + // The lexer reads an interpolated string as one token; its holes are code, not content. + // Judge each parsed literal separately: a closed literal in a hole still counts when + // the outer interpolation is unterminated. HasError rejects only the outer text. + // Error recovery may put a closed inner literal in skipped-token trivia. + foreach (var part in SyntaxFactory.ParseExpression(token.Text, options: Options).DescendantTokens(descendIntoTrivia: true)) + { + CollectString(part, offset + token.SpanStart); + } + } + else if (IsMultiLineStringContent(token.Kind()) && !HasError(token)) Add(offset + token.SpanStart, offset + token.Span.End); + } + + private void Add(int start, int end) + { + for (var i = start; i < end; i++) + { + if (_text[i] == '\r' && (i + 1 >= _text.Length || _text[i + 1] != '\n')) _positions.Add(i); + } + } + + // An unterminated literal (CS1039, CS8997) runs past where the string really ends, so its extent is + // wrong; other errors, such as raw-string indentation, leave the extent intact. An interpolated + // string's text token is well-formed only when the enclosing literal is closed. Only the token's + // own diagnostics count: trailing trivia can hold a later, unrelated literal's. + private static bool IsUnterminated(SyntaxToken token) => token.WithoutTrivia().GetDiagnostics().Any(d => d.Id is "CS1039" or "CS8997"); + + private static bool HasError(SyntaxToken token) + { + var literal = token.IsKind(SyntaxKind.InterpolatedStringTextToken) ? token.Parent?.Parent : null; + return IsUnterminated(token) || literal is InterpolatedStringExpressionSyntax interpolated && interpolated.StringEndToken.IsMissing; + } + + } + + // The lines as Roslyn's scan of skipped text sees them, indexed so that a skipped group's #elif, #else, + // and #endif lines are found without rescanning the group. A skipped group ends at the first #endif + // that brings the #if/#endif count back below its level. + private sealed class Lines + { + private readonly string _text; + private readonly List _starts = new(); + private readonly Dictionary _index = new(); + private readonly List _kinds = new(); + // The #if minus #endif count before each line. + private readonly List _levels = new(); + private readonly Dictionary> _endIfsByLevel = new(); + private readonly Dictionary> _branchesByLevel = new(); + + public Lines(string text) + { + _text = text; + var level = 0; + for (var position = 0; position < text.Length; position = LineEnd(position)) + { + var line = _starts.Count; + var kind = Classify(position); + _index[position] = line; + _starts.Add(position); + _kinds.Add(kind); + _levels.Add(level); + if (kind == DirectiveKind.EndIf) Lookup(_endIfsByLevel, level).Add(line); + else if (kind is DirectiveKind.Elif or DirectiveKind.Else) Lookup(_branchesByLevel, level).Add(line); + if (kind == DirectiveKind.If) level++; + else if (kind == DirectiveKind.EndIf) level--; + } + } + + public const string TakenSymbol = "_"; + + // The lexer reads a whole skipped group before the token after a false #if, which would make + // lexing up to the next directive cost the rest of a deeply nested file. The copy it lexes has each + // #if condition made only of plain characters replaced, in place, by a defined symbol. Such + // characters lex the same as the symbol and spaces inside a string, comment, or skipped text, + // so token boundaries and offsets are unchanged. + public string WithTakenConditions() + { + var copy = _text.ToCharArray(); + for (var line = 0; line < _starts.Count; line++) + { + if (_kinds[line] != DirectiveKind.If) continue; + var start = SkipWhitespace(_text.IndexOf('#', _starts[line]) + 1) + "if".Length; + var end = start; + while (end < _text.Length && !SyntaxFacts.IsNewLine(_text[end])) end++; + // At least two characters: a space keeps the symbol apart from "if". + if (end - start < 2 || _text[start..end].Trim().Length == 0 || !_text[start..end].All(IsPlainConditionCharacter)) continue; + for (var i = start; i < end; i++) copy[i] = ' '; + copy[end - 1] = TakenSymbol[0]; + } + return new string(copy); + } + + private static bool IsPlainConditionCharacter(char c) => + char.IsAsciiLetterOrDigit(c) || c is '_' or '!' or '&' or '|' or '(' or ')' or '=' or ' ' or '\t'; + + // The start of the #endif line that closes the skipped group starting at position, if any. + public int? MatchingEndIf(int position) => + _index.TryGetValue(position, out var line) && EndIfLine(line) is { } endIf ? _starts[endIf] : null; + + // The #elif and #else lines at the level of the skipped group starting at position, then its #endif. + public IEnumerable<(DirectiveKind Kind, int Start)> Branches(int position) + { + if (!_index.TryGetValue(position, out var line)) yield break; + var endIf = EndIfLine(line); + if (_branchesByLevel.TryGetValue(_levels[line], out var branches)) + { + for (var i = FirstAtOrAfter(branches, line); i < branches.Count && (endIf is null || branches[i] < endIf); i++) + yield return (_kinds[branches[i]], _starts[branches[i]]); + } + if (endIf is { } end) yield return (DirectiveKind.EndIf, _starts[end]); + } + + private int? EndIfLine(int line) + { + if (!_endIfsByLevel.TryGetValue(_levels[line], out var endIfs)) return null; + var i = FirstAtOrAfter(endIfs, line); + return i < endIfs.Count ? endIfs[i] : null; + } + + private static int FirstAtOrAfter(List sorted, int value) + { + var i = sorted.BinarySearch(value); + return i >= 0 ? i : ~i; + } + + private static List Lookup(Dictionary> map, int key) + { + if (!map.TryGetValue(key, out var list)) map[key] = list = new List(); + return list; + } + + // The conditional directive starting a line: '#' and its name after optional whitespace. + public DirectiveKind Classify(int line) + { + var i = SkipWhitespace(line); + if (i >= _text.Length || _text[i] != '#') return DirectiveKind.Other; + var nameStart = SkipWhitespace(i + 1); + var nameEnd = nameStart; + while (nameEnd < _text.Length && SyntaxFacts.IsIdentifierPartCharacter(_text[nameEnd])) nameEnd++; + return _text[nameStart..nameEnd] switch + { + "if" => DirectiveKind.If, + "elif" => DirectiveKind.Elif, + "else" => DirectiveKind.Else, + "endif" => DirectiveKind.EndIf, + _ => DirectiveKind.Other, + }; + } + + private int SkipWhitespace(int i) + { + while (i < _text.Length && SyntaxFacts.IsWhitespace(_text[i])) i++; + return i; + } + + // The start of the next line; CRLF is one line break. + public int LineEnd(int i) + { + while (i < _text.Length && !SyntaxFacts.IsNewLine(_text[i])) i++; + if (i < _text.Length && _text[i] == '\r' && i + 1 < _text.Length && _text[i + 1] == '\n') i++; + return Math.Min(i + 1, _text.Length); + } + } + + // Only verbatim, raw, and interpolated text can span lines; a CR ends any other literal. + private static bool IsMultiLineStringContent(SyntaxKind kind) => kind is + SyntaxKind.StringLiteralToken or SyntaxKind.Utf8StringLiteralToken or + SyntaxKind.MultiLineRawStringLiteralToken or SyntaxKind.Utf8MultiLineRawStringLiteralToken or + SyntaxKind.InterpolatedStringTextToken; + + private static Encoding DetectEncoding(byte[] b) + { + if (b.Length >= 3 && b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF) return new UTF8Encoding(encoderShouldEmitUTF8Identifier: true); + if (b.Length >= 4 && b[0] == 0xFF && b[1] == 0xFE && b[2] == 0 && b[3] == 0) return new UTF32Encoding(bigEndian: false, byteOrderMark: true); + if (b.Length >= 2 && b[0] == 0xFF && b[1] == 0xFE) return new UnicodeEncoding(bigEndian: false, byteOrderMark: true); + if (b.Length >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0xFE && b[3] == 0xFF) return new UTF32Encoding(bigEndian: true, byteOrderMark: true); + if (b.Length >= 2 && b[0] == 0xFE && b[1] == 0xFF) return new UnicodeEncoding(bigEndian: true, byteOrderMark: true); + return Utf8NoBom; + } + + private static string? DetectNewLine(string text) + { + int crlf = 0, lf = 0, cr = 0; + for (var i = 0; i < text.Length; i++) + { + if (text[i] == '\n') lf++; + else if (text[i] != '\r') continue; + else if (i + 1 < text.Length && text[i + 1] == '\n') { crlf++; i++; } + else cr++; + } + if (crlf > 0 && lf == 0 && cr == 0) return "\r\n"; + if (lf > 0 && crlf == 0 && cr == 0) return "\n"; + if (cr > 0 && crlf == 0 && lf == 0) return "\r"; + return null; + } +} + +public static class LspSourceFile +{ + public static async Task<(string Text, LspSourceFileFormat Format)> ReadAsync(string path) + => LspSourceFileFormat.Decode(await File.ReadAllBytesAsync(path)); + + public static Task WriteAsync(string path, string text, LspSourceFileFormat format) + => File.WriteAllTextAsync(path, format.ApplyNewlines(text), format.Encoding); +} diff --git a/lsp/Server.Core/Server.Core.csproj b/lsp/Server.Core/Server.Core.csproj index 6dbc53fb..2fd19655 100644 --- a/lsp/Server.Core/Server.Core.csproj +++ b/lsp/Server.Core/Server.Core.csproj @@ -7,4 +7,7 @@ + + + diff --git a/lsp/SourceFileFormatOracleTests.cs b/lsp/SourceFileFormatOracleTests.cs new file mode 100644 index 00000000..99feeeb3 --- /dev/null +++ b/lsp/SourceFileFormatOracleTests.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using UnityCli.Lsp.Core; +using Xunit; + +// #520: compares ApplyNewlines with an oracle that parses every branch-selection configuration. +public sealed class SourceFileFormatOracleTests +{ + private static readonly LspSourceFileFormat LfFile = new(new UTF8Encoding(false), "\n"); + + // Enumerates independent choices for every candidate #if/#elif, letting Roslyn decide which lines + // are directives in each configuration. A lone CR is kept iff some configuration reads it inside a + // closed multi-line string literal. + private static string Oracle(string text) + { + var candidates = Regex.Matches(text, @"(?<=^|[\r\n])[ \t]*#[ \t]*(if|elif)[ \t]+[^\r\n]*"); + Assert.InRange(candidates.Count, 0, 7); // Exhaustive enumeration is deliberately test-only and bounded. + var keep = new HashSet(); + for (var mask = 0; mask < 1 << candidates.Count; mask++) + { + var defined = Enumerable.Range(0, candidates.Count).Where(i => (mask & (1 << i)) != 0).Select(i => ((char)('a' + i)).ToString()); + var options = CSharpParseOptions.Default.WithPreprocessorSymbols(defined); + var builder = new StringBuilder(text); + var root = CSharpSyntaxTree.ParseText(text, options).GetRoot(); + for (var i = 0; i < candidates.Count; i++) + { + var line = candidates[i]; + var hash = text.IndexOf('#', line.Index); + var directive = root.DescendantTrivia(descendIntoTrivia: true) + .FirstOrDefault(trivia => trivia.IsDirective && trivia.SpanStart == hash).GetStructure(); + var condition = directive switch + { + IfDirectiveTriviaSyntax ifDirective => ifDirective.Condition, + ElifDirectiveTriviaSyntax elifDirective => elifDirective.Condition, + _ => null, + }; + if (condition is null || condition.Span.IsEmpty) continue; + // Apply choices in source order, re-parsing before the next candidate. An earlier choice + // can expose a string containing a later '#if'; never overwrite that string's contents. + var replacement = ((char)('a' + i)).ToString().PadRight(condition.Span.Length); + for (var k = 0; k < replacement.Length; k++) builder[condition.SpanStart + k] = replacement[k]; + root = CSharpSyntaxTree.ParseText(builder.ToString(), options).GetRoot(); + } + foreach (var token in root.DescendantTokens(descendIntoTrivia: true)) Keep(token, 0); + } + + // Error recovery can leave a closed literal in skipped-token trivia, where an interpolated string + // stays one lexer token; the lexer still reads it as a closed literal, so it counts as well. + void Keep(SyntaxToken token, int offset) + { + if (token.IsKind(SyntaxKind.InterpolatedStringToken)) + { + foreach (var part in SyntaxFactory.ParseExpression(token.Text).DescendantTokens(descendIntoTrivia: true)) Keep(part, offset + token.SpanStart); + return; + } + if (!token.IsKind(SyntaxKind.StringLiteralToken) && !token.IsKind(SyntaxKind.Utf8StringLiteralToken) && + !token.IsKind(SyntaxKind.MultiLineRawStringLiteralToken) && !token.IsKind(SyntaxKind.Utf8MultiLineRawStringLiteralToken) && + !token.IsKind(SyntaxKind.InterpolatedStringTextToken)) return; + var literal = token.IsKind(SyntaxKind.InterpolatedStringTextToken) ? token.Parent?.Parent : null; + // Only the token's own diagnostics: its trailing trivia can hold a later skipped literal's. + if (token.WithoutTrivia().GetDiagnostics().Any(d => d.Id is "CS1039" or "CS8997") || + literal is InterpolatedStringExpressionSyntax interpolated && interpolated.StringEndToken.IsMissing) return; + for (var i = offset + token.Span.Start; i < offset + token.Span.End; i++) + { + if (text[i] == '\r' && (i + 1 >= text.Length || text[i + 1] != '\n')) keep.Add(i); + } + } + + var result = new StringBuilder(); + for (var i = 0; i < text.Length; i++) + { + var c = text[i]; + if (c == '\n') result.Append('\n'); + else if (c != '\r') result.Append(c); + else if (i + 1 < text.Length && text[i + 1] == '\n') { result.Append('\n'); i++; } + else result.Append(keep.Contains(i) ? "\r" : "\n"); + } + return result.ToString(); + } + + private static readonly string[] Fragments = + { + "var s = @\"x\ry\";\n", "var t = @\"\n", "var x = \"\";\n", "var u = \"\"\"\n", "\"\"\";\n", + "int a = 1;\rint b = 2;\n", "var v = @\"p\r#else\rq\";\n", "var w = @\"p\r#endif\rq\";\n", + "class C { string f = @\"a\r#else\rb\"; }\n", "/*\n", "*/\n", "var z = $@\"k\r{1}\";\n", + }; + + private static readonly string[] Conditions = { "A", "B", "false", "true", "C" }; + + private static readonly string[] RegressionFragments = Fragments.Concat(new[] + { + "var s = @\"x\r#if A\";\n", "var s = $@\"x\r#elif A\";\n", + "var s = $@\"outer\n{ @\"inner\rtext\" }\n", "var s = $@\"outer\n{ $@\"inner\r{1}\" }\n", + }).ToArray(); + + private static string Block(Random random, int depth, bool includeRegressions) + { + var builder = new StringBuilder(); + for (var n = random.Next(1, 4); n > 0; n--) + { + if (depth < 3 && random.Next(3) == 0) + { + builder.Append("#if " + Conditions[random.Next(Conditions.Length)] + "\n").Append(Block(random, depth + 1, includeRegressions)); + if (random.Next(2) == 0) builder.Append("#elif " + Conditions[random.Next(Conditions.Length)] + "\n").Append(Block(random, depth + 1, includeRegressions)); + if (random.Next(2) == 0) builder.Append("#else\n").Append(Block(random, depth + 1, includeRegressions)); + builder.Append("#endif\n"); + } + else + { + var fragments = includeRegressions ? RegressionFragments : Fragments; + builder.Append(fragments[random.Next(fragments.Length)]); + } + } + return builder.ToString(); + } + + private static string Show(string text) => text.Replace("\r", "\\r").Replace("\n", "\\n"); + + [Theory] + [InlineData("var s = @\"x\r#if A\";\n")] + [InlineData("var s = @\"x\r#elif A\";\n")] + [InlineData("#if A\nvar s = @\"x\r#if B\";\n#endif\n")] + [InlineData("#if A\nvar s = $@\"x\r#if B\";\n#endif\n")] + [InlineData("#if A\nvar s = \"\"\"\nx\r#if B\r\"\"\";\n#endif\n")] + [InlineData("var s = $@\"outer\n{ @\"inner\rtext\" }\n")] + [InlineData("var s = $@\"outer\n{ $@\"inner\r{1}\" }\n")] + [InlineData("var s = $$\"\"\"\nouter\n{{ @\"inner\rtext\" }}\n")] + public void Oracle_PreservesClosedLiteralContent(string input) + { + Assert.Equal(input, Oracle(input)); + Assert.Equal(input, LfFile.ApplyNewlines(input)); + } + + [Theory] + [InlineData(516, false)] + [InlineData(520, true)] + public void ApplyNewlines_MatchesTheAllConfigurationsOracleOnGeneratedSources(int seed, bool includeRegressions) + { + var random = new Random(seed); + var compared = 0; + var mismatches = new List(); + for (var iteration = 0; iteration < 50000 && compared < 1000; iteration++) + { + var text = Block(random, 0, includeRegressions); + if (!text.Contains('\r') || Regex.Matches(text, "#if|#elif").Count > 7) continue; + compared++; + var expected = Oracle(text); + var actual = LfFile.ApplyNewlines(text); + if (expected != actual) mismatches.Add(Show(text) + "\n oracle: " + Show(expected) + "\n actual: " + Show(actual)); + } + + Assert.True(compared >= 400, "compared " + compared); + Assert.True(mismatches.Count == 0, mismatches.Count + " of " + compared + " mismatched:\n" + string.Join("\n", mismatches.Take(10))); + } + + // Representative minimal mismatches the generator reported against develop 74806ad1. + [Theory] + [InlineData("#if true\nvar t = @\"\n#else\nvar s = @\"x\ry\";\n#endif\n")] + [InlineData("#if true\n/*\n#else\nvar v = @\"p\r#else\rq\";\n#endif\n")] + [InlineData("#if true\n/*\n#elif C\nvar w = @\"p\r#endif\rq\";\n#endif\n")] + [InlineData("#if true\n/*\n#endif\nvar w = @\"p\r#endif\rq\";\n")] + [InlineData("#if B\n#elif true\nvar t = @\"\n#endif\nvar z = $@\"k\r{1}\";\n")] + [InlineData("#if A\nvar v = @\"p\r#else\rq\";\n/*\n#endif\n")] + [InlineData("#if C\n/*\n#if C\n*/\n#endif\nvar v = @\"p\r#else\rq\";\n#endif\n")] + [InlineData("#if B\nvar v = @\"p\r#else\rq\";\n#elif true\nvar z = $@\"k\r{1}\";\n#endif\n")] + [InlineData("#if false\nvar a = \"\"\"\n x\r #if B\r \"\"\";\n#else\nvar a = $@\"x\r#else\r{1}\";\n#endif\n")] + public void ApplyNewlines_MatchesTheOracleOnMinimalMismatches(string input) + { + Assert.Equal(Oracle(input), LfFile.ApplyNewlines(input)); + } +} diff --git a/lsp/SourceFileFormatTests.cs b/lsp/SourceFileFormatTests.cs new file mode 100644 index 00000000..fa502293 --- /dev/null +++ b/lsp/SourceFileFormatTests.cs @@ -0,0 +1,535 @@ +using System; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; +using UnityCli.Lsp.Core; +using Xunit; + +public sealed class SourceFileFormatTests +{ + private const string Original = "public class Sample\n{\n public int Run() { return 1; }\n}\n"; + + // Every BOM the reader recognises, plus UTF-8 without one. + private static readonly string[] Encodings = { "utf-8", "utf-8-bom", "utf-16le", "utf-16be", "utf-32le", "utf-32be" }; + + public static TheoryData ExistingFileEdits() + { + var data = new TheoryData(); + foreach (var operation in new[] { "write", "apply", "replace_body", "insert_before", "insert_after", "remove", "rename" }) + foreach (var encoding in Encodings) + foreach (var newline in new[] { "\n", "\r\n", "\r" }) + { + data.Add(operation, encoding, newline); + } + return data; + } + + [Theory] + [MemberData(nameof(ExistingFileEdits))] + public async Task ExistingFileEdits_KeepTheOriginalBomAndNewlines(string operation, string encoding, string newline) + { + var root = Path.Combine(Path.GetTempPath(), "unity-cli-format-" + Path.GetRandomFileName()); + Directory.CreateDirectory(Path.Combine(root, "Assets")); + var scriptPath = Path.Combine(root, "Assets", "Sample.cs"); + await File.WriteAllBytesAsync(scriptPath, Encode(Original, encoding, newline)); + try + { + var service = new LspEditService(root, new LspFileLockProvider()); + // Inputs always use LF so a CRLF file also proves newline preservation. + const string written = "public class Sample\n{\n public int Run() { return 2; }\n}\n"; + using var files = JsonDocument.Parse(JsonSerializer.Serialize(new[] { new { relative = "Assets/Sample.cs", newText = written } })); + var (result, expected) = operation switch + { + "write" => (await service.WriteCSharpFileAsync("Assets/Sample.cs", written, true, true, false), written), + "apply" => (await service.ApplyCSharpEditsAsync(files.RootElement, true, true, false), written), + "replace_body" => (await service.ReplaceSymbolBodyAsync("Assets/Sample.cs", "Sample/Run", "{ return 2; }", true), written), + "insert_before" => (await service.InsertAroundSymbolAsync("Assets/Sample.cs", "Sample/Run", "public int Added;\n", false, true), + "public class Sample\n{\npublic int Added;\n public int Run() { return 1; }\n}\n"), + "insert_after" => (await service.InsertAroundSymbolAsync("Assets/Sample.cs", "Sample/Run", "public int Added;\n", true, true), + "public class Sample\n{\n public int Run() { return 1; }\npublic int Added;\n}\n"), + "remove" => (await service.RemoveSymbolAsync("Assets/Sample.cs", "Sample/Run", true, false, false), + // KeepExteriorTrivia leaves the member's indentation and line break behind. + "public class Sample\n{\n \n}\n"), + _ => (await service.RenameByNamePathAsync("Assets/Sample.cs", "Sample/Run", "Execute", true), + Original.Replace("Run", "Execute")), + }; + + using var response = JsonDocument.Parse(JsonSerializer.Serialize(result)); + Assert.True(response.RootElement.GetProperty("applied").GetBoolean(), response.RootElement.ToString()); + Assert.Equal(Encode(expected, encoding, newline), await File.ReadAllBytesAsync(scriptPath)); + } + finally + { + Directory.Delete(root, recursive: true); + } + } + + [Fact] + public async Task RenameAcrossFiles_KeepsEachFileFormat() + { + var root = Path.Combine(Path.GetTempPath(), "unity-cli-format-" + Path.GetRandomFileName()); + Directory.CreateDirectory(Path.Combine(root, "Assets")); + const string declaration = "namespace Demo\n{\n public partial class Sample {}\n}\n"; + const string use = "namespace Demo\n{\n public class Consumer { public Sample Value; }\n}\n"; + await File.WriteAllBytesAsync(Path.Combine(root, "Assets", "Sample.cs"), Encode(declaration, "utf-8-bom", "\r\n")); + await File.WriteAllBytesAsync(Path.Combine(root, "Assets", "Use.cs"), Encode(use, "utf-8", "\n")); + try + { + var service = new LspEditService(root, new LspFileLockProvider()); + + var result = await service.RenameByNamePathAsync("Assets/Sample.cs", "Sample", "Renamed", true); + + using var response = JsonDocument.Parse(JsonSerializer.Serialize(result)); + Assert.True(response.RootElement.GetProperty("applied").GetBoolean(), response.RootElement.ToString()); + Assert.Equal(Encode(declaration.Replace("Sample", "Renamed"), "utf-8-bom", "\r\n"), + await File.ReadAllBytesAsync(Path.Combine(root, "Assets", "Sample.cs"))); + Assert.Equal(Encode(use.Replace("Sample", "Renamed"), "utf-8", "\n"), + await File.ReadAllBytesAsync(Path.Combine(root, "Assets", "Use.cs"))); + } + finally + { + Directory.Delete(root, recursive: true); + } + } + + [Theory] + [InlineData("public class Sample {}\n")] + [InlineData("using UnityEngine;\r\npublic class Sample : MonoBehaviour {}\r\n")] + public async Task CreateCSharpFile_WritesUtf8WithoutBomAndKeepsGivenNewlines(string text) + { + var root = Path.Combine(Path.GetTempPath(), "unity-cli-format-" + Path.GetRandomFileName()); + Directory.CreateDirectory(root); + try + { + var service = new LspEditService(root, new LspFileLockProvider()); + + var result = await service.CreateCSharpFileAsync("Assets/Sample.cs", text, false, true, true, false); + + using var response = JsonDocument.Parse(JsonSerializer.Serialize(result)); + Assert.True(response.RootElement.GetProperty("applied").GetBoolean(), response.RootElement.ToString()); + Assert.Equal(Encoding.UTF8.GetBytes(text), await File.ReadAllBytesAsync(Path.Combine(root, "Assets", "Sample.cs"))); + } + finally + { + Directory.Delete(root, recursive: true); + } + } + + [Fact] + public async Task WriteCSharpFile_TreatsANewlineOnlyDifferenceAsNoChange() + { + var root = Path.Combine(Path.GetTempPath(), "unity-cli-format-" + Path.GetRandomFileName()); + Directory.CreateDirectory(Path.Combine(root, "Assets")); + var scriptPath = Path.Combine(root, "Assets", "Sample.cs"); + await File.WriteAllBytesAsync(scriptPath, Encode(Original, "utf-8-bom", "\r\n")); + try + { + var service = new LspEditService(root, new LspFileLockProvider()); + + var result = await service.WriteCSharpFileAsync("Assets/Sample.cs", Original, true, true, false); + + using var response = JsonDocument.Parse(JsonSerializer.Serialize(result)); + Assert.Equal("no_change", response.RootElement.GetProperty("reason").GetString()); + Assert.Equal(Encode(Original, "utf-8-bom", "\r\n"), await File.ReadAllBytesAsync(scriptPath)); + } + finally + { + Directory.Delete(root, recursive: true); + } + } + + [Theory] + [InlineData("a\r\nb\nc\n", "x\ny\n", "x\ny\n")] + [InlineData("single line", "x\r\ny\n", "x\r\ny\n")] + [InlineData("a\r\nb\r\n", "x\ny\r\nz\rw", "x\r\ny\r\nz\r\nw")] + [InlineData("a\nb\n", "x\ry\r\nz\rw", "x\ny\nz\nw")] + [InlineData("a\nb\n", "x\r\ny\n", "x\ny\n")] + [InlineData("a\rb\r", "x\ny\r\nz\rw", "x\ry\rz\rw")] + [InlineData("a\rb\nc\r", "x\ny\n", "x\ny\n")] + public void ApplyNewlines_OnlyRewritesWhenTheOriginalUsesOneConvention(string original, string text, string expected) + { + var format = LspSourceFileFormat.Detect(Encoding.UTF8.GetBytes(original)); + + Assert.Equal(expected, format.ApplyNewlines(text)); + } + + public static TheoryData NewlineMatrix() + { + var data = new TheoryData(); + foreach (var original in new[] { "\n", "\r\n", "\r" }) + foreach (var input in new[] { "\n", "\r\n", "\r" }) + { + data.Add(original, input); + } + return data; + } + + [Theory] + [MemberData(nameof(NewlineMatrix))] + public async Task EditInputNewlines_AreSavedInTheOriginalConvention(string originalNewline, string inputNewline) + { + const string written = "public class Sample\n{\n public int Run() { return 2; }\n}\n"; + foreach (var operation in new[] { "write", "apply", "create_overwrite" }) + { + var root = Path.Combine(Path.GetTempPath(), "unity-cli-format-" + Path.GetRandomFileName()); + Directory.CreateDirectory(Path.Combine(root, "Assets")); + var scriptPath = Path.Combine(root, "Assets", "Sample.cs"); + await File.WriteAllBytesAsync(scriptPath, Encode(Original, "utf-8", originalNewline)); + try + { + var service = new LspEditService(root, new LspFileLockProvider()); + var input = written.Replace("\n", inputNewline); + using var files = JsonDocument.Parse(JsonSerializer.Serialize(new[] { new { relative = "Assets/Sample.cs", newText = input } })); + var result = operation switch + { + "write" => await service.WriteCSharpFileAsync("Assets/Sample.cs", input, true, true, false), + "apply" => await service.ApplyCSharpEditsAsync(files.RootElement, true, true, false), + _ => await service.CreateCSharpFileAsync("Assets/Sample.cs", input, true, true, true, false), + }; + + using var response = JsonDocument.Parse(JsonSerializer.Serialize(result)); + Assert.True(response.RootElement.GetProperty("applied").GetBoolean(), operation + ": " + response.RootElement); + Assert.Equal(Encode(written, "utf-8", originalNewline), await File.ReadAllBytesAsync(scriptPath)); + } + finally + { + Directory.Delete(root, recursive: true); + } + } + } + + // A lone CR inside a string literal is part of the string's value, so it is never rewritten; + // lone CRs anywhere else (code, comments) are line terminators and follow the file's convention. + [Theory] + [InlineData("\n", "var a = @\"x\ry\";\rvar b = 1;\n", "var a = @\"x\ry\";\nvar b = 1;\n")] + [InlineData("\r\n", "var a = @\"x\ry\";\rvar b = 1;\n", "var a = @\"x\ry\";\r\nvar b = 1;\r\n")] + [InlineData("\n", "var a = $@\"x\r{b}\ry\";\r", "var a = $@\"x\r{b}\ry\";\n")] + [InlineData("\r\n", "var a = \"\"\"\n x\ry\n \"\"\";\r", "var a = \"\"\"\r\n x\ry\r\n \"\"\";\r\n")] + [InlineData("\n", "var a = $\"\"\"\n x\r{b}\n \"\"\";\r", "var a = $\"\"\"\n x\r{b}\n \"\"\";\n")] + [InlineData("\n", "var a = \"\"\"\n x\ry\n \"\"\"u8;\r", "var a = \"\"\"\n x\ry\n \"\"\"u8;\n")] + [InlineData("\n", "// comment\rvar a = 1; /* x\ry */\r", "// comment\nvar a = 1; /* x\ny */\n")] + [InlineData("\n", "var a = \"x\ry\";\r", "var a = \"x\ny\";\n")] + [InlineData("\n", "var a = @\"x\r#\";\r", "var a = @\"x\r#\";\n")] + [InlineData("\n", "#\fif UNITY_EDITOR\nvar a = @\"x\ry\";\r#endif\n", "#\fif UNITY_EDITOR\nvar a = @\"x\ry\";\n#endif\n")] + [InlineData("\n", "#\u00a0if UNITY_EDITOR\nvar a = @\"x\ry\";\r#endif\n", "#\u00a0if UNITY_EDITOR\nvar a = @\"x\ry\";\n#endif\n")] + // A directive-looking line inside a string of an inactive branch is string content once that branch is active. + [InlineData("\n", "#if A\nvar a = @\"x\r#elif false\r\";\n#endif\n", "#if A\nvar a = @\"x\r#elif false\r\";\n#endif\n")] + [InlineData("\n", "#if A\nvar a = @\"x\r#else\ry\";\n#endif\n", "#if A\nvar a = @\"x\r#else\ry\";\n#endif\n")] + [InlineData("\n", "#if A\nvar a = @\"x\r#endif\ry\";\n#endif\n", "#if A\nvar a = @\"x\r#endif\ry\";\n#endif\n")] + // No configuration reaches this #else: when the #if is skipped, the raw string's "#if B" line opens a + // nested group that swallows the #else, so only the raw string's CRs are string content. + [InlineData("\r\n", "#if false\nvar a = \"\"\"\n x\r #if B\r \"\"\";\n#else\nvar a = $@\"x\r#else\r{1}\";\n#endif\n", "#if false\r\nvar a = \"\"\"\r\n x\r #if B\r \"\"\";\r\n#else\r\nvar a = $@\"x\r\n#else\r\n{1}\";\r\n#endif\r\n")] + [InlineData("\r\n", "#if false\nvar a = \"\"\"\n x\r \"\"\";\n#else\nvar a = $@\"x\r#else\r{1}\";\n#endif\n", "#if false\r\nvar a = \"\"\"\r\n x\r \"\"\";\r\n#else\r\nvar a = $@\"x\r#else\r{1}\";\r\n#endif\r\n")] + [InlineData("\n", "#if A\n#if B\nvar a = @\"x\r#elif C\r#endif\ry\";\n#endif\n#endif\n", "#if A\n#if B\nvar a = @\"x\r#elif C\r#endif\ry\";\n#endif\n#endif\n")] + // An unterminated comment or string in one branch must not change how another branch is lexed. + [InlineData("\n", "#if false\nvar s = @\"\n#endif\nx\"\"@\"\";\nvar a = 1;\rvar b = 2;\n#endif\n", "#if false\nvar s = @\"\n#endif\nx\"\"@\"\";\nvar a = 1;\nvar b = 2;\n#endif\n")] + [InlineData("\n", "#if A\nvar s = @\"\n#endif\nx\"\"@\"\";\nvar a = 1;\rvar b = 2;\n#endif\n", "#if A\nvar s = @\"\n#endif\nx\"\"@\"\";\nvar a = 1;\nvar b = 2;\n#endif\n")] + [InlineData("\r\n", "#if A\nvar s = @\"\n#elif B\nx\"\"@\"\";\nvar a = 1;\rvar b = 2;\n#endif\n", "#if A\r\nvar s = @\"\r\n#elif B\r\nx\"\"@\"\";\r\nvar a = 1;\r\nvar b = 2;\r\n#endif\r\n")] + [InlineData("\n", "#if A\nvar s = @\"\n#endif\nx\"\"@\"\"\";\nvar a = 1;\rvar b = 2;\n#endif\n", "#if A\nvar s = @\"\n#endif\nx\"\"@\"\"\";\nvar a = 1;\nvar b = 2;\n#endif\n")] + [InlineData("\n", "#if A\nvar s = @\"\n#endif\nvar t = \"\"+@\"\"\";\nvar a = 1;\rvar b = 2;\n#endif\n", "#if A\nvar s = @\"\n#endif\nvar t = \"\"+@\"\"\";\nvar a = 1;\nvar b = 2;\n#endif\n")] + // A CR stays when any configuration that parses without errors reads it as string content. + [InlineData("\n", "#if A\nvar s = \"\"\"\"\n#else\nvar t = @\"\n\"\"\"\";\nvar u = 1;\rvar v = 2;\n//\";\n#endif\n", "#if A\nvar s = \"\"\"\"\n#else\nvar t = @\"\n\"\"\"\";\nvar u = 1;\rvar v = 2;\n//\";\n#endif\n")] + [InlineData("\n", "#if A\nint q;\n#elif B\nvar s = @\"\n#else\nvar t = \"\"+@\"\"\";\nvar a = 1;\rvar b = 2;\n#endif\n", "#if A\nint q;\n#elif B\nvar s = @\"\n#else\nvar t = \"\"+@\"\"\";\nvar a = 1;\nvar b = 2;\n#endif\n")] + [InlineData("\n", "#if A\nint q;\n#elif B\nvar s = @\"\n#endif\nvar t = \"\"+@\"\"\";\nvar a = 1;\rvar b = 2;\n#endif\n", "#if A\nint q;\n#elif B\nvar s = @\"\n#endif\nvar t = \"\"+@\"\"\";\nvar a = 1;\nvar b = 2;\n#endif\n")] + // An unterminated literal is not valid C#: its extent is unknown, so it keeps no CR. + [InlineData("\n", "var a = @\"x\ry;\r", "var a = @\"x\ny;\n")] + [InlineData("\n", "var a = $@\"x\r{1}y;\r", "var a = $@\"x\n{1}y;\n")] + [InlineData("\n", "var a = \"\"\"\n x\ry;\r", "var a = \"\"\"\n x\ny;\n")] + // A missing semicolon alone or an unrelated syntax error does not change a literal's extent. + [InlineData("\n", "@\"x\ry\"", "@\"x\ry\"")] + [InlineData("\n", "var broken = ;\nvar a = @\"x\ry\";\r", "var broken = ;\nvar a = @\"x\ry\";\n")] + // An unterminated comment or string in one branch must not change how another branch is lexed. + [InlineData("\n", "#if false\n/*\n#else\nvar a = @\"x\ry\";\n#endif\n", "#if false\n/*\n#else\nvar a = @\"x\ry\";\n#endif\n")] + [InlineData("\n", "#if UNITY_EDITOR\n/*\n#elif UNITY_STANDALONE\nvar a = @\"x\ry\";\n#endif\n", "#if UNITY_EDITOR\n/*\n#elif UNITY_STANDALONE\nvar a = @\"x\ry\";\n#endif\n")] + [InlineData("\n", "#if UNITY_EDITOR\nvar b = @\"\n#else\nvar a = 1;\n#endif\nvar c = @\"x\ry\";\r", "#if UNITY_EDITOR\nvar b = @\"\n#else\nvar a = 1;\n#endif\nvar c = @\"x\ry\";\n")] + [InlineData("\r\n", "#if UNITY_EDITOR\nvar b = \"\"\"\n#endif\nvar a = 1;\rvar c = @\"x\ry\";\n", "#if UNITY_EDITOR\r\nvar b = \"\"\"\r\n#endif\r\nvar a = 1;\r\nvar c = @\"x\ry\";\r\n")] + public void ApplyNewlines_KeepsLoneCrInsideStringLiterals(string originalNewline, string text, string expected) + { + var format = LspSourceFileFormat.Detect(Encoding.UTF8.GetBytes("a" + originalNewline + "b" + originalNewline)); + + Assert.Equal(expected, format.ApplyNewlines(text)); + } + + [Fact] + public void ApplyNewlines_HandlesMalformedDirectivesAndManyBranches() + { + var format = LspSourceFileFormat.Detect(Encoding.UTF8.GetBytes("a\nb\n")); + Assert.Equal("#if\nvar a = 1;\n#endif\n", format.ApplyNewlines("#if\rvar a = 1;\r#endif\r")); + + var block = "#if A\nvar a = @\"x\r#else\ry\";\n#else\nvar b = 1;\r#endif\n"; + var input = string.Concat(Enumerable.Repeat(block, 400)); + Assert.Equal(string.Concat(Enumerable.Repeat(block.Replace(";\r#endif", ";\n#endif"), 400)), format.ApplyNewlines(input)); + } + + [Fact] + public void ApplyNewlines_ActivatesBranchesWithDirectivesLongerThanTheFirstWindow() + { + var format = LspSourceFileFormat.Detect(Encoding.UTF8.GetBytes("a\nb\n")); + var condition = string.Join(" || ", Enumerable.Range(0, 60).Select(i => "SYMBOL_" + i)); + foreach (var directive in new[] { "#elif " + condition, "#else // " + new string('x', 300) }) + { + var input = "#if false\nvar a = 1;\r" + directive + "\nvar b = @\"x\ry\";\r#endif\n"; + Assert.True(directive.Length > 256); + Assert.Equal("#if false\nvar a = 1;\n" + directive + "\nvar b = @\"x\ry\";\n#endif\n", format.ApplyNewlines(input)); + } + } + + public static TheoryData InactiveBranchStrings() + { + var data = new TheoryData(); + foreach (var newline in new[] { "\n", "\r\n", "\r" }) + foreach (var inputNewline in new[] { "\n", "\r\n", "\r" }) + foreach (var literal in new[] + { + "@\"x\ry\"", + "\"\"\"\n x\r y\n \"\"\"", + "\"\"\"\n x\r y\n \"\"\"u8", + "$@\"x\r{1}\ry\"", + "$\"\"\"\n x\r {1}\r y\n \"\"\"", + "@\"x\r#if OTHER\r#endif\ry\"", + }) + foreach (var branch in new[] + { + "#if UNITY_EDITOR\n{0}\n#endif\n", + "\t# if UNITY_EDITOR\n{0}\n\t# endif\n", + "#if false\n{0}\n#endif\n", + "#if true\nint enabled = 1;\n#elif UNITY_STANDALONE\n{0}\n#endif\n", + "#if true\nint enabled = 1;\n#else\n{0}\n#endif\n", + "#if UNITY_EDITOR\n#if UNITY_STANDALONE\n{0}\n#endif\n#endif\n", + "#define UNITY_EDITOR\n#if !UNITY_EDITOR\n{0}\n#endif\n", + "#if false\n/*\n#else\n{0}\n#endif\n", + "#if false\n/*\n#elif UNITY_EDITOR\n{0}\n#else\nint enabled = 1;\n#endif\n", + "#if UNITY_EDITOR\n#if true\n/*\n#else\n{0}\n#endif\n#endif\n", + }) + { + data.Add(newline, inputNewline, literal, branch); + } + return data; + } + + [Theory] + [MemberData(nameof(InactiveBranchStrings))] + public async Task EditInputNewlines_KeepStringCrsInInactiveBranches(string newline, string inputNewline, string literal, string branch) + { + // Construct expected bytes separately: source line breaks follow the original convention, + // while lone CRs inside the literal (including CR input line breaks) are retained. + var declaration = "var text = " + literal + ";"; + var input = branch.Replace("\n", inputNewline).Replace("{0}", declaration.Replace("\n", inputNewline)); + var literalNewline = inputNewline == "\r" ? "\r" : newline; + var expectedDeclaration = declaration.Replace("\n", literalNewline); + // The interpolated raw fixture's first/last line breaks delimit the content; + // only its explicit CRs between x, the interpolation, and y belong to the value. + if (inputNewline == "\r" && literal.StartsWith("$\"\"\"\n", StringComparison.Ordinal)) + expectedDeclaration = declaration.Replace("\n", newline); + var expected = branch.Replace("\n", newline).Replace("{0}", expectedDeclaration); + foreach (var operation in new[] { "write", "apply", "create_overwrite" }) + { + var root = Path.Combine(Path.GetTempPath(), "unity-cli-format-" + Path.GetRandomFileName()); + Directory.CreateDirectory(Path.Combine(root, "Assets")); + var scriptPath = Path.Combine(root, "Assets", "Sample.cs"); + await File.WriteAllBytesAsync(scriptPath, Encode(Original, "utf-8-bom", newline)); + try + { + var service = new LspEditService(root, new LspFileLockProvider()); + using var files = JsonDocument.Parse(JsonSerializer.Serialize(new[] { new { relative = "Assets/Sample.cs", newText = input } })); + var result = operation switch + { + "write" => await service.WriteCSharpFileAsync("Assets/Sample.cs", input, true, true, false), + "apply" => await service.ApplyCSharpEditsAsync(files.RootElement, true, true, false), + _ => await service.CreateCSharpFileAsync("Assets/Sample.cs", input, true, true, true, false), + }; + + using var response = JsonDocument.Parse(JsonSerializer.Serialize(result)); + Assert.True(response.RootElement.GetProperty("applied").GetBoolean(), operation + ": " + response.RootElement); + var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true); + Assert.Equal(encoding.GetPreamble().Concat(encoding.GetBytes(expected)).ToArray(), await File.ReadAllBytesAsync(scriptPath)); + } + finally + { + Directory.Delete(root, recursive: true); + } + } + } + + [Fact] + public void ApplyNewlines_KeepsDirectiveLookingLinesInClassFieldStrings() + { + var format = LspSourceFileFormat.Detect(Encoding.UTF8.GetBytes("a\nb\n")); + const string input = "class C\n{\n#if UNITY_EDITOR\npublic string A = @\"x\r#else\ry\";\r#else\npublic string B = $@\"u\r#else\r{1}\rv\";\r#endif\r}\r"; + const string expected = "class C\n{\n#if UNITY_EDITOR\npublic string A = @\"x\r#else\ry\";\n#else\npublic string B = $@\"u\r#else\r{1}\rv\";\n#endif\n}\n"; + + Assert.Equal(expected, format.ApplyNewlines(input)); + } + + [Fact] + public void ApplyNewlines_KeepsClosedStringCrsAcrossMalformedNestedBranches() + { + var format = LspSourceFileFormat.Detect(Encoding.UTF8.GetBytes("a\nb\n")); + const string input = "#if UNITY_EDITOR\n#if true\n@\"unfinished\n#else\nvar prefix = 1;\rvar a = @\"x\ry\";\r#endif\r#endif\r"; + // Activating the inner #if closes its string at the sibling's opening quote. + // The PM union policy protects that closed token despite the malformed statement. + const string expected = "#if UNITY_EDITOR\n#if true\n@\"unfinished\n#else\nvar prefix = 1;\rvar a = @\"x\ry\";\n#endif\n#endif\n"; + + Assert.Equal(expected, format.ApplyNewlines(input)); + } + + [Fact] + public void ApplyNewlines_HandlesLongConditionalExpressions() + { + var format = LspSourceFileFormat.Detect(Encoding.UTF8.GetBytes("a\nb\n")); + var condition = string.Join(" || ", Enumerable.Repeat("UNITY_EDITOR", 80)); + var input = "#if " + condition + "\nvar a = @\"x\ry\";\r#endif\r"; + var expected = "#if " + condition + "\nvar a = @\"x\ry\";\n#endif\n"; + + Assert.Equal(expected, format.ApplyNewlines(input)); + } + + [Fact] + public void ApplyNewlines_KeepsClosedStringCrsAcrossMalformedSiblingBranches() + { + var format = LspSourceFileFormat.Detect(Encoding.UTF8.GetBytes("a\nb\n")); + const string input = "#if false\n@\"unfinished\n#else\nvar prefix = 1;\rvar a = @\"x\ry\";\r#endif\rvar b = 1;\r"; + const string expected = "#if false\n@\"unfinished\n#else\nvar prefix = 1;\rvar a = @\"x\ry\";\n#endif\nvar b = 1;\n"; + + Assert.Equal(expected, format.ApplyNewlines(input)); + } + + [Fact] + public void ApplyNewlines_NormalizesCrsInInactiveCommentsAndDirectiveMessages() + { + var format = LspSourceFileFormat.Detect(Encoding.UTF8.GetBytes("a\nb\n")); + const string input = "#if UNITY_EDITOR\r// @\"x\ry\"\r/* @\"x\ry\" */\r#error @\"x\ry\"\r#endif\r"; + + Assert.Equal(input.Replace("\r", "\n"), format.ApplyNewlines(input)); + } + + [Theory] + [InlineData("var s = $@\"outer\n{ @\"inner\rtext\" }\n")] + [InlineData("var s = $@\"outer\n{ $@\"inner\r{1}\" }\n")] + [InlineData("var s = $$\"\"\"\nouter\n{{ @\"inner\rtext\" }}\n")] + public void ApplyNewlines_KeepsClosedInnerLiteralCrsInUnterminatedInterpolation(string input) + { + var format = new LspSourceFileFormat(new UTF8Encoding(false), "\n"); + Assert.Equal(input, format.ApplyNewlines(input)); + } + + [Fact] + public void ApplyNewlines_NormalizesOnlyUnterminatedOuterInterpolationCrs() + { + var format = new LspSourceFileFormat(new UTF8Encoding(false), "\n"); + Assert.Equal("var s = $@\"outer\n{ @\"inner\rtext\" }\n", + format.ApplyNewlines("var s = $@\"outer\r{ @\"inner\rtext\" }\r")); + } + + [Fact] + public void ApplyNewlines_KeepsRecoveredFieldLiteralAfterUnterminatedInterpolation() + { + const string input = "var s = $@\"outer\n{ @\"inner\rtext\" }\nclass C { string f = @\"a\r#else\rb\"; }\n"; + var format = new LspSourceFileFormat(new UTF8Encoding(false), "\n"); + Assert.Equal(input, format.ApplyNewlines(input)); + } + + // #520: an unterminated literal in one branch must not hide a sibling branch, and a directive-looking + // line inside a nested branch's string must not close the wrong group. Each input keeps its CRs + // because some branch-selection configuration reads them inside a closed string. + [Theory] + [InlineData("#if true\n#if C\nvar w = @\"p\r#endif\rq\";\n#endif\n#endif\nvar s = @\"x\ry\";\n")] + [InlineData("#if B\n#if A\nvar v = @\"p\r#else\rq\";\n#endif\nvar w = @\"p\r#endif\rq\";\n#endif\n")] + [InlineData("#if true\n#if false\nvar w = @\"p\r#endif\rq\";\n#endif\nvar s = @\"x\ry\";\n#endif\n")] + [InlineData("#if B\n#if A\n#if true\nvar t = @\"\n#endif\nvar z = $@\"k\r{1}\";\n#endif\n#endif\n")] + [InlineData("#if true\nvar t = @\"\n#else\nvar s = @\"x\ry\";\n#endif\n")] + [InlineData("#if true\nvar t = @\"\n#elif false\nvar w = @\"p\r#endif\rq\";\n#endif\n")] + [InlineData("#if true\nvar u = \"\"\"\n#endif\nclass C { string f = @\"a\r#else\rb\"; }\n")] + [InlineData("#if A\nclass C { string f = @\"a\r#else\rb\"; }\n#endif\nvar z = $@\"k\r{1}\";\n")] + [InlineData("#if B\nclass C { string f = @\"a\r#else\rb\"; }\nvar u = \"\"\"\n#endif\n")] + // Minimal generator mismatches: an unterminated "/*" or "@\"" in a taken branch hides the next branch. + [InlineData("#if true\n/*\n#else\nvar v = @\"p\r#else\rq\";\n#endif\n")] + [InlineData("#if true\n/*\n#elif C\nvar w = @\"p\r#endif\rq\";\n#endif\n")] + [InlineData("#if true\n/*\n#endif\nvar w = @\"p\r#endif\rq\";\n")] + [InlineData("#if B\n#elif true\nvar t = @\"\n#endif\nvar z = $@\"k\r{1}\";\n")] + public void ApplyNewlines_KeepsClosedStringCrsInBranchesHiddenByUnterminatedLiterals(string input) + { + var format = LspSourceFileFormat.Detect(Encoding.UTF8.GetBytes("a\nb\n")); + + Assert.Equal(input, format.ApplyNewlines(input)); + } + + // #520: each nested group is solved once, so a string whose "#else" line splits a group in two does + // not double the work per nesting level. + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ApplyNewlines_StaysFastAcrossDeeplyNestedBranches(bool nestInElif) + { + var format = LspSourceFileFormat.Detect(Encoding.UTF8.GetBytes("a\nb\n")); + const string literal = "var v = @\"p\r#else\rq\";\n"; + var input = "int x = 1;\r\n"; + for (var depth = 1; depth <= 30; depth++) + { + input = nestInElif + ? "#if A" + depth + "\nint y;\n#elif B" + depth + "\n" + literal + input + "#endif\n" + : "#if A" + depth + "\n" + literal + input + "#elif B" + depth + "\n" + literal + "#endif\n"; + } + + var watch = System.Diagnostics.Stopwatch.StartNew(); + var actual = format.ApplyNewlines(input); + watch.Stop(); + + Assert.Equal(input.Replace("\r\n", "\n"), actual); + Assert.True(watch.Elapsed < TimeSpan.FromSeconds(1), "took " + watch.Elapsed); + } + + // #520: the cost follows the directive count: no state rescans a skipped group, a run of directives, + // or an unterminated comment that the lexer reads to the end of the file. + [Theory] + [InlineData("nested")] + [InlineData("elif")] + [InlineData("comment")] + [InlineData("stray")] + public void ApplyNewlines_StaysFastWithThousandsOfDirectives(string shape) + { + var format = LspSourceFileFormat.Detect(Encoding.UTF8.GetBytes("a\nb\n")); + var input = shape switch + { + "nested" => string.Concat(Enumerable.Repeat("#if A\nint a;\r", 2000)) + string.Concat(Enumerable.Repeat("#endif\n", 2000)), + "elif" => "#if A\nint a;\r" + string.Concat(Enumerable.Range(0, 4000).Select(i => "#elif S" + i + "\nint a;\r")) + "#endif\n", + "comment" => string.Concat(Enumerable.Repeat("#if A\n/*\n#endif\nint a;\r", 1000)), + _ => string.Concat(Enumerable.Repeat("#endif\n#else\nint a;\r", 2000)), + }; + + var watch = System.Diagnostics.Stopwatch.StartNew(); + var actual = format.ApplyNewlines(input); + watch.Stop(); + + Assert.Equal(input.Replace("\r", "\n"), actual); + Assert.True(watch.Elapsed < TimeSpan.FromSeconds(3), "took " + watch.Elapsed); + } + + // #520: past its state budget the scan cannot tell string CRs from line breaks, so it keeps every lone CR. + [Fact] + public void ApplyNewlines_KeepsEveryLoneCrWhenTheScanExceedsItsBudget() + { + var format = LspSourceFileFormat.Detect(Encoding.UTF8.GetBytes("a\nb\n")); + const string input = "#if A\nvar a = @\"x\ry\";\r#else\nint b;\r\n#endif\n"; + + Assert.Equal("#if A\nvar a = @\"x\ry\";\r#else\nint b;\n#endif\n", format.ApplyNewlines(input, maxScanStates: 1)); + Assert.Equal("#if A\nvar a = @\"x\ry\";\n#else\nint b;\n#endif\n", format.ApplyNewlines(input)); + } + + private static byte[] Encode(string lfText, string encoding, string newline) + { + Encoding target = encoding switch + { + "utf-8" => new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), + "utf-8-bom" => new UTF8Encoding(encoderShouldEmitUTF8Identifier: true), + "utf-16le" => new UnicodeEncoding(bigEndian: false, byteOrderMark: true), + "utf-16be" => new UnicodeEncoding(bigEndian: true, byteOrderMark: true), + "utf-32le" => new UTF32Encoding(bigEndian: false, byteOrderMark: true), + "utf-32be" => new UTF32Encoding(bigEndian: true, byteOrderMark: true), + _ => throw new ArgumentOutOfRangeException(nameof(encoding), encoding, null), + }; + return target.GetPreamble().Concat(target.GetBytes(lfText.Replace("\n", newline))).ToArray(); + } +} diff --git a/package.json b/package.json index 8779bd51..43d14cf5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "unity-cli-workspace", - "version": "0.18.1", + "version": "0.19.0", "private": true, "packageManager": "pnpm@10.33.0", "description": "Development environment for unity-cli", @@ -18,13 +18,13 @@ "@commitlint/cli": "^21.1.0", "@commitlint/config-conventional": "^21.1.0", "@eslint/js": "^10.0.1", - "@google/gemini-cli": "^0.49.0", - "@openai/codex": "^0.142.3", - "eslint": "^10.6.0", - "globals": "^17.7.0", + "@google/gemini-cli": "^0.64.0", + "@openai/codex": "^0.163.0", + "eslint": "^10.12.0", + "globals": "^17.13.0", "husky": "^9.1.7", "markdownlint-cli": "^0.49.0", - "prettier": "^3.9.1" + "prettier": "^3.9.10" }, "overrides": { "markdownlint-cli": { diff --git a/packaging/winget/README.md b/packaging/winget/README.md new file mode 100644 index 00000000..d1cc9d64 --- /dev/null +++ b/packaging/winget/README.md @@ -0,0 +1,31 @@ +# winget 初回公開用 manifest + +`akiojin.unity-cli/0.18.1/` は公開 Release v0.18.1 の Windows x64 portable +バイナリを対象にした初回提出用の3ファイル manifest です。 +InstallerSha256 は GitHub Release の asset digest と、インストーラで検証済みの +バイナリの SHA256 に一致します。 + +```powershell +winget validate --manifest packaging/winget/akiojin.unity-cli/0.18.1 +``` + +提出先は microsoft/winget-pkgs の +`manifests/a/akiojin/unity-cli/0.18.1/` です。公開 source への登録はまだ完了していません。 +[Microsoft の提出手順](https://learn.microsoft.com/en-us/windows/package-manager/package/repository) +に沿って、この3ファイルだけを初回 package PR に含めます。 + +後続リリースの自動更新には repository secret `WINGET_TOKEN` が必要です。 +既存の release workflow の `update-winget` job がこの secret を使います。 +[Microsoft の認証手順](https://github.com/microsoft/winget-create/blob/main/doc/token.md) +を参照し、公開リポジトリへ提出できる資格情報を設定します。トークン値は証跡や +コマンドライン引数に残さないでください。 + +公開 source への反映後に、次を実 Windows と開いた検証用 Editor で確認します。 + +```powershell +winget install --id akiojin.unity-cli --exact --source winget --scope user +unity-cli --version +unity-cli --port 6487 system ping +``` + +ローカル manifest の validate 成功は、公開 source からの install 成功とは別の証跡です。 diff --git a/packaging/winget/akiojin.unity-cli/0.18.1/akiojin.unity-cli.installer.yaml b/packaging/winget/akiojin.unity-cli/0.18.1/akiojin.unity-cli.installer.yaml new file mode 100644 index 00000000..8d0209e1 --- /dev/null +++ b/packaging/winget/akiojin.unity-cli/0.18.1/akiojin.unity-cli.installer.yaml @@ -0,0 +1,12 @@ +# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.12.0.schema.json +PackageIdentifier: akiojin.unity-cli +PackageVersion: 0.18.1 +InstallerType: portable +Commands: + - unity-cli +Installers: + - Architecture: x64 + InstallerUrl: https://github.com/akiojin/unity-cli/releases/download/v0.18.1/unity-cli-win-x64.exe + InstallerSha256: EFCD697B940F78B6457829453888D9C608F19D2FCD331D0005B1FF47A7839357 +ManifestType: installer +ManifestVersion: 1.12.0 diff --git a/packaging/winget/akiojin.unity-cli/0.18.1/akiojin.unity-cli.locale.en-US.yaml b/packaging/winget/akiojin.unity-cli/0.18.1/akiojin.unity-cli.locale.en-US.yaml new file mode 100644 index 00000000..4d49bfe7 --- /dev/null +++ b/packaging/winget/akiojin.unity-cli/0.18.1/akiojin.unity-cli.locale.en-US.yaml @@ -0,0 +1,20 @@ +# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.12.0.schema.json +PackageIdentifier: akiojin.unity-cli +PackageVersion: 0.18.1 +PackageLocale: en-US +Publisher: akiojin +PublisherUrl: https://github.com/akiojin +PublisherSupportUrl: https://github.com/akiojin/unity-cli/issues +PackageName: unity-cli +PackageUrl: https://github.com/akiojin/unity-cli +License: MIT +LicenseUrl: https://github.com/akiojin/unity-cli/blob/v0.18.1/LICENSE +ShortDescription: CLI for Unity Editor automation over the Unity TCP protocol +Moniker: unity-cli +Tags: + - automation + - unity + - unity-editor +ReleaseNotesUrl: https://github.com/akiojin/unity-cli/releases/tag/v0.18.1 +ManifestType: defaultLocale +ManifestVersion: 1.12.0 diff --git a/packaging/winget/akiojin.unity-cli/0.18.1/akiojin.unity-cli.yaml b/packaging/winget/akiojin.unity-cli/0.18.1/akiojin.unity-cli.yaml new file mode 100644 index 00000000..7e9a55c2 --- /dev/null +++ b/packaging/winget/akiojin.unity-cli/0.18.1/akiojin.unity-cli.yaml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.12.0.schema.json +PackageIdentifier: akiojin.unity-cli +PackageVersion: 0.18.1 +DefaultLocale: en-US +ManifestType: version +ManifestVersion: 1.12.0 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 25b18a24..a16356cd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,19 +26,19 @@ importers: version: 21.2.3 '@eslint/js': specifier: ^10.0.1 - version: 10.0.1(eslint@10.11.0(jiti@2.6.1)) + version: 10.0.1(eslint@10.12.0(jiti@2.6.1)) '@google/gemini-cli': - specifier: ^0.49.0 - version: 0.49.0 + specifier: ^0.64.0 + version: 0.64.0 '@openai/codex': - specifier: ^0.142.3 - version: 0.142.5 + specifier: ^0.163.0 + version: 0.163.0 eslint: - specifier: ^10.6.0 - version: 10.11.0(jiti@2.6.1) + specifier: ^10.12.0 + version: 10.12.0(jiti@2.6.1) globals: - specifier: ^17.7.0 - version: 17.12.0 + specifier: ^17.13.0 + version: 17.13.0 husky: specifier: ^9.1.7 version: 9.1.7 @@ -46,8 +46,8 @@ importers: specifier: ^0.49.0 version: 0.49.1 prettier: - specifier: ^3.9.1 - version: 3.9.9 + specifier: ^3.9.10 + version: 3.9.10 packages: @@ -150,8 +150,8 @@ packages: resolution: {integrity: sha512-aalGyl7dbB5PArRebDIX43ZvBlXrYm9uWzGJ26t+4SzJVPsOuvfILGGbw5X4yX7i50YEmJ8zvbiWnqH/AAnZqg==} engines: {node: '>=22'} - '@eslint-community/eslint-utils@4.9.1': - resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + '@eslint-community/eslint-utils@4.10.1': + resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 @@ -192,8 +192,8 @@ packages: '@github/keytar@7.10.6': resolution: {integrity: sha512-mRW6cUsSG+nj4jp5gp8e91zPySaT73r+2JM6VyMZfrEgksjPmjSMr+tPGNOK3HUHV+GUU9B1LAiiYy/wmAnIxA==} - '@google/gemini-cli@0.49.0': - resolution: {integrity: sha512-S0b6nfAf+lHbSPMKRuQziU1/710a7f/Jag2mZ7N1J1b48qxoCmjwNCJJ7XPEv/ropvDqkCjJupE32qcw+ym3jQ==} + '@google/gemini-cli@0.64.0': + resolution: {integrity: sha512-FHrZ1NPf9QszyVMaa/BP3SsPy40ogBLnbZNWkv/PMi1Uz2zoDNMLGiBzBGmx4Bl7iLRq01K9PY/5kmloXFTpsA==} engines: {node: '>=20'} hasBin: true @@ -259,43 +259,43 @@ packages: '@lydell/node-pty@1.1.0': resolution: {integrity: sha512-VDD8LtlMTOrPKWMXUAcB9+LTktzuunqrMwkYR1DMRBkS6LQrCt+0/Ws1o2rMml/n3guePpS7cxhHF7Nm5K4iMw==} - '@openai/codex@0.142.5': - resolution: {integrity: sha512-WQEpD7l3k68eIAP0aq28EdR18ENBAf8DyprzFhzNwCOQJSv4nHzpwT8Fl30IJacprko2ZCmUBZjM2u941l2yLw==} + '@openai/codex@0.163.0': + resolution: {integrity: sha512-HNd7vR9oTK6M2ikxFnvNDCdYUgAsyo9VVnd5KnEd2ON0GYI++7MiX9XNPUkhtdgGKFPsWS+CEppQ1UU63uVhUw==} engines: {node: '>=16'} hasBin: true - '@openai/codex@0.142.5-darwin-arm64': - resolution: {integrity: sha512-l43p8xv+Z/2/b6fCUc7/FmcQZsaPB7RFizLponGwHAnFOWe3i9Vky69p+up3BUam9AetoQQUv7Mo+2KdaFEqhA==} + '@openai/codex@0.163.0-darwin-arm64': + resolution: {integrity: sha512-i7Dzk2a5aGmuGM9aNZgaUVTojZ/4bc5lRfosz++Y7X2BGhDkz+cySgbD+NYS1pOxfm0VEbLi9PZ3pAulI4kchw==} engines: {node: '>=16'} cpu: [arm64] os: [darwin] - '@openai/codex@0.142.5-darwin-x64': - resolution: {integrity: sha512-yk6A06/VmW7NFsa48OVPaj//g/zeSpd79wjuqfXZwW8ZKRYQm3+wCd3hWjPl79F3QnXvDvM2j3JMIBL3m3GXXg==} + '@openai/codex@0.163.0-darwin-x64': + resolution: {integrity: sha512-Ioj7h+B1ME9ZU1PH1ATfvFV5DiototEpFFaSSbg3kfDifB9djhl5fcJ++g5mpcL/+uVbcnReei+RiSXEx8o+kw==} engines: {node: '>=16'} cpu: [x64] os: [darwin] - '@openai/codex@0.142.5-linux-arm64': - resolution: {integrity: sha512-77ka5PSnm5HdxdBT99IwntCasmbqevlS0eiC0AtEb6ZXCLkim2gm0AWm+jNYy0EhbssvNK+KghayWo34HMgXeA==} + '@openai/codex@0.163.0-linux-arm64': + resolution: {integrity: sha512-IH2/R+4OarjGvsAf1ll3fdyLwrPgYLl3uzp6u9CyD9sj2Lw+ViDSe3QBZVHdcHJs0eIiZFg6Wprcuy4CRZaUGw==} engines: {node: '>=16'} cpu: [arm64] os: [linux] - '@openai/codex@0.142.5-linux-x64': - resolution: {integrity: sha512-pxY+d3NgNE57Y/MApD3/TZUAygxJN6I9h3ZeDUwe67mxWjUxsuapxMRFTKSznCalYbRAeZp752+AAXmUbmguEg==} + '@openai/codex@0.163.0-linux-x64': + resolution: {integrity: sha512-uwRaOsrYogLQhcxAM/GoeWrw0QIWEMRo7c9gM8sKAviVkZQHlu9kRLJ5PkufbV+ABGjyZgIwiFdJ0LCJ0N6e8w==} engines: {node: '>=16'} cpu: [x64] os: [linux] - '@openai/codex@0.142.5-win32-arm64': - resolution: {integrity: sha512-65BEqGbUZ7r0ayunIHdBjo5crwgbwKX/6puOcO+VCswUw/dXvDsN2IGcbXB52+bS9U5+FxP783cUHfTT6m40DQ==} + '@openai/codex@0.163.0-win32-arm64': + resolution: {integrity: sha512-QnLn3gR2dExcdTThE/HAo5BrUq0/C8zDGQ0UZL3hNzfqt9ZklT6jGTyt8JhDyNZX4uSB4HhcJtbcOWucZGC0VQ==} engines: {node: '>=16'} cpu: [arm64] os: [win32] - '@openai/codex@0.142.5-win32-x64': - resolution: {integrity: sha512-a+wI4PEx9a2fg6V5ueTTDkOkr1XpEvA5RFXIbo/L2hOfzMmGtyRnbG24bCGu5Q2RSgVxSQV0aLkdb3vdYMNH9A==} + '@openai/codex@0.163.0-win32-x64': + resolution: {integrity: sha512-QQGQ/q9dCJ5C5jqhgFrwycpWG3szIyFNThMiKl6hYtu6N/eM3Qd7StesgnCFAfzVED8IkE3N3oH71szzcludqw==} engines: {node: '>=16'} cpu: [x64] os: [win32] @@ -337,8 +337,8 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.17.0: - resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} + acorn@8.19.0: + resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==} engines: {node: '>=0.4.0'} hasBin: true @@ -367,6 +367,10 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} + brace-expansion@5.0.12: + resolution: {integrity: sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==} + engines: {node: 20 || >=22} + brace-expansion@5.0.6: resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} engines: {node: 18 || 20 || >=22} @@ -496,8 +500,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.11.0: - resolution: {integrity: sha512-P7a6UEEqb9G95MYAtqkmsTbVXIYyzIfl6NGOIJk162PaahFxFyeGcrlXYFSiagECg4sEm8IseJdZBKR3rx6MsQ==} + eslint@10.12.0: + resolution: {integrity: sha512-npHjrHb2o4ehH3mE+YuxABR+0gyb0aVWCIolgJDArwCiHEIsonBm3ZKjel5b0U5+a+MbEvIyRCGCzD3eKKK2NA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -557,8 +561,8 @@ packages: flat-cache@6.1.23: resolution: {integrity: sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==} - flatted@3.4.2: - resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + flatted@3.4.4: + resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} @@ -576,8 +580,8 @@ packages: resolution: {integrity: sha512-1pgFdhK3J2LeM+dVf2Pd424yHx2ou338lC0ErNP2hPx4j8eW1Sp0XqSjNxtk6Tc4Kr5wlWtSvz8cn2yb7/SG/w==} engines: {node: '>=20'} - globals@17.12.0: - resolution: {integrity: sha512-cezEd/DTyyht9cvSSURyygXPfy04GtWO/5e6ZPvH7fCtjKz9PYOmuawphw1Ctd1f6C+5JypXfGD7ahNMXvevBA==} + globals@17.13.0: + resolution: {integrity: sha512-RwMTC61u7hrG3ZJMkZQOK4JLJrKS8QtoTii63EmWvFXHqycY9FObBJQCbsLxSO8kjKhWE5kV1GC+Vb1g3RI0Zg==} engines: {node: '>=18'} hashery@1.5.1: @@ -799,6 +803,10 @@ packages: resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} + engines: {node: 18 || 20 || >=22} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -811,8 +819,8 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - node-addon-api@8.8.0: - resolution: {integrity: sha512-c5Ko1fZJIJmzhFIkhRN76WTq+fC6tWnGy9CXA0fA+XygsWZmEwG8vmbkNqxMyoaa0Tin4djul49NzdVcJJcjeA==} + node-addon-api@8.9.2: + resolution: {integrity: sha512-VijLXbi3UACN69I0JVXJsX4tjACjNoQDgv2gTF6sx2wWEi8tkSg2eX8p5gSIFi8z2+DL3oHmY6OyKce38SDolg==} engines: {node: ^18 || ^20 || >= 21} node-pty@1.0.0: @@ -860,8 +868,8 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier@3.9.9: - resolution: {integrity: sha512-Z/CJHIkdujO/OtN7nXUii0Rf3VT5SRuhjBA82Xvu2XhBUgX3nhP67T0LHceBdQLex7OOFGTox+Q5Yg8Jk2Qivg==} + prettier@3.9.10: + resolution: {integrity: sha512-skGHTH1Yb9QvaTC4hWnRTzEYtCpApF0UMBPz+t/0ZPzP8ihefo/btKd+QA7pUE0fEwA1SbS/NmhyEcstdXOIdA==} engines: {node: '>=14'} hasBin: true @@ -1122,9 +1130,9 @@ snapshots: '@conventional-changelog/template@1.4.0': {} - '@eslint-community/eslint-utils@4.9.1(eslint@10.11.0(jiti@2.6.1))': + '@eslint-community/eslint-utils@4.10.1(eslint@10.12.0(jiti@2.6.1))': dependencies: - eslint: 10.11.0(jiti@2.6.1) + eslint: 10.12.0(jiti@2.6.1) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} @@ -1133,7 +1141,7 @@ snapshots: dependencies: '@eslint/object-schema': 3.0.5 debug: 4.4.3 - minimatch: 10.2.5 + minimatch: 10.2.6 transitivePeerDependencies: - supports-color @@ -1145,9 +1153,9 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/js@10.0.1(eslint@10.11.0(jiti@2.6.1))': + '@eslint/js@10.0.1(eslint@10.12.0(jiti@2.6.1))': optionalDependencies: - eslint: 10.11.0(jiti@2.6.1) + eslint: 10.12.0(jiti@2.6.1) '@eslint/object-schema@3.0.5': {} @@ -1158,10 +1166,10 @@ snapshots: '@github/keytar@7.10.6': dependencies: - node-addon-api: 8.8.0 + node-addon-api: 8.9.2 optional: true - '@google/gemini-cli@0.49.0': + '@google/gemini-cli@0.64.0': optionalDependencies: '@github/keytar': 7.10.6 '@lydell/node-pty': 1.1.0 @@ -1224,31 +1232,31 @@ snapshots: '@lydell/node-pty-win32-x64': 1.1.0 optional: true - '@openai/codex@0.142.5': + '@openai/codex@0.163.0': optionalDependencies: - '@openai/codex-darwin-arm64': '@openai/codex@0.142.5-darwin-arm64' - '@openai/codex-darwin-x64': '@openai/codex@0.142.5-darwin-x64' - '@openai/codex-linux-arm64': '@openai/codex@0.142.5-linux-arm64' - '@openai/codex-linux-x64': '@openai/codex@0.142.5-linux-x64' - '@openai/codex-win32-arm64': '@openai/codex@0.142.5-win32-arm64' - '@openai/codex-win32-x64': '@openai/codex@0.142.5-win32-x64' - - '@openai/codex@0.142.5-darwin-arm64': + '@openai/codex-darwin-arm64': '@openai/codex@0.163.0-darwin-arm64' + '@openai/codex-darwin-x64': '@openai/codex@0.163.0-darwin-x64' + '@openai/codex-linux-arm64': '@openai/codex@0.163.0-linux-arm64' + '@openai/codex-linux-x64': '@openai/codex@0.163.0-linux-x64' + '@openai/codex-win32-arm64': '@openai/codex@0.163.0-win32-arm64' + '@openai/codex-win32-x64': '@openai/codex@0.163.0-win32-x64' + + '@openai/codex@0.163.0-darwin-arm64': optional: true - '@openai/codex@0.142.5-darwin-x64': + '@openai/codex@0.163.0-darwin-x64': optional: true - '@openai/codex@0.142.5-linux-arm64': + '@openai/codex@0.163.0-linux-arm64': optional: true - '@openai/codex@0.142.5-linux-x64': + '@openai/codex@0.163.0-linux-x64': optional: true - '@openai/codex@0.142.5-win32-arm64': + '@openai/codex@0.163.0-win32-arm64': optional: true - '@openai/codex@0.142.5-win32-x64': + '@openai/codex@0.163.0-win32-x64': optional: true '@simple-libs/child-process-utils@2.0.0': @@ -1277,11 +1285,11 @@ snapshots: '@types/unist@2.0.11': {} - acorn-jsx@5.3.2(acorn@8.17.0): + acorn-jsx@5.3.2(acorn@8.19.0): dependencies: - acorn: 8.17.0 + acorn: 8.19.0 - acorn@8.17.0: {} + acorn@8.19.0: {} ajv@6.15.0: dependencies: @@ -1307,6 +1315,10 @@ snapshots: balanced-match@4.0.4: {} + brace-expansion@5.0.12: + dependencies: + balanced-match: 4.0.4 + brace-expansion@5.0.6: dependencies: balanced-match: 4.0.4 @@ -1417,9 +1429,9 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.11.0(jiti@2.6.1): + eslint@10.12.0(jiti@2.6.1): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.11.0(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.10.1(eslint@10.12.0(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.23.5 '@eslint/config-helpers': 0.7.0 @@ -1446,7 +1458,7 @@ snapshots: imurmurhash: 0.1.4 is-glob: 4.0.3 json-stable-stringify-without-jsonify: 1.0.1 - minimatch: 10.2.5 + minimatch: 10.2.6 natural-compare: 1.4.0 optionator: 0.9.4 optionalDependencies: @@ -1456,8 +1468,8 @@ snapshots: espree@11.2.0: dependencies: - acorn: 8.17.0 - acorn-jsx: 5.3.2(acorn@8.17.0) + acorn: 8.19.0 + acorn-jsx: 5.3.2(acorn@8.19.0) eslint-visitor-keys: 5.0.1 esquery@1.7.0: @@ -1496,10 +1508,10 @@ snapshots: flat-cache@6.1.23: dependencies: cacheable: 2.5.0 - flatted: 3.4.2 + flatted: 3.4.4 hookified: 1.15.1 - flatted@3.4.2: {} + flatted@3.4.4: {} get-caller-file@2.0.5: {} @@ -1513,7 +1525,7 @@ snapshots: dependencies: ini: 6.0.0 - globals@17.12.0: {} + globals@17.13.0: {} hashery@1.5.1: dependencies: @@ -1828,6 +1840,10 @@ snapshots: dependencies: brace-expansion: 5.0.6 + minimatch@10.2.6: + dependencies: + brace-expansion: 5.0.12 + minimist@1.2.8: {} ms@2.1.3: {} @@ -1837,7 +1853,7 @@ snapshots: natural-compare@1.4.0: {} - node-addon-api@8.8.0: + node-addon-api@8.9.2: optional: true node-pty@1.0.0: @@ -1893,7 +1909,7 @@ snapshots: prelude-ls@1.2.1: {} - prettier@3.9.9: {} + prettier@3.9.10: {} punycode.js@2.3.1: {} diff --git a/scripts/bench-compare-official.py b/scripts/bench-compare-official.py index 886d4eed..09d8b982 100755 --- a/scripts/bench-compare-official.py +++ b/scripts/bench-compare-official.py @@ -127,7 +127,7 @@ def resident_operations(): ("save_scene", {}), ("console", {"tail": 20, "level": "log"}), ("screenshot", {"view": "game", "width": 1280, "height": 720}), - ("find_assets", {"type": "Material", "search_in": [bench.FIXTURE]}), + ("find_assets", {"type": "Material", "search_in": bench.FIXTURE}), ("copy_asset", {"asset": bench.SOURCE, "destination": bench.COPIED}), ("move_asset", {"asset": bench.COPIED, "destination": bench.MOVED}), ("delete_asset", {"asset": bench.MOVED, "confirm": True}), diff --git a/scripts/bridge_auth.py b/scripts/bridge_auth.py index 8032d07f..279e9c43 100644 --- a/scripts/bridge_auth.py +++ b/scripts/bridge_auth.py @@ -4,6 +4,38 @@ from pathlib import Path +def process_alive(pid): + """Observe a process without sending Windows console-control events.""" + if pid <= 0 or pid > 0xFFFFFFFF: + return False + if os.name == "nt": + import ctypes + from ctypes import wintypes + + kernel32 = ctypes.WinDLL("kernel32", use_last_error=True) + kernel32.OpenProcess.argtypes = [wintypes.DWORD, wintypes.BOOL, wintypes.DWORD] + kernel32.OpenProcess.restype = wintypes.HANDLE + kernel32.WaitForSingleObject.argtypes = [wintypes.HANDLE, wintypes.DWORD] + kernel32.WaitForSingleObject.restype = wintypes.DWORD + kernel32.CloseHandle.argtypes = [wintypes.HANDLE] + kernel32.CloseHandle.restype = wintypes.BOOL + handle = kernel32.OpenProcess(0x00100000, False, pid) # SYNCHRONIZE only + if not handle: + return ctypes.get_last_error() == 5 # Access denied to an existing process + try: + state = kernel32.WaitForSingleObject(handle, 0) + if state == 0xFFFFFFFF: # WAIT_FAILED + raise ctypes.WinError(ctypes.get_last_error()) + return state == 258 # WAIT_TIMEOUT: the process has not exited + finally: + kernel32.CloseHandle(handle) + try: + os.kill(pid, 0) + return True + except (ProcessLookupError, OverflowError): + return False + + def auth_fields(port, editors_dir=None, pid=None): folder = Path(editors_dir or os.environ.get("UNITY_CLI_EDITORS_DIR", Path.home() / ".unity-cli/editors")) matches = [] @@ -19,7 +51,8 @@ def auth_fields(port, editors_dir=None, pid=None): or int(lock.get("port", 0)) != int(port) or not isinstance(token, str) or not token): continue - os.kill(editor_pid, 0) + if not process_alive(editor_pid): + continue matches.append(token) except (OSError, ValueError, TypeError): continue diff --git a/scripts/e2e-editor-lifecycle.py b/scripts/e2e-editor-lifecycle.py index 6c24d951..4d83ae20 100644 --- a/scripts/e2e-editor-lifecycle.py +++ b/scripts/e2e-editor-lifecycle.py @@ -10,15 +10,13 @@ import tempfile import time +from bridge_auth import process_alive + ROOT = Path(__file__).resolve().parents[1] def alive(pid): - try: - os.kill(pid, 0) - return True - except ProcessLookupError: - return False + return process_alive(pid) def data(value): diff --git a/scripts/install-from-source.ps1 b/scripts/install-from-source.ps1 new file mode 100644 index 00000000..e9f08cd7 --- /dev/null +++ b/scripts/install-from-source.ps1 @@ -0,0 +1,112 @@ +# Build this checkout and install it as the managed unity-cli binary, the same +# place scripts/install.ps1 puts a release, so unityd and your agents run your +# build. For contributors testing changes the way users run them. +# Usage: ./scripts/install-from-source.ps1 [-DebugBuild] [-SkipBuild] [-Skills | -NoSkills] +# +# Environment (same as install.ps1): +# UNITY_CLI_TOOLS_ROOT managed tools root (default: ~\.unity\tools) +# UNITY_CLI_SKIP_PATH_UPDATE set to 1 to leave the user PATH unchanged +# +# Set UNITY_CLI_NO_AUTO_UPDATE=1 (user scope) while you run a source build: +# otherwise the next release's self-update replaces it. +param( + [switch]$DebugBuild, + [switch]$SkipBuild, + [ValidateSet('claude-code', 'cursor', 'windsurf', 'vscode')][string]$Skills, + [switch]$NoSkills +) +$ErrorActionPreference = 'Stop' + +function Fail([string]$Message) { Write-Error "error: $Message"; exit 1 } + +# Read before step 2 sets it for the daemon-stop call. +$optedOut = ($env:UNITY_CLI_NO_AUTO_UPDATE -eq '1') -or + ([Environment]::GetEnvironmentVariable('UNITY_CLI_NO_AUTO_UPDATE', 'User') -eq '1') + +$repoRoot = Resolve-Path (Join-Path $PSScriptRoot '..') +$profileDir = if ($DebugBuild) { 'debug' } else { 'release' } +$targetDir = if ($env:CARGO_TARGET_DIR) { $env:CARGO_TARGET_DIR } else { Join-Path $repoRoot 'target' } +$built = Join-Path $targetDir "$profileDir\unity-cli.exe" + +# 1. Build +if (-not $SkipBuild) { + if (-not (Get-Command cargo -ErrorAction SilentlyContinue)) { Fail 'cargo not found (install Rust from https://rustup.rs)' } + $cargoArgs = @('build', '--bin', 'unity-cli', '--locked') + if (-not $DebugBuild) { $cargoArgs += '--release' } + Push-Location $repoRoot + try { & cargo @cargoArgs; if ($LASTEXITCODE -ne 0) { Fail 'cargo build failed' } } + finally { Pop-Location } +} +if (-not (Test-Path $built)) { Fail "no build at $built (drop -SkipBuild)" } + +$versionLine = (& $built --version | Out-String).Trim() +if ($versionLine -notmatch '^unity-cli (\S+)$') { Fail "unexpected version output: $versionLine" } +$version = $Matches[1] +$commit = (git -C $repoRoot rev-parse --short HEAD 2>$null) + +# 2. Stop the daemon so the installed exe is not locked +$toolsRoot = if ($env:UNITY_CLI_TOOLS_ROOT) { $env:UNITY_CLI_TOOLS_ROOT.Trim() } ` + else { Join-Path $HOME '.unity\tools' } +$destDir = Join-Path $toolsRoot 'unity-cli\win-x64' +$binary = Join-Path $destDir 'unity-cli.exe' +New-Item -ItemType Directory -Force -Path $destDir | Out-Null +if (Test-Path $binary) { + $env:UNITY_CLI_NO_AUTO_UPDATE = '1' + # A broken or partial install must not block reinstalling. + try { & $binary unityd stop *> $null } catch { } + # Anything else still running the old exe keeps it locked; Windows allows + # renaming a running exe, so move it aside instead of failing. + Get-ChildItem -Path $destDir -Filter 'unity-cli.exe.old-*' -ErrorAction SilentlyContinue | + Remove-Item -Force -ErrorAction SilentlyContinue + $locked = $true + foreach ($i in 1..10) { + try { [IO.File]::Open($binary, 'Open', 'ReadWrite', 'None').Close(); $locked = $false; break } + catch { Start-Sleep -Milliseconds 500 } + } + if ($locked) { + $aside = "$binary.old-$PID" + Move-Item -Force -Path $binary -Destination $aside + Write-Host "unity-cli.exe is in use; moved it to $aside" + } +} + +# 3. Install and write VERSION. VERSION holds the build's own version, so +# self-update only replaces the build once a newer release exists. +$tmp = Join-Path $destDir 'unity-cli.download' +Copy-Item -Force -Path $built -Destination $tmp +Move-Item -Force -Path $tmp -Destination $binary +Set-Content -Path (Join-Path $destDir 'VERSION') -Value $version -NoNewline:$false -Encoding ascii +Write-Host "Installed unity-cli $version ($profileDir build of $commit) -> $binary" + +# 4. Add the managed directory to the user PATH (same as install.ps1) +if ($env:UNITY_CLI_SKIP_PATH_UPDATE -ne '1') { + $userPath = [Environment]::GetEnvironmentVariable('Path', 'User') + $entries = @($userPath -split ';' | Where-Object { $_ }) + if ($entries -notcontains $destDir) { + [Environment]::SetEnvironmentVariable('Path', (($entries + $destDir) -join ';'), 'User') + Write-Host "Added $destDir to the user PATH. Restart your terminal to pick it up." + } + if (($env:Path -split ';') -notcontains $destDir) { + $env:Path = "$env:Path;$destDir" + } +} + +# 5. Skills: refresh installed copies to this build, or install for a client +if ($NoSkills) { + # Leave installed skills alone (tests, or a binary-only change). +} elseif ($Skills) { + & $binary skills install $Skills --force + if ($LASTEXITCODE -ne 0) { Fail "skills install $Skills failed" } +} else { + & $binary skills refresh *> $null + if ($LASTEXITCODE -eq 0) { Write-Host 'Refreshed installed skills to this build.' } +} + +$cargoBin = Join-Path $HOME '.cargo\bin\unity-cli.exe' +if (Test-Path $cargoBin) { + Write-Warning "$cargoBin exists and may shadow the managed binary. Consider running: cargo uninstall unity-cli" +} +if (-not $optedOut) { + Write-Warning ("Self-update will replace this build when a newer release ships. To keep it, run: " + + "[Environment]::SetEnvironmentVariable('UNITY_CLI_NO_AUTO_UPDATE','1','User')") +} diff --git a/scripts/install-from-source.sh b/scripts/install-from-source.sh new file mode 100755 index 00000000..34902b72 --- /dev/null +++ b/scripts/install-from-source.sh @@ -0,0 +1,97 @@ +#!/bin/sh +# Build this checkout and install it as the managed unity-cli binary, the same +# place scripts/install.sh puts a release, so unityd and your agents run your +# build. For contributors testing changes the way users run them. +# Usage: ./scripts/install-from-source.sh [--debug] [--skip-build] [--skills | --no-skills] +# +# Environment: +# UNITY_CLI_TOOLS_ROOT managed tools root (default: ~/.unity/tools) +# +# Export UNITY_CLI_NO_AUTO_UPDATE=1 (in your shell profile) while you run a +# source build: otherwise the next release's self-update replaces it. +set -e + +die() { echo "error: $*" >&2; exit 1; } + +PROFILE=release +SKIP_BUILD=0 +SKILLS="" +NO_SKILLS=0 +while [ $# -gt 0 ]; do + case "$1" in + --debug) PROFILE=debug; shift ;; + --skip-build) SKIP_BUILD=1; shift ;; + --no-skills) NO_SKILLS=1; shift ;; + --skills) SKILLS="${2:-}"; [ -n "$SKILLS" ] || die "--skills needs a client"; shift 2 ;; + -h|--help) sed -n '2,11p' "$0"; exit 0 ;; + *) die "unknown option: $1" ;; + esac +done + +REPO_ROOT=$(cd "$(dirname "$0")/.." && pwd) +BUILT="${CARGO_TARGET_DIR:-${REPO_ROOT}/target}/${PROFILE}/unity-cli" + +case "$(uname -s)/$(uname -m)" in + Darwin/arm64|Darwin/aarch64) RID=osx-arm64 ;; + Darwin/x86_64) RID=osx-x64 ;; + Linux/aarch64|Linux/arm64) RID=linux-arm64 ;; + Linux/x86_64) RID=linux-x64 ;; + *) die "unsupported platform $(uname -s)/$(uname -m) (on Windows use scripts/install-from-source.ps1)" ;; +esac + +# 1. Build +if [ "$SKIP_BUILD" = 0 ]; then + command -v cargo >/dev/null 2>&1 || die "cargo not found (install Rust from https://rustup.rs)" + if [ "$PROFILE" = release ]; then + (cd "$REPO_ROOT" && cargo build --bin unity-cli --locked --release) + else + (cd "$REPO_ROOT" && cargo build --bin unity-cli --locked) + fi +fi +[ -x "$BUILT" ] || die "no build at ${BUILT} (drop --skip-build)" + +VERSION=$("$BUILT" --version | awk '{print $2}') +[ -n "$VERSION" ] || die "could not read the build's version" +COMMIT=$(git -C "$REPO_ROOT" rev-parse --short HEAD 2>/dev/null || echo unknown) + +# 2. Stop the daemon running the old binary +DEST_DIR="${UNITY_CLI_TOOLS_ROOT:-${HOME}/.unity/tools}/unity-cli/${RID}" +BINARY="${DEST_DIR}/unity-cli" +mkdir -p "$DEST_DIR" +if [ -x "$BINARY" ]; then + UNITY_CLI_NO_AUTO_UPDATE=1 "$BINARY" unityd stop >/dev/null 2>&1 || true +fi + +# 3. Install and write VERSION. VERSION holds the build's own version, so +# self-update only replaces the build once a newer release exists. +TMP="${DEST_DIR}/unity-cli.download" +cp "$BUILT" "$TMP" +chmod 755 "$TMP" +mv -f "$TMP" "$BINARY" +printf '%s\n' "$VERSION" > "${DEST_DIR}/VERSION" + +# 4. Symlink (same as install.sh) +LINK_DIR="${HOME}/.local/bin" +mkdir -p "$LINK_DIR" +ln -sf "$BINARY" "${LINK_DIR}/unity-cli" +echo "Installed unity-cli ${VERSION} (${PROFILE} build of ${COMMIT}) -> ${LINK_DIR}/unity-cli" + +# 5. Skills: refresh installed copies to this build, or install for a client +if [ "$NO_SKILLS" = 1 ]; then + : # leave installed skills alone (tests, or a binary-only change) +elif [ -n "$SKILLS" ]; then + "$BINARY" skills install "$SKILLS" --force +elif "$BINARY" skills refresh >/dev/null 2>&1; then + echo "Refreshed installed skills to this build." +fi + +if [ -f "${HOME}/.cargo/bin/unity-cli" ]; then + echo "" + echo "WARNING: ${HOME}/.cargo/bin/unity-cli exists and may shadow the managed binary." + echo " Consider running: cargo uninstall unity-cli" +fi +if [ "${UNITY_CLI_NO_AUTO_UPDATE:-}" != 1 ]; then + echo "" + echo "WARNING: self-update will replace this build when a newer release ships." + echo " To keep it, add to your shell profile: export UNITY_CLI_NO_AUTO_UPDATE=1" +fi diff --git a/scripts/install.ps1 b/scripts/install.ps1 index 22658f3d..7de07394 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -5,7 +5,8 @@ # auto-update maintains (%USERPROFILE%\.unity\tools\unity-cli\), and that # directory is added to the user PATH. The download is verified against the # release SHA256SUMS (or the release manifest for older releases); any -# mismatch aborts the install before the existing binary is touched. +# mismatch aborts the install before the existing binary is touched. Transient +# network errors (no response, 408, 429, 5xx) are retried with backoff. # # Environment: # UNITY_CLI_VERSION install a specific tag instead of the latest @@ -30,18 +31,50 @@ function Get-Rid { } } +function Get-HttpStatus($ErrorRecord) { + $response = $ErrorRecord.Exception.Response + if ($response -and $response.StatusCode) { return [int]$response.StatusCode } + return $null +} + +# No HTTP response (DNS, refused, reset, timeout), 408, 429 and 5xx are worth +# another attempt; any other status is a definitive answer. +function Test-TransientError($ErrorRecord) { + $status = Get-HttpStatus $ErrorRecord + return ($null -eq $status -or $status -eq 408 -or $status -eq 429 -or $status -ge 500) +} + +function Invoke-WithRetry([scriptblock]$Action) { + $attempts = 4 + for ($attempt = 1; ; $attempt++) { + try { + return & $Action + } catch { + if ($attempt -ge $attempts -or -not (Test-TransientError $_)) { throw } + $delay = [math]::Pow(2, $attempt - 1) + Write-Host "Download failed ($($_.Exception.Message)); retrying in ${delay}s..." + Start-Sleep -Seconds $delay + } + } +} + function Get-Text([string]$Url) { - $content = (Invoke-WebRequest -Uri $Url -UseBasicParsing -Headers @{ 'User-Agent' = 'unity-cli-installer' }).Content - # Decode before returning: PowerShell enumerates byte[] function results - # into Object[], which would bypass the caller's byte[] type check. - if ($content -is [byte[]]) { return [System.Text.Encoding]::UTF8.GetString($content) } - return $content + Invoke-WithRetry { + $content = (Invoke-WebRequest -Uri $Url -UseBasicParsing -Headers @{ 'User-Agent' = 'unity-cli-installer' }).Content + # Decode before returning: PowerShell enumerates byte[] function results + # into Object[], which would bypass the caller's byte[] type check. + if ($content -is [byte[]]) { return [System.Text.Encoding]::UTF8.GetString($content) } + return $content + } } +# Returns $null only when the server definitively answers that the file is not +# there, so the caller can fall back; a network failure aborts with its cause. function Get-OptionalText([string]$Url) { try { Get-Text $Url } catch { + if (Test-TransientError $_) { Fail "failed to download ${Url}: $($_.Exception.Message)" } $null } } @@ -55,8 +88,10 @@ if ($env:UNITY_CLI_VERSION) { if (-not $tag.StartsWith('v')) { $tag = "v$tag" } } else { Write-Host 'Fetching latest release...' - $release = Invoke-RestMethod -Uri "https://api.github.com/repos/$Repo/releases/latest" ` - -Headers @{ 'User-Agent' = 'unity-cli-installer' } + $release = Invoke-WithRetry { + Invoke-RestMethod -Uri "https://api.github.com/repos/$Repo/releases/latest" ` + -Headers @{ 'User-Agent' = 'unity-cli-installer' } + } $tag = $release.tag_name } if (-not $tag) { Fail 'failed to determine release tag' } @@ -99,8 +134,10 @@ $tmp = Join-Path $destDir 'unity-cli.download' Write-Host "Downloading $assetName..." try { - Invoke-WebRequest -Uri $assetUrl -OutFile $tmp -UseBasicParsing ` - -Headers @{ 'User-Agent' = 'unity-cli-installer' } + Invoke-WithRetry { + Invoke-WebRequest -Uri $assetUrl -OutFile $tmp -UseBasicParsing ` + -Headers @{ 'User-Agent' = 'unity-cli-installer' } + } } catch { Remove-Item -Force -ErrorAction SilentlyContinue $tmp Fail "download failed: $($_.Exception.Message)" diff --git a/scripts/install.sh b/scripts/install.sh index b7ea6d39..add6e82c 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -4,6 +4,8 @@ # # The download is verified against the release SHA256SUMS (or the release # manifest for older releases) and the install aborts on any mismatch. +# Transient network errors (no response, 408, 429, 5xx) are retried with +# backoff by curl; a missing file (404) is not. # # Environment: # UNITY_CLI_VERSION install a specific tag instead of the latest @@ -18,6 +20,11 @@ LINK_DIR="${HOME}/.local/bin" die() { echo "error: $*" >&2; exit 1; } +# curl with backoff retries for transient failures only. +fetch() { + curl -fsSL --retry 3 --retry-connrefused "$@" +} + need() { command -v "$1" >/dev/null 2>&1 || die "required command not found: $1" } @@ -72,7 +79,7 @@ if [ -n "${UNITY_CLI_VERSION:-}" ]; then case "$TAG" in v*) ;; *) TAG="v${TAG}" ;; esac else echo "Fetching latest release..." - TAG=$(curl -fsSL "https://api.github.com/repos/${REPO}/releases/latest" \ + TAG=$(fetch "https://api.github.com/repos/${REPO}/releases/latest" \ | grep '"tag_name"' | head -1 | sed 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/') fi @@ -85,14 +92,22 @@ ASSET_NAME="unity-cli-${RID}" # 2. Resolve the expected SHA-256 and asset URL. # Prefer SHA256SUMS; fall back to the manifest for releases without it. -SUMS=$(curl -fsSL "${BASE_URL}/${TAG}/SHA256SUMS" 2>/dev/null) || SUMS="" +# Only a definitive "not there" (HTTP error 22, unreadable file:// 37) +# selects the fallback; a network failure aborts with its cause. +SUMS_RC=0 +SUMS=$(fetch "${BASE_URL}/${TAG}/SHA256SUMS") || SUMS_RC=$? +case "$SUMS_RC" in + 0) ;; + 22|37) SUMS="" ;; + *) die "failed to download SHA256SUMS (curl exit ${SUMS_RC})" ;; +esac if [ -n "$SUMS" ]; then EXPECTED_SHA=$(printf '%s\n' "$SUMS" \ | awk -v name="$ASSET_NAME" '{ f = $2; sub(/^\*/, "", f); if (f == name) { print tolower($1); exit } }') [ -z "$EXPECTED_SHA" ] && die "SHA256SUMS has no entry for ${ASSET_NAME}" ASSET_URL="${BASE_URL}/${TAG}/${ASSET_NAME}" else - MANIFEST=$(curl -fsSL "${BASE_URL}/${TAG}/unity-cli-manifest.json") \ + MANIFEST=$(fetch "${BASE_URL}/${TAG}/unity-cli-manifest.json") \ || die "failed to download SHA256SUMS or manifest" ASSET_URL=$(echo "$MANIFEST" | grep -A2 "\"${RID}\"" | grep '"url"' | head -1 \ | sed 's/.*"url"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/') @@ -108,7 +123,7 @@ mkdir -p "$DEST_DIR" TMP="${DEST_DIR}/unity-cli.download" echo "Downloading ${ASSET_NAME}..." -curl -fsSL -o "$TMP" "$ASSET_URL" || { rm -f "$TMP"; die "download failed"; } +fetch -o "$TMP" "$ASSET_URL" || { rm -f "$TMP"; die "download failed"; } # 4. Verify SHA-256 before touching the installed binary ACTUAL_SHA=$(sha256_check "$TMP") diff --git a/scripts/lsp-write-reliability.py b/scripts/lsp-write-reliability.py new file mode 100644 index 00000000..e0e43e86 --- /dev/null +++ b/scripts/lsp-write-reliability.py @@ -0,0 +1,447 @@ +"""Measure real CLI/LSP writes against independent direct-edit byte oracles (#490). + +No Unity Editor is needed: syntax and filesystem editing are the measured surface. +Failure observations are data; an explicit baseline gates *new* checkout regressions. +The initial-download route deliberately measures the published LSP, not a mock. +""" +import argparse +from collections import Counter +from datetime import datetime, timezone +import difflib +import errno +import hashlib +import json +import math +import os +from pathlib import Path +import platform +import shutil +import socket +import subprocess +import tempfile +import time + +CONDITIONS = ("warm_indexed", "daemon_stopped", "unindexed", "first_download") +OS_NAMES = ("Windows", "macOS", "Linux") +BOM = b"\xef\xbb\xbf" +CORRUPTION = {"bom_added", "bom_removed", "newlines_changed", "text_changed", "file_set_changed", "wrong_backend"} + + +def scenarios(): + cases = [] + + def add(scenario_name, tool, before, after, **params): + encode = lambda files: {key: value.encode("utf-8") for key, value in files.items()} + cases.append({"id": scenario_name, "tool": tool, "before": encode(before), + "after": encode(after), "params": params}) + + path = "Assets/Sample.cs" + for kind, parent in (("monobehaviour", "MonoBehaviour"), ("scriptableobject", "ScriptableObject"), ("plain", None)): + text = ("using UnityEngine;\n\n" if parent else "") + "public class Sample" + (f" : {parent}" if parent else "") + "\n{\n}\n" + add("create_class_" + kind, "create_class", {}, {path: text}, name="Sample", path=path, **({"inherits": parent} if parent else {})) + for kind, text in ( + ("plain", "public class Sample {}\n"), + ("monobehaviour", "using UnityEngine;\npublic class Sample : MonoBehaviour {}\n"), + ("scriptableobject", "using UnityEngine;\npublic class Sample : ScriptableObject {}\n"), + ): + add("create_" + kind, "create_csharp_file", {}, {path: text}, relative=path, text=text) + original = "public class Sample { public int Run(){return 1;}}\n" + updated = original.replace("return 1;", "return 2;") + add("replace_body", "replace_symbol_body", {path: original}, {path: updated}, relative=path, namePath="Sample/Run", body="{return 2;}") + add("write_file", "write_csharp_file", {path: original}, {path: updated}, relative=path, newText=updated) + # Compact source makes insertion/removal trivia unambiguous to the direct oracle. + member = "public int Added;" + compact = "public class Sample {public int Run(){return 1;}}\n" + add("insert_before", "insert_before_symbol", {path: compact}, {path: compact.replace("public int Run", member + "public int Run")}, relative=path, namePath="Sample/Run", text=member) + add("insert_after", "insert_after_symbol", {path: compact}, {path: compact.replace("return 1;}", "return 1;}" + member)}, relative=path, namePath="Sample/Run", text=member) + add("remove_member", "remove_symbol", {path: compact}, {path: "public class Sample {}\n"}, relative=path, namePath="Sample/Run") + shaped = "namespace Demo { [System.Serializable] public partial class Sample { public T Run(){return default(T);}} }\n" + add("namespace_partial_generic_attributes", "replace_symbol_body", {path: shaped}, {path: shaped.replace("return default(T);", "throw new System.Exception();")}, relative=path, namePath="Sample/Run", body="{throw new System.Exception();}") + commented = "public class Sample { public int Run(){return 1;} // 日本語の説明を保持\npublic int Next(){return 3;} }\n" + add("replace_preserve_comment", "replace_symbol_body", {path: commented}, {path: commented.replace("return 1;", "return 2;")}, relative=path, namePath="Sample/Run", body="{return 2;}") + declaration = "namespace Demo { public partial class Sample {} }\n" + use = "namespace Demo { public class Consumer { public Sample Value; } }\n" + unrelated = "namespace Other { public class Sample {} public class Consumer { public Sample Value; } }\n" + add("rename_multifile", "rename_symbol", {path: declaration, "Assets/Use.cs": use, "Assets/Other.cs": unrelated}, + {path: declaration.replace("Sample", "Renamed"), "Assets/Use.cs": use.replace("Sample", "Renamed"), "Assets/Other.cs": unrelated}, + relative=path, namePath="Sample", newName="Renamed") + for bom in (False, True): + unicode = ("\ufeff" if bom else "") + "// 日本語コメント 🐈\r\n" + original.replace("\n", "\r\n") + new = unicode.replace("return 1;", "return 2;") + # The BOM is a file encoding property, not part of the LSP newText string. + add("unicode_" + ("bom" if bom else "no_bom") + "_crlf", "write_csharp_file", {path: unicode}, {path: new}, relative=path, newText=new.lstrip("\ufeff")) + large = "public class Sample {\n" + "".join(f" public int Field{i} = {i};\n" for i in range(3500)) + "}\n" + large_new = large.replace("Field3499 = 3499", "Field3499 = 42") + add("large_3500_lines", "write_csharp_file", {path: large}, {path: large_new}, relative=path, newText=large_new) + broken = "public class Sample { public int Run(){return 1} }\n" + add("repair_syntax_error", "apply_csharp_edits", {path: broken, "Assets/Second.cs": "public class Second {}\n"}, + {path: original, "Assets/Second.cs": "public class Second { public int Added; }\n"}, + files=[{"relative": path, "newText": original}, {"relative": "Assets/Second.cs", "newText": "public class Second { public int Added; }\n"}]) + add("validate_without_write", "validate_text_edits", {path: original}, {path: original}, relative=path, newText=updated) + return cases + + +def compare_files(expected, actual): + signatures, differences = set(), [] + for name in sorted(set(expected) | set(actual)): + before, after = expected.get(name), actual.get(name) + if before == after: + continue + if before is None or after is None: + signatures.add("file_set_changed") + else: + if before.startswith(BOM) != after.startswith(BOM): + signatures.add("bom_removed" if before.startswith(BOM) else "bom_added") + left, right = before.removeprefix(BOM), after.removeprefix(BOM) + if left.replace(b"\r\n", b"\n") == right.replace(b"\r\n", b"\n"): + if left != right: + signatures.add("newlines_changed") + else: + signatures.add("text_changed") + left_text = (before or b"").decode("utf-8", errors="replace").splitlines(keepends=True) + right_text = (after or b"").decode("utf-8", errors="replace").splitlines(keepends=True) + differences.append({"path": name, "direct_sha256": hashlib.sha256(before).hexdigest() if before is not None else None, + "lsp_sha256": hashlib.sha256(after).hexdigest() if after is not None else None, + "direct_text_sha256": hashlib.sha256(before.removeprefix(BOM).replace(b"\r\n", b"\n")).hexdigest() if before is not None else None, + "lsp_text_sha256": hashlib.sha256(after.removeprefix(BOM).replace(b"\r\n", b"\n")).hexdigest() if after is not None else None, + "direct_bytes": len(before) if before is not None else None, + "lsp_bytes": len(after) if after is not None else None, + "diff": "".join(difflib.unified_diff(left_text, right_text, fromfile="direct/" + name, tofile="lsp/" + name))}) + return sorted(signatures), differences + + +def response_failures(returncode, envelope): + data = envelope.get("data", {}) + if not isinstance(data, dict): + return ["other"] + if data.get("success") is False: + return ["tool_rejected"] + if returncode != 0 or envelope.get("success") is not True or data.get("success") is not True: + return ["other"] + return [] if data.get("backend") == "lsp" else ["wrong_backend"] + + +def summarize(rows): + def percentile(key, fraction): + values = sorted(row[key] for row in rows) + return round(values[max(0, math.ceil(len(values) * fraction) - 1)], 3) if values else None + failures = Counter(failure for row in rows for failure in row["failures"]) + return {"attempts": len(rows), "successes": sum(not row["failures"] for row in rows), + "success_rate": sum(not row["failures"] for row in rows) / len(rows) if rows else 0, + "failure_types": dict(failures), "p50_ms": percentile("elapsed_ms", 0.5), "p95_ms": percentile("elapsed_ms", 0.95), + "direct_p50_ms": percentile("direct_ms", 0.5), "direct_p95_ms": percentile("direct_ms", 0.95)} + + +def regressions(rows, baseline): + result = [] + expected_paths = {case["id"]: {name for name in set(case["before"]) | set(case["after"]) + if case["before"].get(name) != case["after"].get(name)} for case in scenarios()} + for row in rows: + known = baseline.get(row["scenario"], {}) + # An old release exception cannot hide a checkout or future-release regression. + published = known.get("published", {}) if isinstance(known, dict) else {} + if row.get("lsp_version") in published.get("versions", []): + known = published + allowed = known.get("failures", []) if isinstance(known, dict) else known + new = set(row["failures"]) - set(allowed) + if row["scenario"] in expected_paths and any(d["path"] not in expected_paths[row["scenario"]] for d in row.get("differences", [])): + new.add("unexpected_file_difference") + # A known text defect may never mask a different destructive edit. + if "text_changed" in row["failures"]: + hashes = known.get("text_hashes", {}) if isinstance(known, dict) else {} + changes = [d for d in row.get("differences", []) if d.get("direct_text_sha256") != d.get("lsp_text_sha256")] + if not changes or any(hashes.get(d["path"]) != d.get("lsp_text_sha256") for d in changes): + new.add("unexpected_text_difference") + if new: + result.append({"scenario": row["scenario"], "condition": row.get("condition"), "new_failures": sorted(new)}) + return result + + +def markdown(reports): + groups = {} + for report in reports: + for row in report["rows"]: + groups.setdefault((report["os"], row["condition"], row["scenario"]), []).append(row) + missing = [f"{system}/{condition}/{case['id']}" for system in OS_NAMES for condition in CONDITIONS for case in scenarios() + if (system, condition, case["id"]) not in groups] + corrupt = any(CORRUPTION.intersection(row["failures"]) for rows in groups.values() for row in rows) + incomplete = missing or any(report.get("interrupted") or not report.get("finished_at") for report in reports) + qualification = "INSUFFICIENT" if incomplete else "ELIGIBLE" if not corrupt and all(summarize(rows)["success_rate"] >= 0.99 for rows in groups.values()) else "DO NOT ENFORCE" + lines = ["# C# LSP write reliability", "", f"Decision evidence: **{qualification}**.", "", + "直接編集の禁止はオーナー判断です。全シナリオ・全 OS で成功率 99% 以上、誤編集・BOM/改行の破壊 0 件を目安にします。", + "バイト差分がある試行は失敗として数えます。少数サンプルの 100% は将来の 99% の保証ではありません。", + "初回ダウンロードは公開 LSP、warm/unindexed は checkout LSP、自動起動は LSP 更新を含みます。各試行の VERSION/SHA256 を区別します。Unity のコンパイル・refresh は測定範囲外です。", "", + "Launch mode: autonomous", "User Verification Result: n/a (autonomous)", "Agent Visual Check: n/a (no UI surface)", "", + "| OS | Condition | Scenario | Success / attempts | Rate | LSP p50 / p95 ms | Direct p50 / p95 ms | Failure signatures |", + "| --- | --- | --- | --- | --- | --- | --- | --- |"] + for (system, condition, scenario), rows in sorted(groups.items()): + value = summarize(rows) + lines.append(f"| {system} | {condition} | {scenario} | {value['successes']}/{value['attempts']} | {value['success_rate']:.1%} | {value['p50_ms']} / {value['p95_ms']} | {value['direct_p50_ms']} / {value['direct_p95_ms']} | {json.dumps(value['failure_types'])} |") + lines += ["", "## Coverage", "", f"Missing OS/condition/scenario cells: {len(missing)}."] + if missing: + lines.append("Missing operating systems: " + ", ".join(system for system in OS_NAMES if not any(key[0] == system for key in groups))) + lines += ["", "## Defects to fix before enforcement", ""] + defects = sorted({failure for rows in groups.values() for row in rows for failure in row["failures"]}) + lines += ["- " + failure + ": see per-attempt raw response, SHA256 and unified diff in the JSON artifact." for failure in defects] + if not defects: + lines.append("No defects observed in executed samples; unexecuted cells remain unproven.") + return "\n".join(lines) + "\n" + + +def rid(): + system = {"Windows": "win", "Darwin": "osx", "Linux": "linux"}[platform.system()] + architecture = "arm64" if platform.machine().lower() in ("arm64", "aarch64") else "x64" + return system + "-" + architecture + + +def write_files(root, files): + for name, data in files.items(): + path = root / name + path.parent.mkdir(parents=True, exist_ok=True) + path.write_bytes(data) + + +def snapshot(root): + return {path.relative_to(root).as_posix(): path.read_bytes() for path in root.rglob("*.cs")} + + +def sha256_file(path): + with path.open("rb") as stream: + return hashlib.file_digest(stream, "sha256").hexdigest() + + +def cleanup_trial(directory, root): + if not directory.resolve().is_relative_to(root.resolve()) or directory.resolve() == root.resolve(): + raise RuntimeError("refusing to clean a trial outside the measurement directory") + deadline = time.monotonic() + 10 + while True: + try: + shutil.rmtree(directory) + return + except OSError as error: + # Windows can keep clrjit.dll locked briefly after lspd exits, and a + # stopping lspd can still add files while rmtree walks the tree. + if not (isinstance(error, PermissionError) or error.errno == errno.ENOTEMPTY) or time.monotonic() >= deadline: + raise + time.sleep(0.1) + + +def install_server_alias(source, target): + # macOS / Windows filesystems are usually case-insensitive: Server and server are one file. + if target.exists() and target.samefile(source): + return + shutil.copy2(source, target) + + +class Trial: + def __init__(self, cli, lsp_publish, root, condition, timeout): + self.cli, self.root, self.condition, self.timeout = cli, root, condition, timeout + self.project = root / "project" + (self.project / "Assets").mkdir(parents=True) + self.tools = root / "tools" + self.env = os.environ.copy() + self.env.update({"UNITY_CLI_TOOLS_ROOT": str(self.tools), "UNITY_CLI_CACHE_ROOT": str(root / "cache"), + "UNITY_CLI_REGISTRY_PATH": str(root / "registry.json"), "UNITY_PROJECT_ROOT": str(self.project), + "UNITY_CLI_LSP_MODE": "required", "UNITY_CLI_NO_AUTO_UPDATE": "1", "UNITY_CLI_LSPD_IDLE_TIMEOUT": "30"}) + # Never silently inherit a switch which disables the real download route. + self.env.pop("UNITY_CLI_TEST_SKIP_MANAGED_UPDATE", None) + install = self.tools / "unity-cli" / rid() + install.mkdir(parents=True) + shutil.copy2(cli, install / cli.name) + (install / "VERSION").write_text("checkout\n", encoding="utf-8") + self.server = self.tools / "csharp-lsp" / rid() / ("server.exe" if os.name == "nt" else "server") + if condition != "first_download": + shutil.copytree(lsp_publish, self.server.parent) + install_server_alias(self.server.parent / ("Server.exe" if os.name == "nt" else "Server"), self.server) + self.server.chmod(0o755) + (self.server.parent / "VERSION").write_text("checkout\n", encoding="utf-8") + self.env["UNITY_CLI_TEST_SKIP_MANAGED_UPDATE"] = "1" + self.process = None + self.log = None + + def command(self, args): + return [str(self.cli), "--output", "json", "--project-path", str(self.project), *args] + + def call(self, tool, params): + # --params-file also covers large inputs on Windows without its argv limit. + payload = self.root / "params.json" + payload.write_text(json.dumps(params, ensure_ascii=False), encoding="utf-8") + command = self.command(["raw", tool, "--params-file", str(payload)]) + completed = subprocess.run(command, env=self.env, capture_output=True, timeout=self.timeout) + stdout = completed.stdout.decode("utf-8", errors="replace") + stderr = completed.stderr.decode("utf-8", errors="replace") + try: + envelope = json.loads(stdout) + except ValueError: + envelope = {} + return completed.returncode, envelope, stdout, stderr + + def start(self): + # Windows lspd currently has a host-wide fixed port. Refuse to share it. + if os.name == "nt": + with socket.socket() as probe: + if probe.connect_ex(("127.0.0.1", 6421)) == 0: + raise RuntimeError("lsp_startup_failure: lspd port 6421 already occupied; no process was stopped") + self.log = (self.root / "daemon.log").open("wb") + self.process = subprocess.Popen(self.command(["lspd", "serve"]), env=self.env, stdout=self.log, stderr=subprocess.STDOUT) + deadline = time.monotonic() + 20 + while time.monotonic() < deadline: + if self.process.poll() is not None: + raise RuntimeError("lsp_startup_failure: owned lspd exited: " + (self.root / "daemon.log").read_text(errors="replace")) + completed = subprocess.run(self.command(["lspd", "status"]), env=self.env, capture_output=True, timeout=10) + try: + if json.loads(completed.stdout).get("data", {}).get("running") is True: + return + except ValueError: + pass + time.sleep(0.05) + raise RuntimeError("lsp_startup_failure: owned lspd did not become ready") + + def close(self): + # A PID file in this unique tools root identifies the auto-started daemon. + pid_file = self.tools / "run" / "lspd" / "lspd.pid" + owned = pid_file.exists() + if owned and self.process is not None: + owned = pid_file.read_text().strip() == str(self.process.pid) + if owned: + try: + subprocess.run(self.command(["lspd", "stop"]), env=self.env, capture_output=True, timeout=15) + except subprocess.TimeoutExpired: + pass + # `lspd stop` only requests shutdown; the daemon removes its PID file on exit. + deadline = time.monotonic() + 10 + while pid_file.exists() and time.monotonic() < deadline: + time.sleep(0.1) + if self.process is not None: + try: + self.process.wait(timeout=10) + except subprocess.TimeoutExpired: + self.process.kill() # Only the exact child started by this trial. + self.process.wait(timeout=10) + if self.log is not None: + self.log.close() + + +def measure(cli, lsp_publish, output, condition, case, sample, timeout): + directory = output / "trials" / f"{condition}-{case['id']}-{sample}" + directory.mkdir(parents=True) + trial = Trial(cli, lsp_publish, directory, condition, timeout) + write_files(trial.project, case["before"]) + direct = directory / "direct" + write_files(direct, case["before"]) + started = time.perf_counter() + for name in set(case["before"]) - set(case["after"]): + (direct / name).unlink() + write_files(direct, case["after"]) + direct_ms = (time.perf_counter() - started) * 1000 + row = {"scenario": case["id"], "tool": case["tool"], "condition": condition, "sample": sample, + "direct_ms": direct_ms, "failures": [], "differences": []} + started = time.perf_counter() + try: + if condition in ("warm_indexed", "unindexed"): + trial.start() + elif os.name == "nt": + with socket.socket() as probe: + if probe.connect_ex(("127.0.0.1", 6421)) == 0: + raise RuntimeError("lsp_startup_failure: lspd port 6421 already occupied") + if condition == "warm_indexed": + rc, value, _, error = trial.call("build_index", {}) + if rc or value.get("success") is not True: + raise RuntimeError("lsp_startup_failure: index setup failed: " + error + json.dumps(value)) + row["setup_ms"] = (time.perf_counter() - started) * 1000 + started = time.perf_counter() + params = dict(case["params"]) + if case["tool"] not in ("validate_text_edits", "create_class"): + params["apply"] = True + if case["tool"] in ("create_csharp_file", "write_csharp_file", "apply_csharp_edits"): + params.update({"refresh": False, "waitForCompile": False}) + rc, value, stdout, stderr = trial.call(case["tool"], params) + row.update({"returncode": rc, "response": value, "stdout": stdout, "stderr": stderr}) + row["failures"] = response_failures(rc, value) + error = (stdout + stderr).lower() + if row["failures"]: + if "timeout" in error or "timed out" in error: + row["failures"] = ["timeout"] + elif "failed to start" in error or "failed to spawn" in error or "failed to connect" in error: + row["failures"] = ["lsp_startup_failure"] + elif "manifest" in error or "download" in error: + row["failures"] = ["download_failure"] + except subprocess.TimeoutExpired as error: + row.update({"failures": ["timeout"], "error": str(error)}) + except (RuntimeError, OSError) as error: + row.update({"failures": ["lsp_startup_failure"], "error": str(error)}) + finally: + row["elapsed_ms"] = (time.perf_counter() - started) * 1000 + signatures, row["differences"] = compare_files(snapshot(direct), snapshot(trial.project)) + row["failures"] = sorted(set(row["failures"] + signatures)) + if trial.server.exists(): + row["lsp_version"] = (trial.server.parent / "VERSION").read_text().strip() + row["lsp_sha256"] = sha256_file(trial.server) + trial.close() + # Delete only this generated trial, after resolving its boundary explicitly. + cleanup_trial(directory, output) + return row + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--unity-cli", type=Path) + parser.add_argument("--lsp-publish", type=Path) + parser.add_argument("--out", type=Path, required=True) + parser.add_argument("--repetitions", type=int, default=5) + parser.add_argument("--download-repetitions", type=int, default=1) + parser.add_argument("--cold-repetitions", type=int, default=1) + parser.add_argument("--conditions", default=",".join(CONDITIONS)) + parser.add_argument("--scenarios", help="Comma-separated scenario IDs for a focused recovery run; default: all") + parser.add_argument("--timeout", type=int, default=180) + parser.add_argument("--baseline", type=Path) + parser.add_argument("--record-only", action="store_true", help="Collect failures as evidence without a regression gate") + parser.add_argument("--merge", type=Path, nargs="+", help="Aggregate existing JSON reports; no tests are executed") + args = parser.parse_args() + args.out = args.out.resolve() + args.out.mkdir(parents=True, exist_ok=True) + if args.merge: + reports = [json.loads(path.read_text(encoding="utf-8")) for path in args.merge] + (args.out / "summary.md").write_text(markdown(reports), encoding="utf-8") + return 0 + conditions = args.conditions.split(",") + cases = scenarios() + if args.scenarios: + selected = args.scenarios.split(",") + if any(name not in {case["id"] for case in cases} for name in selected): + parser.error("unknown scenario ID") + cases = [case for case in cases if case["id"] in selected] + if not args.unity_cli or not args.lsp_publish or min(args.repetitions, args.download_repetitions, args.cold_repetitions) < 1 or any(c not in CONDITIONS for c in conditions): + parser.error("supply --unity-cli/--lsp-publish, positive repetitions and valid conditions") + cli, publish = args.unity_cli.resolve(), args.lsp_publish.resolve() + if not cli.is_file() or not (publish / ("Server.exe" if os.name == "nt" else "Server")).is_file(): + parser.error("build the CLI and publish the real LSP for the current RID first") + # Use a short temporary path on Unix for the daemon's Unix socket limit. + reports = {"schema_version": 1, "os": "macOS" if platform.system() == "Darwin" else platform.system(), + "rid": rid(), "started_at": datetime.now(timezone.utc).isoformat(), "cli_sha256": sha256_file(cli), + "runner_sha256": sha256_file(Path(__file__)), + "requested_conditions": conditions, "repetitions": args.repetitions, + "cold_repetitions": args.cold_repetitions, "download_repetitions": args.download_repetitions, + "rows": []} + with tempfile.TemporaryDirectory(prefix="lsp490-") as temp: + for condition in conditions: + count = args.download_repetitions if condition == "first_download" else args.cold_repetitions if condition == "daemon_stopped" else args.repetitions + for case in cases: + for sample in range(count): + row = measure(cli, publish, Path(temp), condition, case, sample, args.timeout) + reports["rows"].append(row) + print(f"{condition}/{case['id']}/{sample}: {','.join(row['failures']) or 'PASS'}", flush=True) + # Persist each measured row so a later abort cannot erase evidence. + (args.out / "results.json").write_text(json.dumps(reports, ensure_ascii=False, indent=2), encoding="utf-8") + reports["summary"] = summarize(reports["rows"]) + baseline = json.loads(args.baseline.read_text(encoding="utf-8")) if args.baseline else {} + reports["regressions"] = regressions(reports["rows"], baseline) + reports["finished_at"] = datetime.now(timezone.utc).isoformat() + (args.out / "results.json").write_text(json.dumps(reports, ensure_ascii=False, indent=2), encoding="utf-8") + (args.out / "summary.md").write_text(markdown([reports]), encoding="utf-8") + print(json.dumps(reports["summary"])) + return 1 if reports["regressions"] and not args.record_only else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/skill-eval/run-codex-routing.py b/scripts/skill-eval/run-codex-routing.py index 52335633..40435290 100644 --- a/scripts/skill-eval/run-codex-routing.py +++ b/scripts/skill-eval/run-codex-routing.py @@ -462,8 +462,14 @@ def has_any(*terms: str) -> bool: return make_prediction(["unity-csharp-edit"], "validate_text_edits", ["relative", "newText"]) if has_any("play検証はまだ不要") and has_any(".cs") and has_any("実装したい"): return make_prediction(["unity-csharp-edit"], "write_csharp_file", ["relative", "newText"]) - if has_any("クラス") and has_any("assets/") and has_any("作りたい", "新規作成"): - return make_prediction(["unity-csharp-edit"], "create_class", ["name", "folder"]) + if has_any("コンパイルエラー", "compile error") and has_any("直", "修正", "fix"): + return make_prediction(["unity-csharp-edit"], "apply_csharp_edits", ["files"]) + if ( + has_any("クラス", "monobehaviour", "scriptableobject", "c# script") + and has_any("assets/") + and has_any("作りたい", "新規作成", "create", "write") + ): + return make_prediction(["unity-csharp-edit"], "create_csharp_file", ["relative", "text"]) if has_any("ゲームパッド") and has_any("ボタン"): return make_prediction(["unity-playmode-testing"], "input_gamepad", ["action", "button", "buttonAction"]) if has_any("play") and has_any("space") and has_any("スクリーンショット"): diff --git a/src/app/editor.rs b/src/app/editor.rs index 72cfa87f..ec0be9df 100644 --- a/src/app/editor.rs +++ b/src/app/editor.rs @@ -37,10 +37,11 @@ pub(super) fn running(root: &Path) -> Option { } pub(super) fn launch_command(editor: &Path, root: &Path, headless: bool) -> Command { + let root = unity_argument_path(root); let mut command = Command::new(editor); command .arg("-projectPath") - .arg(root) + .arg(&root) .arg("-logFile") .arg(root.join("Logs/unity-cli-editor.log")) .stdin(Stdio::null()) @@ -59,6 +60,21 @@ pub(super) fn launch_command(editor: &Path, root: &Path, headless: bool) -> Comm command } +pub(super) fn unity_argument_path(path: &Path) -> PathBuf { + #[cfg(windows)] + { + // Unity's command-line parser does not accept canonical Win32 verbatim paths. + let text = path.to_string_lossy(); + if let Some(unc) = text.strip_prefix(r"\\?\UNC\") { + return PathBuf::from(format!(r"\\{unc}")); + } + if let Some(local) = text.strip_prefix(r"\\?\") { + return PathBuf::from(local); + } + } + path.to_path_buf() +} + pub async fn open(cli: &Cli, headless: bool, wait_ready: u64) -> Result { let root = project(cli)?; let version = super::setup::project_unity_version(&root)?; @@ -85,8 +101,7 @@ pub async fn open(cli: &Cli, headless: bool, wait_ready: u64) -> Result { command.env("UNITY_CLI_PORT_OVERRIDE", port.to_string()); } Some( - command - .spawn() + crate::daemon::spawn::spawn_detached(&mut command) .with_context(|| format!("Failed to launch {}", editor.display()))?, ) } else { @@ -226,3 +241,29 @@ pub async fn status(cli: &Cli) -> Result { }; Ok(json!({"state": label, "projectPath": root, "diagnostic": diagnostic})) } + +#[cfg(all(test, windows))] +mod tests { + use super::*; + + #[test] + fn editor_launch_uses_paths_supported_by_unity() { + for (root, expected) in [ + (r"\\?\C:\Projects\With spaces", r"C:\Projects\With spaces"), + (r"\\?\UNC\server\share\Project", r"\\server\share\Project"), + ] { + let command = launch_command(Path::new("Unity.exe"), Path::new(root), true); + let args: Vec<_> = command + .get_args() + .map(|arg| arg.to_string_lossy()) + .collect(); + assert_eq!(args[1], expected); + assert_eq!( + args[3], + Path::new(expected) + .join("Logs/unity-cli-editor.log") + .to_string_lossy() + ); + } + } +} diff --git a/src/app/setup.rs b/src/app/setup.rs index 4733a7b5..b8cfda44 100644 --- a/src/app/setup.rs +++ b/src/app/setup.rs @@ -211,7 +211,7 @@ fn launch_editor(root: &Path, port: u16) -> Result { let mut command = std::process::Command::new(&editor); command .arg("-projectPath") - .arg(root) + .arg(super::editor::unity_argument_path(root)) .env("UNITY_CLI_PORT", port.to_string()) .stdin(std::process::Stdio::null()) .stdout(std::process::Stdio::null()) @@ -222,8 +222,7 @@ fn launch_editor(root: &Path, port: u16) -> Result { // Detach from the caller's process group so the Editor outlives it. command.process_group(0); } - let child = command - .spawn() + let child = crate::daemon::spawn::spawn_detached(&mut command) .with_context(|| format!("Failed to launch {}", editor.display()))?; Ok(json!({ "launched": true, diff --git a/src/app/test_runner.rs b/src/app/test_runner.rs index 031fdca8..76300032 100644 --- a/src/app/test_runner.rs +++ b/src/app/test_runner.rs @@ -37,7 +37,8 @@ pub async fn run(cli: &Cli, args: &TestArgs) -> Result<()> { if let Some(port) = cli.port { command.env("UNITY_CLI_PORT_OVERRIDE", port.to_string()); } - let child = command.spawn().context(FailureKind::Unreachable)?; + let child = + crate::daemon::spawn::spawn_detached(&mut command).context(FailureKind::Unreachable)?; eprintln!("Started headless Editor (pid {})", child.id()); Some(child) }; diff --git a/src/core/failure.rs b/src/core/failure.rs index b6438831..b9e3ec53 100644 --- a/src/core/failure.rs +++ b/src/core/failure.rs @@ -25,11 +25,15 @@ pub struct UnityCommandError { impl UnityCommandError { pub fn new(response: Value) -> Self { - let error = response + let detail = response + .as_array() + .and_then(|items| items.iter().find(|item| item["ok"] == false)) + .unwrap_or(&response); + let error = detail .get("error") .and_then(Value::as_str) .unwrap_or_else(|| { - if response + if detail .get("status") .and_then(Value::as_str) .is_some_and(|status| status.eq_ignore_ascii_case("error")) @@ -39,7 +43,7 @@ impl UnityCommandError { "Unity command failed" } }); - let code = response + let code = detail .get("code") .and_then(Value::as_str) .unwrap_or("UNKNOWN_ERROR"); @@ -150,3 +154,23 @@ pub fn batch_error(error: &Error) -> Value { let failure = classify(error); serde_json::json!({"ok":false, "code":failure.code, "error":failure.message, "details":failure.data}) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn failed_batch_preserves_first_failure_message_and_all_results() { + let response = serde_json::json!([ + {"ok": true, "result": {"message": "pong"}}, + {"ok": false, "code": "EDITOR_UNREACHABLE", "error": "Failed to connect to Unity at 127.0.0.1:9"}, + {"ok": false, "code": "UNAUTHORIZED", "error": "Missing credential"} + ]); + let error = check_response(&response).unwrap_err(); + assert!(format!("{error:#}").contains("Failed to connect to Unity at 127.0.0.1:9")); + let failure = classify(&error); + assert_eq!(failure.code, "EDITOR_UNREACHABLE"); + assert_eq!(failure.exit, exit_code::EDITOR_UNREACHABLE); + assert_eq!(failure.data, response); + } +} diff --git a/src/core/managed_binaries.rs b/src/core/managed_binaries.rs index 8a059614..524b383c 100644 --- a/src/core/managed_binaries.rs +++ b/src/core/managed_binaries.rs @@ -179,7 +179,6 @@ pub fn install_dir() -> Result { install_dir_for(ManagedBinary::CSharpLsp) } -#[cfg(test)] pub fn binary_path() -> Result { binary_path_for(ManagedBinary::CSharpLsp) } @@ -306,6 +305,12 @@ fn install_latest_for( ensure_latest_for(managed_binary, force_download, false) } +/// `UNITY_CLI_NO_AUTO_UPDATE=1`: never replace an installed unity-cli with a +/// newer release unless the user asks for it. +pub(crate) fn auto_update_disabled() -> bool { + std::env::var("UNITY_CLI_NO_AUTO_UPDATE").ok().as_deref() == Some("1") +} + fn ensure_latest_for( managed_binary: ManagedBinary, force_download: bool, @@ -322,6 +327,18 @@ fn ensure_latest_for( )); } + // Daemon startup (`unityd start`, `lspd`) honours the same opt-out as + // `maybe_self_update` and keeps the installed CLI. A missing binary is + // still installed, since the daemon needs one to run. + if allow_stale_existing + && !force_download + && status.binary_exists + && managed_binary == ManagedBinary::UnityCli + && auto_update_disabled() + { + return Ok(status); + } + match fetch_latest_release(managed_binary) { Ok(latest) => { status.update_available = @@ -1001,6 +1018,49 @@ mod tests { assert!(status.latest.is_none()); } + #[test] + fn daemon_startup_keeps_installed_cli_when_auto_update_disabled() { + let _guard = env_lock() + .lock() + .unwrap_or_else(|poison| poison.into_inner()); + let dir = tempdir().expect("tempdir should succeed"); + let _env = EnvVarGuard::set( + "UNITY_CLI_TOOLS_ROOT", + dir.path() + .to_str() + .expect("tempdir path should be valid UTF-8"), + ); + // Exercise the real code path, not the test-only skip. + let _skip = EnvVarGuard::set("UNITY_CLI_TEST_SKIP_MANAGED_UPDATE", "0"); + let _opt_out = EnvVarGuard::set("UNITY_CLI_NO_AUTO_UPDATE", "1"); + + let binary = + binary_path_for(ManagedBinary::UnityCli).expect("unity-cli binary path should resolve"); + if let Some(parent) = binary.parent() { + fs::create_dir_all(parent).expect("binary parent directory should be created"); + } + fs::write(&binary, b"source-build").expect("binary fixture should be writable"); + // A VERSION that can never match a release, so an update would be due. + write_local_version_for(ManagedBinary::UnityCli, "0.0.0-local") + .expect("VERSION fixture should be writable"); + + let status = + ensure_latest_cli_for_daemon().expect("opt-out should keep the installed binary"); + assert_eq!(status.binary_path, binary); + assert!(status.binary_exists); + // No release lookup at all: neither a result nor a lookup error. + assert!(status.latest.is_none()); + assert!(status.latest_error.is_none()); + assert_eq!( + fs::read(&binary).expect("binary should be readable"), + b"source-build" + ); + assert_eq!( + read_local_version_for(ManagedBinary::UnityCli).as_deref(), + Some("0.0.0-local") + ); + } + #[test] fn sha256_file_matches_known_hash() { let dir = tempdir().expect("tempdir should succeed"); diff --git a/src/core/self_update.rs b/src/core/self_update.rs index 2397cdb8..1f59b2a7 100644 --- a/src/core/self_update.rs +++ b/src/core/self_update.rs @@ -4,8 +4,8 @@ use std::thread::{self, JoinHandle}; use std::time::{Duration, SystemTime}; use crate::core::managed_binaries::{ - binary_path_for, detect_rid, download_latest_binary, fetch_latest_release, install_dir_for, - read_local_version_for, ManagedBinary, + auto_update_disabled, binary_path_for, detect_rid, download_latest_binary, + fetch_latest_release, install_dir_for, read_local_version_for, ManagedBinary, }; const THROTTLE_SECS: u64 = 4 * 60 * 60; // 4 hours @@ -14,7 +14,7 @@ const THROTTLE_SECS: u64 = 4 * 60 * 60; // 4 hours /// binary if a newer version is available. Returns `None` when the check is /// skipped (opt-out env, throttle, or error resolving paths). pub fn maybe_self_update() -> Option> { - if std::env::var("UNITY_CLI_NO_AUTO_UPDATE").ok().as_deref() == Some("1") { + if auto_update_disabled() { tracing::debug!("self-update skipped: UNITY_CLI_NO_AUTO_UPDATE=1"); return None; } diff --git a/src/daemon/unityd.rs b/src/daemon/unityd.rs index ef77b788..0643dfbc 100644 --- a/src/daemon/unityd.rs +++ b/src/daemon/unityd.rs @@ -494,7 +494,7 @@ pub async fn try_batch( )) } -#[cfg(test)] +#[cfg(all(test, unix))] fn ping() -> Result<()> { let response = request(DaemonRequest::Ping)?; if response.ok { @@ -826,6 +826,7 @@ async fn handle_request( #[cfg(test)] mod tests { use super::*; + #[cfg(unix)] use std::io::{BufRead, BufReader, Write}; use tempfile::tempdir; diff --git a/src/lsp/client.rs b/src/lsp/client.rs index cfad58de..9b34ced1 100644 --- a/src/lsp/client.rs +++ b/src/lsp/client.rs @@ -16,6 +16,8 @@ use crate::lspd; const MAX_HEADER_BYTES: usize = 16 * 1024; const DEFAULT_TIMEOUT_MS: u64 = 60_000; +const DEFAULT_AUTO_TIMEOUT_MS: u64 = 10_000; +const AUTO_INSTALL_MARKER_TTL: Duration = Duration::from_secs(600); #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum LspMode { @@ -64,6 +66,11 @@ pub fn maybe_execute( return None; } + // Only symbol search defaults to `auto` (see `route_search`); write tools + // keep their direct-session default unless a mode is set explicitly. + if !lsp_mode_is_set() { + return None; + } let mode = lsp_mode(); if mode == LspMode::Off { return None; @@ -78,6 +85,158 @@ pub fn maybe_execute( } } +/// Why a symbol search was answered by the local regex index instead of the LSP. +#[derive(Debug, Clone)] +pub struct LspFallback { + pub reason: &'static str, + pub detail: String, +} + +impl LspFallback { + fn new(reason: &'static str, detail: impl Into) -> Self { + Self { + reason, + detail: detail.into(), + } + } + + /// Marks an index-backed response so callers can tell the LSP was not used. + pub fn annotate(&self, value: &mut Value) { + if let Some(map) = value.as_object_mut() { + map.insert("backend".to_string(), json!("index")); + map.insert("fallbackReason".to_string(), json!(self.reason)); + map.insert("fallbackDetail".to_string(), json!(self.detail)); + } + } +} + +pub enum SearchRoute { + Lsp(Result), + Index(LspFallback), +} + +/// Routes the read-only symbol search tools. `auto` (the default) prefers the +/// LSP but never waits longer than `UNITY_CLI_LSP_AUTO_TIMEOUT_MS`, and never +/// blocks on the first LSP download. +pub fn route_search(tool_name: &str, params: &Value, project_root: &Path) -> SearchRoute { + match lsp_mode() { + LspMode::Off => SearchRoute::Index(LspFallback::new( + "lsp_disabled", + "UNITY_CLI_LSP_MODE=off selects the local symbol index", + )), + LspMode::Required => SearchRoute::Lsp(execute_via_daemon(tool_name, params, project_root)), + LspMode::Auto => match execute_auto(tool_name, params, project_root) { + Ok(value) => SearchRoute::Lsp(Ok(value)), + Err(fallback) => SearchRoute::Index(fallback), + }, + } +} + +fn execute_auto( + tool_name: &str, + params: &Value, + project_root: &Path, +) -> std::result::Result { + let installed = lsp_manager::binary_path() + .map(|path| path.exists()) + .unwrap_or(false); + if !installed { + let detail = match request_background_install() { + Ok(()) => "C# LSP is not installed yet; installing it in the background".to_string(), + Err(error) => { + format!("C# LSP is not installed and the background install failed: {error:#}") + } + }; + return Err(LspFallback::new("lsp_not_installed", detail)); + } + + let tool_name = tool_name.to_string(); + let params = params.clone(); + let project_root = project_root.to_path_buf(); + run_with_timeout(auto_timeout(), move || { + execute_via_daemon(&tool_name, ¶ms, &project_root) + }) +} + +fn run_with_timeout(timeout: Duration, call: F) -> std::result::Result +where + F: FnOnce() -> Result + Send + 'static, +{ + let (sender, receiver) = mpsc::channel(); + thread::spawn(move || { + let _ = sender.send(call()); + }); + match receiver.recv_timeout(timeout) { + Ok(Ok(value)) => Ok(value), + Ok(Err(error)) => Err(LspFallback::new("lsp_unavailable", format!("{error:#}"))), + Err(mpsc::RecvTimeoutError::Timeout) => Err(LspFallback::new( + "lsp_timeout", + format!( + "LSP did not answer within {}ms (UNITY_CLI_LSP_AUTO_TIMEOUT_MS); it keeps warming up in lspd", + timeout.as_millis() + ), + )), + Err(mpsc::RecvTimeoutError::Disconnected) => Err(LspFallback::new( + "lsp_unavailable", + "LSP worker ended without a response", + )), + } +} + +fn auto_timeout() -> Duration { + let millis = env::var("UNITY_CLI_LSP_AUTO_TIMEOUT_MS") + .ok() + .and_then(|value| value.trim().parse::().ok()) + .filter(|value| *value > 0) + .unwrap_or(DEFAULT_AUTO_TIMEOUT_MS); + Duration::from_millis(millis) +} + +fn auto_install_marker() -> Result { + Ok(lsp_manager::install_dir()?.join(".auto-install-requested")) +} + +/// Starts `unity-cli lsp install` detached so the download survives this +/// short-lived CLI process. A marker keeps concurrent calls from racing on the +/// same download file. +fn request_background_install() -> Result<()> { + let marker = auto_install_marker()?; + let fresh = fs_modified_age(&marker).is_some_and(|age| age < AUTO_INSTALL_MARKER_TTL); + if fresh { + return Ok(()); + } + if let Some(parent) = marker.parent() { + std::fs::create_dir_all(parent) + .with_context(|| format!("Failed to create {}", parent.display()))?; + } + std::fs::write(&marker, now_epoch_ms().to_string()) + .with_context(|| format!("Failed to write {}", marker.display()))?; + spawn_background_install() +} + +fn fs_modified_age(path: &Path) -> Option { + let modified = std::fs::metadata(path).ok()?.modified().ok()?; + std::time::SystemTime::now().duration_since(modified).ok() +} + +#[cfg(not(test))] +fn spawn_background_install() -> Result<()> { + let exe = env::current_exe().context("Failed to resolve unity-cli executable")?; + Command::new(exe) + .args(["lsp", "install"]) + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn() + .context("Failed to spawn background C# LSP install")?; + Ok(()) +} + +#[cfg(test)] +fn spawn_background_install() -> Result<()> { + Ok(()) +} + fn execute_via_daemon(tool_name: &str, params: &Value, project_root: &Path) -> Result { let _ = lsp_manager::ensure_local(false)?; @@ -215,7 +374,7 @@ fn handle_get_symbols( return Err(anyhow!("File not found: {rel}")); } - let uri = file_uri(&abs); + let uri = file_uri(&abs, session.file_uri_encoding)?; let response = session.request( "textDocument/documentSymbol", json!({ @@ -296,7 +455,7 @@ fn handle_find_symbol( Some(value) => value, None => continue, }; - let rel_path = match uri_to_rel_path(project_root, uri) { + let rel_path = match uri_to_rel_path(project_root, uri, session.file_uri_encoding) { Some(value) => value, None => continue, }; @@ -383,8 +542,8 @@ fn handle_find_refs( let mut refs = response.as_array().cloned().unwrap_or_default(); refs.sort_by(|a, b| { - let a_path = ref_path(project_root, a).unwrap_or_default(); - let b_path = ref_path(project_root, b).unwrap_or_default(); + let a_path = ref_path(project_root, a, session.file_uri_encoding).unwrap_or_default(); + let b_path = ref_path(project_root, b, session.file_uri_encoding).unwrap_or_default(); let a_line = a.get("line").and_then(Value::as_u64).unwrap_or(0); let b_line = b.get("line").and_then(Value::as_u64).unwrap_or(0); let a_col = a.get("column").and_then(Value::as_u64).unwrap_or(0); @@ -402,7 +561,7 @@ fn handle_find_refs( let mut last_path: Option = None; for item in refs { - let Some(path) = ref_path(project_root, &item) else { + let Some(path) = ref_path(project_root, &item, session.file_uri_encoding) else { continue; }; @@ -1072,17 +1231,29 @@ fn normalize_rel_path(raw: &str) -> Option { Some(parts.join("/")) } -fn file_uri(path: &Path) -> String { - format!("file://{}", path.to_string_lossy().replace('\\', "/")) +fn file_uri(path: &Path, encoded: bool) -> Result { + if !encoded { + return Ok(format!( + "file://{}", + path.to_string_lossy().replace('\\', "/") + )); + } + + url::Url::from_file_path(path) + .map(|uri| uri.to_string()) + .map_err(|()| anyhow!("LSP file paths must be absolute")) } -fn uri_to_rel_path(project_root: &Path, uri: &str) -> Option { +fn uri_to_rel_path(project_root: &Path, uri: &str, encoded: bool) -> Option { if !uri.starts_with("file://") { return None; } - let raw = uri.trim_start_matches("file://").replace('\\', "/"); - let path = PathBuf::from(raw); + let path = if encoded { + url::Url::parse(uri).ok()?.to_file_path().ok()? + } else { + PathBuf::from(uri.trim_start_matches("file://").replace('\\', "/")) + }; let rel = path .strip_prefix(project_root) .ok() @@ -1092,10 +1263,10 @@ fn uri_to_rel_path(project_root: &Path, uri: &str) -> Option { normalize_rel_path(&rel) } -fn ref_path(project_root: &Path, item: &Value) -> Option { +fn ref_path(project_root: &Path, item: &Value, encoded: bool) -> Option { let path = item.get("path").and_then(Value::as_str)?; if path.starts_with("file://") { - return uri_to_rel_path(project_root, path); + return uri_to_rel_path(project_root, path, encoded); } normalize_rel_path(path) } @@ -1117,15 +1288,20 @@ fn now_epoch_ms() -> u64 { .unwrap_or(0) } +fn lsp_mode_is_set() -> bool { + env::var("UNITY_CLI_LSP_MODE").is_ok_and(|value| !value.trim().is_empty()) +} + fn lsp_mode() -> LspMode { let raw = env::var("UNITY_CLI_LSP_MODE") .ok() - .unwrap_or_else(|| "off".to_string()) + .unwrap_or_default() + .trim() .to_ascii_lowercase(); match raw.as_str() { "required" => LspMode::Required, - "auto" => LspMode::Auto, + "" | "auto" => LspMode::Auto, _ => LspMode::Off, } } @@ -1148,6 +1324,7 @@ struct LspSession { rx: Receiver, next_id: u64, timeout: Duration, + file_uri_encoding: bool, } impl LspSession { @@ -1191,8 +1368,13 @@ impl LspSession { rx, next_id: 1, timeout: lsp_timeout(), + file_uri_encoding: false, }; + // Older published servers treat file URIs as unescaped path strings. + let ping = session.request("unitycli/ping", json!({}))?; + session.file_uri_encoding = + ping.get("fileUriEncoding").and_then(Value::as_bool) == Some(true); session.initialize(project_root)?; Ok(session) } @@ -1205,7 +1387,7 @@ impl LspSession { "method": "initialize", "params": { "processId": std::process::id(), - "rootUri": file_uri(project_root), + "rootUri": file_uri(project_root, self.file_uri_encoding)?, "capabilities": {} } }))?; @@ -1408,13 +1590,19 @@ mod tests { use std::process::{Command, Stdio}; #[cfg(unix)] use std::sync::{Mutex, OnceLock}; + #[cfg(unix)] + use std::time::Duration; + #[cfg(unix)] use super::{ - build_remove_symbol_request, collect_document_symbols, execute_direct, file_uri, get_apply, - id_matches, is_retryable_session_error, kind_from_lsp, maybe_execute, - normalize_lsp_write_result, normalize_rel_path, path_matches_scope, read_message, ref_path, - require_name_path, require_relative_path, reset_cached_session, to_project_relative_or_raw, - uri_to_rel_path, + auto_timeout, execute_direct, lsp_mode, maybe_execute, read_message, reset_cached_session, + route_search, run_with_timeout, LspMode, SearchRoute, + }; + use super::{ + build_remove_symbol_request, collect_document_symbols, file_uri, get_apply, id_matches, + is_retryable_session_error, kind_from_lsp, normalize_lsp_write_result, normalize_rel_path, + path_matches_scope, ref_path, require_name_path, require_relative_path, + to_project_relative_or_raw, uri_to_rel_path, }; #[cfg(unix)] @@ -1498,7 +1686,9 @@ while True: method = message.get("method") message_id = message.get("id") - if method == "initialize": + if method == "unitycli/ping": + send_message({"jsonrpc": "2.0", "id": message_id, "result": {"ok": True, "fileUriEncoding": True}}) + elif method == "initialize": send_message({"jsonrpc": "2.0", "id": message_id, "result": {"capabilities": {"documentSymbolProvider": True}}}) elif method == "initialized": continue @@ -1636,14 +1826,17 @@ while True: let rel = "Assets/Scripts/Player.cs"; let abs = root.path().join(rel); - let uri = file_uri(&abs); - assert_eq!(uri_to_rel_path(root.path(), &uri).as_deref(), Some(rel)); + let uri = file_uri(&abs, true).expect("file URI should convert"); + assert_eq!( + uri_to_rel_path(root.path(), &uri, true).as_deref(), + Some(rel) + ); assert_eq!( - ref_path(root.path(), &json!({ "path": uri })).as_deref(), + ref_path(root.path(), &json!({ "path": uri }), true).as_deref(), Some(rel) ); assert_eq!( - ref_path(root.path(), &json!({ "path": rel })).as_deref(), + ref_path(root.path(), &json!({ "path": rel }), true).as_deref(), Some(rel) ); } @@ -1651,7 +1844,68 @@ while True: #[test] fn uri_to_rel_path_rejects_non_file_uris() { let root = tempdir().expect("tempdir should succeed"); - assert!(uri_to_rel_path(root.path(), "https://example.com/file.cs").is_none()); + assert!(uri_to_rel_path(root.path(), "https://example.com/file.cs", true).is_none()); + } + + #[test] + fn canonical_file_uris_preserve_encoded_paths_and_assets_scope() { + let root = tempfile::Builder::new() + .prefix("lsp URI 日本語 #%-") + .tempdir() + .expect("tempdir should succeed"); + let rel = "Assets/Scripts/日本語 # %20.cs"; + let abs = root.path().join(rel); + let uri = url::Url::from_file_path(&abs) + .expect("absolute file path should convert") + .to_string(); + + assert_eq!( + uri_to_rel_path(root.path(), &uri, true).as_deref(), + Some(rel) + ); + assert_eq!(file_uri(&abs, true).expect("file URI should convert"), uri); + assert!(path_matches_scope( + &uri_to_rel_path(root.path(), &uri, true).expect("file URI should resolve"), + "assets" + )); + } + + #[cfg(windows)] + #[test] + fn canonical_windows_drive_and_unc_uris_resolve_assets_paths() { + for (root, uri) in [ + (r"C:\repo", "file:///C:/repo/Assets/Player.cs"), + ( + r"\\server\share\repo", + "file://server/share/repo/Assets/Player.cs", + ), + ] { + assert_eq!( + uri_to_rel_path(std::path::Path::new(root), uri, true).as_deref(), + Some("Assets/Player.cs") + ); + } + } + + #[test] + fn legacy_file_uris_preserve_raw_paths_for_older_servers() { + let root = tempfile::Builder::new() + .prefix("legacy URI 日本語 #%-") + .tempdir() + .expect("tempdir should succeed"); + let rel = "Assets/日本語 # %20.cs"; + let path = root.path().join(rel); + let uri = file_uri(&path, false).expect("legacy file URI should convert"); + + assert!(uri.ends_with(rel)); + assert_eq!( + uri_to_rel_path(root.path(), &uri, false).as_deref(), + Some(rel) + ); + assert_eq!( + ref_path(root.path(), &json!({ "path": uri }), false).as_deref(), + Some(rel) + ); } #[test] @@ -1831,7 +2085,10 @@ while True: .to_str() .expect("tools root path should be valid UTF-8"), ); - let _uri = EnvVarGuard::set("FAKE_LSP_PLAYER_URI", &file_uri(&player_path)); + let _uri = EnvVarGuard::set( + "FAKE_LSP_PLAYER_URI", + &file_uri(&player_path, true).expect("file URI should convert"), + ); let _out = EnvVarGuard::set( "FAKE_LSP_OUTPUT_PATH", project_dir @@ -1911,7 +2168,10 @@ while True: .to_str() .expect("tools root path should be valid UTF-8"), ); - let _uri = EnvVarGuard::set("FAKE_LSP_PLAYER_URI", &file_uri(&player_path)); + let _uri = EnvVarGuard::set( + "FAKE_LSP_PLAYER_URI", + &file_uri(&player_path, true).expect("file URI should convert"), + ); let _out = EnvVarGuard::set( "FAKE_LSP_OUTPUT_PATH", project_dir @@ -2027,4 +2287,182 @@ while True: std::env::remove_var("UNITY_CLI_LSP_MODE"); } + + #[cfg(unix)] + #[test] + fn lsp_mode_defaults_to_auto_when_unset() { + let _guard = env_lock().lock().expect("lock should succeed"); + let _mode = EnvVarGuard::set("UNITY_CLI_LSP_MODE", ""); + assert_eq!(lsp_mode(), LspMode::Auto); + std::env::remove_var("UNITY_CLI_LSP_MODE"); + assert_eq!(lsp_mode(), LspMode::Auto); + std::env::set_var("UNITY_CLI_LSP_MODE", "OFF"); + assert_eq!(lsp_mode(), LspMode::Off); + std::env::set_var("UNITY_CLI_LSP_MODE", "Required"); + assert_eq!(lsp_mode(), LspMode::Required); + std::env::set_var("UNITY_CLI_LSP_MODE", "auto"); + assert_eq!(lsp_mode(), LspMode::Auto); + std::env::set_var("UNITY_CLI_LSP_MODE", "bogus"); + assert_eq!(lsp_mode(), LspMode::Off); + } + + #[cfg(unix)] + #[test] + fn auto_timeout_uses_env_override_and_default() { + let _guard = env_lock().lock().expect("lock should succeed"); + let _timeout = EnvVarGuard::set("UNITY_CLI_LSP_AUTO_TIMEOUT_MS", "250"); + assert_eq!(auto_timeout(), Duration::from_millis(250)); + std::env::set_var("UNITY_CLI_LSP_AUTO_TIMEOUT_MS", "0"); + assert_eq!(auto_timeout(), Duration::from_millis(10_000)); + std::env::set_var("UNITY_CLI_LSP_AUTO_TIMEOUT_MS", "nope"); + assert_eq!(auto_timeout(), Duration::from_millis(10_000)); + std::env::remove_var("UNITY_CLI_LSP_AUTO_TIMEOUT_MS"); + assert_eq!(auto_timeout(), Duration::from_millis(10_000)); + } + + #[cfg(unix)] + #[test] + fn run_with_timeout_returns_value_or_times_out() { + let fast = run_with_timeout(Duration::from_secs(5), || Ok(json!({"ok": true}))); + assert_eq!(fast.expect("fast call should succeed")["ok"], true); + + let failing = run_with_timeout(Duration::from_secs(5), || Err(anyhow!("boom"))); + let fallback = failing.expect_err("failing call should fall back"); + assert_eq!(fallback.reason, "lsp_unavailable"); + assert!(fallback.detail.contains("boom")); + + let slow = run_with_timeout(Duration::from_millis(50), || { + std::thread::sleep(Duration::from_millis(500)); + Ok(json!({})) + }); + let fallback = slow.expect_err("slow call should time out"); + assert_eq!(fallback.reason, "lsp_timeout"); + assert!(fallback.detail.contains("50ms")); + } + + #[cfg(unix)] + #[test] + fn route_search_falls_back_to_index_with_reason() { + let _guard = env_lock().lock().expect("lock should succeed"); + let root = tempdir().expect("tempdir should be created"); + let tools = tempdir().expect("tempdir should be created"); + let _tools = EnvVarGuard::set( + "UNITY_CLI_TOOLS_ROOT", + tools + .path() + .to_str() + .expect("tools root path should be valid UTF-8"), + ); + let _skip_updates = EnvVarGuard::set("UNITY_CLI_TEST_SKIP_MANAGED_UPDATE", "1"); + let _mode = EnvVarGuard::set("UNITY_CLI_LSP_MODE", "off"); + let params = json!({"path":"Assets/Scripts/Player.cs"}); + + let SearchRoute::Index(off) = route_search("get_symbols", ¶ms, root.path()) else { + panic!("off mode should use the index"); + }; + assert_eq!(off.reason, "lsp_disabled"); + let mut annotated = json!({"success": true}); + off.annotate(&mut annotated); + assert_eq!(annotated["backend"], "index"); + assert_eq!(annotated["fallbackReason"], "lsp_disabled"); + assert!(annotated["fallbackDetail"] + .as_str() + .expect("detail should be a string") + .contains("UNITY_CLI_LSP_MODE=off")); + + // Default (unset) mode without an installed LSP falls back immediately and + // requests a background install exactly once per marker lifetime. + std::env::remove_var("UNITY_CLI_LSP_MODE"); + let SearchRoute::Index(missing) = route_search("find_symbol", ¶ms, root.path()) else { + panic!("auto mode without LSP should use the index"); + }; + assert_eq!(missing.reason, "lsp_not_installed"); + let marker = super::auto_install_marker().expect("marker path should resolve"); + assert!(marker.exists(), "background install should be requested"); + let first_stamp = fs::read_to_string(&marker).expect("marker should be readable"); + let SearchRoute::Index(again) = route_search("find_symbol", ¶ms, root.path()) else { + panic!("auto mode without LSP should use the index"); + }; + assert_eq!(again.reason, "lsp_not_installed"); + assert_eq!( + fs::read_to_string(&marker).expect("marker should be readable"), + first_stamp, + "a fresh marker must not re-request the install" + ); + + // Installed LSP whose daemon cannot start falls back with the error. + setup_fake_lsp_server(tools.path()); + let _timeout = EnvVarGuard::set("UNITY_CLI_LSP_AUTO_TIMEOUT_MS", "20000"); + let SearchRoute::Index(unavailable) = route_search("find_refs", ¶ms, root.path()) + else { + panic!("auto mode with a broken daemon should use the index"); + }; + assert_eq!(unavailable.reason, "lsp_unavailable"); + + // Required mode keeps surfacing the LSP error instead of falling back. + std::env::set_var("UNITY_CLI_LSP_MODE", "required"); + let SearchRoute::Lsp(result) = route_search("find_refs", ¶ms, root.path()) else { + panic!("required mode should not fall back"); + }; + assert!(result.is_err()); + } + + #[cfg(unix)] + #[test] + fn write_tools_keep_direct_session_default_when_mode_is_unset() { + use std::io::{BufRead, Write as _}; + + let _guard = env_lock().lock().expect("lock should succeed"); + let root = tempdir().expect("tempdir should be created"); + let tools = tempdir().expect("tempdir should be created"); + setup_fake_lsp_server(tools.path()); + let _tools = EnvVarGuard::set( + "UNITY_CLI_TOOLS_ROOT", + tools + .path() + .to_str() + .expect("tools root path should be valid UTF-8"), + ); + let _skip_updates = EnvVarGuard::set("UNITY_CLI_TEST_SKIP_MANAGED_UPDATE", "1"); + let _mode = EnvVarGuard::set("UNITY_CLI_LSP_MODE", ""); + + // A fake lspd that answers exactly one request proves which path ran. + let socket = crate::daemon::runtime::DaemonRuntimePaths::new("lspd") + .and_then(|paths| paths.socket_file()) + .expect("lspd socket path should resolve"); + fs::create_dir_all(socket.parent().expect("socket should have a parent")) + .expect("socket parent should be created"); + let _ = fs::remove_file(&socket); + let listener = + std::os::unix::net::UnixListener::bind(&socket).expect("fake lspd should bind"); + let server = std::thread::spawn(move || { + let (mut stream, _) = listener.accept().expect("fake lspd should accept"); + let mut line = String::new(); + BufReader::new(stream.try_clone().expect("stream should clone")) + .read_line(&mut line) + .expect("request should be readable"); + stream + .write_all(b"{\"ok\":true,\"result\":{\"via\":\"lspd\"}}\n") + .expect("response should be written"); + }); + + let params = json!({"relative":"Assets/Scripts/Player.cs","newText":"class P {}"}); + for unset in ["", " "] { + std::env::set_var("UNITY_CLI_LSP_MODE", unset); + assert!( + maybe_execute("write_csharp_file", ¶ms, root.path()).is_none(), + "unset mode must leave writes on the direct LSP session" + ); + } + std::env::remove_var("UNITY_CLI_LSP_MODE"); + assert!(maybe_execute("write_csharp_file", ¶ms, root.path()).is_none()); + + std::env::set_var("UNITY_CLI_LSP_MODE", "auto"); + let via_daemon = maybe_execute("write_csharp_file", ¶ms, root.path()) + .expect("explicit auto should use lspd") + .expect("fake lspd should answer"); + assert_eq!(via_daemon["via"], "lspd"); + server.join().expect("fake lspd should finish"); + let _ = fs::remove_file(&socket); + } } diff --git a/src/lsp/daemon.rs b/src/lsp/daemon.rs index 65cdaaf8..be21df81 100644 --- a/src/lsp/daemon.rs +++ b/src/lsp/daemon.rs @@ -3,7 +3,7 @@ use std::fs; use std::io::ErrorKind; use std::io::{BufRead, BufReader, Write}; use std::path::{Path, PathBuf}; -use std::process::{Command, Stdio}; +use std::process::{Child, Command, Stdio}; use std::thread; use std::time::{Duration, Instant}; @@ -15,6 +15,10 @@ use crate::daemon::runtime::DaemonRuntimePaths; use crate::lsp_manager; const DAEMON_IDLE_TIMEOUT_SECS: u64 = 600; +/// Upper bound for an auto-started lspd to answer `ping`. A cold start on a +/// busy machine has been measured at more than 12 seconds, so the wait is +/// generous; a startup process that exits fails immediately instead. +const DAEMON_START_TIMEOUT_MS: u64 = 60_000; #[derive(Debug, Serialize, Deserialize)] #[serde(tag = "type", rename_all = "snake_case")] @@ -131,27 +135,80 @@ pub fn start_background() -> Result { let _ = lsp_manager::ensure_latest_lsp_for_daemon()?; let exe = daemon_command_path()?; - Command::new(&exe) - .arg("lspd") - .arg("serve") - .stdin(Stdio::null()) - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .spawn() - .context("Failed to spawn lspd background process")?; - - let deadline = Instant::now() + Duration::from_secs(5); - while Instant::now() < deadline { - if ping().is_ok() { - return Ok(json!({ - "success": true, - "running": true - })); + let log_path = log_file_path()?; + if let Some(parent) = log_path.parent() { + fs::create_dir_all(parent) + .with_context(|| format!("Failed to create daemon directory: {}", parent.display()))?; + } + let log = fs::OpenOptions::new() + .create(true) + .append(true) + .open(&log_path) + .with_context(|| format!("Failed to open lspd log: {}", log_path.display()))?; + let mut child = crate::daemon::spawn::spawn_detached( + Command::new(&exe) + .arg("lspd") + .arg("serve") + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::from(log)), + ) + .context("Failed to spawn lspd background process")?; + + wait_until_ready(&mut child, daemon_start_timeout(), &log_path, || { + ping().is_ok() + })?; + // Reap the daemon if it exits while this process is still alive. + thread::spawn(move || { + let _ = child.wait(); + }); + Ok(json!({ + "success": true, + "running": true + })) +} + +/// Polls `ready` until it succeeds, the startup process exits, or `timeout` +/// elapses. A timed-out startup process is killed so it cannot linger. +fn wait_until_ready( + child: &mut Child, + timeout: Duration, + log_path: &Path, + mut ready: impl FnMut() -> bool, +) -> Result<()> { + let started = Instant::now(); + loop { + if ready() { + return Ok(()); + } + if let Some(status) = child + .try_wait() + .context("Failed to inspect lspd startup process")? + { + // A concurrent auto-start may have won the listener; its daemon + // is serving even though this startup process exited. + if ready() { + return Ok(()); + } + return Err(anyhow!( + "lspd exited during startup ({status}) after {} ms; see {}", + started.elapsed().as_millis(), + log_path.display() + )); + } + if started.elapsed() >= timeout { + let _ = child.kill(); + let _ = child.wait(); + return Err(anyhow!( + "lspd failed to start within {} ms (waited {} ms); see {} \ + (set UNITY_CLI_LSPD_START_TIMEOUT_MS to wait longer)", + timeout.as_millis(), + started.elapsed().as_millis(), + log_path.display() + )); } thread::sleep(Duration::from_millis(100)); } - - Err(anyhow!("lspd failed to start within timeout")) } pub fn stop() -> Result { @@ -485,18 +542,29 @@ fn connect_client() -> Result { #[cfg(not(unix))] { - let stream = std::net::TcpStream::connect(("127.0.0.1", daemon_port())) - .context("Failed to connect to lspd TCP endpoint")?; - stream - .set_read_timeout(Some(Duration::from_secs(10))) - .context("Failed to set lspd read timeout")?; - stream - .set_write_timeout(Some(Duration::from_secs(10))) - .context("Failed to set lspd write timeout")?; - Ok(stream) + connect_tcp_client(daemon_port()) } } +#[cfg(not(unix))] +fn connect_tcp_client(port: u16) -> Result { + // A closed loopback port takes seconds to fail on Windows. Startup probes + // must return promptly so auto-start can spawn/poll lspd without TCP retries. + // Match unityd's connection deadline; RPC timeouts remain independent. + let stream = std::net::TcpStream::connect_timeout( + &std::net::SocketAddr::from(([127, 0, 0, 1], port)), + Duration::from_millis(100), + ) + .context("Failed to connect to lspd TCP endpoint")?; + stream + .set_read_timeout(Some(Duration::from_secs(10))) + .context("Failed to set lspd read timeout")?; + stream + .set_write_timeout(Some(Duration::from_secs(10))) + .context("Failed to set lspd write timeout")?; + Ok(stream) +} + fn is_would_block(error: &std::io::Error) -> bool { error.kind() == std::io::ErrorKind::WouldBlock } @@ -509,6 +577,20 @@ fn daemon_idle_timeout_secs() -> u64 { .unwrap_or(DAEMON_IDLE_TIMEOUT_SECS) } +fn daemon_start_timeout() -> Duration { + Duration::from_millis( + env::var("UNITY_CLI_LSPD_START_TIMEOUT_MS") + .ok() + .and_then(|v| v.parse::().ok()) + .filter(|v| *v > 0) + .unwrap_or(DAEMON_START_TIMEOUT_MS), + ) +} + +fn log_file_path() -> Result { + Ok(DaemonRuntimePaths::new("lspd")?.dir()?.join("lspd.log")) +} + fn pid_file_path() -> Result { DaemonRuntimePaths::new("lspd")?.pid_file() } @@ -561,9 +643,58 @@ fn cleanup_stale_files_on_start() { mod tests { use super::*; use serde_json::json; - use std::io::{self, BufRead, BufReader, Write}; + use std::io::{self, Write}; + #[cfg(unix)] + use std::io::{BufRead, BufReader}; use tempfile::tempdir; + #[cfg(not(unix))] + #[test] + fn tcp_connect_without_a_daemon_returns_promptly() { + let listener = std::net::TcpListener::bind(("127.0.0.1", 0)).unwrap(); + let port = listener.local_addr().unwrap().port(); + drop(listener); + + let started = Instant::now(); + let error = connect_tcp_client(port).expect_err("no daemon is listening"); + assert!(error + .to_string() + .contains("Failed to connect to lspd TCP endpoint")); + assert!( + started.elapsed() < Duration::from_secs(1), + "a missing local daemon must not wait for Windows TCP retries: {:?}", + started.elapsed() + ); + } + + #[cfg(not(unix))] + #[test] + fn tcp_connect_to_a_running_daemon_preserves_io_timeouts_and_responses() { + let listener = std::net::TcpListener::bind(("127.0.0.1", 0)).unwrap(); + let mut client = connect_tcp_client(listener.local_addr().unwrap().port()).unwrap(); + assert_eq!( + client.read_timeout().unwrap(), + Some(Duration::from_secs(10)) + ); + assert_eq!( + client.write_timeout().unwrap(), + Some(Duration::from_secs(10)) + ); + + let (mut server, _) = listener.accept().unwrap(); + server + .set_read_timeout(Some(Duration::from_secs(1))) + .unwrap(); + client.write_all(b"{\"type\":\"ping\"}\n").unwrap(); + let mut request = String::new(); + BufReader::new(&mut server).read_line(&mut request).unwrap(); + assert_eq!(request, "{\"type\":\"ping\"}\n"); + server.write_all(b"{\"ok\":true}\n").unwrap(); + let mut response = String::new(); + BufReader::new(client).read_line(&mut response).unwrap(); + assert_eq!(response, "{\"ok\":true}\n"); + } + fn env_lock() -> &'static std::sync::Mutex<()> { crate::test_env::env_lock() } @@ -602,6 +733,7 @@ mod tests { (dir, env) } + #[cfg(unix)] fn ensure_local_lsp_binary() { let binary = crate::lsp_manager::binary_path().expect("binary path should resolve"); if let Some(parent) = binary.parent() { @@ -1085,6 +1217,122 @@ mod tests { assert!(!socket.exists(), "socket file should be cleaned up"); } + fn exiting_child(code: i32) -> std::process::Child { + #[cfg(unix)] + let mut command = Command::new("sh"); + #[cfg(unix)] + command.args(["-c", &format!("exit {code}")]); + #[cfg(windows)] + let mut command = Command::new("cmd"); + #[cfg(windows)] + command.args(["/C", &format!("exit {code}")]); + command.spawn().expect("exiting child should spawn") + } + + fn sleeping_child() -> std::process::Child { + #[cfg(unix)] + let mut command = Command::new("sleep"); + #[cfg(unix)] + command.arg("30"); + #[cfg(windows)] + let mut command = Command::new("ping"); + #[cfg(windows)] + command.args(["-n", "30", "127.0.0.1"]); + command + .stdout(Stdio::null()) + .spawn() + .expect("sleeping child should spawn") + } + + #[test] + fn wait_until_ready_fails_immediately_when_startup_process_exits() { + let log = Path::new("/tmp/lspd-test.log"); + let mut child = exiting_child(3); + let started = Instant::now(); + let error = wait_until_ready(&mut child, Duration::from_secs(30), log, || false) + .expect_err("an exited startup process must fail"); + assert!(started.elapsed() < Duration::from_secs(10)); + let message = error.to_string(); + assert!(message.contains("exited during startup"), "{message}"); + assert!(message.contains(&log.display().to_string()), "{message}"); + } + + #[test] + fn wait_until_ready_reports_waited_time_and_log_on_timeout() { + let log = Path::new("/tmp/lspd-test.log"); + let mut child = sleeping_child(); + let error = wait_until_ready(&mut child, Duration::from_millis(300), log, || false) + .expect_err("a daemon that never answers must time out"); + let message = error.to_string(); + assert!(message.contains("within 300 ms"), "{message}"); + assert!(message.contains("waited"), "{message}"); + assert!(message.contains(&log.display().to_string()), "{message}"); + assert!( + child + .try_wait() + .expect("child should be inspectable") + .is_some(), + "a timed-out startup process must not be left running" + ); + } + + #[test] + fn wait_until_ready_keeps_polling_while_the_daemon_is_alive() { + let log = Path::new("/tmp/lspd-test.log"); + let mut child = sleeping_child(); + let mut probes = 0; + wait_until_ready(&mut child, Duration::from_secs(30), log, || { + probes += 1; + probes >= 5 + }) + .expect("a live daemon that answers late should be accepted"); + assert_eq!(probes, 5); + let _ = child.kill(); + let _ = child.wait(); + } + + #[test] + fn wait_until_ready_accepts_a_daemon_started_by_a_concurrent_caller() { + let log = Path::new("/tmp/lspd-test.log"); + let mut child = exiting_child(1); + let _ = child.wait(); + let mut probes = 0; + wait_until_ready(&mut child, Duration::from_secs(30), log, || { + probes += 1; + probes >= 2 + }) + .expect("an exited loser of a startup race should accept the running daemon"); + } + + #[test] + fn daemon_start_timeout_uses_env_override() { + let _guard = env_lock() + .lock() + .unwrap_or_else(|poison| poison.into_inner()); + std::env::remove_var("UNITY_CLI_LSPD_START_TIMEOUT_MS"); + assert_eq!(daemon_start_timeout(), Duration::from_secs(60)); + + let _env = EnvVarGuard::set("UNITY_CLI_LSPD_START_TIMEOUT_MS", "1500"); + assert_eq!(daemon_start_timeout(), Duration::from_millis(1500)); + + drop(_env); + let _invalid = EnvVarGuard::set("UNITY_CLI_LSPD_START_TIMEOUT_MS", "0"); + assert_eq!(daemon_start_timeout(), Duration::from_secs(60)); + } + + #[test] + fn daemon_log_lives_in_the_lspd_runtime_dir() { + let _guard = env_lock() + .lock() + .unwrap_or_else(|poison| poison.into_inner()); + let (_tools_root, _env) = prepare_tools_root(); + let log = log_file_path().expect("log path should resolve"); + let dir = DaemonRuntimePaths::new("lspd") + .and_then(|paths| paths.dir()) + .expect("runtime dir should resolve"); + assert_eq!(log, dir.join("lspd.log")); + } + #[test] fn daemon_idle_timeout_uses_env_override() { let _guard = env_lock() diff --git a/src/lsp/mod.rs b/src/lsp/mod.rs index 061f8243..3db28549 100644 --- a/src/lsp/mod.rs +++ b/src/lsp/mod.rs @@ -1,4 +1,4 @@ pub mod client; pub mod daemon; -pub use client::{execute_direct, maybe_execute}; +pub use client::{execute_direct, maybe_execute, route_search, SearchRoute}; diff --git a/src/mcp/configure.rs b/src/mcp/configure.rs index 2f5500eb..4ac663d5 100644 --- a/src/mcp/configure.rs +++ b/src/mcp/configure.rs @@ -31,7 +31,16 @@ fn destination(client: McpClient, local: bool) -> Result { let base = if local { std::env::current_dir()? } else { - dirs::home_dir().context("Home directory unavailable")? + // Windows' shell API ignores a process-local USERPROFILE override. + // Honor it so configuration follows the selected profile, including tests. + #[cfg(windows)] + let home = std::env::var_os("USERPROFILE") + .filter(|value| !value.is_empty()) + .map(PathBuf::from) + .or_else(dirs::home_dir); + #[cfg(not(windows))] + let home = dirs::home_dir(); + home.context("Home directory unavailable")? } .canonicalize()?; if !local { diff --git a/src/reference/embed.rs b/src/reference/embed.rs index ea406b7a..b92fc99d 100644 --- a/src/reference/embed.rs +++ b/src/reference/embed.rs @@ -60,7 +60,7 @@ impl FastEmbedder { std::env::set_var("ORT_DYLIB_PATH", dylib); } let model_id = format!("{model:?}"); - let options = fastembed::InitOptions::new(model); + let options = fastembed::TextInitOptions::new(model); let inner = fastembed::TextEmbedding::try_new(options) .map_err(|e| anyhow!("failed to initialize embedding model: {e}"))?; Ok(Self { @@ -402,6 +402,41 @@ mod tests { assert_eq!(loaded, index); } + #[test] + fn embedding_reads_fastembed6_bincode1_fixture() { + // Written by save_embedding_index with fastembed 6.1.0 and bincode 1.3.3 + // before the fastembed 7 migration. Do not regenerate with the new writer. + let bytes = + include_bytes!("../../tests/fixtures/reference-embedding/fastembed6-bincode1.bin"); + let tmp = TempDir::new().unwrap(); + let path = tmp.path().join(EMBEDDING_INDEX_REL_PATH); + fs::create_dir_all(path.parent().unwrap()).unwrap(); + fs::write(&path, bytes).unwrap(); + + let index = load_embedding_index(&path).unwrap(); + let model = fastembed::EmbeddingModel::BGESmallENV15; + let model_info = fastembed::TextEmbedding::get_model_info(&model).unwrap(); + assert_eq!(index.version, EMBEDDING_INDEX_VERSION); + assert_eq!(index.model_id, format!("{model:?}")); + assert_eq!(index.dim, model_info.dim); + assert_eq!(index.items.len(), 1); + let item = &index.items[0]; + assert_eq!(item.symbol, "UnityEngine.Animator"); + assert_eq!(item.kind, "class"); + assert_eq!(item.path, "Runtime/Export/Animation/Animator.bindings.cs"); + assert_eq!(item.line, 42); + let mut query = vec![0.0; model_info.dim]; + query[0] = 1.0; + assert_eq!(item.vector, query); + let hits = search(&index, &query, 1); + assert_eq!(hits[0].0, *item); + assert!((hits[0].1 - 1.0).abs() < f32::EPSILON); + + // Updating an existing index must also retain its on-disk format. + save_embedding_index(&path, &index).unwrap(); + assert_eq!(fs::read(&path).unwrap(), bytes); + } + #[test] fn search_ranks_by_cosine_similarity() { let index = EmbeddingIndex { diff --git a/src/reference/fetcher.rs b/src/reference/fetcher.rs index d25cd432..5cf6134e 100644 --- a/src/reference/fetcher.rs +++ b/src/reference/fetcher.rs @@ -4,6 +4,7 @@ use std::path::{Path, PathBuf}; use std::process::Command; use anyhow::{anyhow, Context, Result}; +use base64::Engine; pub const UNITY_CS_REFERENCE_URL: &str = "https://github.com/Unity-Technologies/UnityCsReference.git"; @@ -101,7 +102,7 @@ pub fn fetch_selected( dest, ); } - git_output(Command::new("git").arg("init").arg("--").arg(dest), "init")?; + git_output(git_command().arg("init").arg("--").arg(dest), "init")?; git_output( authenticated_git() .arg("-C") @@ -110,14 +111,14 @@ pub fn fetch_selected( "fetch", )?; git_output( - Command::new("git") + git_command() .arg("-C") .arg(dest) .args(["checkout", "--detach", "FETCH_HEAD"]), "checkout", )?; let actual = git_output( - Command::new("git") + git_command() .arg("-C") .arg(dest) .args(["rev-parse", "HEAD"]), @@ -132,13 +133,22 @@ pub fn fetch_selected( Ok(()) } -fn authenticated_git() -> Command { +fn git_command() -> Command { let mut command = Command::new("git"); + #[cfg(windows)] + command.args(["-c", "core.longpaths=true"]); command.env("GIT_TERMINAL_PROMPT", "0"); + command +} + +fn authenticated_git() -> Command { + let mut command = git_command(); if let Some(token) = github_token() { - command - .arg("-c") - .arg(format!("http.extraHeader=Authorization: token {token}")); + let credentials = + base64::engine::general_purpose::STANDARD.encode(format!("x-access-token:{token}")); + command.arg("-c").arg(format!( + "http.extraHeader=Authorization: Basic {credentials}" + )); } command } @@ -220,11 +230,7 @@ pub fn run_clone( } fn run_clone_via_git(url: &str, branch: &str, dest: &Path, depth: u32) -> Result<()> { - let mut cmd = Command::new("git"); - if let Some(token) = github_token() { - cmd.arg("-c") - .arg(format!("http.extraHeader=Authorization: token {token}")); - } + let mut cmd = authenticated_git(); cmd.arg("clone"); for arg in build_clone_args(url, branch, dest, depth) { cmd.arg(arg); @@ -278,7 +284,10 @@ pub fn extract_zip_to(archive_bytes: &[u8], dest: &Path) -> Result<()> { let mut file = archive .by_index(i) .with_context(|| format!("failed to read zip entry {i}"))?; - let raw_name = file.name().to_string(); + let raw_name = file + .name() + .with_context(|| format!("failed to read name of zip entry {i}"))? + .into_owned(); let stripped = match strip_prefix(&raw_name, &prefix) { Some(s) if !s.is_empty() => s.to_string(), _ => continue, @@ -311,7 +320,9 @@ fn detect_top_level_prefix(archive: &mut zip::ZipArchive>) -> Resu return Err(anyhow!("zip archive is empty")); } let first = archive.by_index(0).context("zip archive has no entries")?; - let name = first.name(); + let name = first + .name() + .context("failed to read name of first zip entry")?; if let Some(idx) = name.find('/') { Ok(name[..=idx].to_string()) } else { @@ -536,6 +547,43 @@ mod tests { assert!(!dest.exists()); } + #[cfg(windows)] + #[test] + fn fetch_selected_checks_out_long_windows_paths_without_global_configuration() { + let _guard = env_lock().lock().unwrap(); + let _count = EnvVarGuard::set("GIT_CONFIG_COUNT", "1"); + let _key = EnvVarGuard::set("GIT_CONFIG_KEY_0", "core.longpaths"); + let _value = EnvVarGuard::set("GIT_CONFIG_VALUE_0", "false"); + let (repo, _) = fixture_repo(); + let relative = PathBuf::from("Module".repeat(7)) + .join("GraphToolkit".repeat(4)) + .join("CommandStateObserver".repeat(3)) + .join("PersistedStateComponent.cs"); + let source = repo.path().join(&relative); + fs::create_dir_all(source.parent().unwrap()).unwrap(); + fs::write(&source, "long path fixture").unwrap(); + fixture_git(repo.path(), &["-c", "core.longpaths=true", "add", "."]); + fixture_git( + repo.path(), + &["-c", "core.longpaths=true", "commit", "-m", "long path"], + ); + let selection = super::super::version::RefSelection { + source_ref: "refs/heads/6000.0".into(), + commit_sha: fixture_git(repo.path(), &["rev-parse", "HEAD"]), + exact_match: false, + selection_reason: "long Windows path fixture".into(), + }; + let root = tempfile::tempdir().unwrap(); + let dest = root.path().join("reference-cache").join("nested".repeat(8)); + assert!(dest.join(&relative).as_os_str().len() > 260); + fetch_selected(repo.path().to_str().unwrap(), &selection, &dest, true).unwrap(); + assert_eq!( + fs::read_to_string(dest.join(relative)).unwrap(), + "long path fixture" + ); + assert_eq!(env::var("GIT_CONFIG_VALUE_0").unwrap(), "false"); + } + #[test] fn build_clone_args_emits_shallow_single_branch() { let dest = PathBuf::from("/tmp/unity-cs-reference/2023.2.20f1"); @@ -602,6 +650,49 @@ mod tests { assert_eq!(github_token().as_deref(), Some("ghp_test_value")); } + #[test] + fn public_refs_use_basic_authentication_for_git_http() { + use std::io::Write; + use std::net::TcpListener; + + let _guard = env_lock().lock().unwrap(); + let _token = EnvVarGuard::set("GITHUB_TOKEN", "fixture-token"); + let listener = TcpListener::bind("127.0.0.1:0").unwrap(); + let address = listener.local_addr().unwrap(); + let server = std::thread::spawn(move || { + let (mut stream, _) = listener.accept().unwrap(); + stream + .set_read_timeout(Some(std::time::Duration::from_secs(10))) + .unwrap(); + let mut request = Vec::new(); + while !request.ends_with(b"\r\n\r\n") { + let mut byte = [0]; + stream.read_exact(&mut byte).unwrap(); + request.push(byte[0]); + } + let reference = format!("{} refs/heads/6000.4\0multi_ack\n", "a".repeat(40)); + let body = format!( + "001e# service=git-upload-pack\n0000{:04x}{}0000", + reference.len() + 4, + reference + ); + write!(stream, "HTTP/1.1 200 OK\r\nContent-Type: application/x-git-upload-pack-advertisement\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{}", body.len(), body).unwrap(); + String::from_utf8(request).unwrap() + }); + let refs = list_public_refs(&format!("http://{address}/fixture.git")).unwrap(); + let request = server.join().unwrap(); + assert!( + request.lines().any(|line| line.eq_ignore_ascii_case( + "Authorization: Basic eC1hY2Nlc3MtdG9rZW46Zml4dHVyZS10b2tlbg==" + )), + "Git HTTP must authenticate with username and token credentials" + ); + assert!(refs + .iter() + .any(|reference| reference.name == "refs/heads/6000.4" + && reference.commit_sha == "a".repeat(40))); + } + #[test] fn ensure_git_available_succeeds_in_test_env() { ensure_git_available().expect("git is expected on dev/CI environment"); diff --git a/src/skills/distribution.rs b/src/skills/distribution.rs index d89448d4..8965f51e 100644 --- a/src/skills/distribution.rs +++ b/src/skills/distribution.rs @@ -66,7 +66,9 @@ fn scope_root(local: bool) -> Result { let root = if local { std::env::current_dir()? } else { - dirs::home_dir().context("cannot determine the user home directory")? + // Not `dirs::home_dir`: Windows clients resolve their home from + // %USERPROFILE%, which the shell API behind `dirs` ignores. + std::env::home_dir().context("cannot determine the user home directory")? }; ensure!( !fs::symlink_metadata(&root)?.file_type().is_symlink(), diff --git a/src/skills/rules.rs b/src/skills/rules.rs index 39063315..ddb2b686 100644 --- a/src/skills/rules.rs +++ b/src/skills/rules.rs @@ -576,6 +576,25 @@ pub fn rule_r21(skill: &Skill, ctx: &RuleContext<'_>) -> Vec { check_symlink(skill, &link, RuleId::R21AgentsSymlink) } +fn canonical_skill_link(link: &Path) -> std::io::Result { + #[cfg(windows)] + if link.is_file() && !link.is_symlink() { + // Git with core.symlinks=false checks out a symlink as a file containing + // its relative target. Validate that target against the canonical skill + // below, without requiring Developer Mode or changing checkout files. + let text = fs::read_to_string(link)?; + let target = Path::new(&text); + if !text.is_empty() && !text.chars().any(char::is_control) && target.is_relative() { + return link + .parent() + .unwrap_or(Path::new(".")) + .join(target) + .canonicalize(); + } + } + link.canonicalize() +} + fn check_symlink(skill: &Skill, link: &Path, rule: RuleId) -> Vec { if !link.exists() && !link.is_symlink() { return vec![Violation::new( @@ -586,7 +605,7 @@ fn check_symlink(skill: &Skill, link: &Path, rule: RuleId) -> Vec { format!("symlink `{}` is missing", link.display()), )]; } - let target = match link.canonicalize() { + let target = match canonical_skill_link(link) { Ok(p) => p, Err(_) => { return vec![Violation::new( diff --git a/src/skills/tests.rs b/src/skills/tests.rs index e1a3b968..a389ef78 100644 --- a/src/skills/tests.rs +++ b/src/skills/tests.rs @@ -11,7 +11,8 @@ use tempfile::TempDir; use super::loader::load_skills; use super::model::{allowed_tool_set, RuleId, Severity, Violation}; use super::report::{render, ReportFormat}; -use super::rules::{rule_r18, rule_r19, rule_r20, rule_r21, run_all, RuleContext}; +use super::rules::{rule_r18, rule_r19, run_all, RuleContext}; +use super::rules::{rule_r20, rule_r21}; use super::runner::{discover_root, lint, LintOptions, LintOutcome}; const VALID_DESC: &str = "Manage Unity prefab assets with unity-cli. Use when the user asks to create a prefab from a scene object or open a prefab in edit mode. Do not use for general scene object editing; use `unity-gameobject-edit` instead."; @@ -572,6 +573,51 @@ fn r20_and_r21_symlink_rules_cover_missing_and_valid_targets() { assert!(rule_r21(skill, &ctx).is_empty()); } +#[cfg(windows)] +#[test] +fn r20_and_r21_validate_windows_git_symlink_placeholders() { + let tmp = TempDir::new().unwrap(); + write_skill( + tmp.path(), + "unity-symlinked", + &valid_frontmatter("unity-symlinked"), + &valid_body(), + ); + write_skill( + tmp.path(), + "unity-gameobject-edit", + &sibling_frontmatter("unity-gameobject-edit", "unity-symlinked"), + &valid_body(), + ); + let skills = load_skills(tmp.path()).unwrap(); + let skill = skills.iter().find(|s| s.name == "unity-symlinked").unwrap(); + let ctx = RuleContext { + skills: &skills, + repo_root: tmp.path(), + }; + type Check = fn(&super::model::Skill, &RuleContext<'_>) -> Vec; + for (parent, rule) in [ + (".claude/skills", rule_r20 as Check), + (".agents/skills", rule_r21 as Check), + ] { + let parent = tmp.path().join(parent); + fs::create_dir_all(&parent).unwrap(); + let link = parent.join("unity-symlinked"); + assert!(!rule(skill, &ctx).is_empty(), "missing placeholder"); + fs::write(&link, "../../unity-symlinked").unwrap(); + assert!(rule(skill, &ctx).is_empty(), "valid Git placeholder"); + for invalid in [ + "../../unity-gameobject-edit", + "../../missing-skill", + "../../unity-symlinked\nadditional content", + "", + ] { + fs::write(&link, invalid).unwrap(); + assert!(!rule(skill, &ctx).is_empty(), "accepted {invalid:?}"); + } + } +} + #[test] fn report_and_runner_cover_text_json_discovery_and_error_paths() { let tmp = TempDir::new().unwrap(); diff --git a/src/tooling/local_tools.rs b/src/tooling/local_tools.rs index cb5e4293..54c869e6 100644 --- a/src/tooling/local_tools.rs +++ b/src/tooling/local_tools.rs @@ -70,12 +70,11 @@ pub fn maybe_execute_local_tool(tool_name: &str, params: &Value) -> Option Some(local_read(params)), "search" => Some(local_search(params)), "list_packages" => Some(local_list_packages()), - "get_symbols" => Some(local_get_symbols(params)), - "build_index" => Some(local_build_index(params)), + "get_symbols" | "build_index" | "find_symbol" | "find_refs" => { + Some(local_symbol_search(tool_name, params)) + } "update_index" => Some(local_update_index(params)), "get_index_status" => Some(local_get_index_status()), - "find_symbol" => Some(local_find_symbol(params)), - "find_refs" => Some(local_find_refs(params)), "rename_symbol" => Some(local_lsp_write("rename_symbol", params)), "replace_symbol_body" => Some(local_lsp_write("replace_symbol_body", params)), "insert_before_symbol" => Some(local_lsp_write("insert_before_symbol", params)), @@ -246,12 +245,25 @@ fn local_list_packages() -> Result { })) } -fn local_get_symbols(params: &Value) -> Result { +fn local_symbol_search(tool_name: &str, params: &Value) -> Result { + let index_search: fn(&Value) -> Result = match tool_name { + "get_symbols" => local_get_symbols, + "build_index" => local_build_index, + "find_symbol" => local_find_symbol, + _ => local_find_refs, + }; let root = project_root()?; - if let Some(result) = crate::lsp::maybe_execute("get_symbols", params, &root) { - return result; - } + let fallback = match crate::lsp::route_search(tool_name, params, &root) { + crate::lsp::SearchRoute::Lsp(result) => return result, + crate::lsp::SearchRoute::Index(fallback) => fallback, + }; + let mut value = index_search(params)?; + fallback.annotate(&mut value); + Ok(value) +} +fn local_get_symbols(params: &Value) -> Result { + let root = project_root()?; let path = params .get("path") .and_then(Value::as_str) @@ -276,10 +288,6 @@ fn local_get_symbols(params: &Value) -> Result { fn local_build_index(params: &Value) -> Result { let root = project_root()?; - if let Some(result) = crate::lsp::maybe_execute("build_index", params, &root) { - return result; - } - let exclude_package_cache = params .get("excludePackageCache") .and_then(Value::as_bool) @@ -466,10 +474,6 @@ fn local_update_index(params: &Value) -> Result { fn local_find_symbol(params: &Value) -> Result { let root = project_root()?; - if let Some(result) = crate::lsp::maybe_execute("find_symbol", params, &root) { - return result; - } - let name = params .get("name") .and_then(Value::as_str) @@ -571,10 +575,6 @@ fn local_find_refs(params: &Value) -> Result { .clamp(0, 20) as usize; let root = project_root()?; - if let Some(result) = crate::lsp::maybe_execute("find_refs", params, &root) { - return result; - } - let index = match load_index_if_exists(&root) { Ok(Some(index)) if index_is_ready(&index) => index, Ok(_) => { @@ -898,7 +898,10 @@ async fn poll_compile_state(config: &RuntimeConfig) -> Result { } fn requires_unityengine_using(inherits: Option<&str>) -> bool { - matches!(inherits.map(str::trim), Some("MonoBehaviour")) + matches!( + inherits.map(str::trim), + Some("MonoBehaviour" | "ScriptableObject") + ) } fn local_create_class(params: &Value) -> Result { @@ -943,6 +946,24 @@ fn local_create_class(params: &Value) -> Result { return Err(anyhow!("File already exists: {rel_path}")); } + let body = render_class_template(name, namespace, inherits); + + // Write through the same LSP path as `create_csharp_file` so the generated + // class is validated and the post-write pipeline sees an LSP result. + let mut result = local_lsp_write( + "create_csharp_file", + &json!({ + "relative": rel_path, + "text": body, + "overwrite": false + }), + )?; + result["path"] = json!(rel_path); + result["content"] = json!(body); + Ok(result) +} + +fn render_class_template(name: &str, namespace: Option<&str>, inherits: Option<&str>) -> String { let mut body = String::new(); if requires_unityengine_using(inherits) { body.push_str("using UnityEngine;\n\n"); @@ -963,17 +984,7 @@ fn local_create_class(params: &Value) -> Result { body.push_str("}\n"); } - if let Some(parent) = abs_path.parent() { - fs::create_dir_all(parent) - .with_context(|| format!("Failed to create directory: {}", parent.display()))?; - } - fs::write(&abs_path, &body).with_context(|| format!("Failed to write file: {rel_path}"))?; - - Ok(json!({ - "success": true, - "path": rel_path, - "content": body - })) + body } fn project_root() -> Result { @@ -1513,7 +1524,7 @@ mod tests { use super::{ build_snippet, collect_cs_files, extract_symbols_from_text, index_is_ready, index_not_ready_response, maybe_execute_local_tool, normalize_rel_or_abs_path, - normalize_rel_path, path_matches_scope, requires_unityengine_using, + normalize_rel_path, path_matches_scope, render_class_template, requires_unityengine_using, resolve_candidate_project_path, strip_csharp_comments, symbol_name_matches, IndexedFile, SymbolIndex, }; @@ -1526,6 +1537,28 @@ mod tests { LOCK.get_or_init(|| Mutex::new(())) } + struct ScopedEnv { + key: &'static str, + previous: Option, + } + + impl ScopedEnv { + fn set(key: &'static str, value: &str) -> Self { + let previous = std::env::var_os(key); + std::env::set_var(key, value); + Self { key, previous } + } + } + + impl Drop for ScopedEnv { + fn drop(&mut self) { + match &self.previous { + Some(value) => std::env::set_var(self.key, value), + None => std::env::remove_var(self.key), + } + } + } + fn write_file(path: &Path, content: &str) { if let Some(parent) = path.parent() { std::fs::create_dir_all(parent).expect("parent directory should be created"); @@ -1640,6 +1673,7 @@ mod tests { #[test] fn get_symbols_extracts_class_and_method() { let _guard = env_lock().lock().expect("lock should succeed"); + let _lsp_off = ScopedEnv::set("UNITY_CLI_LSP_MODE", "off"); let tmp = tempfile::tempdir().expect("temp dir should be created"); write_file( &tmp.path().join("Assets/Scripts/Player.cs"), @@ -1651,6 +1685,8 @@ mod tests { maybe_execute_local_tool("get_symbols", &json!({"path":"Assets/Scripts/Player.cs"})) .expect("tool should be handled") .expect("get_symbols should succeed"); + assert_eq!(value["backend"], "index"); + assert_eq!(value["fallbackReason"], "lsp_disabled"); let symbols = value["symbols"] .as_array() @@ -1668,9 +1704,47 @@ mod tests { std::env::remove_var("UNITY_PROJECT_ROOT"); } + #[test] + fn get_symbols_defaults_to_lsp_and_reports_index_fallback() { + let _guard = env_lock().lock().expect("lock should succeed"); + let tmp = tempfile::tempdir().expect("temp dir should be created"); + let tools = tempfile::tempdir().expect("tools dir should be created"); + write_file( + &tmp.path().join("Assets/Scripts/Player.cs"), + "public class Player { public void Jump() {} }\n", + ); + let _root = ScopedEnv::set( + "UNITY_PROJECT_ROOT", + tmp.path().to_str().expect("project root should be UTF-8"), + ); + let _tools = ScopedEnv::set( + "UNITY_CLI_TOOLS_ROOT", + tools.path().to_str().expect("tools root should be UTF-8"), + ); + let previous_mode = std::env::var_os("UNITY_CLI_LSP_MODE"); + std::env::remove_var("UNITY_CLI_LSP_MODE"); + + let value = + maybe_execute_local_tool("get_symbols", &json!({"path":"Assets/Scripts/Player.cs"})) + .expect("tool should be handled") + .expect("get_symbols should fall back to the index"); + + if let Some(mode) = previous_mode { + std::env::set_var("UNITY_CLI_LSP_MODE", mode); + } + assert_eq!(value["backend"], "index"); + assert_eq!(value["fallbackReason"], "lsp_not_installed"); + assert!(value["symbols"] + .as_array() + .expect("symbols should be an array") + .iter() + .any(|symbol| symbol["name"] == "Player")); + } + #[test] fn find_symbol_returns_index_not_ready_before_build() { let _guard = env_lock().lock().expect("lock should succeed"); + let _lsp_off = ScopedEnv::set("UNITY_CLI_LSP_MODE", "off"); let tmp = tempfile::tempdir().expect("temp dir should be created"); write_file( &tmp.path().join("Assets/Scripts/Player.cs"), @@ -1691,6 +1765,7 @@ mod tests { #[test] fn build_index_and_find_symbol_roundtrip() { let _guard = env_lock().lock().expect("lock should succeed"); + let _lsp_off = ScopedEnv::set("UNITY_CLI_LSP_MODE", "off"); let tmp = tempfile::tempdir().expect("temp dir should be created"); write_file( &tmp.path().join("Assets/Scripts/Player.cs"), @@ -1740,6 +1815,7 @@ mod tests { #[test] fn update_index_refreshes_symbol_names() { let _guard = env_lock().lock().expect("lock should succeed"); + let _lsp_off = ScopedEnv::set("UNITY_CLI_LSP_MODE", "off"); let tmp = tempfile::tempdir().expect("temp dir should be created"); let target = tmp.path().join("Assets/Scripts/Player.cs"); write_file(&target, "public class BeforeName {}\n"); @@ -1777,6 +1853,7 @@ mod tests { #[test] fn find_refs_supports_cursor_paging() { let _guard = env_lock().lock().expect("lock should succeed"); + let _lsp_off = ScopedEnv::set("UNITY_CLI_LSP_MODE", "off"); let tmp = tempfile::tempdir().expect("temp dir should be created"); write_file( &tmp.path().join("Assets/Scripts/Player.cs"), @@ -1829,56 +1906,19 @@ mod tests { } #[test] - fn create_class_generates_simple_class() { - let _guard = env_lock().lock().expect("lock should succeed"); - let tmp = tempfile::tempdir().expect("temp dir should be created"); - std::env::set_var("UNITY_PROJECT_ROOT", tmp.path()); - - let value = maybe_execute_local_tool( - "create_class", - &json!({"name":"EnemyAI","folder":"Assets/Scripts/AI"}), - ) - .expect("tool should be handled") - .expect("create_class should succeed"); - - assert_eq!(value["success"], true); - assert_eq!(value["path"], "Assets/Scripts/AI/EnemyAI.cs"); - let content = value["content"].as_str().expect("content should be string"); + fn create_class_template_generates_simple_class() { + let content = render_class_template("EnemyAI", None, None); assert!(!content.contains("using UnityEngine;")); assert!(content.contains("public class EnemyAI")); - - let file_content = std::fs::read_to_string(tmp.path().join("Assets/Scripts/AI/EnemyAI.cs")) - .expect("file should exist"); - assert_eq!(file_content, content); - - std::env::remove_var("UNITY_PROJECT_ROOT"); } #[test] - fn create_class_with_namespace_and_inherits() { - let _guard = env_lock().lock().expect("lock should succeed"); - let tmp = tempfile::tempdir().expect("temp dir should be created"); - std::env::set_var("UNITY_PROJECT_ROOT", tmp.path()); - - let value = maybe_execute_local_tool( - "create_class", - &json!({ - "name": "Player", - "namespace": "Game.Characters", - "inherits": "MonoBehaviour", - "folder": "Assets/Scripts" - }), - ) - .expect("tool should be handled") - .expect("create_class should succeed"); - - assert_eq!(value["success"], true); - let content = value["content"].as_str().expect("content should be string"); + fn create_class_template_with_namespace_and_inherits() { + let content = + render_class_template("Player", Some("Game.Characters"), Some("MonoBehaviour")); assert!(content.contains("namespace Game.Characters")); assert!(content.contains("using UnityEngine;")); assert!(content.contains("public class Player : MonoBehaviour")); - - std::env::remove_var("UNITY_PROJECT_ROOT"); } #[test] @@ -2089,12 +2129,26 @@ namespace Demo.Game } #[test] - fn requires_unityengine_using_only_for_monobehaviour() { + fn requires_unityengine_using_for_unqualified_unityengine_bases() { assert!(requires_unityengine_using(Some("MonoBehaviour"))); - assert!(!requires_unityengine_using(Some("ScriptableObject"))); + assert!(requires_unityengine_using(Some("ScriptableObject"))); + assert!(requires_unityengine_using(Some(" ScriptableObject "))); + assert!(!requires_unityengine_using(Some( + "UnityEngine.ScriptableObject" + ))); + assert!(!requires_unityengine_using(Some("BaseService"))); assert!(!requires_unityengine_using(None)); } + #[test] + fn create_class_template_scriptableobject_resolves_unityengine() { + let content = render_class_template("Sample", None, Some("ScriptableObject")); + assert_eq!( + content, + "using UnityEngine;\n\npublic class Sample : ScriptableObject\n{\n}\n" + ); + } + #[test] fn lsp_write_tools_require_lsp_mode() { let _guard = env_lock().lock().expect("lock should succeed"); @@ -2125,4 +2179,25 @@ namespace Demo.Game std::env::remove_var("UNITY_PROJECT_ROOT"); std::env::remove_var("UNITY_CLI_LSP_MODE"); } + + #[test] + fn create_class_requires_lsp_and_does_not_write_directly() { + let _guard = env_lock().lock().expect("lock should succeed"); + let tmp = tempfile::tempdir().expect("temp dir should be created"); + std::env::set_var("UNITY_PROJECT_ROOT", tmp.path()); + std::env::set_var("UNITY_CLI_LSP_MODE", "off"); + + let result = maybe_execute_local_tool( + "create_class", + &json!({"name":"EnemyAI","folder":"Assets/Scripts/AI"}), + ) + .expect("tool should be handled"); + + assert!(result.is_err(), "create_class should fail when LSP is off"); + assert!(result.unwrap_err().to_string().contains("requires LSP")); + assert!(!tmp.path().join("Assets/Scripts/AI/EnemyAI.cs").exists()); + + std::env::remove_var("UNITY_PROJECT_ROOT"); + std::env::remove_var("UNITY_CLI_LSP_MODE"); + } } diff --git a/tasks/lessons.md b/tasks/lessons.md index e66ceee5..73640d5f 100644 --- a/tasks/lessons.md +++ b/tasks/lessons.md @@ -10,6 +10,12 @@ ## Entries +### 2026-10-04 — #386 環境不足の解消を先に試す + +- Context: 実機検証を一部完了後、ユーザーから「全部終わらせて」と継続を指示された。 +- Rule: ツール未導入やリンク作成エラーを即座に最終 blocker にせず、管理者不要の代替、隔離インストール、既存認証、原資料の別保存先を試す。成功条件を緩めたり、未実施を PASS にしたりはしない。 +- Checkpoint: 実行可能な残作業を完了し、外部入力が必須な条件だけ具体的な場所・認証・結果とともに残す。Markdown を含む gwtd body は literal JSON ファイルから渡し、shell の command substitution を起こさない。 + ### 2026-02-27 - Context: Markdown Lint を `npm run lint:md` で実行した際、ローカルに `markdownlint` が存在しなかった。 @@ -78,3 +84,10 @@ - Context: gwt の Session 紐付け不整合で停止後、PM が workspace/build/verify の失敗を blocker にせず、直接実装・検証・push して「PR作成可」を報告するよう裁定した。 - Rule: 明示された復旧裁定がある場合は、失敗したライフサイクル操作を繰り返して停止せず、裁定の範囲で直接作業と検証を完了する。検証結果を偽装したり gwt の保護された状態ファイルを書き換えたりはしない。 - Checkpoint: 実装前の全 AC 監査、実機証跡、commit/push、Board の引き継ぎを確認する。PR 添付・レビューが残る AC は完了扱いにしない。 + +## 2026-10-04 — #386 Windows の待機条件と改行 + +- Context: 複合入力の実テストが失敗したが、表示には押下・解放カウンターが出ていた。原因は CRLF に一致しないテスト用正規表現で、読取値が0になったことだった。 +- Mistake: 実際に失敗する述語と読取値を確かめる前に、scrollやtouchの入力処理と保持時間を疑った。swipeのdurationを秒と解釈したが、実装はミリ秒だった。 +- Rule: 待機失敗は、対象の述語・表示文字列・解析値を先に照合する。Windowsの文字列解析はCRLF/LFを回帰テストに含め、パラメーターの単位はschemaと実装で確認してからfixtureを変更する。 +- Checkpoint: 1. どの待機が失敗したか記録 2. 元の表示と解析値を比較 3. 改行と単位を確認 4. 原因を再現するREDの後に最小修正 5. 元の実シナリオでGREENを確認 diff --git a/tests/auth_warning.rs b/tests/auth_warning.rs index c5d60f74..3b833f2b 100644 --- a/tests/auth_warning.rs +++ b/tests/auth_warning.rs @@ -10,7 +10,7 @@ fn legacy_opt_out_warns_on_stderr_only_for_exact_one() { ] { let mut command = Command::new(env!("CARGO_BIN_EXE_unity-cli")); command - .args(["tool", "list", "--output", "json"]) + .args(["--port", "1", "tool", "list", "--output", "json"]) .env("UNITY_CLI_NO_AUTO_UPDATE", "1") .env_remove("UNITY_CLI_ALLOW_UNAUTHENTICATED"); if let Some(value) = value { diff --git a/tests/csharp_edit_skill_fallback.rs b/tests/csharp_edit_skill_fallback.rs new file mode 100644 index 00000000..9935fa8f --- /dev/null +++ b/tests/csharp_edit_skill_fallback.rs @@ -0,0 +1,55 @@ +//! Issue #494: `unity-csharp-edit` must document what to do when the LSP +//! write tools fail, so the agent is never stuck without a write path. + +use std::fs; +use std::path::Path; + +fn skill_text() -> String { + let path = Path::new(env!("CARGO_MANIFEST_DIR")) + .join(".claude-plugin/plugins/unity-cli/skills/unity-csharp-edit/SKILL.md"); + fs::read_to_string(path).unwrap() +} + +fn fallback_section(text: &str) -> &str { + let start = text + .find("## LSP Write Failure Fallback") + .expect("SKILL.md must contain an `## LSP Write Failure Fallback` section"); + let rest = &text[start + 2..]; + let end = rest.find("\n## ").map_or(rest.len(), |i| i + 2); + &text[start..start + end] +} + +#[test] +fn fallback_section_covers_triggers_edit_refresh_compile_and_report() { + let text = skill_text(); + let section = fallback_section(&text); + for needle in [ + "fails to start", + "times out", + "unsupported", + "`Edit`", + "`Write`", + "refresh_assets", + "get_compilation_state", + "report", + ] { + assert!( + section.contains(needle), + "fallback section is missing `{needle}`:\n{section}" + ); + } +} + +#[test] +fn preferred_flow_points_to_the_fallback() { + let text = skill_text(); + let flow_start = text.find("## Preferred Flow").unwrap(); + let flow = &text[flow_start + ..text + .find("## LSP Write Failure Fallback") + .unwrap_or(text.len())]; + assert!( + flow.contains("LSP Write Failure Fallback"), + "Preferred Flow must point to the fallback section" + ); +} diff --git a/tests/csharp_post_write.rs b/tests/csharp_post_write.rs index 4b3434b1..16a6aa95 100644 --- a/tests/csharp_post_write.rs +++ b/tests/csharp_post_write.rs @@ -241,3 +241,38 @@ fn post_write_tools_use_explicit_endpoint_and_include_compile_results() { assert_eq!(requests[2]["params"]["includeMessages"], true); } } + +#[test] +fn create_class_writes_through_lsp_and_keeps_output_shape() { + let fixture = Fixture::new(); + let response = fixture.call( + "create_class", + &json!({ + "name": "EnemyAI", + "namespace": "Game.AI", + "inherits": "MonoBehaviour", + "folder": "Assets/Scripts/AI" + }), + 1, + ); + assert_eq!(response["success"], true, "{response}"); + assert_eq!(response["backend"], "lsp", "{response}"); + assert_eq!(response["applied"], true); + assert_eq!(response["path"], "Assets/Scripts/AI/EnemyAI.cs"); + assert_eq!( + response["changedFiles"], + json!(["Assets/Scripts/AI/EnemyAI.cs"]) + ); + let content = response["content"].as_str().unwrap(); + assert!(content.contains("using UnityEngine;")); + assert!(content.contains("namespace Game.AI")); + assert!(content.contains("public class EnemyAI : MonoBehaviour")); + let written = fs::read_to_string( + fixture + .root + .path() + .join("project/Assets/Scripts/AI/EnemyAI.cs"), + ) + .unwrap(); + assert_eq!(written, content); +} diff --git a/tests/fixtures/lsp-write-baseline.json b/tests/fixtures/lsp-write-baseline.json new file mode 100644 index 00000000..0aca568d --- /dev/null +++ b/tests/fixtures/lsp-write-baseline.json @@ -0,0 +1,124 @@ +{ + "create_class_monobehaviour": { + "failures": [], + "published": { + "versions": ["0.18.1"], + "failures": ["bom_added"] + } + }, + "create_class_scriptableobject": { + "failures": [], + "published": { + "versions": ["0.18.1"], + "failures": ["bom_added"] + } + }, + "create_class_plain": { + "failures": [], + "published": { + "versions": ["0.18.1"], + "failures": ["bom_added"] + } + }, + "create_plain": { + "failures": [], + "published": { + "versions": ["0.18.1"], + "failures": ["bom_added"] + } + }, + "create_monobehaviour": { + "failures": [], + "published": { + "versions": ["0.18.1"], + "failures": ["bom_added"] + } + }, + "create_scriptableobject": { + "failures": [], + "published": { + "versions": ["0.18.1"], + "failures": ["bom_added"] + } + }, + "replace_body": { + "failures": [], + "published": { + "versions": ["0.18.1"], + "failures": ["bom_added"] + } + }, + "write_file": { + "failures": [], + "published": { + "versions": ["0.18.1"], + "failures": ["bom_added"] + } + }, + "insert_before": { + "failures": [], + "published": { + "versions": ["0.18.1"], + "failures": ["bom_added"] + } + }, + "insert_after": { + "failures": [], + "published": { + "versions": ["0.18.1"], + "failures": ["bom_added"] + } + }, + "remove_member": { + "failures": [], + "published": { + "versions": ["0.18.1"], + "failures": ["bom_added"] + } + }, + "namespace_partial_generic_attributes": { + "failures": [], + "published": { + "versions": ["0.18.1"], + "failures": ["bom_added"] + } + }, + "replace_preserve_comment": { + "failures": [], + "published": { + "versions": ["0.18.1"], + "failures": ["bom_added", "text_changed"], + "text_hashes": { + "Assets/Sample.cs": "215a30f2eaeefdd4d211dd6ada4e5aab889d1a2617366f1343808a9c1540ab68" + } + } + }, + "rename_multifile": { + "failures": [], + "published": { + "versions": ["0.18.1"], + "failures": ["bom_added"] + } + }, + "unicode_no_bom_crlf": { + "failures": [], + "published": { + "versions": ["0.18.1"], + "failures": ["bom_added"] + } + }, + "large_3500_lines": { + "failures": [], + "published": { + "versions": ["0.18.1"], + "failures": ["bom_added"] + } + }, + "repair_syntax_error": { + "failures": [], + "published": { + "versions": ["0.18.1"], + "failures": ["bom_added"] + } + } +} diff --git a/tests/fixtures/reference-embedding/fastembed6-bincode1.bin b/tests/fixtures/reference-embedding/fastembed6-bincode1.bin new file mode 100644 index 00000000..072f12db Binary files /dev/null and b/tests/fixtures/reference-embedding/fastembed6-bincode1.bin differ diff --git a/tests/fixtures/skill-routing/benchmark.jsonl b/tests/fixtures/skill-routing/benchmark.jsonl index 2a7ebc49..b85db987 100644 --- a/tests/fixtures/skill-routing/benchmark.jsonl +++ b/tests/fixtures/skill-routing/benchmark.jsonl @@ -69,7 +69,7 @@ {"id": "SR-069", "expected_skills": ["unity-csharp-edit"], "prompt": "Jumpの後に新規メソッドを追加したい", "expected_tool": "insert_after_symbol", "expected_payload_keys": ["relative", "namePath", "text"], "difficulty": "hard"} {"id": "SR-070", "expected_skills": ["unity-csharp-edit"], "prompt": "不要メンバーを参照チェック付きで削除したい", "expected_tool": "remove_symbol", "expected_payload_keys": ["relative", "namePath", "failOnReferences"], "difficulty": "hard"} {"id": "SR-071", "expected_skills": ["unity-csharp-edit"], "prompt": "newTextの文法だけ先に検証したい", "expected_tool": "validate_text_edits", "expected_payload_keys": ["relative", "newText"], "difficulty": "medium"} -{"id": "SR-072", "expected_skills": ["unity-csharp-edit"], "prompt": "EnemyAIクラスをAssets/Scripts/AIに作りたい", "expected_tool": "create_class", "expected_payload_keys": ["name", "folder"], "difficulty": "easy"} +{"id": "SR-072", "expected_skills": ["unity-csharp-edit"], "prompt": "EnemyAIクラスをAssets/Scripts/AIに作りたい", "expected_tool": "create_csharp_file", "expected_payload_keys": ["relative", "text"], "difficulty": "easy"} {"id": "SR-073", "expected_skills": ["unity-playmode-testing"], "prompt": "Play modeを開始したい", "expected_tool": "play_game", "expected_payload_keys": [], "difficulty": "easy"} {"id": "SR-074", "expected_skills": ["unity-playmode-testing"], "prompt": "Play modeを停止したい", "expected_tool": "stop_game", "expected_payload_keys": [], "difficulty": "easy"} {"id": "SR-075", "expected_skills": ["unity-playmode-testing"], "prompt": "キーボードでspaceを押したい", "expected_tool": "input_keyboard", "expected_payload_keys": ["action", "key"], "difficulty": "easy"} @@ -218,3 +218,8 @@ {"id":"AUD380-06","prompt":"Only create an empty scene called AudioTest in Assets/Scenes/Generated/E2E/. No audio assets or playback setup.","expected_skills":["unity-scene-create"],"expected_tool":"create_scene","expected_payload_keys":["sceneName","path"],"difficulty":"hard"} {"id":"AUD380-07","prompt":"Only enter Play Mode in the existing audio scene. Do not configure its AudioClip or Mixer.","expected_skills":["unity-playmode-testing"],"expected_tool":"play_game","expected_payload_keys":[],"difficulty":"hard"} {"id":"AUD380-08","prompt":"Only read the latest 20 Unity console messages to investigate audio errors; do not change any assets or source settings.","expected_skills":["unity-editor-tools"],"expected_tool":"read_console","expected_payload_keys":["count"],"difficulty":"hard"} +{"id": "CS488-01", "expected_skills": ["unity-csharp-edit"], "prompt": "Assets/Scripts/AIにEnemyAIのMonoBehaviourを作りたい", "expected_tool": "create_csharp_file", "expected_payload_keys": ["relative", "text"], "difficulty": "easy"} +{"id": "CS488-02", "expected_skills": ["unity-csharp-edit"], "prompt": "Create an EnemyAI MonoBehaviour in Assets/Scripts/AI.", "expected_tool": "create_csharp_file", "expected_payload_keys": ["relative", "text"], "difficulty": "easy"} +{"id": "CS488-03", "expected_skills": ["unity-csharp-edit"], "prompt": "Write a C# script that rotates its GameObject every frame and save it as Assets/Scripts/Rotator.cs.", "expected_tool": "create_csharp_file", "expected_payload_keys": ["relative", "text"], "difficulty": "medium"} +{"id": "CS488-04", "expected_skills": ["unity-csharp-edit"], "prompt": "PlayerController.csのコンパイルエラーを直したい", "expected_tool": "apply_csharp_edits", "expected_payload_keys": ["files"], "difficulty": "medium"} +{"id": "CS488-05", "expected_skills": ["unity-csharp-edit"], "prompt": "Fix the compile error in Assets/Scripts/PlayerController.cs.", "expected_tool": "apply_csharp_edits", "expected_payload_keys": ["files"], "difficulty": "medium"} diff --git a/tests/install_script.rs b/tests/install_script.rs index 21b10bcf..371cbebd 100644 --- a/tests/install_script.rs +++ b/tests/install_script.rs @@ -164,3 +164,126 @@ fn install_sh_falls_back_to_manifest_checksum_without_sha256sums() { assert!(stderr.contains("checksum mismatch"), "stderr: {stderr}"); assert!(installed_binaries(&home).is_empty()); } + +/// Serves the release under `release_dir` over HTTP on 127.0.0.1, answering +/// the first `failures` requests for `flaky_path` with 503 (#514). Returns the +/// base URL and the per-path request counter. +fn serve_release_with_transient_failures( + release_dir: PathBuf, + flaky_path: &'static str, + failures: usize, +) -> (String, std::sync::Arc>>) { + use std::io::{BufRead, BufReader, Write}; + use std::net::TcpListener; + use std::sync::{Arc, Mutex}; + + let listener = TcpListener::bind("127.0.0.1:0").expect("bind"); + let base_url = format!("http://{}", listener.local_addr().expect("addr")); + let requests = Arc::new(Mutex::new(Vec::new())); + let seen = Arc::clone(&requests); + std::thread::spawn(move || { + for stream in listener.incoming() { + let Ok(mut stream) = stream else { break }; + let mut request_line = String::new(); + let mut reader = BufReader::new(stream.try_clone().expect("clone")); + if reader.read_line(&mut request_line).is_err() { + continue; + } + loop { + let mut header = String::new(); + match reader.read_line(&mut header) { + Ok(0) | Err(_) => break, + Ok(_) if header == "\r\n" || header == "\n" => break, + Ok(_) => {} + } + } + let path = request_line + .split_whitespace() + .nth(1) + .unwrap_or("/") + .to_string(); + let attempt = { + let mut seen = seen.lock().expect("lock"); + seen.push(path.clone()); + seen.iter().filter(|p| **p == path).count() + }; + let (status, body) = if path == flaky_path && attempt <= failures { + ("503 Service Unavailable", b"busy".to_vec()) + } else { + match fs::read(release_dir.join(path.trim_start_matches('/'))) { + Ok(bytes) => ("200 OK", bytes), + Err(_) => ("404 Not Found", b"missing".to_vec()), + } + }; + let header = format!( + "HTTP/1.1 {status}\r\nContent-Length: {}\r\nConnection: close\r\n\r\n", + body.len() + ); + let _ = stream.write_all(header.as_bytes()); + let _ = stream.write_all(&body); + } + }); + (base_url, requests) +} + +#[test] +fn install_sh_retries_transient_sha256sums_errors_and_keeps_checksum_gate() { + let root = TempDir::new().expect("tempdir"); + let (_, tag_dir) = write_release(root.path(), b"genuine binary"); + write_sha256sums(&tag_dir, b"genuine binary"); + let sums_path = "/v9.9.9/SHA256SUMS"; + let (base_url, requests) = + serve_release_with_transient_failures(root.path().join("release"), sums_path, 1); + + let home = root.path().join("home"); + let output = run_install(&home, &base_url); + + assert!( + output.status.success(), + "install should survive one 503: {}", + String::from_utf8_lossy(&output.stderr) + ); + let sums_requests = requests + .lock() + .expect("lock") + .iter() + .filter(|p| *p == sums_path) + .count(); + assert_eq!(sums_requests, 2, "SHA256SUMS should be retried once"); + assert_eq!(installed_binaries(&home).len(), 1); + + // The retry must not weaken the gate: a tampered binary still aborts. + for rid in UNIX_RIDS { + fs::write(tag_dir.join(format!("unity-cli-{rid}")), b"tampered binary").expect("asset"); + } + let (base_url, _) = + serve_release_with_transient_failures(root.path().join("release"), sums_path, 1); + let tampered_home = root.path().join("tampered-home"); + let output = run_install(&tampered_home, &base_url); + assert!(!output.status.success(), "tampered install must fail"); + let stderr = String::from_utf8_lossy(&output.stderr); + assert!(stderr.contains("checksum mismatch"), "stderr: {stderr}"); + assert!(installed_binaries(&tampered_home).is_empty()); +} + +#[test] +fn install_sh_reports_unreachable_release_instead_of_missing_checksums() { + let root = TempDir::new().expect("tempdir"); + // Bind then drop a listener so the port refuses connections. + let port = std::net::TcpListener::bind("127.0.0.1:0") + .expect("bind") + .local_addr() + .expect("addr") + .port(); + let home = root.path().join("home"); + + let output = run_install(&home, &format!("http://127.0.0.1:{port}")); + + assert!(!output.status.success()); + let stderr = String::from_utf8_lossy(&output.stderr); + assert!( + stderr.contains("failed to download SHA256SUMS") && !stderr.contains("or manifest"), + "a network failure must not be reported as a missing SHA256SUMS: {stderr}" + ); + assert!(installed_binaries(&home).is_empty()); +} diff --git a/tests/mcp.rs b/tests/mcp.rs index 25979403..380e314d 100644 --- a/tests/mcp.rs +++ b/tests/mcp.rs @@ -123,7 +123,10 @@ fn stdio_catalog_and_failure_contract_without_editor() { .iter() .map(|t| t["name"].as_str().unwrap().to_string()) .collect(); - let list = cli().args(["tool", "list"]).output().unwrap(); + let list = cli() + .args(["--port", "1", "tool", "list"]) + .output() + .unwrap(); let mut expected: Vec<_> = String::from_utf8(list.stdout) .unwrap() .lines() @@ -186,6 +189,11 @@ fn configure_all_clients_preserves_other_servers_and_dry_run() { "{client}: {}", String::from_utf8_lossy(&preview.stderr) ); + assert!( + String::from_utf8_lossy(&preview.stdout) + .contains(dir.path().canonicalize().unwrap().to_str().unwrap()), + "{client}: preview must target the isolated configuration directory" + ); assert!(String::from_utf8_lossy(&preview.stdout).contains("+")); assert_eq!(std::fs::read_to_string(&path).unwrap(), before); let write = run(false); @@ -195,6 +203,15 @@ fn configure_all_clients_preserves_other_servers_and_dry_run() { String::from_utf8_lossy(&write.stderr) ); let after = std::fs::read_to_string(&path).unwrap(); + if !toml { + let configured: Value = serde_json::from_str(&after).unwrap(); + let key = if client == "vscode" { + "servers" + } else { + "mcpServers" + }; + assert_eq!(configured[key]["unity-cli"]["command"], "unity-cli"); + } assert!(after.contains("keep")); assert!(after.contains("unity-cli")); assert!( diff --git a/tests/scripts/install-from-source-ps1-test.ps1 b/tests/scripts/install-from-source-ps1-test.ps1 new file mode 100644 index 00000000..c1cb24c7 --- /dev/null +++ b/tests/scripts/install-from-source-ps1-test.ps1 @@ -0,0 +1,110 @@ +# Installs a locally built unity-cli.exe through scripts/install-from-source.ps1 +# (-SkipBuild) into a temporary UNITY_CLI_TOOLS_ROOT and checks the managed +# layout: fresh install, reinstall, a locked exe, a missing build, and the +# auto-update warning. +param( + [Parameter(Mandatory = $true)][string]$Binary +) +$ErrorActionPreference = 'Stop' + +function Assert([bool]$Condition, [string]$Message) { + if (-not $Condition) { throw "FAIL: $Message" } +} + +$repoRoot = Resolve-Path (Join-Path $PSScriptRoot '..\..') +$installer = Join-Path $repoRoot 'scripts\install-from-source.ps1' +$built = (Resolve-Path $Binary).Path +$shell = (Get-Process -Id $PID).Path + +$builtVersion = (& $built --version | Out-String).Trim() +Assert ($builtVersion -match '^unity-cli (\S+)$') "unexpected version output: $builtVersion" +$version = $Matches[1] +$builtHash = (Get-FileHash -Algorithm SHA256 -Path $built).Hash + +$work = Join-Path ([System.IO.Path]::GetTempPath()) ("unity-cli-install-from-source-" + [guid]::NewGuid()) +$targetDir = Join-Path $work 'target' +$emptyTarget = Join-Path $work 'empty-target' +$toolsRoot = Join-Path $work 'tools' +New-Item -ItemType Directory -Force -Path (Join-Path $targetDir 'debug'), $emptyTarget | Out-Null +Copy-Item -Path $built -Destination (Join-Path $targetDir 'debug\unity-cli.exe') + +$destDir = Join-Path $toolsRoot 'unity-cli\win-x64' +$installed = Join-Path $destDir 'unity-cli.exe' +$saved = @{} +foreach ($name in 'CARGO_TARGET_DIR', 'UNITY_CLI_TOOLS_ROOT', 'UNITY_CLI_SKIP_PATH_UPDATE', 'UNITY_CLI_NO_AUTO_UPDATE') { + $saved[$name] = [Environment]::GetEnvironmentVariable($name, 'Process') +} +$originalUserPath = [Environment]::GetEnvironmentVariable('Path', 'User') +$userOptOut = [Environment]::GetEnvironmentVariable('UNITY_CLI_NO_AUTO_UPDATE', 'User') + +# Runs the installer in a child shell so its `exit 1` can't end this test. +# Continue: Windows PowerShell turns the child's stderr into terminating errors. +function Invoke-Installer { + $ErrorActionPreference = 'Continue' + $output = & $shell -NoProfile -ExecutionPolicy Bypass -File $installer -DebugBuild -SkipBuild -NoSkills 2>&1 | Out-String + return [pscustomobject]@{ Code = $LASTEXITCODE; Output = $output } +} + +try { + $env:CARGO_TARGET_DIR = $targetDir + $env:UNITY_CLI_TOOLS_ROOT = $toolsRoot + $env:UNITY_CLI_SKIP_PATH_UPDATE = '1' + $env:UNITY_CLI_NO_AUTO_UPDATE = '1' + + # Fresh install + $run = Invoke-Installer + Assert ($run.Code -eq 0) "fresh install exited with $($run.Code): $($run.Output)" + Assert (Test-Path $installed) 'binary must be installed into the managed layout' + Assert ((Get-FileHash -Algorithm SHA256 -Path $installed).Hash -eq $builtHash) 'installed binary must match the build' + Assert ((Get-Content -Raw (Join-Path $destDir 'VERSION')).Trim() -eq $version) 'VERSION must hold the build version' + Assert ((& $installed --version | Out-String).Trim() -eq $builtVersion) 'installed binary must run' + Assert ([Environment]::GetEnvironmentVariable('Path', 'User') -eq $originalUserPath) 'UNITY_CLI_SKIP_PATH_UPDATE=1 must leave the user PATH alone' + Assert ($run.Output -notmatch 'Self-update will replace') 'no auto-update warning when UNITY_CLI_NO_AUTO_UPDATE=1' + + # Reinstall replaces an existing binary + Set-Content -Path $installed -Value 'stale' -Encoding ascii + $run = Invoke-Installer + Assert ($run.Code -eq 0) "reinstall exited with $($run.Code): $($run.Output)" + Assert ((Get-FileHash -Algorithm SHA256 -Path $installed).Hash -eq $builtHash) 'reinstall must replace the binary' + + # A held-open exe (like one a running daemon was started from) is moved aside + $handle = [System.IO.File]::Open($installed, 'Open', 'Read', [System.IO.FileShare]'Read, Delete') + try { + $run = Invoke-Installer + } finally { + $handle.Dispose() + } + Assert ($run.Code -eq 0) "install over a locked exe exited with $($run.Code): $($run.Output)" + Assert (@(Get-ChildItem -Path $destDir -Filter 'unity-cli.exe.old-*').Count -eq 1) 'the locked exe must be moved aside' + Assert ((Get-FileHash -Algorithm SHA256 -Path $installed).Hash -eq $builtHash) 'the build must replace the locked exe' + $run = Invoke-Installer + Assert ($run.Code -eq 0) "install after a locked exe exited with $($run.Code)" + Assert (@(Get-ChildItem -Path $destDir -Filter 'unity-cli.exe.old-*').Count -eq 0) 'the next run must remove the moved-aside exe' + + # A missing build fails and leaves the install alone + $env:CARGO_TARGET_DIR = $emptyTarget + $run = Invoke-Installer + Assert ($run.Code -ne 0) 'a missing build must fail' + Assert ($run.Output -match 'no build at') "missing build must say so: $($run.Output)" + Assert ((Get-FileHash -Algorithm SHA256 -Path $installed).Hash -eq $builtHash) 'a failed run must leave the install alone' + $env:CARGO_TARGET_DIR = $targetDir + + # Auto-update warning when the opt-out is not set (skipped when the + # machine sets it at user scope, which the installer also honours) + if ($userOptOut -ne '1') { + Remove-Item Env:UNITY_CLI_NO_AUTO_UPDATE + $run = Invoke-Installer + Assert ($run.Code -eq 0) "install without the opt-out exited with $($run.Code)" + Assert ($run.Output -match 'Self-update will replace') 'must warn when UNITY_CLI_NO_AUTO_UPDATE is unset' + } else { + Write-Host 'Skipping the warning check: UNITY_CLI_NO_AUTO_UPDATE=1 is set at user scope.' + } + + Write-Host "install-from-source.ps1 test passed ($builtVersion)" +} finally { + foreach ($name in $saved.Keys) { + [Environment]::SetEnvironmentVariable($name, $saved[$name], 'Process') + } + [Environment]::SetEnvironmentVariable('Path', $originalUserPath, 'User') + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue $work +} diff --git a/tests/scripts/install-from-source-sh-test.sh b/tests/scripts/install-from-source-sh-test.sh new file mode 100755 index 00000000..ff445dd1 --- /dev/null +++ b/tests/scripts/install-from-source-sh-test.sh @@ -0,0 +1,69 @@ +#!/bin/sh +# Installs a locally built unity-cli through scripts/install-from-source.sh +# (--skip-build) into a temporary HOME and UNITY_CLI_TOOLS_ROOT and checks the +# managed layout: fresh install, symlink, reinstall, a missing build, and the +# auto-update warning. +# Usage: tests/scripts/install-from-source-sh-test.sh target/debug/unity-cli +set -eu + +BUILT=${1:?usage: $0 } +REPO_ROOT=$(cd "$(dirname "$0")/../.." && pwd) +INSTALLER="${REPO_ROOT}/scripts/install-from-source.sh" + +fail() { echo "FAIL: $*" >&2; exit 1; } + +case "$(uname -s)/$(uname -m)" in + Darwin/arm64|Darwin/aarch64) RID=osx-arm64 ;; + Darwin/x86_64) RID=osx-x64 ;; + Linux/aarch64|Linux/arm64) RID=linux-arm64 ;; + Linux/x86_64) RID=linux-x64 ;; + *) fail "unsupported platform $(uname -s)/$(uname -m)" ;; +esac + +BUILT_VERSION=$("$BUILT" --version) +VERSION=$(echo "$BUILT_VERSION" | awk '{print $2}') +hash_of() { cksum < "$1"; } +BUILT_HASH=$(hash_of "$BUILT") + +WORK=$(mktemp -d) +trap 'rm -rf "$WORK"' EXIT +mkdir -p "$WORK/home" "$WORK/target/debug" "$WORK/empty-target" +cp "$BUILT" "$WORK/target/debug/unity-cli" + +export HOME="$WORK/home" +export UNITY_CLI_TOOLS_ROOT="$WORK/tools" +export CARGO_TARGET_DIR="$WORK/target" +export UNITY_CLI_NO_AUTO_UPDATE=1 +DEST="$WORK/tools/unity-cli/$RID" +INSTALLED="$DEST/unity-cli" +OUT="$WORK/out" + +run() { sh "$INSTALLER" --debug --skip-build --no-skills >"$OUT" 2>&1; } + +# Fresh install +run || fail "fresh install failed: $(cat "$OUT")" +[ -x "$INSTALLED" ] || fail "binary must be installed into the managed layout" +[ "$(hash_of "$INSTALLED")" = "$BUILT_HASH" ] || fail "installed binary must match the build" +[ "$(cat "$DEST/VERSION")" = "$VERSION" ] || fail "VERSION must hold the build version" +[ "$("$INSTALLED" --version)" = "$BUILT_VERSION" ] || fail "installed binary must run" +[ "$(readlink "$HOME/.local/bin/unity-cli")" = "$INSTALLED" ] || fail "~/.local/bin/unity-cli must point at the managed binary" +! grep -q "self-update will replace" "$OUT" || fail "no auto-update warning when UNITY_CLI_NO_AUTO_UPDATE=1" + +# Reinstall replaces an existing binary +printf 'stale\n' > "$INSTALLED" +run || fail "reinstall failed: $(cat "$OUT")" +[ "$(hash_of "$INSTALLED")" = "$BUILT_HASH" ] || fail "reinstall must replace the binary" + +# A missing build fails and leaves the install alone +CARGO_TARGET_DIR="$WORK/empty-target" +if run; then fail "a missing build must fail"; fi +grep -q "no build at" "$OUT" || fail "missing build must say so: $(cat "$OUT")" +[ "$(hash_of "$INSTALLED")" = "$BUILT_HASH" ] || fail "a failed run must leave the install alone" +CARGO_TARGET_DIR="$WORK/target" + +# Auto-update warning when the opt-out is not set +unset UNITY_CLI_NO_AUTO_UPDATE +run || fail "install without the opt-out failed: $(cat "$OUT")" +grep -q "self-update will replace" "$OUT" || fail "must warn when UNITY_CLI_NO_AUTO_UPDATE is unset" + +echo "install-from-source.sh test passed (${BUILT_VERSION})" diff --git a/tests/scripts/install-ps1-published-test.ps1 b/tests/scripts/install-ps1-published-test.ps1 new file mode 100644 index 00000000..0f049a2f --- /dev/null +++ b/tests/scripts/install-ps1-published-test.ps1 @@ -0,0 +1,35 @@ +# Installs the latest published release the way the README tells users to +# (`irm .../main/scripts/install.ps1 | iex`) and checks that the installed +# unity-cli reports that release's version (#465). Needs network access and a +# published release, so it runs from published-install.yml, not on every PR. +$ErrorActionPreference = 'Stop' + +function Assert([bool]$Condition, [string]$Message) { + if (-not $Condition) { throw "FAIL: $Message" } +} + +$repo = 'akiojin/unity-cli' +$installerUrl = "https://raw.githubusercontent.com/$repo/main/scripts/install.ps1" + +$headers = @{ 'User-Agent' = 'unity-cli-published-install-test' } +if ($env:GH_TOKEN) { $headers['Authorization'] = "Bearer $env:GH_TOKEN" } +$tag = (Invoke-RestMethod -Uri "https://api.github.com/repos/$repo/releases/latest" -Headers $headers).tag_name +Assert ($tag -match '^v\d+\.\d+\.\d+$') "unexpected latest release tag: $tag" +$expected = "unity-cli $($tag.TrimStart('v'))" + +# The installer must pick the release and the install location by itself. +foreach ($name in 'UNITY_CLI_VERSION', 'UNITY_CLI_RELEASE_BASE_URL', 'UNITY_CLI_TOOLS_ROOT', 'UNITY_CLI_SKIP_PATH_UPDATE') { + Remove-Item "Env:$name" -ErrorAction SilentlyContinue +} +# A child scope keeps the installer's own variables out of this script. +& { Invoke-RestMethod -Uri $installerUrl | Invoke-Expression } + +$installed = Join-Path $HOME '.unity\tools\unity-cli\win-x64\unity-cli.exe' +Assert (Test-Path $installed) "binary must be installed at $installed" +$resolved = (Get-Command unity-cli -CommandType Application | Select-Object -First 1).Source +Assert ($resolved -eq $installed) "unity-cli must resolve to the installed binary, got: $resolved" +$actual = (unity-cli --version | Out-String).Trim() +Assert ($LASTEXITCODE -eq 0) "unity-cli --version exited with $LASTEXITCODE" +Assert ($actual -eq $expected) "installed binary reported '$actual', expected '$expected' (release $tag)" + +Write-Host "published install test passed ($actual from release $tag)" diff --git a/tests/scripts/install-ps1-test.ps1 b/tests/scripts/install-ps1-test.ps1 index 80393296..9dda12cb 100644 --- a/tests/scripts/install-ps1-test.ps1 +++ b/tests/scripts/install-ps1-test.ps1 @@ -23,10 +23,30 @@ $tampered = [System.Text.Encoding]::ASCII.GetBytes('tampered binary') Set-Content -Path (Join-Path $releaseDir 'SHA256SUMS') -Encoding ascii ` -Value "$(Get-Sha256Hex $genuine) unity-cli-win-x64" -$port = Get-Random -Minimum 20000 -Maximum 40000 +# Let the OS pick a free port instead of guessing one. +$probe = [System.Net.Sockets.TcpListener]::new([System.Net.IPAddress]::Loopback, 0) +$probe.Start() +$port = $probe.LocalEndpoint.Port +$probe.Stop() $server = Start-Process -PassThru -NoNewWindow python ` -ArgumentList @('-m', 'http.server', "$port", '--bind', '127.0.0.1', '--directory', (Join-Path $work 'release')) -Start-Sleep -Seconds 2 + +# Wait until the server answers instead of sleeping a fixed time: on a busy +# Windows runner python can take longer than 2 s to bind, and the installer +# then reports the refused connection as a download failure (#514). +function Wait-ReleaseServer { + $deadline = [DateTime]::UtcNow.AddSeconds(60) + while ([DateTime]::UtcNow -lt $deadline) { + if ($server.HasExited) { throw "FAIL: local release server exited with code $($server.ExitCode)" } + try { + Invoke-WebRequest -Uri "http://127.0.0.1:$port/$tag/SHA256SUMS" -UseBasicParsing | Out-Null + return + } catch { + Start-Sleep -Milliseconds 200 + } + } + throw 'FAIL: local release server did not start within 60 s' +} function Invoke-Installer([string]$ToolsRoot) { $env:UNITY_CLI_VERSION = $tag @@ -42,6 +62,8 @@ function Invoke-Installer([string]$ToolsRoot) { } try { + Wait-ReleaseServer + # Tampered binary: install must abort and leave nothing behind. [System.IO.File]::WriteAllBytes((Join-Path $releaseDir 'unity-cli-win-x64'), $tampered) $tamperedRoot = Join-Path $work 'tools-tampered' diff --git a/tests/scripts/install-ps1-text-test.ps1 b/tests/scripts/install-ps1-text-test.ps1 index 07a3959c..45df7dd8 100644 --- a/tests/scripts/install-ps1-text-test.ps1 +++ b/tests/scripts/install-ps1-text-test.ps1 @@ -1,28 +1,89 @@ -# Check the installer's HTTP text boundary on any PowerShell platform. +# Check the installer's HTTP text and retry boundary on any PowerShell platform. $ErrorActionPreference = 'Stop' $installer = Join-Path $PSScriptRoot '../../scripts/install.ps1' $ast = [System.Management.Automation.Language.Parser]::ParseFile($installer, [ref]$null, [ref]$null) -foreach ($name in @('Get-Text', 'Get-OptionalText')) { +foreach ($name in @('Fail', 'Get-HttpStatus', 'Test-TransientError', 'Invoke-WithRetry', 'Get-Text', 'Get-OptionalText')) { $definition = $ast.Find({ param($node) $node -is [System.Management.Automation.Language.FunctionDefinitionAst] -and $node.Name -eq $name }, $false) + if (-not $definition) { throw "install.ps1 must define $name" } . ([scriptblock]::Create($definition.Extent.Text)) } +# Keep the retry backoff out of the test run. +function Start-Sleep { param($Seconds, $Milliseconds) $script:sleeps++ } + # Invoke-WebRequest returns byte[] for application/octet-stream (SHA256SUMS). +# $script:failures holds the exceptions to throw before the response succeeds. function Invoke-WebRequest { - param($Uri, [switch]$UseBasicParsing, $Headers) + param($Uri, [switch]$UseBasicParsing, $Headers, $OutFile) + $script:calls++ + if ($script:failures.Count -gt 0) { + $next = $script:failures[0] + $script:failures = @($script:failures | Select-Object -Skip 1) + throw $next + } [pscustomobject]@{ Content = $script:responseContent } } +function Reset-Http([object[]]$Failures) { + $script:calls = 0 + $script:sleeps = 0 + $script:failures = @($Failures) +} + +# Same shape as WebException (PS 5.1) and HttpResponseException (PS 7): the +# HTTP status is on Exception.Response.StatusCode. +class FakeHttpException : System.Exception { + [object]$Response + FakeHttpException([string]$Message, [int]$Status) : base($Message) { + $this.Response = [pscustomobject]@{ StatusCode = $Status } + } +} + +function New-HttpError([int]$Status) { + [FakeHttpException]::new("Response status code does not indicate success: $Status", $Status) +} + +function New-NetworkError { + [System.Net.Http.HttpRequestException]::new('No connection could be made because the target machine actively refused it.') +} + +$url = 'https://example.invalid/SHA256SUMS' $expected = ('a' * 64) + " unity-cli-win-x64`r`n" + ('b' * 64) + " unity-cli-win-x64.exe`r`n" foreach ($binary in @($true, $false)) { + Reset-Http @() $script:responseContent = if ($binary) { [System.Text.Encoding]::UTF8.GetBytes($expected) } else { $expected } # Preserve the byte[] type in the mocked HTTP response. if ($binary) { $script:responseContent = [byte[]]$script:responseContent } - $actual = Get-OptionalText 'https://example.invalid/SHA256SUMS' + $actual = Get-OptionalText $url if ($actual -isnot [string] -or $actual -cne $expected) { throw "HTTP content must return unchanged text (binary=$binary, actual type=$($actual.GetType().FullName))" } } + +# Transient failures (no response, 5xx, 429) are retried with backoff (#514). +$script:responseContent = [byte[]][System.Text.Encoding]::UTF8.GetBytes($expected) +Reset-Http @((New-NetworkError), (New-HttpError 503), (New-HttpError 429)) +$actual = Get-Text $url +if ($actual -cne $expected) { throw "transient errors must be retried until the download succeeds (actual: $actual)" } +if ($script:calls -ne 4) { throw "expected 4 HTTP attempts, got $($script:calls)" } +if ($script:sleeps -ne 3) { throw "expected a backoff before each retry, got $($script:sleeps)" } + +# A missing optional file (404) is not retried and selects the fallback. +Reset-Http @((New-HttpError 404)) +$actual = Get-OptionalText $url +if ($null -ne $actual) { throw "404 must return null so the installer can fall back to the manifest" } +if ($script:calls -ne 1) { throw "404 must not be retried, got $($script:calls) attempts" } + +# A persistent network failure is reported with its cause, never as a missing file. +Reset-Http @(1..10 | ForEach-Object { New-NetworkError }) +$message = $null +try { Get-OptionalText $url | Out-Null } catch { $message = $_.Exception.Message } +if (-not $message) { throw 'a persistent network failure must abort, not fall back to the manifest' } +if ($message -notlike "unity-cli install failed: failed to download ${url}:*refused*") { + throw "unexpected network failure message: $message" +} +if ($script:calls -ne 4) { throw "expected 4 HTTP attempts before giving up, got $($script:calls)" } + Write-Host 'install.ps1 HTTP text tests passed' diff --git a/tests/scripts/platform-checks.py b/tests/scripts/platform-checks.py index 86ce1f49..48ddb214 100644 --- a/tests/scripts/platform-checks.py +++ b/tests/scripts/platform-checks.py @@ -9,7 +9,8 @@ setup `setup --dry-run` prints the Bridge install plan and writes nothing (#363) screenshot a silent fake Editor makes `capture_screenshot` time out and fall - back to an OS screenshot that must be a real PNG (#369) + back to an OS screenshot that must be a real PNG (#369). Linux + checks the X11 tools, or grim when WAYLAND_DISPLAY is set (#465) Unix isolates the home directory through $HOME. Windows resolves the profile through the shell API instead of %USERPROFILE%, so the lockfiles go into the @@ -38,10 +39,11 @@ CHECKS = ("discovery", "setup", "screenshot") IS_WINDOWS = os.name == "nt" PNG_SIGNATURE = b"\x89PNG\r\n\x1a\n" -# X11 tools the CLI tries on Linux, in order (src/tooling/os_capture.rs). -# The Wayland tools (grim, gnome-screenshot, spectacle) need a compositor that -# CI runners do not have, so they stay with the real-machine checks in #386. +# Tools the CLI tries on Linux, in order (src/tooling/os_capture.rs). grim runs +# under a headless wlroots compositor (#465); gnome-screenshot and spectacle +# need a full desktop session, so they stay with the real-machine checks in #386. X11_TOOLS = ("import", "scrot", "maim") +WAYLAND_TOOLS = ("grim",) results: list[tuple[str, bool, str]] = [] @@ -251,7 +253,7 @@ def check_screenshot(runner: Runner) -> None: tools = {"powershell": None} elif sys.platform.startswith("linux"): tools = {} - for tool in X11_TOOLS: + for tool in WAYLAND_TOOLS if os.environ.get("WAYLAND_DISPLAY") else X11_TOOLS: resolved = shutil.which(tool) if resolved is None: check(f"screenshot: {tool} is installed", False, "not on PATH") diff --git a/tests/scripts/test_auto_merge_workflow.py b/tests/scripts/test_auto_merge_workflow.py new file mode 100644 index 00000000..bdedebf4 --- /dev/null +++ b/tests/scripts/test_auto_merge_workflow.py @@ -0,0 +1,190 @@ +"""Checks .github/workflows/auto-merge.yml (Issue #486). + +The step scripts run against a fake `gh` on PATH, so the permission check, +pinned head SHA and synchronize revocation are exercised without GitHub. +""" + +import os +import stat +import subprocess +import tempfile +import unittest +from pathlib import Path + +import yaml + +ROOT = Path(__file__).resolve().parents[2] +WORKFLOW = ROOT / '.github' / 'workflows' / 'auto-merge.yml' +README = ROOT / '.github' / 'workflows' / 'README.md' + +LABEL = 'reviewed-safe' +SHA = '0123456789abcdef0123456789abcdef01234567' + +# Fake gh: logs every call, answers from FAKE_* environment variables. +FAKE_GH = r'''#!/bin/sh +printf '%s\n' "$*" >> "$FAKE_GH_LOG" +case "$*" in + *collaborators/*/permission*) printf '%s\n' "$FAKE_PERMISSION"; exit 0 ;; + "pr view"*headRefOid*) printf '%s\n' "$FAKE_HEAD_SHA"; exit 0 ;; + "pr view"*mergeable*) printf 'MERGEABLE\n'; exit 0 ;; + "pr merge"*--disable-auto*) exit "${FAKE_DISABLE_EXIT:-0}" ;; + "pr merge"*) exit 0 ;; + "pr edit"*) exit 0 ;; +esac +exit 0 +''' + + +def load_workflow(): + with WORKFLOW.open(encoding='utf-8') as f: + return yaml.safe_load(f) + + +def triggers(workflow): + # PyYAML (YAML 1.1) reads the bare `on` key as True. + return workflow.get('on', workflow.get(True)) + + +def run_job(job, env): + """Run every `run` step of a job with a fake gh; return the gh call log.""" + with tempfile.TemporaryDirectory() as tmp: + tmp_path = Path(tmp) + gh = tmp_path / 'gh' + gh.write_text(FAKE_GH, encoding='utf-8') + gh.chmod(gh.stat().st_mode | stat.S_IEXEC) + log = tmp_path / 'gh.log' + log.touch() + full_env = { + 'PATH': f'{tmp_path}{os.pathsep}{os.environ["PATH"]}', + 'FAKE_GH_LOG': str(log), + 'GH_TOKEN': 'token', + 'REPO': 'akiojin/unity-cli', + 'PR_NUMBER': '481', + 'LABEL': LABEL, + 'HEAD_SHA': SHA, + 'FAKE_HEAD_SHA': SHA, + 'FAKE_PERMISSION': 'write', + 'ACTOR': 'reviewer', + } + full_env.update(env) + code = 0 + for step in job['steps']: + if 'run' not in step: + continue + result = subprocess.run(['bash', '-c', step['run']], env=full_env, + capture_output=True, text=True) + if result.returncode != 0: + code = result.returncode + break + return code, log.read_text(encoding='utf-8').splitlines() + + +class AutoMergeWorkflowStructure(unittest.TestCase): + def setUp(self): + self.workflow = load_workflow() + self.jobs = self.workflow['jobs'] + + def test_triggers_on_labeled_and_synchronize(self): + on = triggers(self.workflow) + types = on['pull_request_target']['types'] + self.assertIn('labeled', types) + self.assertIn('synchronize', types) + + def test_minimal_permissions(self): + self.assertEqual(self.workflow['permissions'], + {'contents': 'write', 'pull-requests': 'write'}) + + def test_never_checks_out_fork_code(self): + for name, job in self.jobs.items(): + for step in job['steps']: + self.assertNotIn('uses', step, f'{name} must only call gh') + + def test_owner_job_keeps_behavior_and_ignores_label_events(self): + cond = self.jobs['auto-merge']['if'] + self.assertIn("github.event.pull_request.head.repo.full_name == github.repository", cond) + self.assertIn("'akiojin'", cond) + self.assertIn("'dependabot[bot]'", cond) + self.assertIn("github.event.action != 'labeled'", cond) + + def test_external_job_conditions(self): + cond = self.jobs['external-reviewed']['if'] + self.assertIn("github.event.action == 'labeled'", cond) + self.assertIn(f"github.event.label.name == '{LABEL}'", cond) + self.assertIn("github.event.pull_request.head.repo.full_name != github.repository", cond) + self.assertIn('github.event.pull_request.draft == false', cond) + self.assertIn("github.event.pull_request.base.ref == 'develop'", cond) + + def test_revoke_job_conditions(self): + cond = self.jobs['external-revoke']['if'] + self.assertIn("github.event.action == 'synchronize'", cond) + self.assertIn("github.event.pull_request.head.repo.full_name != github.repository", cond) + self.assertIn(f"'{LABEL}'", cond) + + def test_external_job_pins_labeled_head_sha(self): + env = self.jobs['external-reviewed']['steps'][0]['env'] + self.assertEqual(env['HEAD_SHA'], '${{ github.event.pull_request.head.sha }}') + self.assertEqual(env['ACTOR'], '${{ github.event.sender.login }}') + + +class ExternalReviewedJob(unittest.TestCase): + def setUp(self): + self.job = load_workflow()['jobs']['external-reviewed'] + + def test_write_permission_enables_pinned_merge(self): + for permission in ('admin', 'maintain', 'write'): + code, calls = run_job(self.job, {'FAKE_PERMISSION': permission}) + self.assertEqual(code, 0, calls) + merges = [c for c in calls if c.startswith('pr merge')] + self.assertEqual(len(merges), 1, calls) + self.assertIn('--auto', merges[0]) + self.assertIn('--merge', merges[0]) + self.assertIn(f'--match-head-commit {SHA}', merges[0]) + + def test_owner_is_trusted_without_permission_lookup(self): + code, calls = run_job(self.job, {'ACTOR': 'akiojin', 'FAKE_PERMISSION': 'none'}) + self.assertEqual(code, 0, calls) + self.assertTrue(any(c.startswith('pr merge') for c in calls), calls) + + def test_insufficient_permission_does_not_merge(self): + for permission in ('read', 'triage', 'none'): + code, calls = run_job(self.job, {'FAKE_PERMISSION': permission}) + self.assertNotEqual(code, 0, calls) + self.assertFalse(any(c.startswith('pr merge') for c in calls), calls) + self.assertTrue(any(c.startswith('pr edit') and '--remove-label' in c + for c in calls), calls) + + def test_head_moved_since_label_does_not_merge(self): + code, calls = run_job(self.job, {'FAKE_HEAD_SHA': 'f' * 40}) + self.assertNotEqual(code, 0, calls) + self.assertFalse(any(c.startswith('pr merge') for c in calls), calls) + self.assertTrue(any('--remove-label' in c for c in calls), calls) + + +class ExternalRevokeJob(unittest.TestCase): + def setUp(self): + self.job = load_workflow()['jobs']['external-revoke'] + + def test_new_push_removes_label_and_disables_auto_merge(self): + code, calls = run_job(self.job, {}) + self.assertEqual(code, 0, calls) + self.assertTrue(any(c.startswith('pr edit') and f'--remove-label {LABEL}' in c + for c in calls), calls) + self.assertTrue(any(c.startswith('pr merge') and '--disable-auto' in c + for c in calls), calls) + + def test_disable_without_auto_merge_still_succeeds(self): + code, calls = run_job(self.job, {'FAKE_DISABLE_EXIT': '1'}) + self.assertEqual(code, 0, calls) + self.assertTrue(any('--remove-label' in c for c in calls), calls) + + +class WorkflowReadme(unittest.TestCase): + def test_documents_external_review_flow(self): + text = README.read_text(encoding='utf-8') + self.assertIn(LABEL, text) + self.assertIn('--match-head-commit', text) + self.assertIn('synchronize', text) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/scripts/test_lsp_write_reliability.py b/tests/scripts/test_lsp_write_reliability.py new file mode 100644 index 00000000..a2e41f8d --- /dev/null +++ b/tests/scripts/test_lsp_write_reliability.py @@ -0,0 +1,193 @@ +"""Protect the reliability measurement from false PASS and hidden regressions.""" +import importlib.util +import tempfile +from pathlib import Path +import unittest +from unittest import mock + +ROOT = Path(__file__).resolve().parents[2] +SPEC = importlib.util.spec_from_file_location("reliability", ROOT / "scripts/lsp-write-reliability.py") +reliability = importlib.util.module_from_spec(SPEC) +SPEC.loader.exec_module(reliability) + + +class ReliabilityTests(unittest.TestCase): + def test_scenarios_cover_every_write_tool_and_large_unicode_inputs(self): + cases = reliability.scenarios() + self.assertEqual({case["tool"] for case in cases}, { + "create_csharp_file", "write_csharp_file", "apply_csharp_edits", + "replace_symbol_body", "insert_before_symbol", "insert_after_symbol", + "remove_symbol", "rename_symbol", "validate_text_edits", "create_class", + }) + self.assertGreater(max(data.count(b"\n") for case in cases for data in case["before"].values()), 3000) + self.assertTrue(any(data.startswith(b"\xef\xbb\xbf") and b"\r\n" in data + for case in cases for data in case["before"].values())) + + def test_byte_comparison_distinguishes_bom_newlines_text_and_extra_files(self): + expected = {"Assets/A.cs": "// 日本語\r\nclass A {}\r\n".encode()} + actual = {"Assets/A.cs": b"\xef\xbb\xbf" + expected["Assets/A.cs"].replace(b"\r\n", b"\n"), + "Assets/Unexpected.cs": b"class Extra {}"} + signatures, differences = reliability.compare_files(expected, actual) + self.assertEqual(set(signatures), {"bom_added", "newlines_changed", "file_set_changed"}) + self.assertEqual(len(differences), 2) + self.assertIn("--- direct/", differences[0]["diff"]) + self.assertEqual(reliability.compare_files(expected, expected), ([], [])) + self.assertIn("text_changed", reliability.compare_files(expected, {"Assets/A.cs": b"class Wrong {}"})[0]) + + def test_server_alias_tolerates_case_insensitive_filesystems(self): + import os, tempfile + with tempfile.TemporaryDirectory() as temp: + source = Path(temp) / "Server" + source.write_bytes(b"binary") + alias = Path(temp) / "server" + if not alias.exists(): + # Case-sensitive filesystems: a hard link stands in for macOS / Windows aliasing. + os.link(source, alias) + reliability.install_server_alias(source, alias) + self.assertEqual(alias.read_bytes(), b"binary") + with tempfile.TemporaryDirectory() as temp: + source = Path(temp) / "Server" + source.write_bytes(b"binary") + target = Path(temp) / "sub" / "server" + target.parent.mkdir() + reliability.install_server_alias(source, target) + self.assertEqual(target.read_bytes(), b"binary") + + def test_false_success_or_fallback_is_not_a_successful_lsp_edit(self): + self.assertEqual(reliability.response_failures(0, {"success": True, "data": {"success": False, "backend": "lsp"}}), ["tool_rejected"]) + self.assertEqual(reliability.response_failures(0, {"success": True, "data": {"success": True, "backend": "unity"}}), ["wrong_backend"]) + self.assertEqual(reliability.response_failures(0, {"success": True, "data": {"success": True, "backend": "lsp"}}), []) + + def test_nearest_rank_percentiles_and_rate_include_failed_attempts(self): + rows = [{"elapsed_ms": n, "direct_ms": 1, "failures": [] if n < 100 else ["timeout"]} + for n in range(1, 101)] + summary = reliability.summarize(rows) + self.assertEqual(summary["success_rate"], 0.99) + self.assertEqual(summary["p50_ms"], 50) + self.assertEqual(summary["p95_ms"], 95) + self.assertEqual(summary["failure_types"], {"timeout": 1}) + self.assertEqual(reliability.summarize([])["success_rate"], 0) + + def test_regression_baseline_allows_only_exact_documented_signatures(self): + baseline = {"replace": ["bom_added"]} + self.assertEqual(reliability.regressions([{"scenario": "replace", "failures": ["bom_added"]}], baseline), []) + self.assertTrue(reliability.regressions([{"scenario": "replace", "failures": ["bom_added", "text_changed"]}], baseline)) + self.assertTrue(reliability.regressions([{"scenario": "new", "failures": ["bom_added"]}], baseline)) + self.assertEqual(reliability.regressions([{"scenario": "replace", "failures": []}], baseline), []) + + def test_missing_os_or_condition_never_produces_enforcement_recommendation(self): + report = {"os": "Windows", "rows": [{"scenario": "create_plain", "condition": "warm_indexed", "failures": [], "elapsed_ms": 1, "direct_ms": 1}]} + text = reliability.markdown([report]) + self.assertIn("Windows", text) + self.assertIn("INSUFFICIENT", text) + self.assertIn("macOS", text) + self.assertIn("Linux", text) + + def test_known_text_defect_cannot_mask_a_different_destructive_edit(self): + baseline = {"replace": {"failures": ["text_changed"], "text_hashes": {"Assets/A.cs": "known"}}} + row = {"scenario": "replace", "failures": ["text_changed"], "differences": [ + {"path": "Assets/A.cs", "direct_text_sha256": "expected", "lsp_text_sha256": "known"}]} + self.assertEqual(reliability.regressions([row], baseline), []) + row["differences"][0]["lsp_text_sha256"] = "different-loss" + self.assertTrue(reliability.regressions([row], baseline)) + row["failures"] = [] + self.assertEqual(reliability.regressions([row], baseline), []) + + def test_published_lsp_exception_never_relaxes_the_checkout_gate(self): + # A fix merged into the checkout LSP stays enforced even before it is released. + baseline = {"replace": {"failures": ["bom_added"], "published": { + "versions": ["0.18.1"], + "failures": ["bom_added", "text_changed"], "text_hashes": {"Assets/A.cs": "known"}}}} + known = [{"path": "Assets/A.cs", "direct_text_sha256": "expected", "lsp_text_sha256": "known"}] + published = {"scenario": "replace", "lsp_version": "0.18.1", "failures": ["bom_added", "text_changed"], "differences": known} + self.assertEqual(reliability.regressions([published], baseline), []) + checkout = dict(published, lsp_version="checkout") + self.assertTrue(reliability.regressions([checkout], baseline)) + missing = dict(published) + del missing["lsp_version"] + self.assertTrue(reliability.regressions([missing], baseline)) + self.assertTrue(reliability.regressions([dict(published, lsp_version="0.18.2")], baseline)) + other = dict(published, differences=[dict(known[0], lsp_text_sha256="different-loss")]) + self.assertTrue(reliability.regressions([other], baseline)) + self.assertEqual(reliability.regressions([dict(checkout, failures=["bom_added"], differences=[])], baseline), []) + + def test_ci_retains_failures_and_runs_real_lsp_on_all_three_platforms(self): + workflow = (ROOT / ".github/workflows/lsp-write-reliability.yml").read_text(encoding="utf-8") + self.assertIn("os: [windows-latest, macos-latest, ubuntu-latest]", workflow) + self.assertIn("dotnet publish lsp/Server.csproj", workflow) + self.assertIn("--baseline tests/fixtures/lsp-write-baseline.json", workflow) + self.assertIn("if: always()", workflow) + self.assertNotIn("continue-on-error", workflow) + self.assertNotIn("--record-only", workflow) + required = (ROOT / ".github/workflows/test.yml").read_text(encoding="utf-8") + lsp_job = required.split(" lsp-test:\n", 1)[1].split(" rust-coverage:\n", 1)[0] + self.assertIn("name: LSP Tests (required)", lsp_job) + self.assertIn("needs: lsp-write-reliability", lsp_job) + self.assertIn("if: always()", lsp_job) + self.assertIn('run: test "$RELIABILITY_RESULT" = success', lsp_job) + + def test_one_corrupt_edit_prevents_enforcement_even_at_99_percent(self): + reports = [] + for system in reliability.OS_NAMES: + rows = [{"scenario": case["id"], "condition": condition, + "failures": [], "elapsed_ms": 1, "direct_ms": 1} + for condition in reliability.CONDITIONS for case in reliability.scenarios() for _ in range(100)] + reports.append({"os": system, "rows": rows, "finished_at": "2026-10-13T00:00:00Z"}) + self.assertIn("ELIGIBLE", reliability.markdown(reports)) + reports[0]["rows"][0]["failures"] = ["bom_added"] + self.assertIn("DO NOT ENFORCE", reliability.markdown(reports)) + reports[0].pop("finished_at") + self.assertIn("INSUFFICIENT", reliability.markdown(reports)) + + def test_known_bom_defect_cannot_mask_an_unrelated_file_write(self): + row = {"scenario": "rename_multifile", "failures": ["bom_added"], "differences": [{"path": "Assets/Other.cs"}]} + self.assertTrue(reliability.regressions([row], {"rename_multifile": ["bom_added"]})) + row["differences"] = [{"path": "Assets/Sample.cs"}] + self.assertEqual(reliability.regressions([row], {"rename_multifile": ["bom_added"]}), []) + + def test_trial_cleanup_retries_windows_dll_locks_and_rejects_escape(self): + with mock.patch.object(reliability.shutil, "rmtree", side_effect=[PermissionError("DLL still unloading"), None]) as remove: + with mock.patch.object(reliability.time, "sleep"): + reliability.cleanup_trial(ROOT / ".cache/trial", ROOT / ".cache") + self.assertEqual(remove.call_count, 2) + with mock.patch.object(reliability.shutil, "rmtree") as remove: + with self.assertRaises(RuntimeError): + reliability.cleanup_trial(ROOT, ROOT / ".cache") + remove.assert_not_called() + + def test_trial_cleanup_retries_when_lspd_writes_during_removal(self): + busy = OSError(reliability.errno.ENOTEMPTY, "Directory not empty", "tools") + with mock.patch.object(reliability.shutil, "rmtree", side_effect=[busy, busy, None]) as remove: + with mock.patch.object(reliability.time, "sleep"): + reliability.cleanup_trial(ROOT / ".cache/trial", ROOT / ".cache") + self.assertEqual(remove.call_count, 3) + broken = OSError(reliability.errno.EIO, "I/O error") + with mock.patch.object(reliability.shutil, "rmtree", side_effect=broken) as remove: + with self.assertRaises(OSError): + reliability.cleanup_trial(ROOT / ".cache/trial", ROOT / ".cache") + self.assertEqual(remove.call_count, 1) + + def test_close_waits_for_the_auto_started_lspd_to_remove_its_pid_file(self): + with tempfile.TemporaryDirectory() as directory: + trial = reliability.Trial.__new__(reliability.Trial) + trial.tools, trial.process, trial.log, trial.env = Path(directory), None, None, {} + trial.cli, trial.project = Path("unity-cli"), Path(directory) + pid_file = trial.tools / "run" / "lspd" / "lspd.pid" + pid_file.parent.mkdir(parents=True) + pid_file.write_text("4242") + polls = [] + + def sleep(_): + polls.append(1) + if len(polls) == 3: + pid_file.unlink() # The daemon finishes its shutdown writes. + + with mock.patch.object(reliability.subprocess, "run") as run, mock.patch.object(reliability.time, "sleep", side_effect=sleep): + trial.close() + self.assertIn("stop", run.call_args.args[0]) + self.assertEqual(len(polls), 3) + self.assertFalse(pid_file.exists()) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/scripts/test_process_liveness.py b/tests/scripts/test_process_liveness.py new file mode 100644 index 00000000..8d702b3d --- /dev/null +++ b/tests/scripts/test_process_liveness.py @@ -0,0 +1,81 @@ +"""Editor authentication and lifecycle probes must only observe processes.""" +import importlib.util +import json +import os +from pathlib import Path +import subprocess +import sys +import tempfile +import unittest + +ROOT = Path(__file__).resolve().parents[2] +sys.path.insert(0, str(ROOT / "scripts")) +import bridge_auth + +spec = importlib.util.spec_from_file_location( + "editor_lifecycle", ROOT / "scripts/e2e-editor-lifecycle.py") +lifecycle = importlib.util.module_from_spec(spec) +spec.loader.exec_module(lifecycle) + + +class ProcessLivenessTests(unittest.TestCase): + def child(self, code): + process = subprocess.Popen( + [sys.executable, "-c", code], stdout=subprocess.PIPE, + stderr=subprocess.PIPE, text=True) + + def cleanup(): + if process.poll() is None: + process.terminate() + process.communicate(timeout=10) + + self.addCleanup(cleanup) + return process + + def probe(self, kind, pid): + if kind == "lifecycle": + return lifecycle.alive(pid) + with tempfile.TemporaryDirectory() as directory: + (Path(directory) / "editor.json").write_text(json.dumps({ + "pid": pid, "host": "127.0.0.1", "port": 6540, + "authToken": "fixture-token"})) + return bool(bridge_auth.auth_fields(6540, directory)) + + def test_live_process_survives_authentication_and_lifecycle_probes(self): + for kind in ("auth", "lifecycle"): + with self.subTest(kind=kind): + process = self.child( + 'import time; print("ready", flush=True); time.sleep(60)') + self.assertEqual(process.stdout.readline().strip(), "ready") + self.assertTrue(self.probe(kind, process.pid)) + try: + process.wait(timeout=0.2) + except subprocess.TimeoutExpired: + pass + else: + self.fail(f"{kind} liveness probe terminated its live child") + + def test_exited_process_is_not_alive_or_eligible_for_authentication(self): + process = self.child("pass") + process.wait(timeout=10) + for kind in ("auth", "lifecycle"): + with self.subTest(kind=kind): + self.assertFalse(self.probe(kind, process.pid)) + + def test_invalid_process_ids_are_not_alive_or_eligible_for_authentication(self): + for kind in ("auth", "lifecycle"): + for pid in (0, -1, 0xFFFFFFFF, 0x100000000): + with self.subTest(kind=kind, pid=pid): + self.assertFalse(self.probe(kind, pid)) + + @unittest.skipUnless(os.name == "nt", "Windows process exit code contract") + def test_exit_code_still_active_does_not_mean_process_is_running(self): + process = self.child("import sys; sys.exit(259)") + self.assertEqual(process.wait(timeout=10), 259) + for kind in ("auth", "lifecycle"): + with self.subTest(kind=kind): + self.assertFalse(self.probe(kind, process.pid)) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/scripts/test_readme_install.py b/tests/scripts/test_readme_install.py new file mode 100644 index 00000000..788ce414 --- /dev/null +++ b/tests/scripts/test_readme_install.py @@ -0,0 +1,139 @@ +import re +import unittest +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[2] +READMES = ['README.md', 'README.ja.md', 'README.zh.md', 'README.de.md', + 'README.es.md', 'README.fr.md', 'README.it.md'] + +PROMPT_STEPS = [ + 'scripts/install.sh', + 'scripts/install.ps1', + 'PATH', + 'unity-cli --output json setup --launch-editor', + 'unity-cli system ping', + 'unity-cli doctor --output json', + 'Packages/manifest.json', +] + +UPDATE_STEPS = [ + 'UNITY_CLI_NO_AUTO_UPDATE', + 'UNITY_CLI_VERSION', + 'unity-cli cli install', + 'brew upgrade akiojin/tap/unity-cli', + 'winget upgrade akiojin.unity-cli', +] + +BRIDGE_STEPS = [ + 'unity-cli --output json bridge status', + 'mismatch', + 'unity-cli bridge upgrade', + 'custom', + 'unknown', +] + +# Heading words that say "install or update" in each README language. +UPDATE_HEADINGS = { + 'README.md': 'update', 'README.ja.md': '更新', 'README.zh.md': '更新', + 'README.de.md': 'aktualisier', 'README.es.md': 'actualiz', + 'README.fr.md': 'a jour', 'README.it.md': 'aggiorna', +} + +MANUAL_CONTENT = [ + 'scripts/install.sh | sh', + 'scripts/install.ps1 | iex', + 'SHA256SUMS', + 'UNITY_CLI_VERSION', + 'UNITY_CLI_NO_AUTO_UPDATE', + 'brew install akiojin/tap/unity-cli', + 'winget install akiojin.unity-cli', + 'ORT_DYLIB_PATH', + 'releases', + 'cargo install --path .', + 'unity-cli --output json setup --launch-editor', + 'unity-cli bridge install | upgrade | status', + 'activeInputHandler', + 'openupm add com.akiojin.unity-cli-bridge', + '?path=UnityCliBridge/Packages/unity-cli-bridge', + 'unity-cli system ping', + 'unity-cli doctor --output json', + 'unity-cli cli doctor', + 'unity-cli cli install', + 'UNITY_CLI_TOOLS_ROOT', +] + + +def getting_started(text): + """Return the `##` section that holds the Editor compatibility note.""" + sections = re.split(r'^(?=## )', text, flags=re.MULTILINE) + matches = [s for s in sections if 'docs/editor-compatibility.md' in s] + assert len(matches) == 1, 'Getting Started section not found' + return matches[0] + + +def subsections(section): + parts = re.split(r'^(?=### )', section, flags=re.MULTILINE)[1:] + return [(part.splitlines()[0], part) for part in parts] + + +class ReadmeInstallStructureTest(unittest.TestCase): + def test_getting_started_has_compat_llm_and_manual_paths(self): + for name in READMES: + with self.subTest(readme=name): + subs = subsections(getting_started((ROOT / name).read_text())) + self.assertEqual(len(subs), 3, [title for title, _ in subs]) + self.assertIn('docs/editor-compatibility.md', subs[0][1]) + + def test_llm_section_has_single_prompt_with_all_steps(self): + for name in READMES: + with self.subTest(readme=name): + llm = subsections(getting_started((ROOT / name).read_text()))[1][1] + prompts = re.findall(r'^```text\n(.*?)^```', llm, + flags=re.MULTILINE | re.DOTALL) + self.assertEqual(len(prompts), 1) + prompt = prompts[0] + positions = [prompt.find(step) for step in PROMPT_STEPS] + for step, pos in zip(PROMPT_STEPS, positions): + self.assertGreaterEqual(pos, 0, step) + ordered = [positions[0], positions[3], positions[4], positions[5]] + self.assertEqual(ordered, sorted(ordered)) + # manifest.json confirmation must come before setup runs + self.assertLess(positions[6], positions[3]) + self.assertIn('/plugin marketplace add akiojin/unity-cli', llm) + self.assertIn('.agents/skills/', llm) + + def test_llm_prompt_updates_cli_and_bridge(self): + for name in READMES: + with self.subTest(readme=name): + title, llm = subsections(getting_started((ROOT / name).read_text()))[1] + self.assertIn(UPDATE_HEADINGS[name], title.lower()) + prompt = re.findall(r'^```text\n(.*?)^```', llm, + flags=re.MULTILINE | re.DOTALL)[0] + self.assertIn(UPDATE_HEADINGS[name], prompt.splitlines()[0].lower()) + for needle in UPDATE_STEPS + BRIDGE_STEPS: + self.assertIn(needle, prompt, needle) + setup = prompt.find('unity-cli --output json setup --launch-editor') + ping = prompt.find('unity-cli system ping') + # CLI update happens before setup; pinned versions are checked first + self.assertLess(prompt.find('UNITY_CLI_NO_AUTO_UPDATE'), + prompt.find('unity-cli cli install')) + self.assertLess(prompt.find('winget upgrade'), setup) + # bridge alignment runs between setup and the final ping + status = prompt.find('unity-cli --output json bridge status') + upgrade = prompt.find('unity-cli bridge upgrade') + self.assertTrue(setup < status < upgrade < ping) + # upgrade asks before touching the manifest + self.assertIn('Packages/manifest.json', prompt[status:upgrade]) + # the final ping confirms versionCheck is match + self.assertRegex(prompt[ping:], r'versionCheck\.status[^\n]*match') + + def test_manual_section_keeps_every_install_path(self): + for name in READMES: + with self.subTest(readme=name): + manual = subsections(getting_started((ROOT / name).read_text()))[2][1] + for needle in MANUAL_CONTENT: + self.assertIn(needle, manual, needle) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/scripts/test_skill_routing.py b/tests/scripts/test_skill_routing.py index ab2dcb16..20f655c7 100644 --- a/tests/scripts/test_skill_routing.py +++ b/tests/scripts/test_skill_routing.py @@ -114,6 +114,21 @@ def test_asset_update_then_play_keeps_existing_route(self): self.assertEqual(prediction["predicted_tool"], "add_input_binding") self.assertEqual(prediction["predicted_skills"][0], "unity-input-system") + def test_csharp_creation_and_compile_fixes_route_to_lsp_write_tools(self): + benchmark = ROOT / "tests/fixtures/skill-routing/benchmark.jsonl" + rows = [row for row in map(json.loads, benchmark.read_text().splitlines()) + if row["id"] == "SR-072" or row["id"].startswith("CS488-")] + self.assertEqual(len(rows), 6) + for row in rows: + with self.subTest(case=row["id"]): + self.assertIn(row["expected_tool"], {"create_csharp_file", "apply_csharp_edits"}) + prediction = routing.route_by_keywords(row["prompt"]) + self.assertIsNotNone(prediction) + self.assertEqual(prediction["predicted_tool"], row["expected_tool"]) + self.assertEqual(prediction["predicted_skills"], row["expected_skills"]) + self.assertEqual(prediction["predicted_payload_keys"], + row["expected_payload_keys"]) + if __name__ == "__main__": unittest.main() diff --git a/tests/setup_dry_run.rs b/tests/setup_dry_run.rs index 9374bbb7..67c8c3c9 100644 --- a/tests/setup_dry_run.rs +++ b/tests/setup_dry_run.rs @@ -27,6 +27,91 @@ fn drain(mut pipe: impl Read + Send + 'static) -> std::thread::JoinHandle