-
Notifications
You must be signed in to change notification settings - Fork 49
feat: add file watching capabilities with inotify support #324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: 5f87bbe The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
…ing or encoding Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Documents the new sandbox.watch() method that enables real-time filesystem monitoring using Linux inotify. Includes: - API reference for watch() method in files.mdx - Comprehensive how-to guide with practical examples - Cross-references between related documentation This documentation covers: - Basic file watching with callbacks - Filtering by file type with glob patterns - Event type filtering (create, modify, delete, rename) - Cancellation with AbortController - Hot reload and log monitoring examples - Best practices and troubleshooting Synced from cloudflare/sandbox-sdk#324
commit: |
🐳 Docker Images PublishedDefault: FROM cloudflare/sandbox:0.0.0-pr-324-11723aaWith Python: FROM cloudflare/sandbox:0.0.0-pr-324-11723aa-pythonWith OpenCode: FROM cloudflare/sandbox:0.0.0-pr-324-11723aa-opencodeVersion: Use the 📦 Standalone BinaryFor arbitrary Dockerfiles: COPY --from=cloudflare/sandbox:0.0.0-pr-324-11723aa /container-server/sandbox /sandbox
ENTRYPOINT ["/sandbox"]Download via GitHub CLI: gh run download 20676656862 -n sandbox-binaryExtract from Docker: docker run --rm cloudflare/sandbox:0.0.0-pr-324-11723aa cat /container-server/sandbox > sandbox && chmod +x sandbox |
…ses. Update tests to validate new event parsing logic and ensure proper handling of inotifywait output.
…efault and custom excludes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Claude Code Review
This PR adds real-time file watching using Linux's inotify. The implementation follows the three-layer architecture correctly with good separation of concerns. However, there are critical error handling issues that need to be addressed before merging.
Critical Issues
1. Silent process cleanup failures
watch-service.ts:383-387 - The finally block swallows all process.kill() errors:
finally {
try {
proc.kill();
} catch {
// Process may already be dead
}
self.activeWatches.delete(watchId);
}This hides permission errors, system failures, and other unexpected issues. Users won't know if cleanup failed, potentially leading to zombie processes. Log unexpected errors (not just ESRCH).
2. FileWatch.stop() fails silently
sandbox.ts:311-330 - Multiple silent failures:
- Lines 313, 330:
loopPromise.catch(() => {})swallows all stream errors - Lines 321-327: Server-side stop failures only logged, never surfaced to user
Users call await watcher.stop() and get success even when server-side cleanup failed. This leaves watches active on the server.
3. Establishment promise can hang forever
sandbox.ts:168-182 - If the watch is cancelled (via AbortSignal) during establishment before receiving the "watching" event, the establishment promise never resolves or rejects. The AbortSignal handler (lines 1420-1426) doesn't call establishedReject(), causing FileWatch.create() to hang indefinitely.
4. Weak type guard allows undefined access
sandbox.ts:228-233 - isFileWatchSSEEvent only checks that type is a string, but doesn't validate required properties exist:
if (typeof obj.type !== 'string') return false;
return ['watching', 'event', 'error', 'stopped'].includes(obj.type);This allows accessing event.watchId (line 255) or event.path (line 265) when they might be undefined, causing runtime errors.
Important Issues
5. Comments reference historical context
watch-service.ts:374-377 - Per CLAUDE.md, avoid phrases like "to avoid", "to prevent", "expected case":
// Expected case: process already exited (no longer running)
// Unexpected: permission errors, system issuesDescribe current behavior, not why the code exists.
6. No validation of watchId parameter
watch-client.ts:50-61 - stopWatch() sends user input directly to API without checking it's a non-empty string.
7. Malformed events silently dropped
sandbox.ts:240-244, 246-248 - Malformed JSON and invalid event structures are silently ignored with no logging. Users won't know events are being lost.
Test Coverage Gaps (High Priority)
8. Missing: Concurrent watch operations
No tests for:
- Multiple watches on same directory
stopAllWatches()called while events streaming- Rapid start/stop cycles
The stopAllWatches() implementation could have race conditions with concurrent modifications to the activeWatches map.
9. Missing: inotifywait crash handling
What happens when inotifywait exits unexpectedly (permission denied, kernel limit reached)? The code monitors stderr but no test verifies error events are sent before stream closes.
10. Missing: Stream cancellation during active events
No test verifies calling reader.cancel() while events are streaming properly kills the process and cleans up the watch from activeWatches.
Positive Observations
- Follows three-layer architecture correctly
- Strong security focus: comprehensive ReDoS prevention tests (watch-service.test.ts:84-160)
- Proper logger injection via constructor
- Good use of ErrorCode enum
- FileWatch state machine is well-designed
- Comprehensive E2E tests for happy path scenarios
Verdict
The architecture and happy path implementation are solid, but the error handling needs significant work. The silent failures will make debugging very difficult for users and could lead to resource leaks.
Recommendations before merge:
- Fix the 4 critical issues (especially #2 and #3 which affect user experience directly)
- Add logging to error paths (issues #1, #7)
- Add tests for concurrent operations and error scenarios (issues #8, #9, #10)
Let me know if you'd like me to help with any of these fixes!
Adds real-time file watching using Linux's native inotify via inotifywait.
API
Implementation