8 Commits

Author SHA1 Message Date
Shutong Wu 67445dff3d fix(execute_code): route CodeDom references through a response file (#1144)
`CodeDomCompile` in `MCPForUnity/Editor/Tools/ExecuteCode.cs` pushed every
filtered assembly path into `CompilerParameters.ReferencedAssemblies`. Mono's
`CSharpCodeCompiler.BuildArgs` (verified at
mcs/class/System/Microsoft.CSharp/CSharpCodeCompiler.cs:388-392) turns each
reference into a literal `/r:"<absolute_path>"` flag and concatenates them
inline on the `mono.exe csc ...` command line.

Projects with ~100+ asmdefs (a perfectly normal large Unity project) overflow
Windows' 32 KB CreateProcess argument limit and `Process.Start` throws
Win32 `ERROR_FILENAME_EXCED_RANGE`, which Mono surfaces as:

    SystemException: Error running …mono.exe: The filename or extension is too long.

…exactly the failure reported in #1144 at ExecuteCode.cs:115 on Windows
10/11 + Unity 2022.3.62f2 + MCP for Unity 9.6.9-beta.8.

Fix: write all `/r:"…"` lines to a GUID-named temp response file and pass
`@"<path>"` via `CompilerParameters.CompilerOptions` (which `BuildArgs`
appends verbatim, confirmed at line 396 of the same Mono source). One short
argument regardless of reference count — the 32 KB ceiling is no longer
reachable.

Both legacy mcs and Roslyn csc accept `@responsefile`, so the change is
cross-platform: macOS/Linux Mono behaves identically, and the path doesn't
have a 32 KB limit there to begin with. Response file is cleaned up in a
`finally` block (best-effort; OS reaps temp on its own otherwise).

Tests: added two EditMode regression tests in `ExecuteCodeTests.cs` that
exercise the codedom backend end-to-end:
- `Execute_CodedomBackend_CompilesAndRuns` — basic compile + execute.
- `Execute_CodedomBackend_ResolvesUnityTypes` — verifies Unity references
  resolve through the response file.

Could not reproduce the exact 32 KB failure on macOS (Mono on POSIX doesn't
hit the limit), but the response-file path is the only path in the new code,
so the fix is mechanically equivalent for any reference-set size on any
platform.

Sources:
- Mono CSharpCodeCompiler.cs — BuildArgs converts ReferencedAssemblies to
  `/r:"…"` inline and appends CompilerOptions verbatim.
- C# compiler — ResponseFiles option (`@responsefile` syntax).
2026-05-26 16:43:18 +08:00
SebM f116493d4d fix(roslyn): install missing System.Runtime.CompilerServices.Unsafe and surface inner errors
The RoslynInstaller downloads only 4 NuGet packages but Microsoft.CodeAnalysis 4.12.0
on netstandard2.0 also references System.Runtime.CompilerServices.Unsafe v6.0.0.0,
which is NOT what Unity ships (Unity bundles v4.x). The reference is unresolved at
runtime, so Roslyn's StringTable static cctor throws FileNotFoundException, which
in turn poisons CSharpSyntaxTree's cctor: every parse / compile attempt then
throws TypeInitializationException.

The error is invisible because RoslynCompiler.Compile's catch block only logs
e.Message, and for TargetInvocationException that string is the generic
"Exception has been thrown by the target of an invocation." — the real cause
in InnerException is silently dropped.

Repro:
  1. Trigger Tools > MCP for Unity > Install Roslyn on a fresh project.
  2. Ask the MCP execute_code tool to compile any Roslyn-only snippet.
  3. Observe: "Compilation failed: Roslyn compilation error: Exception has been
     thrown by the target of an invocation." — with no further detail.
  4. Drilling via reflection reveals:
       TypeInitializationException for CSharpSyntaxTree
        └─ TypeInitializationException for Roslyn.Utilities.StringTable
            └─ FileNotFoundException: Could not load file or assembly
                'System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0'

Fix:
  * RoslynInstaller.NuGetEntries: add the missing dependency so a fresh install
    drops all 5 DLLs into Assets/Plugins/Roslyn/.
  * RoslynCompiler.Compile catch: walk the InnerException chain so a future
    bootstrap regression surfaces the actual cause (type + message) instead of
    the generic invocation wrapper.

Verified locally: after dropping System.Runtime.CompilerServices.Unsafe.dll v6
into the plugins folder and forcing a domain reload, the execute_code tool
compiles C# 7+ snippets via the Roslyn backend successfully.
2026-05-09 11:46:50 +02:00
Shutong Wu 1fba42998c Update0503
1.Add Compat based scripts revolving around UnityCompatShims.cs, that will document our current API Compatibility changes in several files.
2.Add custom screenshot folder selection
2026-05-03 18:16:10 -04:00
Shutong Wu 6312ec2180 Update 2026-04-01 15:32:27 -04:00
Shutong Wu 88fc8f1d18 Update based on review 2026-04-01 15:15:40 -04:00
Shutong Wu fa0c6d123a Update with Roslyn as optional execute_code usage, and UX update 2026-04-01 14:21:09 -04:00
zaferdace d2847a960b fix: address review feedback from Sourcery and CodeRabbit
- Fix off-by-one in WrapperLineOffset (9 → 10)
- Cache resolved assembly paths in static field for performance
- Add encoding="utf-8" to CLI file read
- Add group="scripting_ext" to Python tool decorator

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 17:11:54 +01:00
zaferdace c18ee94da8 feat: add execute_code tool for running arbitrary C# in Unity Editor
Adds a built-in `execute_code` tool that compiles and runs C# code
inside the Unity Editor via CSharpCodeProvider. No external dependencies
(Roslyn not required), no script files created.

## Actions
- `execute` — compile and run C# method body, return result
- `get_history` — list past executions with previews
- `replay` — re-run a history entry with original settings
- `clear_history` — clear execution history

## Safety
- `safety_checks` (default: true) blocks known dangerous patterns
  (File.Delete, Process.Start, AssetDatabase.DeleteAsset, infinite loops)
- Clearly documented as pattern-based blocklist, NOT a security sandbox
- `destructiveHint=True` annotation for MCP clients

## Features
- In-memory compilation with all loaded assembly references
- User-friendly error line numbers (wrapper offset subtracted)
- Execution history (max 50 entries) with code preview truncation
- Replay preserves original safety_checks setting
- CLI commands: `code execute`, `code history`, `code replay`, `code clear-history`

## Files
- C#: `MCPForUnity/Editor/Tools/ExecuteCode.cs` (329 lines)
- Python: `Server/src/services/tools/execute_code.py` (85 lines)
- CLI: `Server/src/cli/commands/code.py` (+89 lines)
- Tests: `Server/tests/test_execute_code.py` (17 tests, all passing)
- Manifest: added `execute_code` entry

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 16:20:28 +01:00