Skip to content

Commit e873ee9

Browse files
mishushakovclaude
andauthored
feat(sdk): add allowNetworkMounts option to filesystem watch (#1420)
Client-side counterpart to [e2b-dev/infra#2982](e2b-dev/infra#2982): adds an `allowNetworkMounts`/`allow_network_mounts` option to filesystem directory watching across the JS and Python (sync + async) SDKs, so clients can explicitly opt into watching paths on network filesystem mounts (NFS, CIFS, SMB, FUSE), which envd rejects by default. Events on network mounts may be unreliable or not delivered at all, hence the explicit opt-in. This regenerates the filesystem proto code from the updated spec and threads the flag through `watchDir`/`watch_dir` (streaming `WatchDir` and polling `CreateWatcher`). The option requires envd 0.6.4 (shipped by the infra PR); using it against an older sandbox throws a `TemplateError`/`TemplateException`. Default behavior is unchanged. Includes new watch tests for all three SDKs and a minor-bump changeset for `e2b` and `@e2b/python-sdk`. > Note: the new tests exercise the flag on a regular directory (a network mount can't be set up from SDK tests) and require envd 0.6.4, so this should land with/after the infra deploy. All pre-existing watch tests pass; the new ones currently fail with the expected `TemplateError` against the deployed envd. ### Usage **JavaScript** ```ts const handle = await sandbox.files.watchDir( '/mnt/nfs-share/my-dir', (event) => console.log(event.type, event.name), { allowNetworkMounts: true } ) ``` **Python (async)** ```python handle = await sandbox.files.watch_dir( "/mnt/nfs-share/my-dir", on_event=lambda e: print(e.type, e.name), allow_network_mounts=True, ) ``` **Python (sync)** ```python handle = sandbox.files.watch_dir("/mnt/nfs-share/my-dir", allow_network_mounts=True) for e in handle.get_new_events(): print(e.type, e.name) ``` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent cab59ca commit e873ee9

13 files changed

Lines changed: 218 additions & 34 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@e2b/python-sdk": minor
3+
"e2b": minor
4+
---
5+
6+
Add an `allowNetworkMounts`/`allow_network_mounts` option to filesystem directory watching. When enabled, paths on network filesystem mounts (NFS, CIFS, SMB, FUSE) can be watched — they are rejected by default because events on network mounts may be unreliable or not delivered at all. Requires envd 0.6.4 or later; watching with this option against an older sandbox raises a template error.

packages/js-sdk/src/envd/filesystem/filesystem_pb.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import type { Message } from '@bufbuild/protobuf'
2424
export const file_filesystem_filesystem: GenFile =
2525
/*@__PURE__*/
2626
fileDesc(
27-
'ChtmaWxlc3lzdGVtL2ZpbGVzeXN0ZW0ucHJvdG8SCmZpbGVzeXN0ZW0iMgoLTW92ZVJlcXVlc3QSDgoGc291cmNlGAEgASgJEhMKC2Rlc3RpbmF0aW9uGAIgASgJIjQKDE1vdmVSZXNwb25zZRIkCgVlbnRyeRgBIAEoCzIVLmZpbGVzeXN0ZW0uRW50cnlJbmZvIh4KDk1ha2VEaXJSZXF1ZXN0EgwKBHBhdGgYASABKAkiNwoPTWFrZURpclJlc3BvbnNlEiQKBWVudHJ5GAEgASgLMhUuZmlsZXN5c3RlbS5FbnRyeUluZm8iHQoNUmVtb3ZlUmVxdWVzdBIMCgRwYXRoGAEgASgJIhAKDlJlbW92ZVJlc3BvbnNlIhsKC1N0YXRSZXF1ZXN0EgwKBHBhdGgYASABKAkiNAoMU3RhdFJlc3BvbnNlEiQKBWVudHJ5GAEgASgLMhUuZmlsZXN5c3RlbS5FbnRyeUluZm8i5QIKCUVudHJ5SW5mbxIMCgRuYW1lGAEgASgJEiIKBHR5cGUYAiABKA4yFC5maWxlc3lzdGVtLkZpbGVUeXBlEgwKBHBhdGgYAyABKAkSDAoEc2l6ZRgEIAEoAxIMCgRtb2RlGAUgASgNEhMKC3Blcm1pc3Npb25zGAYgASgJEg0KBW93bmVyGAcgASgJEg0KBWdyb3VwGAggASgJEjEKDW1vZGlmaWVkX3RpbWUYCSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhsKDnN5bWxpbmtfdGFyZ2V0GAogASgJSACIAQESNQoIbWV0YWRhdGEYCyADKAsyIy5maWxlc3lzdGVtLkVudHJ5SW5mby5NZXRhZGF0YUVudHJ5Gi8KDU1ldGFkYXRhRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4AUIRCg9fc3ltbGlua190YXJnZXQiLQoOTGlzdERpclJlcXVlc3QSDAoEcGF0aBgBIAEoCRINCgVkZXB0aBgCIAEoDSI5Cg9MaXN0RGlyUmVzcG9uc2USJgoHZW50cmllcxgBIAMoCzIVLmZpbGVzeXN0ZW0uRW50cnlJbmZvIkkKD1dhdGNoRGlyUmVxdWVzdBIMCgRwYXRoGAEgASgJEhEKCXJlY3Vyc2l2ZRgCIAEoCBIVCg1pbmNsdWRlX2VudHJ5GAMgASgIInkKD0ZpbGVzeXN0ZW1FdmVudBIMCgRuYW1lGAEgASgJEiMKBHR5cGUYAiABKA4yFS5maWxlc3lzdGVtLkV2ZW50VHlwZRIpCgVlbnRyeRgDIAEoCzIVLmZpbGVzeXN0ZW0uRW50cnlJbmZvSACIAQFCCAoGX2VudHJ5IuABChBXYXRjaERpclJlc3BvbnNlEjgKBXN0YXJ0GAEgASgLMicuZmlsZXN5c3RlbS5XYXRjaERpclJlc3BvbnNlLlN0YXJ0RXZlbnRIABIxCgpmaWxlc3lzdGVtGAIgASgLMhsuZmlsZXN5c3RlbS5GaWxlc3lzdGVtRXZlbnRIABI7CglrZWVwYWxpdmUYAyABKAsyJi5maWxlc3lzdGVtLldhdGNoRGlyUmVzcG9uc2UuS2VlcEFsaXZlSAAaDAoKU3RhcnRFdmVudBoLCglLZWVwQWxpdmVCBwoFZXZlbnQiTgoUQ3JlYXRlV2F0Y2hlclJlcXVlc3QSDAoEcGF0aBgBIAEoCRIRCglyZWN1cnNpdmUYAiABKAgSFQoNaW5jbHVkZV9lbnRyeRgDIAEoCCIrChVDcmVhdGVXYXRjaGVyUmVzcG9uc2USEgoKd2F0Y2hlcl9pZBgBIAEoCSItChdHZXRXYXRjaGVyRXZlbnRzUmVxdWVzdBISCgp3YXRjaGVyX2lkGAEgASgJIkcKGEdldFdhdGNoZXJFdmVudHNSZXNwb25zZRIrCgZldmVudHMYASADKAsyGy5maWxlc3lzdGVtLkZpbGVzeXN0ZW1FdmVudCIqChRSZW1vdmVXYXRjaGVyUmVxdWVzdBISCgp3YXRjaGVyX2lkGAEgASgJIhcKFVJlbW92ZVdhdGNoZXJSZXNwb25zZSpSCghGaWxlVHlwZRIZChVGSUxFX1RZUEVfVU5TUEVDSUZJRUQQABISCg5GSUxFX1RZUEVfRklMRRABEhcKE0ZJTEVfVFlQRV9ESVJFQ1RPUlkQAiqYAQoJRXZlbnRUeXBlEhoKFkVWRU5UX1RZUEVfVU5TUEVDSUZJRUQQABIVChFFVkVOVF9UWVBFX0NSRUFURRABEhQKEEVWRU5UX1RZUEVfV1JJVEUQAhIVChFFVkVOVF9UWVBFX1JFTU9WRRADEhUKEUVWRU5UX1RZUEVfUkVOQU1FEAQSFAoQRVZFTlRfVFlQRV9DSE1PRBAFMp8FCgpGaWxlc3lzdGVtEjkKBFN0YXQSFy5maWxlc3lzdGVtLlN0YXRSZXF1ZXN0GhguZmlsZXN5c3RlbS5TdGF0UmVzcG9uc2USQgoHTWFrZURpchIaLmZpbGVzeXN0ZW0uTWFrZURpclJlcXVlc3QaGy5maWxlc3lzdGVtLk1ha2VEaXJSZXNwb25zZRI5CgRNb3ZlEhcuZmlsZXN5c3RlbS5Nb3ZlUmVxdWVzdBoYLmZpbGVzeXN0ZW0uTW92ZVJlc3BvbnNlEkIKB0xpc3REaXISGi5maWxlc3lzdGVtLkxpc3REaXJSZXF1ZXN0GhsuZmlsZXN5c3RlbS5MaXN0RGlyUmVzcG9uc2USPwoGUmVtb3ZlEhkuZmlsZXN5c3RlbS5SZW1vdmVSZXF1ZXN0GhouZmlsZXN5c3RlbS5SZW1vdmVSZXNwb25zZRJHCghXYXRjaERpchIbLmZpbGVzeXN0ZW0uV2F0Y2hEaXJSZXF1ZXN0GhwuZmlsZXN5c3RlbS5XYXRjaERpclJlc3BvbnNlMAESVAoNQ3JlYXRlV2F0Y2hlchIgLmZpbGVzeXN0ZW0uQ3JlYXRlV2F0Y2hlclJlcXVlc3QaIS5maWxlc3lzdGVtLkNyZWF0ZVdhdGNoZXJSZXNwb25zZRJdChBHZXRXYXRjaGVyRXZlbnRzEiMuZmlsZXN5c3RlbS5HZXRXYXRjaGVyRXZlbnRzUmVxdWVzdBokLmZpbGVzeXN0ZW0uR2V0V2F0Y2hlckV2ZW50c1Jlc3BvbnNlElQKDVJlbW92ZVdhdGNoZXISIC5maWxlc3lzdGVtLlJlbW92ZVdhdGNoZXJSZXF1ZXN0GiEuZmlsZXN5c3RlbS5SZW1vdmVXYXRjaGVyUmVzcG9uc2VCaQoOY29tLmZpbGVzeXN0ZW1CD0ZpbGVzeXN0ZW1Qcm90b1ABogIDRlhYqgIKRmlsZXN5c3RlbcoCCkZpbGVzeXN0ZW3iAhZGaWxlc3lzdGVtXEdQQk1ldGFkYXRh6gIKRmlsZXN5c3RlbWIGcHJvdG8z',
27+
'ChtmaWxlc3lzdGVtL2ZpbGVzeXN0ZW0ucHJvdG8SCmZpbGVzeXN0ZW0iMgoLTW92ZVJlcXVlc3QSDgoGc291cmNlGAEgASgJEhMKC2Rlc3RpbmF0aW9uGAIgASgJIjQKDE1vdmVSZXNwb25zZRIkCgVlbnRyeRgBIAEoCzIVLmZpbGVzeXN0ZW0uRW50cnlJbmZvIh4KDk1ha2VEaXJSZXF1ZXN0EgwKBHBhdGgYASABKAkiNwoPTWFrZURpclJlc3BvbnNlEiQKBWVudHJ5GAEgASgLMhUuZmlsZXN5c3RlbS5FbnRyeUluZm8iHQoNUmVtb3ZlUmVxdWVzdBIMCgRwYXRoGAEgASgJIhAKDlJlbW92ZVJlc3BvbnNlIhsKC1N0YXRSZXF1ZXN0EgwKBHBhdGgYASABKAkiNAoMU3RhdFJlc3BvbnNlEiQKBWVudHJ5GAEgASgLMhUuZmlsZXN5c3RlbS5FbnRyeUluZm8i5QIKCUVudHJ5SW5mbxIMCgRuYW1lGAEgASgJEiIKBHR5cGUYAiABKA4yFC5maWxlc3lzdGVtLkZpbGVUeXBlEgwKBHBhdGgYAyABKAkSDAoEc2l6ZRgEIAEoAxIMCgRtb2RlGAUgASgNEhMKC3Blcm1pc3Npb25zGAYgASgJEg0KBW93bmVyGAcgASgJEg0KBWdyb3VwGAggASgJEjEKDW1vZGlmaWVkX3RpbWUYCSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhsKDnN5bWxpbmtfdGFyZ2V0GAogASgJSACIAQESNQoIbWV0YWRhdGEYCyADKAsyIy5maWxlc3lzdGVtLkVudHJ5SW5mby5NZXRhZGF0YUVudHJ5Gi8KDU1ldGFkYXRhRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4AUIRCg9fc3ltbGlua190YXJnZXQiLQoOTGlzdERpclJlcXVlc3QSDAoEcGF0aBgBIAEoCRINCgVkZXB0aBgCIAEoDSI5Cg9MaXN0RGlyUmVzcG9uc2USJgoHZW50cmllcxgBIAMoCzIVLmZpbGVzeXN0ZW0uRW50cnlJbmZvImcKD1dhdGNoRGlyUmVxdWVzdBIMCgRwYXRoGAEgASgJEhEKCXJlY3Vyc2l2ZRgCIAEoCBIVCg1pbmNsdWRlX2VudHJ5GAMgASgIEhwKFGFsbG93X25ldHdvcmtfbW91bnRzGAQgASgIInkKD0ZpbGVzeXN0ZW1FdmVudBIMCgRuYW1lGAEgASgJEiMKBHR5cGUYAiABKA4yFS5maWxlc3lzdGVtLkV2ZW50VHlwZRIpCgVlbnRyeRgDIAEoCzIVLmZpbGVzeXN0ZW0uRW50cnlJbmZvSACIAQFCCAoGX2VudHJ5IuABChBXYXRjaERpclJlc3BvbnNlEjgKBXN0YXJ0GAEgASgLMicuZmlsZXN5c3RlbS5XYXRjaERpclJlc3BvbnNlLlN0YXJ0RXZlbnRIABIxCgpmaWxlc3lzdGVtGAIgASgLMhsuZmlsZXN5c3RlbS5GaWxlc3lzdGVtRXZlbnRIABI7CglrZWVwYWxpdmUYAyABKAsyJi5maWxlc3lzdGVtLldhdGNoRGlyUmVzcG9uc2UuS2VlcEFsaXZlSAAaDAoKU3RhcnRFdmVudBoLCglLZWVwQWxpdmVCBwoFZXZlbnQibAoUQ3JlYXRlV2F0Y2hlclJlcXVlc3QSDAoEcGF0aBgBIAEoCRIRCglyZWN1cnNpdmUYAiABKAgSFQoNaW5jbHVkZV9lbnRyeRgDIAEoCBIcChRhbGxvd19uZXR3b3JrX21vdW50cxgEIAEoCCIrChVDcmVhdGVXYXRjaGVyUmVzcG9uc2USEgoKd2F0Y2hlcl9pZBgBIAEoCSItChdHZXRXYXRjaGVyRXZlbnRzUmVxdWVzdBISCgp3YXRjaGVyX2lkGAEgASgJIkcKGEdldFdhdGNoZXJFdmVudHNSZXNwb25zZRIrCgZldmVudHMYASADKAsyGy5maWxlc3lzdGVtLkZpbGVzeXN0ZW1FdmVudCIqChRSZW1vdmVXYXRjaGVyUmVxdWVzdBISCgp3YXRjaGVyX2lkGAEgASgJIhcKFVJlbW92ZVdhdGNoZXJSZXNwb25zZSpSCghGaWxlVHlwZRIZChVGSUxFX1RZUEVfVU5TUEVDSUZJRUQQABISCg5GSUxFX1RZUEVfRklMRRABEhcKE0ZJTEVfVFlQRV9ESVJFQ1RPUlkQAiqYAQoJRXZlbnRUeXBlEhoKFkVWRU5UX1RZUEVfVU5TUEVDSUZJRUQQABIVChFFVkVOVF9UWVBFX0NSRUFURRABEhQKEEVWRU5UX1RZUEVfV1JJVEUQAhIVChFFVkVOVF9UWVBFX1JFTU9WRRADEhUKEUVWRU5UX1RZUEVfUkVOQU1FEAQSFAoQRVZFTlRfVFlQRV9DSE1PRBAFMp8FCgpGaWxlc3lzdGVtEjkKBFN0YXQSFy5maWxlc3lzdGVtLlN0YXRSZXF1ZXN0GhguZmlsZXN5c3RlbS5TdGF0UmVzcG9uc2USQgoHTWFrZURpchIaLmZpbGVzeXN0ZW0uTWFrZURpclJlcXVlc3QaGy5maWxlc3lzdGVtLk1ha2VEaXJSZXNwb25zZRI5CgRNb3ZlEhcuZmlsZXN5c3RlbS5Nb3ZlUmVxdWVzdBoYLmZpbGVzeXN0ZW0uTW92ZVJlc3BvbnNlEkIKB0xpc3REaXISGi5maWxlc3lzdGVtLkxpc3REaXJSZXF1ZXN0GhsuZmlsZXN5c3RlbS5MaXN0RGlyUmVzcG9uc2USPwoGUmVtb3ZlEhkuZmlsZXN5c3RlbS5SZW1vdmVSZXF1ZXN0GhouZmlsZXN5c3RlbS5SZW1vdmVSZXNwb25zZRJHCghXYXRjaERpchIbLmZpbGVzeXN0ZW0uV2F0Y2hEaXJSZXF1ZXN0GhwuZmlsZXN5c3RlbS5XYXRjaERpclJlc3BvbnNlMAESVAoNQ3JlYXRlV2F0Y2hlchIgLmZpbGVzeXN0ZW0uQ3JlYXRlV2F0Y2hlclJlcXVlc3QaIS5maWxlc3lzdGVtLkNyZWF0ZVdhdGNoZXJSZXNwb25zZRJdChBHZXRXYXRjaGVyRXZlbnRzEiMuZmlsZXN5c3RlbS5HZXRXYXRjaGVyRXZlbnRzUmVxdWVzdBokLmZpbGVzeXN0ZW0uR2V0V2F0Y2hlckV2ZW50c1Jlc3BvbnNlElQKDVJlbW92ZVdhdGNoZXISIC5maWxlc3lzdGVtLlJlbW92ZVdhdGNoZXJSZXF1ZXN0GiEuZmlsZXN5c3RlbS5SZW1vdmVXYXRjaGVyUmVzcG9uc2VCaQoOY29tLmZpbGVzeXN0ZW1CD0ZpbGVzeXN0ZW1Qcm90b1ABogIDRlhYqgIKRmlsZXN5c3RlbcoCCkZpbGVzeXN0ZW3iAhZGaWxlc3lzdGVtXEdQQk1ldGFkYXRh6gIKRmlsZXN5c3RlbWIGcHJvdG8z',
2828
[file_google_protobuf_timestamp]
2929
)
3030

@@ -307,6 +307,14 @@ export type WatchDirRequest = Message<'filesystem.WatchDirRequest'> & {
307307
* @generated from field: bool include_entry = 3;
308308
*/
309309
includeEntry: boolean
310+
311+
/**
312+
* If true, allows watching paths on network filesystem mounts (NFS, CIFS, SMB, FUSE).
313+
* Events on network mounts may be unreliable or not delivered at all.
314+
*
315+
* @generated from field: bool allow_network_mounts = 4;
316+
*/
317+
allowNetworkMounts: boolean
310318
}
311319

312320
/**
@@ -438,6 +446,14 @@ export type CreateWatcherRequest =
438446
* @generated from field: bool include_entry = 3;
439447
*/
440448
includeEntry: boolean
449+
450+
/**
451+
* If true, allows watching paths on network filesystem mounts (NFS, CIFS, SMB, FUSE).
452+
* Events on network mounts may be unreliable or not delivered at all.
453+
*
454+
* @generated from field: bool allow_network_mounts = 4;
455+
*/
456+
allowNetworkMounts: boolean
441457
}
442458

443459
/**

packages/js-sdk/src/envd/versions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ export const ENVD_ENVD_CLOSE = '0.5.2'
66
export const ENVD_OCTET_STREAM_UPLOAD = '0.5.7'
77
export const ENVD_FILE_METADATA = '0.6.2'
88
export const ENVD_VERSION_FS_EVENT_ENTRY_INFO = '0.6.3'
9+
export const ENVD_VERSION_WATCH_NETWORK_MOUNTS = '0.6.4'

packages/js-sdk/src/sandbox/filesystem/index.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import {
3535
ENVD_OCTET_STREAM_UPLOAD,
3636
ENVD_VERSION_FS_EVENT_ENTRY_INFO,
3737
ENVD_VERSION_RECURSIVE_WATCH,
38+
ENVD_VERSION_WATCH_NETWORK_MOUNTS,
3839
} from '../../envd/versions'
3940
import {
4041
FileNotFoundError,
@@ -311,6 +312,15 @@ export interface WatchOpts extends FilesystemRequestOpts {
311312
* throws a `TemplateError`.
312313
*/
313314
includeEntry?: boolean
315+
/**
316+
* Allow watching paths on network filesystem mounts (NFS, CIFS, SMB, FUSE),
317+
* which are rejected by default. Events on network mounts may be unreliable
318+
* or not delivered at all.
319+
*
320+
* Requires envd 0.6.4 or later. Watching with this option against an older sandbox
321+
* throws a `TemplateError`.
322+
*/
323+
allowNetworkMounts?: boolean
314324
}
315325

316326
/**
@@ -909,6 +919,17 @@ export class Filesystem {
909919
)
910920
}
911921

922+
if (
923+
opts?.allowNetworkMounts &&
924+
this.envdApi.version &&
925+
compareVersions(this.envdApi.version, ENVD_VERSION_WATCH_NETWORK_MOUNTS) <
926+
0
927+
) {
928+
throw new TemplateError(
929+
'You need to update the template to watch directories on network mounts.'
930+
)
931+
}
932+
912933
const requestTimeoutMs =
913934
opts?.requestTimeoutMs ?? this.connectionConfig.requestTimeoutMs
914935

@@ -922,6 +943,7 @@ export class Filesystem {
922943
path,
923944
recursive: opts?.recursive ?? this.defaultWatchRecursive,
924945
includeEntry: opts?.includeEntry ?? false,
946+
allowNetworkMounts: opts?.allowNetworkMounts ?? false,
925947
},
926948
{
927949
headers: {

packages/js-sdk/tests/sandbox/files/watch.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,46 @@ sandboxTest('watch directory changes with entry info', async ({ sandbox }) => {
177177
await handle.stop()
178178
})
179179

180+
sandboxTest(
181+
'watch directory changes with network mounts allowed',
182+
async ({ sandbox }) => {
183+
const dirname = 'test_watch_dir_network_mounts'
184+
const filename = 'test_watch.txt'
185+
const content = 'This file will be watched.'
186+
const newContent = 'This file has been modified.'
187+
188+
await sandbox.files.makeDir(dirname)
189+
await sandbox.files.write(`${dirname}/${filename}`, content)
190+
191+
let trigger: () => void
192+
193+
const eventPromise = new Promise<void>((resolve) => {
194+
trigger = resolve
195+
})
196+
197+
// The flag only lifts the network-mount restriction — watching a regular
198+
// directory must work the same with it enabled.
199+
const handle = await sandbox.files.watchDir(
200+
dirname,
201+
async (event) => {
202+
if (
203+
event.type === FilesystemEventType.WRITE &&
204+
event.name === filename
205+
) {
206+
trigger()
207+
}
208+
},
209+
{ allowNetworkMounts: true }
210+
)
211+
212+
await sandbox.files.write(`${dirname}/${filename}`, newContent)
213+
214+
await eventPromise
215+
216+
await handle.stop()
217+
}
218+
)
219+
180220
sandboxTest('watch non-existing directory', async ({ sandbox }) => {
181221
const dirname = 'non_existing_watch_dir'
182222

0 commit comments

Comments
 (0)