{"id":269,"date":"2026-03-03T00:00:00","date_gmt":"2026-03-03T00:00:00","guid":{"rendered":"https:\/\/wordpress.securinsight.ca\/index.php\/2026\/03\/03\/agents-real-time-file-watching-in-sandboxes\/"},"modified":"2026-03-03T00:00:00","modified_gmt":"2026-03-03T00:00:00","slug":"agents-real-time-file-watching-in-sandboxes","status":"publish","type":"post","link":"https:\/\/wordpress.securinsight.ca\/index.php\/2026\/03\/03\/agents-real-time-file-watching-in-sandboxes\/","title":{"rendered":"Agents &#8211; Real-time file watching in Sandboxes"},"content":{"rendered":"<p><a href=\"https:\/\/developers.cloudflare.com\/sandbox\/\">Sandboxes<\/a> now support real-time filesystem watching via <code>sandbox.watch()<\/code>. The method returns a <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Server-sent_events\" target=\"_blank\">Server-Sent Events<\/a> stream backed by native inotify, so your Worker receives <code>create<\/code>, <code>modify<\/code>, <code>delete<\/code>, and <code>move<\/code> events as they happen inside the container.<\/p>\n<h4><code>sandbox.watch(path, options)<\/code><\/h4>\n<p>Pass a directory path and optional filters. The returned stream is a standard <code>ReadableStream<\/code> you can proxy directly to a browser client or consume server-side.<\/p>\n<ul>\n<li>\n<p>JavaScript<\/p>\n<div>\n<div>\n<figure>\n<pre data-language=\"js\"><code class=\"language-js\"><div><div><span>\/\/ Stream events to a browser client<\/span><\/div><\/div><div><div><span>const<\/span><span> <\/span><span>stream<\/span><span> <\/span><span>=<\/span><span> <\/span><span>await<\/span><span> <\/span><span>sandbox<\/span><span>.<\/span><span>watch<\/span><span>(<\/span><span>\"\/workspace\/src\"<\/span><span>,<\/span><span> <\/span><span>{<\/span><\/div><\/div><div><div><span><span>  <\/span><\/span><span>recursive<\/span><span>:<\/span><span> true<\/span><span>,<\/span><\/div><\/div><div><div><span><span>  <\/span><\/span><span>include<\/span><span>:<\/span><span> [<\/span><span>\"*.ts\"<\/span><span>,<\/span><span> <\/span><span>\"*.js\"<\/span><span>]<\/span><span>,<\/span><\/div><\/div><div><div><span>}<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div>\n<\/div><\/div><div><div><span>return<\/span><span> <\/span><span>new<\/span><span> <\/span><span>Response<\/span><span>(<\/span><span>stream<\/span><span>,<\/span><span> <\/span><span>{<\/span><\/div><\/div><div><div><span><span>  <\/span><\/span><span>headers<\/span><span>:<\/span><span> <\/span><span>{<\/span><span> <\/span><span>\"Content-Type\"<\/span><span>:<\/span><span> <\/span><span>\"text\/event-stream\"<\/span><span> <\/span><span>},<\/span><\/div><\/div><div><div><span>}<\/span><span>)<\/span><span>;<\/span><\/div><\/div><\/code><\/pre>\n<div>\n<div><\/div>\n<\/div>\n<\/figure>\n<\/div><\/div>\n<\/li>\n<li>\n<p>TypeScript<\/p>\n<div>\n<div>\n<figure>\n<pre data-language=\"ts\"><code class=\"language-ts\"><div><div><span>\/\/ Stream events to a browser client<\/span><\/div><\/div><div><div><span>const<\/span><span> <\/span><span>stream<\/span><span> <\/span><span>=<\/span><span> <\/span><span>await<\/span><span> <\/span><span>sandbox<\/span><span>.<\/span><span>watch<\/span><span>(<\/span><span>\"\/workspace\/src\"<\/span><span>,<\/span><span> <\/span><span>{<\/span><\/div><\/div><div><div><span><span>  <\/span><\/span><span>recursive<\/span><span>:<\/span><span> true<\/span><span>,<\/span><\/div><\/div><div><div><span><span>  <\/span><\/span><span>include<\/span><span>:<\/span><span> [<\/span><span>\"*.ts\"<\/span><span>,<\/span><span> <\/span><span>\"*.js\"<\/span><span>]<\/span><span>,<\/span><\/div><\/div><div><div><span>}<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div>\n<\/div><\/div><div><div><span>return<\/span><span> <\/span><span>new<\/span><span> <\/span><span>Response<\/span><span>(<\/span><span>stream<\/span><span>,<\/span><span> <\/span><span>{<\/span><\/div><\/div><div><div><span><span>  <\/span><\/span><span>headers<\/span><span>:<\/span><span> <\/span><span>{<\/span><span> <\/span><span>\"Content-Type\"<\/span><span>:<\/span><span> <\/span><span>\"text\/event-stream\"<\/span><span> <\/span><span>},<\/span><\/div><\/div><div><div><span>}<\/span><span>)<\/span><span>;<\/span><\/div><\/div><\/code><\/pre>\n<div>\n<div><\/div>\n<\/div>\n<\/figure>\n<\/div><\/div>\n<\/li>\n<\/ul>\n<h4>Server-side consumption with <code>parseSSEStream<\/code><\/h4>\n<p>Use <code>parseSSEStream<\/code> to iterate over events inside a Worker without forwarding them to a client.<\/p>\n<ul>\n<li>\n<p>JavaScript<\/p>\n<div>\n<div>\n<figure>\n<pre data-language=\"js\"><code class=\"language-js\"><div><div><span>import <\/span><span>{<\/span><span><span> <\/span><span>parseSSEStream<\/span><span> <\/span><\/span><span>}<\/span><span> from <\/span><span>\"@cloudflare\/sandbox\"<\/span><span>;<\/span><\/div><\/div><div><div><span>const<\/span><span> <\/span><span>stream<\/span><span> <\/span><span>=<\/span><span> <\/span><span>await<\/span><span> <\/span><span>sandbox<\/span><span>.<\/span><span>watch<\/span><span>(<\/span><span>\"\/workspace\/src\"<\/span><span>,<\/span><span> <\/span><span>{<\/span><span> recursive<\/span><span>:<\/span><span> true <\/span><span>}<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div>\n<\/div><\/div><div><div><span>for<\/span><span> <\/span><span>await<\/span><span> (<\/span><span>const<\/span><span> <\/span><span>event<\/span><span> <\/span><span>of<\/span><span> <\/span><span>parseSSEStream<\/span><span>(<\/span><span>stream<\/span><span>)) <\/span><span>{<\/span><\/div><\/div><div><div><span><span>  <\/span><\/span><span>console<\/span><span>.<\/span><span>log<\/span><span>(<\/span><span>event<\/span><span>.<\/span><span>type<\/span><span>,<\/span><span> <\/span><span>event<\/span><span>.<\/span><span>path<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div><span>}<\/span><\/div><\/div><\/code><\/pre>\n<div>\n<div><\/div>\n<\/div>\n<\/figure>\n<\/div><\/div>\n<\/li>\n<li>\n<p>TypeScript<\/p>\n<div>\n<div>\n<figure>\n<pre data-language=\"ts\"><code class=\"language-ts\"><div><div><span>import <\/span><span>{<\/span><span><span> <\/span><span>parseSSEStream<\/span><span> <\/span><\/span><span>}<\/span><span> from <\/span><span>\"@cloudflare\/sandbox\"<\/span><span>;<\/span><\/div><\/div><div><div><span>import type <\/span><span>{<\/span><span><span> <\/span><span>FileWatchSSEEvent<\/span><span> <\/span><\/span><span>}<\/span><span> from <\/span><span>\"@cloudflare\/sandbox\"<\/span><span>;<\/span><\/div><\/div><div><div>\n<\/div><\/div><div><div><span>const<\/span><span> <\/span><span>stream<\/span><span> <\/span><span>=<\/span><span> <\/span><span>await<\/span><span> <\/span><span>sandbox<\/span><span>.<\/span><span>watch<\/span><span>(<\/span><span>\"\/workspace\/src\"<\/span><span>,<\/span><span> <\/span><span>{<\/span><span> recursive<\/span><span>:<\/span><span> true <\/span><span>}<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div>\n<\/div><\/div><div><div><span>for<\/span><span> <\/span><span>await<\/span><span> (<\/span><span>const<\/span><span> <\/span><span>event<\/span><span> <\/span><span>of<\/span><span> <\/span><span>parseSSEStream<\/span><span>&lt;<\/span><span>FileWatchSSEEvent<\/span><span>&gt;<\/span><span>(<\/span><span>stream<\/span><span>)) <\/span><span>{<\/span><\/div><\/div><div><div><span><span>  <\/span><\/span><span>console<\/span><span>.<\/span><span>log<\/span><span>(<\/span><span>event<\/span><span>.<\/span><span>type<\/span><span>,<\/span><span> <\/span><span>event<\/span><span>.<\/span><span>path<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div><span>}<\/span><\/div><\/div><\/code><\/pre>\n<div>\n<div><\/div>\n<\/div>\n<\/figure>\n<\/div><\/div>\n<\/li>\n<\/ul>\n<p>Each event includes a <code>type<\/code> field (<code>create<\/code>, <code>modify<\/code>, <code>delete<\/code>, or <code>move<\/code>) and the affected <code>path<\/code>. Move events also include a <code>from<\/code> field with the original path.<\/p>\n<h4>Options<\/h4>\n<table>\n<thead>\n<tr>\n<th>Option<\/th>\n<th>Type<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>recursive<\/code><\/td>\n<td><code>boolean<\/code><\/td>\n<td>Watch subdirectories. Defaults to <code>false<\/code>.<\/td>\n<\/tr>\n<tr>\n<td><code>include<\/code><\/td>\n<td><code>string[]<\/code><\/td>\n<td>Glob patterns to filter events. Omit to receive all events.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>Upgrade<\/h4>\n<p>To update to the latest version:<\/p>\n<div>\n<figure>\n<pre data-language=\"sh\"><code class=\"language-sh\"><div><div><span>npm<\/span><span> <\/span><span>i<\/span><span> <\/span><span>@cloudflare\/sandbox@latest<\/span><\/div><\/div><\/code><\/pre>\n<div>\n<div><\/div>\n<\/div>\n<\/figure>\n<\/div>\n<p>For full API details, refer to the <a href=\"https:\/\/developers.cloudflare.com\/sandbox\/api\/file-watching\/\">Sandbox file watching reference<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Sandboxes now support real-time filesystem watching via sandbox.watch(). The method returns a Server-Sent Events stream backed by native inotify, so your Worker receives create, modify, delete, and move events as they happen inside the container. sandbox.watch(path, options) Pass a directory path and optional filters. The returned stream is a standard ReadableStream you can proxy directly [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-269","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/posts\/269","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/comments?post=269"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/posts\/269\/revisions"}],"wp:attachment":[{"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/media?parent=269"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/categories?post=269"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/tags?post=269"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}