chore: bump version to 9.4.7#808
Merged
github-actions[bot] merged 57 commits intomainfrom Feb 21, 2026
Merged
Conversation
…39178995 chore: sync main (v9.4.6) into beta
* Fix UnityEvent wiring via manage_components set_property (#631) UnityEventBase-derived fields set via reflection create disconnected objects that Unity's serialization layer doesn't track, causing m_PersistentCalls to be empty on save. Route these types through SerializedObject/SerializedProperty instead. Adds recursive SerializedProperty setter supporting Generic structs, arrays, ObjectReference, and leaf types (int, bool, float, string, enum). Includes fuzzy child property matching to handle batch_execute stripping underscores from nested JSON keys (tracked in #756). Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Fix batch_execute mangling nested value keys (#756) batch_execute NormalizeParameterKeys recursively converted all JSON keys to camelCase, including nested value data like Unity serialized property paths (m_PersistentCalls to mPersistentCalls). This broke UnityEvent wiring and any tool receiving structured nested data through batch_execute. Stop recursing into values -- only normalize top-level parameter keys. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Guard against null value in SerializedProperty string setter Address Sourcery review: check value == null before accessing value.Type to prevent NullReferenceException in the string case of SetSerializedPropertyRecursive. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
…5939238 chore: update Unity package to beta version 9.4.7-beta.2
* Sync claude-nl-suite workflow with proven main version * Fix preflight sys.path under Server working directory
…) (#762) * Fix read_console reflection crash on Unity 6.5 and batch-mode test crash (#761) - Remove unused LogEntry.instanceID reflection that fatally blocked read_console initialization on Unity 6000.5.0a6 - Skip Collider.GeometryHolder in GameObjectSerializer to prevent native PhysX SEGV in batch-mode test runs - Fix CodexConfigHelperTests to work with both release and prerelease package versions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add com.unity.test-framework as package dependency The package has a hard compile dependency on Test Framework (RunTests, TestJobManager, TestRunnerService, etc.) but did not declare it in package.json. Projects without Test Framework installed would get CS0234/CS0246 errors on import. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Address review: dispose SerializedObject, fix null stringValue, remove dead method - Wrap SerializedObject in using block in SetViaSerializedProperty - Use string.Empty instead of null for SerializedProperty.stringValue - Remove unused GetRemappedTypeForFiltering from ReadConsole Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…7760337 chore: update Unity package to beta version 9.4.7-beta.3
…fallback (#765) (#766) * Fix misleading 'Property not found' error for conversion failures and add SerializedProperty fallback (#765) When setting component properties via reflection failed (e.g. array types, UdonSharp proxies), the error message falsely reported "Property 'X' not found. Did you mean: X?" — even though the property existed. The root cause was that SetProperty returned a bare bool with no error detail, so the caller interpreted every failure as "not found." Changes: - GameObjectComponentHelpers.SetProperty now returns error details via out parameter, distinguishing conversion failures from missing properties - ComponentOps.SetProperty falls back to SetViaSerializedProperty when reflection-based conversion fails, handling arrays and custom serialization - GameObjectComponentHelpers falls back to ComponentOps.SetProperty when its local reflection fails, gaining the same SerializedProperty support Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Include token context in SetProperty error message for debuggability Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Remove redundant local SetProperty; delegate to ComponentOps directly Address CodeRabbit review feedback: - Remove duplicated reflection logic from GameObjectComponentHelpers - Route non-nested property paths directly through ComponentOps.SetProperty - Add out string error to SetNestedProperty for proper error propagation - Fix MaterialOps.TrySetShaderProperty call to set error on failure Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix empty array error message and support [SerializeField] in nested paths Address CodeRabbit review round 2: - Handle empty arrays/lists separately to avoid nonsensical "out of range (0--1)" - Add [SerializeField] private field lookup for final segment of nested paths - Expose FindSerializedFieldInHierarchy as internal for cross-class reuse Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…4680294 chore: update Unity package to beta version 9.4.7-beta.4
…arm (#760) When the uvx cache already has the package, pass --offline to skip the network dependency check that can hang for 30+ seconds on poor connections. A lightweight probe (uvx --offline ... --help) with a 3-second timeout determines cache warmth before building the command. Also fixes stale LogAssert expectations in SetComponentProperties test to match current error message format from ComponentOps refactor. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract GetUvxDevFlags() and GetUvxDevFlagsList() helpers to AssetPathUtility, replacing duplicated if/else if/else blocks across 6 call sites. Add 30-second TTL cache to ShouldUseUvxOffline() to avoid redundant subprocess spawns. Simplify ConfigureWithCapturedValues signature from two bools to a single pre-captured flags string. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…resh calls Address CodeRabbit nitpicks: relocate static cache fields above the methods that use them for readability, extract GetCachedOfflineProbeResult() so GetUvxDevFlags()/GetUvxDevFlagsList() evaluate ShouldForceUvxRefresh() only once per call instead of twice. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When HTTP transport is enabled, skip Configure() for clients that do not support HTTP (e.g., Claude Desktop). Previously this threw and logged a spurious warning on every editor launch. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add --offline to uvx launches for faster startup (#760)
…6530970 chore: update Unity package to beta version 9.4.7-beta.5
… (#770) Unity internal LogEntry type does not expose timestamp data via reflection, so the parameter was accepted but silently did nothing. Remove it from Python, C#, and tool reference docs. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…6967023 chore: update Unity package to beta version 9.4.7-beta.6
…ion (#772) Any tool call can now include a unity_instance parameter to route that specific call to a target Unity instance without changing the session default and without requiring a set_active_instance call first. The middleware pops unity_instance from tool call arguments before Pydantic validation runs, resolves it (port number, hash prefix, or Name@hash), and injects it into request-scoped state for that call only. - Port numbers resolve to the matching Name@hash via status file lookup rather than synthetic direct:{port} IDs, so the transport layer can route them correctly - HTTP mode rejects port-based targeting with a clear error - set_active_instance now also accepts port numbers for consistency - Multi-instance scenarios log available instances with ports when auto-select cannot choose - _discover_instances() helper DRYs up transport-aware instance discovery previously duplicated across the codebase - Server instructions updated to document both routing approaches - 18 new tests covering pop behaviour, per-call vs session routing, port resolution, transport modes, and edge cases Closes #697 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…9509793 chore: update Unity package to beta version 9.4.7-beta.7
…cOS (#783) * Fix focus nudge launching Electron instead of restoring VS Code on macOS The focus restore used process name (e.g. "Electron") which caused macOS to launch a standalone Electron instance instead of returning to VS Code. Now captures bundle identifier and uses `tell application id` for precise activation, falling back to name-based activation if bundle ID fails. Fixes #699 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Address review feedback: guard AppleScript missing value, fix escaping, improve logging - Guard AppleScript against `missing value` bundle identifier that would crash osascript and silently disable the entire nudge cycle (CodeRabbit) - Also filter "missing value" string on the Python side as belt-and-suspenders (Sourcery) - Fix AppleScript string escaping: use "" (AppleScript convention) not \" (Python convention) for both bundle_id and app_name (CodeRabbit) - Log AppleScript stderr when bundle_id activation fails (Sourcery) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…7691143 chore: update Unity package to beta version 9.4.7-beta.8
…ad (#787) * Fix StdioBridgeHost zombie state after domain reload (#785) After domain reload, the bridge could accept TCP connections but never process commands. Three defensive fixes address the plausible failure vectors: 1. Stale client cleanup: when a new client connects, close all other active clients (in stdio there is only one server). Forces hung ReadFrameAsUtf8Async to throw and exit cleanly. 2. ProcessCommands self-healing: track consecutive TCS timeouts. After 2+ consecutive, force re-register ProcessCommands on EditorApplication.update and reset the reentrancy guard. 3. Stale command eviction: commands stuck with IsExecuting=true for more than 60s are evicted from the queue with an error result. Also adds always-on diagnostic logging at client connect/disconnect with active client counts. Includes E2E reconnection tests that verify both abrupt disconnect recovery and stale client cleanup. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix stdio bridge stalls when Unity is backgrounded during domain reload - Add QueuePlayerLoopUpdate after command enqueue so ProcessCommands fires even when Unity is backgrounded (mirrors HTTP RequestMainThreadPump) - Keep ProcessCommands permanently registered on EditorApplication.update to eliminate the registration gap between Stop and Start during reload - Replace blocking retry loop in Start() (Thread.Sleep x 10) with single attempt + port-switch fallback; async retries handled by reload handler - Replace fire-and-forget TryStartBridgeImmediate with async retry loop (6 attempts with backoff: 0s, 1s, 3s, 5s, 10s, 30s) matching HTTP - Fix macOS port conflict: use ExclusiveAddressUse in both the real listener (CreateConfiguredListener) and the port probe (IsPortAvailable) to prevent AssetImportWorkers from binding the same port via SO_REUSEADDR - Add PortManager unit tests (5 tests including macOS SO_REUSEADDR case) Fixes #785 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add resource URI reference table to unity-mcp-skill Adds a prominent 'Do NOT Guess' section with a URI lookup table near the top of the skill, so LLMs use exact URIs instead of fabricating similar-looking ones. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Address PR review feedback - Collapse double lock in HandleClientAsync (add + count in one lock) - Add CancellationToken to ResumeStdioWithRetriesAsync so retries abort on editor quit or subsequent domain reloads - Fix 'gameobject' → 'GameObject' capitalization in skill URI table Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Address CodeRabbit review feedback - PortManagerTests: save/restore on-disk port files in SetUp/TearDown to prevent DiscoverNewPort from mutating persistent state - StdioBridgeReconnectTests: replace blocking Connect with ConnectAsync + Wait(ConnectTimeoutMs) so CI tests cannot hang indefinitely Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…0502613 chore: update Unity package to beta version 9.4.7-beta.9
) * Fix editor state always reporting stale when Unity is backgrounded EditorStateCache.GetSnapshot() returned a cached clone with the observed_at_unix_ms from the last OnUpdate tick. When Unity is backgrounded, OnUpdate is throttled, so the timestamp grows stale even though the data is current and Unity is responsive. Now stamps the clone at serve time so the server-side staleness check (>2s = stale) reflects when the snapshot was served, not when the update loop last ran. This fixes ready_for_tools being false for every backgrounded Unity editor on HTTP. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Only re-stamp editor state when Unity is backgrounded Addresses CodeRabbit review feedback: the unconditional re-stamp defeated the staleness check for genuinely unresponsive focused editors. Now uses InternalEditorUtility.isApplicationActive to conditionally re-stamp only when Unity is backgrounded. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add /mcp-source skill and fix upstream main URL Add Claude Code skill for switching MCP package source in Unity projects. Fix mcp_source.py upstream main URL to include required #main branch suffix. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…11319809 chore: update Unity package to beta version 9.4.7-beta.10
…792) When Unity enters domain reload after a script edit, the retry loop in send_command_with_retry would re-send the identical edit command up to 40 times, duplicating insert_method/anchor_insert edits. Pass retry_on_reload=False on all script-mutating send calls since the edit lands on disk before the reload triggers. Also fix _flip_async coroutine in apply_text_edits that was passed as a threading.Thread target — the coroutine was never awaited. Replace with asyncio.create_task so the sentinel reload flip actually executes. Fixes #790 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…33095438 chore: update Unity package to beta version 9.4.7-beta.11
) * Fix script edit tools retrying non-idempotent commands during reload When Unity enters domain reload after a script edit, the retry loop in send_command_with_retry would re-send the identical edit command up to 40 times, duplicating insert_method/anchor_insert edits. Pass retry_on_reload=False on all script-mutating send calls since the edit lands on disk before the reload triggers. Also fix _flip_async coroutine in apply_text_edits that was passed as a threading.Thread target — the coroutine was never awaited. Replace with asyncio.create_task so the sentinel reload flip actually executes. Fixes #790 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add post-mutation wait-for-ready and reloading-rejection retry Script-mutating tools (create_script, delete_script, apply_text_edits, script_apply_edits) use retry_on_reload=False to avoid re-sending non-idempotent commands during domain reload. But this meant they returned before Unity finished reloading, causing the next tool call to timeout. This commit: - Extracts wait_for_editor_ready() helper from refresh_unity.py that polls editor_state until Unity reports ready_for_tools - Adds is_reloading_rejection() to detect when Unity rejected a command due to stale reloading state (safe to retry since command never ran) - Calls both at all 9 mutation sites (4 in manage_script, 5 in script_apply_edits): retry on rejection, then wait for readiness - Adds 9 unit tests for the new helpers Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix stale socket causing mutations to silently fail after domain reload UnityConnection reuses TCP sockets across commands. After domain reload kills Unity TCP listener, the Python side still holds the dead socket. With retry_on_reload=False (used for non-idempotent mutations), there are no retries to recover -- the command is never delivered to Unity. - Add _ensure_live_connection() to detect dead sockets via non-blocking MSG_PEEK before each send, allowing reconnection - Add is_connection_lost_after_send() helper and post-mutation verification at all 9 mutation sites (create/delete/apply_text_edits/script_apply_edits) to recover when domain reload drops the TCP response - Fix stale reloading heartbeat in C# bridge: write reloading=false at Start() entry and after retry exhaustion in StdioBridgeReloadHandler Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Extract send_mutation() and verify_edit_by_sha() shared helpers Consolidates the repeated retry+wait+verify pattern from 9 inline sites across manage_script.py and script_apply_edits.py into a single send_mutation() helper in refresh_unity.py. Addresses Sourcery code review feedback on PR #796. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…42593753 chore: update Unity package to beta version 9.4.7-beta.12
…43317202 chore: update Unity package to beta version 9.4.7-beta.13
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…43507739 chore: update Unity package to beta version 9.4.7-beta.14
…52367644 chore: update Unity package to beta version 9.4.7-beta.15
…udge) (#804) * fix: remove broken root rename assertion from prefab test LoadAssetAtPath returns the asset filename as .name for prefab roots, not the internally renamed root object name. Remove the rename + assert that was causing CombinesWithOtherModifications to fail. The test still verifies that componentProperties works alongside position changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: remove yield frames causing StdioBridge reconnect test flakiness The 5-frame yield between client2 handshake and ping created a window where the MCP Python server could reconnect and close our test client as stale. Stale-client cleanup runs synchronously in HandleClientAsync before the read loop, so no yield is needed after reading the handshake. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: ensure focus nudge fires and logs correctly during test polling - Add file handler to root logger so __name__-based loggers (focus_nudge, run_tests) write to the log file instead of only stderr - Add fire-and-forget nudge check on non-wait_timeout get_test_job calls so stalls are detected regardless of client polling style - Add 13 unit tests for should_nudge logic, backoff reset, and gating Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address PR #804 review feedback - Store asyncio.create_task reference in module-level set to prevent GC (CodeRabbit) - Add test for _get_frontmost_app() returning None (CodeRabbit nitpick) - Add comment explaining why prefab root rename is not tested (Sourcery) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add Claude Code to MCP client examples in README Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…62651671 chore: update Unity package to beta version 9.4.7-beta.16
data.get('progress', {}) returns None when key exists with null value.
Use 'or {}' fallback to prevent AttributeError on progress.get().
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…62768294 chore: update Unity package to beta version 9.4.7-beta.17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Automated version bump to 9.4.7.