-
Notifications
You must be signed in to change notification settings - Fork 0
Framed transport + Claude‑friendly edit tools + live Unity NL test framework #42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ck; add uv -q for quieter stdio; MCP server: compatibility guards for capabilities/resource decorators and indentation fix; ManageScript: shadow var fix; robust mac config path.
…text edits; anchor aliasing and text-op conversion; immediate compile on NL/structured; add resource_tools (tail_lines, find_in_file); update test cases
…xt ops; preview+confirm for regex; safe_script_edit wrapper; immediate compile & verification; header-safe anchors
…ck; add uv -q for quieter stdio; MCP server: compatibility guards for capabilities/resource decorators and indentation fix; ManageScript: shadow var fix; robust mac config path.
…add SHA precondition and immediate refresh; keep verification slice; minor test and uv.lock updates
…cription with canonical fields & examples; alias/wrapper normalization; machine-parsable validation hints; auto applyMode=sequential for mixed insert+replace; echo normalizedEdits
…edit'; add routing='text' for pure text; echo normalizedEdits; C#: include 'code' in error payloads
…ontext access might be invalid' on forks
…enrich spec examples; add routing metadata; add standalone long test script
…ed-named-value-errors
…ed-named-value-errors-1zr4mk
…onfig fix: update Unity MCP server path in workflow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (2)
.github/workflows/claude-nl-suite.yml (2)
47-47
: Pin all third‑party Actions by immutable commit SHAs.Prevents supply‑chain drift and stabilizes CI. Apply at each uses: line shown below.
- - uses: actions/checkout@v4 + - uses: actions/checkout@<commit-sha> - - uses: astral-sh/setup-uv@v4 + - uses: astral-sh/setup-uv@<commit-sha> - uses: game-ci/unity-test-runner@v4 + uses: game-ci/unity-test-runner@<commit-sha> - uses: anthropics/claude-code-base-action@beta + uses: anthropics/claude-code-base-action@<commit-sha> - uses: mikepenz/action-junit-report@v5 + uses: mikepenz/action-junit-report@<commit-sha> - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@<commit-sha>List all unpinned actions in the repo:
#!/bin/bash rg -nP 'uses:\s+\S+@(?!(?:[a-f0-9]{40}))' .github/workflows/*.ymlAlso applies to: 52-52, 76-76, 251-251, 454-454, 466-466
14-17
: Pin Unity Docker image by digest to avoid tag drift.Locks the editor image for reproducible runs.
env: UNITY_VERSION: 2021.3.45f1 - UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3 + # Pin to immutable digest (replace <DIGEST> with the resolved sha256) + UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3@sha256:<DIGEST> UNITY_CACHE_ROOT: /home/runner/work/_temp/_github_home
🧹 Nitpick comments (3)
.github/workflows/claude-nl-suite.yml (3)
24-26
: Fix YAMLlint findings: extra spaces after colons and trailing spaces.Minor but keeps linters and actionlint quiet.
- MD_OUT: reports/junit-nl-suite.md + MD_OUT: reports/junit-nl-suite.md @@ - UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} - UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} - UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} - UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} @@ - UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} - UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} - UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} - UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} @@ - UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} @@ - UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} @@ - JSON - + JSON @@ - - name: Prepare reports + - name: Prepare reports @@ - - + + @@ - retention-days: 7 - + retention-days: 7 +Also applies to: 33-36, 79-82, 107-109, 207-207, 209-209, 462-463, 473-473
140-167
: Optionally assert FRAMING preamble before declaring bridge ready.Given the new strict
FRAMING=1
handshake, probe a short preamble slice to catch regressions early. Non‑intrusive and fast.- if [ -n "${PORT:-}" ] && { try_connect_host "$PORT" || docker exec unity-mcp bash -lc "timeout 1 bash -lc 'exec 3<>/dev/tcp/127.0.0.1/$PORT' || (command -v nc >/dev/null 2>&1 && nc -6 -z ::1 $PORT)"; }; then - READY=1; echo "Bridge ready on port $PORT"; break + if [ -n "${PORT:-}" ] && { try_connect_host "$PORT" || docker exec unity-mcp bash -lc "timeout 1 bash -lc 'exec 3<>/dev/tcp/127.0.0.1/$PORT' || (command -v nc >/dev/null 2>&1 && nc -6 -z ::1 $PORT)"; }; then + # Best-effort preamble assert (expect 'FRAMING=1' within first 16 bytes) + PRE=$(timeout 1 bash -lc "exec 3<>/dev/tcp/127.0.0.1/$PORT; dd bs=1 count=16 <&3 2>/dev/null || true" || true) + if printf '%s' "$PRE" | grep -q 'FRAMING=1'; then + READY=1; echo "Bridge ready on port $PORT (preamble OK)"; break + else + echo "Port $PORT open but preamble missing; will continue waiting…" + fi fi
75-88
: Make license priming non-fatal to avoid blocking the run.If license seeding flakes, the container step may still succeed with EBL/ULF. Let the job continue.
- - name: Prime Unity license on host (GameCI) + - name: Prime Unity license on host (GameCI) if: steps.detect.outputs.unity_ok == 'true' uses: game-ci/unity-test-runner@v4 + continue-on-error: true
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
.claude/prompts/nl-unity-suite-full.md
(1 hunks).github/workflows/claude-nl-suite.yml
(1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
.github/workflows/claude-nl-suite.yml
[warning] 26-26: too many spaces after colon
(colons)
[warning] 33-33: too many spaces after colon
(colons)
[warning] 34-34: too many spaces after colon
(colons)
[warning] 36-36: too many spaces after colon
(colons)
[warning] 79-79: too many spaces after colon
(colons)
[warning] 80-80: too many spaces after colon
(colons)
[warning] 82-82: too many spaces after colon
(colons)
[warning] 107-107: too many spaces after colon
(colons)
[warning] 109-109: too many spaces after colon
(colons)
[error] 207-207: trailing spaces
(trailing-spaces)
[error] 209-209: trailing spaces
(trailing-spaces)
[error] 450-450: trailing spaces
(trailing-spaces)
[error] 462-462: trailing spaces
(trailing-spaces)
[error] 463-463: trailing spaces
(trailing-spaces)
[error] 473-473: trailing spaces
(trailing-spaces)
🪛 LanguageTool
.claude/prompts/nl-unity-suite-full.md
[grammar] ~17-~17: There might be a mistake here.
Context: ...tools. ## Tool mapping (use these APIs) When the tests say replace_range or ...
(QB_NEW_EN)
[grammar] ~21-~21: There might be a mistake here.
Context: ...t for validation (
level: "standard"`). Edits within a batch are applied atomica...
(QB_NEW_EN)
[grammar] ~25-~25: There might be a mistake here.
Context: ...equirements (match NL suite conventions) - JUnit at $JUNIT_OUT
if set, otherwise ...
(QB_NEW_EN)
[grammar] ~29-~29: There might be a mistake here.
Context: ...wise perform a single re-read and retry. - Evidence windows only (±20–40 lines); ca...
(QB_NEW_EN)
[grammar] ~33-~33: There might be a mistake here.
Context: ... ### Reporting discipline (must-follow) - CI pre-creates the report skeletons. Do ...
(QB_NEW_EN)
[grammar] ~41-~41: There might be a mistake here.
Context: ...hesize the final markdown from JUnit. - Keep transient state in memory; if persisten...
(QB_NEW_EN)
[grammar] ~44-~44: There might be a mistake here.
Context: ...er validation so the workspace is clean. - At suite start, capture baseline `{ text...
(QB_NEW_EN)
[grammar] ~49-~49: There might be a mistake here.
Context: ...ning per workflow. ## CI headless hints - For mcp__unity__list_resources
/`read_r...
(QB_NEW_EN)
[grammar] ~50-~50: There might be a mistake here.
Context: ...ist_resources/
read_resource, specify: -
project_root:
"TestProjects/UnityMCPTests" -
ct...
(QB_NEW_EN)
[grammar] ~51-~51: There might be a mistake here.
Context: ...resource, specify: -
project_root:
"TestProjects/UnityMCPTests" -
ctx:
{}- Canonical URIs: -
unity://pa...
(QB_NEW_EN)
[grammar] ~52-~52: There might be a mistake here.
Context: ...TestProjects/UnityMCPTests" -
ctx:
{}- Canonical URIs: -
unity://path/Assets...
(QB_NEW_EN)
[grammar] ~59-~59: There might be a mistake here.
Context: ...order (must follow; do not regex-filter) Run tests exactly in this order: NL-0, N...
(QB_NEW_EN)
[grammar] ~60-~60: There might be a mistake here.
Context: ...filter) Run tests exactly in this order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, ...
(QB_NEW_EN)
[grammar] ~61-~61: There might be a mistake here.
Context: ...his order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, T-C, T-D, T-E, T-F, T-G, T-H, ...
(QB_NEW_EN)
[grammar] ~62-~62: There might be a mistake here.
Context: ... T-C, T-D, T-E, T-F, T-G, T-H, T-I, T-J. At suite start, emit a single line plan:...
(QB_NEW_EN)
[grammar] ~63-~63: There might be a mistake here.
Context: ...At suite start, emit a single line plan: PLAN: NL-0,NL-1,NL-2,NL-3,NL-4,T-A,T-B,T...
(QB_NEW_EN)
[grammar] ~64-~64: There might be a mistake here.
Context: ...,T-G,T-H,T-I,T-J (len=16 inc. bootstrap) After each testcase, emit: PROGRESS: ...
(QB_NEW_EN)
[grammar] ~65-~65: There might be a mistake here.
Context: ...c. bootstrap) After each testcase, emit: PROGRESS: /16 completed ### NL-0. Sa...
(QB_NEW_EN)
[grammar] ~68-~68: There might be a mistake here.
Context: ...leted ### NL-0. Sanity Reads (windowed) - Tail 120 lines; read 40 lines around `Up...
(QB_NEW_EN)
[grammar] ~73-~73: There might be a mistake here.
Context: ...er GetCurrentTarget
logging "1,2,3"
. - Verify windows, then delete `PrintSeries...
(QB_NEW_EN)
[grammar] ~74-~74: There might be a mistake here.
Context: ...y windows, then delete PrintSeries()
; confirm original hash. ### NL-2. Anchor commen...
(QB_NEW_EN)
[grammar] ~76-~76: There might be a mistake here.
Context: ...ash. ### NL-2. Anchor comment insertion - Insert // Build marker OK
immediately ...
(QB_NEW_EN)
[grammar] ~79-~79: There might be a mistake here.
Context: ...docs). ### NL-3. End-of-class insertion - Insert three lines // Tail test A/B/C
...
(QB_NEW_EN)
[grammar] ~80-~80: There might be a mistake here.
Context: ...Insert three lines // Tail test A/B/C
before final class brace; preserve indentation...
(QB_NEW_EN)
[grammar] ~82-~82: There might be a mistake here.
Context: ... ### NL-4. Compile trigger (record-only) - Ensure no obvious syntax issues; record ...
(QB_NEW_EN)
[grammar] ~85-~85: There might be a mistake here.
Context: ...NFO. ### T-A. Anchor insert (text path) - After GetCurrentTarget
, insert `privat...
(QB_NEW_EN)
[grammar] ~86-~86: There might be a mistake here.
Context: ..., int b) => a + b;via
replace_range` at insertion point; verify; then delete vi...
(QB_NEW_EN)
[grammar] ~91-~91: There might be a mistake here.
Context: ...rt. ### T-C. Header/region preservation - For ApplyBlend
, modify interior lines ...
(QB_NEW_EN)
[grammar] ~94-~94: There might be a mistake here.
Context: ...### T-D. End-of-class insertion (anchor) - Find final class brace; insert helper be...
(QB_NEW_EN)
[grammar] ~104-~104: There might be a mistake here.
Context: ...alization - Run the same edit with both URIs; second attempt should return `{ status:...
(QB_NEW_EN)
[grammar] ~106-~106: There might be a mistake here.
Context: ..._change" }. ### T-H. Validation levels - Use
validate_scriptwith
level: "stan...
(QB_NEW_EN)
[grammar] ~109-~109: There might be a mistake here.
Context: ...s. ### T-I. Failure surfaces (expected) - Too large payload → `{status:"too_large"...
(QB_NEW_EN)
[grammar] ~110-~110: There might be a mistake here.
Context: ...rfaces (expected) - Too large payload → {status:"too_large"}
- Stale file (old hash) → `{status:"stale_...
(QB_NEW_EN)
[grammar] ~111-~111: There might be a mistake here.
Context: ..."too_large"}- Stale file (old hash) →
{status:"stale_file"}` - Overlap → rejection - Unbalanced braces ...
(QB_NEW_EN)
[grammar] ~112-~112: There might be a mistake here.
Context: ...tus:"stale_file"}` - Overlap → rejection - Unbalanced braces → validation failure -...
(QB_NEW_EN)
[grammar] ~113-~113: There might be a mistake here.
Context: ...- Unbalanced braces → validation failure - Using-directives guard → `{status:"using...
(QB_NEW_EN)
[grammar] ~114-~114: There might be a mistake here.
Context: ...tion failure - Using-directives guard → {status:"using_guard"}
- Parameter aliasing accepted; server echo...
(QB_NEW_EN)
[grammar] ~115-~115: There might be a mistake here.
Context: ... accepted; server echoes canonical keys. - Auto-upgrade: prefer structured edits or...
(QB_NEW_EN)
[grammar] ~123-~123: There might be a mistake here.
Context: ...indows; include pre/post hashes in logs. - Maintain a per-test in-memory working bu...
(QB_NEW_EN)
[grammar] ~126-~126: There might be a mistake here.
Context: ...; otherwise record failure and continue. - Re-read only at well-defined points: (a)...
(QB_NEW_EN)
[grammar] ~128-~128: There might be a mistake here.
Context: ...t the end of each test, then re-read to confirm clean state before the next test. - Nev...
(QB_NEW_EN)
[grammar] ~128-~128: There might be a mistake here.
Context: ...onfirm clean state before the next test. - Never abort the suite on a single test f...
(QB_NEW_EN)
[grammar] ~136-~136: There might be a mistake here.
Context: ... bytes)>` ### Test driver (must follow) For each test NL-0..NL-4, then T-A..T-J:...
(QB_NEW_EN)
[grammar] ~142-~142: There might be a mistake here.
Context: ...; re-read and confirm the hash matches. 6) Append
VERDICT: PASSor
VERDICT: FAIL...
(QB_NEW_EN)
[grammar] ~144-~144: There might be a mistake here.
Context: ...7) Continue to the next test regardless of outcome. ### Guarded write pattern (mu...
(QB_NEW_EN)
[grammar] ~180-~180: There might be a mistake here.
Context: ...not available, compute the minimal edit against current buf
to restore exact content,...
(QB_NEW_EN)
[grammar] ~180-~180: There might be a mistake here.
Context: ...e minimal edit against current buf
to restore exact content, then confirm hash matche...
(QB_NEW_EN)
[grammar] ~180-~180: There might be a mistake here.
Context: ...nt buf
to restore exact content, then confirm hash matches the baseline. ### Status ...
(QB_NEW_EN)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: nl-suite
- GitHub Check: Cursor Bugbot
🔇 Additional comments (3)
.claude/prompts/nl-unity-suite-full.md (3)
17-23
: Tool mapping and atomicity note look good.Accurately distinguishes text vs. structured edits and clarifies atomic multi-edit batches. No change needed.
33-41
: Confirm fragment filename pattern matches CI assembler.Assembler globs
reports/*_results.xml
; your recommendedreports/nl_final_results.xml
is compatible. Keep this exact suffix to ensure pickup.If you ever rename, ensure it still matches
*_results.xml
.
124-129
: Hashing semantics are precise and aligned with server behavior.Raw‑byte SHA‑256, guarded retry with server‑provided hash, and limited re‑reads will minimize false stale conflicts and reduce I/O.
…<cases> root and only <testcase> children; no raw text outside CDATA
…extracts <testcase> via regex on bad fragments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (1)
.claude/prompts/nl-unity-suite-full.md (1)
123-126
: Good: precondition hashing over raw bytes is now explicit and consistent.
🧹 Nitpick comments (3)
.claude/prompts/nl-unity-suite-full.md (3)
156-165
: Tighten null-safe hash selection in stale retry pseudo-code.Use explicit null-safe semantics to avoid implying attribute errors in runner implementations.
- next_sha = (res.data.current_sha256 or res.data.expected_sha256) if hasattr(res, 'data') else None + next_sha = res.data?.current_sha256 ?? res.data?.expected_sha256 ?? None
108-111
: Clarify “too_large” threshold to match transport cap.Add the concrete limit to reduce ambiguity.
-- Too large payload → `{status:"too_large"}` +- Too large payload → `{status:"too_large"}` (e.g., payload >64 MiB per frame/request)
28-29
: Specify AllowedTools logging format.Make the required format explicit to avoid parsing ambiguity.
-- Log allowed tools once as a single line: `AllowedTools: ...`. +- Log allowed tools once as a single line: `AllowedTools: <tool_id1,tool_id2,...>`.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
.claude/prompts/nl-unity-suite-full.md
(1 hunks)
🧰 Additional context used
🪛 LanguageTool
.claude/prompts/nl-unity-suite-full.md
[grammar] ~17-~17: There might be a mistake here.
Context: ...tools. ## Tool mapping (use these APIs) When the tests say replace_range or ...
(QB_NEW_EN)
[grammar] ~21-~21: There might be a mistake here.
Context: ...t for validation (
level: "standard"`). Edits within a batch are applied atomica...
(QB_NEW_EN)
[grammar] ~25-~25: There might be a mistake here.
Context: ...equirements (match NL suite conventions) - JUnit at $JUNIT_OUT
if set, otherwise ...
(QB_NEW_EN)
[grammar] ~29-~29: There might be a mistake here.
Context: ...wise perform a single re-read and retry. - Evidence windows only (±20–40 lines); ca...
(QB_NEW_EN)
[grammar] ~33-~33: There might be a mistake here.
Context: ... ### Reporting discipline (must-follow) - CI pre-creates the report skeletons. Do ...
(QB_NEW_EN)
[grammar] ~40-~40: There might be a mistake here.
Context: ...hesize the final markdown from JUnit. - Keep transient state in memory; if persisten...
(QB_NEW_EN)
[grammar] ~43-~43: There might be a mistake here.
Context: ...er validation so the workspace is clean. - At suite start, capture baseline `{ text...
(QB_NEW_EN)
[grammar] ~48-~48: There might be a mistake here.
Context: ...ning per workflow. ## CI headless hints - For mcp__unity__list_resources
/`read_r...
(QB_NEW_EN)
[grammar] ~49-~49: There might be a mistake here.
Context: ...ist_resources/
read_resource, specify: -
project_root:
"TestProjects/UnityMCPTests" -
ct...
(QB_NEW_EN)
[grammar] ~50-~50: There might be a mistake here.
Context: ...resource, specify: -
project_root:
"TestProjects/UnityMCPTests" -
ctx:
{}- Canonical URIs: -
unity://pa...
(QB_NEW_EN)
[grammar] ~51-~51: There might be a mistake here.
Context: ...TestProjects/UnityMCPTests" -
ctx:
{}- Canonical URIs: -
unity://path/Assets...
(QB_NEW_EN)
[grammar] ~58-~58: There might be a mistake here.
Context: ...order (must follow; do not regex-filter) Run tests exactly in this order: NL-0, N...
(QB_NEW_EN)
[grammar] ~59-~59: There might be a mistake here.
Context: ...filter) Run tests exactly in this order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, ...
(QB_NEW_EN)
[grammar] ~60-~60: There might be a mistake here.
Context: ...his order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, T-C, T-D, T-E, T-F, T-G, T-H, ...
(QB_NEW_EN)
[grammar] ~61-~61: There might be a mistake here.
Context: ... T-C, T-D, T-E, T-F, T-G, T-H, T-I, T-J. At suite start, emit a single line plan:...
(QB_NEW_EN)
[grammar] ~62-~62: There might be a mistake here.
Context: ...At suite start, emit a single line plan: PLAN: NL-0,NL-1,NL-2,NL-3,NL-4,T-A,T-B,T...
(QB_NEW_EN)
[grammar] ~63-~63: There might be a mistake here.
Context: ...,T-G,T-H,T-I,T-J (len=16 inc. bootstrap) After each testcase, emit: PROGRESS: ...
(QB_NEW_EN)
[grammar] ~64-~64: There might be a mistake here.
Context: ...c. bootstrap) After each testcase, emit: PROGRESS: /16 completed ### NL-0. Sa...
(QB_NEW_EN)
[grammar] ~67-~67: There might be a mistake here.
Context: ...leted ### NL-0. Sanity Reads (windowed) - Tail 120 lines; read 40 lines around `Up...
(QB_NEW_EN)
[grammar] ~72-~72: There might be a mistake here.
Context: ...er GetCurrentTarget
logging "1,2,3"
. - Verify windows, then delete `PrintSeries...
(QB_NEW_EN)
[grammar] ~73-~73: There might be a mistake here.
Context: ...y windows, then delete PrintSeries()
; confirm original hash. ### NL-2. Anchor commen...
(QB_NEW_EN)
[grammar] ~75-~75: There might be a mistake here.
Context: ...ash. ### NL-2. Anchor comment insertion - Insert // Build marker OK
immediately ...
(QB_NEW_EN)
[grammar] ~78-~78: There might be a mistake here.
Context: ...docs). ### NL-3. End-of-class insertion - Insert three lines // Tail test A/B/C
...
(QB_NEW_EN)
[grammar] ~79-~79: There might be a mistake here.
Context: ...Insert three lines // Tail test A/B/C
before final class brace; preserve indentation...
(QB_NEW_EN)
[grammar] ~81-~81: There might be a mistake here.
Context: ... ### NL-4. Compile trigger (record-only) - Ensure no obvious syntax issues; record ...
(QB_NEW_EN)
[grammar] ~84-~84: There might be a mistake here.
Context: ...NFO. ### T-A. Anchor insert (text path) - After GetCurrentTarget
, insert `privat...
(QB_NEW_EN)
[grammar] ~85-~85: There might be a mistake here.
Context: ..., int b) => a + b;via
replace_range` at insertion point; verify; then delete vi...
(QB_NEW_EN)
[grammar] ~90-~90: There might be a mistake here.
Context: ...rt. ### T-C. Header/region preservation - For ApplyBlend
, modify interior lines ...
(QB_NEW_EN)
[grammar] ~93-~93: There might be a mistake here.
Context: ...### T-D. End-of-class insertion (anchor) - Find final class brace; insert helper be...
(QB_NEW_EN)
[grammar] ~103-~103: There might be a mistake here.
Context: ...alization - Run the same edit with both URIs; second attempt should return `{ status:...
(QB_NEW_EN)
[grammar] ~105-~105: There might be a mistake here.
Context: ..._change" }. ### T-H. Validation levels - Use
validate_scriptwith
level: "stan...
(QB_NEW_EN)
[grammar] ~108-~108: There might be a mistake here.
Context: ...s. ### T-I. Failure surfaces (expected) - Too large payload → `{status:"too_large"...
(QB_NEW_EN)
[grammar] ~109-~109: There might be a mistake here.
Context: ...rfaces (expected) - Too large payload → {status:"too_large"}
- Stale file (old hash) → `{status:"stale_...
(QB_NEW_EN)
[grammar] ~110-~110: There might be a mistake here.
Context: ..."too_large"}- Stale file (old hash) →
{status:"stale_file"}` - Overlap → rejection - Unbalanced braces ...
(QB_NEW_EN)
[grammar] ~111-~111: There might be a mistake here.
Context: ...tus:"stale_file"}` - Overlap → rejection - Unbalanced braces → validation failure -...
(QB_NEW_EN)
[grammar] ~112-~112: There might be a mistake here.
Context: ...- Unbalanced braces → validation failure - Using-directives guard → `{status:"using...
(QB_NEW_EN)
[grammar] ~113-~113: There might be a mistake here.
Context: ...tion failure - Using-directives guard → {status:"using_guard"}
- Parameter aliasing accepted; server echo...
(QB_NEW_EN)
[grammar] ~114-~114: There might be a mistake here.
Context: ... accepted; server echoes canonical keys. - Auto-upgrade: prefer structured edits or...
(QB_NEW_EN)
[grammar] ~122-~122: There might be a mistake here.
Context: ...indows; include pre/post hashes in logs. - Maintain a per-test in-memory working bu...
(QB_NEW_EN)
[grammar] ~125-~125: There might be a mistake here.
Context: ...; otherwise record failure and continue. - Re-read only at well-defined points: (a)...
(QB_NEW_EN)
[grammar] ~127-~127: There might be a mistake here.
Context: ...t the end of each test, then re-read to confirm clean state before the next test. - Nev...
(QB_NEW_EN)
[grammar] ~127-~127: There might be a mistake here.
Context: ...onfirm clean state before the next test. - Never abort the suite on a single test f...
(QB_NEW_EN)
[grammar] ~135-~135: There might be a mistake here.
Context: ... bytes)>` ### Test driver (must follow) For each test NL-0..NL-4, then T-A..T-J:...
(QB_NEW_EN)
[grammar] ~141-~141: There might be a mistake here.
Context: ...; re-read and confirm the hash matches. 6) Append
VERDICT: PASSor
VERDICT: FAIL...
(QB_NEW_EN)
[grammar] ~143-~143: There might be a mistake here.
Context: ...7) Continue to the next test regardless of outcome. ### Guarded write pattern (mu...
(QB_NEW_EN)
[grammar] ~179-~179: There might be a mistake here.
Context: ...not available, compute the minimal edit against current buf
to restore exact content,...
(QB_NEW_EN)
[grammar] ~179-~179: There might be a mistake here.
Context: ...e minimal edit against current buf
to restore exact content, then confirm hash matche...
(QB_NEW_EN)
[grammar] ~179-~179: There might be a mistake here.
Context: ...nt buf
to restore exact content, then confirm hash matches the baseline. ### Status ...
(QB_NEW_EN)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Cursor Bugbot
…pt: require re-read after every revert; correct PLAN/PROGRESS to 15
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (5)
.github/workflows/claude-nl-suite-mini.yml (2)
47-53
: Pin all third‑party Actions by immutable SHAs (supply‑chain hardening).- - uses: actions/checkout@v4 + - uses: actions/checkout@<commit-sha> - - uses: astral-sh/setup-uv@v4 + - uses: astral-sh/setup-uv@<commit-sha> - uses: game-ci/unity-test-runner@v4 + uses: game-ci/unity-test-runner@<commit-sha> - uses: anthropics/claude-code-base-action@beta + uses: anthropics/claude-code-base-action@<commit-sha> - uses: mikepenz/action-junit-report@v5 + uses: mikepenz/action-junit-report@<commit-sha> - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@<commit-sha>Also applies to: 74-88, 214-229, 333-350
14-18
: Pin Unity Docker image by digest to prevent tag drift.UNITY_VERSION: 2021.3.45f1 - UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3 + # Pinned to immutable digest (replace <DIGEST> with resolved sha256) + UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3@sha256:<DIGEST>Also applies to: 126-139
.github/workflows/claude-nl-suite.yml (3)
460-462
: Fix stale suite/classname: use NL‑T consistently.- ' <testcase classname="UnityMCP.NL" name="NL-Suite.Execution" time="0.0">' \ + ' <testcase classname="UnityMCP.NL-T" name="NL-Suite.Execution" time="0.0">' \
47-47
: Pin all third‑party Actions by immutable SHAs.- - uses: actions/checkout@v4 + - uses: actions/checkout@<commit-sha> - - uses: astral-sh/setup-uv@v4 + - uses: astral-sh/setup-uv@<commit-sha> - uses: game-ci/unity-test-runner@v4 + uses: game-ci/unity-test-runner@<commit-sha> - uses: anthropics/claude-code-base-action@beta + uses: anthropics/claude-code-base-action@<commit-sha> - uses: mikepenz/action-junit-report@v5 + uses: mikepenz/action-junit-report@<commit-sha> - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@<commit-sha>Also applies to: 52-52, 77-77, 251-261, 471-471, 483-483
14-18
: Pin Unity Docker image by digest to prevent tag drift.UNITY_VERSION: 2021.3.45f1 - UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3 + # Pin to immutable digest (replace <DIGEST>) + UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3@sha256:<DIGEST>Also applies to: 126-139
🧹 Nitpick comments (7)
.github/workflows/claude-nl-suite-mini.yml (3)
25-27
: YAMLlint: remove extra spaces after colons (env maps).Normalize to single space after colon to satisfy linters.
- MD_OUT: reports/junit-nl-suite.md + MD_OUT: reports/junit-nl-suite.md - UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} - UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} - UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} - UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} - UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} - UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} - UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}Also applies to: 33-38, 79-82, 107-110, 218-221
206-206
: Strip trailing spaces to fix YAMLlint errors.- + @@ - + @@ - +Also applies to: 331-331, 343-343
344-350
: Artifacts: add retention and keep block well‑formed.with: name: claude-nl-suite-artifacts path: reports/** + retention-days: 7
.claude/prompts/nl-unity-suite-full.md (1)
25-39
: Ensure CI normalizer ingests the “preferred” nl_final_results.xml format.Doc says to write a single
reports/nl_final_results.xml
with<cases>/<testcase>
elements. The full workflow’s normalizer currently imports*_results.xml
fragments only. Please either (a) keep this “preferred” output and update the workflow to mergenl_final_results.xml
, or (b) change the doc to prefer per‑test*_results.xml
. I’ve proposed the workflow change in its file..github/workflows/claude-nl-suite.yml (3)
25-26
: YAMLlint: remove extra spaces after colon (env).- MD_OUT: reports/junit-nl-suite.md + MD_OUT: reports/junit-nl-suite.md
149-149
: Broaden log redaction patterns (cover bearer/api/secret).-docker logs -f unity-mcp 2>&1 | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' & LOGPID=$! +docker logs -f unity-mcp 2>&1 | sed -E 's/((serial|license|password|token|api[_-]?key|bearer|secret)[^[:space:]]*)/[REDACTED]/ig' & LOGPID=$! -docker logs --tail 200 unity-mcp | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' || true +docker logs --tail 200 unity-mcp | sed -E 's/((serial|license|password|token|api[_-]?key|bearer|secret)[^[:space:]]*)/[REDACTED]/ig' || true -docker logs --tail 400 unity-mcp | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' || true +docker logs --tail 400 unity-mcp | sed -E 's/((serial|license|password|token|api[_-]?key|bearer|secret)[^[:space:]]*)/[REDACTED]/ig' || trueAlso applies to: 182-182, 496-496
207-207
: Strip trailing spaces flagged by YAMLlint.- JSON - + JSON + @@ - - name: Fallback JUnit if missing + - name: Fallback JUnit if missing @@ - fail_on_parse_error: true - + fail_on_parse_error: true @@ - retention-days: 7 - + retention-days: 7Also applies to: 209-209, 467-467, 479-480, 490-490
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
.claude/prompts/nl-unity-suite-full.md
(1 hunks).github/workflows/claude-nl-suite-mini.yml
(1 hunks).github/workflows/claude-nl-suite.yml
(1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
.github/workflows/claude-nl-suite-mini.yml
[warning] 26-26: too many spaces after colon
(colons)
[warning] 33-33: too many spaces after colon
(colons)
[warning] 34-34: too many spaces after colon
(colons)
[warning] 36-36: too many spaces after colon
(colons)
[warning] 79-79: too many spaces after colon
(colons)
[warning] 80-80: too many spaces after colon
(colons)
[warning] 82-82: too many spaces after colon
(colons)
[warning] 107-107: too many spaces after colon
(colons)
[warning] 109-109: too many spaces after colon
(colons)
[error] 206-206: trailing spaces
(trailing-spaces)
[warning] 219-219: too many spaces after colon
(colons)
[error] 331-331: trailing spaces
(trailing-spaces)
[error] 343-343: trailing spaces
(trailing-spaces)
.github/workflows/claude-nl-suite.yml
[warning] 26-26: too many spaces after colon
(colons)
[warning] 33-33: too many spaces after colon
(colons)
[warning] 34-34: too many spaces after colon
(colons)
[warning] 36-36: too many spaces after colon
(colons)
[warning] 79-79: too many spaces after colon
(colons)
[warning] 80-80: too many spaces after colon
(colons)
[warning] 82-82: too many spaces after colon
(colons)
[warning] 107-107: too many spaces after colon
(colons)
[warning] 109-109: too many spaces after colon
(colons)
[error] 207-207: trailing spaces
(trailing-spaces)
[error] 209-209: trailing spaces
(trailing-spaces)
[error] 467-467: trailing spaces
(trailing-spaces)
[error] 479-479: trailing spaces
(trailing-spaces)
[error] 480-480: trailing spaces
(trailing-spaces)
[error] 490-490: trailing spaces
(trailing-spaces)
🪛 LanguageTool
.claude/prompts/nl-unity-suite-full.md
[grammar] ~17-~17: There might be a mistake here.
Context: ...tools. ## Tool mapping (use these APIs) When the tests say replace_range or ...
(QB_NEW_EN)
[grammar] ~21-~21: There might be a mistake here.
Context: ...t for validation (
level: "standard"`). Edits within a batch are applied atomica...
(QB_NEW_EN)
[grammar] ~25-~25: There might be a mistake here.
Context: ...equirements (match NL suite conventions) - JUnit at $JUNIT_OUT
if set, otherwise ...
(QB_NEW_EN)
[grammar] ~29-~29: There might be a mistake here.
Context: ...wise perform a single re-read and retry. - Evidence windows only (±20–40 lines); ca...
(QB_NEW_EN)
[grammar] ~33-~33: There might be a mistake here.
Context: ... ### Reporting discipline (must-follow) - CI pre-creates the report skeletons. Do ...
(QB_NEW_EN)
[grammar] ~40-~40: There might be a mistake here.
Context: ...hesize the final markdown from JUnit. - Keep transient state in memory; if persisten...
(QB_NEW_EN)
[grammar] ~43-~43: There might be a mistake here.
Context: ...er validation so the workspace is clean. - At suite start, capture baseline `{ text...
(QB_NEW_EN)
[grammar] ~44-~44: There might be a mistake here.
Context: ...to confirm the revert before proceeding. - Never push commits from CI. - Do not mod...
(QB_NEW_EN)
[grammar] ~48-~48: There might be a mistake here.
Context: ...ning per workflow. ## CI headless hints - For mcp__unity__list_resources
/`read_r...
(QB_NEW_EN)
[grammar] ~49-~49: There might be a mistake here.
Context: ...ist_resources/
read_resource, specify: -
project_root:
"TestProjects/UnityMCPTests" -
ct...
(QB_NEW_EN)
[grammar] ~50-~50: There might be a mistake here.
Context: ...resource, specify: -
project_root:
"TestProjects/UnityMCPTests" -
ctx:
{}- Canonical URIs: -
unity://pa...
(QB_NEW_EN)
[grammar] ~51-~51: There might be a mistake here.
Context: ...TestProjects/UnityMCPTests" -
ctx:
{}- Canonical URIs: -
unity://path/Assets...
(QB_NEW_EN)
[grammar] ~58-~58: There might be a mistake here.
Context: ...order (must follow; do not regex-filter) Run tests exactly in this order: NL-0, N...
(QB_NEW_EN)
[grammar] ~59-~59: There might be a mistake here.
Context: ...filter) Run tests exactly in this order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, ...
(QB_NEW_EN)
[grammar] ~60-~60: There might be a mistake here.
Context: ...his order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, T-C, T-D, T-E, T-F, T-G, T-H, ...
(QB_NEW_EN)
[grammar] ~61-~61: There might be a mistake here.
Context: ... T-C, T-D, T-E, T-F, T-G, T-H, T-I, T-J. At suite start, emit a single line plan:...
(QB_NEW_EN)
[grammar] ~62-~62: There might be a mistake here.
Context: ...At suite start, emit a single line plan: PLAN: NL-0,NL-1,NL-2,NL-3,NL-4,T-A,T-B,T...
(QB_NEW_EN)
[grammar] ~63-~63: There might be a mistake here.
Context: ...T-C,T-D,T-E,T-F,T-G,T-H,T-I,T-J (len=15) After each testcase, emit: PROGRESS: ...
(QB_NEW_EN)
[grammar] ~64-~64: There might be a mistake here.
Context: ...,T-J (len=15) After each testcase, emit: PROGRESS: /15 completed ### NL-0. Sa...
(QB_NEW_EN)
[grammar] ~67-~67: There might be a mistake here.
Context: ...leted ### NL-0. Sanity Reads (windowed) - Tail 120 lines; read 40 lines around `Up...
(QB_NEW_EN)
[grammar] ~72-~72: There might be a mistake here.
Context: ...er GetCurrentTarget
logging "1,2,3"
. - Verify windows, then delete `PrintSeries...
(QB_NEW_EN)
[grammar] ~73-~73: There might be a mistake here.
Context: ...y windows, then delete PrintSeries()
; confirm original hash. ### NL-2. Anchor commen...
(QB_NEW_EN)
[grammar] ~75-~75: There might be a mistake here.
Context: ...ash. ### NL-2. Anchor comment insertion - Insert // Build marker OK
immediately ...
(QB_NEW_EN)
[grammar] ~78-~78: There might be a mistake here.
Context: ...docs). ### NL-3. End-of-class insertion - Insert three lines // Tail test A/B/C
...
(QB_NEW_EN)
[grammar] ~79-~79: There might be a mistake here.
Context: ...Insert three lines // Tail test A/B/C
before final class brace; preserve indentation...
(QB_NEW_EN)
[grammar] ~81-~81: There might be a mistake here.
Context: ... ### NL-4. Compile trigger (record-only) - Ensure no obvious syntax issues; record ...
(QB_NEW_EN)
[grammar] ~84-~84: There might be a mistake here.
Context: ...NFO. ### T-A. Anchor insert (text path) - After GetCurrentTarget
, insert `privat...
(QB_NEW_EN)
[grammar] ~85-~85: There might be a mistake here.
Context: ..., int b) => a + b;via
replace_range` at insertion point; verify; then delete vi...
(QB_NEW_EN)
[grammar] ~90-~90: There might be a mistake here.
Context: ...rt. ### T-C. Header/region preservation - For ApplyBlend
, modify interior lines ...
(QB_NEW_EN)
[grammar] ~93-~93: There might be a mistake here.
Context: ...### T-D. End-of-class insertion (anchor) - Find final class brace; insert helper be...
(QB_NEW_EN)
[grammar] ~94-~94: There might be a mistake here.
Context: ...tion (anchor) - Find final class brace; insert helper before; then remove. ### T-E. T...
(QB_NEW_EN)
[grammar] ~103-~103: There might be a mistake here.
Context: ...alization - Run the same edit with both URIs; second attempt should return `{ status:...
(QB_NEW_EN)
[grammar] ~105-~105: There might be a mistake here.
Context: ..._change" }. ### T-H. Validation levels - Use
validate_scriptwith
level: "stan...
(QB_NEW_EN)
[grammar] ~108-~108: There might be a mistake here.
Context: ...s. ### T-I. Failure surfaces (expected) - Too large payload → `{status:"too_large"...
(QB_NEW_EN)
[grammar] ~109-~109: There might be a mistake here.
Context: ...rfaces (expected) - Too large payload → {status:"too_large"}
- Stale file (old hash) → `{status:"stale_...
(QB_NEW_EN)
[grammar] ~110-~110: There might be a mistake here.
Context: ..."too_large"}- Stale file (old hash) →
{status:"stale_file"}` - Overlap → rejection - Unbalanced braces ...
(QB_NEW_EN)
[grammar] ~111-~111: There might be a mistake here.
Context: ...tus:"stale_file"}` - Overlap → rejection - Unbalanced braces → validation failure -...
(QB_NEW_EN)
[grammar] ~112-~112: There might be a mistake here.
Context: ...- Unbalanced braces → validation failure - Using-directives guard → `{status:"using...
(QB_NEW_EN)
[grammar] ~113-~113: There might be a mistake here.
Context: ...tion failure - Using-directives guard → {status:"using_guard"}
- Parameter aliasing accepted; server echo...
(QB_NEW_EN)
[grammar] ~114-~114: There might be a mistake here.
Context: ... accepted; server echoes canonical keys. - Auto-upgrade: prefer structured edits or...
(QB_NEW_EN)
[grammar] ~122-~122: There might be a mistake here.
Context: ...indows; include pre/post hashes in logs. - Maintain a per-test in-memory working bu...
(QB_NEW_EN)
[grammar] ~125-~125: There might be a mistake here.
Context: ...; otherwise record failure and continue. - Re-read only at well-defined points: (a)...
(QB_NEW_EN)
[grammar] ~127-~127: There might be a mistake here.
Context: ...t the end of each test, then re-read to confirm clean state before the next test. - Nev...
(QB_NEW_EN)
[grammar] ~127-~127: There might be a mistake here.
Context: ...onfirm clean state before the next test. - Never abort the suite on a single test f...
(QB_NEW_EN)
[grammar] ~135-~135: There might be a mistake here.
Context: ... bytes)>` ### Test driver (must follow) For each test NL-0..NL-4, then T-A..T-J:...
(QB_NEW_EN)
[grammar] ~140-~140: There might be a mistake here.
Context: ...windows; write JUnit + Markdown entries. 5) REVERT: if the test mutated the file, re...
(QB_NEW_EN)
[grammar] ~141-~141: There might be a mistake here.
Context: ...firm the hash matches before continuing. 6) Append VERDICT: PASS
or `VERDICT: FAIL...
(QB_NEW_EN)
[grammar] ~143-~143: There might be a mistake here.
Context: ...7) Continue to the next test regardless of outcome. ### Guarded write pattern (mu...
(QB_NEW_EN)
[grammar] ~179-~179: There might be a mistake here.
Context: ...not available, compute the minimal edit against current buf
to restore exact content,...
(QB_NEW_EN)
[grammar] ~179-~179: There might be a mistake here.
Context: ...e minimal edit against current buf
to restore exact content, then confirm hash matche...
(QB_NEW_EN)
[grammar] ~179-~179: There might be a mistake here.
Context: ...nt buf
to restore exact content, then confirm hash matches the baseline. ### Status ...
(QB_NEW_EN)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Cursor Bugbot
🔇 Additional comments (1)
.claude/prompts/nl-unity-suite-full.md (1)
29-31
: Stale-file/guarded write flow is consistent and specific. LGTM.Also applies to: 121-129, 145-175
…id create_script and env/mkdir checks, enforce single baseline-byte revert flow and post-revert re-read; add corruption-handling guidance
…ha; prefer script_apply_edits for anchors; avoid header/using changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (4)
.github/workflows/claude-nl-suite.yml (4)
164-167
: Refactor fragile JSON one-liner for port detection.The double json.load and race-prone one-liner is brittle. Replace with a short Python snippet.
- PORT=$(python -c "import os,glob,json,sys,time; b=os.path.expanduser('~/.unity-mcp'); fs=sorted(glob.glob(os.path.join(b,'unity-mcp-status-*.json')), key=os.path.getmtime, reverse=True); print(next((json.load(open(f,'r',encoding='utf-8')).get('unity_port') for f in fs if time.time()-os.path.getmtime(f)<=300 and json.load(open(f,'r',encoding='utf-8')).get('unity_port')), '' ))" 2>/dev/null || true) + PORT=$(python - <<'PY' 2>/dev/null || true +import os, glob, json, time, sys +b = os.path.expanduser('~/.unity-mcp') +ports = [] +for f in sorted(glob.glob(os.path.join(b,'unity-mcp-status-*.json')), key=os.path.getmtime, reverse=True): + try: + if time.time() - os.path.getmtime(f) > 300: + continue + with open(f, 'r', encoding='utf-8') as fh: + data = json.load(fh) + p = data.get('unity_port') + if p: + ports.append(str(p)) + except Exception: + pass +print(ports[0] if ports else('')) +PY +)
47-47
: Pin Actions to immutable commit SHAs.Mutable tags are supply-chain risk. Pin each Action to a full commit SHA.
- - uses: actions/checkout@v4 + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.1.7 - - uses: astral-sh/setup-uv@v4 + - uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a - uses: game-ci/unity-test-runner@v4 + uses: game-ci/unity-test-runner@0ff419b913a3630032cbe0de48a0099b5a9f0ed9 - uses: anthropics/claude-code-base-action@beta + uses: anthropics/claude-code-base-action@e9863f822497ff36abdac4571937150d27397a34 - uses: mikepenz/action-junit-report@v5 + uses: mikepenz/action-junit-report@db71d41eb79864e25ab0337e395c352e84523afe - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02Also applies to: 52-52, 75-78, 251-251, 471-471, 483-483
14-17
: Pin Unity image by digest to avoid tag drift.Pin the Docker image to a sha256 digest.
env: UNITY_VERSION: 2021.3.45f1 - UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3 + # Pinned for reproducibility (replace <DIGEST> with resolved sha256) + UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3@sha256:<DIGEST> UNITY_CACHE_ROOT: /home/runner/work/_temp/_github_home
290-321
: Normalizer should import preferred nl_final_results.xml and roots.Doc’s “preferred single-file” isn’t currently ingested. Extend the normalizer.
- # Append any testcase fragments from reports/*_results.xml - fragments = sorted(Path('reports').glob('*_results.xml')) + # Append any testcase fragments from reports/*_results.xml + fragments = sorted(Path('reports').glob('*_results.xml')) + # Also support preferred single-file output + preferred = Path('reports/nl_final_results.xml') + if preferred.exists(): + try: + proot = ET.parse(preferred).getroot() + if localname(proot.tag) == 'cases': + for tc in proot.findall('./testcase'): + suite.append(tc) + except Exception as pe: + print(f"Parse error for preferred file {preferred}: {pe}")
🧹 Nitpick comments (4)
.claude/prompts/nl-unity-suite-full.md (2)
124-128
: Unify post-write re-read policy (conflicting guidance).“Implementation notes” says to avoid re-read when positions are stable, while “Guarded write pattern” says to immediately re-read after every successful write. Pick one policy and state it once.
-- CRITICAL: After every successful write, immediately re-read raw bytes from disk and set `pre_sha` to the on-disk hash before any further edits within the same test. +- CRITICAL: After a successful write, refresh `pre_sha` to the on-disk hash before any further edit that depends on absolute offsets. Otherwise, you may continue using the local buf and defer the re-read until validation or revert requires it.Also delete the “Optionally refresh pre_sha…” comment in the pseudo-code to avoid mixed signals.
Also applies to: 149-161
153-181
: Clarify response shape in pseudo-code.Avoid
hasattr(res, 'data')
in examples; specify a stable field for the server-provided hash to prevent ambiguous client implementations.- next_sha = (res.data.current_sha256 or res.data.expected_sha256) if hasattr(res, 'data') else None + next_sha = (res.current_sha256 or res.expected_sha256 or (res.data or {}).get('current_sha256') or (res.data or {}).get('expected_sha256')).github/workflows/claude-nl-suite.yml (2)
207-209
: Strip trailing spaces; fix minor YAML lint warnings.Remove trailing spaces at noted lines to satisfy linters.
- JSON - + JSON @@ - + @@ - - + @@ - retention-days: 7 - + retention-days: 7Also applies to: 467-467, 479-480, 490-490
178-183
: Redact potential secrets in status dump as well.Mask obvious secret-like tokens when printing status files.
- echo "== status contents =="; for f in "$HOME"/.unity-mcp/unity-mcp-status-*.json; do [ -f "$f" ] && { echo "--- $f"; sed -n '1,120p' "$f"; }; done + echo "== status contents =="; for f in "$HOME"/.unity-mcp/unity-mcp-status-*.json; do + [ -f "$f" ] || continue + echo "--- $f" + sed -n '1,120p' "$f" | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' + done
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
.claude/prompts/nl-unity-suite-full.md
(1 hunks).github/workflows/claude-nl-suite.yml
(1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
.github/workflows/claude-nl-suite.yml
[warning] 26-26: too many spaces after colon
(colons)
[warning] 33-33: too many spaces after colon
(colons)
[warning] 34-34: too many spaces after colon
(colons)
[warning] 36-36: too many spaces after colon
(colons)
[warning] 79-79: too many spaces after colon
(colons)
[warning] 80-80: too many spaces after colon
(colons)
[warning] 82-82: too many spaces after colon
(colons)
[warning] 107-107: too many spaces after colon
(colons)
[warning] 109-109: too many spaces after colon
(colons)
[error] 207-207: trailing spaces
(trailing-spaces)
[error] 209-209: trailing spaces
(trailing-spaces)
[error] 467-467: trailing spaces
(trailing-spaces)
[error] 479-479: trailing spaces
(trailing-spaces)
[error] 480-480: trailing spaces
(trailing-spaces)
[error] 490-490: trailing spaces
(trailing-spaces)
🪛 LanguageTool
.claude/prompts/nl-unity-suite-full.md
[grammar] ~17-~17: There might be a mistake here.
Context: ...tools. ## Tool mapping (use these APIs) When the tests say replace_range or ...
(QB_NEW_EN)
[grammar] ~21-~21: There might be a mistake here.
Context: ...t for validation (
level: "standard"). - Do not use
mcp__unity__create_script`; ...
(QB_NEW_EN)
[grammar] ~26-~26: There might be a mistake here.
Context: ...equirements (match NL suite conventions) - JUnit at $JUNIT_OUT
if set, otherwise ...
(QB_NEW_EN)
[grammar] ~30-~30: There might be a mistake here.
Context: ...wise perform a single re-read and retry. - Evidence windows only (±20–40 lines); ca...
(QB_NEW_EN)
[grammar] ~34-~34: There might be a mistake here.
Context: ... ### Reporting discipline (must-follow) - CI pre-creates the report skeletons. Do ...
(QB_NEW_EN)
[grammar] ~42-~42: There might be a mistake here.
Context: ...hesize the final markdown from JUnit. - Keep transient state in memory; if persisten...
(QB_NEW_EN)
[grammar] ~45-~45: There might be a mistake here.
Context: ...er validation so the workspace is clean. - At suite start, capture baseline `{ text...
(QB_NEW_EN)
[grammar] ~50-~50: There might be a mistake here.
Context: ...ning per workflow. ## CI headless hints - For mcp__unity__list_resources
/`read_r...
(QB_NEW_EN)
[grammar] ~51-~51: There might be a mistake here.
Context: ...ist_resources/
read_resource, specify: -
project_root:
"TestProjects/UnityMCPTests" -
ct...
(QB_NEW_EN)
[grammar] ~52-~52: There might be a mistake here.
Context: ...resource, specify: -
project_root:
"TestProjects/UnityMCPTests" -
ctx:
{}- Canonical URIs: -
unity://pa...
(QB_NEW_EN)
[grammar] ~53-~53: There might be a mistake here.
Context: ...TestProjects/UnityMCPTests" -
ctx:
{}- Canonical URIs: -
unity://path/Assets...
(QB_NEW_EN)
[grammar] ~60-~60: There might be a mistake here.
Context: ...order (must follow; do not regex-filter) Run tests exactly in this order: NL-0, N...
(QB_NEW_EN)
[grammar] ~61-~61: There might be a mistake here.
Context: ...filter) Run tests exactly in this order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, ...
(QB_NEW_EN)
[grammar] ~62-~62: There might be a mistake here.
Context: ...his order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, T-C, T-D, T-E, T-F, T-G, T-H, ...
(QB_NEW_EN)
[grammar] ~63-~63: There might be a mistake here.
Context: ... T-C, T-D, T-E, T-F, T-G, T-H, T-I, T-J. At suite start, emit a single line plan:...
(QB_NEW_EN)
[grammar] ~64-~64: There might be a mistake here.
Context: ...At suite start, emit a single line plan: PLAN: NL-0,NL-1,NL-2,NL-3,NL-4,T-A,T-B,T...
(QB_NEW_EN)
[grammar] ~65-~65: There might be a mistake here.
Context: ...T-C,T-D,T-E,T-F,T-G,T-H,T-I,T-J (len=15) After each testcase, emit: PROGRESS: ...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ...,T-J (len=15) After each testcase, emit: PROGRESS: /15 completed ### NL-0. Sa...
(QB_NEW_EN)
[grammar] ~69-~69: There might be a mistake here.
Context: ...leted ### NL-0. Sanity Reads (windowed) - Tail 120 lines; read 40 lines around `Up...
(QB_NEW_EN)
[grammar] ~74-~74: There might be a mistake here.
Context: ...er GetCurrentTarget
logging "1,2,3"
. - Verify windows, then delete `PrintSeries...
(QB_NEW_EN)
[grammar] ~75-~75: There might be a mistake here.
Context: ...y windows, then delete PrintSeries()
; confirm original hash. ### NL-2. Anchor commen...
(QB_NEW_EN)
[grammar] ~77-~77: There might be a mistake here.
Context: ...ash. ### NL-2. Anchor comment insertion - Insert // Build marker OK
immediately ...
(QB_NEW_EN)
[grammar] ~80-~80: There might be a mistake here.
Context: ...docs). ### NL-3. End-of-class insertion - Insert three lines // Tail test A/B/C
...
(QB_NEW_EN)
[grammar] ~81-~81: There might be a mistake here.
Context: ...Insert three lines // Tail test A/B/C
before final class brace; preserve indentation...
(QB_NEW_EN)
[grammar] ~83-~83: There might be a mistake here.
Context: ... ### NL-4. Compile trigger (record-only) - Ensure no obvious syntax issues; record ...
(QB_NEW_EN)
[grammar] ~86-~86: There might be a mistake here.
Context: ...NFO. ### T-A. Anchor insert (text path) - After GetCurrentTarget
, insert `privat...
(QB_NEW_EN)
[grammar] ~87-~87: There might be a mistake here.
Context: ..., int b) => a + b;via
replace_range` at insertion point; verify; then delete vi...
(QB_NEW_EN)
[grammar] ~92-~92: There might be a mistake here.
Context: ...rt. ### T-C. Header/region preservation - For ApplyBlend
, modify interior lines ...
(QB_NEW_EN)
[grammar] ~95-~95: There might be a mistake here.
Context: ...### T-D. End-of-class insertion (anchor) - Find final class brace; insert helper be...
(QB_NEW_EN)
[grammar] ~96-~96: There might be a mistake here.
Context: ...tion (anchor) - Find final class brace; insert helper before; then remove. ### T-E. T...
(QB_NEW_EN)
[grammar] ~105-~105: There might be a mistake here.
Context: ...alization - Run the same edit with both URIs; second attempt should return `{ status:...
(QB_NEW_EN)
[grammar] ~107-~107: There might be a mistake here.
Context: ..._change" }. ### T-H. Validation levels - Use
validate_scriptwith
level: "stan...
(QB_NEW_EN)
[grammar] ~110-~110: There might be a mistake here.
Context: ...s. ### T-I. Failure surfaces (expected) - Too large payload → `{status:"too_large"...
(QB_NEW_EN)
[grammar] ~111-~111: There might be a mistake here.
Context: ...rfaces (expected) - Too large payload → {status:"too_large"}
- Stale file (old hash) → `{status:"stale_...
(QB_NEW_EN)
[grammar] ~112-~112: There might be a mistake here.
Context: ..."too_large"}- Stale file (old hash) →
{status:"stale_file"}` - Overlap → rejection - Unbalanced braces ...
(QB_NEW_EN)
[grammar] ~113-~113: There might be a mistake here.
Context: ...tus:"stale_file"}` - Overlap → rejection - Unbalanced braces → validation failure -...
(QB_NEW_EN)
[grammar] ~114-~114: There might be a mistake here.
Context: ...- Unbalanced braces → validation failure - Using-directives guard → `{status:"using...
(QB_NEW_EN)
[grammar] ~115-~115: There might be a mistake here.
Context: ...tion failure - Using-directives guard → {status:"using_guard"}
- Parameter aliasing accepted; server echo...
(QB_NEW_EN)
[grammar] ~116-~116: There might be a mistake here.
Context: ... accepted; server echoes canonical keys. - Auto-upgrade: prefer structured edits or...
(QB_NEW_EN)
[grammar] ~124-~124: There might be a mistake here.
Context: ...indows; include pre/post hashes in logs. - Maintain a per-test in-memory working bu...
(QB_NEW_EN)
[grammar] ~127-~127: There might be a mistake here.
Context: ...; otherwise record failure and continue. - Re-read only at well-defined points: (a)...
(QB_NEW_EN)
[grammar] ~129-~129: There might be a mistake here.
Context: ...t the end of each test, then re-read to confirm clean state before the next test. - Nev...
(QB_NEW_EN)
[grammar] ~129-~129: There might be a mistake here.
Context: ...onfirm clean state before the next test. - Never abort the suite on a single test f...
(QB_NEW_EN)
[grammar] ~137-~137: There might be a mistake here.
Context: ... bytes)>` ### Test driver (must follow) For each test NL-0..NL-4, then T-A..T-J:...
(QB_NEW_EN)
[grammar] ~143-~143: There might be a mistake here.
Context: ...irm the baseline hash before continuing. 6) Append VERDICT: PASS
or `VERDICT: FAIL...
(QB_NEW_EN)
[grammar] ~145-~145: There might be a mistake here.
Context: ...7) Continue to the next test regardless of outcome. ### Guarded write pattern (mu...
(QB_NEW_EN)
[grammar] ~147-~147: There might be a mistake here.
Context: ... write pattern (must use for every edit) Hash refresh and anchors (priority rules...
(QB_NEW_EN)
[grammar] ~148-~148: There might be a mistake here.
Context: ...sh refresh and anchors (priority rules): - CRITICAL: After every successful write, ...
(QB_NEW_EN)
[grammar] ~149-~149: There might be a mistake here.
Context: ... any further edits within the same test. - Prefer mcp__unity__script_apply_edits
...
(QB_NEW_EN)
[grammar] ~188-~188: There might be a mistake here.
Context: ...not available, compute the minimal edit against current buf
to restore exact content,...
(QB_NEW_EN)
[grammar] ~188-~188: There might be a mistake here.
Context: ...e minimal edit against current buf
to restore exact content, then confirm hash matche...
(QB_NEW_EN)
[grammar] ~188-~188: There might be a mistake here.
Context: ...nt buf
to restore exact content, then confirm hash matches the baseline. ### Status ...
(QB_NEW_EN)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: nl-suite
- GitHub Check: Cursor Bugbot
…ends via Write or Bash(printf/echo); forbid wrappers and full-file round-trips
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (1)
.claude/prompts/nl-unity-suite-full.md (1)
29-29
: Specify exactly where to log AllowedTools.To avoid duplicate/stray logs, specify that the single “AllowedTools: …” line must be emitted inside the NL-0 testcase’s
<system-out>
only.-- Log allowed tools once as a single line: `AllowedTools: ...`. +- Log allowed tools once as a single line: `AllowedTools: ...` inside NL-0 `<system-out>` only (do not repeat in later testcases).Also applies to: 34-39, 66-66
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
.claude/prompts/nl-unity-suite-full.md
(1 hunks)
🧰 Additional context used
🪛 LanguageTool
.claude/prompts/nl-unity-suite-full.md
[grammar] ~17-~17: There might be a mistake here.
Context: ...tools. ## Tool mapping (use these APIs) When the tests say replace_range or ...
(QB_NEW_EN)
[grammar] ~21-~21: There might be a mistake here.
Context: ...t for validation (
level: "standard"). - Do not use
mcp__unity__create_script`; ...
(QB_NEW_EN)
[grammar] ~26-~26: There might be a mistake here.
Context: ...equirements (match NL suite conventions) - JUnit at $JUNIT_OUT
(canonical). Suite...
(QB_NEW_EN)
[grammar] ~28-~28: There might be a mistake here.
Context: ...t $MD_OUT
(canonical). CI synthesizes at end; you may append small fragments but...
(QB_NEW_EN)
[grammar] ~28-~28: There might be a mistake here.
Context: ...gments but do not round‑trip full files. - Log allowed tools once as a single line:...
(QB_NEW_EN)
[grammar] ~30-~30: There might be a mistake here.
Context: ...wise perform a single re-read and retry. - Evidence windows only (±20–40 lines); ca...
(QB_NEW_EN)
[grammar] ~34-~34: There might be a mistake here.
Context: ... ### Reporting discipline (must-follow) - CI pre-creates the report skeletons. Do ...
(QB_NEW_EN)
[grammar] ~37-~37: There might be a mistake here.
Context: ...o full‑file round‑trips and no wrappers. - All human‑readable lines (PLAN, AllowedT...
(QB_NEW_EN)
[grammar] ~38-~38: There might be a mistake here.
Context: ...]]>within a
`. - Keep transient state in memory. ## Safe...
(QB_NEW_EN)
[grammar] ~42-~42: There might be a mistake here.
Context: ...er validation so the workspace is clean. - At suite start, capture baseline `{ text...
(QB_NEW_EN)
[grammar] ~47-~47: There might be a mistake here.
Context: ...ning per workflow. ## CI headless hints - For mcp__unity__list_resources
/`read_r...
(QB_NEW_EN)
[grammar] ~48-~48: There might be a mistake here.
Context: ...ist_resources/
read_resource, specify: -
project_root:
"TestProjects/UnityMCPTests" -
ct...
(QB_NEW_EN)
[grammar] ~49-~49: There might be a mistake here.
Context: ...resource, specify: -
project_root:
"TestProjects/UnityMCPTests" -
ctx:
{}- Canonical URIs: -
unity://pa...
(QB_NEW_EN)
[grammar] ~50-~50: There might be a mistake here.
Context: ...TestProjects/UnityMCPTests" -
ctx:
{}- Canonical URIs: -
unity://path/Assets...
(QB_NEW_EN)
[grammar] ~57-~57: There might be a mistake here.
Context: ...order (must follow; do not regex-filter) Run tests exactly in this order: NL-0, N...
(QB_NEW_EN)
[grammar] ~58-~58: There might be a mistake here.
Context: ...filter) Run tests exactly in this order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, ...
(QB_NEW_EN)
[grammar] ~59-~59: There might be a mistake here.
Context: ...his order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, T-C, T-D, T-E, T-F, T-G, T-H, ...
(QB_NEW_EN)
[grammar] ~60-~60: There might be a mistake here.
Context: ... T-C, T-D, T-E, T-F, T-G, T-H, T-I, T-J. At suite start, emit a single line plan:...
(QB_NEW_EN)
[grammar] ~61-~61: There might be a mistake here.
Context: ...At suite start, emit a single line plan: PLAN: NL-0,NL-1,NL-2,NL-3,NL-4,T-A,T-B,T...
(QB_NEW_EN)
[grammar] ~62-~62: There might be a mistake here.
Context: ...T-C,T-D,T-E,T-F,T-G,T-H,T-I,T-J (len=15) After each testcase, emit: PROGRESS: ...
(QB_NEW_EN)
[grammar] ~63-~63: There might be a mistake here.
Context: ...,T-J (len=15) After each testcase, emit: PROGRESS: /15 completed ### NL-0. Sa...
(QB_NEW_EN)
[grammar] ~66-~66: There might be a mistake here.
Context: ...leted ### NL-0. Sanity Reads (windowed) - Tail 120 lines; read 40 lines around `Up...
(QB_NEW_EN)
[grammar] ~71-~71: There might be a mistake here.
Context: ...er GetCurrentTarget
logging "1,2,3"
. - Verify windows, then delete `PrintSeries...
(QB_NEW_EN)
[grammar] ~72-~72: There might be a mistake here.
Context: ...y windows, then delete PrintSeries()
; confirm original hash. ### NL-2. Anchor commen...
(QB_NEW_EN)
[grammar] ~74-~74: There might be a mistake here.
Context: ...ash. ### NL-2. Anchor comment insertion - Insert // Build marker OK
immediately ...
(QB_NEW_EN)
[grammar] ~77-~77: There might be a mistake here.
Context: ...docs). ### NL-3. End-of-class insertion - Insert three lines // Tail test A/B/C
...
(QB_NEW_EN)
[grammar] ~78-~78: There might be a mistake here.
Context: ...Insert three lines // Tail test A/B/C
before final class brace; preserve indentation...
(QB_NEW_EN)
[grammar] ~80-~80: There might be a mistake here.
Context: ... ### NL-4. Compile trigger (record-only) - Ensure no obvious syntax issues; record ...
(QB_NEW_EN)
[grammar] ~83-~83: There might be a mistake here.
Context: ...NFO. ### T-A. Anchor insert (text path) - After GetCurrentTarget
, insert `privat...
(QB_NEW_EN)
[grammar] ~84-~84: There might be a mistake here.
Context: ..., int b) => a + b;via
replace_range` at insertion point; verify; then delete vi...
(QB_NEW_EN)
[grammar] ~89-~89: There might be a mistake here.
Context: ...rt. ### T-C. Header/region preservation - For ApplyBlend
, modify interior lines ...
(QB_NEW_EN)
[grammar] ~92-~92: There might be a mistake here.
Context: ...### T-D. End-of-class insertion (anchor) - Find final class brace; insert helper be...
(QB_NEW_EN)
[grammar] ~102-~102: There might be a mistake here.
Context: ...alization - Run the same edit with both URIs; second attempt should return `{ status:...
(QB_NEW_EN)
[grammar] ~104-~104: There might be a mistake here.
Context: ..._change" }. ### T-H. Validation levels - Use
validate_scriptwith
level: "stan...
(QB_NEW_EN)
[grammar] ~107-~107: There might be a mistake here.
Context: ...s. ### T-I. Failure surfaces (expected) - Too large payload → `{status:"too_large"...
(QB_NEW_EN)
[grammar] ~108-~108: There might be a mistake here.
Context: ...rfaces (expected) - Too large payload → {status:"too_large"}
- Stale file (old hash) → `{status:"stale_...
(QB_NEW_EN)
[grammar] ~109-~109: There might be a mistake here.
Context: ..."too_large"}- Stale file (old hash) →
{status:"stale_file"}` - Overlap → rejection - Unbalanced braces ...
(QB_NEW_EN)
[grammar] ~110-~110: There might be a mistake here.
Context: ...tus:"stale_file"}` - Overlap → rejection - Unbalanced braces → validation failure -...
(QB_NEW_EN)
[grammar] ~111-~111: There might be a mistake here.
Context: ...- Unbalanced braces → validation failure - Using-directives guard → `{status:"using...
(QB_NEW_EN)
[grammar] ~112-~112: There might be a mistake here.
Context: ...tion failure - Using-directives guard → {status:"using_guard"}
- Parameter aliasing accepted; server echo...
(QB_NEW_EN)
[grammar] ~113-~113: There might be a mistake here.
Context: ... accepted; server echoes canonical keys. - Auto-upgrade: prefer structured edits or...
(QB_NEW_EN)
[grammar] ~121-~121: There might be a mistake here.
Context: ...indows; include pre/post hashes in logs. - Maintain a per-test in-memory working bu...
(QB_NEW_EN)
[grammar] ~124-~124: There might be a mistake here.
Context: ...; otherwise record failure and continue. - Re-read only at well-defined points: (a)...
(QB_NEW_EN)
[grammar] ~126-~126: There might be a mistake here.
Context: ...t the end of each test, then re-read to confirm clean state before the next test. - Nev...
(QB_NEW_EN)
[grammar] ~126-~126: There might be a mistake here.
Context: ...onfirm clean state before the next test. - Never abort the suite on a single test f...
(QB_NEW_EN)
[grammar] ~134-~134: There might be a mistake here.
Context: ... bytes)>` ### Test driver (must follow) For each test NL-0..NL-4, then T-A..T-J:...
(QB_NEW_EN)
[grammar] ~140-~140: There might be a mistake here.
Context: ...irm the baseline hash before continuing. 6) Append VERDICT: PASS
or `VERDICT: FAIL...
(QB_NEW_EN)
[grammar] ~142-~142: There might be a mistake here.
Context: ...7) Continue to the next test regardless of outcome. ### Guarded write pattern (mu...
(QB_NEW_EN)
[grammar] ~144-~144: There might be a mistake here.
Context: ... write pattern (must use for every edit) Hash refresh and anchors (priority rules...
(QB_NEW_EN)
[grammar] ~145-~145: There might be a mistake here.
Context: ...sh refresh and anchors (priority rules): - CRITICAL: After every successful write o...
(QB_NEW_EN)
[grammar] ~146-~146: There might be a mistake here.
Context: ... any further edits within the same test. - Prefer mcp__unity__script_apply_edits
...
(QB_NEW_EN)
[grammar] ~185-~185: There might be a mistake here.
Context: ...not available, compute the minimal edit against current buf
to restore exact content,...
(QB_NEW_EN)
[grammar] ~185-~185: There might be a mistake here.
Context: ...e minimal edit against current buf
to restore exact content, then confirm hash matche...
(QB_NEW_EN)
[grammar] ~185-~185: There might be a mistake here.
Context: ...nt buf
to restore exact content, then confirm hash matches the baseline. ### Status ...
(QB_NEW_EN)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Cursor Bugbot
🔇 Additional comments (1)
.claude/prompts/nl-unity-suite-full.md (1)
30-31
: Stale-file retry semantics are now consistent. LGTM.Output Requirements (Line 30) and Implementation notes (Lines 124–125) agree on a single guarded retry using server-provided hashes before any re-read. Good alignment.
Also applies to: 124-125
…cution order, specs, status
…end path; align allowed_tools
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (8)
.github/workflows/claude-nl-suite-mini.yml (3)
14-18
: Pin Unity Docker image by digest (prevent tag drift).Use an immutable sha256 to ensure reproducible CI.
env: UNITY_VERSION: 2021.3.45f1 - UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3 + # Pin to immutable digest + UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3@sha256:<DIGEST> UNITY_CACHE_ROOT: /home/runner/work/_temp/_github_home
47-55
: Pin all third‑party Actions by commit SHA (supply‑chain hardening).Replace mutable tags (@v4/@beta/@v5) with exact SHAs.
- - uses: actions/checkout@v4 + - uses: actions/checkout@<commit-sha> - - uses: astral-sh/setup-uv@v4 + - uses: astral-sh/setup-uv@<commit-sha> - uses: game-ci/unity-test-runner@v4 + uses: game-ci/unity-test-runner@<commit-sha> - uses: anthropics/claude-code-base-action@beta + uses: anthropics/claude-code-base-action@<commit-sha> - uses: mikepenz/action-junit-report@v5 + uses: mikepenz/action-junit-report@<commit-sha> - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@<commit-sha>Also applies to: 74-88, 213-229, 333-351
221-224
: Fix prompt_file path (likely mismatch → file-not-found).Align to the actual prompt file name used elsewhere in the repo/PR.
- prompt_file: .claude/prompts/nl-unity-claude-tests-mini.md + prompt_file: .claude/prompts/nl-unity-tests-mini.md.claude/prompts/nl-unity-suite-full.md (2)
73-76
: Revert policy: explicitly require re-read to confirm baseline.Make the revert confirmation unambiguous.
-- Restore exact pre-test bytes via a single full-file replace with `precondition_sha256` = current on-disk sha (or server-provided hash on stale), then re-read to confirm baseline hash. +- Restore exact pre-test bytes via a single full-file replace with `precondition_sha256` = current on-disk sha (or server-provided hash on stale), then re-read and verify sha256 matches the captured baseline before proceeding.
61-72
: Guarded write: avoid mandatory post-write disk re-read.Re-reading after every write harms perf and contradicts “minimal reads” guidance. Refresh from disk only when required (validation/anchors/before exit).
-- After every successful write: - - Immediately re-read raw bytes and set `pre_sha = sha256(read_bytes(uri))` before any further edits in the same test. +- After a successful write: + - Update in-memory buffer. Refresh `pre_sha` from on-disk bytes only when the next step requires exact sync (validation, anchor recompute) or before leaving the test..github/workflows/claude-nl-suite.yml (3)
246-299
: Normalizer: also import preferred single-filenl_final_results.xml
and<cases>
roots.Ensure we consume the documented “preferred” output path.
- # Append any testcase fragments from reports/*_results.xml - fragments = sorted(Path('reports').glob('*_results.xml')) + # Append testcase fragments from shards and preferred single-file + fragments = sorted(Path('reports').glob('*_results.xml')) + preferred = Path('reports/nl_final_results.xml') + if preferred.exists(): + fragments.append(preferred) @@ - if localname(froot.tag) == 'testcase': + tag = localname(froot.tag) + if tag == 'testcase': suite.append(froot); added += 1 - else: + elif tag == 'cases': + for tc in froot.findall('./testcase'): + suite.append(tc); added += 1 + else: for tc in froot.findall('.//testcase'): suite.append(tc); added += 1
14-18
: Pin Unity Docker image by digest (prevent tag drift).Use an immutable sha256 to stabilize runs.
env: UNITY_VERSION: 2021.3.45f1 - UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3 + # Pin to immutable digest + UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3@sha256:<DIGEST> UNITY_CACHE_ROOT: /home/runner/work/_temp/_github_home
47-55
: Pin all third‑party Actions by commit SHA.Replace mutable tags to reduce supply‑chain risk.
- - uses: actions/checkout@v4 + - uses: actions/checkout@<commit-sha> - - uses: astral-sh/setup-uv@v4 + - uses: astral-sh/setup-uv@<commit-sha> - uses: game-ci/unity-test-runner@v4 + uses: game-ci/unity-test-runner@<commit-sha> - uses: anthropics/claude-code-base-action@beta + uses: anthropics/claude-code-base-action@<commit-sha> - uses: mikepenz/action-junit-report@v5 + uses: mikepenz/action-junit-report@<commit-sha> - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@<commit-sha>Also applies to: 74-88, 222-245, 417-427, 428-439
🧹 Nitpick comments (4)
.github/workflows/claude-nl-suite-mini.yml (2)
206-206
: YAML lint: remove trailing spaces and extra alignment after colons.Clean up trailing spaces and over-aligned values to satisfy YAML/actionlint.
- JSON - + JSON @@ - MD_OUT: reports/junit-nl-suite.md + MD_OUT: reports/junit-nl-suite.md @@ - + @@ - +Also applies to: 219-219, 331-331, 343-343
344-350
: Artifacts: add retention-days.Keep artifacts for a bounded time and fix indent.
- name: Upload artifacts if: always() uses: actions/upload-artifact@v4 with: - name: claude-nl-suite-artifacts - path: reports/** + name: claude-nl-suite-artifacts + path: reports/** + retention-days: 7.claude/prompts/nl-unity-suite-full.md (1)
31-37
: Standardize read_console tool ID tomcp__unity__read_console
- In
.claude/prompts/nl-unity-suite-full.md
(lines 31–40), replace the straymcp__read__console
entry withmcp__unity__read_console
.- Ensure
mcp__unity__read_console
is also included in theallowed_tools
list of.github/workflows/claude-nl-suite-full.yml
..github/workflows/claude-nl-suite.yml (1)
331-346
: YAML lint: trailing spaces and over-aligned colons.Tighten formatting to silence YAMLlint.
- lines += ['# Unity NL/T Editing Suite Test Results','',f'Totals: {passed} passed, {failures} failed, {total} total','', '## Test Checklist'] + lines += ['# Unity NL/T Editing Suite Test Results','',f'Totals: {passed} passed, {failures} failed, {total} total','', '## Test Checklist'] @@ - if [ ! -f "$JUNIT_OUT" ]; then + if [ ! -f "$JUNIT_OUT" ]; then printf '%s\n' \ '<?xml version="1.0" encoding="UTF-8"?>' \ '<testsuite name="UnityMCP.NL-T" tests="1" failures="1" time="0">' \ ' <testcase classname="UnityMCP.NL-T" name="NL-Suite.Execution" time="0.0">' \ ' <failure><![CDATA[No JUnit was produced by the NL suite step. See the step logs.]]></failure>' \ ' </testcase>' \ '</testsuite>' \ > "$JUNIT_OUT" fi @@ - docker logs --tail 400 unity-mcp | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' || true + docker logs --tail 400 unity-mcp | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' || true docker rm -f unity-mcp || trueAlso applies to: 401-416, 439-446
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
.claude/prompts/nl-unity-suite-full.md
(1 hunks).github/workflows/claude-nl-suite-mini.yml
(1 hunks).github/workflows/claude-nl-suite.yml
(1 hunks)
🧰 Additional context used
🪛 LanguageTool
.claude/prompts/nl-unity-suite-full.md
[grammar] ~5-~5: There might be a mistake here.
Context: ...this once, verbatim, early in the run:** AllowedTools: Write,Bash(printf:*),Bash(...
(QB_NEW_EN)
[grammar] ~16-~16: There might be a mistake here.
Context: ...5) Revert file changes after each test; keep workspace clean. --- ## Environment &...
(QB_NEW_EN)
[grammar] ~20-~20: There might be a mistake here.
Context: ...clean. --- ## Environment & Paths (CI) - Always pass: `project_root: "TestProject...
(QB_NEW_EN)
[grammar] ~21-~21: There might be a mistake here.
Context: ...nd ctx: {}
on list/read/edit/validate. - Canonical URIs only: - Primary: `uni...
(QB_NEW_EN)
[grammar] ~22-~22: There might be a mistake here.
Context: ...dit/validate. - Canonical URIs only: - Primary: unity://path/Assets/...
(neve...
(QB_NEW_EN)
[grammar] ~23-~23: There might be a mistake here.
Context: ...never embed project_root
into the URI) - Relative (when supported): Assets/...
...
(QB_NEW_EN)
[grammar] ~24-~24: There might be a mistake here.
Context: ...the URI) - Relative (when supported): Assets/...
- CI prepares: - `$JUNIT_OUT=reports/jun...
(QB_NEW_EN)
[grammar] ~31-~31: There might be a mistake here.
Context: ...esizes from JUnit) --- ## Tool Mapping - Anchors/regex/structured: `mcp__unity_...
(QB_NEW_EN)
[grammar] ~32-~32: There might be a mistake here.
Context: ...Mapping - Anchors/regex/structured: mcp__unity__script_apply_edits
- **Precise ranges / atomic multi‑edit batch...
(QB_NEW_EN)
[grammar] ~33-~33: There might be a mistake here.
Context: ...ply_text_edits(non‑overlapping ranges) - **Validation**:
mcp__unity__validate_scri...
(QB_NEW_EN)
[grammar] ~34-~34: There might be a mistake here.
Context: ...n‑overlapping ranges) - Validation: mcp__unity__validate_script(level:"standard")
- Reporting: Write
small XML fragments...
(QB_NEW_EN)
[grammar] ~35-~35: There might be a mistake here.
Context: ...ML fragments to reports/*_results.xml
. Bash is allowed but not required; do not...
(QB_NEW_EN)
[grammar] ~38-~38: There might be a mistake here.
Context: ...nsole”, or any tool not in AllowedTools. > Never edit using
directives or the hea...
(QB_NEW_EN)
[grammar] ~45-~45: There might be a mistake here.
Context: ... ]]>of that testcase’s
`. - Evidence windows only (±20–40 lines). If...
(QB_NEW_EN)
🪛 YAMLlint (1.37.1)
.github/workflows/claude-nl-suite.yml
[warning] 20-20: wrong indentation: expected 2 but found 4
(indentation)
[warning] 26-26: too many spaces after colon
(colons)
[error] 27-27: trailing spaces
(trailing-spaces)
[warning] 33-33: too many spaces after colon
(colons)
[warning] 34-34: too many spaces after colon
(colons)
[warning] 36-36: too many spaces after colon
(colons)
[error] 46-46: trailing spaces
(trailing-spaces)
[error] 50-50: trailing spaces
(trailing-spaces)
[error] 55-55: trailing spaces
(trailing-spaces)
[error] 73-73: trailing spaces
(trailing-spaces)
[warning] 79-79: too many spaces after colon
(colons)
[warning] 80-80: too many spaces after colon
(colons)
[warning] 82-82: too many spaces after colon
(colons)
[error] 88-88: trailing spaces
(trailing-spaces)
[error] 95-95: trailing spaces
(trailing-spaces)
[error] 102-102: trailing spaces
(trailing-spaces)
[warning] 107-107: too many spaces after colon
(colons)
[warning] 109-109: too many spaces after colon
(colons)
[error] 139-139: trailing spaces
(trailing-spaces)
[error] 179-179: trailing spaces
(trailing-spaces)
[error] 201-201: trailing spaces
(trailing-spaces)
[error] 208-208: trailing spaces
(trailing-spaces)
[error] 221-221: trailing spaces
(trailing-spaces)
[error] 245-245: trailing spaces
(trailing-spaces)
[error] 255-255: trailing spaces
(trailing-spaces)
[error] 258-258: trailing spaces
(trailing-spaces)
[error] 264-264: trailing spaces
(trailing-spaces)
[error] 273-273: trailing spaces
(trailing-spaces)
[error] 299-299: trailing spaces
(trailing-spaces)
[error] 346-346: trailing spaces
(trailing-spaces)
[error] 358-358: trailing spaces
(trailing-spaces)
[error] 370-370: trailing spaces
(trailing-spaces)
[error] 383-383: trailing spaces
(trailing-spaces)
[error] 400-400: trailing spaces
(trailing-spaces)
[error] 416-416: trailing spaces
(trailing-spaces)
[error] 427-427: trailing spaces
(trailing-spaces)
[error] 439-439: trailing spaces
(trailing-spaces)
[error] 446-446: no new line character at the end of file
(new-line-at-end-of-file)
[error] 446-446: trailing spaces
(trailing-spaces)
.github/workflows/claude-nl-suite-mini.yml
[warning] 26-26: too many spaces after colon
(colons)
[warning] 33-33: too many spaces after colon
(colons)
[warning] 34-34: too many spaces after colon
(colons)
[warning] 36-36: too many spaces after colon
(colons)
[warning] 79-79: too many spaces after colon
(colons)
[warning] 80-80: too many spaces after colon
(colons)
[warning] 82-82: too many spaces after colon
(colons)
[warning] 107-107: too many spaces after colon
(colons)
[warning] 109-109: too many spaces after colon
(colons)
[error] 206-206: trailing spaces
(trailing-spaces)
[warning] 219-219: too many spaces after colon
(colons)
[error] 331-331: trailing spaces
(trailing-spaces)
[error] 343-343: trailing spaces
(trailing-spaces)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: nl-suite
- GitHub Check: Cursor Bugbot
🔇 Additional comments (3)
.github/workflows/claude-nl-suite.yml (3)
212-221
: Heredoc indentation: keep the entire payload indented consistently.This block looks correct now; leaving a note to retain exact indent to avoid YAML parse errors.
221-245
: Workflow step gating and parameters look correct.Gated on both Anthropic and Unity; good use of continue-on-error for resilience.
428-439
: Artifacts block: good coverage and retention; keep.Includes JUnit, MD, fragments, transcript with retention-days.
…s, Status as proper markdown lists and code fences
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (3)
.claude/prompts/nl-unity-suite-full.md (3)
14-14
: Clarify validation exception for read-only steps.Avoid forcing validation when no mutation occurred.
-3) Validate each edit with `mcp__unity__validate_script(level:"standard")`. +3) Validate each edit with `mcp__unity__validate_script(level:"standard")` (skip for read‑only steps).
52-52
: Use a proper heading for the example block (MD036).-**Example fragment** +### Example fragment
68-76
: Ensure snapshot directory exists before writing baseline.Prevents failures on first run in clean workspaces.
- Snapshot (once after confirming the target): ```bash + mkdir -p reports/_snapshots scripts/nlt-revert.sh snapshot "TestProjects/UnityMCPTests/Assets/Scripts/LongUnityScriptClaudeTest.cs" "reports/_snapshots/LongUnityScriptClaudeTest.cs.baseline"
</blockquote></details> </blockquote></details> <details> <summary>📜 Review details</summary> **Configuration used**: CodeRabbit UI **Review profile**: CHILL **Plan**: Pro **💡 Knowledge Base configuration:** - MCP integration is disabled by default for public repositories - Jira integration is disabled by default for public repositories - Linear integration is disabled by default for public repositories You can enable these sources in your CodeRabbit configuration. <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between e016171cf891432712ee721194800594b315a545 and 5dad550df1d7d7ebf18f4dee14eb2ce17c2493af. </details> <details> <summary>📒 Files selected for processing (1)</summary> * `.claude/prompts/nl-unity-suite-full.md` (1 hunks) </details> <details> <summary>🧰 Additional context used</summary> <details> <summary>🪛 LanguageTool</summary> <details> <summary>.claude/prompts/nl-unity-suite-full.md</summary> [grammar] ~5-~5: There might be a mistake here. Context: ...this once, verbatim, early in the run:** AllowedTools: Write,Bash(printf:*),Bash(... (QB_NEW_EN) --- [grammar] ~10-~10: There might be a mistake here. Context: ...cp__unity__read_console --- ## Mission 1) Pick target file (prefer): - `unity:/... (QB_NEW_EN) --- [grammar] ~20-~20: There might be a mistake here. Context: ...write. --- ## Environment & Paths (CI) - Always pass: `project_root: "TestProject... (QB_NEW_EN) --- [grammar] ~21-~21: There might be a mistake here. Context: ...nd `ctx: {}` on list/read/edit/validate. - **Canonical URIs only**: - Primary: `uni... (QB_NEW_EN) --- [grammar] ~22-~22: There might be a mistake here. Context: ...dit/validate. - **Canonical URIs only**: - Primary: `unity://path/Assets/...` (neve... (QB_NEW_EN) --- [grammar] ~23-~23: There might be a mistake here. Context: ... (never embed `project_root` in the URI) - Relative (when supported): `Assets/...` ... (QB_NEW_EN) --- [grammar] ~24-~24: There might be a mistake here. Context: ...the URI) - Relative (when supported): `Assets/...` - File paths for the helper script are wor... (QB_NEW_EN) --- [grammar] ~30-~30: There might be a mistake here. Context: ...it-nl-suite.md` (synthesized from JUnit) - Helper script: `scripts/nlt-revert.sh` (... (QB_NEW_EN) --- [grammar] ~35-~35: There might be a mistake here. Context: ...(snapshot/restore) --- ## Tool Mapping - **Anchors/regex/structured**: `mcp__unity_... (QB_NEW_EN) --- [grammar] ~36-~36: There might be a mistake here. Context: ...Mapping - **Anchors/regex/structured**: `mcp__unity__script_apply_edits` - **Precise ranges / atomic batch**: `mcp__u... (QB_NEW_EN) --- [grammar] ~37-~37: There might be a mistake here. Context: ...ply_text_edits` (non‑overlapping ranges) - **Validation**: `mcp__unity__validate_scri... (QB_NEW_EN) --- [grammar] ~38-~38: There might be a mistake here. Context: ...n‑overlapping ranges) - **Validation**: `mcp__unity__validate_script(level:"standard")` - **Reporting**: `Write` small XML fragments... (QB_NEW_EN) --- [grammar] ~39-~39: There might be a mistake here. Context: ...rting**: `Write` small XML fragments to `reports/*_results.xml` - **Snapshot/Restore**: `Bash(scripts/nlt-re... (QB_NEW_EN) --- [grammar] ~48-~48: There might be a mistake here. Context: ...tem-out><![CDATA[ ... ]]></system-out>`. - Evidence windows only (±20–40 lines). If... (QB_NEW_EN) --- [grammar] ~86-~86: Ensure spelling is correct Context: ...a.expected_sha256`). - If absent, one re‑read then a final retry. No loops. - After s... (QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1) --- [grammar] ~87-~87: There might be a mistake here. Context: ...fore any further edits in the same test. - Prefer anchors (`script_apply_edits`) fo... (QB_NEW_EN) --- [grammar] ~92-~92: There might be a mistake here. Context: ...T-E, T-F, T-G, T-H, T-I, T-J (15 total). - NL‑0 must include the PLAN line (len=15)... (QB_NEW_EN) --- [grammar] ~99-~99: There might be a mistake here. Context: ...verify; delete `PrintSeries()`; restore. - NL‑2. Anchor comment — Insert `// Build ... (QB_NEW_EN) --- [grammar] ~100-~100: There might be a mistake here. Context: ...bove `public void Update(...)`; restore. - NL‑3. End‑of‑class — Insert `// Tail tes... (QB_NEW_EN) --- [grammar] ~101-~101: There might be a mistake here. Context: ...— Insert `// Tail test A/B/C` (3 lines) before final brace; restore. - NL‑4. Compile t... (QB_NEW_EN) --- [grammar] ~101-~101: There might be a mistake here. Context: ...` (3 lines) before final brace; restore. - NL‑4. Compile trigger — Record INFO only... (QB_NEW_EN) --- [grammar] ~104-~104: There might be a mistake here. Context: ...fy; delete via `regex_replace`; restore. - T‑B. Replace body — Single `replace_rang... (QB_NEW_EN) --- [grammar] ~105-~105: There might be a mistake here. Context: ...lace_range` inside `HasTarget`; restore. - T‑C. Header/region preservation — Edit i... (QB_NEW_EN) --- [grammar] ~106-~106: There might be a mistake here. Context: ...reserve signature/docs/regions; restore. - T‑D. End‑of‑class (anchor) — Insert help... (QB_NEW_EN) --- [grammar] ~107-~107: There might be a mistake here. Context: ...per before final brace; remove; restore. - T‑E. Lifecycle — Insert → update → delet... (QB_NEW_EN) --- [grammar] ~108-~108: There might be a mistake here. Context: ...rt → update → delete via regex; restore. - T‑F. Atomic batch — One call: two small ... (QB_NEW_EN) --- [grammar] ~109-~109: There might be a mistake here. Context: ...‑class comment; all‑or‑nothing; restore. - T‑G. Path normalization — Same edit with... (QB_NEW_EN) --- [grammar] ~110-~110: There might be a mistake here. Context: ...dit with `unity://path/Assets/...` then `Assets/...`; second returns `{status:"no_change"}`. ... (QB_NEW_EN) --- [grammar] ~110-~110: There might be a mistake here. Context: ...; second returns `{status:"no_change"}`. - T‑H. Validation — `standard` after edits... (QB_NEW_EN) --- [grammar] ~111-~111: There might be a mistake here. Context: ...dits; `basic` only for transient checks. - T‑I. Failure surfaces — Record INFO on `... (QB_NEW_EN) --- [grammar] ~117-~117: There might be a mistake here. Context: ...uses are non‑fatal; record and continue. - End each testcase `<system-out>` with `V... (QB_NEW_EN) </details> </details> <details> <summary>🪛 markdownlint-cli2 (0.17.2)</summary> <details> <summary>.claude/prompts/nl-unity-suite-full.md</summary> 52-52: Emphasis used instead of a heading (MD036, no-emphasis-as-heading) </details> </details> </details> <details> <summary>⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)</summary> * GitHub Check: Cursor Bugbot </details> <details> <summary>🔇 Additional comments (1)</summary><blockquote> <details> <summary>.claude/prompts/nl-unity-suite-full.md (1)</summary><blockquote> `46-51`: **Output rules are crisp and consistent (fragments-only, no `$JUNIT_OUT/$MD_OUT` writes).** </blockquote></details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
{ | ||
throw new System.IO.IOException($"Invalid framed length: {payloadLen}"); | ||
} | ||
if (payloadLen > int.MaxValue) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Asymmetric Frame Handling Blocks Empty Messages
The framed I/O implementation is asymmetric: WriteFrameAsync
allows zero-length payloads, but ReadFrameAsUtf8Async
rejects them as invalid. This prevents clients from sending legitimate empty messages (e.g., pings or acknowledgments) and means the bridge can send frames it cannot receive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (4)
.github/workflows/claude-nl-suite.yml (4)
141-169
: Replace fragile Python one‑liner for port detection with robust snippet.- PORT=$(python -c "import os,glob,json,sys,time; b=os.path.expanduser('~/.unity-mcp'); fs=sorted(glob.glob(os.path.join(b,'unity-mcp-status-*.json')), key=os.path.getmtime, reverse=True); print(next((json.load(open(f,'r',encoding='utf-8')).get('unity_port') for f in fs if time.time()-os.path.getmtime(f)<=300 and json.load(open(f,'r',encoding='utf-8')).get('unity_port')), '' ))" 2>/dev/null || true) + PORT="$(python3 - <<'PY' 2>/dev/null +import os, glob, json, time, sys +b = os.path.expanduser('~/.unity-mcp') +fs = sorted(glob.glob(os.path.join(b, 'unity-mcp-status-*.json')), key=os.path.getmtime, reverse=True) +for f in fs: + try: + if time.time() - os.path.getmtime(f) > 300: # stale + continue + with open(f, 'r', encoding='utf-8') as fh: + p = (json.load(fh) or {}).get('unity_port') + if p: + print(p); sys.exit(0) + except Exception: + pass +print("") +PY +)"
285-317
: Normalizer should also import preferred single‑file and roots.- fragments = sorted(Path('reports').glob('*_results.xml')) + fragments = sorted(Path('reports').glob('*_results.xml')) + preferred = Path('reports/nl_final_results.xml') + if preferred.exists(): + try: + proot = ET.parse(preferred).getroot() + if localname(proot.tag) == 'cases': + for tc in proot.findall('./testcase'): + suite.append(tc); added += 1 + else: + for tc in proot.findall('.//testcase'): + suite.append(tc); added += 1 + except Exception as pe: + print(f"Parse error for preferred file {preferred}: {pe}")
48-54
: Pin third‑party Actions by immutable commit SHAs (supply‑chain hardening).Apply:
- - uses: actions/checkout@v4 + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 - - uses: astral-sh/setup-uv@v4 + - uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4Do the same for:
- game-ci/unity-test-runner@v4 → 0ff419b913a3630032cbe0de48a0099b5a9f0ed9
- anthropics/claude-code-base-action@beta → e9863f822497ff36abdac4571937150d27397a34
- mikepenz/action-junit-report@v5 → replace with its exact commit SHA
- actions/upload-artifact@v4 → ea165f8d65b6e75b540449e92b4886f43607fa02
16-18
: Pin Unity Docker image by digest to prevent tag drift.env: UNITY_VERSION: 2021.3.45f1 - UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3 + UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3@sha256:<DIGEST> UNITY_CACHE_ROOT: /home/runner/work/_temp/_github_homeResolve via:
docker buildx imagetools inspect unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3 | rg -n 'Digest:' | head -1
🧹 Nitpick comments (3)
.github/workflows/claude-nl-suite.yml (3)
401-417
: Use MD_OUT env when adding job summary (avoid hardcoded path).- p = Path('reports/junit-nl-suite.md') + import os + p = Path(os.environ.get('MD_OUT', 'reports/junit-nl-suite.md'))
279-283
: Avoid mutable model alias in CI for reproducibility.Consider pinning
model: claude-3-7-sonnet-<dated-id>
instead of-latest
. Please confirm the exact stable model identifier you want here.
434-455
: Artifacts/JUnit publishing look correct; just ensure actions are pinned.Once SHAs are pinned, run actionlint/yamllint locally to confirm no remaining warnings. I can provide a pre-commit config if helpful.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
.github/workflows/claude-nl-suite.yml
(1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.7)
.github/workflows/claude-nl-suite.yml
4-4: could not parse as YAML: yaml: line 4: mapping values are not allowed in this context
(syntax-check)
🪛 YAMLlint (1.37.1)
.github/workflows/claude-nl-suite.yml
[error] 3-3: trailing spaces
(trailing-spaces)
[error] 6-6: trailing spaces
(trailing-spaces)
[error] 10-10: trailing spaces
(trailing-spaces)
[error] 14-14: trailing spaces
(trailing-spaces)
[error] 19-19: trailing spaces
(trailing-spaces)
[error] 28-28: trailing spaces
(trailing-spaces)
[error] 47-47: trailing spaces
(trailing-spaces)
[error] 51-51: trailing spaces
(trailing-spaces)
[error] 56-56: trailing spaces
(trailing-spaces)
[error] 74-74: trailing spaces
(trailing-spaces)
[error] 89-89: trailing spaces
(trailing-spaces)
[error] 96-96: trailing spaces
(trailing-spaces)
[error] 103-103: trailing spaces
(trailing-spaces)
[error] 140-140: trailing spaces
(trailing-spaces)
[error] 180-180: trailing spaces
(trailing-spaces)
[error] 202-202: trailing spaces
(trailing-spaces)
[error] 209-209: trailing spaces
(trailing-spaces)
[error] 222-222: trailing spaces
(trailing-spaces)
[error] 258-258: trailing spaces
(trailing-spaces)
[error] 283-283: trailing spaces
(trailing-spaces)
[error] 318-318: trailing spaces
(trailing-spaces)
[error] 363-363: trailing spaces
(trailing-spaces)
[error] 375-375: trailing spaces
(trailing-spaces)
[error] 387-387: trailing spaces
(trailing-spaces)
[error] 400-400: trailing spaces
(trailing-spaces)
[error] 417-417: trailing spaces
(trailing-spaces)
[error] 433-433: trailing spaces
(trailing-spaces)
[error] 444-444: trailing spaces
(trailing-spaces)
[error] 456-456: trailing spaces
(trailing-spaces)
[error] 463-463: no new line character at the end of file
(new-line-at-end-of-file)
[error] 463-463: trailing spaces
(trailing-spaces)
[error] 4-4: syntax error: mapping values are not allowed here
(syntax)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Cursor Bugbot
🔇 Additional comments (1)
.github/workflows/claude-nl-suite.yml (1)
261-263
: Good: gate NL run on both Anthropic and Unity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
.claude/prompts/nl-unity-suite-full.md (1)
86-92
: Replace pseudo APIs withread_resource
and drop mandatory post-write re-read.Current guidance uses nonexistent
read_text/read_bytes
and forces an immediate re-read after every write, contradicting prior resolved comments and adding needless I/O.-### Guarded Write Pattern (for edits, not restores) - -- Before any mutation: `buf = read_text(uri)`; `pre_sha = sha256(read_bytes(uri))`. -- Write with `precondition_sha256 = pre_sha`. -- On `{status:"stale_file"}`: - - Retry once using the server hash (`data.current_sha256` or `data.expected_sha256`). - - If absent, one re‑read then a final retry. No loops. -- After success: immediately re‑read raw bytes and set `pre_sha = sha256(read_bytes(uri))` before any further edits in the same test. - - Prefer anchors (`script_apply_edits`) for end‑of‑class / above‑method insertions. Keep edits inside method bodies. Avoid header/using. +### Guarded Write Pattern (for edits, not restores) + +- Before any mutation: `res = mcp__unity__read_resource(uri, project_root)`; set `buf = res.text`; set `pre_sha = res.sha256` (server‑computed over raw on‑disk bytes). +- Write with `precondition_sha256 = pre_sha`. +- On `{status:"stale_file"}`: retry once using a server hash (`data.current_sha256` or `data.expected_sha256`) if present; otherwise perform one `read_resource(...)` to refresh `pre_sha` and retry. No loops. +- After success: prefer not to re‑read. Update `buf` locally; refresh `pre_sha = read_resource(...).sha256` only if the next step requires exact on‑disk sync (validation, anchor recompute) or before leaving the test. +- Prefer anchors (`script_apply_edits`) for end‑of‑class / above‑method insertions. Keep edits inside method bodies. Avoid header/using.
🧹 Nitpick comments (2)
.claude/prompts/nl-unity-suite-full.md (2)
5-5
: Use a proper heading instead of emphasis (markdownlint MD036).Switch the emphasized line to a heading for consistency and to satisfy linters.
-**Print this once, verbatim, early in the run:** +### Print this once, verbatim, early in the run
71-82
: Ensure snapshot directory exists or document helper behavior.If
reports/_snapshots
isn’t pre-created, snapshot/restore can fail. Either guarantee the helper creates parent dirs or note it here.- Snapshot once at NL‑0, then restore after each test via the helper. + - Snapshot once at NL‑0, then restore after each test via the helper. + - The helper creates parent directories for the snapshot path (`reports/_snapshots`) if missing.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
.claude/prompts/nl-unity-suite-full.md
(1 hunks)
🧰 Additional context used
🪛 LanguageTool
.claude/prompts/nl-unity-suite-full.md
[grammar] ~5-~5: There might be a mistake here.
Context: ...this once, verbatim, early in the run:** AllowedTools: Write,Bash(printf:*),Bash(...
(QB_NEW_EN)
[grammar] ~20-~20: There might be a mistake here.
Context: ...write. --- ## Environment & Paths (CI) - Always pass: `project_root: "TestProject...
(QB_NEW_EN)
[grammar] ~21-~21: There might be a mistake here.
Context: ...nd ctx: {}
on list/read/edit/validate. - Canonical URIs only: - Primary: `uni...
(QB_NEW_EN)
[grammar] ~22-~22: There might be a mistake here.
Context: ...dit/validate. - Canonical URIs only: - Primary: unity://path/Assets/...
(neve...
(QB_NEW_EN)
[grammar] ~23-~23: There might be a mistake here.
Context: ... (never embed project_root
in the URI) - Relative (when supported): Assets/...
...
(QB_NEW_EN)
[grammar] ~24-~24: There might be a mistake here.
Context: ...the URI) - Relative (when supported): Assets/...
- File paths for the helper script are wor...
(QB_NEW_EN)
[grammar] ~30-~30: There might be a mistake here.
Context: ...it-nl-suite.md(synthesized from JUnit) - Helper script:
scripts/nlt-revert.sh` (...
(QB_NEW_EN)
[grammar] ~35-~35: There might be a mistake here.
Context: ...(snapshot/restore) --- ## Tool Mapping - Anchors/regex/structured: `mcp__unity_...
(QB_NEW_EN)
[grammar] ~36-~36: There might be a mistake here.
Context: ...Mapping - Anchors/regex/structured: mcp__unity__script_apply_edits
- Precise ranges / atomic batch: `mcp__u...
(QB_NEW_EN)
[grammar] ~37-~37: There might be a mistake here.
Context: ...ply_text_edits(non‑overlapping ranges) - **Validation**:
mcp__unity__validate_scri...
(QB_NEW_EN)
[grammar] ~38-~38: There might be a mistake here.
Context: ...n‑overlapping ranges) - Validation: mcp__unity__validate_script(level:"standard")
- Reporting: Write
small XML fragments...
(QB_NEW_EN)
[grammar] ~39-~39: There might be a mistake here.
Context: ...rting**: Write
small XML fragments to reports/*_results.xml
- Snapshot/Restore: `Bash(scripts/nlt-re...
(QB_NEW_EN)
[grammar] ~48-~48: There might be a mistake here.
Context: ...tem-out>`. - Evidence windows only (±20–40 lines). If...
(QB_NEW_EN)
[grammar] ~90-~90: Ensure spelling is correct
Context: ...a.expected_sha256`). - If absent, one re‑read then a final retry. No loops. - After s...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~91-~91: There might be a mistake here.
Context: ...fore any further edits in the same test. - Prefer anchors (script_apply_edits
) fo...
(QB_NEW_EN)
[grammar] ~96-~96: There might be a mistake here.
Context: ...T-E, T-F, T-G, T-H, T-I, T-J (15 total). - NL‑0 must include the PLAN line (len=15)...
(QB_NEW_EN)
[grammar] ~103-~103: There might be a mistake here.
Context: ...verify; delete PrintSeries()
; restore. - NL‑2. Anchor comment — Insert `// Build ...
(QB_NEW_EN)
[grammar] ~104-~104: There might be a mistake here.
Context: ...bove public void Update(...)
; restore. - NL‑3. End‑of‑class — Insert `// Tail tes...
(QB_NEW_EN)
[grammar] ~105-~105: There might be a mistake here.
Context: ...— Insert // Tail test A/B/C
(3 lines) before final brace; restore. - NL‑4. Compile t...
(QB_NEW_EN)
[grammar] ~105-~105: There might be a mistake here.
Context: ...` (3 lines) before final brace; restore. - NL‑4. Compile trigger — Record INFO only...
(QB_NEW_EN)
[grammar] ~108-~108: There might be a mistake here.
Context: ...fy; delete via regex_replace
; restore. - T‑B. Replace body — Single `replace_rang...
(QB_NEW_EN)
[grammar] ~109-~109: There might be a mistake here.
Context: ...lace_rangeinside
HasTarget`; restore. - T‑C. Header/region preservation — Edit i...
(QB_NEW_EN)
[grammar] ~110-~110: There might be a mistake here.
Context: ...reserve signature/docs/regions; restore. - T‑D. End‑of‑class (anchor) — Insert help...
(QB_NEW_EN)
[grammar] ~111-~111: There might be a mistake here.
Context: ...per before final brace; remove; restore. - T‑E. Lifecycle — Insert → update → delet...
(QB_NEW_EN)
[grammar] ~112-~112: There might be a mistake here.
Context: ...rt → update → delete via regex; restore. - T‑F. Atomic batch — One call: two small ...
(QB_NEW_EN)
[grammar] ~113-~113: There might be a mistake here.
Context: ...‑class comment; all‑or‑nothing; restore. - T‑G. Path normalization — Same edit with...
(QB_NEW_EN)
[grammar] ~114-~114: There might be a mistake here.
Context: ...dit with unity://path/Assets/...
then Assets/...
; second returns {status:"no_change"}
. ...
(QB_NEW_EN)
[grammar] ~114-~114: There might be a mistake here.
Context: ...; second returns {status:"no_change"}
. - T‑H. Validation — standard
after edits...
(QB_NEW_EN)
[grammar] ~115-~115: There might be a mistake here.
Context: ...dits; basic
only for transient checks. - T‑I. Failure surfaces — Record INFO on `...
(QB_NEW_EN)
[grammar] ~121-~121: There might be a mistake here.
Context: ...uses are non‑fatal; record and continue. - End each testcase <system-out>
with `V...
(QB_NEW_EN)
🪛 markdownlint-cli2 (0.17.2)
.claude/prompts/nl-unity-suite-full.md
52-52: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Cursor Bugbot
🔇 Additional comments (4)
.claude/prompts/nl-unity-suite-full.md (4)
35-38
: Tool mapping reads accurately reflect atomic multi-edit support.Good correction on
apply_text_edits
(non-overlapping atomic batches) and division of responsibilities withscript_apply_edits
.
52-66
: Suite name consistency looks correct.Example uses
classname="UnityMCP.NL-T"
and the PLAN/PROGRESS totals are 15; both match the current workflows/docs.
96-99
: Execution order and totals are coherent (15 tests, NL‑0 includes PLAN).No changes needed.
6-6
: AllowedTools list is correct; mcp__unity__read_console is permitted in both workflows.
…s and revert helper
…hen needed; convert 'Print this once' to heading; note snapshot helper creates parent dirs
…ases present; recompute tests/failures
…system-out> blocks (truncated)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (3)
.github/workflows/claude-nl-suite.yml (3)
283-333
: Support preferred single-file results (nl_final_results.xml) and<cases>
root in normalizer.Matches the prompt’s “preferred single-file” output path and improves robustness.
- fragments = sorted(Path('reports').glob('*_results.xml')) + fragments = sorted(Path('reports').glob('*_results.xml')) + # Also import preferred single-file results if present + preferred = Path('reports/nl_final_results.xml') + if preferred.exists(): + fragments.insert(0, preferred) @@ - if localname(froot.tag) == 'testcase': + if localname(froot.tag) == 'testcase': suite.append(froot); added += 1 - else: + elif localname(froot.tag) == 'cases': + for tc in froot.findall('./testcase'): + suite.append(tc); added += 1 + else: for tc in froot.findall('.//testcase'): suite.append(tc); added += 1
47-50
: Pin all third‑party Actions by commit SHA (supply‑chain hardening).Mutable tags can drift. Replace with immutable SHAs.
- - uses: actions/checkout@v4 + - uses: actions/checkout@<COMMIT_SHA> ... - - uses: astral-sh/setup-uv@v4 + - uses: astral-sh/setup-uv@<COMMIT_SHA> ... - uses: game-ci/unity-test-runner@v4 + uses: game-ci/unity-test-runner@<COMMIT_SHA> ... - - name: Run Claude NL suite (single pass) - uses: anthropics/claude-code-base-action@beta + - name: Run Claude NL suite (single pass) + uses: anthropics/claude-code-base-action@<COMMIT_SHA> ... - uses: mikepenz/action-junit-report@v5 + uses: mikepenz/action-junit-report@<COMMIT_SHA> ... - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@<COMMIT_SHA>Note: apply the same SHA to each occurrence of the same Action.
Also applies to: 52-55, 75-88, 258-282, 478-488, 489-499
14-17
: Pin Unity Docker image by digest to prevent tag drift.Locks the editor layer for reproducible runs.
env: UNITY_VERSION: 2021.3.45f1 - UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3 + # Pin to immutable digest (replace <DIGEST>) + UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3@sha256:<DIGEST> UNITY_CACHE_ROOT: /home/runner/work/_temp/_github_home
🧹 Nitpick comments (5)
.claude/prompts/nl-unity-suite-full.md (3)
5-6
: Fix heading level (MD001) in “Print this once…”Use H2 after H1 to avoid heading jumps.
-### Print this once, verbatim, early in the run +## Print this once, verbatim, early in the run
60-72
: Use a heading instead of emphasized text for the example block (MD036).Minor readability/markdownlint improvement.
-**Example fragment** +### Example fragment<testcase ...>
...
48-50
: Avoid brittle “scan braces” fallback; leverage find_in_file for ranges.Computing ranges by manual brace scans is error‑prone with nested types/regions. Prefer
mcp__unity__find_in_file
to derive exact start/end offsets for the helper method before callingapply_text_edits
.- 2) If that returns `missing_field` or `bad_request`, fallback to `apply_text_edits` with a single `replace_range` computed from the method’s start/end offsets (found by scanning braces). + 2) If that returns `missing_field` or `bad_request`, use `mcp__unity__find_in_file` to locate the method’s exact span and then `apply_text_edits` with a single `replace_range` for that span..github/workflows/claude-nl-suite.yml (2)
148-149
: Harden log redaction: include api keys and similar tokens.Extend the regex to catch common API key patterns.
- docker logs -f unity-mcp 2>&1 | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' & LOGPID=$! + docker logs -f unity-mcp 2>&1 | sed -E 's/((serial|license|password|token|api[-_]?key)[^[:space:]]*)/[REDACTED]/ig' & LOGPID=$! @@ - docker logs --tail 200 unity-mcp | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' || true + docker logs --tail 200 unity-mcp | sed -E 's/((serial|license|password|token|api[-_]?key)[^[:space:]]*)/[REDACTED]/ig' || true @@ - docker logs --tail 400 unity-mcp | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' || true + docker logs --tail 400 unity-mcp | sed -E 's/((serial|license|password|token|api[-_]?key)[^[:space:]]*)/[REDACTED]/ig' || trueAlso applies to: 176-176, 505-506
26-26
: Fix spacing after colon (YAMLlint MD_OUT).Removes extra spaces flagged by linters.
- MD_OUT: reports/junit-nl-suite.md + MD_OUT: reports/junit-nl-suite.md
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
.claude/prompts/nl-unity-suite-full.md
(1 hunks).github/workflows/claude-nl-suite.yml
(1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
.github/workflows/claude-nl-suite.yml
[error] 5-5: trailing spaces
(trailing-spaces)
[error] 9-9: trailing spaces
(trailing-spaces)
[error] 13-13: trailing spaces
(trailing-spaces)
[error] 18-18: trailing spaces
(trailing-spaces)
[warning] 21-21: wrong indentation: expected 8 but found 6
(indentation)
[warning] 25-25: wrong indentation: expected 10 but found 8
(indentation)
[warning] 26-26: too many spaces after colon
(colons)
[error] 27-27: trailing spaces
(trailing-spaces)
[warning] 30-30: wrong indentation: expected 10 but found 8
(indentation)
[warning] 33-33: wrong indentation: expected 14 but found 12
(indentation)
[warning] 33-33: too many spaces after colon
(colons)
[warning] 34-34: too many spaces after colon
(colons)
[warning] 36-36: too many spaces after colon
(colons)
[error] 46-46: trailing spaces
(trailing-spaces)
[warning] 49-49: wrong indentation: expected 14 but found 12
(indentation)
[error] 50-50: trailing spaces
(trailing-spaces)
[warning] 54-54: wrong indentation: expected 14 but found 12
(indentation)
[error] 55-55: trailing spaces
(trailing-spaces)
[error] 73-73: trailing spaces
(trailing-spaces)
[warning] 79-79: wrong indentation: expected 14 but found 12
(indentation)
[warning] 79-79: too many spaces after colon
(colons)
[warning] 80-80: too many spaces after colon
(colons)
[warning] 82-82: too many spaces after colon
(colons)
[warning] 84-84: wrong indentation: expected 14 but found 12
(indentation)
[error] 88-88: trailing spaces
(trailing-spaces)
[error] 95-95: trailing spaces
(trailing-spaces)
[error] 102-102: trailing spaces
(trailing-spaces)
[warning] 107-107: wrong indentation: expected 14 but found 12
(indentation)
[warning] 107-107: too many spaces after colon
(colons)
[warning] 109-109: too many spaces after colon
(colons)
[error] 139-139: trailing spaces
(trailing-spaces)
[error] 179-179: trailing spaces
(trailing-spaces)
[error] 201-201: trailing spaces
(trailing-spaces)
[error] 208-208: trailing spaces
(trailing-spaces)
[error] 221-221: trailing spaces
(trailing-spaces)
[error] 257-257: trailing spaces
(trailing-spaces)
[warning] 264-264: wrong indentation: expected 14 but found 12
(indentation)
[error] 282-282: trailing spaces
(trailing-spaces)
[error] 333-333: trailing spaces
(trailing-spaces)
[error] 407-407: trailing spaces
(trailing-spaces)
[error] 419-419: trailing spaces
(trailing-spaces)
[error] 431-431: trailing spaces
(trailing-spaces)
[error] 444-444: trailing spaces
(trailing-spaces)
[error] 461-461: trailing spaces
(trailing-spaces)
[error] 477-477: trailing spaces
(trailing-spaces)
[warning] 482-482: wrong indentation: expected 14 but found 12
(indentation)
[error] 488-488: trailing spaces
(trailing-spaces)
[warning] 493-493: wrong indentation: expected 14 but found 12
(indentation)
[error] 500-500: trailing spaces
(trailing-spaces)
[error] 507-507: no new line character at the end of file
(new-line-at-end-of-file)
[error] 507-507: trailing spaces
(trailing-spaces)
🪛 LanguageTool
.claude/prompts/nl-unity-suite-full.md
[grammar] ~10-~10: There might be a mistake here.
Context: ...cp__unity__read_console --- ## Mission 1) Pick target file (prefer): - `unity:/...
(QB_NEW_EN)
[grammar] ~20-~20: There might be a mistake here.
Context: ...write. --- ## Environment & Paths (CI) - Always pass: `project_root: "TestProject...
(QB_NEW_EN)
[grammar] ~21-~21: There might be a mistake here.
Context: ...nd ctx: {}
on list/read/edit/validate. - Canonical URIs only: - Primary: `uni...
(QB_NEW_EN)
[grammar] ~22-~22: There might be a mistake here.
Context: ...dit/validate. - Canonical URIs only: - Primary: unity://path/Assets/...
(neve...
(QB_NEW_EN)
[grammar] ~23-~23: There might be a mistake here.
Context: ... (never embed project_root
in the URI) - Relative (when supported): Assets/...
...
(QB_NEW_EN)
[grammar] ~24-~24: There might be a mistake here.
Context: ...the URI) - Relative (when supported): Assets/...
- File paths for the helper script are wor...
(QB_NEW_EN)
[grammar] ~30-~30: There might be a mistake here.
Context: ...it-nl-suite.md(synthesized from JUnit) - Helper script:
scripts/nlt-revert.sh` (...
(QB_NEW_EN)
[grammar] ~35-~35: There might be a mistake here.
Context: ...(snapshot/restore) --- ## Tool Mapping - Anchors/regex/structured: `mcp__unity_...
(QB_NEW_EN)
[grammar] ~36-~36: There might be a mistake here.
Context: ...Mapping - Anchors/regex/structured: mcp__unity__script_apply_edits
- Precise ranges / atomic batch: `mcp__u...
(QB_NEW_EN)
[grammar] ~37-~37: There might be a mistake here.
Context: ...ply_text_edits(non‑overlapping ranges) - **Validation**:
mcp__unity__validate_scri...
(QB_NEW_EN)
[grammar] ~38-~38: There might be a mistake here.
Context: ...n‑overlapping ranges) - Validation: mcp__unity__validate_script(level:"standard")
- Reporting: Write
small XML fragments...
(QB_NEW_EN)
[grammar] ~39-~39: There might be a mistake here.
Context: ...rting**: Write
small XML fragments to reports/*_results.xml
- Snapshot/Restore: `Bash(scripts/nlt-re...
(QB_NEW_EN)
[grammar] ~49-~49: There might be a mistake here.
Context: .../end offsets (found by scanning braces). - If any write returns missing_field
, `b...
(QB_NEW_EN)
[grammar] ~50-~50: There might be a mistake here.
Context: ...restore* and proceed to the next test. - Never call generic Bash like mkdir
; th...
(QB_NEW_EN)
[grammar] ~56-~56: There might be a mistake here.
Context: ...tem-out>`. - Evidence windows only (±20–40 lines). If...
(QB_NEW_EN)
[grammar] ~95-~95: There might be a mistake here.
Context: ...s, not restores) - Before any mutation: - Call `mcp__unity__read_resource(uri, pro...
(QB_NEW_EN)
[grammar] ~96-~96: There might be a mistake here.
Context: ...server‑computed over raw on‑disk bytes). - Write with `precondition_sha256 = pre_sh...
(QB_NEW_EN)
[grammar] ~101-~101: There might be a mistake here.
Context: ...aand retry. No loops. - After success: - Prefer not to re‑read. Update
buf` loca...
(QB_NEW_EN)
[grammar] ~102-~102: Ensure spelling is correct
Context: ...ops. - After success: - Prefer not to re‑read. Update buf
locally; refresh `pre_sha...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~102-~102: There might be a mistake here.
Context: ...r recompute) or before leaving the test. - Prefer anchors (script_apply_edits
) fo...
(QB_NEW_EN)
[grammar] ~107-~107: There might be a mistake here.
Context: ...T-E, T-F, T-G, T-H, T-I, T-J (15 total). - NL‑0 must include the PLAN line (len=15)...
(QB_NEW_EN)
[grammar] ~114-~114: There might be a mistake here.
Context: ...verify; delete PrintSeries()
; restore. - NL‑2. Anchor comment — Insert `// Build ...
(QB_NEW_EN)
[grammar] ~115-~115: There might be a mistake here.
Context: ...bove public void Update(...)
; restore. - NL‑3. End‑of‑class — Insert `// Tail tes...
(QB_NEW_EN)
[grammar] ~116-~116: There might be a mistake here.
Context: ...— Insert // Tail test A/B/C
(3 lines) before final brace; restore. - NL‑4. Compile t...
(QB_NEW_EN)
[grammar] ~116-~116: There might be a mistake here.
Context: ...` (3 lines) before final brace; restore. - NL‑4. Compile trigger — Record INFO only...
(QB_NEW_EN)
[grammar] ~119-~119: There might be a mistake here.
Context: ...fy; delete via regex_replace
; restore. - T‑B. Replace body — Single `replace_rang...
(QB_NEW_EN)
[grammar] ~120-~120: There might be a mistake here.
Context: ...lace_rangeinside
HasTarget`; restore. - T‑C. Header/region preservation — Edit i...
(QB_NEW_EN)
[grammar] ~121-~121: There might be a mistake here.
Context: ...reserve signature/docs/regions; restore. - T‑D. End‑of‑class (anchor) — Insert help...
(QB_NEW_EN)
[grammar] ~122-~122: There might be a mistake here.
Context: ...per before final brace; remove; restore. - T‑E. Lifecycle — Insert → update → delet...
(QB_NEW_EN)
[grammar] ~123-~123: There might be a mistake here.
Context: ...rt → update → delete via regex; restore. - T‑F. Atomic batch — One call: two small ...
(QB_NEW_EN)
[grammar] ~124-~124: There might be a mistake here.
Context: ...‑class comment; all‑or‑nothing; restore. - T‑G. Path normalization — Same edit with...
(QB_NEW_EN)
[grammar] ~125-~125: There might be a mistake here.
Context: ...dit with unity://path/Assets/...
then Assets/...
; second returns {status:"no_change"}
. ...
(QB_NEW_EN)
[grammar] ~125-~125: There might be a mistake here.
Context: ...; second returns {status:"no_change"}
. - T‑H. Validation — standard
after edits...
(QB_NEW_EN)
[grammar] ~126-~126: There might be a mistake here.
Context: ...dits; basic
only for transient checks. - T‑I. Failure surfaces — Record INFO on `...
(QB_NEW_EN)
[grammar] ~132-~132: There might be a mistake here.
Context: ...uses are non‑fatal; record and continue. - End each testcase <system-out>
with `V...
(QB_NEW_EN)
🪛 markdownlint-cli2 (0.17.2)
.claude/prompts/nl-unity-suite-full.md
5-5: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
60-60: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: nl-suite
- GitHub Check: Cursor Bugbot
name: Claude NL/T Full Suite (Unity live) | ||
|
||
on: | ||
workflow_dispatch: {} | ||
|
||
workflow_dispatch: {} | ||
permissions: | ||
contents: write # allow Claude to write test artifacts | ||
pull-requests: write # allow annotations / comments | ||
issues: write | ||
|
||
contents: read | ||
checks: write | ||
|
||
concurrency: | ||
group: ${{ github.workflow }}-${{ github.ref }} | ||
cancel-in-progress: true | ||
|
||
group: ${{ github.workflow }}-${{ github.ref }} | ||
cancel-in-progress: true | ||
|
||
env: | ||
UNITY_VERSION: 2021.3.45f1 | ||
UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3 | ||
UNITY_CACHE_ROOT: /home/runner/work/_temp/_github_home | ||
|
||
jobs: | ||
nl-suite: | ||
if: github.event_name == 'workflow_dispatch' | ||
runs-on: ubuntu-latest | ||
timeout-minutes: 60 | ||
|
||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 0 | ||
|
||
# Python + uv for the Unity MCP server | ||
- name: Install Python + uv | ||
uses: astral-sh/setup-uv@v4 | ||
with: | ||
python-version: '3.11' | ||
|
||
- name: Install UnityMcpServer deps | ||
run: | | ||
set -eux | ||
if [ -f "UnityMcpBridge/UnityMcpServer~/src/pyproject.toml" ]; then | ||
uv venv | ||
. .venv/bin/activate | ||
uv pip install -e "UnityMcpBridge/UnityMcpServer~/src" | ||
elif [ -f "UnityMcpBridge/UnityMcpServer~/src/requirements.txt" ]; then | ||
nl-suite: | ||
if: github.event_name == 'workflow_dispatch' | ||
runs-on: ubuntu-latest | ||
timeout-minutes: 60 | ||
env: | ||
JUNIT_OUT: reports/junit-nl-suite.xml | ||
MD_OUT: reports/junit-nl-suite.md | ||
|
||
steps: | ||
# ---------- Secrets check ---------- | ||
- name: Detect secrets (outputs) | ||
id: detect | ||
env: | ||
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} | ||
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} | ||
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} | ||
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} | ||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | ||
run: | | ||
set -e | ||
if [ -n "$ANTHROPIC_API_KEY" ]; then echo "anthropic_ok=true" >> "$GITHUB_OUTPUT"; else echo "anthropic_ok=false" >> "$GITHUB_OUTPUT"; fi | ||
if [ -n "$UNITY_LICENSE" ] || { [ -n "$UNITY_EMAIL" ] && [ -n "$UNITY_PASSWORD" ]; } || [ -n "$UNITY_SERIAL" ]; then | ||
echo "unity_ok=true" >> "$GITHUB_OUTPUT" | ||
else | ||
echo "unity_ok=false" >> "$GITHUB_OUTPUT" | ||
fi | ||
- uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 0 | ||
|
||
# ---------- Python env for MCP server (uv) ---------- | ||
- uses: astral-sh/setup-uv@v4 | ||
with: | ||
python-version: '3.11' | ||
|
||
- name: Install MCP server | ||
run: | | ||
set -eux | ||
uv venv | ||
. .venv/bin/activate | ||
uv pip install -r "UnityMcpBridge/UnityMcpServer~/src/requirements.txt" | ||
else | ||
echo "No Python deps found (skipping)" | ||
fi | ||
- name: Run Claude NL/T test suite | ||
id: claude | ||
uses: anthropics/claude-code-base-action@beta | ||
with: | ||
# Test instructions live here | ||
prompt_file: .claude/prompts/nl-unity-suite.md | ||
|
||
# Tight tool allowlist | ||
allowed_tools: "Bash(git:*),View,GlobTool,GrepTool,BatchTool,mcp__unity__*" | ||
|
||
# MCP server path (matches your screenshots) | ||
mcp_config: | | ||
echo "VIRTUAL_ENV=$GITHUB_WORKSPACE/.venv" >> "$GITHUB_ENV" | ||
echo "$GITHUB_WORKSPACE/.venv/bin" >> "$GITHUB_PATH" | ||
if [ -f UnityMcpBridge/UnityMcpServer~/src/pyproject.toml ]; then | ||
uv pip install -e UnityMcpBridge/UnityMcpServer~/src | ||
elif [ -f UnityMcpBridge/UnityMcpServer~/src/requirements.txt ]; then | ||
uv pip install -r UnityMcpBridge/UnityMcpServer~/src/requirements.txt | ||
elif [ -f UnityMcpBridge/UnityMcpServer~/pyproject.toml ]; then | ||
uv pip install -e UnityMcpBridge/UnityMcpServer~/ | ||
elif [ -f UnityMcpBridge/UnityMcpServer~/requirements.txt ]; then | ||
uv pip install -r UnityMcpBridge/UnityMcpServer~/requirements.txt | ||
else | ||
echo "No MCP Python deps found (skipping)" | ||
fi | ||
# ---------- License prime on host (GameCI) ---------- | ||
- name: Prime Unity license on host (GameCI) | ||
if: steps.detect.outputs.unity_ok == 'true' | ||
uses: game-ci/unity-test-runner@v4 | ||
env: | ||
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} | ||
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} | ||
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} | ||
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} | ||
with: | ||
projectPath: TestProjects/UnityMCPTests | ||
testMode: EditMode | ||
customParameters: -runTests -testFilter __NoSuchTest__ -batchmode -nographics | ||
unityVersion: ${{ env.UNITY_VERSION }} | ||
|
||
# (Optional) Inspect license caches | ||
- name: Inspect GameCI license caches (host) | ||
if: steps.detect.outputs.unity_ok == 'true' | ||
run: | | ||
set -eux | ||
find "${{ env.UNITY_CACHE_ROOT }}" -maxdepth 4 \( -path "*/.cache" -prune -o -type f \( -name '*.ulf' -o -name 'user.json' \) -print \) 2>/dev/null || true | ||
# ---------- Clean old MCP status ---------- | ||
- name: Clean old MCP status | ||
run: | | ||
set -eux | ||
mkdir -p "$HOME/.unity-mcp" | ||
rm -f "$HOME/.unity-mcp"/unity-mcp-status-*.json || true | ||
# ---------- Start headless Unity (persistent bridge) ---------- | ||
- name: Start Unity (persistent bridge) | ||
if: steps.detect.outputs.unity_ok == 'true' | ||
env: | ||
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} | ||
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} | ||
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} | ||
run: | | ||
set -eu | ||
if [ ! -d "${{ github.workspace }}/TestProjects/UnityMCPTests/ProjectSettings" ]; then | ||
echo "Unity project not found; failing fast." | ||
exit 1 | ||
fi | ||
mkdir -p "$HOME/.unity-mcp" | ||
MANUAL_ARG=() | ||
if [ -f "${UNITY_CACHE_ROOT}/.local/share/unity3d/Unity_lic.ulf" ]; then | ||
MANUAL_ARG=(-manualLicenseFile /root/.local/share/unity3d/Unity_lic.ulf) | ||
fi | ||
EBL_ARGS=() | ||
[ -n "${UNITY_SERIAL:-}" ] && EBL_ARGS+=(-serial "$UNITY_SERIAL") | ||
[ -n "${UNITY_EMAIL:-}" ] && EBL_ARGS+=(-username "$UNITY_EMAIL") | ||
[ -n "${UNITY_PASSWORD:-}" ] && EBL_ARGS+=(-password "$UNITY_PASSWORD") | ||
docker rm -f unity-mcp >/dev/null 2>&1 || true | ||
docker run -d --name unity-mcp --network host \ | ||
-e HOME=/root \ | ||
-e UNITY_MCP_ALLOW_BATCH=1 -e UNITY_MCP_STATUS_DIR=/root/.unity-mcp \ | ||
-e UNITY_MCP_BIND_HOST=127.0.0.1 \ | ||
-v "${{ github.workspace }}:/workspace" -w /workspace \ | ||
-v "${{ env.UNITY_CACHE_ROOT }}:/root" \ | ||
-v "$HOME/.unity-mcp:/root/.unity-mcp" \ | ||
${{ env.UNITY_IMAGE }} /opt/unity/Editor/Unity -batchmode -nographics -logFile - \ | ||
-stackTraceLogType Full \ | ||
-projectPath /workspace/TestProjects/UnityMCPTests \ | ||
"${MANUAL_ARG[@]}" \ | ||
"${EBL_ARGS[@]}" \ | ||
-executeMethod MCPForUnity.Editor.MCPForUnityBridge.StartAutoConnect | ||
# ---------- Wait for Unity bridge ---------- | ||
- name: Wait for Unity bridge (robust) | ||
if: steps.detect.outputs.unity_ok == 'true' | ||
run: | | ||
set -euo pipefail | ||
if ! docker ps --format '{{.Names}}' | grep -qx 'unity-mcp'; then | ||
echo "Unity container failed to start"; docker ps -a || true; exit 1 | ||
fi | ||
docker logs -f unity-mcp 2>&1 | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' & LOGPID=$! | ||
deadline=$((SECONDS+420)); READY=0 | ||
try_connect_host() { | ||
P="$1" | ||
timeout 1 bash -lc "exec 3<>/dev/tcp/127.0.0.1/$P; head -c 8 <&3 >/dev/null" && return 0 || true | ||
if command -v nc >/dev/null 2>&1; then nc -6 -z ::1 "$P" && return 0 || true; fi | ||
return 1 | ||
} | ||
while [ $SECONDS -lt $deadline ]; do | ||
if docker logs unity-mcp 2>&1 | grep -qE "MCP Bridge listening|Bridge ready|Server started"; then | ||
READY=1; echo "Bridge ready (log markers)"; break | ||
fi | ||
PORT=$(python -c "import os,glob,json,sys,time; b=os.path.expanduser('~/.unity-mcp'); fs=sorted(glob.glob(os.path.join(b,'unity-mcp-status-*.json')), key=os.path.getmtime, reverse=True); print(next((json.load(open(f,'r',encoding='utf-8')).get('unity_port') for f in fs if time.time()-os.path.getmtime(f)<=300 and json.load(open(f,'r',encoding='utf-8')).get('unity_port')), '' ))" 2>/dev/null || true) | ||
if [ -n "${PORT:-}" ] && { try_connect_host "$PORT" || docker exec unity-mcp bash -lc "timeout 1 bash -lc 'exec 3<>/dev/tcp/127.0.0.1/$PORT' || (command -v nc >/dev/null 2>&1 && nc -6 -z ::1 $PORT)"; }; then | ||
READY=1; echo "Bridge ready on port $PORT"; break | ||
fi | ||
if docker logs unity-mcp 2>&1 | grep -qE "No valid Unity Editor license|Token not found in cache|com\.unity\.editor\.headless"; then | ||
echo "Licensing error detected"; break | ||
fi | ||
sleep 2 | ||
done | ||
kill $LOGPID || true | ||
if [ "$READY" != "1" ]; then | ||
echo "Bridge not ready; diagnostics:" | ||
echo "== status files =="; ls -la "$HOME/.unity-mcp" || true | ||
echo "== status contents =="; for f in "$HOME"/.unity-mcp/unity-mcp-status-*.json; do [ -f "$f" ] && { echo "--- $f"; sed -n '1,120p' "$f"; }; done | ||
echo "== sockets (inside container) =="; docker exec unity-mcp bash -lc 'ss -lntp || netstat -tulpen || true' | ||
echo "== tail of Unity log ==" | ||
docker logs --tail 200 unity-mcp | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' || true | ||
exit 1 | ||
fi | ||
# ---------- MCP client config ---------- | ||
- name: Write MCP config (.claude/mcp.json) | ||
run: | | ||
set -eux | ||
mkdir -p .claude | ||
cat > .claude/mcp.json <<JSON | ||
{ | ||
"mcpServers": { | ||
"unity": { | ||
"command": "python", | ||
"args": ["UnityMcpBridge/UnityMcpServer~/src/server.py"] | ||
"command": "uv", | ||
"args": ["run","--active","--directory","UnityMcpBridge/UnityMcpServer~/src","python","server.py"], | ||
"transport": { "type": "stdio" }, | ||
"env": { | ||
"PYTHONUNBUFFERED": "1", | ||
"MCP_LOG_LEVEL": "debug", | ||
"UNITY_PROJECT_ROOT": "$GITHUB_WORKSPACE/TestProjects/UnityMCPTests" | ||
} | ||
} | ||
} | ||
} | ||
# Guardrails | ||
model: "claude-3-7-sonnet-20250219" | ||
max_turns: "10" | ||
timeout_minutes: "20" | ||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} | ||
|
||
- name: Upload JUnit (Claude NL/T) | ||
if: always() | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: claude-nl-tests | ||
path: reports/claude-nl-tests.xml | ||
if-no-files-found: ignore | ||
|
||
- name: Annotate PR with test results (Claude NL/T) | ||
if: always() | ||
uses: dorny/test-reporter@v1 | ||
with: | ||
name: Claude NL/T | ||
path: reports/claude-nl-tests.xml | ||
reporter: java-junit | ||
fail-on-empty: false | ||
|
||
# Detect secrets + project/package mode WITHOUT using secrets in `if:` | ||
- name: Detect Unity mode & secrets | ||
id: detect | ||
env: | ||
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} | ||
run: | | ||
if [ -n "$UNITY_LICENSE" ]; then echo "has_license=true" >> "$GITHUB_OUTPUT"; else echo "has_license=false" >> "$GITHUB_OUTPUT"; fi | ||
if [ -f "ProjectSettings/ProjectVersion.txt" ]; then echo "is_project=true" >> "$GITHUB_OUTPUT"; else echo "is_project=false" >> "$GITHUB_OUTPUT"; fi | ||
if [ -f "Packages/manifest.json" ] && [ ! -f "ProjectSettings/ProjectVersion.txt" ]; then echo "is_package=true" >> "$GITHUB_OUTPUT"; else echo "is_package=false" >> "$GITHUB_OUTPUT"; fi | ||
# --- Optional: Unity compile after Claude’s edits (satisfies NL-4) --- | ||
- name: Unity compile (Project) | ||
if: always() && steps.detect.outputs.has_license == 'true' && steps.detect.outputs.is_project == 'true' | ||
uses: game-ci/unity-test-runner@v4 | ||
env: | ||
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} | ||
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} | ||
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} | ||
with: | ||
projectPath: . | ||
githubToken: ${{ secrets.GITHUB_TOKEN }} | ||
testMode: EditMode | ||
|
||
- name: Unity compile (Package) | ||
if: always() && steps.detect.outputs.has_license == 'true' && steps.detect.outputs.is_package == 'true' | ||
uses: game-ci/unity-test-runner@v4 | ||
env: | ||
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} | ||
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} | ||
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} | ||
with: | ||
packageMode: true | ||
unityVersion: 2022.3.45f1 # set your exact version | ||
projectPath: . | ||
githubToken: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
- name: Clean working tree (discard temp edits) | ||
if: always() | ||
run: | | ||
git restore -SW :/ | ||
git clean -fd | ||
JSON | ||
# ---------- Reports & helper ---------- | ||
- name: Prepare reports and dirs | ||
run: | | ||
set -eux | ||
rm -f reports/*.xml reports/*.md || true | ||
mkdir -p reports reports/_snapshots scripts | ||
- name: Create report skeletons | ||
run: | | ||
set -eu | ||
cat > "$JUNIT_OUT" <<'XML' | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<testsuites><testsuite name="UnityMCP.NL-T" tests="1" failures="1" errors="0" skipped="0" time="0"> | ||
<testcase name="NL-Suite.Bootstrap" classname="UnityMCP.NL-T"> | ||
<failure message="bootstrap">Bootstrap placeholder; suite will append real tests.</failure> | ||
</testcase> | ||
</testsuite></testsuites> | ||
XML | ||
printf '# Unity NL/T Editing Suite Test Results\n\n' > "$MD_OUT" | ||
- name: Write safe revert helper (scripts/nlt-revert.sh) | ||
shell: bash | ||
run: | | ||
set -eux | ||
cat > scripts/nlt-revert.sh <<'BASH' | ||
#!/usr/bin/env bash | ||
set -euo pipefail | ||
sub="${1:-}"; target_rel="${2:-}"; snap="${3:-}" | ||
WS="${GITHUB_WORKSPACE:-$PWD}" | ||
ROOT="$WS/TestProjects/UnityMCPTests" | ||
t_abs="$(realpath -m "$WS/$target_rel")" | ||
s_abs="$(realpath -m "$WS/$snap")" | ||
if [[ "$t_abs" != "$ROOT/Assets/"* ]]; then | ||
echo "refuse: target outside allowed scope: $t_abs" >&2; exit 2 | ||
fi | ||
mkdir -p "$(dirname "$s_abs")" | ||
case "$sub" in | ||
snapshot) | ||
cp -f "$t_abs" "$s_abs" | ||
sha=$(sha256sum "$s_abs" | awk '{print $1}') | ||
echo "snapshot_sha=$sha" | ||
;; | ||
restore) | ||
if [[ ! -f "$s_abs" ]]; then echo "snapshot missing: $s_abs" >&2; exit 3; fi | ||
cp -f "$s_abs" "$t_abs" | ||
touch "$t_abs" | ||
sha=$(sha256sum "$t_abs" | awk '{print $1}') | ||
echo "restored_sha=$sha" | ||
;; | ||
*) | ||
echo "usage: $0 snapshot|restore <target_rel_path> <snapshot_path>" >&2; exit 1 | ||
;; | ||
esac | ||
BASH | ||
chmod +x scripts/nlt-revert.sh | ||
# ---------- Run suite ---------- | ||
- name: Run Claude NL suite (single pass) | ||
uses: anthropics/claude-code-base-action@beta | ||
if: steps.detect.outputs.anthropic_ok == 'true' && steps.detect.outputs.unity_ok == 'true' | ||
continue-on-error: true | ||
with: | ||
use_node_cache: false | ||
prompt_file: .claude/prompts/nl-unity-suite-full.md | ||
mcp_config: .claude/mcp.json | ||
allowed_tools: >- | ||
Write, | ||
Bash(printf:*),Bash(echo:*),Bash(scripts/nlt-revert.sh:*), | ||
mcp__unity__manage_editor, | ||
mcp__unity__list_resources, | ||
mcp__unity__read_resource, | ||
mcp__unity__apply_text_edits, | ||
mcp__unity__script_apply_edits, | ||
mcp__unity__validate_script, | ||
mcp__unity__find_in_file, | ||
mcp__unity__read_console | ||
disallowed_tools: TodoWrite,Task | ||
model: claude-3-7-sonnet-latest | ||
timeout_minutes: "30" | ||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} | ||
|
||
# ---------- Merge testcase fragments into JUnit ---------- | ||
- name: Normalize/assemble JUnit in-place (single file) | ||
if: always() | ||
shell: bash | ||
run: | | ||
python3 - <<'PY' | ||
from pathlib import Path | ||
import xml.etree.ElementTree as ET | ||
import re, os | ||
def localname(tag: str) -> str: return tag.rsplit('}', 1)[-1] if '}' in tag else tag | ||
src = Path(os.environ.get('JUNIT_OUT', 'reports/junit-nl-suite.xml')) | ||
if not src.exists(): raise SystemExit(0) | ||
tree = ET.parse(src); root = tree.getroot() | ||
suite = root.find('./*') if localname(root.tag) == 'testsuites' else root | ||
if suite is None: raise SystemExit(0) | ||
fragments = sorted(Path('reports').glob('*_results.xml')) | ||
added = 0 | ||
for frag in fragments: | ||
try: | ||
froot = ET.parse(frag).getroot() | ||
if localname(froot.tag) == 'testcase': | ||
suite.append(froot); added += 1 | ||
else: | ||
for tc in froot.findall('.//testcase'): | ||
suite.append(tc); added += 1 | ||
except Exception: | ||
txt = Path(frag).read_text(encoding='utf-8', errors='replace') | ||
for m in re.findall(r'<testcase[\\s\\S]*?</testcase>', txt, flags=re.DOTALL): | ||
try: suite.append(ET.fromstring(m)); added += 1 | ||
except Exception: pass | ||
if added: | ||
# If we added real testcases, drop the bootstrap placeholder and recompute counts | ||
removed_bootstrap = 0 | ||
for tc in list(suite.findall('.//testcase')): | ||
name = (tc.get('name') or '') | ||
fail = tc.find('failure') | ||
if name == 'NL-Suite.Bootstrap' and (added > 0): | ||
suite.remove(tc) | ||
removed_bootstrap += 1 | ||
# Recompute suite attributes | ||
testcases = suite.findall('.//testcase') | ||
tests_cnt = len(testcases) | ||
failures_cnt = sum(1 for tc in testcases if (tc.find('failure') is not None or tc.find('error') is not None)) | ||
suite.set('tests', str(tests_cnt)) | ||
suite.set('failures', str(failures_cnt)) | ||
suite.set('errors', str(0)) | ||
suite.set('skipped', str(0)) | ||
tree.write(src, encoding='utf-8', xml_declaration=True) | ||
print(f"Added {added} testcase fragments, removed bootstrap={removed_bootstrap}, tests={tests_cnt}, failures={failures_cnt}") | ||
PY | ||
# ---------- Markdown summary from JUnit ---------- | ||
- name: Build markdown summary from JUnit | ||
if: always() | ||
shell: bash | ||
run: | | ||
python3 - <<'PY' | ||
import xml.etree.ElementTree as ET | ||
from pathlib import Path | ||
import os | ||
def localname(tag: str) -> str: return tag.rsplit('}', 1)[-1] if '}' in tag else tag | ||
src = Path(os.environ.get('JUNIT_OUT', 'reports/junit-nl-suite.xml')) | ||
md_out = Path(os.environ.get('MD_OUT', 'reports/junit-nl-suite.md')) | ||
if not src.exists(): | ||
md_out.write_text("# Unity NL/T Editing Suite Test Results\n\n(No JUnit found)\n", encoding='utf-8'); raise SystemExit(0) | ||
tree = ET.parse(src); root = tree.getroot() | ||
suite = root.find('./*') if localname(root.tag) == 'testsuites' else root | ||
cases = [] if suite is None else [tc for tc in suite.findall('.//testcase')] | ||
total = len(cases) | ||
failures = sum(1 for tc in cases if (tc.find('failure') is not None or tc.find('error') is not None)) | ||
passed = total - failures | ||
desired = ['NL-0','NL-1','NL-2','NL-3','NL-4','T-A','T-B','T-C','T-D','T-E','T-F','T-G','T-H','T-I','T-J'] | ||
name_to_case = {(tc.get('name') or ''): tc for tc in cases} | ||
def status_for(prefix: str): | ||
for name, tc in name_to_case.items(): | ||
if name.startswith(prefix): | ||
return not ((tc.find('failure') is not None) or (tc.find('error') is not None)) | ||
return None | ||
lines = [] | ||
lines += ['# Unity NL/T Editing Suite Test Results','',f'Totals: {passed} passed, {failures} failed, {total} total','', '## Test Checklist'] | ||
for p in desired: | ||
st = status_for(p) | ||
lines.append(f"- [x] {p}" if st is True else (f"- [ ] {p} (fail)" if st is False else f"- [ ] {p} (not run)")) | ||
lines.append('') | ||
# Rich per-test details (pull from <system-out>) | ||
lines.append('## Test Details') | ||
# Sort by canonical order where possible | ||
def order_key(n: str): | ||
try: | ||
if n.startswith('NL-') and n[3].isdigit(): | ||
return (0, int(n.split('.')[0].split('-')[1])) | ||
except Exception: | ||
pass | ||
if n.startswith('T-') and len(n)>2 and n[2].isalpha(): | ||
return (1, ord(n[2])) | ||
return (2, n) | ||
for name in sorted(name_to_case.keys(), key=order_key): | ||
tc = name_to_case[name] | ||
so = tc.find('system-out') | ||
text = '' if so is None or so.text is None else so.text | ||
text = text.replace('\r\n','\n') | ||
# Trim overly long outputs | ||
MAX_CHARS = 2000 | ||
if len(text) > MAX_CHARS: | ||
text = text[:MAX_CHARS] + "\n…(truncated)" | ||
lines.append(f"### {name}") | ||
if text.strip(): | ||
lines.append('```') | ||
lines.append(text.strip()) | ||
lines.append('```') | ||
else: | ||
lines.append('(no system-out)') | ||
lines.append('') | ||
for name, tc in name_to_case.items(): | ||
node = tc.find('failure') or tc.find('error') | ||
if node is None: continue | ||
msg = (node.get('message') or '').strip() | ||
text = (node.text or '').strip() | ||
lines.append(f"### {name}") | ||
if msg: lines.append(f"- Message: {msg}") | ||
if text: lines.append(f"- Detail: {text.splitlines()[0][:500]}") | ||
lines.append('') | ||
md_out.write_text('\n'.join(lines), encoding='utf-8') | ||
PY | ||
- name: "Debug: list report files" | ||
if: always() | ||
shell: bash | ||
run: | | ||
set -eux | ||
ls -la reports || true | ||
shopt -s nullglob | ||
for f in reports/*.xml; do | ||
echo "===== $f =====" | ||
head -n 40 "$f" || true | ||
done | ||
# ---------- Collect execution transcript (if present) ---------- | ||
- name: Collect action execution transcript | ||
if: always() | ||
shell: bash | ||
run: | | ||
set -eux | ||
if [ -f "$RUNNER_TEMP/claude-execution-output.json" ]; then | ||
cp "$RUNNER_TEMP/claude-execution-output.json" reports/claude-execution-output.json | ||
elif [ -f "/home/runner/work/_temp/claude-execution-output.json" ]; then | ||
cp "/home/runner/work/_temp/claude-execution-output.json" reports/claude-execution-output.json | ||
fi | ||
- name: Sanitize markdown (normalize newlines) | ||
if: always() | ||
run: | | ||
set -eu | ||
python - <<'PY' | ||
from pathlib import Path | ||
rp=Path('reports'); rp.mkdir(parents=True, exist_ok=True) | ||
for p in rp.glob('*.md'): | ||
b=p.read_bytes().replace(b'\x00', b'') | ||
s=b.decode('utf-8','replace').replace('\r\n','\n') | ||
p.write_text(s, encoding='utf-8', newline='\n') | ||
PY | ||
- name: NL/T details → Job Summary | ||
if: always() | ||
run: | | ||
echo "## Unity NL/T Editing Suite — Summary" >> $GITHUB_STEP_SUMMARY | ||
python - <<'PY' >> $GITHUB_STEP_SUMMARY | ||
from pathlib import Path | ||
p = Path('reports/junit-nl-suite.md') | ||
if p.exists(): | ||
text = p.read_bytes().decode('utf-8', 'replace') | ||
MAX = 65000 | ||
print(text[:MAX]) | ||
if len(text) > MAX: | ||
print("\n\n_…truncated; full report in artifacts._") | ||
else: | ||
print("_No markdown report found._") | ||
PY | ||
- name: Fallback JUnit if missing | ||
if: always() | ||
run: | | ||
set -eu | ||
mkdir -p reports | ||
if [ ! -f "$JUNIT_OUT" ]; then | ||
printf '%s\n' \ | ||
'<?xml version="1.0" encoding="UTF-8"?>' \ | ||
'<testsuite name="UnityMCP.NL-T" tests="1" failures="1" time="0">' \ | ||
' <testcase classname="UnityMCP.NL-T" name="NL-Suite.Execution" time="0.0">' \ | ||
' <failure><![CDATA[No JUnit was produced by the NL suite step. See the step logs.]]></failure>' \ | ||
' </testcase>' \ | ||
'</testsuite>' \ | ||
> "$JUNIT_OUT" | ||
fi | ||
- name: Publish JUnit report | ||
if: always() | ||
uses: mikepenz/action-junit-report@v5 | ||
with: | ||
report_paths: '${{ env.JUNIT_OUT }}' | ||
include_passed: true | ||
detailed_summary: true | ||
annotate_notice: true | ||
require_tests: false | ||
fail_on_parse_error: true | ||
|
||
- name: Upload artifacts (reports + fragments + transcript) | ||
if: always() | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: claude-nl-suite-artifacts | ||
path: | | ||
${{ env.JUNIT_OUT }} | ||
${{ env.MD_OUT }} | ||
reports/*_results.xml | ||
reports/claude-execution-output.json | ||
retention-days: 7 | ||
|
||
# ---------- Always stop Unity ---------- | ||
- name: Stop Unity | ||
if: always() | ||
run: | | ||
docker logs --tail 400 unity-mcp | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' || true | ||
docker rm -f unity-mcp || true | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Strip trailing spaces and ensure newline at EOF.
Several lines carry trailing spaces; no newline at EOF. Clean to satisfy actionlint/YAMLlint.
Run:
🏁 Script executed:
#!/bin/bash
yamllint -f parsable .github/workflows/claude-nl-suite.yml || true
sed -n '1,999p' .github/workflows/claude-nl-suite.yml | nl -ba | sed -n '1,120p'
Length of output: 11004
Fix YAML lint errors in .github/workflows/claude-nl-suite.yml
- Add the missing document start marker (
---
) at the top of the file. - Replace truthy values (
{}
) with valid YAML booleans (true
/false
). - Correct indentation throughout (e.g. around jobs/steps definitions).
- Remove all trailing spaces.
- Ensure the file ends with a single newline.
🧰 Tools
🪛 YAMLlint (1.37.1)
[error] 5-5: trailing spaces
(trailing-spaces)
[error] 9-9: trailing spaces
(trailing-spaces)
[error] 13-13: trailing spaces
(trailing-spaces)
[error] 18-18: trailing spaces
(trailing-spaces)
[warning] 21-21: wrong indentation: expected 8 but found 6
(indentation)
[warning] 25-25: wrong indentation: expected 10 but found 8
(indentation)
[warning] 26-26: too many spaces after colon
(colons)
[error] 27-27: trailing spaces
(trailing-spaces)
[warning] 30-30: wrong indentation: expected 10 but found 8
(indentation)
[warning] 33-33: wrong indentation: expected 14 but found 12
(indentation)
[warning] 33-33: too many spaces after colon
(colons)
[warning] 34-34: too many spaces after colon
(colons)
[warning] 36-36: too many spaces after colon
(colons)
[error] 46-46: trailing spaces
(trailing-spaces)
[warning] 49-49: wrong indentation: expected 14 but found 12
(indentation)
[error] 50-50: trailing spaces
(trailing-spaces)
[warning] 54-54: wrong indentation: expected 14 but found 12
(indentation)
[error] 55-55: trailing spaces
(trailing-spaces)
[error] 73-73: trailing spaces
(trailing-spaces)
[warning] 79-79: wrong indentation: expected 14 but found 12
(indentation)
[warning] 79-79: too many spaces after colon
(colons)
[warning] 80-80: too many spaces after colon
(colons)
[warning] 82-82: too many spaces after colon
(colons)
[warning] 84-84: wrong indentation: expected 14 but found 12
(indentation)
[error] 88-88: trailing spaces
(trailing-spaces)
[error] 95-95: trailing spaces
(trailing-spaces)
[error] 102-102: trailing spaces
(trailing-spaces)
[warning] 107-107: wrong indentation: expected 14 but found 12
(indentation)
[warning] 107-107: too many spaces after colon
(colons)
[warning] 109-109: too many spaces after colon
(colons)
[error] 139-139: trailing spaces
(trailing-spaces)
[error] 179-179: trailing spaces
(trailing-spaces)
[error] 201-201: trailing spaces
(trailing-spaces)
[error] 208-208: trailing spaces
(trailing-spaces)
[error] 221-221: trailing spaces
(trailing-spaces)
[error] 257-257: trailing spaces
(trailing-spaces)
[warning] 264-264: wrong indentation: expected 14 but found 12
(indentation)
[error] 282-282: trailing spaces
(trailing-spaces)
[error] 333-333: trailing spaces
(trailing-spaces)
[error] 407-407: trailing spaces
(trailing-spaces)
[error] 419-419: trailing spaces
(trailing-spaces)
[error] 431-431: trailing spaces
(trailing-spaces)
[error] 444-444: trailing spaces
(trailing-spaces)
[error] 461-461: trailing spaces
(trailing-spaces)
[error] 477-477: trailing spaces
(trailing-spaces)
[warning] 482-482: wrong indentation: expected 14 but found 12
(indentation)
[error] 488-488: trailing spaces
(trailing-spaces)
[warning] 493-493: wrong indentation: expected 14 but found 12
(indentation)
[error] 500-500: trailing spaces
(trailing-spaces)
[error] 507-507: no new line character at the end of file
(new-line-at-end-of-file)
[error] 507-507: trailing spaces
(trailing-spaces)
🤖 Prompt for AI Agents
In .github/workflows/claude-nl-suite.yml (lines 1-507): the file is failing YAML
lint due to a missing document start marker, use of {} where booleans are
required, inconsistent indentation and trailing spaces, and missing final
newline; fix by (1) add a top-line document marker ---, (2) replace occurrences
of {} used as truthy values (e.g. workflow_dispatch: {}) with explicit YAML
booleans (workflow_dispatch: true or false as appropriate), (3) correct
indentation under top-level keys (on permissions, concurrency, env, jobs, and
every jobs.*.steps block) so sequences and mappings follow YAML rules, (4)
remove all trailing spaces and ensure consistent indentation (2 spaces per level
or match repository style), and (5) ensure the file ends with exactly one
newline character.
TL;DR
This PR hardens the transport with explicit framing + timeouts/retries, upgrades the editing surface for Claude (micro‑edits and resource read/search), and adds an end‑to‑end natural‑language (NL) test harness that drives a live Unity instance from CI and reports JUnit/Markdown artifacts suitable for Actions. (+6,962/−741 over 47 files.) ([GitHub]1)
Why this matters
Highlights (compared to
main
)1) Robust framing of messages (with testing)
FRAMING=1
handshake; non‑blocking script writes; TCPNoDelay
; timeouts and retries on reads/writes. Caps frames at 64 MiB and rejects zero‑length frames. ([GitHub]1)test_unity_socket_framing.py
. ([GitHub]1)2) Claude‑friendly editing tools + resource reading
apply_text_edits
(with precondition hashes and atomic multi‑edit batches) andscript_apply_edits
for structured C# edits;validate_script
to catch syntax issues before writes. ([GitHub]2)list_resources
,read_resource
, andfind_in_file
enable read‑first plans and targeted diffs. ([GitHub]3)manage_script
paths stay for compatibility while read/update/edit flavors are de‑emphasized. ([GitHub]1)3) New end‑to‑end NL testing CI (client prompts → Unity → back)
…manage_editor, …list_resources, …read_resource, …apply_text_edits, …script_apply_edits, …validate_script, …find_in_file
+ minimal Bash). ([GitHub]3)FRAMING=1
preamble before tests proceed. ([GitHub]1)reports/junit-for-actions.xml
) and a Markdown summary; usesmikepenz/action-junit-report@v5
. ([GitHub]3)What changed (selected)
Transport & bridge
ReadExact
with timeouts/retries; 64 MiB frame cap; rejects zero‑length frames; non‑blocking script writes;NoDelay
on sockets. ([GitHub]1)Server & tools
apply_text_edits
/script_apply_edits
; addlist_resources
/read_resource
; improve method‑span parsing and validation flows to reduce false negatives. ([GitHub]1)Tests
CI
.github/workflows/claude-nl-suite.yml
switched to a mini NL prompt; honorsJUNIT_OUT
/MD_OUT
; normalizes toreports/junit-for-actions.xml
; publishes via action‑junit‑report v5; adds summary to the job page. ([GitHub]3)How to verify
A) In CI (recommended)
Run “Claude NL Test Suite (mini)” on this branch. (Requires an
ANTHROPIC_API_KEY
in your GH secrets)Confirm the steps:
FRAMING=1
and the suite proceeds. ([GitHub]1)reports/junit-for-actions.xml
is published and annotated by the JUnit action. ([GitHub]3)B) Locally (quick check)
test_unity_socket_framing.py
assertions for boundary and preamble checks. ([GitHub]2)apply_text_edits
orscript_apply_edits
on a small C# file, then callvalidate_script
andread_resource
to confirm read‑write‑re‑read flows. ([GitHub]2)Backwards compatibility
manage_script
remains available; the NL suite and docs steer tooling toward micro‑edits and resource‑first reads. No public API breaks are expected for existing automations. ([GitHub]1)Risks
FRAMING=1
and proper lengths. The NL suite explicitly verifies this path. ([GitHub]1)Follow‑ups
Change map (at a glance)
Summary by CodeRabbit
New Features
Improvements
Documentation
Tests
Chores