From harness-claude
Performs file system operations using fs.promises, path utilities, and file watching. Useful for reading, writing, manipulating files/directories, and watching file changes.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:node-path-fs-patternsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Perform file system operations correctly using fs.promises, path utilities, and file watching
Perform file system operations correctly using fs.promises, path utilities, and file watching
fs/promises for async operations:import { readFile, writeFile, mkdir, readdir, stat, rm } from 'node:fs/promises';
import { join } from 'node:path';
const content = await readFile(join(dir, 'data.json'), 'utf-8');
const data = JSON.parse(content);
path.join and path.resolve:import { join, resolve, basename, dirname, extname } from 'node:path';
join('src', 'utils', 'helper.ts'); // 'src/utils/helper.ts'
resolve('src', 'utils'); // '/absolute/path/to/src/utils'
basename('/path/to/file.ts'); // 'file.ts'
basename('/path/to/file.ts', '.ts'); // 'file'
dirname('/path/to/file.ts'); // '/path/to'
extname('file.test.ts'); // '.ts'
Never concatenate paths with string templates — use join() for OS-safe separators.
await mkdir(join(outputDir, 'images', 'thumbnails'), { recursive: true });
import { writeFile, rename } from 'node:fs/promises';
async function writeFileAtomic(filePath: string, content: string) {
const tempPath = `${filePath}.tmp`;
await writeFile(tempPath, content, 'utf-8');
await rename(tempPath, filePath); // Atomic on most file systems
}
import { access, constants } from 'node:fs/promises';
async function fileExists(path: string): Promise<boolean> {
try {
await access(path, constants.F_OK);
return true;
} catch {
return false;
}
}
import { readdir } from 'node:fs/promises';
const files = await readdir(srcDir, { recursive: true, withFileTypes: true });
const tsFiles = files
.filter((f) => f.isFile() && f.name.endsWith('.ts'))
.map((f) => join(f.parentPath, f.name));
import { watch } from 'node:fs/promises';
const watcher = watch(srcDir, { recursive: true });
for await (const event of watcher) {
console.log(`${event.eventType}: ${event.filename}`);
}
import { createReadStream, createWriteStream } from 'node:fs';
import { pipeline } from 'node:stream/promises';
await pipeline(
createReadStream('large-input.csv'),
transformStream,
createWriteStream('output.csv')
);
rm:await rm(tempDir, { recursive: true, force: true });
node:fs/promises provides Promise-based file system operations. Always prefer it over the callback-based fs and the synchronous fs.*Sync variants.
readFile vs createReadStream: Use readFile for files under ~50MB that you need in memory. Use createReadStream for larger files or when you can process data incrementally.
recursive: true: Available on mkdir (create nested directories), readdir (list all descendants), rm (delete directory trees), and watch (monitor subdirectories). Node.js 20+ supports readdir with recursive and withFileTypes together.
File watching: fs.watch is OS-dependent and can emit duplicate events. For production file watching, consider chokidar which normalizes behavior across platforms.
Trade-offs:
fs/promises is non-blocking — but adds async overhead for small operationspath.join handles OS differences — but you must remember to use it consistentlyrecursive: true on readdir is convenient — but can be slow on large directory treeshttps://nodejs.org/api/fs.html
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeGuides Bun file I/O: Bun.file for reading text/JSON/arrayBuffer/streams/exists checks, Bun.write for writing strings/JSON/binary/files, plus streams, appending, directories, glob patterns, metadata.
Provides file and directory operations using Claude Code's native Read, Write, Edit, Grep, Glob, and Bash tools, replacing the Filesystem MCP server. Useful for reading, writing, editing, searching, and navigating files.
Troubleshoots Windows file path errors in Claude Code on Git Bash: backslash vs forward slash issues, Edit/Write/Read tool failures, MINGW resolution, cross-platform conversion.