{"id":"02376a77-2667-4f0b-96bb-216809ce5095","slug":"windows-compatibility","kind":"skill","name":"windows-compatibility","summary":"Cross-platform path handling and command patterns","owner":"github","repoUrl":"https://github.com/github/gh-aw/tree/HEAD/.squad/templates/skills/windows-compatibility","license":"MIT","licenseTier":"permissive","trust":"official","stars":5390,"match":null,"fewStars":false,"format":"skill","createdAt":null,"addedAt":"2026-10-14T05:40:47.349Z","logoUrl":"https://avatars.githubusercontent.com/u/9919?v=4","linkOnly":false,"collection":{"name":"gh-aw","repo":"github/gh-aw"},"skillPath":".squad/templates/skills/windows-compatibility","categories":["developer-tools"],"tags":["gh-extension","actions","cai","ci","claude-code","codex","copilot","github-actions"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-14T05:40:47.347Z","sample":false,"url":"https://conduits.dev/tools/windows-compatibility","language":"Go","transports":[],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"## Context\n\nSquad runs on Windows, macOS, and Linux. Several bugs have been traced to platform-specific assumptions: ISO timestamps with colons (illegal on Windows), `git -C` with Windows paths (unreliable), forward-slash paths in Node.js on Windows.\n\n## Patterns\n\n### Filenames & Timestamps\n- **Never use colons in filenames:** ISO 8601 format `2026-03-15T05:30:00Z` is illegal on Windows\n- **Use `safeTimestamp()` utility:** Replaces colons with hyphens → `2026-03-15T05-30-00Z`\n- **Centralize formatting:** Don't inline `.toISOString().replace(/:/g, '-')` — use the utility\n\n### Git Commands\n- **Never use `git -C {path}`:** Unreliable with Windows paths (backslashes, spaces, drive letters)\n- **Always `cd` first:** Change directory, then run git commands\n- **Check for changes before commit:** `git diff --cached --quiet` (exit 0 = no changes)\n\n### Commit Messages\n- **Never embed newlines in `-m` flag:** Backtick-n (`\\n`) fails silently in PowerShell\n- **Use temp file + `-F` flag:** Write message to file, commit with `git commit -F $msgFile`\n\n### Paths\n- **Never assume CWD is repo root:** Always use `TEAM ROOT` from spawn prompt or run `git rev-parse --show-toplevel`\n- **Use path.join() or path.resolve():** Don't manually concatenate with `/` or `\\`\n\n### Path Comparison (Case Sensitivity)\n- **Never use case-sensitive `startsWith` or `===` for path comparison on Windows or macOS:** These filesystems are case-insensitive — `C:\\Users\\` and `c:\\users\\` refer to the same location\n- **Use platform-aware comparison:** Check `process.platform === 'win32' || process.platform === 'darwin'` and lowercase both sides before comparing\n- **Pattern:**\n  ```typescript\n  const CASE_INSENSITIVE = process.platform === 'win32' || process.platform === 'darwin';\n  \n  function pathStartsWith(fullPath: string, prefix: string): boolean {\n    if (CASE_INSENSITIVE) {\n      return fullPath.toLowerCase().startsWith(prefix.toLowerCase());\n    }\n    return fullPath.startsWith(prefix);\n  }\n  ```\n- **Where it matters:** Security checks (path traversal prevention), rootDir confinement, any path-contains-path validation\n- **Linux is case-sensitive:** Do NOT lowercase on Linux — `/Home/` and `/home/` are different directories\n\n## Examples\n\n✓ **Correct:**\n```javascript\n// Timestamp utility\nconst safeTimestamp = () => new Date().toISOString().replace(/:/g, '-').split('.')[0] + 'Z';\n\n// Git workflow (PowerShell)\ncd $teamRoot\ngit add .squad/\nif ($LASTEXITCODE -eq 0) {\n  $msg = @\"\ndocs(ai-team): session log\n\nChanges:\n- Added decisions\n\"@\n  $msgFile = [System.IO.Path]::GetTempFileName()\n  Set-Content -Path $msgFile -Value $msg -Encoding utf8\n  git commit -F $msgFile\n  Remove-Item $msgFile\n}\n```\n\n✗ **Incorrect:**\n```javascript\n// Colon in filename\nconst logPath = `.squad/log/${new Date().toISOString()}.md`; // ILLEGAL on Windows\n\n// git -C with Windows path\nexec('git -C C:\\\\src\\\\squad add .squad/'); // UNRELIABLE\n\n// Inline newlines in commit message\nexec('git commit -m \"First line\\nSecond line\"'); // FAILS silently in PowerShell\n```\n\n## Anti-Patterns\n\n- Testing only on one platform (bugs ship to other platforms)\n- Assuming Unix-style paths work everywhere\n- Using `git -C` because it \"looks cleaner\" (it doesn't work)\n- Skipping `git diff --cached --quiet` check (creates empty commits)\n- **Wrong — case-sensitive path check on Windows and macOS:**\n  ```typescript\n  if (!resolved.startsWith(rootDir + path.sep)) {\n    throw new Error('Path traversal blocked');\n  }\n  // Fails: 'c:\\\\Users\\\\temp\\\\file'.startsWith('C:\\\\Users\\\\temp\\\\') → false\n  ```"}