Skip to main content

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:

ParameterTypeDescription
pathstringFile path (required); supports nested directories
contentstring | BlobThe file content

Supported content formats:

FormatDescription
A plain stringSaved as a UTF-8 text file
A data URL stringAutomatically decoded and saved as binary (e.g. data:image/png;base64,...)
A Blob objectSaved directly as binary data

Return value, WriteResult:

FieldTypeDescription
pathstringThe path the file was saved to
sizenumberFile 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:

ParameterTypeDefaultDescription
pathstringFile path (required)
format"text" | "bloburl""text"The read format

Return value, ReadResult:

FieldTypeConditionDescription
pathstringAlwaysFile path
sizenumberAlwaysFile size
contentstringformat="text"The file's text content
blobUrlstringformat="bloburl"A blob URL
mimeTypestringformat="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:

ExtensionMIME type
.jpg / .jpegimage/jpeg
.pngimage/png
.gifimage/gif
.webpimage/webp
.svgimage/svg+xml
.mp3audio/mpeg
.wavaudio/wav
.mp4video/mp4
.pdfapplication/pdf
.jsonapplication/json
.txttext/plain
.htmltext/html
.csstext/css
.jsapplication/javascript
Otherapplication/octet-stream

list — List a Directory

const entries = await CAT.agent.opfs.list(path?);

Parameters:

ParameterTypeDefaultDescription
pathstring""Directory path; an empty string means the root directory

Return value, FileEntry[]:

FieldTypeDescription
namestringFile/directory name
type"file" | "directory"Type
sizenumberFile 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:

ParameterTypeDescription
attachmentIdstringAttachment ID (required)

Return value:

FieldTypeDescription
idstringAttachment ID
dataBlobThe attachment's binary data
sizenumberFile size in bytes
mimeTypestringMIME 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" });