aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CLAUDE.md115
1 files changed, 115 insertions, 0 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index 45a9bddce..759f85768 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -310,3 +310,118 @@ When debugging zenserver-test or other multi-process scenarios, use child proces
xmake bundle
```
+
+## Windows Scripting and File Editing
+
+### Available scripting runtimes
+
+- **PowerShell** - always available; preferred for file inspection and manipulation
+- **Node.js** - available; use for complex text transformations
+- **python3** - NOT available (`python3` opens Microsoft Store; use PowerShell or Node.js instead)
+- **git** - use `git -C <path>` rather than `cd <path> && git`; the `cd` compound form triggers a hardcoded security prompt
+
+### Edit tool and tab characters
+
+Source files use real tab characters (`\t`). The Edit tool does exact string matching, so a match failure is almost always a whitespace mismatch. Before retrying a failed edit:
+
+1. Use Grep with `output_mode: "content"` to read the exact lines from the file.
+2. Copy the literal text from the Grep output (including tabs) into `old_string`.
+3. Never type spaces where the file has tabs, or vice versa.
+
+To inspect exact bytes on specific lines (useful when Grep output is ambiguous):
+
+```powershell
+$lines = [System.IO.File]::ReadAllText('file.cpp') -split '\r?\n'
+for ($i = 4515; $i -le 4520; $i++) {
+ Write-Host "$($i+1): $([System.Text.RegularExpressions.Regex]::Escape($lines[$i]))"
+}
+```
+
+For large or complex edits where tab/whitespace issues are likely (e.g. replacing multi-line blocks), use PowerShell string replacement instead of the Edit tool:
+
+```powershell
+# Read file, replace, write back (preserves encoding)
+$text = [System.IO.File]::ReadAllText('path\to\file.cpp')
+$text = $text.Replace('old string with `t tabs', 'new string with `t tabs')
+[System.IO.File]::WriteAllText('path\to\file.cpp', $text)
+```
+
+### PowerShell string literals and tabs
+
+In PowerShell double-quoted strings, `\t` is a **literal backslash-t**, not a tab character.
+Use `` `t `` (backtick-t) for actual tab characters:
+
+```powershell
+$line = "`t`treturn Result;" # two tabs then text - correct
+$line = "\t\treturn Result;" # WRONG - produces backslash-t literally
+```
+
+### PowerShell file replacement
+
+`$text.Replace()` replaces **every** occurrence in the file. Always check the match count first:
+
+```powershell
+$matches = [regex]::Matches($text, [regex]::Escape($old))
+if ($matches.Count -ne 1) { Write-Host "ERROR: $($matches.Count) occurrences found"; exit 1 }
+$text = $text.Replace($old, $new)
+```
+
+For patterns that are inherently non-unique, add surrounding context lines to make `$old` unique.
+When variable amounts of tabs/spaces appear between tokens, use `\s+` in `-replace` patterns instead:
+
+```powershell
+$text = $text -replace 'RemoteProjectStore::Result \w+\s*=\s*LoadOplog\(', 'LoadOplog('
+```
+
+### Write complex content to files - never inline into bash or PowerShell strings
+
+Any content that would require multi-level escaping should be written to a file with the Write tool
+rather than embedded inline. Two common cases:
+
+**PowerShell scripts**: Never pass complex PS via `powershell.exe -Command "..."` from bash, and
+never use `-File -` with a bash heredoc. Bash interprets PowerShell's backtick `` ` `` as command
+substitution and `[...]` as globs, causing parse errors or hangs. Instead:
+
+```bash
+# Write the .ps1 with the Write tool, then:
+powershell.exe -NoProfile -ExecutionPolicy Bypass -File D:/path/to/script.ps1
+rm D:/path/to/script.ps1
+```
+
+**C++ template content**: C++ code with `$`, `{}`, or `()` causes silent interpolation or parser
+errors inside PowerShell double-quoted strings. Write it to a template file with the Write tool
+instead, then read it back:
+
+```powershell
+$template = [System.IO.File]::ReadAllText('D:/path/to/template.cpp')
+$template = $template -replace '(?<!\r)\n', "`r`n" # normalise LF → CRLF
+$template = $template.TrimEnd("`r", "`n")
+# Now splice $template into $text at the desired position
+```
+
+### Code Coverage with OpenCppCoverage
+
+OpenCppCoverage is installed at `C:\Program Files\OpenCppCoverage\OpenCppCoverage.exe`.
+Run from the **project root** after a debug build (tests only exist in debug mode).
+
+The debug binaries are ASAN-instrumented and require the ASAN runtime DLL to be in PATH.
+Use a `.ps1` script so the DLL path is set before launching the tool:
+
+```powershell
+# run_coverage.ps1
+Set-Location D:\github\ue-foundation\zen
+$asanDir = 'C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.44.35207\bin\Hostx64\x64'
+$env:PATH = "$asanDir;$env:PATH"
+$cov = 'C:\Program Files\OpenCppCoverage\OpenCppCoverage.exe'
+$bin = 'build\windows\x64\debug\zenremotestore-test.exe'
+& $cov --sources="src\zenremotestore\projectstore" --export_type="html:coverage-report" -- $bin
+```
+
+Run it with:
+```powershell
+powershell.exe -NoProfile -ExecutionPolicy Bypass -File run_coverage.ps1
+```
+
+Open `coverage-report\index.html` in a browser for line-level detail.
+Uncovered lines are highlighted red (`background-color:#fdd` in the HTML source).
+The `--sources` path must point to the specific subdirectory (not the module root) or no files are matched.