CR

cross-platform-paths

Best practices for writing platform-agnostic file path code in TypeScript.

Install

mkdir -p .claude/skills/cross-platform-paths && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/15874" && unzip -o skill.zip -d .claude/skills/cross-platform-paths && rm skill.zip

Installs to .claude/skills/cross-platform-paths

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Critical patterns for cross-platform path handling in this VS Code extension. Windows vs POSIX path bugs are the #1 source of issues. Use this skill when reviewing or writing path-related code.
193 chars✓ has a “when” trigger
Beginner

Key capabilities

  • Concatenate paths using `path.join()`
  • Resolve paths for comparison with `path.resolve()`
  • Use `Uri.file().fsPath` for VS Code paths
  • Get platform-specific home directory
  • Quote paths for shell commands

How it works

The skill provides rules and examples for handling file paths to ensure compatibility across Windows, macOS, and Linux environments.

Inputs & outputs

You give it
File path or path segments
You get back
Correctly formatted and resolved cross-platform path

When to use cross-platform-paths

  • Review path logic
  • Fix Windows path bugs
  • Compare file system paths

About this skill

Cross-Platform Path Handling

CRITICAL: This extension runs on Windows, macOS, and Linux. Path bugs are the #1 source of issues.

Core Rules

Rule 1: Never Concatenate Paths with /

// ❌ WRONG: POSIX-style path concatenation
const envPath = homeDir + '/.venv/bin/python';

// ✅ RIGHT: Use path.join()
const envPath = path.join(homeDir, '.venv', 'bin', 'python');

Rule 2: Use path.resolve() for Comparisons, Not path.normalize()

// ❌ WRONG: path.normalize keeps relative paths relative on Windows
const normalized = path.normalize(fsPath);
// path.normalize('\test') → '\test' (still relative!)

// ✅ RIGHT: path.resolve adds drive letter on Windows
const normalized = path.resolve(fsPath);
// path.resolve('\test') → 'C:\test' (absolute!)

// When comparing paths, use resolve() on BOTH sides:
const pathA = path.resolve(fsPath);
const pathB = path.resolve(e.environmentPath.fsPath);
return pathA === pathB;

Rule 3: Use Uri.file().fsPath for VS Code Paths

// ❌ WRONG: Raw string comparison
if (filePath === otherPath) {
}

// ✅ RIGHT: Compare fsPath to fsPath
import { Uri } from 'vscode';
const fsPathA = Uri.file(pathA).fsPath;
const fsPathB = Uri.file(pathB).fsPath;
if (fsPathA === fsPathB) {
}

Platform-Specific Gotchas

Windows

IssueDetails
Drive lettersPaths start with C:\, D:\, etc.
BackslashesSeparator is \, not /
Case insensitivityC:\Test equals c:\test
Long pathsPaths >260 chars may fail
Mapped drivesZ:\ may not be accessible
pyenv-winUses pyenv.bat, not pyenv or pyenv.exe
Poetry cache%LOCALAPPDATA%\pypoetry\Cache\virtualenvs
UNC paths\\server\share\ format

macOS

IssueDetails
Case sensitivityDepends on filesystem (usually insensitive)
Homebrew symlinksComplex symlink chains in /opt/homebrew/
Poetry cache~/Library/Caches/pypoetry/virtualenvs
XCode PythonDifferent from Command Line Tools Python

Linux

IssueDetails
Case sensitivityPaths ARE case-sensitive
/bin symlinks/bin may be symlink to /usr/bin
XDG directories~/.local/share/virtualenvs for pipenv
Poetry cache~/.cache/pypoetry/virtualenvs
Hidden filesDot-prefixed files are hidden

Common Patterns

Getting Platform-Specific Paths

import * as os from 'os';
import * as path from 'path';

// Home directory
const home = os.homedir(); // Works cross-platform

// Construct paths correctly
const venvPath = path.join(home, '.venv', 'bin', 'python');
// Windows: C:\Users\name\.venv\bin\python
// macOS:   /Users/name/.venv/bin/python
// Linux:   /home/name/.venv/bin/python

Environment-Specific Executable Names

const isWindows = process.platform === 'win32';

// Python executable
const pythonExe = isWindows ? 'python.exe' : 'python';

// Activate script
const activateScript = isWindows
    ? path.join(venvPath, 'Scripts', 'activate.bat')
    : path.join(venvPath, 'bin', 'activate');

// pyenv command
const pyenvCmd = isWindows ? 'pyenv.bat' : 'pyenv';

Normalizing Paths for Comparison

import { normalizePath } from './common/utils/pathUtils';

// Use normalizePath() for map keys and comparisons
const key = normalizePath(filePath);
cache.set(key, value);

// But preserve original for user display
traceLog(`Discovered: ${filePath}`); // Keep original

Handling Uri | string Union Types

// ❌ WRONG: Assuming Uri
function process(locator: Uri | string) {
    const fsPath = locator.fsPath; // Crashes if string!
}

// ✅ RIGHT: Handle both types
function process(locator: Uri | string) {
    const fsPath = locator instanceof Uri ? locator.fsPath : locator;

    // Now normalize for comparisons
    const normalized = path.resolve(fsPath);
}

File Existence Checks

import * as fs from 'fs';
import * as path from 'path';

// Check file exists (cross-platform)
const configPath = path.join(projectRoot, 'pyproject.toml');
if (fs.existsSync(configPath)) {
    // File exists
}

// Use async version when possible
import { promises as fsPromises } from 'fs';
try {
    await fsPromises.access(configPath);
    // File exists
} catch {
    // File does not exist
}

Shell Path Escaping

// ❌ WRONG: Unescaped paths in shell commands
terminal.sendText(`python ${filePath}`);
// D:\path\file.py becomes "D:pathfile.py" in some shells!

// ✅ RIGHT: Quote paths
terminal.sendText(`python "${filePath}"`);

// For Git Bash on Windows, escape backslashes
const shellPath = isGitBash ? filePath.replace(/\\/g, '/') : filePath;

Testing Cross-Platform Code

When testing path-related code:

  1. Test on Windows (cmd, PowerShell, Git Bash)
  2. Test on macOS (zsh, bash)
  3. Test on Linux (bash, fish)

Pay special attention to:

  • Paths with spaces: C:\Program Files\Python
  • Paths with Unicode: ~/проекты/
  • Very long paths (>260 chars on Windows)
  • Paths with special characters: $, &, (, )

When not to use it

  • When concatenating paths with `/`
  • When using `path.normalize()` for comparisons
  • When comparing raw string paths directly

Limitations

  • Prohibits concatenating paths with `/`
  • Requires `path.resolve()` for path comparisons
  • Requires `Uri.file().fsPath` for VS Code path comparisons

How it compares

This skill enforces specific path manipulation functions and patterns to avoid common cross-platform path bugs, unlike generic string operations.

Compared to similar skills

cross-platform-paths side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
cross-platform-paths (this skill)06moNo flagsBeginner
effect-patterns-error-handling17moNo flagsAdvanced
effect-patterns-scheduling17moNo flagsBeginner
nextjs-server-side-error-debugging17moReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

More by microsoft

View all by microsoft

You might also like

effect-patterns-error-handling

PaulJPhilp

Effect-TS patterns for Error Handling. Use when working with error handling in Effect-TS applications.

12

effect-patterns-scheduling

PaulJPhilp

Effect-TS patterns for Scheduling. Use when working with scheduling in Effect-TS applications.

12

nextjs-server-side-error-debugging

blader

Debug getServerSideProps and getStaticProps errors in Next.js. Use when: (1) Page shows generic error but browser console is empty, (2) API routes return 500 with no details, (3) Server-side code fails silently, (4) Error only occurs on refresh not client navigation. Check terminal/server logs instead of browser for actual error messages.

11

typescript-node-esm-compiler-runtime

GonkaGate

Own TypeScript plus Node.js ESM compiler/runtime correctness. Use whenever the real question is why TypeScript compiles but Node fails, how `tsconfig`/`package.json`/entrypoint/runtime mode must align, whether relative imports should use `.js` or `.ts`, how `nodenext`/`node20`/`verbatimModuleSyntax`

00

supabase-developer

daffy0208

Build full-stack applications with Supabase (PostgreSQL, Auth, Storage, Real-time, Edge Functions). Use when implementing authentication, database design with RLS, file storage, real-time features, or serverless functions.

95185

payload

payloadcms

Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks, access control, Payload API). Use when debugging validation errors, security issues, relationship queries, transactions, or hook behavior.

73206

Search skills

Search the agent skills registry