Skip to content

chore: bump version to 10.3.0 - #1425

Merged
github-actions[bot] merged 120 commits into
mainfrom
release/v10.3.0
Oct 4, 2026
Merged

github-actions[bot] merged 120 commits into
mainfrom
release/v10.3.0

Conversation

@github-actions

@github-actions github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Automated version bump to 10.3.0.

crowdedfire and others added 30 commits July 20, 2026 13:34
ReadUserScopeConfig merged duplicate normalized project keys from
~/.claude.json ("D:/Dev/X" vs "D:\Dev\X") last-entry-wins, on the
assumption the last is most recent. JSON property order is not
correlated with recency across variants: when the last duplicate is a
stale entry without mcpServers it shadows the real registration, and
CheckStatus reports NotConfigured despite a working
`claude mcp add --scope local` setup (observed live 2026-07-20).

Merge by preferring the entry that actually carries a UnityMCP
registration (then any mcpServers, then last-wins as before).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`claude mcp add --scope local` keys the registration in ~/.claude.json
by the git MAIN repo root. When the Unity project is a linked worktree
(e.g. C:/Dev/stay-booping -> repo C:/Dev/stay) that key is a sibling
path, so ReadUserScopeConfig's ancestor walk never finds it and
CheckStatus reports NotConfigured while the CLI itself resolves the
worktree fine (`claude mcp list` shows Connected). Parse the main root
from the worktree's .git pointer file and retry the walk from there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
When a command outlives the broker's patience, the Python side closes the
socket, reconnects and resends the same payload. The bridge queued that
resend as a brand-new command behind the still-executing original, so the
work ran twice — visibly so for commands with side effects such as a long
ExecuteMenuItem or a build.

The enqueue path now looks for an in-flight command with the same payload
that was queued by a different connection, and attaches the new caller to
that command's completion source rather than queueing a copy. Comparing
the owning connection as well as the payload is what keeps this safe:
a single connection handles one command at a time, so two identical
payloads on one connection are sequential and genuinely distinct requests.

QueuedCommand gains an Owner field, held for identity comparison only and
never dereferenced.

Closes #1130
The test sampled Dictionary.Count directly by reflection while listener
tasks could be adding entries under lockObj, and Dictionary does not
support concurrent reads and writes. Sleeping on the main thread stops
ProcessCommands from draining the queue but does nothing to synchronise
against the socket threads that fill it.

Replaces the reflection with an internal QueuedCommandCount accessor that
takes lockObj, documented as diagnostics-only.

Addresses CodeRabbit review on #1361.
…3553983134

chore: sync main (v10.2.0) into beta
… too

DiscoverAllTools queried TypeCache and then materialised every type in
every loaded assembly anyway, calling GetCustomAttribute on each one
before merging the two sets — so the fast path never saved anything.

The result is cached, so that walk ran once per domain reload, and again
whenever a tool is toggled in the editor window. A reload therefore paid
for two full assembly walks: this one and the one in
CommandRegistry.AutoDiscoverCommands that #1364 removed.

Now TypeCache-only, matching CommandRegistry and ResourceDiscoveryService.
Ordered by FullName for the same reason #1364 sorts: a duplicate tool name
overwrites the previous registration, so order decides the winner, and
TypeCache documents no order.

Relates to #1336
…ypes

FullName is not a total order: two assemblies can declare the same full
type name, and OrderBy leaves their relative position to the input, which
TypeCache does not define. If those types also resolve to the same tool
name, the later registration overwrites the earlier one, so the winner
could differ between domain reloads.

Ordering now falls back to Assembly.FullName. The comparison moved into
an internal InRegistrationOrder helper so it can be tested directly:
two identically named types cannot coexist in one assembly, so the test
emits them into separate dynamic assemblies to construct a real tie and
asserts the result does not depend on input order.

Addresses CodeRabbit review on #1369.
Unity talks straight to the BlenderMCP addon socket, so a Blender to Unity
handoff is one blender_bridge call: export (GLB/FBX) from Blender, import
through the shared model pipeline, place in the open scene and normalize the
size from measured bounds. Other actions: status, scene/object info, viewport
screenshot, run Python in Blender, check the blender-mcp checkout for
updates, and sync its addon.py into Blender's addons folder.

The informational "Blender -> Unity Handoff" row in the Asset Gen tab becomes
a real panel: socket host/port with Test Connection, blender-mcp checkout and
Blender addons dir (Select/Clear, resolved path and addon-in-sync state), and
Sync Addon / Check Updates / Import Selection buttons. Settings live in
EditorPrefs under MCPForUnity.Blender.* via BlenderBridgePrefs; no
machine-specific defaults. BlenderDetection gains user addons dir discovery.
Menu items under Window/MCP for Unity/Blender Bridge drive the same handler.
Registers blender_bridge in the asset_gen group with typed parameters that
map to the C# handler (snake_case to camelCase, None stripped), and adds the
`unity-mcp blender` CLI group (status, scene-info, object-info, screenshot,
run-python, import-model, check-updates, sync-addon).
…ection

Python: registration group, parameter mapping, non-dict result handling and
CLI flag mapping. Unity EditMode: framing-free JSON parse/unwrap, handler
validation errors that need no Blender, and PickAddonsDir/ParseVersion.
- Run socket and git work on the thread pool: HandleCommand is async, the
  panel and menu await it, and Unity API calls happen after the await on the
  editor thread. Buttons are disabled while a call is in flight.
- BlenderSocketClient takes an explicit BlenderEndpoint (EditorPrefs is
  main-thread only) and rejects responses whose status is neither success
  nor error instead of returning a null payload.
- Canonicalize screenshot output_folder through AssetGenPaths so
  "Assets/../x" cannot escape the project.
- Pass target_size through unchanged; 0 now keeps the imported scale as the
  CLI documents (the pipeline only rescales when > 0).
- Embed export-script values as one JSON literal parsed inside Blender, so
  names with quotes or placeholder-looking text cannot alter the program.
- Suppress Ruff A002 on the public `format` parameter.
- Document the existing asset_gen group in CLAUDE.md, dev-setup and the
  tool-groups guide.
- XML docs on the new C# members; tests for invalid status, output_folder
  traversal and the export-script builder.
- Screenshot and export paths get a timestamp plus random suffix so
  concurrent commands (menu + MCP) started in the same second never share a
  file.
- check_updates strips user info from git remote URLs before returning them,
  so a token embedded in https://user:token@host/... never reaches the MCP
  response or the editor log.
- Tool count in the tool-groups guide and README is 48 with blender_bridge.
… compare

- import_model: auto_animate (default on) creates a looping AnimatorController
  next to the asset with one state per imported clip and assigns it, so a
  rigged model moves instead of sitting frozen with a null controller; FBX
  clips are marked looping on the importer first. save_prefab stores the placed
  instance under <asset folder>/Prefabs. ensure_bloom enables camera
  post-processing and adds a Bloom override to the global volume (through
  manage_graphics) when the model has emissive materials.
- New actions: compare_screenshot composites Blender's viewport (left) and a
  Unity capture framed on the placed object (right) into one PNG;
  setup_bloom runs the Bloom setup on its own.
- Export prefers the addon's export_scene command (validated parameters, no
  code execution) and falls back to the execute_code script on older addons.
- Python tool, CLI (--no-animate, --save-prefab, --ensure-bloom,
  compare-screenshot, setup-bloom), tests and generated docs updated.
A core.autocrlf checkout gives tools/compile-defines.txt and tools/compile-refs/*.txt
CRLF endings; the read loops kept the CR, so every -define: carried a stray \r and
every LIBCACHE/ reference failed to resolve, failing the Editor build on TestRunner
types. Strip the CR when reading and pin those manifests to LF in .gitattributes.

Also normalise REPO/UNITY_DATA/OUT through pwd -W so Git Bash's /x/... paths do not
reach Roslyn as X:\x/..., and document the Windows recipe in the header.
The lock's own-project entry still said 10.1.0 while pyproject.toml said 10.2.0, so
uv sync --locked failed and CI silently re-resolved. update_versions.py now rewrites
the mcpforunityserver entry, release.yml stages the lock in the bump commit, and
python-tests.yml runs uv sync --locked --extra dev so pytest uses the pinned dev
dependencies instead of whatever uv pip install fetches on the day.
…orPrefs

McpCiBoot wrote UseHttpTransport=false to the developer's EditorPrefs and still lost
to the value EditorConfigurationCache had already read: on a machine whose prefs
choose HTTP with auto-start, UNITY_MCP_ALLOW_BATCH let HttpAutoStartHandler run and
BridgeControlService.StartAsync stopped the stdio bridge the harness was talking to.
Keep the override in SessionState so it survives domain reloads, dies with the editor
process, and never touches the user's real preference.
Discovery is parameterised by platform so it can be tested for every OS from any OS,
but it used pathlib.Path, which picks the host separator; four tests failed on
Windows with \home\dev\Unity. Use PurePosixPath/PureWindowsPath by target.
…face

- /register-tools is no longer registered in remote-hosted mode. It carried no
  API-key check, so any caller could replace tool definitions for every tenant; the
  plugin registers tools over the hub WebSocket and never calls this route.
- debug_request_context redacts the values of secret-bearing argv flags. It handed
  --api-key-service-token to every authenticated tenant.
- ApiKeyService caps its cache at 1024 entries (expired first, negatives never evict
  a validated key) so unauthenticated key guesses cannot grow memory, and logs a
  sha256 fingerprint instead of eight literal characters of the key.
set -x printed the expanded -password/-serial arguments into the job log and left
GitHub's secret masking as the only protection.
…ent in remote URLs

- setup_bloom returns an error response when manage_graphics could not add
  the Bloom override instead of reporting success with a failure payload.
- RedactRemoteUrl also drops query strings and fragments, so ?token=... or
  #access_token=... never reach the check_updates response.
- Tests for the failure mapping and the extra redaction cases.
perf(discovery): drop the redundant assembly walk from tool discovery too
…693125446

chore: update Unity package to beta version 10.2.1-beta.2
fix: Claude Code registrations invisible to CheckStatus (duplicate path-variant keys, git worktrees)
…694138160

chore: update Unity package to beta version 10.2.1-beta.3
Scriptwonder and others added 27 commits October 2, 2026 17:23
On a tr-TR editor "Warning".ToUpper() gives "WARNİNG", so the validate parser's ^(ERROR|WARNING|INFO): regex misses it and the diagnostic comes back as severity info, line 0.
fix: upper-case Roslyn severity with the invariant culture
fix(tests): recover jobs after reload, bound focus nudges, and fix CI
Signed-off-by: pumisj <pumisj@naver.com>
…ore-1407

fix(windows): preserve window state and Unicode focus metadata
feat: Blender Bridge — drive BlenderMCP from the Unity Editor (tool + Asset Gen panel)
…ey row

- Editor DropdownFields open a native GenericMenu that turns every '/' in a
  model id into a submenu; menu items now show U+2215 instead (passed via the
  ctor, since formatListItemCallback is not public before Unity 6).
- Cap each model menu at 25 entries, keep the saved selection, and point to
  Search for the rest of large live catalogs.
- The fal 3D row reuses the 2D fal key and toggle like the audio row, instead
  of a second key field and an out-of-sync Enabled toggle.
- Rebuild model controls only on catalog Changed events, scoped by provider,
  and keep failed compatibility checks visible across rebuilds.
- Skip the selector for providers with no models (Sketchfab showed "No models
  found") and show verification state only for fal/OpenRouter.
With a saved selection missing from the catalog, the caveat label kept its validation-description background with no text, which showed as an empty blue bar under the audio row.
…he cap

- A paid-generation (or selection) preflight no longer waits on the request
  gate that background catalog refreshes take turns through. With a full
  refresh in flight it could queue behind several paced requests and hit its
  60 s timeout. Without a key it still honors the public pacing interval.
- Raise the fal/OpenRouter cache read cap from 2 MB to 16 MB (~25x today's
  ~0.6 MB catalog) and log a warning when a cache is skipped, instead of
  silently re-fetching after every domain reload once the catalog outgrows it.
Resolves McpAssetGenSection.cs against the Blender Bridge panel from #1375: keep blenderPanel?.Refresh() next to the catalog refresh, and drop the old AddBlenderHandoffRow call that beta replaced with the panel.
…talog

feat: auto-discover live fal and OpenRouter asset models
…ll state

- Probe the BlenderMCP addon socket automatically (in the background) when the
  panel is built, each time the Generative tab is shown, and after a host/port
  change. One probe at a time; a request during a probe re-runs it so the shown
  result always belongs to the current endpoint. Test Connection is a manual
  re-check and no longer disables the action buttons.
- Detect Microsoft Store Blender (per-user %LOCALAPPDATA%\Packages\
  BlenderFoundation.Blender* folder; the WindowsApps install dir is unreadable),
  Steam's default library on Windows/macOS/Linux, and Linux per-user flatpak.
  A Store-only machine was reported as "Blender app not found".
- The addons line now says when the resolved folder does not exist yet and
  whether addon.py is installed, and is green only when the addon is installed
  (and matches the checkout when one is set). It used to show a nonexistent
  folder in green.
- Replace the yellow "pick your checkout" banner with a neutral note: the
  checkout is optional and only for addon developers (Sync Addon / Check
  Updates). Rename the import button to "Import Blender Selection (GLB)" and
  explain what it needs in its tooltip.
…ion-ux

Blender Bridge panel: auto-detect the addon and report the real install state
…n parse it

The file ended in "assetBundleVariant:" with no space and no final newline.
Unity 6 reads that last line as a key without its ':' separator, logs
"YAML Parsing error 'Parser Failure at line 11'", and ignores the asset
("does not have a valid GUID"). Unity 2021.3 and 2022.3 accept the file.

On the 6000.0 and 6000.4 legs of Beta Release, the error is logged during the
SetUp of the four DomainReloadResilienceTests, which fail on the unhandled log
message. The full EditMode suite is then skipped, so every Beta Release run
since #1389 (91eb0f4) is red and nothing has published.

Reproduced on 6000.6.4f1: the original bytes give the same error and no GUID;
the same bytes plus a final newline import normally. No other tracked .meta
file ends in a bare "key:".
test: end ExecPathBatchShimTests.cs.meta with a newline so Unity 6 can parse it
@coderabbitai

coderabbitai Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 72742b4e-ae5e-4497-bad9-dd2effc953c5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

❤️ Share

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

@github-actions
github-actions Bot merged commit aa5fc63 into main Oct 4, 2026
1 check passed
@github-actions
github-actions Bot deleted the release/v10.3.0 branch October 4, 2026 02:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.