> For the complete documentation index, see [llms.txt](https://seanime.gitbook.io/seanime-extensions/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://seanime.gitbook.io/seanime-extensions/plugins/apis/system/os.md).

# OS

OS-agonistic APIs for operating system functionality, such as interacting with the filesystem.

Go reference: <https://pkg.go.dev/os>

{% hint style="warning" %}
As of Seanime `v3.8.0`, if the user enables Extension Secure Mode, sensitive filesystem actions can prompt for confirmation.

If the user rejects the prompt, reads, writes, directory listing, creation, rename, delete, move, and extraction calls can throw. If prompts cannot be shown, such as during app startup, these calls fail immediately.
{% endhint %}

## $os

### Info

```typescript
console.log("Platform:", $os.platform); // darwin
console.log("Arch:", $os.arch); // arm64
```

### Directories

```typescript
$os.tempDir() // $TEMP must be in the allow list
$os.cacheDir() // $CACHE must be in the allow list
$os.configDir() // $CONFIG must be in the allow list
$os.homeDir() // $HOME must be in the allow list
```

### File operations

{% hint style="warning" %}
Always call `close()` once you're done manipulating a file.
{% endhint %}

{% code title="Example" %}

```typescript
// C:\Users\user\Downloads\test.txt
Hello World!

// my-plugin.ts
// "C:/Users/user/Downloads/**/*" and "$TEMP/**/*" have been added to 'allowReadPaths' and 'allowWritePaths'

// Access the temp directory
const tempDirPath = $os.tempDir();
console.log("Temp dir:", tempDirPath);

// Read files
const content = $os.readFile("C:\Users\user\Downloads\test.txt");
console.log("File content:", $toString(content)); // Hello World!

// Write/create files
$os.writeFile("C:\Users\user\Downloads\test.txt.new", $toBytes("New content"), 0644);
const newContent = $os.readFile("C:\Users\user\Downloads\test.txt.new");
console.log("New file content:", $toString(newContent)); // New content

// Read directories
const entries = $os.readDir("C:\Users\user\Downloads");
for (const entry of entries) {
	console.log(entry.name()); // test.txt, test.txt.new
}

// Create directories
$os.mkdir("C:\Users\user\Downloads\newdir", 0755);
const newEntries = $os.readDir("C:\Users\user\Downloads");
for (const entry of newEntries) {
	console.log(entry.name()); // test.txt, test.txt.new, newdir
}

// Rename files
$os.rename("C:\Users\user\Downloads\test.txt.new", "C:\Users\user\Downloads\test.txt.renamed");
let renameSuccess = true
try {
	// File exists, no error thrown
	$os.stat("C:\Users\user\Downloads\test.txt.renamed");
} catch(e) {
	renameSuccess = false
}
console.log(renameSuccess); // true

// Remove files
$os.remove("C:\Users\user\Downloads\test.txt.renamed");
let removeSuccess = true;
try {
	$os.stat("C:\Users\user\Downloads\test.txt.renamed");
	removeSuccess = false;
} catch (e) {
	// Error thrown becuase file should not exist
	removeSuccess = true;
}
console.log(removeSuccess); // true
```

{% endcode %}

## $osExtra

This API gives you additional functionalities

### Directories

```typescript
$osExtra.desktopDir() // $DESKTOP must be in the allow list
$osExtra.documentDir() // $DOCUMENT must be in the allow list
$osExtra.downloadDir() // $DOWNLOAD must be in the allow list
```

### Unarchive files

* unzipFile, unrarFile

```typescript
// If "file.zip" contains `folder > file.text`
$osExtra.unzipFile("/path/to/downloaded/file.zip", "/path/to/dest") 
// -> "/path/to/dest/folder/file.txt"

// If "file.rar" contains `file.txt`
$osExtra.unrarFile("/path/to/downloaded/file.zip", "/path/to/dest")
// -> "/path/to/dest/file.txt"
```
