@efffrida/frida-tools 0.0.26 → 0.0.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/FridaDevice.d.ts +9 -8
  2. package/dist/FridaDevice.d.ts.map +1 -1
  3. package/dist/FridaDevice.js.map +1 -1
  4. package/dist/FridaDeviceAcquisitionError.d.ts +3 -18
  5. package/dist/FridaDeviceAcquisitionError.d.ts.map +1 -1
  6. package/dist/FridaDeviceAcquisitionError.js +2 -13
  7. package/dist/FridaDeviceAcquisitionError.js.map +1 -1
  8. package/dist/FridaScript.d.ts +12 -13
  9. package/dist/FridaScript.d.ts.map +1 -1
  10. package/dist/FridaScript.js +10 -9
  11. package/dist/FridaScript.js.map +1 -1
  12. package/dist/FridaSession.d.ts +21 -7
  13. package/dist/FridaSession.d.ts.map +1 -1
  14. package/dist/FridaSession.js.map +1 -1
  15. package/dist/FridaSessionError.d.ts +1 -16
  16. package/dist/FridaSessionError.d.ts.map +1 -1
  17. package/dist/FridaSessionError.js +2 -13
  18. package/dist/FridaSessionError.js.map +1 -1
  19. package/dist/internal/compiler.d.ts +2 -0
  20. package/dist/internal/compiler.d.ts.map +1 -0
  21. package/dist/internal/compiler.js +82 -0
  22. package/dist/internal/compiler.js.map +1 -0
  23. package/dist/internal/device.js +33 -32
  24. package/dist/internal/device.js.map +1 -1
  25. package/dist/internal/script.js +56 -105
  26. package/dist/internal/script.js.map +1 -1
  27. package/dist/internal/session.js +90 -48
  28. package/dist/internal/session.js.map +1 -1
  29. package/package.json +11 -17
  30. package/src/FridaDevice.ts +11 -10
  31. package/src/FridaDeviceAcquisitionError.ts +4 -29
  32. package/src/FridaScript.ts +22 -23
  33. package/src/FridaSession.ts +25 -7
  34. package/src/FridaSessionError.ts +2 -24
  35. package/src/internal/compiler.ts +122 -0
  36. package/src/internal/device.ts +85 -67
  37. package/src/internal/script.ts +209 -292
  38. package/src/internal/session.ts +116 -52
@@ -1,27 +1,28 @@
1
1
  import type * as Scope from "effect/Scope";
2
2
 
3
- import * as FileSystem from "@effect/platform/FileSystem";
4
- import * as Path from "@effect/platform/Path";
5
3
  import * as Cause from "effect/Cause";
6
- import * as Chunk from "effect/Chunk";
7
4
  import * as Context from "effect/Context";
8
5
  import * as Deferred from "effect/Deferred";
9
6
  import * as Effect from "effect/Effect";
10
7
  import * as Exit from "effect/Exit";
8
+ import * as FileSystem from "effect/FileSystem";
11
9
  import * as Function from "effect/Function";
12
10
  import * as Layer from "effect/Layer";
13
- import * as Mailbox from "effect/Mailbox";
14
11
  import * as Option from "effect/Option";
12
+ import * as Path from "effect/Path";
15
13
  import * as Predicate from "effect/Predicate";
14
+ import * as Queue from "effect/Queue";
16
15
  import * as Schema from "effect/Schema";
17
16
  import * as Sink from "effect/Sink";
18
17
  import * as Stream from "effect/Stream";
19
- import * as Frida from "frida";
20
18
 
21
19
  import type * as FridaScript from "../FridaScript.ts";
22
20
 
21
+ import * as Frida from "frida";
22
+
23
23
  import * as FridaSession from "../FridaSession.ts";
24
24
  import * as FridaSessionError from "../FridaSessionError.ts";
25
+ import * as internalCompiler from "./compiler.ts";
25
26
 
26
27
  /** @internal */
27
28
  export const FridaScriptTypeId: FridaScript.FridaScriptTypeId = Symbol.for(
@@ -29,112 +30,11 @@ export const FridaScriptTypeId: FridaScript.FridaScriptTypeId = Symbol.for(
29
30
  ) as FridaScript.FridaScriptTypeId;
30
31
 
31
32
  /** @internal */
32
- export const Tag = Context.GenericTag<FridaScript.FridaScript>("@efffrida/frida-tools/FridaScript");
33
+ export const Tag = Context.Service<FridaScript.FridaScript>("@efffrida/frida-tools/FridaScript");
33
34
 
34
35
  /** @internal */
35
36
  export const isFridaScript = (u: unknown): u is FridaScript.FridaScript => Predicate.hasProperty(u, FridaScriptTypeId);
36
37
 
37
- /** @internal */
38
- export const compile = Function.dual<
39
- (
40
- options?: Frida.CompilerOptions | undefined
41
- ) => (path: string) => Effect.Effect<string, FridaSessionError.FridaSessionError, Scope.Scope>,
42
- (
43
- path: string,
44
- options?: Frida.CompilerOptions | undefined
45
- ) => Effect.Effect<string, FridaSessionError.FridaSessionError, Scope.Scope>
46
- >(
47
- (arguments_) => Predicate.isString(arguments_[0]),
48
- (path: string, options?: Frida.CompilerOptions | undefined) =>
49
- Effect.asyncEffect<string, FridaSessionError.FridaSessionError, never, never, never, Scope.Scope>(
50
- Effect.fnUntraced(function* (resume) {
51
- // https://github.com/frida/frida-compile/blob/e81ae27369466c69868fc6ee36c0f227bbfe340c/src/cli.ts#L173-L182
52
- interface Diagnostic {
53
- category: string;
54
- code: number;
55
- text: string;
56
- file?: {
57
- path: string;
58
- line: number;
59
- character: number;
60
- };
61
- }
62
-
63
- const formatDiagnostic = (diagnostic: Diagnostic): FridaSessionError.FridaSessionError => {
64
- const location = diagnostic.file
65
- ? `${diagnostic.file.path}:${diagnostic.file.line}:${diagnostic.file.character}`
66
- : undefined;
67
- const message = `TS${diagnostic.code}: ${diagnostic.text}`;
68
- const cause = location ? `${location} - ${message}` : message;
69
- return new FridaSessionError.FridaSessionError({ cause, when: "compile" });
70
- };
71
-
72
- const compileErrors: Array<Diagnostic> = [];
73
- const compiler = new Frida.Compiler();
74
-
75
- const onOutput = (bundle: string) => resume(Effect.succeed(bundle));
76
- yield* Effect.addFinalizer(() => Effect.sync(() => compiler.output.disconnect(onOutput)));
77
- compiler.output.connect(onOutput);
78
-
79
- const onDiagnostic = (diagnostic: Array<Diagnostic>) => {
80
- for (const diag of diagnostic) {
81
- if (diag.category === "error") {
82
- compileErrors.push(diag);
83
- }
84
- }
85
- };
86
- yield* Effect.addFinalizer(() => Effect.sync(() => compiler.diagnostics.disconnect(onDiagnostic)));
87
- compiler.diagnostics.connect(onDiagnostic);
88
-
89
- const onFinished = () => {
90
- if (compileErrors.length > 0) {
91
- resume(
92
- Effect.failCauseSync(() => {
93
- const [first, ...rest] = compileErrors;
94
- let cause = Cause.fail(formatDiagnostic(first));
95
- for (const diag of rest) {
96
- cause = Cause.parallel(cause, Cause.fail(formatDiagnostic(diag)));
97
- }
98
- return cause;
99
- })
100
- );
101
- }
102
- };
103
- yield* Effect.addFinalizer(() => Effect.sync(() => compiler.finished.disconnect(onFinished)));
104
- compiler.finished.connect(onFinished);
105
-
106
- const cancellable = new Frida.Cancellable();
107
- compiler
108
- .build(
109
- path,
110
- {
111
- externals: options?.externals,
112
- projectRoot: options?.projectRoot,
113
- platform: options?.platform ?? Frida.JsPlatform.Gum,
114
- typeCheck: options?.typeCheck ?? Frida.TypeCheckMode.Full,
115
- sourceMaps: options?.sourceMaps ?? Frida.SourceMaps.Included,
116
- compression: options?.compression ?? Frida.JsCompression.None,
117
- bundleFormat: options?.bundleFormat ?? Frida.BundleFormat.Esm,
118
- outputFormat: options?.outputFormat ?? Frida.OutputFormat.Unescaped,
119
- },
120
- cancellable
121
- )
122
- .catch((error) =>
123
- resume(
124
- Effect.fail(
125
- new FridaSessionError.FridaSessionError({
126
- cause: error,
127
- when: "compile",
128
- })
129
- )
130
- )
131
- );
132
-
133
- return Effect.sync(() => cancellable.cancel());
134
- })
135
- )
136
- );
137
-
138
38
  /** @internal */
139
39
  export const load = Function.dual<
140
40
  (
@@ -156,202 +56,219 @@ export const load = Function.dual<
156
56
  >
157
57
  >(
158
58
  (arguments_) => Predicate.hasProperty(arguments_[0], "href"),
159
- Effect.fnUntraced(
160
- function* (entrypoint: URL, options?: FridaScript.LoadOptions | undefined) {
161
- const path = yield* Path.Path;
162
- const { session } = yield* FridaSession.FridaSession;
59
+ Effect.fnUntraced(function* (entrypoint: URL, options?: FridaScript.LoadOptions | undefined) {
60
+ const path = yield* Path.Path;
61
+ const { session } = yield* FridaSession.FridaSession;
163
62
 
164
- const projectRoot = yield* path.fromFileUrl(entrypoint).pipe(
165
- Effect.mapError(
166
- (cause) =>
167
- new FridaSessionError.FridaSessionError({
168
- when: "compile",
169
- cause,
170
- })
171
- ),
172
- Effect.map((p) => path.dirname(p))
173
- );
174
-
175
- const source = yield* path.fromFileUrl(entrypoint).pipe(
176
- Effect.flatMap(
177
- compile({
178
- ...options,
179
- projectRoot: options?.projectRoot ?? projectRoot,
180
- })
181
- ),
182
- Effect.scoped,
183
- Effect.timeoutFail({
184
- duration: "1 minute",
185
- onTimeout: () =>
186
- new FridaSessionError.FridaSessionError({
187
- when: "compile",
188
- cause: "TypeScript compilation timed out",
189
- }),
190
- }),
191
- Effect.catchTag(
192
- "BadArgument",
193
- (platformCause) =>
194
- new FridaSessionError.FridaSessionError({
195
- when: "compile",
196
- cause: platformCause,
197
- })
198
- )
199
- );
200
-
201
- const script = yield* Effect.tryPromise({
202
- try: (signal) => {
203
- const cancellable = new Frida.Cancellable();
204
- signal.onabort = () => cancellable.cancel();
205
- return session.createScript(
206
- source,
207
- {
208
- runtime: Frida.ScriptRuntime.V8,
209
- ...options,
210
- },
211
- cancellable
212
- );
213
- },
214
- catch: (cause) =>
63
+ const projectRoot = yield* path.fromFileUrl(entrypoint).pipe(
64
+ Effect.mapError(
65
+ (cause) =>
215
66
  new FridaSessionError.FridaSessionError({
67
+ when: "compile",
216
68
  cause,
69
+ })
70
+ ),
71
+ Effect.map((p) => path.dirname(p))
72
+ );
73
+
74
+ const source = yield* path.fromFileUrl(entrypoint).pipe(
75
+ Effect.flatMap(
76
+ internalCompiler.compile({
77
+ ...options,
78
+ projectRoot: options?.projectRoot ?? projectRoot,
79
+ })
80
+ ),
81
+ Effect.timeoutOrElse({
82
+ duration: "1 minute",
83
+ orElse: () =>
84
+ new FridaSessionError.FridaSessionError({
85
+ cause: "Compilation timed out",
217
86
  when: "compile",
218
87
  }),
219
- });
88
+ }),
89
+ Effect.catchTag(
90
+ "BadArgument",
91
+ (platformCause) =>
92
+ new FridaSessionError.FridaSessionError({
93
+ cause: platformCause,
94
+ when: "compile",
95
+ })
96
+ )
97
+ );
220
98
 
221
- const destroyed = yield* Deferred.make<void, never>();
222
- const scriptError = yield* Deferred.make<unknown, never>();
223
- const mailbox = yield* Mailbox.make<
224
- { message: unknown; data: Option.Option<Buffer> },
225
- FridaSessionError.FridaSessionError
226
- >(options?.messageMailboxCapacity);
227
- yield* Effect.addFinalizer(() => mailbox.shutdown); // TODO: is this needed?
228
-
229
- const destroyedHandler: Frida.ScriptDestroyedHandler = () => {
230
- Deferred.unsafeDone(destroyed, Effect.void);
231
- mailbox.unsafeDone(
232
- Exit.fail(
233
- new FridaSessionError.FridaSessionError({
234
- cause: "Script destroyed",
235
- when: "message",
236
- })
237
- )
99
+ const script = yield* Effect.tryPromise({
100
+ try: (signal) => {
101
+ const cancellable = new Frida.Cancellable();
102
+ signal.onabort = () => cancellable.cancel();
103
+ return session.createScript(
104
+ source,
105
+ {
106
+ runtime: Frida.ScriptRuntime.V8,
107
+ ...options,
108
+ },
109
+ cancellable
238
110
  );
239
- };
240
- yield* Effect.addFinalizer(() => Effect.sync(() => script.destroyed.disconnect(destroyedHandler)));
241
- script.destroyed.connect(destroyedHandler);
242
-
243
- const messageHandler: Frida.ScriptMessageHandler = (message: Frida.Message, data: Buffer | null): void => {
244
- switch (message.type) {
245
- case Frida.MessageType.Error: {
246
- const cause = new Error();
247
- cause.name = "FridaScriptDefect";
248
- cause.stack = message.stack ?? "";
249
- cause.message = message.description.replace(/^\w{0,}: /, "") ?? "";
250
- Deferred.unsafeDone(scriptError, Exit.succeed(cause));
251
- mailbox.unsafeDone(
252
- Exit.fail(
253
- new FridaSessionError.FridaSessionError({
254
- when: "message",
255
- cause,
256
- })
257
- )
258
- );
259
- break;
260
- }
261
-
262
- case Frida.MessageType.Send: {
263
- mailbox.unsafeOffer({
264
- message: message.payload,
265
- data: Option.fromNullable(data),
266
- });
267
- break;
268
- }
269
-
270
- default: {
271
- return Function.absurd(message);
272
- }
273
- }
274
- };
275
- yield* Effect.addFinalizer(() => Effect.sync(() => script.message.disconnect(messageHandler)));
276
- script.message.connect(messageHandler);
277
-
278
- const failIfScriptError = (when: FridaSessionError.FridaSessionError["when"]) =>
279
- Effect.if(Deferred.isDone(scriptError), {
280
- onFalse: () => Effect.void,
281
- onTrue: () =>
282
- Effect.flatMap(
283
- Deferred.await(scriptError),
284
- (cause) => new FridaSessionError.FridaSessionError({ cause, when })
285
- ),
286
- });
287
-
288
- const failIfDestroyed = (when: FridaSessionError.FridaSessionError["when"]) =>
289
- Effect.if(Deferred.isDone(destroyed), {
290
- onFalse: () => Effect.void,
291
- onTrue: () => new FridaSessionError.FridaSessionError({ cause: "Script is destroyed", when }),
292
- });
293
-
294
- const stream = yield* Stream.share(
295
- Mailbox.toStream(mailbox),
296
- options?.streamShareOptions ?? {
297
- replay: 100,
298
- capacity: "unbounded",
299
- }
300
- );
111
+ },
112
+ catch: (cause) =>
113
+ new FridaSessionError.FridaSessionError({
114
+ when: "compile",
115
+ cause,
116
+ }),
117
+ });
301
118
 
302
- const sink = Sink.forEach<
303
- { message: unknown; data: Option.Option<Buffer> },
304
- void,
305
- FridaSessionError.FridaSessionError,
306
- never
307
- >(
308
- Effect.fnUntraced(function* ({ data, message }) {
309
- yield* failIfDestroyed("message");
310
- yield* failIfScriptError("message");
311
- script.post(message, Option.getOrNull(data));
312
- })
119
+ yield* Effect.addFinalizer(() =>
120
+ Effect.promise((signal) => {
121
+ const cancellable = new Frida.Cancellable();
122
+ signal.onabort = () => cancellable.cancel();
123
+ return script.unload(cancellable);
124
+ })
125
+ );
126
+
127
+ const scriptError = yield* Deferred.make<unknown, never>();
128
+ const destroyed = yield* Deferred.make<void, never>();
129
+
130
+ const queue = yield* Queue.make<
131
+ { message: unknown; data: Option.Option<Buffer> },
132
+ FridaSessionError.FridaSessionError
133
+ >(options?.messageMailboxCapacity);
134
+ yield* Effect.addFinalizer(() => Queue.shutdown(queue));
135
+
136
+ const destroyedHandler: Frida.ScriptDestroyedHandler = () => {
137
+ Deferred.doneUnsafe(destroyed, Exit.void);
138
+ Queue.failCauseUnsafe(
139
+ queue,
140
+ Cause.fail(
141
+ new FridaSessionError.FridaSessionError({
142
+ cause: "Script destroyed",
143
+ when: "message",
144
+ })
145
+ )
313
146
  );
147
+ };
148
+ yield* Effect.addFinalizer(() => Effect.sync(() => script.destroyed.disconnect(destroyedHandler)));
149
+ script.destroyed.connect(destroyedHandler);
150
+
151
+ const messageHandler: Frida.ScriptMessageHandler = (message: Frida.Message, data: Buffer | null): void => {
152
+ switch (message.type) {
153
+ case Frida.MessageType.Error: {
154
+ const cause = new Error();
155
+ cause.name = "FridaScriptDefect";
156
+ cause.stack = message.stack ?? "";
157
+ cause.message = message.description.replace(/^\w{0,}: /, "") ?? "";
158
+ Deferred.doneUnsafe(scriptError, Exit.succeed(cause));
159
+ Queue.failCauseUnsafe(
160
+ queue,
161
+ Cause.fail(
162
+ new FridaSessionError.FridaSessionError({
163
+ when: "message",
164
+ cause,
165
+ })
166
+ )
167
+ );
168
+ break;
169
+ }
314
170
 
315
- const callExport = <A, I, R>(exportName: string, schema: Schema.Schema<A, I, R>) =>
316
- Effect.fn(`call frida export ${exportName}`)(function* (...args: Array<any>) {
317
- yield* Effect.annotateCurrentSpan("args", args);
318
- yield* failIfDestroyed("rpcCall");
319
- yield* failIfScriptError("rpcCall");
320
- const result = yield* Effect.tryPromise({
321
- try: () => script.exports[exportName](...args) as Promise<unknown>,
322
- catch: (cause) => new FridaSessionError.FridaSessionError({ when: "rpcCall", cause }),
171
+ case Frida.MessageType.Send: {
172
+ Queue.offerUnsafe(queue, {
173
+ message: message.payload,
174
+ data: Option.fromNullishOr(data),
323
175
  });
324
- yield* Effect.annotateCurrentSpan("result", result);
325
- return yield* Schema.decodeUnknown(schema)(result);
326
- });
176
+ break;
177
+ }
327
178
 
328
- yield* Effect.tryPromise({
329
- try: (signal) => {
330
- const cancellable = new Frida.Cancellable();
331
- signal.onabort = () => cancellable.cancel();
332
- return script.load(cancellable);
333
- },
334
- catch: (cause) => new FridaSessionError.FridaSessionError({ cause, when: "load" }),
179
+ default: {
180
+ return Function.absurd(message);
181
+ }
182
+ }
183
+ };
184
+ yield* Effect.addFinalizer(() => Effect.sync(() => script.message.disconnect(messageHandler)));
185
+ script.message.connect(messageHandler);
186
+
187
+ const failIfScriptError = Effect.fnUntraced(function* (when: FridaSessionError.FridaSessionError["when"]) {
188
+ const isDone = yield* Deferred.isDone(scriptError);
189
+ if (!isDone) return yield* Effect.void;
190
+ const cause = yield* Deferred.await(scriptError);
191
+ return yield* new FridaSessionError.FridaSessionError({
192
+ cause,
193
+ when,
194
+ });
195
+ });
196
+
197
+ const failIfDestroyed = Effect.fnUntraced(function* (when: FridaSessionError.FridaSessionError["when"]) {
198
+ const isDone = yield* Deferred.isDone(destroyed);
199
+ if (!isDone) return yield* Effect.void;
200
+ return yield* new FridaSessionError.FridaSessionError({
201
+ cause: "Script is destroyed",
202
+ when,
203
+ });
204
+ });
205
+
206
+ const stream = yield* Stream.share(
207
+ Stream.fromQueue(queue),
208
+ options?.streamShareOptions ?? {
209
+ strategy: "suspend",
210
+ capacity: 100,
211
+ replay: 100,
212
+ }
213
+ );
214
+
215
+ const sink = Sink.forEach<
216
+ { message: unknown; data: Option.Option<Buffer> },
217
+ void,
218
+ FridaSessionError.FridaSessionError,
219
+ never
220
+ >(
221
+ Effect.fnUntraced(function* ({ data, message }) {
222
+ yield* failIfDestroyed("message");
223
+ yield* failIfScriptError("message");
224
+ script.post(message, Option.getOrNull(data));
225
+ })
226
+ );
227
+
228
+ const callExport = <A = unknown, R = never>(exportName: string, schema?: Schema.Decoder<A, R> | undefined) =>
229
+ Effect.fn(`call frida export ${exportName}`)(function* (
230
+ ...args: Array<any>
231
+ ): Effect.fn.Return<A, FridaSessionError.FridaSessionError | Schema.SchemaError, R> {
232
+ yield* Effect.annotateCurrentSpan("args", args);
233
+ yield* failIfDestroyed("rpcCall");
234
+ yield* failIfScriptError("rpcCall");
235
+ const result = yield* Effect.tryPromise({
236
+ try: () => script.exports[exportName](...args),
237
+ catch: (cause) =>
238
+ new FridaSessionError.FridaSessionError({
239
+ when: "rpcCall",
240
+ cause,
241
+ }),
242
+ });
243
+ yield* Effect.annotateCurrentSpan("result", result);
244
+ const decoder = Schema.decodeEffect(schema ?? Schema.Unknown);
245
+ const decoded = yield* decoder(result);
246
+ return decoded as A;
335
247
  });
336
248
 
337
- return {
338
- sink,
339
- stream,
340
- script,
341
- destroyed,
342
- callExport,
343
- scriptError,
344
- [FridaScriptTypeId]: FridaScriptTypeId,
345
- } as const;
346
- },
347
- Effect.acquireRelease(({ script }: FridaScript.FridaScript) =>
348
- Effect.promise((signal) => {
249
+ yield* Effect.tryPromise({
250
+ try: (signal) => {
349
251
  const cancellable = new Frida.Cancellable();
350
252
  signal.onabort = () => cancellable.cancel();
351
- return script.unload(cancellable);
352
- })
353
- )
354
- )
253
+ return script.load(cancellable);
254
+ },
255
+ catch: (cause) =>
256
+ new FridaSessionError.FridaSessionError({
257
+ when: "load",
258
+ cause,
259
+ }),
260
+ });
261
+
262
+ return {
263
+ sink,
264
+ stream,
265
+ script,
266
+ destroyed,
267
+ callExport,
268
+ scriptError,
269
+ [FridaScriptTypeId]: FridaScriptTypeId,
270
+ } as const;
271
+ })
355
272
  );
356
273
 
357
274
  /** @internal */
@@ -368,7 +285,7 @@ export const layer = Function.dual<
368
285
  >(
369
286
  (arguments_) => Predicate.hasProperty(arguments_[0], "href"),
370
287
  (entrypoint: URL, options?: FridaScript.LoadOptions | undefined) =>
371
- Layer.scoped(Tag, load(entrypoint, options)).pipe(Layer.provide(Path.layer))
288
+ Layer.effect(Tag, load(entrypoint, options)).pipe(Layer.provide(Path.layer))
372
289
  );
373
290
 
374
291
  /** @internal */
@@ -422,7 +339,7 @@ export const watch = Function.dual<
422
339
 
423
340
  return fileSystem.watch(pathString).pipe(
424
341
  Stream.filter((event) => event._tag === "Update"),
425
- Stream.prepend(Chunk.of(FileSystem.WatchEventUpdate({ path: pathString }))),
342
+ Stream.prepend([{ _tag: "Update" as const, path: pathString }]),
426
343
  Stream.debounce("2 second"),
427
344
  Stream.mapError(
428
345
  (cause) =>
@@ -444,7 +361,7 @@ export const watch = Function.dual<
444
361
  );
445
362
  },
446
363
  Stream.unwrap,
447
- Stream.provideSomeLayer(Path.layer)
364
+ Stream.provide(Path.layer)
448
365
  )
449
366
  );
450
367
 
@@ -462,12 +379,12 @@ export const logWatchErrors = <A, E1, E2, R>(
462
379
  const cause = exit.cause;
463
380
 
464
381
  // Interruption only
465
- if (Cause.isInterruptedOnly(cause)) {
382
+ if (Cause.hasInterruptsOnly(cause)) {
466
383
  return Effect.logDebug("Script interrupted with no errors");
467
384
  }
468
385
 
469
386
  // Defect
470
- if (Cause.isDie(cause)) {
387
+ if (Cause.hasDies(cause)) {
471
388
  return Effect.logError(cause);
472
389
  }
473
390