unity-mcp/UnityMcpBridge/UnityMcpServer~/src/tools/manage_script.py

562 lines
27 KiB
Python
Raw Normal View History

from mcp.server.fastmcp import FastMCP, Context
Claude‑friendly edit tools + framed transport + live Unity NL test framework (#243) * CI: gate desktop-parity on Anthropic key; pass anthropic_api_key like NL suite * Add quickprobe prompt and CI workflow (mcp-quickprobe.md, unity-mcp-quickprobe.yml) * strictier tool use to prevent subagent spawning and force mcp tools * update workflow filesto reduce likelihood of subagent spawning * improve permissions for claude agent, fix mcpbridge timeout/token issue * increase max turns to 10 * ci: align NL suite to new permissions schema; prevent subagent drift * ci: NL suite -> mini prompt for e2e; add full NL/T prompt; server: ctx optional + project_root fallback; workflows: set UNITY_PROJECT_ROOT for CI * ci: add checks:write; revert local project hardcodes (manifest, ProjectVersion.txt) * tools: text-edit routing fixes (anchor_insert via text, CRLF calc); prompts: mini NL/T clarifications * ci: use absolute UNITY_PROJECT_ROOT; prompts target TestProjects; server: accept relative UNITY_PROJECT_ROOT and bare spec URI * ci: ignore Unity test project's packages-lock.json; remove from repo to avoid absolute paths * CI: start persistent Unity Editor for MCP (guarded by license) + allow batch-mode bridge via UNITY_MCP_ALLOW_BATCH * CI: hide license and pass via env to docker; fix invalid ref format * CI: readiness probe uses handshake on Unity MCP port (deterministic) * CI: fix YAML; use TCP handshake readiness probe (FRAMING=1) * CI: prime Unity license via game-ci; mount ULF into container; extend readiness timeout * CI: use ULF write + mount for Unity licensing; remove serial/email/pass from container * CI: entitlement activation (UNITY_SERIAL=''); verify host ULF cache; keep mount * CI: write ULF from secret and verify; drop entitlement activation step * CI: detect any licensing path; GameCI prime; status dir env; log+probe readiness; fix YAML * CI: add GameCI license prime; conditional ULF write; one-shot license validation; explicit status dir + license env * CI: fix YAML (inline python), add Anthropic key detect via GITHUB_ENV; ready to run happy path * CI: mount Unity token/ulf/cache dirs into container to share host license; create dirs before start * CI: fix YAML indentation; write ULF on host; activate in container with shared mounts; mount .config and .cache too * CI: gate Claude via outputs; mount all Unity license dirs; fix inline probe python; stabilize licensing flow * CI: normalize detect to step outputs; ensure license dirs mounted and validated; fix indentation * Bridge: honor UNITY_MCP_STATUS_DIR for heartbeat/status file (CI-friendly) * CI: guard project path for activation/start; align tool allowlist; run MCP server with python; tighten secret scoping * CI: finalize Unity licensing mounts + status dir; mode-detect (ULF/EBL); readiness logs+probe; Claude gating via outputs * CI: fix YAML probe (inline python -c) and finalize happy-path Unity licensing and MCP/Claude wiring * CI: inline python probe; unify Unity image and cache mounts; ready to test * CI: fix docker run IMAGE placement; ignore cache find perms; keep same editor image * CI: pass -manualLicenseFile to persistent Editor; keep mounts and single image * CI: mount full GameCI cache to /root in persistent Unity; set HOME=/root; add optional license check * CI: make -manualLicenseFile conditional; keep full /root mount and license check * CI: set HOME=/github/home; mount GameCI cache there; adjust manualLicenseFile path; expand license check * CI: EBL sign-in for persistent Unity (email/password/serial); revert HOME=/root and full /root mount; keep conditional manualLicenseFile and improved readiness * CI: run full NL/T suite prompt (nl-unity-suite-full.md) instead of mini * NL/T: require unified diffs + explicit verdicts in JUnit; CI: remove short sanity step, publish JUnit, upload artifacts * NL/T prompt: require CDATA wrapping for JUnit XML fields; guidance for splitting embedded ]]>; keep VERDICT in CDATA only * CI: remove in-container license check step; keep readiness and full suite * NL/T prompt: add version header, stricter JUnit schema, hashing/normalization, anchors, statuses, atomic semantics, tool logging * CI: increase Claude NL/T suite timeout to 30 minutes * CI: pre-create reports dir and result files to avoid tool approval prompts * CI: skip wait if container not running; skip Editor start if project missing; broaden MCP deps detection; expand allowed tools * fixies to harden ManageScript * CI: sanitize NL/T markdown report to avoid NUL/encoding issues * revert breaking yyaml changes * CI: prime license, robust Unity start/wait, sanitize markdown via heredoc * Resolve merge: accept upstream renames/installer (fix/installer-cleanup-v2) and keep local framing/script-editing - Restored upstream server.py, EditorWindow, uv.lock\n- Preserved ManageScript editing/validation; switched to atomic write + debounced refresh\n- Updated tools/__init__.py to keep script_edits/resources and adopt new logger name\n- All Python tests via uv: 7 passed, 6 skipped, 9 xpassed; Unity compile OK * Fix Claude Desktop config path and atomic write issues - Fix macOS path for Claude Desktop config: use ~/Library/Application Support/Claude/ instead of ~/.config/Claude/ - Improve atomic write pattern with backup/restore safety - Replace File.Replace() with File.Move() for better macOS compatibility - Add proper error handling and cleanup for file operations - Resolves issue where installer couldn't find Claude Desktop config on macOS * Editor: use macConfigPath on macOS for MCP client config writes (Claude Desktop, etc.). Fallback to linuxConfigPath only if mac path missing. * Models: add macConfigPath to McpClient for macOS config path selection (fixes CS1061 in editor window). * Editor: on macOS, prefer macConfigPath in ManualConfigEditorWindow (fallback to linux path); Linux/Windows unchanged. * Fix McpClient: align with upstream/main, prep for framing split * NL suite: shard workflow; tighten bridge readiness; add MCP preflight; use env-based shard vars * NL suite: fix shard step indentation; move shard vars to env; remove invalid inputs * MCP clients: split VSCode Copilot config paths into macConfigPath and linuxConfigPath * Unity bridge: clean stale status; bind host; robust wait probe with IPv4/IPv6 + diagnostics * CI: use MCPForUnity.Editor.MCPForUnityBridge.StartAutoConnect as executeMethod * Action wiring: inline mcpServers in settings for all shards; remove redundant .claude/mcp.json step * CI: embed mcpServers in settings for all shards; fix startup sanity step; lint clean * CI: pin claude-code-base-action to e6f32c8; use claude_args --mcp-config; switch to allowed_tools; ensure MCP config per step * CI: unpin claude-code-base-action to @beta (commit ref not found) * CI: align with claude-code-base-action @beta; pass MCP via claude_args and allowedTools * Editor: Fix apply_text_edits heuristic when edits shift positions; recompute method span on candidate text with fallback delta adjustment * CI: unify MCP wiring across workflows; write .claude/mcp.json; switch to claude_args with --mcp-config/--allowedTools; remove unsupported inputs * CI: collapse NL suite shards into a single run to avoid repeated test execution * CI: minimize allowedTools for NL suite to essential Unity MCP + Bash("git:*") + Write * CI: mkdir -p reports before run; remove unsupported --timeout-minutes from claude_args * CI: broaden allowedTools to include find_in_file and mcp__unity__* * CI: enable use_node_cache and switch NL suite model to claude-3-7-haiku-20250219 * CI: disable use_node_cache to avoid setup-node lockfile error * CI: set NL suite model to claude-3-haiku-20240307 * CI: cap Haiku output with --max-tokens 2048 for NL suite * CI: switch to claude-3-7-sonnet-latest and remove unsupported --max-tokens * CI: update allowedTools to Bash(*) and explicit Unity MCP tool list * CI: update NL suite workflow (latest tweaks) * Tests: tighten NL suite prompt for logging, hash discipline, stale retry, evidence windows, diff cap, and VERDICT line * Add disallowed tools to NL suite workflow * docs: clarify stale write retry * Add fallback JUnit report and adjust publisher * Indent fallback JUnit XML in workflow * fix: correct fallback JUnit report generation * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update Response.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update MCPForUnityBridge.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: correct McpTypes reference * Add directory existence checks for symlink and XDG paths * fix: only set installation flag after successful server install * Update resource_tools.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: respect mac config paths * Use File.Replace for atomic config write * Remove unused imports in manage_script * bump server version * Tests: update NL suite prompt and workflows; remove deprecated smoke/desktop-parity; quickprobe tidy * Editor: atomic config write via File.Replace fallback; remove redundant backups and racey exists checks * CI: harden NL suite - idempotent docker, gate on unity_ok, safer port probe, least-priv perms * Editor: make atomic config write restoration safe (flag writeDone; copy-overwrite restore; cleanup in finally) * CI: fix fallback JUnit heredoc by using printf lines (no EOF delimiter issues) * CI: switch NL suite to mini prompt; mini prompt honors / and NL discipline * CI: replace claude_args with allowed_tools/model/mcp_config per action schema * CI: expand UNITY_PROJECT_ROOT via in MCP config heredoc * EditorWindow: add cross-platform fallback for File.Replace; macOS-insensitive PathsEqual; safer uv resolve; honor macConfigPath * CI: strengthen JUnit publishing for NL mini suite (normalize, debug list, publish both, fail_on_parse_error) * CI: set job-wide JUNIT_OUT/MD_OUT; normalization uses env; publish references env and ungroup reports * CI: publish a single normalized JUnit (reports/junit-for-actions.xml); fallback writes same; avoid checkName/reportPaths mismatch * CI: align mini prompt report filenames; redact Unity log tail in diagnostics * chore: sync workflow and mini prompt; redacted logs; JUnit normalization/publish tweaks * CI: redact sensitive tokens in Stop Unity; docs: CI usage + edit tools * prompts: update nl-unity-suite-full (mini-style setup + reporting discipline); remove obsolete prompts * CI: harden NL workflows (timeout_minutes, robust normalization); prompts: unify JUnit suite name and reporting discipline * prompts: add guarded write pattern (LF hash, stale_file retry) to full suite * prompts: enforce continue-on-failure, driver flow, and status handling in full suite * Make test list more explicit in prompt. Get rid of old test prompts for hygeine. * prompts: add stale fast-retry (server hash) + in-memory buf guidance * CI: standardize JUNIT_OUT to reports/junit-nl-suite.xml; fix artifact upload indentation; prompt copy cleanups * prompts: reporting discipline — append-only fragments, batch writes, no model round-trip * prompts: stale fast-retry preference, buffer/sha carry, snapshot revert, essential logging * workflows(nl-suite): precreate report skeletons, assemble junit, synthesize markdown; restrict allowed_tools to append-only Bash + MCP tools * thsis too * Update README-DEV.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite-mini.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * workflows(nl-mini): fix YAML indentation/trailing spaces under with: and cleanup heredoc spacing * workflows(nl-suite): fix indentation on docker logs redaction line (YAML lint) * Add write to allowlist * nl-suite: harden reporting discipline (fragment-only writes, forbid alt paths); workflow: clean stray junit-*updated*.xml * nl-suite: enforce end-of-suite single Write (no bash redirection); workflow: restrict allowed_tools to Write+MCP only * prompts(nl-full): end-of-suite results must be valid XML with single <cases> root and only <testcase> children; no raw text outside CDATA * workflows(nl-suite): make Claude step non-fatal; tolerant normalizer extracts <testcase> via regex on bad fragments * nl-suite: fix stale classname to UnityMCP.NL-T in mini fallback; prompt: require re-read after every revert; correct PLAN/PROGRESS to 15 * nl-suite: fix fallback JUnit classname to UnityMCP.NL-T; prompt: forbid create_script and env/mkdir checks, enforce single baseline-byte revert flow and post-revert re-read; add corruption-handling guidance * prompts(nl-full): after each write re-read raw bytes to refresh pre_sha; prefer script_apply_edits for anchors; avoid header/using changes * prompts(nl-full): canonicalize outputs to /; allow small fragment appends via Write or Bash(printf/echo); forbid wrappers and full-file round-trips * prompts(nl-full): finalize markdown formatting for guarded write, execution order, specs, status * workflows(nl-suite, mini): header/lint fixes and constrained Bash append path; align allowed_tools * prompts(nl-full): format Fast Restore, Guarded Write, Execution, Specs, Status as proper markdown lists and code fences * workflows(nl-suite): keep header tidy and append-path alignment with prompt * minor fix * workflows(nl-suite): fix indentation and dispatch; align allowed_tools and revert helper * prompts(nl-full): switch to read_resource for buf/sha; re-read only when needed; convert 'Print this once' to heading; note snapshot helper creates parent dirs * workflows(nl-suite): normalize step removes bootstrap when real testcases present; recompute tests/failures * workflows(nl-suite): enrich Markdown summary by extracting per-test <system-out> blocks (truncated) * clarify prompt resilience instructions * ci(nl-suite): revert prompt and workflow to known-good e0f8a72 for green run; remove extra MD details * ci(nl-suite): minimal fixes — no-mkdir guard in prompt; drop bootstrap and recompute JUnit counts * ci(nl-suite): richer JUnit→Markdown report (per-test system-out) * Small guard to incorret asset read call. * ci(nl-suite): refine MD builder — unescape XML entities, safe code fences, PASS/FAIL badges * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * server(manage_script): robust URI handling — percent-decode file://, normalize, strip host/leading slashes, return Assets-relative if present * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * tests(framing): reduce handshake poll window, nonblocking peek to avoid disconnect race; still enforce pre-handshake data drop * tests(manage_script): add _split_uri tests for unity://path, file:// URLs (decoded/Assets-relative), and plain paths * server+tests: fix handshake syntax error; robust file:// URI normalization in manage_script; add _split_uri tests; adjust stdout scan to ignore venv/site-packages * bridge(framing): accept zero-length frames (treat as empty keepalive) * tests(logging): use errors='replace' on decode fallback to avoid silent drops * resources(list): restrict to Assets/, resolve symlinks, enforce .cs; add traversal/outside-path tests * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * misc: framing keepalive (zero-length), regex preview consistency, resource.list hardening, URI parsing, legacy update routing, test cleanups * docs(tools): richer MCP tool descriptions; tests accept decorator kwargs; resource URI parsing hardened * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * net+docs: hard-reject zero-length frames; TCP_NODELAY on connect; Assets detection case-insensitive; NL prompt statuses aligned * prompt(nl-suite): constrain Write destinations under reports/, forbid traversal * prompt+net: harden Write path rules; use monotonic deadline and plain-text advisory for non-framed peers * unity_connection: restore recv timeout via try/finally; make global connection getter thread-safe with module lock and double-checked init * NL/T prompt: pin structured edit ops for T-D/T-E; add schema-error guarded write behavior; keep existing path/URI and revert rules * unity_connection: add FRAMED_MAX; use ValueError for framed length violations; lower framed receive log to debug; serialize connect() with per-instance lock * ManageScript: use UTF8Encoding(without BOM) for atomic writes in ApplyTextEdits/EditScript to align with Create/Update and avoid BOM-related diffs/hash mismatches * NL/T prompt: make helper deletion regex multiline-safe ((?ms) so ^ anchors line starts) * ManageScript: emit structured overlap status {status:"overlap"} for overlapping edit ranges in apply_text_edits and edit paths * NL/T prompt: clarify fallback vs failure — fallback only for unsupported/missing_field; treat bad_request as failure; note unsupported after fallback as failure * NL/T prompt: pin deterministic overlap probe (apply_text_edits two ranges from same snapshot); gate too_large behind RUN_TOO_LARGE env hint * TB update * NL/T prompt: harden Output Rules — constrain Bash(printf|echo) to stdout-only; forbid redirection/here-docs/tee; only scripts/nlt-revert.sh may mutate FS * Prompt: enumerate allowed script_apply_edits ops; add manage_editor/read_console guidance; fix T‑F atomic batch to single script_apply_edits. ManageScript: regex timeout for diagnostics; symlink ancestor guard; complete allowed-modes list. * Fixes * ManageScript: add rich overlap diagnostics (conflicts + hint) for both text range and structured batch paths * ManageScript: return structured {status:"validation_failed"} diagnostics in create/update/edits and validate before commit * ManageScript: echo canonical uri in responses (create/read/update/apply_text_edits/structured edits) to reinforce resource identity * improve clarity of capabilities message * Framing: allow zero-length frames on both ends (C# bridge, Python server). Prompt: harden T-F to single text-range apply_text_edits batch (descending order, one snapshot). URI: normalize file:// outside Assets by stripping leading slash. * ManageScript: include new sha256 in success payload for apply_text_edits; harden TryResolveUnderAssets by rejecting symlinked ancestors up to Assets/. * remove claudetest dir * manage_script_edits: normalize method-anchored anchor_insert to insert_method (map text->replacement); improves CI compatibility for T‑A/T‑E without changing Editor behavior. * tighten testing protocol around mkdir * manage_script: validate create_script inputs (Assets/.cs/name/no traversal); add Assets/ guard to delete_script; validate level+Assets in validate_script; make legacy manage_script optional params; harden legacy update routing with base64 reuse and payload size preflight. * Tighten prompt for testing * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script_edits: honor ignore_case on anchor_insert and regex_replace in both direct and text-conversion paths (MULTILINE|IGNORECASE). * remove extra file * workflow: use python3 for inline scripts and port detection on ubuntu-latest. * Tighten prompt + manage_script * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script: improve file:// UNC handling; preserve POSIX absolute semantics internally; keep test-expected slash stripping for non-Assets paths. * ManageScript.cs: add TimeSpan timeouts to all Regex uses (IsMatch/Match/new Regex) and keep CultureInvariant/Multiline options; reduces risk of catastrophic backtracking stalls. * workflow: ensure reports/ exists in markdown build step to avoid FileNotFoundError when writing MD_OUT. * fix brace * manage_script_edits: expand backrefs for regex_replace in preview->text conversion and translate to \g<n> in local apply; keeps previews and actual edits consistent. * anchor_insert: default to position=after, normalize surrounding newlines in Python conversion paths; C# path ensures trailing newline and skips duplicate insertion within class. * feat(mcp): add get_sha tool; apply_text_edits normalization+overlap preflight+strict; no-op evidence in C#; update NL suite prompt; add unit tests * feat(frames): accept zero-length heartbeat frames in client; add heartbeat test * feat(edits): guard destructive regex_replace with structural preflight; add robust tests; prompt uses delete_method for temp helper * feat(frames): bound heartbeat loop with timeout/threshold; align zero-length response with C#; update test * SDK hardening: atomic multi-span text edits; stop forcing sequential for structured ops; forward options on apply_text_edits; add validate=relaxed support and scoped checks; update NL/T prompt; add tests for options forwarding, relaxed mode, and atomic batches * Router: default applyMode=atomic for multi-span apply_text_edits; add tests * CI prompt: pass options.validate=relaxed for T-B/C; options.applyMode=atomic for T-F; emphasize always writing testcase and restoring on errors * Validation & DX: add validate=syntax (scoped), standardize evidence windows; early regex compile with hints; debug_preview for apply_text_edits * Update UnityMcpBridge/Editor/Windows/MCPForUnityEditorWindow.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * NL/T suite-driven edits: LongUnityScriptClaudeTest, bridge helpers, server_version; prepare framing tests * Fix duplicate macConfigPath field in McpClient to resolve CS0102 * Editor threading: run EnsureServerInstalled on main thread; marshal EditorPrefs/DeleteKey + logging via delayCall * Docs(apply_text_edits): strengthen guidance on 1-based positions, verify-before-edit, and recommend anchors/structured edits * Docs(script_apply_edits): add safety guidance (anchors, method ops, validators) and recommended practices * Framed VerifyBridgePing in editor window; docs hardening for apply_text_edits and script_apply_edits --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-31 00:55:38 +08:00
from typing import Dict, Any, List
from unity_connection import send_command_with_retry
import base64
Claude‑friendly edit tools + framed transport + live Unity NL test framework (#243) * CI: gate desktop-parity on Anthropic key; pass anthropic_api_key like NL suite * Add quickprobe prompt and CI workflow (mcp-quickprobe.md, unity-mcp-quickprobe.yml) * strictier tool use to prevent subagent spawning and force mcp tools * update workflow filesto reduce likelihood of subagent spawning * improve permissions for claude agent, fix mcpbridge timeout/token issue * increase max turns to 10 * ci: align NL suite to new permissions schema; prevent subagent drift * ci: NL suite -> mini prompt for e2e; add full NL/T prompt; server: ctx optional + project_root fallback; workflows: set UNITY_PROJECT_ROOT for CI * ci: add checks:write; revert local project hardcodes (manifest, ProjectVersion.txt) * tools: text-edit routing fixes (anchor_insert via text, CRLF calc); prompts: mini NL/T clarifications * ci: use absolute UNITY_PROJECT_ROOT; prompts target TestProjects; server: accept relative UNITY_PROJECT_ROOT and bare spec URI * ci: ignore Unity test project's packages-lock.json; remove from repo to avoid absolute paths * CI: start persistent Unity Editor for MCP (guarded by license) + allow batch-mode bridge via UNITY_MCP_ALLOW_BATCH * CI: hide license and pass via env to docker; fix invalid ref format * CI: readiness probe uses handshake on Unity MCP port (deterministic) * CI: fix YAML; use TCP handshake readiness probe (FRAMING=1) * CI: prime Unity license via game-ci; mount ULF into container; extend readiness timeout * CI: use ULF write + mount for Unity licensing; remove serial/email/pass from container * CI: entitlement activation (UNITY_SERIAL=''); verify host ULF cache; keep mount * CI: write ULF from secret and verify; drop entitlement activation step * CI: detect any licensing path; GameCI prime; status dir env; log+probe readiness; fix YAML * CI: add GameCI license prime; conditional ULF write; one-shot license validation; explicit status dir + license env * CI: fix YAML (inline python), add Anthropic key detect via GITHUB_ENV; ready to run happy path * CI: mount Unity token/ulf/cache dirs into container to share host license; create dirs before start * CI: fix YAML indentation; write ULF on host; activate in container with shared mounts; mount .config and .cache too * CI: gate Claude via outputs; mount all Unity license dirs; fix inline probe python; stabilize licensing flow * CI: normalize detect to step outputs; ensure license dirs mounted and validated; fix indentation * Bridge: honor UNITY_MCP_STATUS_DIR for heartbeat/status file (CI-friendly) * CI: guard project path for activation/start; align tool allowlist; run MCP server with python; tighten secret scoping * CI: finalize Unity licensing mounts + status dir; mode-detect (ULF/EBL); readiness logs+probe; Claude gating via outputs * CI: fix YAML probe (inline python -c) and finalize happy-path Unity licensing and MCP/Claude wiring * CI: inline python probe; unify Unity image and cache mounts; ready to test * CI: fix docker run IMAGE placement; ignore cache find perms; keep same editor image * CI: pass -manualLicenseFile to persistent Editor; keep mounts and single image * CI: mount full GameCI cache to /root in persistent Unity; set HOME=/root; add optional license check * CI: make -manualLicenseFile conditional; keep full /root mount and license check * CI: set HOME=/github/home; mount GameCI cache there; adjust manualLicenseFile path; expand license check * CI: EBL sign-in for persistent Unity (email/password/serial); revert HOME=/root and full /root mount; keep conditional manualLicenseFile and improved readiness * CI: run full NL/T suite prompt (nl-unity-suite-full.md) instead of mini * NL/T: require unified diffs + explicit verdicts in JUnit; CI: remove short sanity step, publish JUnit, upload artifacts * NL/T prompt: require CDATA wrapping for JUnit XML fields; guidance for splitting embedded ]]>; keep VERDICT in CDATA only * CI: remove in-container license check step; keep readiness and full suite * NL/T prompt: add version header, stricter JUnit schema, hashing/normalization, anchors, statuses, atomic semantics, tool logging * CI: increase Claude NL/T suite timeout to 30 minutes * CI: pre-create reports dir and result files to avoid tool approval prompts * CI: skip wait if container not running; skip Editor start if project missing; broaden MCP deps detection; expand allowed tools * fixies to harden ManageScript * CI: sanitize NL/T markdown report to avoid NUL/encoding issues * revert breaking yyaml changes * CI: prime license, robust Unity start/wait, sanitize markdown via heredoc * Resolve merge: accept upstream renames/installer (fix/installer-cleanup-v2) and keep local framing/script-editing - Restored upstream server.py, EditorWindow, uv.lock\n- Preserved ManageScript editing/validation; switched to atomic write + debounced refresh\n- Updated tools/__init__.py to keep script_edits/resources and adopt new logger name\n- All Python tests via uv: 7 passed, 6 skipped, 9 xpassed; Unity compile OK * Fix Claude Desktop config path and atomic write issues - Fix macOS path for Claude Desktop config: use ~/Library/Application Support/Claude/ instead of ~/.config/Claude/ - Improve atomic write pattern with backup/restore safety - Replace File.Replace() with File.Move() for better macOS compatibility - Add proper error handling and cleanup for file operations - Resolves issue where installer couldn't find Claude Desktop config on macOS * Editor: use macConfigPath on macOS for MCP client config writes (Claude Desktop, etc.). Fallback to linuxConfigPath only if mac path missing. * Models: add macConfigPath to McpClient for macOS config path selection (fixes CS1061 in editor window). * Editor: on macOS, prefer macConfigPath in ManualConfigEditorWindow (fallback to linux path); Linux/Windows unchanged. * Fix McpClient: align with upstream/main, prep for framing split * NL suite: shard workflow; tighten bridge readiness; add MCP preflight; use env-based shard vars * NL suite: fix shard step indentation; move shard vars to env; remove invalid inputs * MCP clients: split VSCode Copilot config paths into macConfigPath and linuxConfigPath * Unity bridge: clean stale status; bind host; robust wait probe with IPv4/IPv6 + diagnostics * CI: use MCPForUnity.Editor.MCPForUnityBridge.StartAutoConnect as executeMethod * Action wiring: inline mcpServers in settings for all shards; remove redundant .claude/mcp.json step * CI: embed mcpServers in settings for all shards; fix startup sanity step; lint clean * CI: pin claude-code-base-action to e6f32c8; use claude_args --mcp-config; switch to allowed_tools; ensure MCP config per step * CI: unpin claude-code-base-action to @beta (commit ref not found) * CI: align with claude-code-base-action @beta; pass MCP via claude_args and allowedTools * Editor: Fix apply_text_edits heuristic when edits shift positions; recompute method span on candidate text with fallback delta adjustment * CI: unify MCP wiring across workflows; write .claude/mcp.json; switch to claude_args with --mcp-config/--allowedTools; remove unsupported inputs * CI: collapse NL suite shards into a single run to avoid repeated test execution * CI: minimize allowedTools for NL suite to essential Unity MCP + Bash("git:*") + Write * CI: mkdir -p reports before run; remove unsupported --timeout-minutes from claude_args * CI: broaden allowedTools to include find_in_file and mcp__unity__* * CI: enable use_node_cache and switch NL suite model to claude-3-7-haiku-20250219 * CI: disable use_node_cache to avoid setup-node lockfile error * CI: set NL suite model to claude-3-haiku-20240307 * CI: cap Haiku output with --max-tokens 2048 for NL suite * CI: switch to claude-3-7-sonnet-latest and remove unsupported --max-tokens * CI: update allowedTools to Bash(*) and explicit Unity MCP tool list * CI: update NL suite workflow (latest tweaks) * Tests: tighten NL suite prompt for logging, hash discipline, stale retry, evidence windows, diff cap, and VERDICT line * Add disallowed tools to NL suite workflow * docs: clarify stale write retry * Add fallback JUnit report and adjust publisher * Indent fallback JUnit XML in workflow * fix: correct fallback JUnit report generation * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update Response.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update MCPForUnityBridge.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: correct McpTypes reference * Add directory existence checks for symlink and XDG paths * fix: only set installation flag after successful server install * Update resource_tools.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: respect mac config paths * Use File.Replace for atomic config write * Remove unused imports in manage_script * bump server version * Tests: update NL suite prompt and workflows; remove deprecated smoke/desktop-parity; quickprobe tidy * Editor: atomic config write via File.Replace fallback; remove redundant backups and racey exists checks * CI: harden NL suite - idempotent docker, gate on unity_ok, safer port probe, least-priv perms * Editor: make atomic config write restoration safe (flag writeDone; copy-overwrite restore; cleanup in finally) * CI: fix fallback JUnit heredoc by using printf lines (no EOF delimiter issues) * CI: switch NL suite to mini prompt; mini prompt honors / and NL discipline * CI: replace claude_args with allowed_tools/model/mcp_config per action schema * CI: expand UNITY_PROJECT_ROOT via in MCP config heredoc * EditorWindow: add cross-platform fallback for File.Replace; macOS-insensitive PathsEqual; safer uv resolve; honor macConfigPath * CI: strengthen JUnit publishing for NL mini suite (normalize, debug list, publish both, fail_on_parse_error) * CI: set job-wide JUNIT_OUT/MD_OUT; normalization uses env; publish references env and ungroup reports * CI: publish a single normalized JUnit (reports/junit-for-actions.xml); fallback writes same; avoid checkName/reportPaths mismatch * CI: align mini prompt report filenames; redact Unity log tail in diagnostics * chore: sync workflow and mini prompt; redacted logs; JUnit normalization/publish tweaks * CI: redact sensitive tokens in Stop Unity; docs: CI usage + edit tools * prompts: update nl-unity-suite-full (mini-style setup + reporting discipline); remove obsolete prompts * CI: harden NL workflows (timeout_minutes, robust normalization); prompts: unify JUnit suite name and reporting discipline * prompts: add guarded write pattern (LF hash, stale_file retry) to full suite * prompts: enforce continue-on-failure, driver flow, and status handling in full suite * Make test list more explicit in prompt. Get rid of old test prompts for hygeine. * prompts: add stale fast-retry (server hash) + in-memory buf guidance * CI: standardize JUNIT_OUT to reports/junit-nl-suite.xml; fix artifact upload indentation; prompt copy cleanups * prompts: reporting discipline — append-only fragments, batch writes, no model round-trip * prompts: stale fast-retry preference, buffer/sha carry, snapshot revert, essential logging * workflows(nl-suite): precreate report skeletons, assemble junit, synthesize markdown; restrict allowed_tools to append-only Bash + MCP tools * thsis too * Update README-DEV.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite-mini.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * workflows(nl-mini): fix YAML indentation/trailing spaces under with: and cleanup heredoc spacing * workflows(nl-suite): fix indentation on docker logs redaction line (YAML lint) * Add write to allowlist * nl-suite: harden reporting discipline (fragment-only writes, forbid alt paths); workflow: clean stray junit-*updated*.xml * nl-suite: enforce end-of-suite single Write (no bash redirection); workflow: restrict allowed_tools to Write+MCP only * prompts(nl-full): end-of-suite results must be valid XML with single <cases> root and only <testcase> children; no raw text outside CDATA * workflows(nl-suite): make Claude step non-fatal; tolerant normalizer extracts <testcase> via regex on bad fragments * nl-suite: fix stale classname to UnityMCP.NL-T in mini fallback; prompt: require re-read after every revert; correct PLAN/PROGRESS to 15 * nl-suite: fix fallback JUnit classname to UnityMCP.NL-T; prompt: forbid create_script and env/mkdir checks, enforce single baseline-byte revert flow and post-revert re-read; add corruption-handling guidance * prompts(nl-full): after each write re-read raw bytes to refresh pre_sha; prefer script_apply_edits for anchors; avoid header/using changes * prompts(nl-full): canonicalize outputs to /; allow small fragment appends via Write or Bash(printf/echo); forbid wrappers and full-file round-trips * prompts(nl-full): finalize markdown formatting for guarded write, execution order, specs, status * workflows(nl-suite, mini): header/lint fixes and constrained Bash append path; align allowed_tools * prompts(nl-full): format Fast Restore, Guarded Write, Execution, Specs, Status as proper markdown lists and code fences * workflows(nl-suite): keep header tidy and append-path alignment with prompt * minor fix * workflows(nl-suite): fix indentation and dispatch; align allowed_tools and revert helper * prompts(nl-full): switch to read_resource for buf/sha; re-read only when needed; convert 'Print this once' to heading; note snapshot helper creates parent dirs * workflows(nl-suite): normalize step removes bootstrap when real testcases present; recompute tests/failures * workflows(nl-suite): enrich Markdown summary by extracting per-test <system-out> blocks (truncated) * clarify prompt resilience instructions * ci(nl-suite): revert prompt and workflow to known-good e0f8a72 for green run; remove extra MD details * ci(nl-suite): minimal fixes — no-mkdir guard in prompt; drop bootstrap and recompute JUnit counts * ci(nl-suite): richer JUnit→Markdown report (per-test system-out) * Small guard to incorret asset read call. * ci(nl-suite): refine MD builder — unescape XML entities, safe code fences, PASS/FAIL badges * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * server(manage_script): robust URI handling — percent-decode file://, normalize, strip host/leading slashes, return Assets-relative if present * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * tests(framing): reduce handshake poll window, nonblocking peek to avoid disconnect race; still enforce pre-handshake data drop * tests(manage_script): add _split_uri tests for unity://path, file:// URLs (decoded/Assets-relative), and plain paths * server+tests: fix handshake syntax error; robust file:// URI normalization in manage_script; add _split_uri tests; adjust stdout scan to ignore venv/site-packages * bridge(framing): accept zero-length frames (treat as empty keepalive) * tests(logging): use errors='replace' on decode fallback to avoid silent drops * resources(list): restrict to Assets/, resolve symlinks, enforce .cs; add traversal/outside-path tests * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * misc: framing keepalive (zero-length), regex preview consistency, resource.list hardening, URI parsing, legacy update routing, test cleanups * docs(tools): richer MCP tool descriptions; tests accept decorator kwargs; resource URI parsing hardened * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * net+docs: hard-reject zero-length frames; TCP_NODELAY on connect; Assets detection case-insensitive; NL prompt statuses aligned * prompt(nl-suite): constrain Write destinations under reports/, forbid traversal * prompt+net: harden Write path rules; use monotonic deadline and plain-text advisory for non-framed peers * unity_connection: restore recv timeout via try/finally; make global connection getter thread-safe with module lock and double-checked init * NL/T prompt: pin structured edit ops for T-D/T-E; add schema-error guarded write behavior; keep existing path/URI and revert rules * unity_connection: add FRAMED_MAX; use ValueError for framed length violations; lower framed receive log to debug; serialize connect() with per-instance lock * ManageScript: use UTF8Encoding(without BOM) for atomic writes in ApplyTextEdits/EditScript to align with Create/Update and avoid BOM-related diffs/hash mismatches * NL/T prompt: make helper deletion regex multiline-safe ((?ms) so ^ anchors line starts) * ManageScript: emit structured overlap status {status:"overlap"} for overlapping edit ranges in apply_text_edits and edit paths * NL/T prompt: clarify fallback vs failure — fallback only for unsupported/missing_field; treat bad_request as failure; note unsupported after fallback as failure * NL/T prompt: pin deterministic overlap probe (apply_text_edits two ranges from same snapshot); gate too_large behind RUN_TOO_LARGE env hint * TB update * NL/T prompt: harden Output Rules — constrain Bash(printf|echo) to stdout-only; forbid redirection/here-docs/tee; only scripts/nlt-revert.sh may mutate FS * Prompt: enumerate allowed script_apply_edits ops; add manage_editor/read_console guidance; fix T‑F atomic batch to single script_apply_edits. ManageScript: regex timeout for diagnostics; symlink ancestor guard; complete allowed-modes list. * Fixes * ManageScript: add rich overlap diagnostics (conflicts + hint) for both text range and structured batch paths * ManageScript: return structured {status:"validation_failed"} diagnostics in create/update/edits and validate before commit * ManageScript: echo canonical uri in responses (create/read/update/apply_text_edits/structured edits) to reinforce resource identity * improve clarity of capabilities message * Framing: allow zero-length frames on both ends (C# bridge, Python server). Prompt: harden T-F to single text-range apply_text_edits batch (descending order, one snapshot). URI: normalize file:// outside Assets by stripping leading slash. * ManageScript: include new sha256 in success payload for apply_text_edits; harden TryResolveUnderAssets by rejecting symlinked ancestors up to Assets/. * remove claudetest dir * manage_script_edits: normalize method-anchored anchor_insert to insert_method (map text->replacement); improves CI compatibility for T‑A/T‑E without changing Editor behavior. * tighten testing protocol around mkdir * manage_script: validate create_script inputs (Assets/.cs/name/no traversal); add Assets/ guard to delete_script; validate level+Assets in validate_script; make legacy manage_script optional params; harden legacy update routing with base64 reuse and payload size preflight. * Tighten prompt for testing * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script_edits: honor ignore_case on anchor_insert and regex_replace in both direct and text-conversion paths (MULTILINE|IGNORECASE). * remove extra file * workflow: use python3 for inline scripts and port detection on ubuntu-latest. * Tighten prompt + manage_script * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script: improve file:// UNC handling; preserve POSIX absolute semantics internally; keep test-expected slash stripping for non-Assets paths. * ManageScript.cs: add TimeSpan timeouts to all Regex uses (IsMatch/Match/new Regex) and keep CultureInvariant/Multiline options; reduces risk of catastrophic backtracking stalls. * workflow: ensure reports/ exists in markdown build step to avoid FileNotFoundError when writing MD_OUT. * fix brace * manage_script_edits: expand backrefs for regex_replace in preview->text conversion and translate to \g<n> in local apply; keeps previews and actual edits consistent. * anchor_insert: default to position=after, normalize surrounding newlines in Python conversion paths; C# path ensures trailing newline and skips duplicate insertion within class. * feat(mcp): add get_sha tool; apply_text_edits normalization+overlap preflight+strict; no-op evidence in C#; update NL suite prompt; add unit tests * feat(frames): accept zero-length heartbeat frames in client; add heartbeat test * feat(edits): guard destructive regex_replace with structural preflight; add robust tests; prompt uses delete_method for temp helper * feat(frames): bound heartbeat loop with timeout/threshold; align zero-length response with C#; update test * SDK hardening: atomic multi-span text edits; stop forcing sequential for structured ops; forward options on apply_text_edits; add validate=relaxed support and scoped checks; update NL/T prompt; add tests for options forwarding, relaxed mode, and atomic batches * Router: default applyMode=atomic for multi-span apply_text_edits; add tests * CI prompt: pass options.validate=relaxed for T-B/C; options.applyMode=atomic for T-F; emphasize always writing testcase and restoring on errors * Validation & DX: add validate=syntax (scoped), standardize evidence windows; early regex compile with hints; debug_preview for apply_text_edits * Update UnityMcpBridge/Editor/Windows/MCPForUnityEditorWindow.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * NL/T suite-driven edits: LongUnityScriptClaudeTest, bridge helpers, server_version; prepare framing tests * Fix duplicate macConfigPath field in McpClient to resolve CS0102 * Editor threading: run EnsureServerInstalled on main thread; marshal EditorPrefs/DeleteKey + logging via delayCall * Docs(apply_text_edits): strengthen guidance on 1-based positions, verify-before-edit, and recommend anchors/structured edits * Docs(script_apply_edits): add safety guidance (anchors, method ops, validators) and recommended practices * Framed VerifyBridgePing in editor window; docs hardening for apply_text_edits and script_apply_edits --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-31 00:55:38 +08:00
import os
from urllib.parse import urlparse, unquote
def register_manage_script_tools(mcp: FastMCP):
"""Register all script management tools with the MCP server."""
Claude‑friendly edit tools + framed transport + live Unity NL test framework (#243) * CI: gate desktop-parity on Anthropic key; pass anthropic_api_key like NL suite * Add quickprobe prompt and CI workflow (mcp-quickprobe.md, unity-mcp-quickprobe.yml) * strictier tool use to prevent subagent spawning and force mcp tools * update workflow filesto reduce likelihood of subagent spawning * improve permissions for claude agent, fix mcpbridge timeout/token issue * increase max turns to 10 * ci: align NL suite to new permissions schema; prevent subagent drift * ci: NL suite -> mini prompt for e2e; add full NL/T prompt; server: ctx optional + project_root fallback; workflows: set UNITY_PROJECT_ROOT for CI * ci: add checks:write; revert local project hardcodes (manifest, ProjectVersion.txt) * tools: text-edit routing fixes (anchor_insert via text, CRLF calc); prompts: mini NL/T clarifications * ci: use absolute UNITY_PROJECT_ROOT; prompts target TestProjects; server: accept relative UNITY_PROJECT_ROOT and bare spec URI * ci: ignore Unity test project's packages-lock.json; remove from repo to avoid absolute paths * CI: start persistent Unity Editor for MCP (guarded by license) + allow batch-mode bridge via UNITY_MCP_ALLOW_BATCH * CI: hide license and pass via env to docker; fix invalid ref format * CI: readiness probe uses handshake on Unity MCP port (deterministic) * CI: fix YAML; use TCP handshake readiness probe (FRAMING=1) * CI: prime Unity license via game-ci; mount ULF into container; extend readiness timeout * CI: use ULF write + mount for Unity licensing; remove serial/email/pass from container * CI: entitlement activation (UNITY_SERIAL=''); verify host ULF cache; keep mount * CI: write ULF from secret and verify; drop entitlement activation step * CI: detect any licensing path; GameCI prime; status dir env; log+probe readiness; fix YAML * CI: add GameCI license prime; conditional ULF write; one-shot license validation; explicit status dir + license env * CI: fix YAML (inline python), add Anthropic key detect via GITHUB_ENV; ready to run happy path * CI: mount Unity token/ulf/cache dirs into container to share host license; create dirs before start * CI: fix YAML indentation; write ULF on host; activate in container with shared mounts; mount .config and .cache too * CI: gate Claude via outputs; mount all Unity license dirs; fix inline probe python; stabilize licensing flow * CI: normalize detect to step outputs; ensure license dirs mounted and validated; fix indentation * Bridge: honor UNITY_MCP_STATUS_DIR for heartbeat/status file (CI-friendly) * CI: guard project path for activation/start; align tool allowlist; run MCP server with python; tighten secret scoping * CI: finalize Unity licensing mounts + status dir; mode-detect (ULF/EBL); readiness logs+probe; Claude gating via outputs * CI: fix YAML probe (inline python -c) and finalize happy-path Unity licensing and MCP/Claude wiring * CI: inline python probe; unify Unity image and cache mounts; ready to test * CI: fix docker run IMAGE placement; ignore cache find perms; keep same editor image * CI: pass -manualLicenseFile to persistent Editor; keep mounts and single image * CI: mount full GameCI cache to /root in persistent Unity; set HOME=/root; add optional license check * CI: make -manualLicenseFile conditional; keep full /root mount and license check * CI: set HOME=/github/home; mount GameCI cache there; adjust manualLicenseFile path; expand license check * CI: EBL sign-in for persistent Unity (email/password/serial); revert HOME=/root and full /root mount; keep conditional manualLicenseFile and improved readiness * CI: run full NL/T suite prompt (nl-unity-suite-full.md) instead of mini * NL/T: require unified diffs + explicit verdicts in JUnit; CI: remove short sanity step, publish JUnit, upload artifacts * NL/T prompt: require CDATA wrapping for JUnit XML fields; guidance for splitting embedded ]]>; keep VERDICT in CDATA only * CI: remove in-container license check step; keep readiness and full suite * NL/T prompt: add version header, stricter JUnit schema, hashing/normalization, anchors, statuses, atomic semantics, tool logging * CI: increase Claude NL/T suite timeout to 30 minutes * CI: pre-create reports dir and result files to avoid tool approval prompts * CI: skip wait if container not running; skip Editor start if project missing; broaden MCP deps detection; expand allowed tools * fixies to harden ManageScript * CI: sanitize NL/T markdown report to avoid NUL/encoding issues * revert breaking yyaml changes * CI: prime license, robust Unity start/wait, sanitize markdown via heredoc * Resolve merge: accept upstream renames/installer (fix/installer-cleanup-v2) and keep local framing/script-editing - Restored upstream server.py, EditorWindow, uv.lock\n- Preserved ManageScript editing/validation; switched to atomic write + debounced refresh\n- Updated tools/__init__.py to keep script_edits/resources and adopt new logger name\n- All Python tests via uv: 7 passed, 6 skipped, 9 xpassed; Unity compile OK * Fix Claude Desktop config path and atomic write issues - Fix macOS path for Claude Desktop config: use ~/Library/Application Support/Claude/ instead of ~/.config/Claude/ - Improve atomic write pattern with backup/restore safety - Replace File.Replace() with File.Move() for better macOS compatibility - Add proper error handling and cleanup for file operations - Resolves issue where installer couldn't find Claude Desktop config on macOS * Editor: use macConfigPath on macOS for MCP client config writes (Claude Desktop, etc.). Fallback to linuxConfigPath only if mac path missing. * Models: add macConfigPath to McpClient for macOS config path selection (fixes CS1061 in editor window). * Editor: on macOS, prefer macConfigPath in ManualConfigEditorWindow (fallback to linux path); Linux/Windows unchanged. * Fix McpClient: align with upstream/main, prep for framing split * NL suite: shard workflow; tighten bridge readiness; add MCP preflight; use env-based shard vars * NL suite: fix shard step indentation; move shard vars to env; remove invalid inputs * MCP clients: split VSCode Copilot config paths into macConfigPath and linuxConfigPath * Unity bridge: clean stale status; bind host; robust wait probe with IPv4/IPv6 + diagnostics * CI: use MCPForUnity.Editor.MCPForUnityBridge.StartAutoConnect as executeMethod * Action wiring: inline mcpServers in settings for all shards; remove redundant .claude/mcp.json step * CI: embed mcpServers in settings for all shards; fix startup sanity step; lint clean * CI: pin claude-code-base-action to e6f32c8; use claude_args --mcp-config; switch to allowed_tools; ensure MCP config per step * CI: unpin claude-code-base-action to @beta (commit ref not found) * CI: align with claude-code-base-action @beta; pass MCP via claude_args and allowedTools * Editor: Fix apply_text_edits heuristic when edits shift positions; recompute method span on candidate text with fallback delta adjustment * CI: unify MCP wiring across workflows; write .claude/mcp.json; switch to claude_args with --mcp-config/--allowedTools; remove unsupported inputs * CI: collapse NL suite shards into a single run to avoid repeated test execution * CI: minimize allowedTools for NL suite to essential Unity MCP + Bash("git:*") + Write * CI: mkdir -p reports before run; remove unsupported --timeout-minutes from claude_args * CI: broaden allowedTools to include find_in_file and mcp__unity__* * CI: enable use_node_cache and switch NL suite model to claude-3-7-haiku-20250219 * CI: disable use_node_cache to avoid setup-node lockfile error * CI: set NL suite model to claude-3-haiku-20240307 * CI: cap Haiku output with --max-tokens 2048 for NL suite * CI: switch to claude-3-7-sonnet-latest and remove unsupported --max-tokens * CI: update allowedTools to Bash(*) and explicit Unity MCP tool list * CI: update NL suite workflow (latest tweaks) * Tests: tighten NL suite prompt for logging, hash discipline, stale retry, evidence windows, diff cap, and VERDICT line * Add disallowed tools to NL suite workflow * docs: clarify stale write retry * Add fallback JUnit report and adjust publisher * Indent fallback JUnit XML in workflow * fix: correct fallback JUnit report generation * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update Response.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update MCPForUnityBridge.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: correct McpTypes reference * Add directory existence checks for symlink and XDG paths * fix: only set installation flag after successful server install * Update resource_tools.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: respect mac config paths * Use File.Replace for atomic config write * Remove unused imports in manage_script * bump server version * Tests: update NL suite prompt and workflows; remove deprecated smoke/desktop-parity; quickprobe tidy * Editor: atomic config write via File.Replace fallback; remove redundant backups and racey exists checks * CI: harden NL suite - idempotent docker, gate on unity_ok, safer port probe, least-priv perms * Editor: make atomic config write restoration safe (flag writeDone; copy-overwrite restore; cleanup in finally) * CI: fix fallback JUnit heredoc by using printf lines (no EOF delimiter issues) * CI: switch NL suite to mini prompt; mini prompt honors / and NL discipline * CI: replace claude_args with allowed_tools/model/mcp_config per action schema * CI: expand UNITY_PROJECT_ROOT via in MCP config heredoc * EditorWindow: add cross-platform fallback for File.Replace; macOS-insensitive PathsEqual; safer uv resolve; honor macConfigPath * CI: strengthen JUnit publishing for NL mini suite (normalize, debug list, publish both, fail_on_parse_error) * CI: set job-wide JUNIT_OUT/MD_OUT; normalization uses env; publish references env and ungroup reports * CI: publish a single normalized JUnit (reports/junit-for-actions.xml); fallback writes same; avoid checkName/reportPaths mismatch * CI: align mini prompt report filenames; redact Unity log tail in diagnostics * chore: sync workflow and mini prompt; redacted logs; JUnit normalization/publish tweaks * CI: redact sensitive tokens in Stop Unity; docs: CI usage + edit tools * prompts: update nl-unity-suite-full (mini-style setup + reporting discipline); remove obsolete prompts * CI: harden NL workflows (timeout_minutes, robust normalization); prompts: unify JUnit suite name and reporting discipline * prompts: add guarded write pattern (LF hash, stale_file retry) to full suite * prompts: enforce continue-on-failure, driver flow, and status handling in full suite * Make test list more explicit in prompt. Get rid of old test prompts for hygeine. * prompts: add stale fast-retry (server hash) + in-memory buf guidance * CI: standardize JUNIT_OUT to reports/junit-nl-suite.xml; fix artifact upload indentation; prompt copy cleanups * prompts: reporting discipline — append-only fragments, batch writes, no model round-trip * prompts: stale fast-retry preference, buffer/sha carry, snapshot revert, essential logging * workflows(nl-suite): precreate report skeletons, assemble junit, synthesize markdown; restrict allowed_tools to append-only Bash + MCP tools * thsis too * Update README-DEV.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite-mini.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * workflows(nl-mini): fix YAML indentation/trailing spaces under with: and cleanup heredoc spacing * workflows(nl-suite): fix indentation on docker logs redaction line (YAML lint) * Add write to allowlist * nl-suite: harden reporting discipline (fragment-only writes, forbid alt paths); workflow: clean stray junit-*updated*.xml * nl-suite: enforce end-of-suite single Write (no bash redirection); workflow: restrict allowed_tools to Write+MCP only * prompts(nl-full): end-of-suite results must be valid XML with single <cases> root and only <testcase> children; no raw text outside CDATA * workflows(nl-suite): make Claude step non-fatal; tolerant normalizer extracts <testcase> via regex on bad fragments * nl-suite: fix stale classname to UnityMCP.NL-T in mini fallback; prompt: require re-read after every revert; correct PLAN/PROGRESS to 15 * nl-suite: fix fallback JUnit classname to UnityMCP.NL-T; prompt: forbid create_script and env/mkdir checks, enforce single baseline-byte revert flow and post-revert re-read; add corruption-handling guidance * prompts(nl-full): after each write re-read raw bytes to refresh pre_sha; prefer script_apply_edits for anchors; avoid header/using changes * prompts(nl-full): canonicalize outputs to /; allow small fragment appends via Write or Bash(printf/echo); forbid wrappers and full-file round-trips * prompts(nl-full): finalize markdown formatting for guarded write, execution order, specs, status * workflows(nl-suite, mini): header/lint fixes and constrained Bash append path; align allowed_tools * prompts(nl-full): format Fast Restore, Guarded Write, Execution, Specs, Status as proper markdown lists and code fences * workflows(nl-suite): keep header tidy and append-path alignment with prompt * minor fix * workflows(nl-suite): fix indentation and dispatch; align allowed_tools and revert helper * prompts(nl-full): switch to read_resource for buf/sha; re-read only when needed; convert 'Print this once' to heading; note snapshot helper creates parent dirs * workflows(nl-suite): normalize step removes bootstrap when real testcases present; recompute tests/failures * workflows(nl-suite): enrich Markdown summary by extracting per-test <system-out> blocks (truncated) * clarify prompt resilience instructions * ci(nl-suite): revert prompt and workflow to known-good e0f8a72 for green run; remove extra MD details * ci(nl-suite): minimal fixes — no-mkdir guard in prompt; drop bootstrap and recompute JUnit counts * ci(nl-suite): richer JUnit→Markdown report (per-test system-out) * Small guard to incorret asset read call. * ci(nl-suite): refine MD builder — unescape XML entities, safe code fences, PASS/FAIL badges * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * server(manage_script): robust URI handling — percent-decode file://, normalize, strip host/leading slashes, return Assets-relative if present * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * tests(framing): reduce handshake poll window, nonblocking peek to avoid disconnect race; still enforce pre-handshake data drop * tests(manage_script): add _split_uri tests for unity://path, file:// URLs (decoded/Assets-relative), and plain paths * server+tests: fix handshake syntax error; robust file:// URI normalization in manage_script; add _split_uri tests; adjust stdout scan to ignore venv/site-packages * bridge(framing): accept zero-length frames (treat as empty keepalive) * tests(logging): use errors='replace' on decode fallback to avoid silent drops * resources(list): restrict to Assets/, resolve symlinks, enforce .cs; add traversal/outside-path tests * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * misc: framing keepalive (zero-length), regex preview consistency, resource.list hardening, URI parsing, legacy update routing, test cleanups * docs(tools): richer MCP tool descriptions; tests accept decorator kwargs; resource URI parsing hardened * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * net+docs: hard-reject zero-length frames; TCP_NODELAY on connect; Assets detection case-insensitive; NL prompt statuses aligned * prompt(nl-suite): constrain Write destinations under reports/, forbid traversal * prompt+net: harden Write path rules; use monotonic deadline and plain-text advisory for non-framed peers * unity_connection: restore recv timeout via try/finally; make global connection getter thread-safe with module lock and double-checked init * NL/T prompt: pin structured edit ops for T-D/T-E; add schema-error guarded write behavior; keep existing path/URI and revert rules * unity_connection: add FRAMED_MAX; use ValueError for framed length violations; lower framed receive log to debug; serialize connect() with per-instance lock * ManageScript: use UTF8Encoding(without BOM) for atomic writes in ApplyTextEdits/EditScript to align with Create/Update and avoid BOM-related diffs/hash mismatches * NL/T prompt: make helper deletion regex multiline-safe ((?ms) so ^ anchors line starts) * ManageScript: emit structured overlap status {status:"overlap"} for overlapping edit ranges in apply_text_edits and edit paths * NL/T prompt: clarify fallback vs failure — fallback only for unsupported/missing_field; treat bad_request as failure; note unsupported after fallback as failure * NL/T prompt: pin deterministic overlap probe (apply_text_edits two ranges from same snapshot); gate too_large behind RUN_TOO_LARGE env hint * TB update * NL/T prompt: harden Output Rules — constrain Bash(printf|echo) to stdout-only; forbid redirection/here-docs/tee; only scripts/nlt-revert.sh may mutate FS * Prompt: enumerate allowed script_apply_edits ops; add manage_editor/read_console guidance; fix T‑F atomic batch to single script_apply_edits. ManageScript: regex timeout for diagnostics; symlink ancestor guard; complete allowed-modes list. * Fixes * ManageScript: add rich overlap diagnostics (conflicts + hint) for both text range and structured batch paths * ManageScript: return structured {status:"validation_failed"} diagnostics in create/update/edits and validate before commit * ManageScript: echo canonical uri in responses (create/read/update/apply_text_edits/structured edits) to reinforce resource identity * improve clarity of capabilities message * Framing: allow zero-length frames on both ends (C# bridge, Python server). Prompt: harden T-F to single text-range apply_text_edits batch (descending order, one snapshot). URI: normalize file:// outside Assets by stripping leading slash. * ManageScript: include new sha256 in success payload for apply_text_edits; harden TryResolveUnderAssets by rejecting symlinked ancestors up to Assets/. * remove claudetest dir * manage_script_edits: normalize method-anchored anchor_insert to insert_method (map text->replacement); improves CI compatibility for T‑A/T‑E without changing Editor behavior. * tighten testing protocol around mkdir * manage_script: validate create_script inputs (Assets/.cs/name/no traversal); add Assets/ guard to delete_script; validate level+Assets in validate_script; make legacy manage_script optional params; harden legacy update routing with base64 reuse and payload size preflight. * Tighten prompt for testing * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script_edits: honor ignore_case on anchor_insert and regex_replace in both direct and text-conversion paths (MULTILINE|IGNORECASE). * remove extra file * workflow: use python3 for inline scripts and port detection on ubuntu-latest. * Tighten prompt + manage_script * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script: improve file:// UNC handling; preserve POSIX absolute semantics internally; keep test-expected slash stripping for non-Assets paths. * ManageScript.cs: add TimeSpan timeouts to all Regex uses (IsMatch/Match/new Regex) and keep CultureInvariant/Multiline options; reduces risk of catastrophic backtracking stalls. * workflow: ensure reports/ exists in markdown build step to avoid FileNotFoundError when writing MD_OUT. * fix brace * manage_script_edits: expand backrefs for regex_replace in preview->text conversion and translate to \g<n> in local apply; keeps previews and actual edits consistent. * anchor_insert: default to position=after, normalize surrounding newlines in Python conversion paths; C# path ensures trailing newline and skips duplicate insertion within class. * feat(mcp): add get_sha tool; apply_text_edits normalization+overlap preflight+strict; no-op evidence in C#; update NL suite prompt; add unit tests * feat(frames): accept zero-length heartbeat frames in client; add heartbeat test * feat(edits): guard destructive regex_replace with structural preflight; add robust tests; prompt uses delete_method for temp helper * feat(frames): bound heartbeat loop with timeout/threshold; align zero-length response with C#; update test * SDK hardening: atomic multi-span text edits; stop forcing sequential for structured ops; forward options on apply_text_edits; add validate=relaxed support and scoped checks; update NL/T prompt; add tests for options forwarding, relaxed mode, and atomic batches * Router: default applyMode=atomic for multi-span apply_text_edits; add tests * CI prompt: pass options.validate=relaxed for T-B/C; options.applyMode=atomic for T-F; emphasize always writing testcase and restoring on errors * Validation & DX: add validate=syntax (scoped), standardize evidence windows; early regex compile with hints; debug_preview for apply_text_edits * Update UnityMcpBridge/Editor/Windows/MCPForUnityEditorWindow.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * NL/T suite-driven edits: LongUnityScriptClaudeTest, bridge helpers, server_version; prepare framing tests * Fix duplicate macConfigPath field in McpClient to resolve CS0102 * Editor threading: run EnsureServerInstalled on main thread; marshal EditorPrefs/DeleteKey + logging via delayCall * Docs(apply_text_edits): strengthen guidance on 1-based positions, verify-before-edit, and recommend anchors/structured edits * Docs(script_apply_edits): add safety guidance (anchors, method ops, validators) and recommended practices * Framed VerifyBridgePing in editor window; docs hardening for apply_text_edits and script_apply_edits --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-31 00:55:38 +08:00
def _split_uri(uri: str) -> tuple[str, str]:
"""Split an incoming URI or path into (name, directory) suitable for Unity.
Rules:
- unity://path/Assets/... keep as Assets-relative (after decode/normalize)
- file://... percent-decode, normalize, strip host and leading slashes,
then, if any 'Assets' segment exists, return path relative to that 'Assets' root.
Otherwise, fall back to original name/dir behavior.
- plain paths decode/normalize separators; if they contain an 'Assets' segment,
return relative to 'Assets'.
"""
raw_path: str
if uri.startswith("unity://path/"):
raw_path = uri[len("unity://path/") :]
elif uri.startswith("file://"):
parsed = urlparse(uri)
host = (parsed.netloc or "").strip()
p = parsed.path or ""
# UNC: file://server/share/... -> //server/share/...
if host and host.lower() != "localhost":
p = f"//{host}{p}"
# Use percent-decoded path, preserving leading slashes
raw_path = unquote(p)
else:
raw_path = uri
# Percent-decode any residual encodings and normalize separators
raw_path = unquote(raw_path).replace("\\", "/")
# Strip leading slash only for Windows drive-letter forms like "/C:/..."
if os.name == "nt" and len(raw_path) >= 3 and raw_path[0] == "/" and raw_path[2] == ":":
raw_path = raw_path[1:]
# Normalize path (collapse ../, ./)
norm = os.path.normpath(raw_path).replace("\\", "/")
# If an 'Assets' segment exists, compute path relative to it (case-insensitive)
parts = [p for p in norm.split("/") if p not in ("", ".")]
idx = next((i for i, seg in enumerate(parts) if seg.lower() == "assets"), None)
assets_rel = "/".join(parts[idx:]) if idx is not None else None
effective_path = assets_rel if assets_rel else norm
# For POSIX absolute paths outside Assets, drop the leading '/'
# to return a clean relative-like directory (e.g., '/tmp' -> 'tmp').
if effective_path.startswith("/"):
effective_path = effective_path[1:]
name = os.path.splitext(os.path.basename(effective_path))[0]
directory = os.path.dirname(effective_path)
return name, directory
@mcp.tool(description=(
"Apply small text edits to a C# script identified by URI.\n\n"
"⚠️ IMPORTANT: This tool replaces EXACT character positions. Always verify content at target lines/columns BEFORE editing!\n"
"Common mistakes:\n"
"- Assuming what's on a line without checking\n"
"- Using wrong line numbers (they're 1-indexed)\n"
"- Miscounting column positions (also 1-indexed, tabs count as 1)\n\n"
"RECOMMENDED WORKFLOW:\n"
"1) First call resources/read with start_line/line_count to verify exact content\n"
"2) Count columns carefully (or use find_in_file to locate patterns)\n"
"3) Apply your edit with precise coordinates\n"
"4) Consider script_apply_edits with anchors for safer pattern-based replacements\n\n"
"Args:\n"
"- uri: unity://path/Assets/... or file://... or Assets/...\n"
"- edits: list of {startLine,startCol,endLine,endCol,newText} (1-indexed!)\n"
"- precondition_sha256: optional SHA of current file (prevents concurrent edit conflicts)\n\n"
"Notes:\n"
"- Path must resolve under Assets/\n"
"- For method/class operations, use script_apply_edits (safer, structured edits)\n"
"- For pattern-based replacements, consider anchor operations in script_apply_edits\n"
))
def apply_text_edits(
ctx: Context,
uri: str,
edits: List[Dict[str, Any]],
precondition_sha256: str | None = None,
strict: bool | None = None,
options: Dict[str, Any] | None = None,
) -> Dict[str, Any]:
"""Apply small text edits to a C# script identified by URI."""
name, directory = _split_uri(uri)
# Normalize common aliases/misuses for resilience:
# - Accept LSP-style range objects: {range:{start:{line,character}, end:{...}}, newText|text}
# - Accept index ranges as a 2-int array: {range:[startIndex,endIndex], text}
# If normalization is required, read current contents to map indices -> 1-based line/col.
def _needs_normalization(arr: List[Dict[str, Any]]) -> bool:
for e in arr or []:
if ("startLine" not in e) or ("startCol" not in e) or ("endLine" not in e) or ("endCol" not in e) or ("newText" not in e and "text" in e):
return True
return False
normalized_edits: List[Dict[str, Any]] = []
warnings: List[str] = []
if _needs_normalization(edits):
# Read file to support index->line/col conversion when needed
read_resp = send_command_with_retry("manage_script", {
"action": "read",
"name": name,
"path": directory,
})
if not (isinstance(read_resp, dict) and read_resp.get("success")):
return read_resp if isinstance(read_resp, dict) else {"success": False, "message": str(read_resp)}
data = read_resp.get("data", {})
contents = data.get("contents")
if not contents and data.get("contentsEncoded"):
try:
contents = base64.b64decode(data.get("encodedContents", "").encode("utf-8")).decode("utf-8", "replace")
except Exception:
contents = contents or ""
# Helper to map 0-based character index to 1-based line/col
def line_col_from_index(idx: int) -> tuple[int, int]:
if idx <= 0:
return 1, 1
# Count lines up to idx and position within line
nl_count = contents.count("\n", 0, idx)
line = nl_count + 1
last_nl = contents.rfind("\n", 0, idx)
col = (idx - (last_nl + 1)) + 1 if last_nl >= 0 else idx + 1
return line, col
for e in edits or []:
e2 = dict(e)
# Map text->newText if needed
if "newText" not in e2 and "text" in e2:
e2["newText"] = e2.pop("text")
if "startLine" in e2 and "startCol" in e2 and "endLine" in e2 and "endCol" in e2:
# Guard: explicit fields must be 1-based.
zero_based = False
for k in ("startLine","startCol","endLine","endCol"):
try:
if int(e2.get(k, 1)) < 1:
zero_based = True
except Exception:
pass
if zero_based:
if strict:
return {"success": False, "code": "zero_based_explicit_fields", "message": "Explicit line/col fields are 1-based; received zero-based.", "data": {"normalizedEdits": normalized_edits}}
# Normalize by clamping to 1 and warn
for k in ("startLine","startCol","endLine","endCol"):
try:
if int(e2.get(k, 1)) < 1:
e2[k] = 1
except Exception:
pass
warnings.append("zero_based_explicit_fields_normalized")
normalized_edits.append(e2)
continue
rng = e2.get("range")
if isinstance(rng, dict):
# LSP style: 0-based
s = rng.get("start", {})
t = rng.get("end", {})
e2["startLine"] = int(s.get("line", 0)) + 1
e2["startCol"] = int(s.get("character", 0)) + 1
e2["endLine"] = int(t.get("line", 0)) + 1
e2["endCol"] = int(t.get("character", 0)) + 1
e2.pop("range", None)
normalized_edits.append(e2)
continue
if isinstance(rng, (list, tuple)) and len(rng) == 2:
try:
a = int(rng[0])
b = int(rng[1])
if b < a:
a, b = b, a
sl, sc = line_col_from_index(a)
el, ec = line_col_from_index(b)
e2["startLine"] = sl
e2["startCol"] = sc
e2["endLine"] = el
e2["endCol"] = ec
e2.pop("range", None)
normalized_edits.append(e2)
continue
except Exception:
pass
# Could not normalize this edit
return {
"success": False,
"code": "missing_field",
"message": "apply_text_edits requires startLine/startCol/endLine/endCol/newText or a normalizable 'range'",
"data": {"expected": ["startLine","startCol","endLine","endCol","newText"], "got": e}
}
else:
# Even when edits appear already in explicit form, validate 1-based coordinates.
normalized_edits = []
for e in edits or []:
e2 = dict(e)
has_all = all(k in e2 for k in ("startLine","startCol","endLine","endCol"))
if has_all:
zero_based = False
for k in ("startLine","startCol","endLine","endCol"):
try:
if int(e2.get(k, 1)) < 1:
zero_based = True
except Exception:
pass
if zero_based:
if strict:
return {"success": False, "code": "zero_based_explicit_fields", "message": "Explicit line/col fields are 1-based; received zero-based.", "data": {"normalizedEdits": [e2]}}
for k in ("startLine","startCol","endLine","endCol"):
try:
if int(e2.get(k, 1)) < 1:
e2[k] = 1
except Exception:
pass
if "zero_based_explicit_fields_normalized" not in warnings:
warnings.append("zero_based_explicit_fields_normalized")
normalized_edits.append(e2)
# Preflight: detect overlapping ranges among normalized line/col spans
def _pos_tuple(e: Dict[str, Any], key_start: bool) -> tuple[int, int]:
return (
int(e.get("startLine", 1)) if key_start else int(e.get("endLine", 1)),
int(e.get("startCol", 1)) if key_start else int(e.get("endCol", 1)),
)
def _le(a: tuple[int, int], b: tuple[int, int]) -> bool:
return a[0] < b[0] or (a[0] == b[0] and a[1] <= b[1])
# Consider only true replace ranges (non-zero length). Pure insertions (zero-width) don't overlap.
spans = []
for e in normalized_edits or []:
try:
s = _pos_tuple(e, True)
t = _pos_tuple(e, False)
if s != t:
spans.append((s, t))
except Exception:
# If coordinates missing or invalid, let the server validate later
pass
if spans:
spans_sorted = sorted(spans, key=lambda p: (p[0][0], p[0][1]))
for i in range(1, len(spans_sorted)):
prev_end = spans_sorted[i-1][1]
curr_start = spans_sorted[i][0]
# Overlap if prev_end > curr_start (strict), i.e., not prev_end <= curr_start
if not _le(prev_end, curr_start):
conflicts = [{
"startA": {"line": spans_sorted[i-1][0][0], "col": spans_sorted[i-1][0][1]},
"endA": {"line": spans_sorted[i-1][1][0], "col": spans_sorted[i-1][1][1]},
"startB": {"line": spans_sorted[i][0][0], "col": spans_sorted[i][0][1]},
"endB": {"line": spans_sorted[i][1][0], "col": spans_sorted[i][1][1]},
}]
return {"success": False, "code": "overlap", "data": {"status": "overlap", "conflicts": conflicts}}
# Note: Do not auto-compute precondition if missing; callers should supply it
# via mcp__unity__get_sha or a prior read. This avoids hidden extra calls and
# preserves existing call-count expectations in clients/tests.
# Default options: for multi-span batches, prefer atomic to avoid mid-apply imbalance
opts: Dict[str, Any] = dict(options or {})
try:
if len(normalized_edits) > 1 and "applyMode" not in opts:
opts["applyMode"] = "atomic"
except Exception:
pass
# Support optional debug preview for span-by-span simulation without write
if opts.get("debug_preview"):
try:
import difflib
# Apply locally to preview final result
lines = []
# Build an indexable original from a read if we normalized from read; otherwise skip
prev = ""
# We cannot guarantee file contents here without a read; return normalized spans only
return {
"success": True,
"message": "Preview only (no write)",
"data": {
"normalizedEdits": normalized_edits,
"preview": True
}
}
except Exception as e:
return {"success": False, "code": "preview_failed", "message": f"debug_preview failed: {e}", "data": {"normalizedEdits": normalized_edits}}
params = {
"action": "apply_text_edits",
"name": name,
"path": directory,
"edits": normalized_edits,
"precondition_sha256": precondition_sha256,
"options": opts,
}
params = {k: v for k, v in params.items() if v is not None}
resp = send_command_with_retry("manage_script", params)
if isinstance(resp, dict):
data = resp.setdefault("data", {})
data.setdefault("normalizedEdits", normalized_edits)
if warnings:
data.setdefault("warnings", warnings)
return resp
return {"success": False, "message": str(resp)}
@mcp.tool(description=(
"Create a new C# script at the given project path.\n\n"
"Args: path (e.g., 'Assets/Scripts/My.cs'), contents (string), script_type, namespace.\n"
"Rules: path must be under Assets/. Contents will be Base64-encoded over transport.\n"
))
def create_script(
ctx: Context,
path: str,
contents: str = "",
script_type: str | None = None,
namespace: str | None = None,
) -> Dict[str, Any]:
"""Create a new C# script at the given path."""
name = os.path.splitext(os.path.basename(path))[0]
directory = os.path.dirname(path)
# Local validation to avoid round-trips on obviously bad input
norm_path = os.path.normpath((path or "").replace("\\", "/")).replace("\\", "/")
if not directory or directory.split("/")[0].lower() != "assets":
return {"success": False, "code": "path_outside_assets", "message": f"path must be under 'Assets/'; got '{path}'."}
if ".." in norm_path.split("/") or norm_path.startswith("/"):
return {"success": False, "code": "bad_path", "message": "path must not contain traversal or be absolute."}
if not name:
return {"success": False, "code": "bad_path", "message": "path must include a script file name."}
if not norm_path.lower().endswith(".cs"):
return {"success": False, "code": "bad_extension", "message": "script file must end with .cs."}
params: Dict[str, Any] = {
"action": "create",
"name": name,
"path": directory,
"namespace": namespace,
"scriptType": script_type,
}
if contents:
params["encodedContents"] = base64.b64encode(contents.encode("utf-8")).decode("utf-8")
params["contentsEncoded"] = True
params = {k: v for k, v in params.items() if v is not None}
resp = send_command_with_retry("manage_script", params)
return resp if isinstance(resp, dict) else {"success": False, "message": str(resp)}
@mcp.tool(description=(
"Delete a C# script by URI or Assets-relative path.\n\n"
"Args: uri (unity://path/... or file://... or Assets/...).\n"
"Rules: Target must resolve under Assets/.\n"
))
def delete_script(ctx: Context, uri: str) -> Dict[str, Any]:
"""Delete a C# script by URI."""
name, directory = _split_uri(uri)
if not directory or directory.split("/")[0].lower() != "assets":
return {"success": False, "code": "path_outside_assets", "message": "URI must resolve under 'Assets/'."}
params = {"action": "delete", "name": name, "path": directory}
resp = send_command_with_retry("manage_script", params)
return resp if isinstance(resp, dict) else {"success": False, "message": str(resp)}
@mcp.tool(description=(
"Validate a C# script and return diagnostics.\n\n"
"Args: uri, level=('basic'|'standard').\n"
"- basic: quick syntax checks.\n"
"- standard: deeper checks (performance hints, common pitfalls).\n"
))
def validate_script(
ctx: Context, uri: str, level: str = "basic"
) -> Dict[str, Any]:
"""Validate a C# script and return diagnostics."""
name, directory = _split_uri(uri)
if not directory or directory.split("/")[0].lower() != "assets":
return {"success": False, "code": "path_outside_assets", "message": "URI must resolve under 'Assets/'."}
if level not in ("basic", "standard"):
return {"success": False, "code": "bad_level", "message": "level must be 'basic' or 'standard'."}
params = {
"action": "validate",
"name": name,
"path": directory,
"level": level,
}
resp = send_command_with_retry("manage_script", params)
return resp if isinstance(resp, dict) else {"success": False, "message": str(resp)}
@mcp.tool(description=(
"Compatibility router for legacy script operations.\n\n"
"Actions: create|read|delete (update is routed to apply_text_edits with precondition).\n"
"Args: name (no .cs), path (Assets/...), contents (for create), script_type, namespace.\n"
"Notes: prefer apply_text_edits (ranges) or script_apply_edits (structured) for edits.\n"
))
def manage_script(
ctx: Context,
action: str,
name: str,
path: str,
Claude‑friendly edit tools + framed transport + live Unity NL test framework (#243) * CI: gate desktop-parity on Anthropic key; pass anthropic_api_key like NL suite * Add quickprobe prompt and CI workflow (mcp-quickprobe.md, unity-mcp-quickprobe.yml) * strictier tool use to prevent subagent spawning and force mcp tools * update workflow filesto reduce likelihood of subagent spawning * improve permissions for claude agent, fix mcpbridge timeout/token issue * increase max turns to 10 * ci: align NL suite to new permissions schema; prevent subagent drift * ci: NL suite -> mini prompt for e2e; add full NL/T prompt; server: ctx optional + project_root fallback; workflows: set UNITY_PROJECT_ROOT for CI * ci: add checks:write; revert local project hardcodes (manifest, ProjectVersion.txt) * tools: text-edit routing fixes (anchor_insert via text, CRLF calc); prompts: mini NL/T clarifications * ci: use absolute UNITY_PROJECT_ROOT; prompts target TestProjects; server: accept relative UNITY_PROJECT_ROOT and bare spec URI * ci: ignore Unity test project's packages-lock.json; remove from repo to avoid absolute paths * CI: start persistent Unity Editor for MCP (guarded by license) + allow batch-mode bridge via UNITY_MCP_ALLOW_BATCH * CI: hide license and pass via env to docker; fix invalid ref format * CI: readiness probe uses handshake on Unity MCP port (deterministic) * CI: fix YAML; use TCP handshake readiness probe (FRAMING=1) * CI: prime Unity license via game-ci; mount ULF into container; extend readiness timeout * CI: use ULF write + mount for Unity licensing; remove serial/email/pass from container * CI: entitlement activation (UNITY_SERIAL=''); verify host ULF cache; keep mount * CI: write ULF from secret and verify; drop entitlement activation step * CI: detect any licensing path; GameCI prime; status dir env; log+probe readiness; fix YAML * CI: add GameCI license prime; conditional ULF write; one-shot license validation; explicit status dir + license env * CI: fix YAML (inline python), add Anthropic key detect via GITHUB_ENV; ready to run happy path * CI: mount Unity token/ulf/cache dirs into container to share host license; create dirs before start * CI: fix YAML indentation; write ULF on host; activate in container with shared mounts; mount .config and .cache too * CI: gate Claude via outputs; mount all Unity license dirs; fix inline probe python; stabilize licensing flow * CI: normalize detect to step outputs; ensure license dirs mounted and validated; fix indentation * Bridge: honor UNITY_MCP_STATUS_DIR for heartbeat/status file (CI-friendly) * CI: guard project path for activation/start; align tool allowlist; run MCP server with python; tighten secret scoping * CI: finalize Unity licensing mounts + status dir; mode-detect (ULF/EBL); readiness logs+probe; Claude gating via outputs * CI: fix YAML probe (inline python -c) and finalize happy-path Unity licensing and MCP/Claude wiring * CI: inline python probe; unify Unity image and cache mounts; ready to test * CI: fix docker run IMAGE placement; ignore cache find perms; keep same editor image * CI: pass -manualLicenseFile to persistent Editor; keep mounts and single image * CI: mount full GameCI cache to /root in persistent Unity; set HOME=/root; add optional license check * CI: make -manualLicenseFile conditional; keep full /root mount and license check * CI: set HOME=/github/home; mount GameCI cache there; adjust manualLicenseFile path; expand license check * CI: EBL sign-in for persistent Unity (email/password/serial); revert HOME=/root and full /root mount; keep conditional manualLicenseFile and improved readiness * CI: run full NL/T suite prompt (nl-unity-suite-full.md) instead of mini * NL/T: require unified diffs + explicit verdicts in JUnit; CI: remove short sanity step, publish JUnit, upload artifacts * NL/T prompt: require CDATA wrapping for JUnit XML fields; guidance for splitting embedded ]]>; keep VERDICT in CDATA only * CI: remove in-container license check step; keep readiness and full suite * NL/T prompt: add version header, stricter JUnit schema, hashing/normalization, anchors, statuses, atomic semantics, tool logging * CI: increase Claude NL/T suite timeout to 30 minutes * CI: pre-create reports dir and result files to avoid tool approval prompts * CI: skip wait if container not running; skip Editor start if project missing; broaden MCP deps detection; expand allowed tools * fixies to harden ManageScript * CI: sanitize NL/T markdown report to avoid NUL/encoding issues * revert breaking yyaml changes * CI: prime license, robust Unity start/wait, sanitize markdown via heredoc * Resolve merge: accept upstream renames/installer (fix/installer-cleanup-v2) and keep local framing/script-editing - Restored upstream server.py, EditorWindow, uv.lock\n- Preserved ManageScript editing/validation; switched to atomic write + debounced refresh\n- Updated tools/__init__.py to keep script_edits/resources and adopt new logger name\n- All Python tests via uv: 7 passed, 6 skipped, 9 xpassed; Unity compile OK * Fix Claude Desktop config path and atomic write issues - Fix macOS path for Claude Desktop config: use ~/Library/Application Support/Claude/ instead of ~/.config/Claude/ - Improve atomic write pattern with backup/restore safety - Replace File.Replace() with File.Move() for better macOS compatibility - Add proper error handling and cleanup for file operations - Resolves issue where installer couldn't find Claude Desktop config on macOS * Editor: use macConfigPath on macOS for MCP client config writes (Claude Desktop, etc.). Fallback to linuxConfigPath only if mac path missing. * Models: add macConfigPath to McpClient for macOS config path selection (fixes CS1061 in editor window). * Editor: on macOS, prefer macConfigPath in ManualConfigEditorWindow (fallback to linux path); Linux/Windows unchanged. * Fix McpClient: align with upstream/main, prep for framing split * NL suite: shard workflow; tighten bridge readiness; add MCP preflight; use env-based shard vars * NL suite: fix shard step indentation; move shard vars to env; remove invalid inputs * MCP clients: split VSCode Copilot config paths into macConfigPath and linuxConfigPath * Unity bridge: clean stale status; bind host; robust wait probe with IPv4/IPv6 + diagnostics * CI: use MCPForUnity.Editor.MCPForUnityBridge.StartAutoConnect as executeMethod * Action wiring: inline mcpServers in settings for all shards; remove redundant .claude/mcp.json step * CI: embed mcpServers in settings for all shards; fix startup sanity step; lint clean * CI: pin claude-code-base-action to e6f32c8; use claude_args --mcp-config; switch to allowed_tools; ensure MCP config per step * CI: unpin claude-code-base-action to @beta (commit ref not found) * CI: align with claude-code-base-action @beta; pass MCP via claude_args and allowedTools * Editor: Fix apply_text_edits heuristic when edits shift positions; recompute method span on candidate text with fallback delta adjustment * CI: unify MCP wiring across workflows; write .claude/mcp.json; switch to claude_args with --mcp-config/--allowedTools; remove unsupported inputs * CI: collapse NL suite shards into a single run to avoid repeated test execution * CI: minimize allowedTools for NL suite to essential Unity MCP + Bash("git:*") + Write * CI: mkdir -p reports before run; remove unsupported --timeout-minutes from claude_args * CI: broaden allowedTools to include find_in_file and mcp__unity__* * CI: enable use_node_cache and switch NL suite model to claude-3-7-haiku-20250219 * CI: disable use_node_cache to avoid setup-node lockfile error * CI: set NL suite model to claude-3-haiku-20240307 * CI: cap Haiku output with --max-tokens 2048 for NL suite * CI: switch to claude-3-7-sonnet-latest and remove unsupported --max-tokens * CI: update allowedTools to Bash(*) and explicit Unity MCP tool list * CI: update NL suite workflow (latest tweaks) * Tests: tighten NL suite prompt for logging, hash discipline, stale retry, evidence windows, diff cap, and VERDICT line * Add disallowed tools to NL suite workflow * docs: clarify stale write retry * Add fallback JUnit report and adjust publisher * Indent fallback JUnit XML in workflow * fix: correct fallback JUnit report generation * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update Response.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update MCPForUnityBridge.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: correct McpTypes reference * Add directory existence checks for symlink and XDG paths * fix: only set installation flag after successful server install * Update resource_tools.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: respect mac config paths * Use File.Replace for atomic config write * Remove unused imports in manage_script * bump server version * Tests: update NL suite prompt and workflows; remove deprecated smoke/desktop-parity; quickprobe tidy * Editor: atomic config write via File.Replace fallback; remove redundant backups and racey exists checks * CI: harden NL suite - idempotent docker, gate on unity_ok, safer port probe, least-priv perms * Editor: make atomic config write restoration safe (flag writeDone; copy-overwrite restore; cleanup in finally) * CI: fix fallback JUnit heredoc by using printf lines (no EOF delimiter issues) * CI: switch NL suite to mini prompt; mini prompt honors / and NL discipline * CI: replace claude_args with allowed_tools/model/mcp_config per action schema * CI: expand UNITY_PROJECT_ROOT via in MCP config heredoc * EditorWindow: add cross-platform fallback for File.Replace; macOS-insensitive PathsEqual; safer uv resolve; honor macConfigPath * CI: strengthen JUnit publishing for NL mini suite (normalize, debug list, publish both, fail_on_parse_error) * CI: set job-wide JUNIT_OUT/MD_OUT; normalization uses env; publish references env and ungroup reports * CI: publish a single normalized JUnit (reports/junit-for-actions.xml); fallback writes same; avoid checkName/reportPaths mismatch * CI: align mini prompt report filenames; redact Unity log tail in diagnostics * chore: sync workflow and mini prompt; redacted logs; JUnit normalization/publish tweaks * CI: redact sensitive tokens in Stop Unity; docs: CI usage + edit tools * prompts: update nl-unity-suite-full (mini-style setup + reporting discipline); remove obsolete prompts * CI: harden NL workflows (timeout_minutes, robust normalization); prompts: unify JUnit suite name and reporting discipline * prompts: add guarded write pattern (LF hash, stale_file retry) to full suite * prompts: enforce continue-on-failure, driver flow, and status handling in full suite * Make test list more explicit in prompt. Get rid of old test prompts for hygeine. * prompts: add stale fast-retry (server hash) + in-memory buf guidance * CI: standardize JUNIT_OUT to reports/junit-nl-suite.xml; fix artifact upload indentation; prompt copy cleanups * prompts: reporting discipline — append-only fragments, batch writes, no model round-trip * prompts: stale fast-retry preference, buffer/sha carry, snapshot revert, essential logging * workflows(nl-suite): precreate report skeletons, assemble junit, synthesize markdown; restrict allowed_tools to append-only Bash + MCP tools * thsis too * Update README-DEV.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite-mini.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * workflows(nl-mini): fix YAML indentation/trailing spaces under with: and cleanup heredoc spacing * workflows(nl-suite): fix indentation on docker logs redaction line (YAML lint) * Add write to allowlist * nl-suite: harden reporting discipline (fragment-only writes, forbid alt paths); workflow: clean stray junit-*updated*.xml * nl-suite: enforce end-of-suite single Write (no bash redirection); workflow: restrict allowed_tools to Write+MCP only * prompts(nl-full): end-of-suite results must be valid XML with single <cases> root and only <testcase> children; no raw text outside CDATA * workflows(nl-suite): make Claude step non-fatal; tolerant normalizer extracts <testcase> via regex on bad fragments * nl-suite: fix stale classname to UnityMCP.NL-T in mini fallback; prompt: require re-read after every revert; correct PLAN/PROGRESS to 15 * nl-suite: fix fallback JUnit classname to UnityMCP.NL-T; prompt: forbid create_script and env/mkdir checks, enforce single baseline-byte revert flow and post-revert re-read; add corruption-handling guidance * prompts(nl-full): after each write re-read raw bytes to refresh pre_sha; prefer script_apply_edits for anchors; avoid header/using changes * prompts(nl-full): canonicalize outputs to /; allow small fragment appends via Write or Bash(printf/echo); forbid wrappers and full-file round-trips * prompts(nl-full): finalize markdown formatting for guarded write, execution order, specs, status * workflows(nl-suite, mini): header/lint fixes and constrained Bash append path; align allowed_tools * prompts(nl-full): format Fast Restore, Guarded Write, Execution, Specs, Status as proper markdown lists and code fences * workflows(nl-suite): keep header tidy and append-path alignment with prompt * minor fix * workflows(nl-suite): fix indentation and dispatch; align allowed_tools and revert helper * prompts(nl-full): switch to read_resource for buf/sha; re-read only when needed; convert 'Print this once' to heading; note snapshot helper creates parent dirs * workflows(nl-suite): normalize step removes bootstrap when real testcases present; recompute tests/failures * workflows(nl-suite): enrich Markdown summary by extracting per-test <system-out> blocks (truncated) * clarify prompt resilience instructions * ci(nl-suite): revert prompt and workflow to known-good e0f8a72 for green run; remove extra MD details * ci(nl-suite): minimal fixes — no-mkdir guard in prompt; drop bootstrap and recompute JUnit counts * ci(nl-suite): richer JUnit→Markdown report (per-test system-out) * Small guard to incorret asset read call. * ci(nl-suite): refine MD builder — unescape XML entities, safe code fences, PASS/FAIL badges * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * server(manage_script): robust URI handling — percent-decode file://, normalize, strip host/leading slashes, return Assets-relative if present * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * tests(framing): reduce handshake poll window, nonblocking peek to avoid disconnect race; still enforce pre-handshake data drop * tests(manage_script): add _split_uri tests for unity://path, file:// URLs (decoded/Assets-relative), and plain paths * server+tests: fix handshake syntax error; robust file:// URI normalization in manage_script; add _split_uri tests; adjust stdout scan to ignore venv/site-packages * bridge(framing): accept zero-length frames (treat as empty keepalive) * tests(logging): use errors='replace' on decode fallback to avoid silent drops * resources(list): restrict to Assets/, resolve symlinks, enforce .cs; add traversal/outside-path tests * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * misc: framing keepalive (zero-length), regex preview consistency, resource.list hardening, URI parsing, legacy update routing, test cleanups * docs(tools): richer MCP tool descriptions; tests accept decorator kwargs; resource URI parsing hardened * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * net+docs: hard-reject zero-length frames; TCP_NODELAY on connect; Assets detection case-insensitive; NL prompt statuses aligned * prompt(nl-suite): constrain Write destinations under reports/, forbid traversal * prompt+net: harden Write path rules; use monotonic deadline and plain-text advisory for non-framed peers * unity_connection: restore recv timeout via try/finally; make global connection getter thread-safe with module lock and double-checked init * NL/T prompt: pin structured edit ops for T-D/T-E; add schema-error guarded write behavior; keep existing path/URI and revert rules * unity_connection: add FRAMED_MAX; use ValueError for framed length violations; lower framed receive log to debug; serialize connect() with per-instance lock * ManageScript: use UTF8Encoding(without BOM) for atomic writes in ApplyTextEdits/EditScript to align with Create/Update and avoid BOM-related diffs/hash mismatches * NL/T prompt: make helper deletion regex multiline-safe ((?ms) so ^ anchors line starts) * ManageScript: emit structured overlap status {status:"overlap"} for overlapping edit ranges in apply_text_edits and edit paths * NL/T prompt: clarify fallback vs failure — fallback only for unsupported/missing_field; treat bad_request as failure; note unsupported after fallback as failure * NL/T prompt: pin deterministic overlap probe (apply_text_edits two ranges from same snapshot); gate too_large behind RUN_TOO_LARGE env hint * TB update * NL/T prompt: harden Output Rules — constrain Bash(printf|echo) to stdout-only; forbid redirection/here-docs/tee; only scripts/nlt-revert.sh may mutate FS * Prompt: enumerate allowed script_apply_edits ops; add manage_editor/read_console guidance; fix T‑F atomic batch to single script_apply_edits. ManageScript: regex timeout for diagnostics; symlink ancestor guard; complete allowed-modes list. * Fixes * ManageScript: add rich overlap diagnostics (conflicts + hint) for both text range and structured batch paths * ManageScript: return structured {status:"validation_failed"} diagnostics in create/update/edits and validate before commit * ManageScript: echo canonical uri in responses (create/read/update/apply_text_edits/structured edits) to reinforce resource identity * improve clarity of capabilities message * Framing: allow zero-length frames on both ends (C# bridge, Python server). Prompt: harden T-F to single text-range apply_text_edits batch (descending order, one snapshot). URI: normalize file:// outside Assets by stripping leading slash. * ManageScript: include new sha256 in success payload for apply_text_edits; harden TryResolveUnderAssets by rejecting symlinked ancestors up to Assets/. * remove claudetest dir * manage_script_edits: normalize method-anchored anchor_insert to insert_method (map text->replacement); improves CI compatibility for T‑A/T‑E without changing Editor behavior. * tighten testing protocol around mkdir * manage_script: validate create_script inputs (Assets/.cs/name/no traversal); add Assets/ guard to delete_script; validate level+Assets in validate_script; make legacy manage_script optional params; harden legacy update routing with base64 reuse and payload size preflight. * Tighten prompt for testing * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script_edits: honor ignore_case on anchor_insert and regex_replace in both direct and text-conversion paths (MULTILINE|IGNORECASE). * remove extra file * workflow: use python3 for inline scripts and port detection on ubuntu-latest. * Tighten prompt + manage_script * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script: improve file:// UNC handling; preserve POSIX absolute semantics internally; keep test-expected slash stripping for non-Assets paths. * ManageScript.cs: add TimeSpan timeouts to all Regex uses (IsMatch/Match/new Regex) and keep CultureInvariant/Multiline options; reduces risk of catastrophic backtracking stalls. * workflow: ensure reports/ exists in markdown build step to avoid FileNotFoundError when writing MD_OUT. * fix brace * manage_script_edits: expand backrefs for regex_replace in preview->text conversion and translate to \g<n> in local apply; keeps previews and actual edits consistent. * anchor_insert: default to position=after, normalize surrounding newlines in Python conversion paths; C# path ensures trailing newline and skips duplicate insertion within class. * feat(mcp): add get_sha tool; apply_text_edits normalization+overlap preflight+strict; no-op evidence in C#; update NL suite prompt; add unit tests * feat(frames): accept zero-length heartbeat frames in client; add heartbeat test * feat(edits): guard destructive regex_replace with structural preflight; add robust tests; prompt uses delete_method for temp helper * feat(frames): bound heartbeat loop with timeout/threshold; align zero-length response with C#; update test * SDK hardening: atomic multi-span text edits; stop forcing sequential for structured ops; forward options on apply_text_edits; add validate=relaxed support and scoped checks; update NL/T prompt; add tests for options forwarding, relaxed mode, and atomic batches * Router: default applyMode=atomic for multi-span apply_text_edits; add tests * CI prompt: pass options.validate=relaxed for T-B/C; options.applyMode=atomic for T-F; emphasize always writing testcase and restoring on errors * Validation & DX: add validate=syntax (scoped), standardize evidence windows; early regex compile with hints; debug_preview for apply_text_edits * Update UnityMcpBridge/Editor/Windows/MCPForUnityEditorWindow.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * NL/T suite-driven edits: LongUnityScriptClaudeTest, bridge helpers, server_version; prepare framing tests * Fix duplicate macConfigPath field in McpClient to resolve CS0102 * Editor threading: run EnsureServerInstalled on main thread; marshal EditorPrefs/DeleteKey + logging via delayCall * Docs(apply_text_edits): strengthen guidance on 1-based positions, verify-before-edit, and recommend anchors/structured edits * Docs(script_apply_edits): add safety guidance (anchors, method ops, validators) and recommended practices * Framed VerifyBridgePing in editor window; docs hardening for apply_text_edits and script_apply_edits --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-31 00:55:38 +08:00
contents: str = "",
script_type: str | None = None,
namespace: str | None = None,
) -> Dict[str, Any]:
Claude‑friendly edit tools + framed transport + live Unity NL test framework (#243) * CI: gate desktop-parity on Anthropic key; pass anthropic_api_key like NL suite * Add quickprobe prompt and CI workflow (mcp-quickprobe.md, unity-mcp-quickprobe.yml) * strictier tool use to prevent subagent spawning and force mcp tools * update workflow filesto reduce likelihood of subagent spawning * improve permissions for claude agent, fix mcpbridge timeout/token issue * increase max turns to 10 * ci: align NL suite to new permissions schema; prevent subagent drift * ci: NL suite -> mini prompt for e2e; add full NL/T prompt; server: ctx optional + project_root fallback; workflows: set UNITY_PROJECT_ROOT for CI * ci: add checks:write; revert local project hardcodes (manifest, ProjectVersion.txt) * tools: text-edit routing fixes (anchor_insert via text, CRLF calc); prompts: mini NL/T clarifications * ci: use absolute UNITY_PROJECT_ROOT; prompts target TestProjects; server: accept relative UNITY_PROJECT_ROOT and bare spec URI * ci: ignore Unity test project's packages-lock.json; remove from repo to avoid absolute paths * CI: start persistent Unity Editor for MCP (guarded by license) + allow batch-mode bridge via UNITY_MCP_ALLOW_BATCH * CI: hide license and pass via env to docker; fix invalid ref format * CI: readiness probe uses handshake on Unity MCP port (deterministic) * CI: fix YAML; use TCP handshake readiness probe (FRAMING=1) * CI: prime Unity license via game-ci; mount ULF into container; extend readiness timeout * CI: use ULF write + mount for Unity licensing; remove serial/email/pass from container * CI: entitlement activation (UNITY_SERIAL=''); verify host ULF cache; keep mount * CI: write ULF from secret and verify; drop entitlement activation step * CI: detect any licensing path; GameCI prime; status dir env; log+probe readiness; fix YAML * CI: add GameCI license prime; conditional ULF write; one-shot license validation; explicit status dir + license env * CI: fix YAML (inline python), add Anthropic key detect via GITHUB_ENV; ready to run happy path * CI: mount Unity token/ulf/cache dirs into container to share host license; create dirs before start * CI: fix YAML indentation; write ULF on host; activate in container with shared mounts; mount .config and .cache too * CI: gate Claude via outputs; mount all Unity license dirs; fix inline probe python; stabilize licensing flow * CI: normalize detect to step outputs; ensure license dirs mounted and validated; fix indentation * Bridge: honor UNITY_MCP_STATUS_DIR for heartbeat/status file (CI-friendly) * CI: guard project path for activation/start; align tool allowlist; run MCP server with python; tighten secret scoping * CI: finalize Unity licensing mounts + status dir; mode-detect (ULF/EBL); readiness logs+probe; Claude gating via outputs * CI: fix YAML probe (inline python -c) and finalize happy-path Unity licensing and MCP/Claude wiring * CI: inline python probe; unify Unity image and cache mounts; ready to test * CI: fix docker run IMAGE placement; ignore cache find perms; keep same editor image * CI: pass -manualLicenseFile to persistent Editor; keep mounts and single image * CI: mount full GameCI cache to /root in persistent Unity; set HOME=/root; add optional license check * CI: make -manualLicenseFile conditional; keep full /root mount and license check * CI: set HOME=/github/home; mount GameCI cache there; adjust manualLicenseFile path; expand license check * CI: EBL sign-in for persistent Unity (email/password/serial); revert HOME=/root and full /root mount; keep conditional manualLicenseFile and improved readiness * CI: run full NL/T suite prompt (nl-unity-suite-full.md) instead of mini * NL/T: require unified diffs + explicit verdicts in JUnit; CI: remove short sanity step, publish JUnit, upload artifacts * NL/T prompt: require CDATA wrapping for JUnit XML fields; guidance for splitting embedded ]]>; keep VERDICT in CDATA only * CI: remove in-container license check step; keep readiness and full suite * NL/T prompt: add version header, stricter JUnit schema, hashing/normalization, anchors, statuses, atomic semantics, tool logging * CI: increase Claude NL/T suite timeout to 30 minutes * CI: pre-create reports dir and result files to avoid tool approval prompts * CI: skip wait if container not running; skip Editor start if project missing; broaden MCP deps detection; expand allowed tools * fixies to harden ManageScript * CI: sanitize NL/T markdown report to avoid NUL/encoding issues * revert breaking yyaml changes * CI: prime license, robust Unity start/wait, sanitize markdown via heredoc * Resolve merge: accept upstream renames/installer (fix/installer-cleanup-v2) and keep local framing/script-editing - Restored upstream server.py, EditorWindow, uv.lock\n- Preserved ManageScript editing/validation; switched to atomic write + debounced refresh\n- Updated tools/__init__.py to keep script_edits/resources and adopt new logger name\n- All Python tests via uv: 7 passed, 6 skipped, 9 xpassed; Unity compile OK * Fix Claude Desktop config path and atomic write issues - Fix macOS path for Claude Desktop config: use ~/Library/Application Support/Claude/ instead of ~/.config/Claude/ - Improve atomic write pattern with backup/restore safety - Replace File.Replace() with File.Move() for better macOS compatibility - Add proper error handling and cleanup for file operations - Resolves issue where installer couldn't find Claude Desktop config on macOS * Editor: use macConfigPath on macOS for MCP client config writes (Claude Desktop, etc.). Fallback to linuxConfigPath only if mac path missing. * Models: add macConfigPath to McpClient for macOS config path selection (fixes CS1061 in editor window). * Editor: on macOS, prefer macConfigPath in ManualConfigEditorWindow (fallback to linux path); Linux/Windows unchanged. * Fix McpClient: align with upstream/main, prep for framing split * NL suite: shard workflow; tighten bridge readiness; add MCP preflight; use env-based shard vars * NL suite: fix shard step indentation; move shard vars to env; remove invalid inputs * MCP clients: split VSCode Copilot config paths into macConfigPath and linuxConfigPath * Unity bridge: clean stale status; bind host; robust wait probe with IPv4/IPv6 + diagnostics * CI: use MCPForUnity.Editor.MCPForUnityBridge.StartAutoConnect as executeMethod * Action wiring: inline mcpServers in settings for all shards; remove redundant .claude/mcp.json step * CI: embed mcpServers in settings for all shards; fix startup sanity step; lint clean * CI: pin claude-code-base-action to e6f32c8; use claude_args --mcp-config; switch to allowed_tools; ensure MCP config per step * CI: unpin claude-code-base-action to @beta (commit ref not found) * CI: align with claude-code-base-action @beta; pass MCP via claude_args and allowedTools * Editor: Fix apply_text_edits heuristic when edits shift positions; recompute method span on candidate text with fallback delta adjustment * CI: unify MCP wiring across workflows; write .claude/mcp.json; switch to claude_args with --mcp-config/--allowedTools; remove unsupported inputs * CI: collapse NL suite shards into a single run to avoid repeated test execution * CI: minimize allowedTools for NL suite to essential Unity MCP + Bash("git:*") + Write * CI: mkdir -p reports before run; remove unsupported --timeout-minutes from claude_args * CI: broaden allowedTools to include find_in_file and mcp__unity__* * CI: enable use_node_cache and switch NL suite model to claude-3-7-haiku-20250219 * CI: disable use_node_cache to avoid setup-node lockfile error * CI: set NL suite model to claude-3-haiku-20240307 * CI: cap Haiku output with --max-tokens 2048 for NL suite * CI: switch to claude-3-7-sonnet-latest and remove unsupported --max-tokens * CI: update allowedTools to Bash(*) and explicit Unity MCP tool list * CI: update NL suite workflow (latest tweaks) * Tests: tighten NL suite prompt for logging, hash discipline, stale retry, evidence windows, diff cap, and VERDICT line * Add disallowed tools to NL suite workflow * docs: clarify stale write retry * Add fallback JUnit report and adjust publisher * Indent fallback JUnit XML in workflow * fix: correct fallback JUnit report generation * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update Response.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update MCPForUnityBridge.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: correct McpTypes reference * Add directory existence checks for symlink and XDG paths * fix: only set installation flag after successful server install * Update resource_tools.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: respect mac config paths * Use File.Replace for atomic config write * Remove unused imports in manage_script * bump server version * Tests: update NL suite prompt and workflows; remove deprecated smoke/desktop-parity; quickprobe tidy * Editor: atomic config write via File.Replace fallback; remove redundant backups and racey exists checks * CI: harden NL suite - idempotent docker, gate on unity_ok, safer port probe, least-priv perms * Editor: make atomic config write restoration safe (flag writeDone; copy-overwrite restore; cleanup in finally) * CI: fix fallback JUnit heredoc by using printf lines (no EOF delimiter issues) * CI: switch NL suite to mini prompt; mini prompt honors / and NL discipline * CI: replace claude_args with allowed_tools/model/mcp_config per action schema * CI: expand UNITY_PROJECT_ROOT via in MCP config heredoc * EditorWindow: add cross-platform fallback for File.Replace; macOS-insensitive PathsEqual; safer uv resolve; honor macConfigPath * CI: strengthen JUnit publishing for NL mini suite (normalize, debug list, publish both, fail_on_parse_error) * CI: set job-wide JUNIT_OUT/MD_OUT; normalization uses env; publish references env and ungroup reports * CI: publish a single normalized JUnit (reports/junit-for-actions.xml); fallback writes same; avoid checkName/reportPaths mismatch * CI: align mini prompt report filenames; redact Unity log tail in diagnostics * chore: sync workflow and mini prompt; redacted logs; JUnit normalization/publish tweaks * CI: redact sensitive tokens in Stop Unity; docs: CI usage + edit tools * prompts: update nl-unity-suite-full (mini-style setup + reporting discipline); remove obsolete prompts * CI: harden NL workflows (timeout_minutes, robust normalization); prompts: unify JUnit suite name and reporting discipline * prompts: add guarded write pattern (LF hash, stale_file retry) to full suite * prompts: enforce continue-on-failure, driver flow, and status handling in full suite * Make test list more explicit in prompt. Get rid of old test prompts for hygeine. * prompts: add stale fast-retry (server hash) + in-memory buf guidance * CI: standardize JUNIT_OUT to reports/junit-nl-suite.xml; fix artifact upload indentation; prompt copy cleanups * prompts: reporting discipline — append-only fragments, batch writes, no model round-trip * prompts: stale fast-retry preference, buffer/sha carry, snapshot revert, essential logging * workflows(nl-suite): precreate report skeletons, assemble junit, synthesize markdown; restrict allowed_tools to append-only Bash + MCP tools * thsis too * Update README-DEV.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite-mini.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * workflows(nl-mini): fix YAML indentation/trailing spaces under with: and cleanup heredoc spacing * workflows(nl-suite): fix indentation on docker logs redaction line (YAML lint) * Add write to allowlist * nl-suite: harden reporting discipline (fragment-only writes, forbid alt paths); workflow: clean stray junit-*updated*.xml * nl-suite: enforce end-of-suite single Write (no bash redirection); workflow: restrict allowed_tools to Write+MCP only * prompts(nl-full): end-of-suite results must be valid XML with single <cases> root and only <testcase> children; no raw text outside CDATA * workflows(nl-suite): make Claude step non-fatal; tolerant normalizer extracts <testcase> via regex on bad fragments * nl-suite: fix stale classname to UnityMCP.NL-T in mini fallback; prompt: require re-read after every revert; correct PLAN/PROGRESS to 15 * nl-suite: fix fallback JUnit classname to UnityMCP.NL-T; prompt: forbid create_script and env/mkdir checks, enforce single baseline-byte revert flow and post-revert re-read; add corruption-handling guidance * prompts(nl-full): after each write re-read raw bytes to refresh pre_sha; prefer script_apply_edits for anchors; avoid header/using changes * prompts(nl-full): canonicalize outputs to /; allow small fragment appends via Write or Bash(printf/echo); forbid wrappers and full-file round-trips * prompts(nl-full): finalize markdown formatting for guarded write, execution order, specs, status * workflows(nl-suite, mini): header/lint fixes and constrained Bash append path; align allowed_tools * prompts(nl-full): format Fast Restore, Guarded Write, Execution, Specs, Status as proper markdown lists and code fences * workflows(nl-suite): keep header tidy and append-path alignment with prompt * minor fix * workflows(nl-suite): fix indentation and dispatch; align allowed_tools and revert helper * prompts(nl-full): switch to read_resource for buf/sha; re-read only when needed; convert 'Print this once' to heading; note snapshot helper creates parent dirs * workflows(nl-suite): normalize step removes bootstrap when real testcases present; recompute tests/failures * workflows(nl-suite): enrich Markdown summary by extracting per-test <system-out> blocks (truncated) * clarify prompt resilience instructions * ci(nl-suite): revert prompt and workflow to known-good e0f8a72 for green run; remove extra MD details * ci(nl-suite): minimal fixes — no-mkdir guard in prompt; drop bootstrap and recompute JUnit counts * ci(nl-suite): richer JUnit→Markdown report (per-test system-out) * Small guard to incorret asset read call. * ci(nl-suite): refine MD builder — unescape XML entities, safe code fences, PASS/FAIL badges * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * server(manage_script): robust URI handling — percent-decode file://, normalize, strip host/leading slashes, return Assets-relative if present * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * tests(framing): reduce handshake poll window, nonblocking peek to avoid disconnect race; still enforce pre-handshake data drop * tests(manage_script): add _split_uri tests for unity://path, file:// URLs (decoded/Assets-relative), and plain paths * server+tests: fix handshake syntax error; robust file:// URI normalization in manage_script; add _split_uri tests; adjust stdout scan to ignore venv/site-packages * bridge(framing): accept zero-length frames (treat as empty keepalive) * tests(logging): use errors='replace' on decode fallback to avoid silent drops * resources(list): restrict to Assets/, resolve symlinks, enforce .cs; add traversal/outside-path tests * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * misc: framing keepalive (zero-length), regex preview consistency, resource.list hardening, URI parsing, legacy update routing, test cleanups * docs(tools): richer MCP tool descriptions; tests accept decorator kwargs; resource URI parsing hardened * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * net+docs: hard-reject zero-length frames; TCP_NODELAY on connect; Assets detection case-insensitive; NL prompt statuses aligned * prompt(nl-suite): constrain Write destinations under reports/, forbid traversal * prompt+net: harden Write path rules; use monotonic deadline and plain-text advisory for non-framed peers * unity_connection: restore recv timeout via try/finally; make global connection getter thread-safe with module lock and double-checked init * NL/T prompt: pin structured edit ops for T-D/T-E; add schema-error guarded write behavior; keep existing path/URI and revert rules * unity_connection: add FRAMED_MAX; use ValueError for framed length violations; lower framed receive log to debug; serialize connect() with per-instance lock * ManageScript: use UTF8Encoding(without BOM) for atomic writes in ApplyTextEdits/EditScript to align with Create/Update and avoid BOM-related diffs/hash mismatches * NL/T prompt: make helper deletion regex multiline-safe ((?ms) so ^ anchors line starts) * ManageScript: emit structured overlap status {status:"overlap"} for overlapping edit ranges in apply_text_edits and edit paths * NL/T prompt: clarify fallback vs failure — fallback only for unsupported/missing_field; treat bad_request as failure; note unsupported after fallback as failure * NL/T prompt: pin deterministic overlap probe (apply_text_edits two ranges from same snapshot); gate too_large behind RUN_TOO_LARGE env hint * TB update * NL/T prompt: harden Output Rules — constrain Bash(printf|echo) to stdout-only; forbid redirection/here-docs/tee; only scripts/nlt-revert.sh may mutate FS * Prompt: enumerate allowed script_apply_edits ops; add manage_editor/read_console guidance; fix T‑F atomic batch to single script_apply_edits. ManageScript: regex timeout for diagnostics; symlink ancestor guard; complete allowed-modes list. * Fixes * ManageScript: add rich overlap diagnostics (conflicts + hint) for both text range and structured batch paths * ManageScript: return structured {status:"validation_failed"} diagnostics in create/update/edits and validate before commit * ManageScript: echo canonical uri in responses (create/read/update/apply_text_edits/structured edits) to reinforce resource identity * improve clarity of capabilities message * Framing: allow zero-length frames on both ends (C# bridge, Python server). Prompt: harden T-F to single text-range apply_text_edits batch (descending order, one snapshot). URI: normalize file:// outside Assets by stripping leading slash. * ManageScript: include new sha256 in success payload for apply_text_edits; harden TryResolveUnderAssets by rejecting symlinked ancestors up to Assets/. * remove claudetest dir * manage_script_edits: normalize method-anchored anchor_insert to insert_method (map text->replacement); improves CI compatibility for T‑A/T‑E without changing Editor behavior. * tighten testing protocol around mkdir * manage_script: validate create_script inputs (Assets/.cs/name/no traversal); add Assets/ guard to delete_script; validate level+Assets in validate_script; make legacy manage_script optional params; harden legacy update routing with base64 reuse and payload size preflight. * Tighten prompt for testing * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script_edits: honor ignore_case on anchor_insert and regex_replace in both direct and text-conversion paths (MULTILINE|IGNORECASE). * remove extra file * workflow: use python3 for inline scripts and port detection on ubuntu-latest. * Tighten prompt + manage_script * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script: improve file:// UNC handling; preserve POSIX absolute semantics internally; keep test-expected slash stripping for non-Assets paths. * ManageScript.cs: add TimeSpan timeouts to all Regex uses (IsMatch/Match/new Regex) and keep CultureInvariant/Multiline options; reduces risk of catastrophic backtracking stalls. * workflow: ensure reports/ exists in markdown build step to avoid FileNotFoundError when writing MD_OUT. * fix brace * manage_script_edits: expand backrefs for regex_replace in preview->text conversion and translate to \g<n> in local apply; keeps previews and actual edits consistent. * anchor_insert: default to position=after, normalize surrounding newlines in Python conversion paths; C# path ensures trailing newline and skips duplicate insertion within class. * feat(mcp): add get_sha tool; apply_text_edits normalization+overlap preflight+strict; no-op evidence in C#; update NL suite prompt; add unit tests * feat(frames): accept zero-length heartbeat frames in client; add heartbeat test * feat(edits): guard destructive regex_replace with structural preflight; add robust tests; prompt uses delete_method for temp helper * feat(frames): bound heartbeat loop with timeout/threshold; align zero-length response with C#; update test * SDK hardening: atomic multi-span text edits; stop forcing sequential for structured ops; forward options on apply_text_edits; add validate=relaxed support and scoped checks; update NL/T prompt; add tests for options forwarding, relaxed mode, and atomic batches * Router: default applyMode=atomic for multi-span apply_text_edits; add tests * CI prompt: pass options.validate=relaxed for T-B/C; options.applyMode=atomic for T-F; emphasize always writing testcase and restoring on errors * Validation & DX: add validate=syntax (scoped), standardize evidence windows; early regex compile with hints; debug_preview for apply_text_edits * Update UnityMcpBridge/Editor/Windows/MCPForUnityEditorWindow.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * NL/T suite-driven edits: LongUnityScriptClaudeTest, bridge helpers, server_version; prepare framing tests * Fix duplicate macConfigPath field in McpClient to resolve CS0102 * Editor threading: run EnsureServerInstalled on main thread; marshal EditorPrefs/DeleteKey + logging via delayCall * Docs(apply_text_edits): strengthen guidance on 1-based positions, verify-before-edit, and recommend anchors/structured edits * Docs(script_apply_edits): add safety guidance (anchors, method ops, validators) and recommended practices * Framed VerifyBridgePing in editor window; docs hardening for apply_text_edits and script_apply_edits --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-31 00:55:38 +08:00
"""Compatibility router for legacy script operations.
IMPORTANT:
- Direct file reads should use resources/read.
- Edits should use apply_text_edits.
Args:
Claude‑friendly edit tools + framed transport + live Unity NL test framework (#243) * CI: gate desktop-parity on Anthropic key; pass anthropic_api_key like NL suite * Add quickprobe prompt and CI workflow (mcp-quickprobe.md, unity-mcp-quickprobe.yml) * strictier tool use to prevent subagent spawning and force mcp tools * update workflow filesto reduce likelihood of subagent spawning * improve permissions for claude agent, fix mcpbridge timeout/token issue * increase max turns to 10 * ci: align NL suite to new permissions schema; prevent subagent drift * ci: NL suite -> mini prompt for e2e; add full NL/T prompt; server: ctx optional + project_root fallback; workflows: set UNITY_PROJECT_ROOT for CI * ci: add checks:write; revert local project hardcodes (manifest, ProjectVersion.txt) * tools: text-edit routing fixes (anchor_insert via text, CRLF calc); prompts: mini NL/T clarifications * ci: use absolute UNITY_PROJECT_ROOT; prompts target TestProjects; server: accept relative UNITY_PROJECT_ROOT and bare spec URI * ci: ignore Unity test project's packages-lock.json; remove from repo to avoid absolute paths * CI: start persistent Unity Editor for MCP (guarded by license) + allow batch-mode bridge via UNITY_MCP_ALLOW_BATCH * CI: hide license and pass via env to docker; fix invalid ref format * CI: readiness probe uses handshake on Unity MCP port (deterministic) * CI: fix YAML; use TCP handshake readiness probe (FRAMING=1) * CI: prime Unity license via game-ci; mount ULF into container; extend readiness timeout * CI: use ULF write + mount for Unity licensing; remove serial/email/pass from container * CI: entitlement activation (UNITY_SERIAL=''); verify host ULF cache; keep mount * CI: write ULF from secret and verify; drop entitlement activation step * CI: detect any licensing path; GameCI prime; status dir env; log+probe readiness; fix YAML * CI: add GameCI license prime; conditional ULF write; one-shot license validation; explicit status dir + license env * CI: fix YAML (inline python), add Anthropic key detect via GITHUB_ENV; ready to run happy path * CI: mount Unity token/ulf/cache dirs into container to share host license; create dirs before start * CI: fix YAML indentation; write ULF on host; activate in container with shared mounts; mount .config and .cache too * CI: gate Claude via outputs; mount all Unity license dirs; fix inline probe python; stabilize licensing flow * CI: normalize detect to step outputs; ensure license dirs mounted and validated; fix indentation * Bridge: honor UNITY_MCP_STATUS_DIR for heartbeat/status file (CI-friendly) * CI: guard project path for activation/start; align tool allowlist; run MCP server with python; tighten secret scoping * CI: finalize Unity licensing mounts + status dir; mode-detect (ULF/EBL); readiness logs+probe; Claude gating via outputs * CI: fix YAML probe (inline python -c) and finalize happy-path Unity licensing and MCP/Claude wiring * CI: inline python probe; unify Unity image and cache mounts; ready to test * CI: fix docker run IMAGE placement; ignore cache find perms; keep same editor image * CI: pass -manualLicenseFile to persistent Editor; keep mounts and single image * CI: mount full GameCI cache to /root in persistent Unity; set HOME=/root; add optional license check * CI: make -manualLicenseFile conditional; keep full /root mount and license check * CI: set HOME=/github/home; mount GameCI cache there; adjust manualLicenseFile path; expand license check * CI: EBL sign-in for persistent Unity (email/password/serial); revert HOME=/root and full /root mount; keep conditional manualLicenseFile and improved readiness * CI: run full NL/T suite prompt (nl-unity-suite-full.md) instead of mini * NL/T: require unified diffs + explicit verdicts in JUnit; CI: remove short sanity step, publish JUnit, upload artifacts * NL/T prompt: require CDATA wrapping for JUnit XML fields; guidance for splitting embedded ]]>; keep VERDICT in CDATA only * CI: remove in-container license check step; keep readiness and full suite * NL/T prompt: add version header, stricter JUnit schema, hashing/normalization, anchors, statuses, atomic semantics, tool logging * CI: increase Claude NL/T suite timeout to 30 minutes * CI: pre-create reports dir and result files to avoid tool approval prompts * CI: skip wait if container not running; skip Editor start if project missing; broaden MCP deps detection; expand allowed tools * fixies to harden ManageScript * CI: sanitize NL/T markdown report to avoid NUL/encoding issues * revert breaking yyaml changes * CI: prime license, robust Unity start/wait, sanitize markdown via heredoc * Resolve merge: accept upstream renames/installer (fix/installer-cleanup-v2) and keep local framing/script-editing - Restored upstream server.py, EditorWindow, uv.lock\n- Preserved ManageScript editing/validation; switched to atomic write + debounced refresh\n- Updated tools/__init__.py to keep script_edits/resources and adopt new logger name\n- All Python tests via uv: 7 passed, 6 skipped, 9 xpassed; Unity compile OK * Fix Claude Desktop config path and atomic write issues - Fix macOS path for Claude Desktop config: use ~/Library/Application Support/Claude/ instead of ~/.config/Claude/ - Improve atomic write pattern with backup/restore safety - Replace File.Replace() with File.Move() for better macOS compatibility - Add proper error handling and cleanup for file operations - Resolves issue where installer couldn't find Claude Desktop config on macOS * Editor: use macConfigPath on macOS for MCP client config writes (Claude Desktop, etc.). Fallback to linuxConfigPath only if mac path missing. * Models: add macConfigPath to McpClient for macOS config path selection (fixes CS1061 in editor window). * Editor: on macOS, prefer macConfigPath in ManualConfigEditorWindow (fallback to linux path); Linux/Windows unchanged. * Fix McpClient: align with upstream/main, prep for framing split * NL suite: shard workflow; tighten bridge readiness; add MCP preflight; use env-based shard vars * NL suite: fix shard step indentation; move shard vars to env; remove invalid inputs * MCP clients: split VSCode Copilot config paths into macConfigPath and linuxConfigPath * Unity bridge: clean stale status; bind host; robust wait probe with IPv4/IPv6 + diagnostics * CI: use MCPForUnity.Editor.MCPForUnityBridge.StartAutoConnect as executeMethod * Action wiring: inline mcpServers in settings for all shards; remove redundant .claude/mcp.json step * CI: embed mcpServers in settings for all shards; fix startup sanity step; lint clean * CI: pin claude-code-base-action to e6f32c8; use claude_args --mcp-config; switch to allowed_tools; ensure MCP config per step * CI: unpin claude-code-base-action to @beta (commit ref not found) * CI: align with claude-code-base-action @beta; pass MCP via claude_args and allowedTools * Editor: Fix apply_text_edits heuristic when edits shift positions; recompute method span on candidate text with fallback delta adjustment * CI: unify MCP wiring across workflows; write .claude/mcp.json; switch to claude_args with --mcp-config/--allowedTools; remove unsupported inputs * CI: collapse NL suite shards into a single run to avoid repeated test execution * CI: minimize allowedTools for NL suite to essential Unity MCP + Bash("git:*") + Write * CI: mkdir -p reports before run; remove unsupported --timeout-minutes from claude_args * CI: broaden allowedTools to include find_in_file and mcp__unity__* * CI: enable use_node_cache and switch NL suite model to claude-3-7-haiku-20250219 * CI: disable use_node_cache to avoid setup-node lockfile error * CI: set NL suite model to claude-3-haiku-20240307 * CI: cap Haiku output with --max-tokens 2048 for NL suite * CI: switch to claude-3-7-sonnet-latest and remove unsupported --max-tokens * CI: update allowedTools to Bash(*) and explicit Unity MCP tool list * CI: update NL suite workflow (latest tweaks) * Tests: tighten NL suite prompt for logging, hash discipline, stale retry, evidence windows, diff cap, and VERDICT line * Add disallowed tools to NL suite workflow * docs: clarify stale write retry * Add fallback JUnit report and adjust publisher * Indent fallback JUnit XML in workflow * fix: correct fallback JUnit report generation * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update Response.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update MCPForUnityBridge.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: correct McpTypes reference * Add directory existence checks for symlink and XDG paths * fix: only set installation flag after successful server install * Update resource_tools.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: respect mac config paths * Use File.Replace for atomic config write * Remove unused imports in manage_script * bump server version * Tests: update NL suite prompt and workflows; remove deprecated smoke/desktop-parity; quickprobe tidy * Editor: atomic config write via File.Replace fallback; remove redundant backups and racey exists checks * CI: harden NL suite - idempotent docker, gate on unity_ok, safer port probe, least-priv perms * Editor: make atomic config write restoration safe (flag writeDone; copy-overwrite restore; cleanup in finally) * CI: fix fallback JUnit heredoc by using printf lines (no EOF delimiter issues) * CI: switch NL suite to mini prompt; mini prompt honors / and NL discipline * CI: replace claude_args with allowed_tools/model/mcp_config per action schema * CI: expand UNITY_PROJECT_ROOT via in MCP config heredoc * EditorWindow: add cross-platform fallback for File.Replace; macOS-insensitive PathsEqual; safer uv resolve; honor macConfigPath * CI: strengthen JUnit publishing for NL mini suite (normalize, debug list, publish both, fail_on_parse_error) * CI: set job-wide JUNIT_OUT/MD_OUT; normalization uses env; publish references env and ungroup reports * CI: publish a single normalized JUnit (reports/junit-for-actions.xml); fallback writes same; avoid checkName/reportPaths mismatch * CI: align mini prompt report filenames; redact Unity log tail in diagnostics * chore: sync workflow and mini prompt; redacted logs; JUnit normalization/publish tweaks * CI: redact sensitive tokens in Stop Unity; docs: CI usage + edit tools * prompts: update nl-unity-suite-full (mini-style setup + reporting discipline); remove obsolete prompts * CI: harden NL workflows (timeout_minutes, robust normalization); prompts: unify JUnit suite name and reporting discipline * prompts: add guarded write pattern (LF hash, stale_file retry) to full suite * prompts: enforce continue-on-failure, driver flow, and status handling in full suite * Make test list more explicit in prompt. Get rid of old test prompts for hygeine. * prompts: add stale fast-retry (server hash) + in-memory buf guidance * CI: standardize JUNIT_OUT to reports/junit-nl-suite.xml; fix artifact upload indentation; prompt copy cleanups * prompts: reporting discipline — append-only fragments, batch writes, no model round-trip * prompts: stale fast-retry preference, buffer/sha carry, snapshot revert, essential logging * workflows(nl-suite): precreate report skeletons, assemble junit, synthesize markdown; restrict allowed_tools to append-only Bash + MCP tools * thsis too * Update README-DEV.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite-mini.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * workflows(nl-mini): fix YAML indentation/trailing spaces under with: and cleanup heredoc spacing * workflows(nl-suite): fix indentation on docker logs redaction line (YAML lint) * Add write to allowlist * nl-suite: harden reporting discipline (fragment-only writes, forbid alt paths); workflow: clean stray junit-*updated*.xml * nl-suite: enforce end-of-suite single Write (no bash redirection); workflow: restrict allowed_tools to Write+MCP only * prompts(nl-full): end-of-suite results must be valid XML with single <cases> root and only <testcase> children; no raw text outside CDATA * workflows(nl-suite): make Claude step non-fatal; tolerant normalizer extracts <testcase> via regex on bad fragments * nl-suite: fix stale classname to UnityMCP.NL-T in mini fallback; prompt: require re-read after every revert; correct PLAN/PROGRESS to 15 * nl-suite: fix fallback JUnit classname to UnityMCP.NL-T; prompt: forbid create_script and env/mkdir checks, enforce single baseline-byte revert flow and post-revert re-read; add corruption-handling guidance * prompts(nl-full): after each write re-read raw bytes to refresh pre_sha; prefer script_apply_edits for anchors; avoid header/using changes * prompts(nl-full): canonicalize outputs to /; allow small fragment appends via Write or Bash(printf/echo); forbid wrappers and full-file round-trips * prompts(nl-full): finalize markdown formatting for guarded write, execution order, specs, status * workflows(nl-suite, mini): header/lint fixes and constrained Bash append path; align allowed_tools * prompts(nl-full): format Fast Restore, Guarded Write, Execution, Specs, Status as proper markdown lists and code fences * workflows(nl-suite): keep header tidy and append-path alignment with prompt * minor fix * workflows(nl-suite): fix indentation and dispatch; align allowed_tools and revert helper * prompts(nl-full): switch to read_resource for buf/sha; re-read only when needed; convert 'Print this once' to heading; note snapshot helper creates parent dirs * workflows(nl-suite): normalize step removes bootstrap when real testcases present; recompute tests/failures * workflows(nl-suite): enrich Markdown summary by extracting per-test <system-out> blocks (truncated) * clarify prompt resilience instructions * ci(nl-suite): revert prompt and workflow to known-good e0f8a72 for green run; remove extra MD details * ci(nl-suite): minimal fixes — no-mkdir guard in prompt; drop bootstrap and recompute JUnit counts * ci(nl-suite): richer JUnit→Markdown report (per-test system-out) * Small guard to incorret asset read call. * ci(nl-suite): refine MD builder — unescape XML entities, safe code fences, PASS/FAIL badges * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * server(manage_script): robust URI handling — percent-decode file://, normalize, strip host/leading slashes, return Assets-relative if present * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * tests(framing): reduce handshake poll window, nonblocking peek to avoid disconnect race; still enforce pre-handshake data drop * tests(manage_script): add _split_uri tests for unity://path, file:// URLs (decoded/Assets-relative), and plain paths * server+tests: fix handshake syntax error; robust file:// URI normalization in manage_script; add _split_uri tests; adjust stdout scan to ignore venv/site-packages * bridge(framing): accept zero-length frames (treat as empty keepalive) * tests(logging): use errors='replace' on decode fallback to avoid silent drops * resources(list): restrict to Assets/, resolve symlinks, enforce .cs; add traversal/outside-path tests * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * misc: framing keepalive (zero-length), regex preview consistency, resource.list hardening, URI parsing, legacy update routing, test cleanups * docs(tools): richer MCP tool descriptions; tests accept decorator kwargs; resource URI parsing hardened * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * net+docs: hard-reject zero-length frames; TCP_NODELAY on connect; Assets detection case-insensitive; NL prompt statuses aligned * prompt(nl-suite): constrain Write destinations under reports/, forbid traversal * prompt+net: harden Write path rules; use monotonic deadline and plain-text advisory for non-framed peers * unity_connection: restore recv timeout via try/finally; make global connection getter thread-safe with module lock and double-checked init * NL/T prompt: pin structured edit ops for T-D/T-E; add schema-error guarded write behavior; keep existing path/URI and revert rules * unity_connection: add FRAMED_MAX; use ValueError for framed length violations; lower framed receive log to debug; serialize connect() with per-instance lock * ManageScript: use UTF8Encoding(without BOM) for atomic writes in ApplyTextEdits/EditScript to align with Create/Update and avoid BOM-related diffs/hash mismatches * NL/T prompt: make helper deletion regex multiline-safe ((?ms) so ^ anchors line starts) * ManageScript: emit structured overlap status {status:"overlap"} for overlapping edit ranges in apply_text_edits and edit paths * NL/T prompt: clarify fallback vs failure — fallback only for unsupported/missing_field; treat bad_request as failure; note unsupported after fallback as failure * NL/T prompt: pin deterministic overlap probe (apply_text_edits two ranges from same snapshot); gate too_large behind RUN_TOO_LARGE env hint * TB update * NL/T prompt: harden Output Rules — constrain Bash(printf|echo) to stdout-only; forbid redirection/here-docs/tee; only scripts/nlt-revert.sh may mutate FS * Prompt: enumerate allowed script_apply_edits ops; add manage_editor/read_console guidance; fix T‑F atomic batch to single script_apply_edits. ManageScript: regex timeout for diagnostics; symlink ancestor guard; complete allowed-modes list. * Fixes * ManageScript: add rich overlap diagnostics (conflicts + hint) for both text range and structured batch paths * ManageScript: return structured {status:"validation_failed"} diagnostics in create/update/edits and validate before commit * ManageScript: echo canonical uri in responses (create/read/update/apply_text_edits/structured edits) to reinforce resource identity * improve clarity of capabilities message * Framing: allow zero-length frames on both ends (C# bridge, Python server). Prompt: harden T-F to single text-range apply_text_edits batch (descending order, one snapshot). URI: normalize file:// outside Assets by stripping leading slash. * ManageScript: include new sha256 in success payload for apply_text_edits; harden TryResolveUnderAssets by rejecting symlinked ancestors up to Assets/. * remove claudetest dir * manage_script_edits: normalize method-anchored anchor_insert to insert_method (map text->replacement); improves CI compatibility for T‑A/T‑E without changing Editor behavior. * tighten testing protocol around mkdir * manage_script: validate create_script inputs (Assets/.cs/name/no traversal); add Assets/ guard to delete_script; validate level+Assets in validate_script; make legacy manage_script optional params; harden legacy update routing with base64 reuse and payload size preflight. * Tighten prompt for testing * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script_edits: honor ignore_case on anchor_insert and regex_replace in both direct and text-conversion paths (MULTILINE|IGNORECASE). * remove extra file * workflow: use python3 for inline scripts and port detection on ubuntu-latest. * Tighten prompt + manage_script * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script: improve file:// UNC handling; preserve POSIX absolute semantics internally; keep test-expected slash stripping for non-Assets paths. * ManageScript.cs: add TimeSpan timeouts to all Regex uses (IsMatch/Match/new Regex) and keep CultureInvariant/Multiline options; reduces risk of catastrophic backtracking stalls. * workflow: ensure reports/ exists in markdown build step to avoid FileNotFoundError when writing MD_OUT. * fix brace * manage_script_edits: expand backrefs for regex_replace in preview->text conversion and translate to \g<n> in local apply; keeps previews and actual edits consistent. * anchor_insert: default to position=after, normalize surrounding newlines in Python conversion paths; C# path ensures trailing newline and skips duplicate insertion within class. * feat(mcp): add get_sha tool; apply_text_edits normalization+overlap preflight+strict; no-op evidence in C#; update NL suite prompt; add unit tests * feat(frames): accept zero-length heartbeat frames in client; add heartbeat test * feat(edits): guard destructive regex_replace with structural preflight; add robust tests; prompt uses delete_method for temp helper * feat(frames): bound heartbeat loop with timeout/threshold; align zero-length response with C#; update test * SDK hardening: atomic multi-span text edits; stop forcing sequential for structured ops; forward options on apply_text_edits; add validate=relaxed support and scoped checks; update NL/T prompt; add tests for options forwarding, relaxed mode, and atomic batches * Router: default applyMode=atomic for multi-span apply_text_edits; add tests * CI prompt: pass options.validate=relaxed for T-B/C; options.applyMode=atomic for T-F; emphasize always writing testcase and restoring on errors * Validation & DX: add validate=syntax (scoped), standardize evidence windows; early regex compile with hints; debug_preview for apply_text_edits * Update UnityMcpBridge/Editor/Windows/MCPForUnityEditorWindow.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * NL/T suite-driven edits: LongUnityScriptClaudeTest, bridge helpers, server_version; prepare framing tests * Fix duplicate macConfigPath field in McpClient to resolve CS0102 * Editor threading: run EnsureServerInstalled on main thread; marshal EditorPrefs/DeleteKey + logging via delayCall * Docs(apply_text_edits): strengthen guidance on 1-based positions, verify-before-edit, and recommend anchors/structured edits * Docs(script_apply_edits): add safety guidance (anchors, method ops, validators) and recommended practices * Framed VerifyBridgePing in editor window; docs hardening for apply_text_edits and script_apply_edits --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-31 00:55:38 +08:00
action: Operation ('create', 'read', 'delete').
name: Script name (no .cs extension).
path: Asset path (default: "Assets/").
contents: C# code for 'create'/'update'.
script_type: Type hint (e.g., 'MonoBehaviour').
namespace: Script namespace.
Returns:
Dictionary with results ('success', 'message', 'data').
"""
try:
Claude‑friendly edit tools + framed transport + live Unity NL test framework (#243) * CI: gate desktop-parity on Anthropic key; pass anthropic_api_key like NL suite * Add quickprobe prompt and CI workflow (mcp-quickprobe.md, unity-mcp-quickprobe.yml) * strictier tool use to prevent subagent spawning and force mcp tools * update workflow filesto reduce likelihood of subagent spawning * improve permissions for claude agent, fix mcpbridge timeout/token issue * increase max turns to 10 * ci: align NL suite to new permissions schema; prevent subagent drift * ci: NL suite -> mini prompt for e2e; add full NL/T prompt; server: ctx optional + project_root fallback; workflows: set UNITY_PROJECT_ROOT for CI * ci: add checks:write; revert local project hardcodes (manifest, ProjectVersion.txt) * tools: text-edit routing fixes (anchor_insert via text, CRLF calc); prompts: mini NL/T clarifications * ci: use absolute UNITY_PROJECT_ROOT; prompts target TestProjects; server: accept relative UNITY_PROJECT_ROOT and bare spec URI * ci: ignore Unity test project's packages-lock.json; remove from repo to avoid absolute paths * CI: start persistent Unity Editor for MCP (guarded by license) + allow batch-mode bridge via UNITY_MCP_ALLOW_BATCH * CI: hide license and pass via env to docker; fix invalid ref format * CI: readiness probe uses handshake on Unity MCP port (deterministic) * CI: fix YAML; use TCP handshake readiness probe (FRAMING=1) * CI: prime Unity license via game-ci; mount ULF into container; extend readiness timeout * CI: use ULF write + mount for Unity licensing; remove serial/email/pass from container * CI: entitlement activation (UNITY_SERIAL=''); verify host ULF cache; keep mount * CI: write ULF from secret and verify; drop entitlement activation step * CI: detect any licensing path; GameCI prime; status dir env; log+probe readiness; fix YAML * CI: add GameCI license prime; conditional ULF write; one-shot license validation; explicit status dir + license env * CI: fix YAML (inline python), add Anthropic key detect via GITHUB_ENV; ready to run happy path * CI: mount Unity token/ulf/cache dirs into container to share host license; create dirs before start * CI: fix YAML indentation; write ULF on host; activate in container with shared mounts; mount .config and .cache too * CI: gate Claude via outputs; mount all Unity license dirs; fix inline probe python; stabilize licensing flow * CI: normalize detect to step outputs; ensure license dirs mounted and validated; fix indentation * Bridge: honor UNITY_MCP_STATUS_DIR for heartbeat/status file (CI-friendly) * CI: guard project path for activation/start; align tool allowlist; run MCP server with python; tighten secret scoping * CI: finalize Unity licensing mounts + status dir; mode-detect (ULF/EBL); readiness logs+probe; Claude gating via outputs * CI: fix YAML probe (inline python -c) and finalize happy-path Unity licensing and MCP/Claude wiring * CI: inline python probe; unify Unity image and cache mounts; ready to test * CI: fix docker run IMAGE placement; ignore cache find perms; keep same editor image * CI: pass -manualLicenseFile to persistent Editor; keep mounts and single image * CI: mount full GameCI cache to /root in persistent Unity; set HOME=/root; add optional license check * CI: make -manualLicenseFile conditional; keep full /root mount and license check * CI: set HOME=/github/home; mount GameCI cache there; adjust manualLicenseFile path; expand license check * CI: EBL sign-in for persistent Unity (email/password/serial); revert HOME=/root and full /root mount; keep conditional manualLicenseFile and improved readiness * CI: run full NL/T suite prompt (nl-unity-suite-full.md) instead of mini * NL/T: require unified diffs + explicit verdicts in JUnit; CI: remove short sanity step, publish JUnit, upload artifacts * NL/T prompt: require CDATA wrapping for JUnit XML fields; guidance for splitting embedded ]]>; keep VERDICT in CDATA only * CI: remove in-container license check step; keep readiness and full suite * NL/T prompt: add version header, stricter JUnit schema, hashing/normalization, anchors, statuses, atomic semantics, tool logging * CI: increase Claude NL/T suite timeout to 30 minutes * CI: pre-create reports dir and result files to avoid tool approval prompts * CI: skip wait if container not running; skip Editor start if project missing; broaden MCP deps detection; expand allowed tools * fixies to harden ManageScript * CI: sanitize NL/T markdown report to avoid NUL/encoding issues * revert breaking yyaml changes * CI: prime license, robust Unity start/wait, sanitize markdown via heredoc * Resolve merge: accept upstream renames/installer (fix/installer-cleanup-v2) and keep local framing/script-editing - Restored upstream server.py, EditorWindow, uv.lock\n- Preserved ManageScript editing/validation; switched to atomic write + debounced refresh\n- Updated tools/__init__.py to keep script_edits/resources and adopt new logger name\n- All Python tests via uv: 7 passed, 6 skipped, 9 xpassed; Unity compile OK * Fix Claude Desktop config path and atomic write issues - Fix macOS path for Claude Desktop config: use ~/Library/Application Support/Claude/ instead of ~/.config/Claude/ - Improve atomic write pattern with backup/restore safety - Replace File.Replace() with File.Move() for better macOS compatibility - Add proper error handling and cleanup for file operations - Resolves issue where installer couldn't find Claude Desktop config on macOS * Editor: use macConfigPath on macOS for MCP client config writes (Claude Desktop, etc.). Fallback to linuxConfigPath only if mac path missing. * Models: add macConfigPath to McpClient for macOS config path selection (fixes CS1061 in editor window). * Editor: on macOS, prefer macConfigPath in ManualConfigEditorWindow (fallback to linux path); Linux/Windows unchanged. * Fix McpClient: align with upstream/main, prep for framing split * NL suite: shard workflow; tighten bridge readiness; add MCP preflight; use env-based shard vars * NL suite: fix shard step indentation; move shard vars to env; remove invalid inputs * MCP clients: split VSCode Copilot config paths into macConfigPath and linuxConfigPath * Unity bridge: clean stale status; bind host; robust wait probe with IPv4/IPv6 + diagnostics * CI: use MCPForUnity.Editor.MCPForUnityBridge.StartAutoConnect as executeMethod * Action wiring: inline mcpServers in settings for all shards; remove redundant .claude/mcp.json step * CI: embed mcpServers in settings for all shards; fix startup sanity step; lint clean * CI: pin claude-code-base-action to e6f32c8; use claude_args --mcp-config; switch to allowed_tools; ensure MCP config per step * CI: unpin claude-code-base-action to @beta (commit ref not found) * CI: align with claude-code-base-action @beta; pass MCP via claude_args and allowedTools * Editor: Fix apply_text_edits heuristic when edits shift positions; recompute method span on candidate text with fallback delta adjustment * CI: unify MCP wiring across workflows; write .claude/mcp.json; switch to claude_args with --mcp-config/--allowedTools; remove unsupported inputs * CI: collapse NL suite shards into a single run to avoid repeated test execution * CI: minimize allowedTools for NL suite to essential Unity MCP + Bash("git:*") + Write * CI: mkdir -p reports before run; remove unsupported --timeout-minutes from claude_args * CI: broaden allowedTools to include find_in_file and mcp__unity__* * CI: enable use_node_cache and switch NL suite model to claude-3-7-haiku-20250219 * CI: disable use_node_cache to avoid setup-node lockfile error * CI: set NL suite model to claude-3-haiku-20240307 * CI: cap Haiku output with --max-tokens 2048 for NL suite * CI: switch to claude-3-7-sonnet-latest and remove unsupported --max-tokens * CI: update allowedTools to Bash(*) and explicit Unity MCP tool list * CI: update NL suite workflow (latest tweaks) * Tests: tighten NL suite prompt for logging, hash discipline, stale retry, evidence windows, diff cap, and VERDICT line * Add disallowed tools to NL suite workflow * docs: clarify stale write retry * Add fallback JUnit report and adjust publisher * Indent fallback JUnit XML in workflow * fix: correct fallback JUnit report generation * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update Response.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update MCPForUnityBridge.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: correct McpTypes reference * Add directory existence checks for symlink and XDG paths * fix: only set installation flag after successful server install * Update resource_tools.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: respect mac config paths * Use File.Replace for atomic config write * Remove unused imports in manage_script * bump server version * Tests: update NL suite prompt and workflows; remove deprecated smoke/desktop-parity; quickprobe tidy * Editor: atomic config write via File.Replace fallback; remove redundant backups and racey exists checks * CI: harden NL suite - idempotent docker, gate on unity_ok, safer port probe, least-priv perms * Editor: make atomic config write restoration safe (flag writeDone; copy-overwrite restore; cleanup in finally) * CI: fix fallback JUnit heredoc by using printf lines (no EOF delimiter issues) * CI: switch NL suite to mini prompt; mini prompt honors / and NL discipline * CI: replace claude_args with allowed_tools/model/mcp_config per action schema * CI: expand UNITY_PROJECT_ROOT via in MCP config heredoc * EditorWindow: add cross-platform fallback for File.Replace; macOS-insensitive PathsEqual; safer uv resolve; honor macConfigPath * CI: strengthen JUnit publishing for NL mini suite (normalize, debug list, publish both, fail_on_parse_error) * CI: set job-wide JUNIT_OUT/MD_OUT; normalization uses env; publish references env and ungroup reports * CI: publish a single normalized JUnit (reports/junit-for-actions.xml); fallback writes same; avoid checkName/reportPaths mismatch * CI: align mini prompt report filenames; redact Unity log tail in diagnostics * chore: sync workflow and mini prompt; redacted logs; JUnit normalization/publish tweaks * CI: redact sensitive tokens in Stop Unity; docs: CI usage + edit tools * prompts: update nl-unity-suite-full (mini-style setup + reporting discipline); remove obsolete prompts * CI: harden NL workflows (timeout_minutes, robust normalization); prompts: unify JUnit suite name and reporting discipline * prompts: add guarded write pattern (LF hash, stale_file retry) to full suite * prompts: enforce continue-on-failure, driver flow, and status handling in full suite * Make test list more explicit in prompt. Get rid of old test prompts for hygeine. * prompts: add stale fast-retry (server hash) + in-memory buf guidance * CI: standardize JUNIT_OUT to reports/junit-nl-suite.xml; fix artifact upload indentation; prompt copy cleanups * prompts: reporting discipline — append-only fragments, batch writes, no model round-trip * prompts: stale fast-retry preference, buffer/sha carry, snapshot revert, essential logging * workflows(nl-suite): precreate report skeletons, assemble junit, synthesize markdown; restrict allowed_tools to append-only Bash + MCP tools * thsis too * Update README-DEV.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite-mini.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * workflows(nl-mini): fix YAML indentation/trailing spaces under with: and cleanup heredoc spacing * workflows(nl-suite): fix indentation on docker logs redaction line (YAML lint) * Add write to allowlist * nl-suite: harden reporting discipline (fragment-only writes, forbid alt paths); workflow: clean stray junit-*updated*.xml * nl-suite: enforce end-of-suite single Write (no bash redirection); workflow: restrict allowed_tools to Write+MCP only * prompts(nl-full): end-of-suite results must be valid XML with single <cases> root and only <testcase> children; no raw text outside CDATA * workflows(nl-suite): make Claude step non-fatal; tolerant normalizer extracts <testcase> via regex on bad fragments * nl-suite: fix stale classname to UnityMCP.NL-T in mini fallback; prompt: require re-read after every revert; correct PLAN/PROGRESS to 15 * nl-suite: fix fallback JUnit classname to UnityMCP.NL-T; prompt: forbid create_script and env/mkdir checks, enforce single baseline-byte revert flow and post-revert re-read; add corruption-handling guidance * prompts(nl-full): after each write re-read raw bytes to refresh pre_sha; prefer script_apply_edits for anchors; avoid header/using changes * prompts(nl-full): canonicalize outputs to /; allow small fragment appends via Write or Bash(printf/echo); forbid wrappers and full-file round-trips * prompts(nl-full): finalize markdown formatting for guarded write, execution order, specs, status * workflows(nl-suite, mini): header/lint fixes and constrained Bash append path; align allowed_tools * prompts(nl-full): format Fast Restore, Guarded Write, Execution, Specs, Status as proper markdown lists and code fences * workflows(nl-suite): keep header tidy and append-path alignment with prompt * minor fix * workflows(nl-suite): fix indentation and dispatch; align allowed_tools and revert helper * prompts(nl-full): switch to read_resource for buf/sha; re-read only when needed; convert 'Print this once' to heading; note snapshot helper creates parent dirs * workflows(nl-suite): normalize step removes bootstrap when real testcases present; recompute tests/failures * workflows(nl-suite): enrich Markdown summary by extracting per-test <system-out> blocks (truncated) * clarify prompt resilience instructions * ci(nl-suite): revert prompt and workflow to known-good e0f8a72 for green run; remove extra MD details * ci(nl-suite): minimal fixes — no-mkdir guard in prompt; drop bootstrap and recompute JUnit counts * ci(nl-suite): richer JUnit→Markdown report (per-test system-out) * Small guard to incorret asset read call. * ci(nl-suite): refine MD builder — unescape XML entities, safe code fences, PASS/FAIL badges * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * server(manage_script): robust URI handling — percent-decode file://, normalize, strip host/leading slashes, return Assets-relative if present * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * tests(framing): reduce handshake poll window, nonblocking peek to avoid disconnect race; still enforce pre-handshake data drop * tests(manage_script): add _split_uri tests for unity://path, file:// URLs (decoded/Assets-relative), and plain paths * server+tests: fix handshake syntax error; robust file:// URI normalization in manage_script; add _split_uri tests; adjust stdout scan to ignore venv/site-packages * bridge(framing): accept zero-length frames (treat as empty keepalive) * tests(logging): use errors='replace' on decode fallback to avoid silent drops * resources(list): restrict to Assets/, resolve symlinks, enforce .cs; add traversal/outside-path tests * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * misc: framing keepalive (zero-length), regex preview consistency, resource.list hardening, URI parsing, legacy update routing, test cleanups * docs(tools): richer MCP tool descriptions; tests accept decorator kwargs; resource URI parsing hardened * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * net+docs: hard-reject zero-length frames; TCP_NODELAY on connect; Assets detection case-insensitive; NL prompt statuses aligned * prompt(nl-suite): constrain Write destinations under reports/, forbid traversal * prompt+net: harden Write path rules; use monotonic deadline and plain-text advisory for non-framed peers * unity_connection: restore recv timeout via try/finally; make global connection getter thread-safe with module lock and double-checked init * NL/T prompt: pin structured edit ops for T-D/T-E; add schema-error guarded write behavior; keep existing path/URI and revert rules * unity_connection: add FRAMED_MAX; use ValueError for framed length violations; lower framed receive log to debug; serialize connect() with per-instance lock * ManageScript: use UTF8Encoding(without BOM) for atomic writes in ApplyTextEdits/EditScript to align with Create/Update and avoid BOM-related diffs/hash mismatches * NL/T prompt: make helper deletion regex multiline-safe ((?ms) so ^ anchors line starts) * ManageScript: emit structured overlap status {status:"overlap"} for overlapping edit ranges in apply_text_edits and edit paths * NL/T prompt: clarify fallback vs failure — fallback only for unsupported/missing_field; treat bad_request as failure; note unsupported after fallback as failure * NL/T prompt: pin deterministic overlap probe (apply_text_edits two ranges from same snapshot); gate too_large behind RUN_TOO_LARGE env hint * TB update * NL/T prompt: harden Output Rules — constrain Bash(printf|echo) to stdout-only; forbid redirection/here-docs/tee; only scripts/nlt-revert.sh may mutate FS * Prompt: enumerate allowed script_apply_edits ops; add manage_editor/read_console guidance; fix T‑F atomic batch to single script_apply_edits. ManageScript: regex timeout for diagnostics; symlink ancestor guard; complete allowed-modes list. * Fixes * ManageScript: add rich overlap diagnostics (conflicts + hint) for both text range and structured batch paths * ManageScript: return structured {status:"validation_failed"} diagnostics in create/update/edits and validate before commit * ManageScript: echo canonical uri in responses (create/read/update/apply_text_edits/structured edits) to reinforce resource identity * improve clarity of capabilities message * Framing: allow zero-length frames on both ends (C# bridge, Python server). Prompt: harden T-F to single text-range apply_text_edits batch (descending order, one snapshot). URI: normalize file:// outside Assets by stripping leading slash. * ManageScript: include new sha256 in success payload for apply_text_edits; harden TryResolveUnderAssets by rejecting symlinked ancestors up to Assets/. * remove claudetest dir * manage_script_edits: normalize method-anchored anchor_insert to insert_method (map text->replacement); improves CI compatibility for T‑A/T‑E without changing Editor behavior. * tighten testing protocol around mkdir * manage_script: validate create_script inputs (Assets/.cs/name/no traversal); add Assets/ guard to delete_script; validate level+Assets in validate_script; make legacy manage_script optional params; harden legacy update routing with base64 reuse and payload size preflight. * Tighten prompt for testing * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script_edits: honor ignore_case on anchor_insert and regex_replace in both direct and text-conversion paths (MULTILINE|IGNORECASE). * remove extra file * workflow: use python3 for inline scripts and port detection on ubuntu-latest. * Tighten prompt + manage_script * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script: improve file:// UNC handling; preserve POSIX absolute semantics internally; keep test-expected slash stripping for non-Assets paths. * ManageScript.cs: add TimeSpan timeouts to all Regex uses (IsMatch/Match/new Regex) and keep CultureInvariant/Multiline options; reduces risk of catastrophic backtracking stalls. * workflow: ensure reports/ exists in markdown build step to avoid FileNotFoundError when writing MD_OUT. * fix brace * manage_script_edits: expand backrefs for regex_replace in preview->text conversion and translate to \g<n> in local apply; keeps previews and actual edits consistent. * anchor_insert: default to position=after, normalize surrounding newlines in Python conversion paths; C# path ensures trailing newline and skips duplicate insertion within class. * feat(mcp): add get_sha tool; apply_text_edits normalization+overlap preflight+strict; no-op evidence in C#; update NL suite prompt; add unit tests * feat(frames): accept zero-length heartbeat frames in client; add heartbeat test * feat(edits): guard destructive regex_replace with structural preflight; add robust tests; prompt uses delete_method for temp helper * feat(frames): bound heartbeat loop with timeout/threshold; align zero-length response with C#; update test * SDK hardening: atomic multi-span text edits; stop forcing sequential for structured ops; forward options on apply_text_edits; add validate=relaxed support and scoped checks; update NL/T prompt; add tests for options forwarding, relaxed mode, and atomic batches * Router: default applyMode=atomic for multi-span apply_text_edits; add tests * CI prompt: pass options.validate=relaxed for T-B/C; options.applyMode=atomic for T-F; emphasize always writing testcase and restoring on errors * Validation & DX: add validate=syntax (scoped), standardize evidence windows; early regex compile with hints; debug_preview for apply_text_edits * Update UnityMcpBridge/Editor/Windows/MCPForUnityEditorWindow.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * NL/T suite-driven edits: LongUnityScriptClaudeTest, bridge helpers, server_version; prepare framing tests * Fix duplicate macConfigPath field in McpClient to resolve CS0102 * Editor threading: run EnsureServerInstalled on main thread; marshal EditorPrefs/DeleteKey + logging via delayCall * Docs(apply_text_edits): strengthen guidance on 1-based positions, verify-before-edit, and recommend anchors/structured edits * Docs(script_apply_edits): add safety guidance (anchors, method ops, validators) and recommended practices * Framed VerifyBridgePing in editor window; docs hardening for apply_text_edits and script_apply_edits --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-31 00:55:38 +08:00
# Graceful migration for legacy 'update': route to apply_text_edits (whole-file replace)
if action == 'update':
try:
# 1) Read current contents to compute end range and precondition
read_resp = send_command_with_retry("manage_script", {
"action": "read",
"name": name,
"path": path,
})
if not (isinstance(read_resp, dict) and read_resp.get("success")):
return {"success": False, "code": "deprecated_update", "message": "Use apply_text_edits; automatic migration failed to read current file."}
data = read_resp.get("data", {})
current = data.get("contents")
if not current and data.get("contentsEncoded"):
current = base64.b64decode(data.get("encodedContents", "").encode("utf-8")).decode("utf-8", "replace")
if current is None:
return {"success": False, "code": "deprecated_update", "message": "Use apply_text_edits; current file read returned no contents."}
# 2) Compute whole-file range (1-based, end exclusive) and SHA
import hashlib as _hashlib
old_lines = current.splitlines(keepends=True)
end_line = len(old_lines) + 1
sha = _hashlib.sha256(current.encode("utf-8")).hexdigest()
# 3) Apply single whole-file text edit with provided 'contents'
edits = [{
"startLine": 1,
"startCol": 1,
"endLine": end_line,
"endCol": 1,
"newText": contents or "",
}]
route_params = {
"action": "apply_text_edits",
"name": name,
"path": path,
"edits": edits,
"precondition_sha256": sha,
"options": {"refresh": "immediate", "validate": "standard"},
}
# Preflight size vs. default cap (256 KiB) to avoid opaque server errors
try:
import json as _json
payload_bytes = len(_json.dumps({"edits": edits}, ensure_ascii=False).encode("utf-8"))
if payload_bytes > 256 * 1024:
return {"success": False, "code": "payload_too_large", "message": f"Edit payload {payload_bytes} bytes exceeds 256 KiB cap; try structured ops or chunking."}
except Exception:
pass
routed = send_command_with_retry("manage_script", route_params)
if isinstance(routed, dict):
routed.setdefault("message", "Routed legacy update to apply_text_edits")
return routed
return {"success": False, "message": str(routed)}
except Exception as e:
return {"success": False, "code": "deprecated_update", "message": f"Use apply_text_edits; migration error: {e}"}
# Prepare parameters for Unity
params = {
"action": action,
"name": name,
"path": path,
"namespace": namespace,
Claude‑friendly edit tools + framed transport + live Unity NL test framework (#243) * CI: gate desktop-parity on Anthropic key; pass anthropic_api_key like NL suite * Add quickprobe prompt and CI workflow (mcp-quickprobe.md, unity-mcp-quickprobe.yml) * strictier tool use to prevent subagent spawning and force mcp tools * update workflow filesto reduce likelihood of subagent spawning * improve permissions for claude agent, fix mcpbridge timeout/token issue * increase max turns to 10 * ci: align NL suite to new permissions schema; prevent subagent drift * ci: NL suite -> mini prompt for e2e; add full NL/T prompt; server: ctx optional + project_root fallback; workflows: set UNITY_PROJECT_ROOT for CI * ci: add checks:write; revert local project hardcodes (manifest, ProjectVersion.txt) * tools: text-edit routing fixes (anchor_insert via text, CRLF calc); prompts: mini NL/T clarifications * ci: use absolute UNITY_PROJECT_ROOT; prompts target TestProjects; server: accept relative UNITY_PROJECT_ROOT and bare spec URI * ci: ignore Unity test project's packages-lock.json; remove from repo to avoid absolute paths * CI: start persistent Unity Editor for MCP (guarded by license) + allow batch-mode bridge via UNITY_MCP_ALLOW_BATCH * CI: hide license and pass via env to docker; fix invalid ref format * CI: readiness probe uses handshake on Unity MCP port (deterministic) * CI: fix YAML; use TCP handshake readiness probe (FRAMING=1) * CI: prime Unity license via game-ci; mount ULF into container; extend readiness timeout * CI: use ULF write + mount for Unity licensing; remove serial/email/pass from container * CI: entitlement activation (UNITY_SERIAL=''); verify host ULF cache; keep mount * CI: write ULF from secret and verify; drop entitlement activation step * CI: detect any licensing path; GameCI prime; status dir env; log+probe readiness; fix YAML * CI: add GameCI license prime; conditional ULF write; one-shot license validation; explicit status dir + license env * CI: fix YAML (inline python), add Anthropic key detect via GITHUB_ENV; ready to run happy path * CI: mount Unity token/ulf/cache dirs into container to share host license; create dirs before start * CI: fix YAML indentation; write ULF on host; activate in container with shared mounts; mount .config and .cache too * CI: gate Claude via outputs; mount all Unity license dirs; fix inline probe python; stabilize licensing flow * CI: normalize detect to step outputs; ensure license dirs mounted and validated; fix indentation * Bridge: honor UNITY_MCP_STATUS_DIR for heartbeat/status file (CI-friendly) * CI: guard project path for activation/start; align tool allowlist; run MCP server with python; tighten secret scoping * CI: finalize Unity licensing mounts + status dir; mode-detect (ULF/EBL); readiness logs+probe; Claude gating via outputs * CI: fix YAML probe (inline python -c) and finalize happy-path Unity licensing and MCP/Claude wiring * CI: inline python probe; unify Unity image and cache mounts; ready to test * CI: fix docker run IMAGE placement; ignore cache find perms; keep same editor image * CI: pass -manualLicenseFile to persistent Editor; keep mounts and single image * CI: mount full GameCI cache to /root in persistent Unity; set HOME=/root; add optional license check * CI: make -manualLicenseFile conditional; keep full /root mount and license check * CI: set HOME=/github/home; mount GameCI cache there; adjust manualLicenseFile path; expand license check * CI: EBL sign-in for persistent Unity (email/password/serial); revert HOME=/root and full /root mount; keep conditional manualLicenseFile and improved readiness * CI: run full NL/T suite prompt (nl-unity-suite-full.md) instead of mini * NL/T: require unified diffs + explicit verdicts in JUnit; CI: remove short sanity step, publish JUnit, upload artifacts * NL/T prompt: require CDATA wrapping for JUnit XML fields; guidance for splitting embedded ]]>; keep VERDICT in CDATA only * CI: remove in-container license check step; keep readiness and full suite * NL/T prompt: add version header, stricter JUnit schema, hashing/normalization, anchors, statuses, atomic semantics, tool logging * CI: increase Claude NL/T suite timeout to 30 minutes * CI: pre-create reports dir and result files to avoid tool approval prompts * CI: skip wait if container not running; skip Editor start if project missing; broaden MCP deps detection; expand allowed tools * fixies to harden ManageScript * CI: sanitize NL/T markdown report to avoid NUL/encoding issues * revert breaking yyaml changes * CI: prime license, robust Unity start/wait, sanitize markdown via heredoc * Resolve merge: accept upstream renames/installer (fix/installer-cleanup-v2) and keep local framing/script-editing - Restored upstream server.py, EditorWindow, uv.lock\n- Preserved ManageScript editing/validation; switched to atomic write + debounced refresh\n- Updated tools/__init__.py to keep script_edits/resources and adopt new logger name\n- All Python tests via uv: 7 passed, 6 skipped, 9 xpassed; Unity compile OK * Fix Claude Desktop config path and atomic write issues - Fix macOS path for Claude Desktop config: use ~/Library/Application Support/Claude/ instead of ~/.config/Claude/ - Improve atomic write pattern with backup/restore safety - Replace File.Replace() with File.Move() for better macOS compatibility - Add proper error handling and cleanup for file operations - Resolves issue where installer couldn't find Claude Desktop config on macOS * Editor: use macConfigPath on macOS for MCP client config writes (Claude Desktop, etc.). Fallback to linuxConfigPath only if mac path missing. * Models: add macConfigPath to McpClient for macOS config path selection (fixes CS1061 in editor window). * Editor: on macOS, prefer macConfigPath in ManualConfigEditorWindow (fallback to linux path); Linux/Windows unchanged. * Fix McpClient: align with upstream/main, prep for framing split * NL suite: shard workflow; tighten bridge readiness; add MCP preflight; use env-based shard vars * NL suite: fix shard step indentation; move shard vars to env; remove invalid inputs * MCP clients: split VSCode Copilot config paths into macConfigPath and linuxConfigPath * Unity bridge: clean stale status; bind host; robust wait probe with IPv4/IPv6 + diagnostics * CI: use MCPForUnity.Editor.MCPForUnityBridge.StartAutoConnect as executeMethod * Action wiring: inline mcpServers in settings for all shards; remove redundant .claude/mcp.json step * CI: embed mcpServers in settings for all shards; fix startup sanity step; lint clean * CI: pin claude-code-base-action to e6f32c8; use claude_args --mcp-config; switch to allowed_tools; ensure MCP config per step * CI: unpin claude-code-base-action to @beta (commit ref not found) * CI: align with claude-code-base-action @beta; pass MCP via claude_args and allowedTools * Editor: Fix apply_text_edits heuristic when edits shift positions; recompute method span on candidate text with fallback delta adjustment * CI: unify MCP wiring across workflows; write .claude/mcp.json; switch to claude_args with --mcp-config/--allowedTools; remove unsupported inputs * CI: collapse NL suite shards into a single run to avoid repeated test execution * CI: minimize allowedTools for NL suite to essential Unity MCP + Bash("git:*") + Write * CI: mkdir -p reports before run; remove unsupported --timeout-minutes from claude_args * CI: broaden allowedTools to include find_in_file and mcp__unity__* * CI: enable use_node_cache and switch NL suite model to claude-3-7-haiku-20250219 * CI: disable use_node_cache to avoid setup-node lockfile error * CI: set NL suite model to claude-3-haiku-20240307 * CI: cap Haiku output with --max-tokens 2048 for NL suite * CI: switch to claude-3-7-sonnet-latest and remove unsupported --max-tokens * CI: update allowedTools to Bash(*) and explicit Unity MCP tool list * CI: update NL suite workflow (latest tweaks) * Tests: tighten NL suite prompt for logging, hash discipline, stale retry, evidence windows, diff cap, and VERDICT line * Add disallowed tools to NL suite workflow * docs: clarify stale write retry * Add fallback JUnit report and adjust publisher * Indent fallback JUnit XML in workflow * fix: correct fallback JUnit report generation * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update Response.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update MCPForUnityBridge.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: correct McpTypes reference * Add directory existence checks for symlink and XDG paths * fix: only set installation flag after successful server install * Update resource_tools.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: respect mac config paths * Use File.Replace for atomic config write * Remove unused imports in manage_script * bump server version * Tests: update NL suite prompt and workflows; remove deprecated smoke/desktop-parity; quickprobe tidy * Editor: atomic config write via File.Replace fallback; remove redundant backups and racey exists checks * CI: harden NL suite - idempotent docker, gate on unity_ok, safer port probe, least-priv perms * Editor: make atomic config write restoration safe (flag writeDone; copy-overwrite restore; cleanup in finally) * CI: fix fallback JUnit heredoc by using printf lines (no EOF delimiter issues) * CI: switch NL suite to mini prompt; mini prompt honors / and NL discipline * CI: replace claude_args with allowed_tools/model/mcp_config per action schema * CI: expand UNITY_PROJECT_ROOT via in MCP config heredoc * EditorWindow: add cross-platform fallback for File.Replace; macOS-insensitive PathsEqual; safer uv resolve; honor macConfigPath * CI: strengthen JUnit publishing for NL mini suite (normalize, debug list, publish both, fail_on_parse_error) * CI: set job-wide JUNIT_OUT/MD_OUT; normalization uses env; publish references env and ungroup reports * CI: publish a single normalized JUnit (reports/junit-for-actions.xml); fallback writes same; avoid checkName/reportPaths mismatch * CI: align mini prompt report filenames; redact Unity log tail in diagnostics * chore: sync workflow and mini prompt; redacted logs; JUnit normalization/publish tweaks * CI: redact sensitive tokens in Stop Unity; docs: CI usage + edit tools * prompts: update nl-unity-suite-full (mini-style setup + reporting discipline); remove obsolete prompts * CI: harden NL workflows (timeout_minutes, robust normalization); prompts: unify JUnit suite name and reporting discipline * prompts: add guarded write pattern (LF hash, stale_file retry) to full suite * prompts: enforce continue-on-failure, driver flow, and status handling in full suite * Make test list more explicit in prompt. Get rid of old test prompts for hygeine. * prompts: add stale fast-retry (server hash) + in-memory buf guidance * CI: standardize JUNIT_OUT to reports/junit-nl-suite.xml; fix artifact upload indentation; prompt copy cleanups * prompts: reporting discipline — append-only fragments, batch writes, no model round-trip * prompts: stale fast-retry preference, buffer/sha carry, snapshot revert, essential logging * workflows(nl-suite): precreate report skeletons, assemble junit, synthesize markdown; restrict allowed_tools to append-only Bash + MCP tools * thsis too * Update README-DEV.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite-mini.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * workflows(nl-mini): fix YAML indentation/trailing spaces under with: and cleanup heredoc spacing * workflows(nl-suite): fix indentation on docker logs redaction line (YAML lint) * Add write to allowlist * nl-suite: harden reporting discipline (fragment-only writes, forbid alt paths); workflow: clean stray junit-*updated*.xml * nl-suite: enforce end-of-suite single Write (no bash redirection); workflow: restrict allowed_tools to Write+MCP only * prompts(nl-full): end-of-suite results must be valid XML with single <cases> root and only <testcase> children; no raw text outside CDATA * workflows(nl-suite): make Claude step non-fatal; tolerant normalizer extracts <testcase> via regex on bad fragments * nl-suite: fix stale classname to UnityMCP.NL-T in mini fallback; prompt: require re-read after every revert; correct PLAN/PROGRESS to 15 * nl-suite: fix fallback JUnit classname to UnityMCP.NL-T; prompt: forbid create_script and env/mkdir checks, enforce single baseline-byte revert flow and post-revert re-read; add corruption-handling guidance * prompts(nl-full): after each write re-read raw bytes to refresh pre_sha; prefer script_apply_edits for anchors; avoid header/using changes * prompts(nl-full): canonicalize outputs to /; allow small fragment appends via Write or Bash(printf/echo); forbid wrappers and full-file round-trips * prompts(nl-full): finalize markdown formatting for guarded write, execution order, specs, status * workflows(nl-suite, mini): header/lint fixes and constrained Bash append path; align allowed_tools * prompts(nl-full): format Fast Restore, Guarded Write, Execution, Specs, Status as proper markdown lists and code fences * workflows(nl-suite): keep header tidy and append-path alignment with prompt * minor fix * workflows(nl-suite): fix indentation and dispatch; align allowed_tools and revert helper * prompts(nl-full): switch to read_resource for buf/sha; re-read only when needed; convert 'Print this once' to heading; note snapshot helper creates parent dirs * workflows(nl-suite): normalize step removes bootstrap when real testcases present; recompute tests/failures * workflows(nl-suite): enrich Markdown summary by extracting per-test <system-out> blocks (truncated) * clarify prompt resilience instructions * ci(nl-suite): revert prompt and workflow to known-good e0f8a72 for green run; remove extra MD details * ci(nl-suite): minimal fixes — no-mkdir guard in prompt; drop bootstrap and recompute JUnit counts * ci(nl-suite): richer JUnit→Markdown report (per-test system-out) * Small guard to incorret asset read call. * ci(nl-suite): refine MD builder — unescape XML entities, safe code fences, PASS/FAIL badges * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * server(manage_script): robust URI handling — percent-decode file://, normalize, strip host/leading slashes, return Assets-relative if present * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * tests(framing): reduce handshake poll window, nonblocking peek to avoid disconnect race; still enforce pre-handshake data drop * tests(manage_script): add _split_uri tests for unity://path, file:// URLs (decoded/Assets-relative), and plain paths * server+tests: fix handshake syntax error; robust file:// URI normalization in manage_script; add _split_uri tests; adjust stdout scan to ignore venv/site-packages * bridge(framing): accept zero-length frames (treat as empty keepalive) * tests(logging): use errors='replace' on decode fallback to avoid silent drops * resources(list): restrict to Assets/, resolve symlinks, enforce .cs; add traversal/outside-path tests * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * misc: framing keepalive (zero-length), regex preview consistency, resource.list hardening, URI parsing, legacy update routing, test cleanups * docs(tools): richer MCP tool descriptions; tests accept decorator kwargs; resource URI parsing hardened * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * net+docs: hard-reject zero-length frames; TCP_NODELAY on connect; Assets detection case-insensitive; NL prompt statuses aligned * prompt(nl-suite): constrain Write destinations under reports/, forbid traversal * prompt+net: harden Write path rules; use monotonic deadline and plain-text advisory for non-framed peers * unity_connection: restore recv timeout via try/finally; make global connection getter thread-safe with module lock and double-checked init * NL/T prompt: pin structured edit ops for T-D/T-E; add schema-error guarded write behavior; keep existing path/URI and revert rules * unity_connection: add FRAMED_MAX; use ValueError for framed length violations; lower framed receive log to debug; serialize connect() with per-instance lock * ManageScript: use UTF8Encoding(without BOM) for atomic writes in ApplyTextEdits/EditScript to align with Create/Update and avoid BOM-related diffs/hash mismatches * NL/T prompt: make helper deletion regex multiline-safe ((?ms) so ^ anchors line starts) * ManageScript: emit structured overlap status {status:"overlap"} for overlapping edit ranges in apply_text_edits and edit paths * NL/T prompt: clarify fallback vs failure — fallback only for unsupported/missing_field; treat bad_request as failure; note unsupported after fallback as failure * NL/T prompt: pin deterministic overlap probe (apply_text_edits two ranges from same snapshot); gate too_large behind RUN_TOO_LARGE env hint * TB update * NL/T prompt: harden Output Rules — constrain Bash(printf|echo) to stdout-only; forbid redirection/here-docs/tee; only scripts/nlt-revert.sh may mutate FS * Prompt: enumerate allowed script_apply_edits ops; add manage_editor/read_console guidance; fix T‑F atomic batch to single script_apply_edits. ManageScript: regex timeout for diagnostics; symlink ancestor guard; complete allowed-modes list. * Fixes * ManageScript: add rich overlap diagnostics (conflicts + hint) for both text range and structured batch paths * ManageScript: return structured {status:"validation_failed"} diagnostics in create/update/edits and validate before commit * ManageScript: echo canonical uri in responses (create/read/update/apply_text_edits/structured edits) to reinforce resource identity * improve clarity of capabilities message * Framing: allow zero-length frames on both ends (C# bridge, Python server). Prompt: harden T-F to single text-range apply_text_edits batch (descending order, one snapshot). URI: normalize file:// outside Assets by stripping leading slash. * ManageScript: include new sha256 in success payload for apply_text_edits; harden TryResolveUnderAssets by rejecting symlinked ancestors up to Assets/. * remove claudetest dir * manage_script_edits: normalize method-anchored anchor_insert to insert_method (map text->replacement); improves CI compatibility for T‑A/T‑E without changing Editor behavior. * tighten testing protocol around mkdir * manage_script: validate create_script inputs (Assets/.cs/name/no traversal); add Assets/ guard to delete_script; validate level+Assets in validate_script; make legacy manage_script optional params; harden legacy update routing with base64 reuse and payload size preflight. * Tighten prompt for testing * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script_edits: honor ignore_case on anchor_insert and regex_replace in both direct and text-conversion paths (MULTILINE|IGNORECASE). * remove extra file * workflow: use python3 for inline scripts and port detection on ubuntu-latest. * Tighten prompt + manage_script * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script: improve file:// UNC handling; preserve POSIX absolute semantics internally; keep test-expected slash stripping for non-Assets paths. * ManageScript.cs: add TimeSpan timeouts to all Regex uses (IsMatch/Match/new Regex) and keep CultureInvariant/Multiline options; reduces risk of catastrophic backtracking stalls. * workflow: ensure reports/ exists in markdown build step to avoid FileNotFoundError when writing MD_OUT. * fix brace * manage_script_edits: expand backrefs for regex_replace in preview->text conversion and translate to \g<n> in local apply; keeps previews and actual edits consistent. * anchor_insert: default to position=after, normalize surrounding newlines in Python conversion paths; C# path ensures trailing newline and skips duplicate insertion within class. * feat(mcp): add get_sha tool; apply_text_edits normalization+overlap preflight+strict; no-op evidence in C#; update NL suite prompt; add unit tests * feat(frames): accept zero-length heartbeat frames in client; add heartbeat test * feat(edits): guard destructive regex_replace with structural preflight; add robust tests; prompt uses delete_method for temp helper * feat(frames): bound heartbeat loop with timeout/threshold; align zero-length response with C#; update test * SDK hardening: atomic multi-span text edits; stop forcing sequential for structured ops; forward options on apply_text_edits; add validate=relaxed support and scoped checks; update NL/T prompt; add tests for options forwarding, relaxed mode, and atomic batches * Router: default applyMode=atomic for multi-span apply_text_edits; add tests * CI prompt: pass options.validate=relaxed for T-B/C; options.applyMode=atomic for T-F; emphasize always writing testcase and restoring on errors * Validation & DX: add validate=syntax (scoped), standardize evidence windows; early regex compile with hints; debug_preview for apply_text_edits * Update UnityMcpBridge/Editor/Windows/MCPForUnityEditorWindow.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * NL/T suite-driven edits: LongUnityScriptClaudeTest, bridge helpers, server_version; prepare framing tests * Fix duplicate macConfigPath field in McpClient to resolve CS0102 * Editor threading: run EnsureServerInstalled on main thread; marshal EditorPrefs/DeleteKey + logging via delayCall * Docs(apply_text_edits): strengthen guidance on 1-based positions, verify-before-edit, and recommend anchors/structured edits * Docs(script_apply_edits): add safety guidance (anchors, method ops, validators) and recommended practices * Framed VerifyBridgePing in editor window; docs hardening for apply_text_edits and script_apply_edits --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-31 00:55:38 +08:00
"scriptType": script_type,
}
Claude‑friendly edit tools + framed transport + live Unity NL test framework (#243) * CI: gate desktop-parity on Anthropic key; pass anthropic_api_key like NL suite * Add quickprobe prompt and CI workflow (mcp-quickprobe.md, unity-mcp-quickprobe.yml) * strictier tool use to prevent subagent spawning and force mcp tools * update workflow filesto reduce likelihood of subagent spawning * improve permissions for claude agent, fix mcpbridge timeout/token issue * increase max turns to 10 * ci: align NL suite to new permissions schema; prevent subagent drift * ci: NL suite -> mini prompt for e2e; add full NL/T prompt; server: ctx optional + project_root fallback; workflows: set UNITY_PROJECT_ROOT for CI * ci: add checks:write; revert local project hardcodes (manifest, ProjectVersion.txt) * tools: text-edit routing fixes (anchor_insert via text, CRLF calc); prompts: mini NL/T clarifications * ci: use absolute UNITY_PROJECT_ROOT; prompts target TestProjects; server: accept relative UNITY_PROJECT_ROOT and bare spec URI * ci: ignore Unity test project's packages-lock.json; remove from repo to avoid absolute paths * CI: start persistent Unity Editor for MCP (guarded by license) + allow batch-mode bridge via UNITY_MCP_ALLOW_BATCH * CI: hide license and pass via env to docker; fix invalid ref format * CI: readiness probe uses handshake on Unity MCP port (deterministic) * CI: fix YAML; use TCP handshake readiness probe (FRAMING=1) * CI: prime Unity license via game-ci; mount ULF into container; extend readiness timeout * CI: use ULF write + mount for Unity licensing; remove serial/email/pass from container * CI: entitlement activation (UNITY_SERIAL=''); verify host ULF cache; keep mount * CI: write ULF from secret and verify; drop entitlement activation step * CI: detect any licensing path; GameCI prime; status dir env; log+probe readiness; fix YAML * CI: add GameCI license prime; conditional ULF write; one-shot license validation; explicit status dir + license env * CI: fix YAML (inline python), add Anthropic key detect via GITHUB_ENV; ready to run happy path * CI: mount Unity token/ulf/cache dirs into container to share host license; create dirs before start * CI: fix YAML indentation; write ULF on host; activate in container with shared mounts; mount .config and .cache too * CI: gate Claude via outputs; mount all Unity license dirs; fix inline probe python; stabilize licensing flow * CI: normalize detect to step outputs; ensure license dirs mounted and validated; fix indentation * Bridge: honor UNITY_MCP_STATUS_DIR for heartbeat/status file (CI-friendly) * CI: guard project path for activation/start; align tool allowlist; run MCP server with python; tighten secret scoping * CI: finalize Unity licensing mounts + status dir; mode-detect (ULF/EBL); readiness logs+probe; Claude gating via outputs * CI: fix YAML probe (inline python -c) and finalize happy-path Unity licensing and MCP/Claude wiring * CI: inline python probe; unify Unity image and cache mounts; ready to test * CI: fix docker run IMAGE placement; ignore cache find perms; keep same editor image * CI: pass -manualLicenseFile to persistent Editor; keep mounts and single image * CI: mount full GameCI cache to /root in persistent Unity; set HOME=/root; add optional license check * CI: make -manualLicenseFile conditional; keep full /root mount and license check * CI: set HOME=/github/home; mount GameCI cache there; adjust manualLicenseFile path; expand license check * CI: EBL sign-in for persistent Unity (email/password/serial); revert HOME=/root and full /root mount; keep conditional manualLicenseFile and improved readiness * CI: run full NL/T suite prompt (nl-unity-suite-full.md) instead of mini * NL/T: require unified diffs + explicit verdicts in JUnit; CI: remove short sanity step, publish JUnit, upload artifacts * NL/T prompt: require CDATA wrapping for JUnit XML fields; guidance for splitting embedded ]]>; keep VERDICT in CDATA only * CI: remove in-container license check step; keep readiness and full suite * NL/T prompt: add version header, stricter JUnit schema, hashing/normalization, anchors, statuses, atomic semantics, tool logging * CI: increase Claude NL/T suite timeout to 30 minutes * CI: pre-create reports dir and result files to avoid tool approval prompts * CI: skip wait if container not running; skip Editor start if project missing; broaden MCP deps detection; expand allowed tools * fixies to harden ManageScript * CI: sanitize NL/T markdown report to avoid NUL/encoding issues * revert breaking yyaml changes * CI: prime license, robust Unity start/wait, sanitize markdown via heredoc * Resolve merge: accept upstream renames/installer (fix/installer-cleanup-v2) and keep local framing/script-editing - Restored upstream server.py, EditorWindow, uv.lock\n- Preserved ManageScript editing/validation; switched to atomic write + debounced refresh\n- Updated tools/__init__.py to keep script_edits/resources and adopt new logger name\n- All Python tests via uv: 7 passed, 6 skipped, 9 xpassed; Unity compile OK * Fix Claude Desktop config path and atomic write issues - Fix macOS path for Claude Desktop config: use ~/Library/Application Support/Claude/ instead of ~/.config/Claude/ - Improve atomic write pattern with backup/restore safety - Replace File.Replace() with File.Move() for better macOS compatibility - Add proper error handling and cleanup for file operations - Resolves issue where installer couldn't find Claude Desktop config on macOS * Editor: use macConfigPath on macOS for MCP client config writes (Claude Desktop, etc.). Fallback to linuxConfigPath only if mac path missing. * Models: add macConfigPath to McpClient for macOS config path selection (fixes CS1061 in editor window). * Editor: on macOS, prefer macConfigPath in ManualConfigEditorWindow (fallback to linux path); Linux/Windows unchanged. * Fix McpClient: align with upstream/main, prep for framing split * NL suite: shard workflow; tighten bridge readiness; add MCP preflight; use env-based shard vars * NL suite: fix shard step indentation; move shard vars to env; remove invalid inputs * MCP clients: split VSCode Copilot config paths into macConfigPath and linuxConfigPath * Unity bridge: clean stale status; bind host; robust wait probe with IPv4/IPv6 + diagnostics * CI: use MCPForUnity.Editor.MCPForUnityBridge.StartAutoConnect as executeMethod * Action wiring: inline mcpServers in settings for all shards; remove redundant .claude/mcp.json step * CI: embed mcpServers in settings for all shards; fix startup sanity step; lint clean * CI: pin claude-code-base-action to e6f32c8; use claude_args --mcp-config; switch to allowed_tools; ensure MCP config per step * CI: unpin claude-code-base-action to @beta (commit ref not found) * CI: align with claude-code-base-action @beta; pass MCP via claude_args and allowedTools * Editor: Fix apply_text_edits heuristic when edits shift positions; recompute method span on candidate text with fallback delta adjustment * CI: unify MCP wiring across workflows; write .claude/mcp.json; switch to claude_args with --mcp-config/--allowedTools; remove unsupported inputs * CI: collapse NL suite shards into a single run to avoid repeated test execution * CI: minimize allowedTools for NL suite to essential Unity MCP + Bash("git:*") + Write * CI: mkdir -p reports before run; remove unsupported --timeout-minutes from claude_args * CI: broaden allowedTools to include find_in_file and mcp__unity__* * CI: enable use_node_cache and switch NL suite model to claude-3-7-haiku-20250219 * CI: disable use_node_cache to avoid setup-node lockfile error * CI: set NL suite model to claude-3-haiku-20240307 * CI: cap Haiku output with --max-tokens 2048 for NL suite * CI: switch to claude-3-7-sonnet-latest and remove unsupported --max-tokens * CI: update allowedTools to Bash(*) and explicit Unity MCP tool list * CI: update NL suite workflow (latest tweaks) * Tests: tighten NL suite prompt for logging, hash discipline, stale retry, evidence windows, diff cap, and VERDICT line * Add disallowed tools to NL suite workflow * docs: clarify stale write retry * Add fallback JUnit report and adjust publisher * Indent fallback JUnit XML in workflow * fix: correct fallback JUnit report generation * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update Response.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update MCPForUnityBridge.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: correct McpTypes reference * Add directory existence checks for symlink and XDG paths * fix: only set installation flag after successful server install * Update resource_tools.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: respect mac config paths * Use File.Replace for atomic config write * Remove unused imports in manage_script * bump server version * Tests: update NL suite prompt and workflows; remove deprecated smoke/desktop-parity; quickprobe tidy * Editor: atomic config write via File.Replace fallback; remove redundant backups and racey exists checks * CI: harden NL suite - idempotent docker, gate on unity_ok, safer port probe, least-priv perms * Editor: make atomic config write restoration safe (flag writeDone; copy-overwrite restore; cleanup in finally) * CI: fix fallback JUnit heredoc by using printf lines (no EOF delimiter issues) * CI: switch NL suite to mini prompt; mini prompt honors / and NL discipline * CI: replace claude_args with allowed_tools/model/mcp_config per action schema * CI: expand UNITY_PROJECT_ROOT via in MCP config heredoc * EditorWindow: add cross-platform fallback for File.Replace; macOS-insensitive PathsEqual; safer uv resolve; honor macConfigPath * CI: strengthen JUnit publishing for NL mini suite (normalize, debug list, publish both, fail_on_parse_error) * CI: set job-wide JUNIT_OUT/MD_OUT; normalization uses env; publish references env and ungroup reports * CI: publish a single normalized JUnit (reports/junit-for-actions.xml); fallback writes same; avoid checkName/reportPaths mismatch * CI: align mini prompt report filenames; redact Unity log tail in diagnostics * chore: sync workflow and mini prompt; redacted logs; JUnit normalization/publish tweaks * CI: redact sensitive tokens in Stop Unity; docs: CI usage + edit tools * prompts: update nl-unity-suite-full (mini-style setup + reporting discipline); remove obsolete prompts * CI: harden NL workflows (timeout_minutes, robust normalization); prompts: unify JUnit suite name and reporting discipline * prompts: add guarded write pattern (LF hash, stale_file retry) to full suite * prompts: enforce continue-on-failure, driver flow, and status handling in full suite * Make test list more explicit in prompt. Get rid of old test prompts for hygeine. * prompts: add stale fast-retry (server hash) + in-memory buf guidance * CI: standardize JUNIT_OUT to reports/junit-nl-suite.xml; fix artifact upload indentation; prompt copy cleanups * prompts: reporting discipline — append-only fragments, batch writes, no model round-trip * prompts: stale fast-retry preference, buffer/sha carry, snapshot revert, essential logging * workflows(nl-suite): precreate report skeletons, assemble junit, synthesize markdown; restrict allowed_tools to append-only Bash + MCP tools * thsis too * Update README-DEV.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite-mini.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * workflows(nl-mini): fix YAML indentation/trailing spaces under with: and cleanup heredoc spacing * workflows(nl-suite): fix indentation on docker logs redaction line (YAML lint) * Add write to allowlist * nl-suite: harden reporting discipline (fragment-only writes, forbid alt paths); workflow: clean stray junit-*updated*.xml * nl-suite: enforce end-of-suite single Write (no bash redirection); workflow: restrict allowed_tools to Write+MCP only * prompts(nl-full): end-of-suite results must be valid XML with single <cases> root and only <testcase> children; no raw text outside CDATA * workflows(nl-suite): make Claude step non-fatal; tolerant normalizer extracts <testcase> via regex on bad fragments * nl-suite: fix stale classname to UnityMCP.NL-T in mini fallback; prompt: require re-read after every revert; correct PLAN/PROGRESS to 15 * nl-suite: fix fallback JUnit classname to UnityMCP.NL-T; prompt: forbid create_script and env/mkdir checks, enforce single baseline-byte revert flow and post-revert re-read; add corruption-handling guidance * prompts(nl-full): after each write re-read raw bytes to refresh pre_sha; prefer script_apply_edits for anchors; avoid header/using changes * prompts(nl-full): canonicalize outputs to /; allow small fragment appends via Write or Bash(printf/echo); forbid wrappers and full-file round-trips * prompts(nl-full): finalize markdown formatting for guarded write, execution order, specs, status * workflows(nl-suite, mini): header/lint fixes and constrained Bash append path; align allowed_tools * prompts(nl-full): format Fast Restore, Guarded Write, Execution, Specs, Status as proper markdown lists and code fences * workflows(nl-suite): keep header tidy and append-path alignment with prompt * minor fix * workflows(nl-suite): fix indentation and dispatch; align allowed_tools and revert helper * prompts(nl-full): switch to read_resource for buf/sha; re-read only when needed; convert 'Print this once' to heading; note snapshot helper creates parent dirs * workflows(nl-suite): normalize step removes bootstrap when real testcases present; recompute tests/failures * workflows(nl-suite): enrich Markdown summary by extracting per-test <system-out> blocks (truncated) * clarify prompt resilience instructions * ci(nl-suite): revert prompt and workflow to known-good e0f8a72 for green run; remove extra MD details * ci(nl-suite): minimal fixes — no-mkdir guard in prompt; drop bootstrap and recompute JUnit counts * ci(nl-suite): richer JUnit→Markdown report (per-test system-out) * Small guard to incorret asset read call. * ci(nl-suite): refine MD builder — unescape XML entities, safe code fences, PASS/FAIL badges * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * server(manage_script): robust URI handling — percent-decode file://, normalize, strip host/leading slashes, return Assets-relative if present * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * tests(framing): reduce handshake poll window, nonblocking peek to avoid disconnect race; still enforce pre-handshake data drop * tests(manage_script): add _split_uri tests for unity://path, file:// URLs (decoded/Assets-relative), and plain paths * server+tests: fix handshake syntax error; robust file:// URI normalization in manage_script; add _split_uri tests; adjust stdout scan to ignore venv/site-packages * bridge(framing): accept zero-length frames (treat as empty keepalive) * tests(logging): use errors='replace' on decode fallback to avoid silent drops * resources(list): restrict to Assets/, resolve symlinks, enforce .cs; add traversal/outside-path tests * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * misc: framing keepalive (zero-length), regex preview consistency, resource.list hardening, URI parsing, legacy update routing, test cleanups * docs(tools): richer MCP tool descriptions; tests accept decorator kwargs; resource URI parsing hardened * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * net+docs: hard-reject zero-length frames; TCP_NODELAY on connect; Assets detection case-insensitive; NL prompt statuses aligned * prompt(nl-suite): constrain Write destinations under reports/, forbid traversal * prompt+net: harden Write path rules; use monotonic deadline and plain-text advisory for non-framed peers * unity_connection: restore recv timeout via try/finally; make global connection getter thread-safe with module lock and double-checked init * NL/T prompt: pin structured edit ops for T-D/T-E; add schema-error guarded write behavior; keep existing path/URI and revert rules * unity_connection: add FRAMED_MAX; use ValueError for framed length violations; lower framed receive log to debug; serialize connect() with per-instance lock * ManageScript: use UTF8Encoding(without BOM) for atomic writes in ApplyTextEdits/EditScript to align with Create/Update and avoid BOM-related diffs/hash mismatches * NL/T prompt: make helper deletion regex multiline-safe ((?ms) so ^ anchors line starts) * ManageScript: emit structured overlap status {status:"overlap"} for overlapping edit ranges in apply_text_edits and edit paths * NL/T prompt: clarify fallback vs failure — fallback only for unsupported/missing_field; treat bad_request as failure; note unsupported after fallback as failure * NL/T prompt: pin deterministic overlap probe (apply_text_edits two ranges from same snapshot); gate too_large behind RUN_TOO_LARGE env hint * TB update * NL/T prompt: harden Output Rules — constrain Bash(printf|echo) to stdout-only; forbid redirection/here-docs/tee; only scripts/nlt-revert.sh may mutate FS * Prompt: enumerate allowed script_apply_edits ops; add manage_editor/read_console guidance; fix T‑F atomic batch to single script_apply_edits. ManageScript: regex timeout for diagnostics; symlink ancestor guard; complete allowed-modes list. * Fixes * ManageScript: add rich overlap diagnostics (conflicts + hint) for both text range and structured batch paths * ManageScript: return structured {status:"validation_failed"} diagnostics in create/update/edits and validate before commit * ManageScript: echo canonical uri in responses (create/read/update/apply_text_edits/structured edits) to reinforce resource identity * improve clarity of capabilities message * Framing: allow zero-length frames on both ends (C# bridge, Python server). Prompt: harden T-F to single text-range apply_text_edits batch (descending order, one snapshot). URI: normalize file:// outside Assets by stripping leading slash. * ManageScript: include new sha256 in success payload for apply_text_edits; harden TryResolveUnderAssets by rejecting symlinked ancestors up to Assets/. * remove claudetest dir * manage_script_edits: normalize method-anchored anchor_insert to insert_method (map text->replacement); improves CI compatibility for T‑A/T‑E without changing Editor behavior. * tighten testing protocol around mkdir * manage_script: validate create_script inputs (Assets/.cs/name/no traversal); add Assets/ guard to delete_script; validate level+Assets in validate_script; make legacy manage_script optional params; harden legacy update routing with base64 reuse and payload size preflight. * Tighten prompt for testing * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script_edits: honor ignore_case on anchor_insert and regex_replace in both direct and text-conversion paths (MULTILINE|IGNORECASE). * remove extra file * workflow: use python3 for inline scripts and port detection on ubuntu-latest. * Tighten prompt + manage_script * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script: improve file:// UNC handling; preserve POSIX absolute semantics internally; keep test-expected slash stripping for non-Assets paths. * ManageScript.cs: add TimeSpan timeouts to all Regex uses (IsMatch/Match/new Regex) and keep CultureInvariant/Multiline options; reduces risk of catastrophic backtracking stalls. * workflow: ensure reports/ exists in markdown build step to avoid FileNotFoundError when writing MD_OUT. * fix brace * manage_script_edits: expand backrefs for regex_replace in preview->text conversion and translate to \g<n> in local apply; keeps previews and actual edits consistent. * anchor_insert: default to position=after, normalize surrounding newlines in Python conversion paths; C# path ensures trailing newline and skips duplicate insertion within class. * feat(mcp): add get_sha tool; apply_text_edits normalization+overlap preflight+strict; no-op evidence in C#; update NL suite prompt; add unit tests * feat(frames): accept zero-length heartbeat frames in client; add heartbeat test * feat(edits): guard destructive regex_replace with structural preflight; add robust tests; prompt uses delete_method for temp helper * feat(frames): bound heartbeat loop with timeout/threshold; align zero-length response with C#; update test * SDK hardening: atomic multi-span text edits; stop forcing sequential for structured ops; forward options on apply_text_edits; add validate=relaxed support and scoped checks; update NL/T prompt; add tests for options forwarding, relaxed mode, and atomic batches * Router: default applyMode=atomic for multi-span apply_text_edits; add tests * CI prompt: pass options.validate=relaxed for T-B/C; options.applyMode=atomic for T-F; emphasize always writing testcase and restoring on errors * Validation & DX: add validate=syntax (scoped), standardize evidence windows; early regex compile with hints; debug_preview for apply_text_edits * Update UnityMcpBridge/Editor/Windows/MCPForUnityEditorWindow.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * NL/T suite-driven edits: LongUnityScriptClaudeTest, bridge helpers, server_version; prepare framing tests * Fix duplicate macConfigPath field in McpClient to resolve CS0102 * Editor threading: run EnsureServerInstalled on main thread; marshal EditorPrefs/DeleteKey + logging via delayCall * Docs(apply_text_edits): strengthen guidance on 1-based positions, verify-before-edit, and recommend anchors/structured edits * Docs(script_apply_edits): add safety guidance (anchors, method ops, validators) and recommended practices * Framed VerifyBridgePing in editor window; docs hardening for apply_text_edits and script_apply_edits --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-31 00:55:38 +08:00
# Base64 encode the contents if they exist to avoid JSON escaping issues
Claude‑friendly edit tools + framed transport + live Unity NL test framework (#243) * CI: gate desktop-parity on Anthropic key; pass anthropic_api_key like NL suite * Add quickprobe prompt and CI workflow (mcp-quickprobe.md, unity-mcp-quickprobe.yml) * strictier tool use to prevent subagent spawning and force mcp tools * update workflow filesto reduce likelihood of subagent spawning * improve permissions for claude agent, fix mcpbridge timeout/token issue * increase max turns to 10 * ci: align NL suite to new permissions schema; prevent subagent drift * ci: NL suite -> mini prompt for e2e; add full NL/T prompt; server: ctx optional + project_root fallback; workflows: set UNITY_PROJECT_ROOT for CI * ci: add checks:write; revert local project hardcodes (manifest, ProjectVersion.txt) * tools: text-edit routing fixes (anchor_insert via text, CRLF calc); prompts: mini NL/T clarifications * ci: use absolute UNITY_PROJECT_ROOT; prompts target TestProjects; server: accept relative UNITY_PROJECT_ROOT and bare spec URI * ci: ignore Unity test project's packages-lock.json; remove from repo to avoid absolute paths * CI: start persistent Unity Editor for MCP (guarded by license) + allow batch-mode bridge via UNITY_MCP_ALLOW_BATCH * CI: hide license and pass via env to docker; fix invalid ref format * CI: readiness probe uses handshake on Unity MCP port (deterministic) * CI: fix YAML; use TCP handshake readiness probe (FRAMING=1) * CI: prime Unity license via game-ci; mount ULF into container; extend readiness timeout * CI: use ULF write + mount for Unity licensing; remove serial/email/pass from container * CI: entitlement activation (UNITY_SERIAL=''); verify host ULF cache; keep mount * CI: write ULF from secret and verify; drop entitlement activation step * CI: detect any licensing path; GameCI prime; status dir env; log+probe readiness; fix YAML * CI: add GameCI license prime; conditional ULF write; one-shot license validation; explicit status dir + license env * CI: fix YAML (inline python), add Anthropic key detect via GITHUB_ENV; ready to run happy path * CI: mount Unity token/ulf/cache dirs into container to share host license; create dirs before start * CI: fix YAML indentation; write ULF on host; activate in container with shared mounts; mount .config and .cache too * CI: gate Claude via outputs; mount all Unity license dirs; fix inline probe python; stabilize licensing flow * CI: normalize detect to step outputs; ensure license dirs mounted and validated; fix indentation * Bridge: honor UNITY_MCP_STATUS_DIR for heartbeat/status file (CI-friendly) * CI: guard project path for activation/start; align tool allowlist; run MCP server with python; tighten secret scoping * CI: finalize Unity licensing mounts + status dir; mode-detect (ULF/EBL); readiness logs+probe; Claude gating via outputs * CI: fix YAML probe (inline python -c) and finalize happy-path Unity licensing and MCP/Claude wiring * CI: inline python probe; unify Unity image and cache mounts; ready to test * CI: fix docker run IMAGE placement; ignore cache find perms; keep same editor image * CI: pass -manualLicenseFile to persistent Editor; keep mounts and single image * CI: mount full GameCI cache to /root in persistent Unity; set HOME=/root; add optional license check * CI: make -manualLicenseFile conditional; keep full /root mount and license check * CI: set HOME=/github/home; mount GameCI cache there; adjust manualLicenseFile path; expand license check * CI: EBL sign-in for persistent Unity (email/password/serial); revert HOME=/root and full /root mount; keep conditional manualLicenseFile and improved readiness * CI: run full NL/T suite prompt (nl-unity-suite-full.md) instead of mini * NL/T: require unified diffs + explicit verdicts in JUnit; CI: remove short sanity step, publish JUnit, upload artifacts * NL/T prompt: require CDATA wrapping for JUnit XML fields; guidance for splitting embedded ]]>; keep VERDICT in CDATA only * CI: remove in-container license check step; keep readiness and full suite * NL/T prompt: add version header, stricter JUnit schema, hashing/normalization, anchors, statuses, atomic semantics, tool logging * CI: increase Claude NL/T suite timeout to 30 minutes * CI: pre-create reports dir and result files to avoid tool approval prompts * CI: skip wait if container not running; skip Editor start if project missing; broaden MCP deps detection; expand allowed tools * fixies to harden ManageScript * CI: sanitize NL/T markdown report to avoid NUL/encoding issues * revert breaking yyaml changes * CI: prime license, robust Unity start/wait, sanitize markdown via heredoc * Resolve merge: accept upstream renames/installer (fix/installer-cleanup-v2) and keep local framing/script-editing - Restored upstream server.py, EditorWindow, uv.lock\n- Preserved ManageScript editing/validation; switched to atomic write + debounced refresh\n- Updated tools/__init__.py to keep script_edits/resources and adopt new logger name\n- All Python tests via uv: 7 passed, 6 skipped, 9 xpassed; Unity compile OK * Fix Claude Desktop config path and atomic write issues - Fix macOS path for Claude Desktop config: use ~/Library/Application Support/Claude/ instead of ~/.config/Claude/ - Improve atomic write pattern with backup/restore safety - Replace File.Replace() with File.Move() for better macOS compatibility - Add proper error handling and cleanup for file operations - Resolves issue where installer couldn't find Claude Desktop config on macOS * Editor: use macConfigPath on macOS for MCP client config writes (Claude Desktop, etc.). Fallback to linuxConfigPath only if mac path missing. * Models: add macConfigPath to McpClient for macOS config path selection (fixes CS1061 in editor window). * Editor: on macOS, prefer macConfigPath in ManualConfigEditorWindow (fallback to linux path); Linux/Windows unchanged. * Fix McpClient: align with upstream/main, prep for framing split * NL suite: shard workflow; tighten bridge readiness; add MCP preflight; use env-based shard vars * NL suite: fix shard step indentation; move shard vars to env; remove invalid inputs * MCP clients: split VSCode Copilot config paths into macConfigPath and linuxConfigPath * Unity bridge: clean stale status; bind host; robust wait probe with IPv4/IPv6 + diagnostics * CI: use MCPForUnity.Editor.MCPForUnityBridge.StartAutoConnect as executeMethod * Action wiring: inline mcpServers in settings for all shards; remove redundant .claude/mcp.json step * CI: embed mcpServers in settings for all shards; fix startup sanity step; lint clean * CI: pin claude-code-base-action to e6f32c8; use claude_args --mcp-config; switch to allowed_tools; ensure MCP config per step * CI: unpin claude-code-base-action to @beta (commit ref not found) * CI: align with claude-code-base-action @beta; pass MCP via claude_args and allowedTools * Editor: Fix apply_text_edits heuristic when edits shift positions; recompute method span on candidate text with fallback delta adjustment * CI: unify MCP wiring across workflows; write .claude/mcp.json; switch to claude_args with --mcp-config/--allowedTools; remove unsupported inputs * CI: collapse NL suite shards into a single run to avoid repeated test execution * CI: minimize allowedTools for NL suite to essential Unity MCP + Bash("git:*") + Write * CI: mkdir -p reports before run; remove unsupported --timeout-minutes from claude_args * CI: broaden allowedTools to include find_in_file and mcp__unity__* * CI: enable use_node_cache and switch NL suite model to claude-3-7-haiku-20250219 * CI: disable use_node_cache to avoid setup-node lockfile error * CI: set NL suite model to claude-3-haiku-20240307 * CI: cap Haiku output with --max-tokens 2048 for NL suite * CI: switch to claude-3-7-sonnet-latest and remove unsupported --max-tokens * CI: update allowedTools to Bash(*) and explicit Unity MCP tool list * CI: update NL suite workflow (latest tweaks) * Tests: tighten NL suite prompt for logging, hash discipline, stale retry, evidence windows, diff cap, and VERDICT line * Add disallowed tools to NL suite workflow * docs: clarify stale write retry * Add fallback JUnit report and adjust publisher * Indent fallback JUnit XML in workflow * fix: correct fallback JUnit report generation * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update Response.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update MCPForUnityBridge.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: correct McpTypes reference * Add directory existence checks for symlink and XDG paths * fix: only set installation flag after successful server install * Update resource_tools.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: respect mac config paths * Use File.Replace for atomic config write * Remove unused imports in manage_script * bump server version * Tests: update NL suite prompt and workflows; remove deprecated smoke/desktop-parity; quickprobe tidy * Editor: atomic config write via File.Replace fallback; remove redundant backups and racey exists checks * CI: harden NL suite - idempotent docker, gate on unity_ok, safer port probe, least-priv perms * Editor: make atomic config write restoration safe (flag writeDone; copy-overwrite restore; cleanup in finally) * CI: fix fallback JUnit heredoc by using printf lines (no EOF delimiter issues) * CI: switch NL suite to mini prompt; mini prompt honors / and NL discipline * CI: replace claude_args with allowed_tools/model/mcp_config per action schema * CI: expand UNITY_PROJECT_ROOT via in MCP config heredoc * EditorWindow: add cross-platform fallback for File.Replace; macOS-insensitive PathsEqual; safer uv resolve; honor macConfigPath * CI: strengthen JUnit publishing for NL mini suite (normalize, debug list, publish both, fail_on_parse_error) * CI: set job-wide JUNIT_OUT/MD_OUT; normalization uses env; publish references env and ungroup reports * CI: publish a single normalized JUnit (reports/junit-for-actions.xml); fallback writes same; avoid checkName/reportPaths mismatch * CI: align mini prompt report filenames; redact Unity log tail in diagnostics * chore: sync workflow and mini prompt; redacted logs; JUnit normalization/publish tweaks * CI: redact sensitive tokens in Stop Unity; docs: CI usage + edit tools * prompts: update nl-unity-suite-full (mini-style setup + reporting discipline); remove obsolete prompts * CI: harden NL workflows (timeout_minutes, robust normalization); prompts: unify JUnit suite name and reporting discipline * prompts: add guarded write pattern (LF hash, stale_file retry) to full suite * prompts: enforce continue-on-failure, driver flow, and status handling in full suite * Make test list more explicit in prompt. Get rid of old test prompts for hygeine. * prompts: add stale fast-retry (server hash) + in-memory buf guidance * CI: standardize JUNIT_OUT to reports/junit-nl-suite.xml; fix artifact upload indentation; prompt copy cleanups * prompts: reporting discipline — append-only fragments, batch writes, no model round-trip * prompts: stale fast-retry preference, buffer/sha carry, snapshot revert, essential logging * workflows(nl-suite): precreate report skeletons, assemble junit, synthesize markdown; restrict allowed_tools to append-only Bash + MCP tools * thsis too * Update README-DEV.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite-mini.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * workflows(nl-mini): fix YAML indentation/trailing spaces under with: and cleanup heredoc spacing * workflows(nl-suite): fix indentation on docker logs redaction line (YAML lint) * Add write to allowlist * nl-suite: harden reporting discipline (fragment-only writes, forbid alt paths); workflow: clean stray junit-*updated*.xml * nl-suite: enforce end-of-suite single Write (no bash redirection); workflow: restrict allowed_tools to Write+MCP only * prompts(nl-full): end-of-suite results must be valid XML with single <cases> root and only <testcase> children; no raw text outside CDATA * workflows(nl-suite): make Claude step non-fatal; tolerant normalizer extracts <testcase> via regex on bad fragments * nl-suite: fix stale classname to UnityMCP.NL-T in mini fallback; prompt: require re-read after every revert; correct PLAN/PROGRESS to 15 * nl-suite: fix fallback JUnit classname to UnityMCP.NL-T; prompt: forbid create_script and env/mkdir checks, enforce single baseline-byte revert flow and post-revert re-read; add corruption-handling guidance * prompts(nl-full): after each write re-read raw bytes to refresh pre_sha; prefer script_apply_edits for anchors; avoid header/using changes * prompts(nl-full): canonicalize outputs to /; allow small fragment appends via Write or Bash(printf/echo); forbid wrappers and full-file round-trips * prompts(nl-full): finalize markdown formatting for guarded write, execution order, specs, status * workflows(nl-suite, mini): header/lint fixes and constrained Bash append path; align allowed_tools * prompts(nl-full): format Fast Restore, Guarded Write, Execution, Specs, Status as proper markdown lists and code fences * workflows(nl-suite): keep header tidy and append-path alignment with prompt * minor fix * workflows(nl-suite): fix indentation and dispatch; align allowed_tools and revert helper * prompts(nl-full): switch to read_resource for buf/sha; re-read only when needed; convert 'Print this once' to heading; note snapshot helper creates parent dirs * workflows(nl-suite): normalize step removes bootstrap when real testcases present; recompute tests/failures * workflows(nl-suite): enrich Markdown summary by extracting per-test <system-out> blocks (truncated) * clarify prompt resilience instructions * ci(nl-suite): revert prompt and workflow to known-good e0f8a72 for green run; remove extra MD details * ci(nl-suite): minimal fixes — no-mkdir guard in prompt; drop bootstrap and recompute JUnit counts * ci(nl-suite): richer JUnit→Markdown report (per-test system-out) * Small guard to incorret asset read call. * ci(nl-suite): refine MD builder — unescape XML entities, safe code fences, PASS/FAIL badges * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * server(manage_script): robust URI handling — percent-decode file://, normalize, strip host/leading slashes, return Assets-relative if present * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * tests(framing): reduce handshake poll window, nonblocking peek to avoid disconnect race; still enforce pre-handshake data drop * tests(manage_script): add _split_uri tests for unity://path, file:// URLs (decoded/Assets-relative), and plain paths * server+tests: fix handshake syntax error; robust file:// URI normalization in manage_script; add _split_uri tests; adjust stdout scan to ignore venv/site-packages * bridge(framing): accept zero-length frames (treat as empty keepalive) * tests(logging): use errors='replace' on decode fallback to avoid silent drops * resources(list): restrict to Assets/, resolve symlinks, enforce .cs; add traversal/outside-path tests * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * misc: framing keepalive (zero-length), regex preview consistency, resource.list hardening, URI parsing, legacy update routing, test cleanups * docs(tools): richer MCP tool descriptions; tests accept decorator kwargs; resource URI parsing hardened * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * net+docs: hard-reject zero-length frames; TCP_NODELAY on connect; Assets detection case-insensitive; NL prompt statuses aligned * prompt(nl-suite): constrain Write destinations under reports/, forbid traversal * prompt+net: harden Write path rules; use monotonic deadline and plain-text advisory for non-framed peers * unity_connection: restore recv timeout via try/finally; make global connection getter thread-safe with module lock and double-checked init * NL/T prompt: pin structured edit ops for T-D/T-E; add schema-error guarded write behavior; keep existing path/URI and revert rules * unity_connection: add FRAMED_MAX; use ValueError for framed length violations; lower framed receive log to debug; serialize connect() with per-instance lock * ManageScript: use UTF8Encoding(without BOM) for atomic writes in ApplyTextEdits/EditScript to align with Create/Update and avoid BOM-related diffs/hash mismatches * NL/T prompt: make helper deletion regex multiline-safe ((?ms) so ^ anchors line starts) * ManageScript: emit structured overlap status {status:"overlap"} for overlapping edit ranges in apply_text_edits and edit paths * NL/T prompt: clarify fallback vs failure — fallback only for unsupported/missing_field; treat bad_request as failure; note unsupported after fallback as failure * NL/T prompt: pin deterministic overlap probe (apply_text_edits two ranges from same snapshot); gate too_large behind RUN_TOO_LARGE env hint * TB update * NL/T prompt: harden Output Rules — constrain Bash(printf|echo) to stdout-only; forbid redirection/here-docs/tee; only scripts/nlt-revert.sh may mutate FS * Prompt: enumerate allowed script_apply_edits ops; add manage_editor/read_console guidance; fix T‑F atomic batch to single script_apply_edits. ManageScript: regex timeout for diagnostics; symlink ancestor guard; complete allowed-modes list. * Fixes * ManageScript: add rich overlap diagnostics (conflicts + hint) for both text range and structured batch paths * ManageScript: return structured {status:"validation_failed"} diagnostics in create/update/edits and validate before commit * ManageScript: echo canonical uri in responses (create/read/update/apply_text_edits/structured edits) to reinforce resource identity * improve clarity of capabilities message * Framing: allow zero-length frames on both ends (C# bridge, Python server). Prompt: harden T-F to single text-range apply_text_edits batch (descending order, one snapshot). URI: normalize file:// outside Assets by stripping leading slash. * ManageScript: include new sha256 in success payload for apply_text_edits; harden TryResolveUnderAssets by rejecting symlinked ancestors up to Assets/. * remove claudetest dir * manage_script_edits: normalize method-anchored anchor_insert to insert_method (map text->replacement); improves CI compatibility for T‑A/T‑E without changing Editor behavior. * tighten testing protocol around mkdir * manage_script: validate create_script inputs (Assets/.cs/name/no traversal); add Assets/ guard to delete_script; validate level+Assets in validate_script; make legacy manage_script optional params; harden legacy update routing with base64 reuse and payload size preflight. * Tighten prompt for testing * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script_edits: honor ignore_case on anchor_insert and regex_replace in both direct and text-conversion paths (MULTILINE|IGNORECASE). * remove extra file * workflow: use python3 for inline scripts and port detection on ubuntu-latest. * Tighten prompt + manage_script * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script: improve file:// UNC handling; preserve POSIX absolute semantics internally; keep test-expected slash stripping for non-Assets paths. * ManageScript.cs: add TimeSpan timeouts to all Regex uses (IsMatch/Match/new Regex) and keep CultureInvariant/Multiline options; reduces risk of catastrophic backtracking stalls. * workflow: ensure reports/ exists in markdown build step to avoid FileNotFoundError when writing MD_OUT. * fix brace * manage_script_edits: expand backrefs for regex_replace in preview->text conversion and translate to \g<n> in local apply; keeps previews and actual edits consistent. * anchor_insert: default to position=after, normalize surrounding newlines in Python conversion paths; C# path ensures trailing newline and skips duplicate insertion within class. * feat(mcp): add get_sha tool; apply_text_edits normalization+overlap preflight+strict; no-op evidence in C#; update NL suite prompt; add unit tests * feat(frames): accept zero-length heartbeat frames in client; add heartbeat test * feat(edits): guard destructive regex_replace with structural preflight; add robust tests; prompt uses delete_method for temp helper * feat(frames): bound heartbeat loop with timeout/threshold; align zero-length response with C#; update test * SDK hardening: atomic multi-span text edits; stop forcing sequential for structured ops; forward options on apply_text_edits; add validate=relaxed support and scoped checks; update NL/T prompt; add tests for options forwarding, relaxed mode, and atomic batches * Router: default applyMode=atomic for multi-span apply_text_edits; add tests * CI prompt: pass options.validate=relaxed for T-B/C; options.applyMode=atomic for T-F; emphasize always writing testcase and restoring on errors * Validation & DX: add validate=syntax (scoped), standardize evidence windows; early regex compile with hints; debug_preview for apply_text_edits * Update UnityMcpBridge/Editor/Windows/MCPForUnityEditorWindow.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * NL/T suite-driven edits: LongUnityScriptClaudeTest, bridge helpers, server_version; prepare framing tests * Fix duplicate macConfigPath field in McpClient to resolve CS0102 * Editor threading: run EnsureServerInstalled on main thread; marshal EditorPrefs/DeleteKey + logging via delayCall * Docs(apply_text_edits): strengthen guidance on 1-based positions, verify-before-edit, and recommend anchors/structured edits * Docs(script_apply_edits): add safety guidance (anchors, method ops, validators) and recommended practices * Framed VerifyBridgePing in editor window; docs hardening for apply_text_edits and script_apply_edits --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-31 00:55:38 +08:00
if contents:
if action == 'create':
params["encodedContents"] = base64.b64encode(contents.encode('utf-8')).decode('utf-8')
params["contentsEncoded"] = True
else:
params["contents"] = contents
Claude‑friendly edit tools + framed transport + live Unity NL test framework (#243) * CI: gate desktop-parity on Anthropic key; pass anthropic_api_key like NL suite * Add quickprobe prompt and CI workflow (mcp-quickprobe.md, unity-mcp-quickprobe.yml) * strictier tool use to prevent subagent spawning and force mcp tools * update workflow filesto reduce likelihood of subagent spawning * improve permissions for claude agent, fix mcpbridge timeout/token issue * increase max turns to 10 * ci: align NL suite to new permissions schema; prevent subagent drift * ci: NL suite -> mini prompt for e2e; add full NL/T prompt; server: ctx optional + project_root fallback; workflows: set UNITY_PROJECT_ROOT for CI * ci: add checks:write; revert local project hardcodes (manifest, ProjectVersion.txt) * tools: text-edit routing fixes (anchor_insert via text, CRLF calc); prompts: mini NL/T clarifications * ci: use absolute UNITY_PROJECT_ROOT; prompts target TestProjects; server: accept relative UNITY_PROJECT_ROOT and bare spec URI * ci: ignore Unity test project's packages-lock.json; remove from repo to avoid absolute paths * CI: start persistent Unity Editor for MCP (guarded by license) + allow batch-mode bridge via UNITY_MCP_ALLOW_BATCH * CI: hide license and pass via env to docker; fix invalid ref format * CI: readiness probe uses handshake on Unity MCP port (deterministic) * CI: fix YAML; use TCP handshake readiness probe (FRAMING=1) * CI: prime Unity license via game-ci; mount ULF into container; extend readiness timeout * CI: use ULF write + mount for Unity licensing; remove serial/email/pass from container * CI: entitlement activation (UNITY_SERIAL=''); verify host ULF cache; keep mount * CI: write ULF from secret and verify; drop entitlement activation step * CI: detect any licensing path; GameCI prime; status dir env; log+probe readiness; fix YAML * CI: add GameCI license prime; conditional ULF write; one-shot license validation; explicit status dir + license env * CI: fix YAML (inline python), add Anthropic key detect via GITHUB_ENV; ready to run happy path * CI: mount Unity token/ulf/cache dirs into container to share host license; create dirs before start * CI: fix YAML indentation; write ULF on host; activate in container with shared mounts; mount .config and .cache too * CI: gate Claude via outputs; mount all Unity license dirs; fix inline probe python; stabilize licensing flow * CI: normalize detect to step outputs; ensure license dirs mounted and validated; fix indentation * Bridge: honor UNITY_MCP_STATUS_DIR for heartbeat/status file (CI-friendly) * CI: guard project path for activation/start; align tool allowlist; run MCP server with python; tighten secret scoping * CI: finalize Unity licensing mounts + status dir; mode-detect (ULF/EBL); readiness logs+probe; Claude gating via outputs * CI: fix YAML probe (inline python -c) and finalize happy-path Unity licensing and MCP/Claude wiring * CI: inline python probe; unify Unity image and cache mounts; ready to test * CI: fix docker run IMAGE placement; ignore cache find perms; keep same editor image * CI: pass -manualLicenseFile to persistent Editor; keep mounts and single image * CI: mount full GameCI cache to /root in persistent Unity; set HOME=/root; add optional license check * CI: make -manualLicenseFile conditional; keep full /root mount and license check * CI: set HOME=/github/home; mount GameCI cache there; adjust manualLicenseFile path; expand license check * CI: EBL sign-in for persistent Unity (email/password/serial); revert HOME=/root and full /root mount; keep conditional manualLicenseFile and improved readiness * CI: run full NL/T suite prompt (nl-unity-suite-full.md) instead of mini * NL/T: require unified diffs + explicit verdicts in JUnit; CI: remove short sanity step, publish JUnit, upload artifacts * NL/T prompt: require CDATA wrapping for JUnit XML fields; guidance for splitting embedded ]]>; keep VERDICT in CDATA only * CI: remove in-container license check step; keep readiness and full suite * NL/T prompt: add version header, stricter JUnit schema, hashing/normalization, anchors, statuses, atomic semantics, tool logging * CI: increase Claude NL/T suite timeout to 30 minutes * CI: pre-create reports dir and result files to avoid tool approval prompts * CI: skip wait if container not running; skip Editor start if project missing; broaden MCP deps detection; expand allowed tools * fixies to harden ManageScript * CI: sanitize NL/T markdown report to avoid NUL/encoding issues * revert breaking yyaml changes * CI: prime license, robust Unity start/wait, sanitize markdown via heredoc * Resolve merge: accept upstream renames/installer (fix/installer-cleanup-v2) and keep local framing/script-editing - Restored upstream server.py, EditorWindow, uv.lock\n- Preserved ManageScript editing/validation; switched to atomic write + debounced refresh\n- Updated tools/__init__.py to keep script_edits/resources and adopt new logger name\n- All Python tests via uv: 7 passed, 6 skipped, 9 xpassed; Unity compile OK * Fix Claude Desktop config path and atomic write issues - Fix macOS path for Claude Desktop config: use ~/Library/Application Support/Claude/ instead of ~/.config/Claude/ - Improve atomic write pattern with backup/restore safety - Replace File.Replace() with File.Move() for better macOS compatibility - Add proper error handling and cleanup for file operations - Resolves issue where installer couldn't find Claude Desktop config on macOS * Editor: use macConfigPath on macOS for MCP client config writes (Claude Desktop, etc.). Fallback to linuxConfigPath only if mac path missing. * Models: add macConfigPath to McpClient for macOS config path selection (fixes CS1061 in editor window). * Editor: on macOS, prefer macConfigPath in ManualConfigEditorWindow (fallback to linux path); Linux/Windows unchanged. * Fix McpClient: align with upstream/main, prep for framing split * NL suite: shard workflow; tighten bridge readiness; add MCP preflight; use env-based shard vars * NL suite: fix shard step indentation; move shard vars to env; remove invalid inputs * MCP clients: split VSCode Copilot config paths into macConfigPath and linuxConfigPath * Unity bridge: clean stale status; bind host; robust wait probe with IPv4/IPv6 + diagnostics * CI: use MCPForUnity.Editor.MCPForUnityBridge.StartAutoConnect as executeMethod * Action wiring: inline mcpServers in settings for all shards; remove redundant .claude/mcp.json step * CI: embed mcpServers in settings for all shards; fix startup sanity step; lint clean * CI: pin claude-code-base-action to e6f32c8; use claude_args --mcp-config; switch to allowed_tools; ensure MCP config per step * CI: unpin claude-code-base-action to @beta (commit ref not found) * CI: align with claude-code-base-action @beta; pass MCP via claude_args and allowedTools * Editor: Fix apply_text_edits heuristic when edits shift positions; recompute method span on candidate text with fallback delta adjustment * CI: unify MCP wiring across workflows; write .claude/mcp.json; switch to claude_args with --mcp-config/--allowedTools; remove unsupported inputs * CI: collapse NL suite shards into a single run to avoid repeated test execution * CI: minimize allowedTools for NL suite to essential Unity MCP + Bash("git:*") + Write * CI: mkdir -p reports before run; remove unsupported --timeout-minutes from claude_args * CI: broaden allowedTools to include find_in_file and mcp__unity__* * CI: enable use_node_cache and switch NL suite model to claude-3-7-haiku-20250219 * CI: disable use_node_cache to avoid setup-node lockfile error * CI: set NL suite model to claude-3-haiku-20240307 * CI: cap Haiku output with --max-tokens 2048 for NL suite * CI: switch to claude-3-7-sonnet-latest and remove unsupported --max-tokens * CI: update allowedTools to Bash(*) and explicit Unity MCP tool list * CI: update NL suite workflow (latest tweaks) * Tests: tighten NL suite prompt for logging, hash discipline, stale retry, evidence windows, diff cap, and VERDICT line * Add disallowed tools to NL suite workflow * docs: clarify stale write retry * Add fallback JUnit report and adjust publisher * Indent fallback JUnit XML in workflow * fix: correct fallback JUnit report generation * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update Response.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update MCPForUnityBridge.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: correct McpTypes reference * Add directory existence checks for symlink and XDG paths * fix: only set installation flag after successful server install * Update resource_tools.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: respect mac config paths * Use File.Replace for atomic config write * Remove unused imports in manage_script * bump server version * Tests: update NL suite prompt and workflows; remove deprecated smoke/desktop-parity; quickprobe tidy * Editor: atomic config write via File.Replace fallback; remove redundant backups and racey exists checks * CI: harden NL suite - idempotent docker, gate on unity_ok, safer port probe, least-priv perms * Editor: make atomic config write restoration safe (flag writeDone; copy-overwrite restore; cleanup in finally) * CI: fix fallback JUnit heredoc by using printf lines (no EOF delimiter issues) * CI: switch NL suite to mini prompt; mini prompt honors / and NL discipline * CI: replace claude_args with allowed_tools/model/mcp_config per action schema * CI: expand UNITY_PROJECT_ROOT via in MCP config heredoc * EditorWindow: add cross-platform fallback for File.Replace; macOS-insensitive PathsEqual; safer uv resolve; honor macConfigPath * CI: strengthen JUnit publishing for NL mini suite (normalize, debug list, publish both, fail_on_parse_error) * CI: set job-wide JUNIT_OUT/MD_OUT; normalization uses env; publish references env and ungroup reports * CI: publish a single normalized JUnit (reports/junit-for-actions.xml); fallback writes same; avoid checkName/reportPaths mismatch * CI: align mini prompt report filenames; redact Unity log tail in diagnostics * chore: sync workflow and mini prompt; redacted logs; JUnit normalization/publish tweaks * CI: redact sensitive tokens in Stop Unity; docs: CI usage + edit tools * prompts: update nl-unity-suite-full (mini-style setup + reporting discipline); remove obsolete prompts * CI: harden NL workflows (timeout_minutes, robust normalization); prompts: unify JUnit suite name and reporting discipline * prompts: add guarded write pattern (LF hash, stale_file retry) to full suite * prompts: enforce continue-on-failure, driver flow, and status handling in full suite * Make test list more explicit in prompt. Get rid of old test prompts for hygeine. * prompts: add stale fast-retry (server hash) + in-memory buf guidance * CI: standardize JUNIT_OUT to reports/junit-nl-suite.xml; fix artifact upload indentation; prompt copy cleanups * prompts: reporting discipline — append-only fragments, batch writes, no model round-trip * prompts: stale fast-retry preference, buffer/sha carry, snapshot revert, essential logging * workflows(nl-suite): precreate report skeletons, assemble junit, synthesize markdown; restrict allowed_tools to append-only Bash + MCP tools * thsis too * Update README-DEV.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite-mini.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * workflows(nl-mini): fix YAML indentation/trailing spaces under with: and cleanup heredoc spacing * workflows(nl-suite): fix indentation on docker logs redaction line (YAML lint) * Add write to allowlist * nl-suite: harden reporting discipline (fragment-only writes, forbid alt paths); workflow: clean stray junit-*updated*.xml * nl-suite: enforce end-of-suite single Write (no bash redirection); workflow: restrict allowed_tools to Write+MCP only * prompts(nl-full): end-of-suite results must be valid XML with single <cases> root and only <testcase> children; no raw text outside CDATA * workflows(nl-suite): make Claude step non-fatal; tolerant normalizer extracts <testcase> via regex on bad fragments * nl-suite: fix stale classname to UnityMCP.NL-T in mini fallback; prompt: require re-read after every revert; correct PLAN/PROGRESS to 15 * nl-suite: fix fallback JUnit classname to UnityMCP.NL-T; prompt: forbid create_script and env/mkdir checks, enforce single baseline-byte revert flow and post-revert re-read; add corruption-handling guidance * prompts(nl-full): after each write re-read raw bytes to refresh pre_sha; prefer script_apply_edits for anchors; avoid header/using changes * prompts(nl-full): canonicalize outputs to /; allow small fragment appends via Write or Bash(printf/echo); forbid wrappers and full-file round-trips * prompts(nl-full): finalize markdown formatting for guarded write, execution order, specs, status * workflows(nl-suite, mini): header/lint fixes and constrained Bash append path; align allowed_tools * prompts(nl-full): format Fast Restore, Guarded Write, Execution, Specs, Status as proper markdown lists and code fences * workflows(nl-suite): keep header tidy and append-path alignment with prompt * minor fix * workflows(nl-suite): fix indentation and dispatch; align allowed_tools and revert helper * prompts(nl-full): switch to read_resource for buf/sha; re-read only when needed; convert 'Print this once' to heading; note snapshot helper creates parent dirs * workflows(nl-suite): normalize step removes bootstrap when real testcases present; recompute tests/failures * workflows(nl-suite): enrich Markdown summary by extracting per-test <system-out> blocks (truncated) * clarify prompt resilience instructions * ci(nl-suite): revert prompt and workflow to known-good e0f8a72 for green run; remove extra MD details * ci(nl-suite): minimal fixes — no-mkdir guard in prompt; drop bootstrap and recompute JUnit counts * ci(nl-suite): richer JUnit→Markdown report (per-test system-out) * Small guard to incorret asset read call. * ci(nl-suite): refine MD builder — unescape XML entities, safe code fences, PASS/FAIL badges * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * server(manage_script): robust URI handling — percent-decode file://, normalize, strip host/leading slashes, return Assets-relative if present * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * tests(framing): reduce handshake poll window, nonblocking peek to avoid disconnect race; still enforce pre-handshake data drop * tests(manage_script): add _split_uri tests for unity://path, file:// URLs (decoded/Assets-relative), and plain paths * server+tests: fix handshake syntax error; robust file:// URI normalization in manage_script; add _split_uri tests; adjust stdout scan to ignore venv/site-packages * bridge(framing): accept zero-length frames (treat as empty keepalive) * tests(logging): use errors='replace' on decode fallback to avoid silent drops * resources(list): restrict to Assets/, resolve symlinks, enforce .cs; add traversal/outside-path tests * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * misc: framing keepalive (zero-length), regex preview consistency, resource.list hardening, URI parsing, legacy update routing, test cleanups * docs(tools): richer MCP tool descriptions; tests accept decorator kwargs; resource URI parsing hardened * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * net+docs: hard-reject zero-length frames; TCP_NODELAY on connect; Assets detection case-insensitive; NL prompt statuses aligned * prompt(nl-suite): constrain Write destinations under reports/, forbid traversal * prompt+net: harden Write path rules; use monotonic deadline and plain-text advisory for non-framed peers * unity_connection: restore recv timeout via try/finally; make global connection getter thread-safe with module lock and double-checked init * NL/T prompt: pin structured edit ops for T-D/T-E; add schema-error guarded write behavior; keep existing path/URI and revert rules * unity_connection: add FRAMED_MAX; use ValueError for framed length violations; lower framed receive log to debug; serialize connect() with per-instance lock * ManageScript: use UTF8Encoding(without BOM) for atomic writes in ApplyTextEdits/EditScript to align with Create/Update and avoid BOM-related diffs/hash mismatches * NL/T prompt: make helper deletion regex multiline-safe ((?ms) so ^ anchors line starts) * ManageScript: emit structured overlap status {status:"overlap"} for overlapping edit ranges in apply_text_edits and edit paths * NL/T prompt: clarify fallback vs failure — fallback only for unsupported/missing_field; treat bad_request as failure; note unsupported after fallback as failure * NL/T prompt: pin deterministic overlap probe (apply_text_edits two ranges from same snapshot); gate too_large behind RUN_TOO_LARGE env hint * TB update * NL/T prompt: harden Output Rules — constrain Bash(printf|echo) to stdout-only; forbid redirection/here-docs/tee; only scripts/nlt-revert.sh may mutate FS * Prompt: enumerate allowed script_apply_edits ops; add manage_editor/read_console guidance; fix T‑F atomic batch to single script_apply_edits. ManageScript: regex timeout for diagnostics; symlink ancestor guard; complete allowed-modes list. * Fixes * ManageScript: add rich overlap diagnostics (conflicts + hint) for both text range and structured batch paths * ManageScript: return structured {status:"validation_failed"} diagnostics in create/update/edits and validate before commit * ManageScript: echo canonical uri in responses (create/read/update/apply_text_edits/structured edits) to reinforce resource identity * improve clarity of capabilities message * Framing: allow zero-length frames on both ends (C# bridge, Python server). Prompt: harden T-F to single text-range apply_text_edits batch (descending order, one snapshot). URI: normalize file:// outside Assets by stripping leading slash. * ManageScript: include new sha256 in success payload for apply_text_edits; harden TryResolveUnderAssets by rejecting symlinked ancestors up to Assets/. * remove claudetest dir * manage_script_edits: normalize method-anchored anchor_insert to insert_method (map text->replacement); improves CI compatibility for T‑A/T‑E without changing Editor behavior. * tighten testing protocol around mkdir * manage_script: validate create_script inputs (Assets/.cs/name/no traversal); add Assets/ guard to delete_script; validate level+Assets in validate_script; make legacy manage_script optional params; harden legacy update routing with base64 reuse and payload size preflight. * Tighten prompt for testing * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script_edits: honor ignore_case on anchor_insert and regex_replace in both direct and text-conversion paths (MULTILINE|IGNORECASE). * remove extra file * workflow: use python3 for inline scripts and port detection on ubuntu-latest. * Tighten prompt + manage_script * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script: improve file:// UNC handling; preserve POSIX absolute semantics internally; keep test-expected slash stripping for non-Assets paths. * ManageScript.cs: add TimeSpan timeouts to all Regex uses (IsMatch/Match/new Regex) and keep CultureInvariant/Multiline options; reduces risk of catastrophic backtracking stalls. * workflow: ensure reports/ exists in markdown build step to avoid FileNotFoundError when writing MD_OUT. * fix brace * manage_script_edits: expand backrefs for regex_replace in preview->text conversion and translate to \g<n> in local apply; keeps previews and actual edits consistent. * anchor_insert: default to position=after, normalize surrounding newlines in Python conversion paths; C# path ensures trailing newline and skips duplicate insertion within class. * feat(mcp): add get_sha tool; apply_text_edits normalization+overlap preflight+strict; no-op evidence in C#; update NL suite prompt; add unit tests * feat(frames): accept zero-length heartbeat frames in client; add heartbeat test * feat(edits): guard destructive regex_replace with structural preflight; add robust tests; prompt uses delete_method for temp helper * feat(frames): bound heartbeat loop with timeout/threshold; align zero-length response with C#; update test * SDK hardening: atomic multi-span text edits; stop forcing sequential for structured ops; forward options on apply_text_edits; add validate=relaxed support and scoped checks; update NL/T prompt; add tests for options forwarding, relaxed mode, and atomic batches * Router: default applyMode=atomic for multi-span apply_text_edits; add tests * CI prompt: pass options.validate=relaxed for T-B/C; options.applyMode=atomic for T-F; emphasize always writing testcase and restoring on errors * Validation & DX: add validate=syntax (scoped), standardize evidence windows; early regex compile with hints; debug_preview for apply_text_edits * Update UnityMcpBridge/Editor/Windows/MCPForUnityEditorWindow.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * NL/T suite-driven edits: LongUnityScriptClaudeTest, bridge helpers, server_version; prepare framing tests * Fix duplicate macConfigPath field in McpClient to resolve CS0102 * Editor threading: run EnsureServerInstalled on main thread; marshal EditorPrefs/DeleteKey + logging via delayCall * Docs(apply_text_edits): strengthen guidance on 1-based positions, verify-before-edit, and recommend anchors/structured edits * Docs(script_apply_edits): add safety guidance (anchors, method ops, validators) and recommended practices * Framed VerifyBridgePing in editor window; docs hardening for apply_text_edits and script_apply_edits --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-31 00:55:38 +08:00
params = {k: v for k, v in params.items() if v is not None}
response = send_command_with_retry("manage_script", params)
Claude‑friendly edit tools + framed transport + live Unity NL test framework (#243) * CI: gate desktop-parity on Anthropic key; pass anthropic_api_key like NL suite * Add quickprobe prompt and CI workflow (mcp-quickprobe.md, unity-mcp-quickprobe.yml) * strictier tool use to prevent subagent spawning and force mcp tools * update workflow filesto reduce likelihood of subagent spawning * improve permissions for claude agent, fix mcpbridge timeout/token issue * increase max turns to 10 * ci: align NL suite to new permissions schema; prevent subagent drift * ci: NL suite -> mini prompt for e2e; add full NL/T prompt; server: ctx optional + project_root fallback; workflows: set UNITY_PROJECT_ROOT for CI * ci: add checks:write; revert local project hardcodes (manifest, ProjectVersion.txt) * tools: text-edit routing fixes (anchor_insert via text, CRLF calc); prompts: mini NL/T clarifications * ci: use absolute UNITY_PROJECT_ROOT; prompts target TestProjects; server: accept relative UNITY_PROJECT_ROOT and bare spec URI * ci: ignore Unity test project's packages-lock.json; remove from repo to avoid absolute paths * CI: start persistent Unity Editor for MCP (guarded by license) + allow batch-mode bridge via UNITY_MCP_ALLOW_BATCH * CI: hide license and pass via env to docker; fix invalid ref format * CI: readiness probe uses handshake on Unity MCP port (deterministic) * CI: fix YAML; use TCP handshake readiness probe (FRAMING=1) * CI: prime Unity license via game-ci; mount ULF into container; extend readiness timeout * CI: use ULF write + mount for Unity licensing; remove serial/email/pass from container * CI: entitlement activation (UNITY_SERIAL=''); verify host ULF cache; keep mount * CI: write ULF from secret and verify; drop entitlement activation step * CI: detect any licensing path; GameCI prime; status dir env; log+probe readiness; fix YAML * CI: add GameCI license prime; conditional ULF write; one-shot license validation; explicit status dir + license env * CI: fix YAML (inline python), add Anthropic key detect via GITHUB_ENV; ready to run happy path * CI: mount Unity token/ulf/cache dirs into container to share host license; create dirs before start * CI: fix YAML indentation; write ULF on host; activate in container with shared mounts; mount .config and .cache too * CI: gate Claude via outputs; mount all Unity license dirs; fix inline probe python; stabilize licensing flow * CI: normalize detect to step outputs; ensure license dirs mounted and validated; fix indentation * Bridge: honor UNITY_MCP_STATUS_DIR for heartbeat/status file (CI-friendly) * CI: guard project path for activation/start; align tool allowlist; run MCP server with python; tighten secret scoping * CI: finalize Unity licensing mounts + status dir; mode-detect (ULF/EBL); readiness logs+probe; Claude gating via outputs * CI: fix YAML probe (inline python -c) and finalize happy-path Unity licensing and MCP/Claude wiring * CI: inline python probe; unify Unity image and cache mounts; ready to test * CI: fix docker run IMAGE placement; ignore cache find perms; keep same editor image * CI: pass -manualLicenseFile to persistent Editor; keep mounts and single image * CI: mount full GameCI cache to /root in persistent Unity; set HOME=/root; add optional license check * CI: make -manualLicenseFile conditional; keep full /root mount and license check * CI: set HOME=/github/home; mount GameCI cache there; adjust manualLicenseFile path; expand license check * CI: EBL sign-in for persistent Unity (email/password/serial); revert HOME=/root and full /root mount; keep conditional manualLicenseFile and improved readiness * CI: run full NL/T suite prompt (nl-unity-suite-full.md) instead of mini * NL/T: require unified diffs + explicit verdicts in JUnit; CI: remove short sanity step, publish JUnit, upload artifacts * NL/T prompt: require CDATA wrapping for JUnit XML fields; guidance for splitting embedded ]]>; keep VERDICT in CDATA only * CI: remove in-container license check step; keep readiness and full suite * NL/T prompt: add version header, stricter JUnit schema, hashing/normalization, anchors, statuses, atomic semantics, tool logging * CI: increase Claude NL/T suite timeout to 30 minutes * CI: pre-create reports dir and result files to avoid tool approval prompts * CI: skip wait if container not running; skip Editor start if project missing; broaden MCP deps detection; expand allowed tools * fixies to harden ManageScript * CI: sanitize NL/T markdown report to avoid NUL/encoding issues * revert breaking yyaml changes * CI: prime license, robust Unity start/wait, sanitize markdown via heredoc * Resolve merge: accept upstream renames/installer (fix/installer-cleanup-v2) and keep local framing/script-editing - Restored upstream server.py, EditorWindow, uv.lock\n- Preserved ManageScript editing/validation; switched to atomic write + debounced refresh\n- Updated tools/__init__.py to keep script_edits/resources and adopt new logger name\n- All Python tests via uv: 7 passed, 6 skipped, 9 xpassed; Unity compile OK * Fix Claude Desktop config path and atomic write issues - Fix macOS path for Claude Desktop config: use ~/Library/Application Support/Claude/ instead of ~/.config/Claude/ - Improve atomic write pattern with backup/restore safety - Replace File.Replace() with File.Move() for better macOS compatibility - Add proper error handling and cleanup for file operations - Resolves issue where installer couldn't find Claude Desktop config on macOS * Editor: use macConfigPath on macOS for MCP client config writes (Claude Desktop, etc.). Fallback to linuxConfigPath only if mac path missing. * Models: add macConfigPath to McpClient for macOS config path selection (fixes CS1061 in editor window). * Editor: on macOS, prefer macConfigPath in ManualConfigEditorWindow (fallback to linux path); Linux/Windows unchanged. * Fix McpClient: align with upstream/main, prep for framing split * NL suite: shard workflow; tighten bridge readiness; add MCP preflight; use env-based shard vars * NL suite: fix shard step indentation; move shard vars to env; remove invalid inputs * MCP clients: split VSCode Copilot config paths into macConfigPath and linuxConfigPath * Unity bridge: clean stale status; bind host; robust wait probe with IPv4/IPv6 + diagnostics * CI: use MCPForUnity.Editor.MCPForUnityBridge.StartAutoConnect as executeMethod * Action wiring: inline mcpServers in settings for all shards; remove redundant .claude/mcp.json step * CI: embed mcpServers in settings for all shards; fix startup sanity step; lint clean * CI: pin claude-code-base-action to e6f32c8; use claude_args --mcp-config; switch to allowed_tools; ensure MCP config per step * CI: unpin claude-code-base-action to @beta (commit ref not found) * CI: align with claude-code-base-action @beta; pass MCP via claude_args and allowedTools * Editor: Fix apply_text_edits heuristic when edits shift positions; recompute method span on candidate text with fallback delta adjustment * CI: unify MCP wiring across workflows; write .claude/mcp.json; switch to claude_args with --mcp-config/--allowedTools; remove unsupported inputs * CI: collapse NL suite shards into a single run to avoid repeated test execution * CI: minimize allowedTools for NL suite to essential Unity MCP + Bash("git:*") + Write * CI: mkdir -p reports before run; remove unsupported --timeout-minutes from claude_args * CI: broaden allowedTools to include find_in_file and mcp__unity__* * CI: enable use_node_cache and switch NL suite model to claude-3-7-haiku-20250219 * CI: disable use_node_cache to avoid setup-node lockfile error * CI: set NL suite model to claude-3-haiku-20240307 * CI: cap Haiku output with --max-tokens 2048 for NL suite * CI: switch to claude-3-7-sonnet-latest and remove unsupported --max-tokens * CI: update allowedTools to Bash(*) and explicit Unity MCP tool list * CI: update NL suite workflow (latest tweaks) * Tests: tighten NL suite prompt for logging, hash discipline, stale retry, evidence windows, diff cap, and VERDICT line * Add disallowed tools to NL suite workflow * docs: clarify stale write retry * Add fallback JUnit report and adjust publisher * Indent fallback JUnit XML in workflow * fix: correct fallback JUnit report generation * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update Response.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update MCPForUnityBridge.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: correct McpTypes reference * Add directory existence checks for symlink and XDG paths * fix: only set installation flag after successful server install * Update resource_tools.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: respect mac config paths * Use File.Replace for atomic config write * Remove unused imports in manage_script * bump server version * Tests: update NL suite prompt and workflows; remove deprecated smoke/desktop-parity; quickprobe tidy * Editor: atomic config write via File.Replace fallback; remove redundant backups and racey exists checks * CI: harden NL suite - idempotent docker, gate on unity_ok, safer port probe, least-priv perms * Editor: make atomic config write restoration safe (flag writeDone; copy-overwrite restore; cleanup in finally) * CI: fix fallback JUnit heredoc by using printf lines (no EOF delimiter issues) * CI: switch NL suite to mini prompt; mini prompt honors / and NL discipline * CI: replace claude_args with allowed_tools/model/mcp_config per action schema * CI: expand UNITY_PROJECT_ROOT via in MCP config heredoc * EditorWindow: add cross-platform fallback for File.Replace; macOS-insensitive PathsEqual; safer uv resolve; honor macConfigPath * CI: strengthen JUnit publishing for NL mini suite (normalize, debug list, publish both, fail_on_parse_error) * CI: set job-wide JUNIT_OUT/MD_OUT; normalization uses env; publish references env and ungroup reports * CI: publish a single normalized JUnit (reports/junit-for-actions.xml); fallback writes same; avoid checkName/reportPaths mismatch * CI: align mini prompt report filenames; redact Unity log tail in diagnostics * chore: sync workflow and mini prompt; redacted logs; JUnit normalization/publish tweaks * CI: redact sensitive tokens in Stop Unity; docs: CI usage + edit tools * prompts: update nl-unity-suite-full (mini-style setup + reporting discipline); remove obsolete prompts * CI: harden NL workflows (timeout_minutes, robust normalization); prompts: unify JUnit suite name and reporting discipline * prompts: add guarded write pattern (LF hash, stale_file retry) to full suite * prompts: enforce continue-on-failure, driver flow, and status handling in full suite * Make test list more explicit in prompt. Get rid of old test prompts for hygeine. * prompts: add stale fast-retry (server hash) + in-memory buf guidance * CI: standardize JUNIT_OUT to reports/junit-nl-suite.xml; fix artifact upload indentation; prompt copy cleanups * prompts: reporting discipline — append-only fragments, batch writes, no model round-trip * prompts: stale fast-retry preference, buffer/sha carry, snapshot revert, essential logging * workflows(nl-suite): precreate report skeletons, assemble junit, synthesize markdown; restrict allowed_tools to append-only Bash + MCP tools * thsis too * Update README-DEV.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite-mini.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * workflows(nl-mini): fix YAML indentation/trailing spaces under with: and cleanup heredoc spacing * workflows(nl-suite): fix indentation on docker logs redaction line (YAML lint) * Add write to allowlist * nl-suite: harden reporting discipline (fragment-only writes, forbid alt paths); workflow: clean stray junit-*updated*.xml * nl-suite: enforce end-of-suite single Write (no bash redirection); workflow: restrict allowed_tools to Write+MCP only * prompts(nl-full): end-of-suite results must be valid XML with single <cases> root and only <testcase> children; no raw text outside CDATA * workflows(nl-suite): make Claude step non-fatal; tolerant normalizer extracts <testcase> via regex on bad fragments * nl-suite: fix stale classname to UnityMCP.NL-T in mini fallback; prompt: require re-read after every revert; correct PLAN/PROGRESS to 15 * nl-suite: fix fallback JUnit classname to UnityMCP.NL-T; prompt: forbid create_script and env/mkdir checks, enforce single baseline-byte revert flow and post-revert re-read; add corruption-handling guidance * prompts(nl-full): after each write re-read raw bytes to refresh pre_sha; prefer script_apply_edits for anchors; avoid header/using changes * prompts(nl-full): canonicalize outputs to /; allow small fragment appends via Write or Bash(printf/echo); forbid wrappers and full-file round-trips * prompts(nl-full): finalize markdown formatting for guarded write, execution order, specs, status * workflows(nl-suite, mini): header/lint fixes and constrained Bash append path; align allowed_tools * prompts(nl-full): format Fast Restore, Guarded Write, Execution, Specs, Status as proper markdown lists and code fences * workflows(nl-suite): keep header tidy and append-path alignment with prompt * minor fix * workflows(nl-suite): fix indentation and dispatch; align allowed_tools and revert helper * prompts(nl-full): switch to read_resource for buf/sha; re-read only when needed; convert 'Print this once' to heading; note snapshot helper creates parent dirs * workflows(nl-suite): normalize step removes bootstrap when real testcases present; recompute tests/failures * workflows(nl-suite): enrich Markdown summary by extracting per-test <system-out> blocks (truncated) * clarify prompt resilience instructions * ci(nl-suite): revert prompt and workflow to known-good e0f8a72 for green run; remove extra MD details * ci(nl-suite): minimal fixes — no-mkdir guard in prompt; drop bootstrap and recompute JUnit counts * ci(nl-suite): richer JUnit→Markdown report (per-test system-out) * Small guard to incorret asset read call. * ci(nl-suite): refine MD builder — unescape XML entities, safe code fences, PASS/FAIL badges * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * server(manage_script): robust URI handling — percent-decode file://, normalize, strip host/leading slashes, return Assets-relative if present * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * tests(framing): reduce handshake poll window, nonblocking peek to avoid disconnect race; still enforce pre-handshake data drop * tests(manage_script): add _split_uri tests for unity://path, file:// URLs (decoded/Assets-relative), and plain paths * server+tests: fix handshake syntax error; robust file:// URI normalization in manage_script; add _split_uri tests; adjust stdout scan to ignore venv/site-packages * bridge(framing): accept zero-length frames (treat as empty keepalive) * tests(logging): use errors='replace' on decode fallback to avoid silent drops * resources(list): restrict to Assets/, resolve symlinks, enforce .cs; add traversal/outside-path tests * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * misc: framing keepalive (zero-length), regex preview consistency, resource.list hardening, URI parsing, legacy update routing, test cleanups * docs(tools): richer MCP tool descriptions; tests accept decorator kwargs; resource URI parsing hardened * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * net+docs: hard-reject zero-length frames; TCP_NODELAY on connect; Assets detection case-insensitive; NL prompt statuses aligned * prompt(nl-suite): constrain Write destinations under reports/, forbid traversal * prompt+net: harden Write path rules; use monotonic deadline and plain-text advisory for non-framed peers * unity_connection: restore recv timeout via try/finally; make global connection getter thread-safe with module lock and double-checked init * NL/T prompt: pin structured edit ops for T-D/T-E; add schema-error guarded write behavior; keep existing path/URI and revert rules * unity_connection: add FRAMED_MAX; use ValueError for framed length violations; lower framed receive log to debug; serialize connect() with per-instance lock * ManageScript: use UTF8Encoding(without BOM) for atomic writes in ApplyTextEdits/EditScript to align with Create/Update and avoid BOM-related diffs/hash mismatches * NL/T prompt: make helper deletion regex multiline-safe ((?ms) so ^ anchors line starts) * ManageScript: emit structured overlap status {status:"overlap"} for overlapping edit ranges in apply_text_edits and edit paths * NL/T prompt: clarify fallback vs failure — fallback only for unsupported/missing_field; treat bad_request as failure; note unsupported after fallback as failure * NL/T prompt: pin deterministic overlap probe (apply_text_edits two ranges from same snapshot); gate too_large behind RUN_TOO_LARGE env hint * TB update * NL/T prompt: harden Output Rules — constrain Bash(printf|echo) to stdout-only; forbid redirection/here-docs/tee; only scripts/nlt-revert.sh may mutate FS * Prompt: enumerate allowed script_apply_edits ops; add manage_editor/read_console guidance; fix T‑F atomic batch to single script_apply_edits. ManageScript: regex timeout for diagnostics; symlink ancestor guard; complete allowed-modes list. * Fixes * ManageScript: add rich overlap diagnostics (conflicts + hint) for both text range and structured batch paths * ManageScript: return structured {status:"validation_failed"} diagnostics in create/update/edits and validate before commit * ManageScript: echo canonical uri in responses (create/read/update/apply_text_edits/structured edits) to reinforce resource identity * improve clarity of capabilities message * Framing: allow zero-length frames on both ends (C# bridge, Python server). Prompt: harden T-F to single text-range apply_text_edits batch (descending order, one snapshot). URI: normalize file:// outside Assets by stripping leading slash. * ManageScript: include new sha256 in success payload for apply_text_edits; harden TryResolveUnderAssets by rejecting symlinked ancestors up to Assets/. * remove claudetest dir * manage_script_edits: normalize method-anchored anchor_insert to insert_method (map text->replacement); improves CI compatibility for T‑A/T‑E without changing Editor behavior. * tighten testing protocol around mkdir * manage_script: validate create_script inputs (Assets/.cs/name/no traversal); add Assets/ guard to delete_script; validate level+Assets in validate_script; make legacy manage_script optional params; harden legacy update routing with base64 reuse and payload size preflight. * Tighten prompt for testing * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script_edits: honor ignore_case on anchor_insert and regex_replace in both direct and text-conversion paths (MULTILINE|IGNORECASE). * remove extra file * workflow: use python3 for inline scripts and port detection on ubuntu-latest. * Tighten prompt + manage_script * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script: improve file:// UNC handling; preserve POSIX absolute semantics internally; keep test-expected slash stripping for non-Assets paths. * ManageScript.cs: add TimeSpan timeouts to all Regex uses (IsMatch/Match/new Regex) and keep CultureInvariant/Multiline options; reduces risk of catastrophic backtracking stalls. * workflow: ensure reports/ exists in markdown build step to avoid FileNotFoundError when writing MD_OUT. * fix brace * manage_script_edits: expand backrefs for regex_replace in preview->text conversion and translate to \g<n> in local apply; keeps previews and actual edits consistent. * anchor_insert: default to position=after, normalize surrounding newlines in Python conversion paths; C# path ensures trailing newline and skips duplicate insertion within class. * feat(mcp): add get_sha tool; apply_text_edits normalization+overlap preflight+strict; no-op evidence in C#; update NL suite prompt; add unit tests * feat(frames): accept zero-length heartbeat frames in client; add heartbeat test * feat(edits): guard destructive regex_replace with structural preflight; add robust tests; prompt uses delete_method for temp helper * feat(frames): bound heartbeat loop with timeout/threshold; align zero-length response with C#; update test * SDK hardening: atomic multi-span text edits; stop forcing sequential for structured ops; forward options on apply_text_edits; add validate=relaxed support and scoped checks; update NL/T prompt; add tests for options forwarding, relaxed mode, and atomic batches * Router: default applyMode=atomic for multi-span apply_text_edits; add tests * CI prompt: pass options.validate=relaxed for T-B/C; options.applyMode=atomic for T-F; emphasize always writing testcase and restoring on errors * Validation & DX: add validate=syntax (scoped), standardize evidence windows; early regex compile with hints; debug_preview for apply_text_edits * Update UnityMcpBridge/Editor/Windows/MCPForUnityEditorWindow.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * NL/T suite-driven edits: LongUnityScriptClaudeTest, bridge helpers, server_version; prepare framing tests * Fix duplicate macConfigPath field in McpClient to resolve CS0102 * Editor threading: run EnsureServerInstalled on main thread; marshal EditorPrefs/DeleteKey + logging via delayCall * Docs(apply_text_edits): strengthen guidance on 1-based positions, verify-before-edit, and recommend anchors/structured edits * Docs(script_apply_edits): add safety guidance (anchors, method ops, validators) and recommended practices * Framed VerifyBridgePing in editor window; docs hardening for apply_text_edits and script_apply_edits --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-31 00:55:38 +08:00
if isinstance(response, dict):
if response.get("success"):
if response.get("data", {}).get("contentsEncoded"):
decoded_contents = base64.b64decode(response["data"]["encodedContents"]).decode('utf-8')
response["data"]["contents"] = decoded_contents
del response["data"]["encodedContents"]
del response["data"]["contentsEncoded"]
return {
"success": True,
"message": response.get("message", "Operation successful."),
"data": response.get("data"),
}
return response
return {"success": False, "message": str(response)}
except Exception as e:
return {
"success": False,
"message": f"Python error managing script: {str(e)}",
}
@mcp.tool(description=(
"Get manage_script capabilities (supported ops, limits, and guards).\n\n"
"Returns:\n- ops: list of supported structured ops\n- text_ops: list of supported text ops\n- max_edit_payload_bytes: server edit payload cap\n- guards: header/using guard enabled flag\n"
))
def manage_script_capabilities(ctx: Context) -> Dict[str, Any]:
try:
# Keep in sync with server/Editor ManageScript implementation
ops = [
"replace_class","delete_class","replace_method","delete_method",
"insert_method","anchor_insert","anchor_delete","anchor_replace"
]
text_ops = ["replace_range","regex_replace","prepend","append"]
# Match ManageScript.MaxEditPayloadBytes if exposed; hardcode a sensible default fallback
max_edit_payload_bytes = 256 * 1024
guards = {"using_guard": True}
extras = {"get_sha": True}
return {"success": True, "data": {
"ops": ops,
"text_ops": text_ops,
"max_edit_payload_bytes": max_edit_payload_bytes,
"guards": guards,
"extras": extras,
}}
except Exception as e:
return {"success": False, "error": f"capabilities error: {e}"}
@mcp.tool(description=(
"Get SHA256 and metadata for a Unity C# script without returning file contents.\n\n"
"Args: uri (unity://path/Assets/... or file://... or Assets/...).\n"
"Returns: {sha256, lengthBytes, lastModifiedUtc, uri, path}."
))
def get_sha(ctx: Context, uri: str) -> Dict[str, Any]:
"""Return SHA256 and basic metadata for a script."""
try:
name, directory = _split_uri(uri)
params = {"action": "get_sha", "name": name, "path": directory}
resp = send_command_with_retry("manage_script", params)
return resp if isinstance(resp, dict) else {"success": False, "message": str(resp)}
except Exception as e:
Claude‑friendly edit tools + framed transport + live Unity NL test framework (#243) * CI: gate desktop-parity on Anthropic key; pass anthropic_api_key like NL suite * Add quickprobe prompt and CI workflow (mcp-quickprobe.md, unity-mcp-quickprobe.yml) * strictier tool use to prevent subagent spawning and force mcp tools * update workflow filesto reduce likelihood of subagent spawning * improve permissions for claude agent, fix mcpbridge timeout/token issue * increase max turns to 10 * ci: align NL suite to new permissions schema; prevent subagent drift * ci: NL suite -> mini prompt for e2e; add full NL/T prompt; server: ctx optional + project_root fallback; workflows: set UNITY_PROJECT_ROOT for CI * ci: add checks:write; revert local project hardcodes (manifest, ProjectVersion.txt) * tools: text-edit routing fixes (anchor_insert via text, CRLF calc); prompts: mini NL/T clarifications * ci: use absolute UNITY_PROJECT_ROOT; prompts target TestProjects; server: accept relative UNITY_PROJECT_ROOT and bare spec URI * ci: ignore Unity test project's packages-lock.json; remove from repo to avoid absolute paths * CI: start persistent Unity Editor for MCP (guarded by license) + allow batch-mode bridge via UNITY_MCP_ALLOW_BATCH * CI: hide license and pass via env to docker; fix invalid ref format * CI: readiness probe uses handshake on Unity MCP port (deterministic) * CI: fix YAML; use TCP handshake readiness probe (FRAMING=1) * CI: prime Unity license via game-ci; mount ULF into container; extend readiness timeout * CI: use ULF write + mount for Unity licensing; remove serial/email/pass from container * CI: entitlement activation (UNITY_SERIAL=''); verify host ULF cache; keep mount * CI: write ULF from secret and verify; drop entitlement activation step * CI: detect any licensing path; GameCI prime; status dir env; log+probe readiness; fix YAML * CI: add GameCI license prime; conditional ULF write; one-shot license validation; explicit status dir + license env * CI: fix YAML (inline python), add Anthropic key detect via GITHUB_ENV; ready to run happy path * CI: mount Unity token/ulf/cache dirs into container to share host license; create dirs before start * CI: fix YAML indentation; write ULF on host; activate in container with shared mounts; mount .config and .cache too * CI: gate Claude via outputs; mount all Unity license dirs; fix inline probe python; stabilize licensing flow * CI: normalize detect to step outputs; ensure license dirs mounted and validated; fix indentation * Bridge: honor UNITY_MCP_STATUS_DIR for heartbeat/status file (CI-friendly) * CI: guard project path for activation/start; align tool allowlist; run MCP server with python; tighten secret scoping * CI: finalize Unity licensing mounts + status dir; mode-detect (ULF/EBL); readiness logs+probe; Claude gating via outputs * CI: fix YAML probe (inline python -c) and finalize happy-path Unity licensing and MCP/Claude wiring * CI: inline python probe; unify Unity image and cache mounts; ready to test * CI: fix docker run IMAGE placement; ignore cache find perms; keep same editor image * CI: pass -manualLicenseFile to persistent Editor; keep mounts and single image * CI: mount full GameCI cache to /root in persistent Unity; set HOME=/root; add optional license check * CI: make -manualLicenseFile conditional; keep full /root mount and license check * CI: set HOME=/github/home; mount GameCI cache there; adjust manualLicenseFile path; expand license check * CI: EBL sign-in for persistent Unity (email/password/serial); revert HOME=/root and full /root mount; keep conditional manualLicenseFile and improved readiness * CI: run full NL/T suite prompt (nl-unity-suite-full.md) instead of mini * NL/T: require unified diffs + explicit verdicts in JUnit; CI: remove short sanity step, publish JUnit, upload artifacts * NL/T prompt: require CDATA wrapping for JUnit XML fields; guidance for splitting embedded ]]>; keep VERDICT in CDATA only * CI: remove in-container license check step; keep readiness and full suite * NL/T prompt: add version header, stricter JUnit schema, hashing/normalization, anchors, statuses, atomic semantics, tool logging * CI: increase Claude NL/T suite timeout to 30 minutes * CI: pre-create reports dir and result files to avoid tool approval prompts * CI: skip wait if container not running; skip Editor start if project missing; broaden MCP deps detection; expand allowed tools * fixies to harden ManageScript * CI: sanitize NL/T markdown report to avoid NUL/encoding issues * revert breaking yyaml changes * CI: prime license, robust Unity start/wait, sanitize markdown via heredoc * Resolve merge: accept upstream renames/installer (fix/installer-cleanup-v2) and keep local framing/script-editing - Restored upstream server.py, EditorWindow, uv.lock\n- Preserved ManageScript editing/validation; switched to atomic write + debounced refresh\n- Updated tools/__init__.py to keep script_edits/resources and adopt new logger name\n- All Python tests via uv: 7 passed, 6 skipped, 9 xpassed; Unity compile OK * Fix Claude Desktop config path and atomic write issues - Fix macOS path for Claude Desktop config: use ~/Library/Application Support/Claude/ instead of ~/.config/Claude/ - Improve atomic write pattern with backup/restore safety - Replace File.Replace() with File.Move() for better macOS compatibility - Add proper error handling and cleanup for file operations - Resolves issue where installer couldn't find Claude Desktop config on macOS * Editor: use macConfigPath on macOS for MCP client config writes (Claude Desktop, etc.). Fallback to linuxConfigPath only if mac path missing. * Models: add macConfigPath to McpClient for macOS config path selection (fixes CS1061 in editor window). * Editor: on macOS, prefer macConfigPath in ManualConfigEditorWindow (fallback to linux path); Linux/Windows unchanged. * Fix McpClient: align with upstream/main, prep for framing split * NL suite: shard workflow; tighten bridge readiness; add MCP preflight; use env-based shard vars * NL suite: fix shard step indentation; move shard vars to env; remove invalid inputs * MCP clients: split VSCode Copilot config paths into macConfigPath and linuxConfigPath * Unity bridge: clean stale status; bind host; robust wait probe with IPv4/IPv6 + diagnostics * CI: use MCPForUnity.Editor.MCPForUnityBridge.StartAutoConnect as executeMethod * Action wiring: inline mcpServers in settings for all shards; remove redundant .claude/mcp.json step * CI: embed mcpServers in settings for all shards; fix startup sanity step; lint clean * CI: pin claude-code-base-action to e6f32c8; use claude_args --mcp-config; switch to allowed_tools; ensure MCP config per step * CI: unpin claude-code-base-action to @beta (commit ref not found) * CI: align with claude-code-base-action @beta; pass MCP via claude_args and allowedTools * Editor: Fix apply_text_edits heuristic when edits shift positions; recompute method span on candidate text with fallback delta adjustment * CI: unify MCP wiring across workflows; write .claude/mcp.json; switch to claude_args with --mcp-config/--allowedTools; remove unsupported inputs * CI: collapse NL suite shards into a single run to avoid repeated test execution * CI: minimize allowedTools for NL suite to essential Unity MCP + Bash("git:*") + Write * CI: mkdir -p reports before run; remove unsupported --timeout-minutes from claude_args * CI: broaden allowedTools to include find_in_file and mcp__unity__* * CI: enable use_node_cache and switch NL suite model to claude-3-7-haiku-20250219 * CI: disable use_node_cache to avoid setup-node lockfile error * CI: set NL suite model to claude-3-haiku-20240307 * CI: cap Haiku output with --max-tokens 2048 for NL suite * CI: switch to claude-3-7-sonnet-latest and remove unsupported --max-tokens * CI: update allowedTools to Bash(*) and explicit Unity MCP tool list * CI: update NL suite workflow (latest tweaks) * Tests: tighten NL suite prompt for logging, hash discipline, stale retry, evidence windows, diff cap, and VERDICT line * Add disallowed tools to NL suite workflow * docs: clarify stale write retry * Add fallback JUnit report and adjust publisher * Indent fallback JUnit XML in workflow * fix: correct fallback JUnit report generation * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update mcp-quickprobe.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update Response.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update MCPForUnityBridge.cs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: correct McpTypes reference * Add directory existence checks for symlink and XDG paths * fix: only set installation flag after successful server install * Update resource_tools.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: respect mac config paths * Use File.Replace for atomic config write * Remove unused imports in manage_script * bump server version * Tests: update NL suite prompt and workflows; remove deprecated smoke/desktop-parity; quickprobe tidy * Editor: atomic config write via File.Replace fallback; remove redundant backups and racey exists checks * CI: harden NL suite - idempotent docker, gate on unity_ok, safer port probe, least-priv perms * Editor: make atomic config write restoration safe (flag writeDone; copy-overwrite restore; cleanup in finally) * CI: fix fallback JUnit heredoc by using printf lines (no EOF delimiter issues) * CI: switch NL suite to mini prompt; mini prompt honors / and NL discipline * CI: replace claude_args with allowed_tools/model/mcp_config per action schema * CI: expand UNITY_PROJECT_ROOT via in MCP config heredoc * EditorWindow: add cross-platform fallback for File.Replace; macOS-insensitive PathsEqual; safer uv resolve; honor macConfigPath * CI: strengthen JUnit publishing for NL mini suite (normalize, debug list, publish both, fail_on_parse_error) * CI: set job-wide JUNIT_OUT/MD_OUT; normalization uses env; publish references env and ungroup reports * CI: publish a single normalized JUnit (reports/junit-for-actions.xml); fallback writes same; avoid checkName/reportPaths mismatch * CI: align mini prompt report filenames; redact Unity log tail in diagnostics * chore: sync workflow and mini prompt; redacted logs; JUnit normalization/publish tweaks * CI: redact sensitive tokens in Stop Unity; docs: CI usage + edit tools * prompts: update nl-unity-suite-full (mini-style setup + reporting discipline); remove obsolete prompts * CI: harden NL workflows (timeout_minutes, robust normalization); prompts: unify JUnit suite name and reporting discipline * prompts: add guarded write pattern (LF hash, stale_file retry) to full suite * prompts: enforce continue-on-failure, driver flow, and status handling in full suite * Make test list more explicit in prompt. Get rid of old test prompts for hygeine. * prompts: add stale fast-retry (server hash) + in-memory buf guidance * CI: standardize JUNIT_OUT to reports/junit-nl-suite.xml; fix artifact upload indentation; prompt copy cleanups * prompts: reporting discipline — append-only fragments, batch writes, no model round-trip * prompts: stale fast-retry preference, buffer/sha carry, snapshot revert, essential logging * workflows(nl-suite): precreate report skeletons, assemble junit, synthesize markdown; restrict allowed_tools to append-only Bash + MCP tools * thsis too * Update README-DEV.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite-mini.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/workflows/claude-nl-suite.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * workflows(nl-mini): fix YAML indentation/trailing spaces under with: and cleanup heredoc spacing * workflows(nl-suite): fix indentation on docker logs redaction line (YAML lint) * Add write to allowlist * nl-suite: harden reporting discipline (fragment-only writes, forbid alt paths); workflow: clean stray junit-*updated*.xml * nl-suite: enforce end-of-suite single Write (no bash redirection); workflow: restrict allowed_tools to Write+MCP only * prompts(nl-full): end-of-suite results must be valid XML with single <cases> root and only <testcase> children; no raw text outside CDATA * workflows(nl-suite): make Claude step non-fatal; tolerant normalizer extracts <testcase> via regex on bad fragments * nl-suite: fix stale classname to UnityMCP.NL-T in mini fallback; prompt: require re-read after every revert; correct PLAN/PROGRESS to 15 * nl-suite: fix fallback JUnit classname to UnityMCP.NL-T; prompt: forbid create_script and env/mkdir checks, enforce single baseline-byte revert flow and post-revert re-read; add corruption-handling guidance * prompts(nl-full): after each write re-read raw bytes to refresh pre_sha; prefer script_apply_edits for anchors; avoid header/using changes * prompts(nl-full): canonicalize outputs to /; allow small fragment appends via Write or Bash(printf/echo); forbid wrappers and full-file round-trips * prompts(nl-full): finalize markdown formatting for guarded write, execution order, specs, status * workflows(nl-suite, mini): header/lint fixes and constrained Bash append path; align allowed_tools * prompts(nl-full): format Fast Restore, Guarded Write, Execution, Specs, Status as proper markdown lists and code fences * workflows(nl-suite): keep header tidy and append-path alignment with prompt * minor fix * workflows(nl-suite): fix indentation and dispatch; align allowed_tools and revert helper * prompts(nl-full): switch to read_resource for buf/sha; re-read only when needed; convert 'Print this once' to heading; note snapshot helper creates parent dirs * workflows(nl-suite): normalize step removes bootstrap when real testcases present; recompute tests/failures * workflows(nl-suite): enrich Markdown summary by extracting per-test <system-out> blocks (truncated) * clarify prompt resilience instructions * ci(nl-suite): revert prompt and workflow to known-good e0f8a72 for green run; remove extra MD details * ci(nl-suite): minimal fixes — no-mkdir guard in prompt; drop bootstrap and recompute JUnit counts * ci(nl-suite): richer JUnit→Markdown report (per-test system-out) * Small guard to incorret asset read call. * ci(nl-suite): refine MD builder — unescape XML entities, safe code fences, PASS/FAIL badges * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .github/scripts/mark_skipped.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * server(manage_script): robust URI handling — percent-decode file://, normalize, strip host/leading slashes, return Assets-relative if present * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * tests(framing): reduce handshake poll window, nonblocking peek to avoid disconnect race; still enforce pre-handshake data drop * tests(manage_script): add _split_uri tests for unity://path, file:// URLs (decoded/Assets-relative), and plain paths * server+tests: fix handshake syntax error; robust file:// URI normalization in manage_script; add _split_uri tests; adjust stdout scan to ignore venv/site-packages * bridge(framing): accept zero-length frames (treat as empty keepalive) * tests(logging): use errors='replace' on decode fallback to avoid silent drops * resources(list): restrict to Assets/, resolve symlinks, enforce .cs; add traversal/outside-path tests * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * misc: framing keepalive (zero-length), regex preview consistency, resource.list hardening, URI parsing, legacy update routing, test cleanups * docs(tools): richer MCP tool descriptions; tests accept decorator kwargs; resource URI parsing hardened * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/unity_connection.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * net+docs: hard-reject zero-length frames; TCP_NODELAY on connect; Assets detection case-insensitive; NL prompt statuses aligned * prompt(nl-suite): constrain Write destinations under reports/, forbid traversal * prompt+net: harden Write path rules; use monotonic deadline and plain-text advisory for non-framed peers * unity_connection: restore recv timeout via try/finally; make global connection getter thread-safe with module lock and double-checked init * NL/T prompt: pin structured edit ops for T-D/T-E; add schema-error guarded write behavior; keep existing path/URI and revert rules * unity_connection: add FRAMED_MAX; use ValueError for framed length violations; lower framed receive log to debug; serialize connect() with per-instance lock * ManageScript: use UTF8Encoding(without BOM) for atomic writes in ApplyTextEdits/EditScript to align with Create/Update and avoid BOM-related diffs/hash mismatches * NL/T prompt: make helper deletion regex multiline-safe ((?ms) so ^ anchors line starts) * ManageScript: emit structured overlap status {status:"overlap"} for overlapping edit ranges in apply_text_edits and edit paths * NL/T prompt: clarify fallback vs failure — fallback only for unsupported/missing_field; treat bad_request as failure; note unsupported after fallback as failure * NL/T prompt: pin deterministic overlap probe (apply_text_edits two ranges from same snapshot); gate too_large behind RUN_TOO_LARGE env hint * TB update * NL/T prompt: harden Output Rules — constrain Bash(printf|echo) to stdout-only; forbid redirection/here-docs/tee; only scripts/nlt-revert.sh may mutate FS * Prompt: enumerate allowed script_apply_edits ops; add manage_editor/read_console guidance; fix T‑F atomic batch to single script_apply_edits. ManageScript: regex timeout for diagnostics; symlink ancestor guard; complete allowed-modes list. * Fixes * ManageScript: add rich overlap diagnostics (conflicts + hint) for both text range and structured batch paths * ManageScript: return structured {status:"validation_failed"} diagnostics in create/update/edits and validate before commit * ManageScript: echo canonical uri in responses (create/read/update/apply_text_edits/structured edits) to reinforce resource identity * improve clarity of capabilities message * Framing: allow zero-length frames on both ends (C# bridge, Python server). Prompt: harden T-F to single text-range apply_text_edits batch (descending order, one snapshot). URI: normalize file:// outside Assets by stripping leading slash. * ManageScript: include new sha256 in success payload for apply_text_edits; harden TryResolveUnderAssets by rejecting symlinked ancestors up to Assets/. * remove claudetest dir * manage_script_edits: normalize method-anchored anchor_insert to insert_method (map text->replacement); improves CI compatibility for T‑A/T‑E without changing Editor behavior. * tighten testing protocol around mkdir * manage_script: validate create_script inputs (Assets/.cs/name/no traversal); add Assets/ guard to delete_script; validate level+Assets in validate_script; make legacy manage_script optional params; harden legacy update routing with base64 reuse and payload size preflight. * Tighten prompt for testing * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script_edits: honor ignore_case on anchor_insert and regex_replace in both direct and text-conversion paths (MULTILINE|IGNORECASE). * remove extra file * workflow: use python3 for inline scripts and port detection on ubuntu-latest. * Tighten prompt + manage_script * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update UnityMcpBridge/Editor/Tools/ManageScript.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update .claude/prompts/nl-unity-suite-full.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * manage_script: improve file:// UNC handling; preserve POSIX absolute semantics internally; keep test-expected slash stripping for non-Assets paths. * ManageScript.cs: add TimeSpan timeouts to all Regex uses (IsMatch/Match/new Regex) and keep CultureInvariant/Multiline options; reduces risk of catastrophic backtracking stalls. * workflow: ensure reports/ exists in markdown build step to avoid FileNotFoundError when writing MD_OUT. * fix brace * manage_script_edits: expand backrefs for regex_replace in preview->text conversion and translate to \g<n> in local apply; keeps previews and actual edits consistent. * anchor_insert: default to position=after, normalize surrounding newlines in Python conversion paths; C# path ensures trailing newline and skips duplicate insertion within class. * feat(mcp): add get_sha tool; apply_text_edits normalization+overlap preflight+strict; no-op evidence in C#; update NL suite prompt; add unit tests * feat(frames): accept zero-length heartbeat frames in client; add heartbeat test * feat(edits): guard destructive regex_replace with structural preflight; add robust tests; prompt uses delete_method for temp helper * feat(frames): bound heartbeat loop with timeout/threshold; align zero-length response with C#; update test * SDK hardening: atomic multi-span text edits; stop forcing sequential for structured ops; forward options on apply_text_edits; add validate=relaxed support and scoped checks; update NL/T prompt; add tests for options forwarding, relaxed mode, and atomic batches * Router: default applyMode=atomic for multi-span apply_text_edits; add tests * CI prompt: pass options.validate=relaxed for T-B/C; options.applyMode=atomic for T-F; emphasize always writing testcase and restoring on errors * Validation & DX: add validate=syntax (scoped), standardize evidence windows; early regex compile with hints; debug_preview for apply_text_edits * Update UnityMcpBridge/Editor/Windows/MCPForUnityEditorWindow.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * NL/T suite-driven edits: LongUnityScriptClaudeTest, bridge helpers, server_version; prepare framing tests * Fix duplicate macConfigPath field in McpClient to resolve CS0102 * Editor threading: run EnsureServerInstalled on main thread; marshal EditorPrefs/DeleteKey + logging via delayCall * Docs(apply_text_edits): strengthen guidance on 1-based positions, verify-before-edit, and recommend anchors/structured edits * Docs(script_apply_edits): add safety guidance (anchors, method ops, validators) and recommended practices * Framed VerifyBridgePing in editor window; docs hardening for apply_text_edits and script_apply_edits --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-31 00:55:38 +08:00
return {"success": False, "message": f"get_sha error: {e}"}