npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nativeai/workspace

v0.9.2

Published

Safe workspaces for native AI

Downloads

4

Readme

Workspace

Managing file paths in Node.js applications often leads to brittle code full of path.join(__dirname, '../../config') and relative paths that break during refactoring. The Workspace singleton addresses this by establishing a project root directory as the reference point for all file operations.

Once configured, all file system operations work relative to this root, eliminating complex path resolution and preventing accidental file access outside your project boundaries. This approach makes file operations more predictable and helps avoid path-related bugs when code is moved or restructured.

Table of Contents

Usage

import {workspace} from '@nativeai/workspace';

workspace.setRootPath('/project/root');
workspace.writeFileSync('config.json', data);
const files = workspace.readdirSync('src');

API

The workspace provides methods organized into five categories. All file operations are relative to the configured root path and automatically create parent directories when needed.

Setup

Configure and retrieve the workspace root directory.

setRootPath(path: string)

Set the workspace root directory with built-in security validation to prevent dangerous paths.

workspace.setRootPath('/Users/john/my-project'); //  Safe project path
workspace.setRootPath('/Users/john'); //  Throws: user home directory
workspace.setRootPath('/'); //  Throws: system path

getRootPath(): string

Get the currently configured root directory path.

const root = workspace.getRootPath(); // '/Users/john/my-project'

Path Operations

Node.js path operations relative to the workspace root.

join(...paths: string[])

Join multiple path segments into a single relative path.

const configPath = workspace.join('config', 'app.json'); // 'config/app.json'
const nested = workspace.join('src', 'components', 'ui', 'Button.tsx');

resolve(...paths: string[])

Resolve path segments relative to the workspace root, returning an absolute path.

const resolved = workspace.resolve('..', 'shared', 'utils.ts');
const absolutePath = workspace.resolve('src', 'main.ts');

relative(targetPath: string)

Get the relative path from workspace root to the target path.

const rel = workspace.relative('/Users/john/my-project/src/main.ts'); // 'src/main.ts'
const relFromAbs = workspace.relative(workspace.resolve('config/app.json'));

dirname(filePath: string)

Get the directory portion of a file path relative to workspace root.

const dir = workspace.dirname('src/components/Button.tsx'); // 'src/components'
const rootDir = workspace.dirname('package.json'); // ''

basename(filePath: string, ext?: string)

Get the filename portion of a path, optionally removing the extension.

const name = workspace.basename('src/main.ts'); // 'main.ts'
const nameNoExt = workspace.basename('src/main.ts', '.ts'); // 'main'

extname(filePath: string)

Get the file extension from a path.

const ext = workspace.extname('config.json'); // '.json'
const noExt = workspace.extname('README'); // ''

Synchronous Operations

Blocking file system operations for simple use cases.

readFileSync(filePath: string, options?)

Read file contents synchronously with path traversal protection.

const content = workspace.readFileSync('package.json', 'utf8');
const buffer = workspace.readFileSync('image.png');

writeFileSync(filePath: string, data: string | Buffer, options?)

Write data to a file synchronously, automatically creating parent directories.

workspace.writeFileSync('config/settings.json', JSON.stringify(config));
workspace.writeFileSync('logs/app.log', 'Application started\n', { flag: 'a' });

mkdirSync(dirPath: string, options?)

Create a directory synchronously, including parent directories if needed.

workspace.mkdirSync('logs/2023');
workspace.mkdirSync('temp', { mode: 0o755 });

existsSync(filePath: string)

Check if a file or directory exists, returning false for invalid/dangerous paths.

if (workspace.existsSync('config.json')) { 
  // file exists and is within workspace
}
const hasLogs = workspace.existsSync('logs/app.log');

readdirSync(dirPath: string, options?)

List the contents of a directory synchronously.

const files = workspace.readdirSync('src');
const detailed = workspace.readdirSync('src', { withFileTypes: true });

statSync(filePath: string)

Get detailed information about a file or directory.

const stats = workspace.statSync('package.json');
console.log(stats.size); // file size in bytes
console.log(stats.isDirectory()); // false

Asynchronous Operations

Non-blocking file system operations for better performance.

readFileAsync(filePath: string, options?)

Read file contents asynchronously with path validation.

const content = await workspace.readFileAsync('package.json', 'utf8');
const imageBuffer = await workspace.readFileAsync('assets/logo.png');

writeFileAsync(filePath: string, data: string | Buffer, options?)

Write data to a file asynchronously, creating parent directories as needed.

await workspace.writeFileAsync('logs/app.log', 'Started application\n');
await workspace.writeFileAsync('config/user.json', JSON.stringify(userData));

mkdirAsync(dirPath: string, options?)

Create directories asynchronously with recursive parent creation.

await workspace.mkdirAsync('temp/cache');
await workspace.mkdirAsync('uploads/2023/october');

existsAsync(filePath: string)

Check if a file or directory exists asynchronously.

const exists = await workspace.existsAsync('config.json');
if (await workspace.existsAsync('backup')) {
  // backup directory exists
}

copyFileAsync(src: string, dest: string, mode?)

Copy a file asynchronously with automatic directory creation.

await workspace.copyFileAsync('template.txt', 'output.txt');
await workspace.copyFileAsync('config/default.json', 'config/production.json');

Utilities

Helper methods for advanced workspace operations.

isWithinRoot(filePath: string)

Validate that a path is safely within the workspace boundaries.

const safe = workspace.isWithinRoot('src/file.ts'); // true
const unsafe = workspace.isWithinRoot('../outside.ts'); // false
const malicious = workspace.isWithinRoot('/etc/passwd'); // false

getAbsolutePath(filePath: string)

Convert a workspace-relative path to an absolute system path.

const abs = workspace.getAbsolutePath('src/main.ts');
// '/Users/john/my-project/src/main.ts'
const configPath = workspace.getAbsolutePath('config/app.json');

walkDirectory(dirPath?: string, options?)

Recursively traverse directories and return all file paths with optional filtering.

const allFiles = await workspace.walkDirectory('src');
const tsFiles = await workspace.walkDirectory('src', {
  filter: (path, isDir) => !isDir && path.endsWith('.ts')
});
const withDirs = await workspace.walkDirectory('', { 
  includeDirs: true,
  filter: (path, isDir) => !path.startsWith('node_modules')
});

Glob Operations

Pattern matching using glob syntax for finding files with security filtering.

globAsync(pattern: string, options?)

Find files matching a glob pattern asynchronously, with results filtered to workspace-only paths.

const jsFiles = await workspace.globAsync('**/*.js');
const srcFiles = await workspace.globAsync('src/**/*.{ts,tsx}');
const tests = await workspace.globAsync('**/*.test.*', { 
  ignore: ['node_modules/**'] 
});

globSync(pattern: string, options?)

Find files matching a glob pattern synchronously with security validation.

const configFiles = workspace.globSync('config/*.json');
const testFiles = workspace.globSync('**/*.test.ts');
const images = workspace.globSync('assets/**/*.{png,jpg,svg}');

Security Features

The workspace includes comprehensive protection against path traversal attacks and dangerous root paths:

Path Traversal Protection

All file operations are validated to prevent escaping the workspace boundary:

Blocked Patterns:

  • Classic traversal: ../../../etc/passwd
  • Windows traversal: ..\..\Windows\System32
  • Mixed separators: ../..\\Windows\\System32
  • Absolute paths: /etc/passwd, C:\Windows\System32
  • URL encoded: %2e%2e%2f (encoded ../)

How it works:

  1. Path validation - Every file operation validates paths before execution
  2. Absolute path detection - Blocks /, C:\ and other absolute references
  3. Resolution checking - Uses path.resolve() to detect traversal attempts
  4. Boundary enforcement - Ensures resolved paths stay within workspace root

Root Path Protection

Prevents setting workspace to sensitive system locations:

Blocked Paths:

  • System directories (/, /usr, /etc, /System, etc.)
  • User home directory (/Users/username, C:\Users\username)
  • Common user folders (~/Desktop, ~/Documents, ~/Downloads)
  • Windows system paths (C:\Windows, C:\Program Files)

Safe Paths:

  • Project subdirectories (~/Documents/my-project)
  • Custom development folders (~/dev/projects/app)
  • Any path that's not a sensitive system location

Security Implementation

// All file operations go through validation
workspace.writeFileSync('../../../etc/passwd', 'hack'); //  Throws error
workspace.readFileSync('/etc/shadow');                   //  Throws error
workspace.copyFileSync('file.txt', 'C:\\Windows\\hack'); //  Throws error

// Safe operations work normally
workspace.writeFileSync('config/app.json', data);        //  Works
workspace.readFileSync('src/main.ts');                   //  Works

This prevents both accidental and malicious file operations outside the intended workspace.