OPFS File API
@grant CAT.agent.opfs
The OPFS (Origin Private File System) File API lets a script read and write files in the Agent workspace. All paths are relative to the agents/workspace/ directory.
write — Write a File
const result = await CAT.agent.opfs.write(path, content);
Parameters:
| Parameter | Type | Description |
|---|---|---|
path | string | File path (required); supports nested directories |
content | string | Blob | The file content |
Supported content formats:
| Format | Description |
|---|---|
| A plain string | Saved as a UTF-8 text file |
| A data URL string | Automatically decoded and saved as binary (e.g. data:image/png;base64,...) |
A Blob object | Saved directly as binary data |
Return value, WriteResult:
| Field | Type | Description |
|---|---|---|
path | string | The path the file was saved to |
size | number | File size in bytes |
// Write a text file
await CAT.agent.opfs.write("data/config.json", JSON.stringify({ key: "value" }));
// Write a binary file (data URL)
const canvas = document.createElement("canvas");
const dataUrl = canvas.toDataURL("image/png");
await CAT.agent.opfs.write("images/chart.png", dataUrl);
If the parent directories in the path don't exist, they're created automatically. If the file already exists, its content is overwritten.
read — Read a File
const result = await CAT.agent.opfs.read(path, format?);
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
path | string | — | File path (required) |
format | "text" | "bloburl" | "text" | The read format |
Return value, ReadResult:
| Field | Type | Condition | Description |
|---|---|---|---|
path | string | Always | File path |
size | number | Always | File size |
content | string | format="text" | The file's text content |
blobUrl | string | format="bloburl" | A blob URL |
mimeType | string | format="bloburl" | MIME type |
Two read modes:
// Text mode — good for JSON and text files
const config = await CAT.agent.opfs.read("data/config.json");
const data = JSON.parse(config.content);
// Blob URL mode — good for images and binary files
const image = await CAT.agent.opfs.read("images/chart.png", "bloburl");
// image.blobUrl = "blob:chrome-extension://xxx/yyy"
// This URL can be used inside an executeScript call in the ISOLATED world
Automatically recognized MIME types:
| Extension | MIME type |
|---|---|
.jpg / .jpeg | image/jpeg |
.png | image/png |
.gif | image/gif |
.webp | image/webp |
.svg | image/svg+xml |
.mp3 | audio/mpeg |
.wav | audio/wav |
.mp4 | video/mp4 |
.pdf | application/pdf |
.json | application/json |
.txt | text/plain |
.html | text/html |
.css | text/css |
.js | application/javascript |
| Other | application/octet-stream |
list — List a Directory
const entries = await CAT.agent.opfs.list(path?);
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
path | string | "" | Directory path; an empty string means the root directory |
Return value, FileEntry[]:
| Field | Type | Description |
|---|---|---|
name | string | File/directory name |
type | "file" | "directory" | Type |
size | number | File size (only for the file type) |
const entries = await CAT.agent.opfs.list("data/");
for (const entry of entries) {
if (entry.type === "file") {
console.log(`${entry.name} (${entry.size} bytes)`);
} else {
console.log(`${entry.name}/`);
}
}
delete — Delete a File or Directory
const result = await CAT.agent.opfs.delete(path);
Supports recursively deleting a directory and all of its contents.
Return value:
{ success: true }
readAttachment — Read an Attachment
const result = await CAT.agent.opfs.readAttachment(attachmentId);
Reads attachment data (images, files, etc.) from a conversation. The attachment ID comes from ContentBlock.attachmentId in a message.
Parameters:
| Parameter | Type | Description |
|---|---|---|
attachmentId | string | Attachment ID (required) |
Return value:
| Field | Type | Description |
|---|---|---|
id | string | Attachment ID |
data | Blob | The attachment's binary data |
size | number | File size in bytes |
mimeType | string | MIME type |
// Read an image attachment generated by the AI in a conversation
const messages = await conv.getMessages();
const lastMsg = messages[messages.length - 1];
const imageBlock = lastMsg.content.find(b => b.type === "image");
if (imageBlock) {
const attachment = await CAT.agent.opfs.readAttachment(imageBlock.attachmentId);
console.log(`Attachment size: ${attachment.size}, type: ${attachment.mimeType}`);
}
Blob URL Usage Notes
- Blob URLs are in the form
blob:chrome-extension://xxx/yyy - Can only be used in the ISOLATED world (the default environment for
executeScript) - The extension's blob URLs cannot be accessed from the MAIN world (the page environment)
- A blob URL's lifetime is tied to the extension session
// Correct: use the blob URL in the ISOLATED world
const img = await CAT.agent.opfs.read("images/photo.png", "bloburl");
await CAT.agent.dom.executeScript(`
const img = document.createElement("img");
img.src = "${img.blobUrl}";
document.body.appendChild(img);
`, { world: "ISOLATED" });
// Wrong: not accessible from the MAIN world
await CAT.agent.dom.executeScript(`
fetch("${img.blobUrl}") // this will fail!
`, { world: "MAIN" });