> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/sinelaw/fresh/llms.txt
> Use this file to discover all available pages before exploring further.

# Filesystem API

> Read, write, and manipulate files and directories

The Filesystem API provides methods for interacting with the file system, including reading and writing files, checking file existence, and working with directories.

## File Operations

### readFile

Read entire file contents as UTF-8 string.

```typescript theme={null}
readFile(path: string): Promise<string>
```

<ParamField path="path" type="string" required>
  File path (absolute or relative to cwd)
</ParamField>

<ResponseField name="returns" type="Promise<string>">
  File contents as UTF-8 string
</ResponseField>

<Warning>
  Throws if file doesn't exist, isn't readable, or isn't valid UTF-8. For binary files, this will fail. For large files, consider memory usage.
</Warning>

**Example:**

```typescript theme={null}
try {
  const content = await editor.readFile("/path/to/file.txt");
  editor.debug(`File content: ${content}`);
} catch (error) {
  editor.error(`Failed to read file: ${error}`);
}
```

### writeFile

Write string content to a NEW file (fails if file exists).

```typescript theme={null}
writeFile(path: string, content: string): Promise<void>
```

<ParamField path="path" type="string" required>
  Destination path (absolute or relative to cwd)
</ParamField>

<ParamField path="content" type="string" required>
  UTF-8 string to write
</ParamField>

<Warning>
  Creates a new file with the given content. Fails if the file already exists to prevent plugins from accidentally overwriting user data.
</Warning>

**Example:**

```typescript theme={null}
try {
  await editor.writeFile("/path/to/new-file.txt", "Hello, world!");
  editor.setStatus("File created successfully");
} catch (error) {
  editor.error(`Failed to create file: ${error}`);
}
```

### fileExists

Check if a path exists (file, directory, or symlink).

```typescript theme={null}
fileExists(path: string): boolean
```

<ParamField path="path" type="string" required>
  Path to check (absolute or relative to cwd)
</ParamField>

<ResponseField name="returns" type="boolean">
  `true` if path exists, `false` otherwise
</ResponseField>

<Note>
  Does not follow symlinks; returns true for broken symlinks. Use `fileStat` for more detailed information.
</Note>

**Example:**

```typescript theme={null}
if (editor.fileExists("/path/to/file.txt")) {
  editor.info("File exists");
} else {
  editor.info("File does not exist");
}
```

### fileStat

Get metadata about a file or directory.

```typescript theme={null}
fileStat(path: string): FileStat
```

<ParamField path="path" type="string" required>
  Path to stat (absolute or relative to cwd)
</ParamField>

<ResponseField name="returns" type="FileStat">
  File metadata object
</ResponseField>

**FileStat Type:**

```typescript theme={null}
interface FileStat {
  exists: boolean;    // Whether the path exists
  is_file: boolean;   // Whether the path is a file
  is_dir: boolean;    // Whether the path is a directory
  size: number;       // File size in bytes
  readonly: boolean;  // Whether the file is read-only
}
```

<Note>
  Follows symlinks. Returns `exists=false` for non-existent paths rather than throwing. Size is in bytes; directories may report 0.
</Note>

**Example:**

```typescript theme={null}
const stat = editor.fileStat("/path/to/file.txt");
if (stat.exists) {
  if (stat.is_file) {
    editor.info(`File size: ${stat.size} bytes`);
  } else if (stat.is_dir) {
    editor.info("Path is a directory");
  }
  if (stat.readonly) {
    editor.warn("File is read-only");
  }
}
```

## Directory Operations

### readDir

List directory contents.

```typescript theme={null}
readDir(path: string): DirEntry[]
```

<ParamField path="path" type="string" required>
  Directory path (absolute or relative to cwd)
</ParamField>

<ResponseField name="returns" type="DirEntry[]">
  Array of directory entries
</ResponseField>

**DirEntry Type:**

```typescript theme={null}
interface DirEntry {
  name: string;       // Entry name only (not full path)
  is_file: boolean;   // True if entry is a regular file
  is_dir: boolean;    // True if entry is a directory
}
```

<Note>
  Returns unsorted entries with type info. Entry names are relative to the directory (use `pathJoin` to construct full paths). Throws on permission errors or if path is not a directory.
</Note>

**Example:**

```typescript theme={null}
try {
  const entries = editor.readDir("/home/user");
  for (const entry of entries) {
    const fullPath = editor.pathJoin(["/home/user", entry.name]);
    if (entry.is_file) {
      editor.debug(`File: ${fullPath}`);
    } else if (entry.is_dir) {
      editor.debug(`Directory: ${fullPath}`);
    }
  }
} catch (error) {
  editor.error(`Failed to read directory: ${error}`);
}
```

## Path Operations

### pathJoin

Join path segments using the OS path separator.

```typescript theme={null}
pathJoin(parts: string[]): string
```

<ParamField path="parts" type="string[]" required>
  Path segments to join
</ParamField>

<ResponseField name="returns" type="string">
  Joined path string
</ResponseField>

<Note>
  Handles empty segments and normalizes separators. If a segment is absolute, previous segments are discarded.
</Note>

**Example:**

```typescript theme={null}
const path1 = editor.pathJoin(["/home", "user", "file.txt"]);
// Result: "/home/user/file.txt"

const path2 = editor.pathJoin(["relative", "/absolute"]);
// Result: "/absolute"
```

### pathDirname

Get the parent directory of a path.

```typescript theme={null}
pathDirname(path: string): string
```

<ParamField path="path" type="string" required>
  File or directory path
</ParamField>

<ResponseField name="returns" type="string">
  Parent directory path, or empty string for root paths
</ResponseField>

<Note>
  Does not resolve symlinks or check existence.
</Note>

**Example:**

```typescript theme={null}
const dir1 = editor.pathDirname("/home/user/file.txt");
// Result: "/home/user"

const dir2 = editor.pathDirname("/");
// Result: ""
```

### pathBasename

Get the final component of a path.

```typescript theme={null}
pathBasename(path: string): string
```

<ParamField path="path" type="string" required>
  File or directory path
</ParamField>

<ResponseField name="returns" type="string">
  Final path component, or empty string for root paths
</ResponseField>

<Note>
  Does not strip file extension; use `pathExtname` for that.
</Note>

**Example:**

```typescript theme={null}
const base1 = editor.pathBasename("/home/user/file.txt");
// Result: "file.txt"

const base2 = editor.pathBasename("/home/user/");
// Result: "user"
```

### pathExtname

Get the file extension including the dot.

```typescript theme={null}
pathExtname(path: string): string
```

<ParamField path="path" type="string" required>
  File path
</ParamField>

<ResponseField name="returns" type="string">
  File extension with dot, or empty string if no extension
</ResponseField>

<Note>
  Only returns the last extension for files like "archive.tar.gz" (returns ".gz").
</Note>

**Example:**

```typescript theme={null}
const ext1 = editor.pathExtname("file.txt");
// Result: ".txt"

const ext2 = editor.pathExtname("archive.tar.gz");
// Result: ".gz"

const ext3 = editor.pathExtname("Makefile");
// Result: ""
```

### pathIsAbsolute

Check if a path is absolute.

```typescript theme={null}
pathIsAbsolute(path: string): boolean
```

<ParamField path="path" type="string" required>
  Path to check
</ParamField>

<ResponseField name="returns" type="boolean">
  `true` if path is absolute, `false` otherwise
</ResponseField>

<Note>
  On Unix: starts with "/". On Windows: starts with drive letter or UNC path.
</Note>

**Example:**

```typescript theme={null}
const abs1 = editor.pathIsAbsolute("/home/user/file.txt");
// Result: true

const abs2 = editor.pathIsAbsolute("relative/path.txt");
// Result: false
```

## Environment Operations

### getCwd

Get the editor's current working directory.

```typescript theme={null}
getCwd(): string
```

<ResponseField name="returns" type="string">
  Absolute path to the editor's working directory set at startup
</ResponseField>

<Note>
  Use as base for resolving relative paths.
</Note>

**Example:**

```typescript theme={null}
const cwd = editor.getCwd();
const absolutePath = editor.pathJoin([cwd, "relative/file.txt"]);
```

### getEnv

Get an environment variable.

```typescript theme={null}
getEnv(name: string): string
```

<ParamField path="name" type="string" required>
  Name of environment variable
</ParamField>

<ResponseField name="returns" type="string">
  Environment variable value, or empty string if not set
</ResponseField>

**Example:**

```typescript theme={null}
const home = editor.getEnv("HOME");
const path = editor.getEnv("PATH");
editor.debug(`Home: ${home}`);
```

## Examples

### Read config file

```typescript theme={null}
const configDir = editor.getConfigDir();
const configPath = editor.pathJoin([configDir, "my-plugin.json"]);

if (editor.fileExists(configPath)) {
  try {
    const content = await editor.readFile(configPath);
    const config = JSON.parse(content);
    editor.debug(`Loaded config: ${JSON.stringify(config)}`);
  } catch (error) {
    editor.error(`Failed to load config: ${error}`);
  }
} else {
  editor.info("Config file not found, using defaults");
}
```

### List files in directory

```typescript theme={null}
const cwd = editor.getCwd();
const entries = editor.readDir(cwd);

const files = entries
  .filter(e => e.is_file)
  .map(e => e.name);

const dirs = entries
  .filter(e => e.is_dir)
  .map(e => e.name);

editor.info(`Files: ${files.length}, Directories: ${dirs.length}`);
```

### Find files recursively

```typescript theme={null}
function findFiles(dir: string, pattern: RegExp): string[] {
  const results: string[] = [];
  
  try {
    const entries = editor.readDir(dir);
    
    for (const entry of entries) {
      const fullPath = editor.pathJoin([dir, entry.name]);
      
      if (entry.is_file && pattern.test(entry.name)) {
        results.push(fullPath);
      } else if (entry.is_dir) {
        results.push(...findFiles(fullPath, pattern));
      }
    }
  } catch (error) {
    editor.warn(`Failed to read ${dir}: ${error}`);
  }
  
  return results;
}

// Find all TypeScript files
const tsFiles = findFiles(editor.getCwd(), /\.ts$/);
editor.info(`Found ${tsFiles.length} TypeScript files`);
```
