Repository: scala-steward-org/scala-steward
Pull request #2059 (2021-04-05 12:42:17)

Update to Cats Effect 3

codecov[bot]: # [Codecov](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059?src=pr&el=h1) Report
> Merging [#2059](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059?src=pr&el=desc) (2ce2c14) into [master](https://codecov.io/gh/scala-steward-org/scala-steward/commit/fd41188318adc545a745fde31eb80e9d6a7cbc95?el=desc) (fd41188) will **decrease** coverage by `0.23%`.
> The diff coverage is `59.45%`.

> :exclamation: Current head 2ce2c14 differs from pull request most recent head 2af7b28. Consider uploading reports for the commit 2af7b28 to get more accurate results
[![Impacted file tree graph](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059/graphs/tree.svg?width=650&height=150&src=pr&token=udzMsc1Dne)](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #2059      +/-   ##
==========================================
- Coverage   78.62%   78.38%   -0.24%     
==========================================
  Files         131      131              
  Lines        2255     2272      +17     
  Branches       57       57              
==========================================
+ Hits         1773     1781       +8     
- Misses        482      491       +9     
```


| [Impacted Files](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [...la/org/scalasteward/core/application/Context.scala](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059/diff?src=pr&el=tree#diff-bW9kdWxlcy9jb3JlL3NyYy9tYWluL3NjYWxhL29yZy9zY2FsYXN0ZXdhcmQvY29yZS9hcHBsaWNhdGlvbi9Db250ZXh0LnNjYWxh) | `86.44% <0.00%> (ø)` | |
| [...org/scalasteward/core/application/StewardAlg.scala](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059/diff?src=pr&el=tree#diff-bW9kdWxlcy9jb3JlL3NyYy9tYWluL3NjYWxhL29yZy9zY2FsYXN0ZXdhcmQvY29yZS9hcHBsaWNhdGlvbi9TdGV3YXJkQWxnLnNjYWxh) | `44.11% <0.00%> (-1.34%)` | :arrow_down: |
| [...org/scalasteward/core/buildtool/mill/MillAlg.scala](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059/diff?src=pr&el=tree#diff-bW9kdWxlcy9jb3JlL3NyYy9tYWluL3NjYWxhL29yZy9zY2FsYXN0ZXdhcmQvY29yZS9idWlsZHRvb2wvbWlsbC9NaWxsQWxnLnNjYWxh) | `90.90% <ø> (ø)` | |
| [...a/org/scalasteward/core/buildtool/sbt/SbtAlg.scala](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059/diff?src=pr&el=tree#diff-bW9kdWxlcy9jb3JlL3NyYy9tYWluL3NjYWxhL29yZy9zY2FsYXN0ZXdhcmQvY29yZS9idWlsZHRvb2wvc2J0L1NidEFsZy5zY2FsYQ==) | `94.87% <ø> (ø)` | |
| [...a/org/scalasteward/core/coursier/CoursierAlg.scala](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059/diff?src=pr&el=tree#diff-bW9kdWxlcy9jb3JlL3NyYy9tYWluL3NjYWxhL29yZy9zY2FsYXN0ZXdhcmQvY29yZS9jb3Vyc2llci9Db3Vyc2llckFsZy5zY2FsYQ==) | `84.84% <ø> (-0.87%)` | :arrow_down: |
| [...ain/scala/org/scalasteward/core/edit/EditAlg.scala](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059/diff?src=pr&el=tree#diff-bW9kdWxlcy9jb3JlL3NyYy9tYWluL3NjYWxhL29yZy9zY2FsYXN0ZXdhcmQvY29yZS9lZGl0L0VkaXRBbGcuc2NhbGE=) | `58.62% <ø> (ø)` | |
| [...in/scala/org/scalasteward/core/git/GenGitAlg.scala](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059/diff?src=pr&el=tree#diff-bW9kdWxlcy9jb3JlL3NyYy9tYWluL3NjYWxhL29yZy9zY2FsYXN0ZXdhcmQvY29yZS9naXQvR2VuR2l0QWxnLnNjYWxh) | `92.00% <ø> (ø)` | |
| [...in/scala/org/scalasteward/core/io/ProcessAlg.scala](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059/diff?src=pr&el=tree#diff-bW9kdWxlcy9jb3JlL3NyYy9tYWluL3NjYWxhL29yZy9zY2FsYXN0ZXdhcmQvY29yZS9pby9Qcm9jZXNzQWxnLnNjYWxh) | `100.00% <ø> (ø)` | |
| [...ala/org/scalasteward/core/nurture/NurtureAlg.scala](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059/diff?src=pr&el=tree#diff-bW9kdWxlcy9jb3JlL3NyYy9tYWluL3NjYWxhL29yZy9zY2FsYXN0ZXdhcmQvY29yZS9udXJ0dXJlL051cnR1cmVBbGcuc2NhbGE=) | `0.00% <ø> (-4.72%)` | :arrow_down: |
| [...teward/core/persistence/CachingKeyValueStore.scala](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059/diff?src=pr&el=tree#diff-bW9kdWxlcy9jb3JlL3NyYy9tYWluL3NjYWxhL29yZy9zY2FsYXN0ZXdhcmQvY29yZS9wZXJzaXN0ZW5jZS9DYWNoaW5nS2V5VmFsdWVTdG9yZS5zY2FsYQ==) | `100.00% <ø> (ø)` | |
| ... and [16 more](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059?src=pr&el=footer). Last update [fd41188...2af7b28](https://codecov.io/gh/scala-steward-org/scala-steward/pull/2059?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/build.sbt b/build.sbt
index 7a359637..3be8bc2b 100644
--- a/build.sbt
+++ b/build.sbt
@@ -91,7 +91,6 @@ lazy val core = myCrossProject("core")
       Dependencies.circeRefined,
       Dependencies.commonsIo,
       Dependencies.coursierCore,
-      Dependencies.coursierCatsInterop,
       Dependencies.cron4sCore,
       Dependencies.fs2Core,
       Dependencies.fs2Io,
@@ -106,7 +105,6 @@ lazy val core = myCrossProject("core")
       Dependencies.monocleCore,
       Dependencies.refined,
       Dependencies.scalacacheCaffeine,
-      Dependencies.scalacacheCatsEffect,
       Dependencies.logbackClassic % Runtime,
       Dependencies.catsLaws % Test,
       Dependencies.circeLiteral % Test,
@@ -339,9 +337,8 @@ addCommandsAlias(
   Seq(
     "clean",
     "headerCheck",
-    "scalafmtCheck",
+    "scalafmtCheckAll",
     "scalafmtSbtCheck",
-    "test:scalafmtCheck",
     "unusedCompileDependenciesTest",
     "coverage",
     "test",
@@ -350,7 +347,7 @@ addCommandsAlias(
     "package",
     "packageSrc",
     "core/assembly",
-    "docker:publishLocal"
+    "Docker/publishLocal"
   )
 )
 
@@ -358,8 +355,7 @@ addCommandsAlias(
   "fmt",
   Seq(
     "headerCreate",
-    "scalafmt",
-    "test:scalafmt",
+    "scalafmtAll",
     "scalafmtSbt"
   )
 )
diff --git a/modules/core/src/main/scala/org/scalasteward/core/application/Context.scala b/modules/core/src/main/scala/org/scalasteward/core/application/Context.scala
index 8d449945..e3fbb864 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/application/Context.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/application/Context.scala
@@ -16,8 +16,8 @@
 
 package org.scalasteward.core.application
 
-import cats.Parallel
 import cats.effect._
+import cats.effect.implicits._
 import cats.syntax.all._
 import org.http4s.Uri
 import org.http4s.client.Client
@@ -72,29 +72,22 @@ final class Context[F[_]](implicit
 )
 
 object Context {
-  def step0[F[_]](args: Cli.Args)(implicit
-      contextShift: ContextShift[F],
-      parallel: Parallel[F],
-      timer: Timer[F],
-      F: ConcurrentEffect[F]
-  ): Resource[F, Context[F]] =
+  def step0[F[_]](args: Cli.Args)(implicit F: Async[F]): Resource[F, Context[F]] =
     for {
-      blocker <- Blocker[F]
+      _ <- Resource.unit[F]
       config = Config.from(args)
       implicit0(logger: Logger[F]) <- Resource.eval(Slf4jLogger.create[F])
-      implicit0(client: Client[F]) <- OkHttpBuilder.withDefaultClient[F](blocker).map(_.create)
+      implicit0(client: Client[F]) <- OkHttpBuilder.withDefaultClient[F].flatMap(_.resource)
       implicit0(fileAlg: FileAlg[F]) = FileAlg.create[F]
-      implicit0(processAlg: ProcessAlg[F]) = ProcessAlg.create[F](blocker, config.processCfg)
+      implicit0(processAlg: ProcessAlg[F]) = ProcessAlg.create[F](config.processCfg)
       implicit0(workspaceAlg: WorkspaceAlg[F]) = WorkspaceAlg.create[F](config)
       context <- Resource.eval(step1[F](config))
     } yield context
 
   def step1[F[_]](config: Config)(implicit
       client: Client[F],
-      contextShift: ContextShift[F],
       fileAlg: FileAlg[F],
       logger: Logger[F],
-      parallel: Parallel[F],
       processAlg: ProcessAlg[F],
       workspaceAlg: WorkspaceAlg[F],
       F: Async[F]
diff --git a/modules/core/src/main/scala/org/scalasteward/core/application/StewardAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/application/StewardAlg.scala
index af9692cf..cfb94238 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/application/StewardAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/application/StewardAlg.scala
@@ -17,7 +17,7 @@
 package org.scalasteward.core.application
 
 import better.files.File
-import cats.effect.{BracketThrow, ExitCode}
+import cats.effect.{ExitCode, Sync}
 import cats.syntax.all._
 import fs2.Stream
 import org.scalasteward.core.buildtool.sbt.SbtAlg
@@ -47,9 +47,8 @@ final class StewardAlg[F[_]](config: Config)(implicit
     repoCacheAlg: RepoCacheAlg[F],
     sbtAlg: SbtAlg[F],
     selfCheckAlg: SelfCheckAlg[F],
-    streamCompiler: Stream.Compiler[F, F],
     workspaceAlg: WorkspaceAlg[F],
-    F: BracketThrow[F]
+    F: Sync[F]
 ) {
   private def readRepos(reposFile: File): Stream[F, Repo] =
     Stream.evals[F, List, Repo] {
@@ -85,13 +84,14 @@ final class StewardAlg[F[_]](config: Config)(implicit
     val label = s"Steward ${repo.show}"
     logger.infoTotalTime(label) {
       logger.attemptLogLabel(util.string.lineLeftRight(label), Some(label)) {
-        F.guarantee {
+        F.guarantee(
           for {
             (data, fork) <- repoCacheAlg.checkCache(repo)
             (attentionNeeded, updates) <- pruningAlg.needsAttention(data)
             _ <- if (attentionNeeded) nurtureAlg.nurture(data, fork, updates) else F.unit
-          } yield ()
-        }(gitAlg.removeClone(repo))
+          } yield (),
+          gitAlg.removeClone(repo)
+        )
       }
     }
   }
diff --git a/modules/core/src/main/scala/org/scalasteward/core/buildtool/mill/MillAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/buildtool/mill/MillAlg.scala
index f39ab3d5..a4f5fc05 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/buildtool/mill/MillAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/buildtool/mill/MillAlg.scala
@@ -16,14 +16,14 @@
 
 package org.scalasteward.core.buildtool.mill
 
-import cats.effect.BracketThrow
+import cats.effect.MonadCancelThrow
 import cats.syntax.all._
 import org.scalasteward.core.BuildInfo
 import org.scalasteward.core.buildtool.BuildToolAlg
 import org.scalasteward.core.data.Scope
 import org.scalasteward.core.data.Scope.Dependencies
-import org.scalasteward.core.io.{FileAlg, ProcessAlg, WorkspaceAlg}
 import org.scalasteward.core.edit.scalafix.ScalafixMigration
+import org.scalasteward.core.io.{FileAlg, ProcessAlg, WorkspaceAlg}
 import org.scalasteward.core.util.Nel
 import org.scalasteward.core.vcs.data.BuildRoot
 
@@ -46,7 +46,7 @@ object MillAlg {
       fileAlg: FileAlg[F],
       processAlg: ProcessAlg[F],
       workspaceAlg: WorkspaceAlg[F],
-      F: BracketThrow[F]
+      F: MonadCancelThrow[F]
   ): MillAlg[F] =
     new MillAlg[F] {
       override def containsBuild(buildRoot: BuildRoot): F[Boolean] =
diff --git a/modules/core/src/main/scala/org/scalasteward/core/buildtool/sbt/SbtAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/buildtool/sbt/SbtAlg.scala
index 1db4b95c..a87287a3 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/buildtool/sbt/SbtAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/buildtool/sbt/SbtAlg.scala
@@ -19,18 +19,18 @@ package org.scalasteward.core.buildtool.sbt
 import better.files.File
 import cats.Functor
 import cats.data.OptionT
-import cats.effect.BracketThrow
+import cats.effect.MonadCancelThrow
 import cats.syntax.all._
-import org.typelevel.log4cats.Logger
 import org.scalasteward.core.application.Config
 import org.scalasteward.core.buildtool.BuildToolAlg
 import org.scalasteward.core.buildtool.sbt.command._
 import org.scalasteward.core.buildtool.sbt.data.SbtVersion
 import org.scalasteward.core.data.{Dependency, Scope}
-import org.scalasteward.core.io.{FileAlg, FileData, ProcessAlg, WorkspaceAlg}
 import org.scalasteward.core.edit.scalafix.ScalafixMigration
+import org.scalasteward.core.io.{FileAlg, FileData, ProcessAlg, WorkspaceAlg}
 import org.scalasteward.core.util.Nel
 import org.scalasteward.core.vcs.data.BuildRoot
+import org.typelevel.log4cats.Logger
 
 trait SbtAlg[F[_]] extends BuildToolAlg[F] {
   def addGlobalPluginTemporarily[A](plugin: FileData)(fa: F[A]): F[A]
@@ -49,7 +49,7 @@ object SbtAlg {
       logger: Logger[F],
       processAlg: ProcessAlg[F],
       workspaceAlg: WorkspaceAlg[F],
-      F: BracketThrow[F]
+      F: MonadCancelThrow[F]
   ): SbtAlg[F] =
     new SbtAlg[F] {
       override def addGlobalPluginTemporarily[A](plugin: FileData)(fa: F[A]): F[A] =
diff --git a/modules/core/src/main/scala/org/scalasteward/core/coursier/CoursierAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/coursier/CoursierAlg.scala
index 97ecb98a..9b8a784d 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/coursier/CoursierAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/coursier/CoursierAlg.scala
@@ -22,11 +22,11 @@ import cats.{Applicative, Parallel}
 import coursier.cache.{CachePolicy, FileCache}
 import coursier.core.{Authentication, Project}
 import coursier.{Fetch, Info, Module, ModuleName, Organization}
-import org.typelevel.log4cats.Logger
 import org.http4s.Uri
 import org.scalasteward.core.data.Resolver.Credentials
 import org.scalasteward.core.data.{Dependency, Resolver, Scope, Version}
 import org.scalasteward.core.util.uri
+import org.typelevel.log4cats.Logger
 
 /** An interface to [[https://get-coursier.io Coursier]] used for
   * fetching dependency versions and metadata.
@@ -46,14 +46,10 @@ trait CoursierAlg[F[_]] {
 
 object CoursierAlg {
   def create[F[_]](implicit
-      contextShift: ContextShift[F],
       logger: Logger[F],
+      parallel: Parallel[F],
       F: Sync[F]
   ): CoursierAlg[F] = {
-    implicit val parallel: Parallel.Aux[F, F] = Parallel.identity[F]
-    implicit val coursierSync: coursier.util.Sync[F] =
-      coursier.interop.cats.coursierSyncFromCats(F, parallel, contextShift)
-
     val fetch: Fetch[F] = Fetch[F](FileCache[F]())
 
     val cacheNoTtl: FileCache[F] =
diff --git a/modules/core/src/main/scala/org/scalasteward/core/coursier/package.scala b/modules/core/src/main/scala/org/scalasteward/core/coursier/package.scala
new file mode 100644
index 00000000..b79ff40f
--- /dev/null
+++ b/modules/core/src/main/scala/org/scalasteward/core/coursier/package.scala
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2018-2021 Scala Steward contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.scalasteward.core
+
+import cats.Parallel
+import cats.effect.Sync
+import cats.syntax.all._
+
+import java.util.concurrent.ExecutorService
+
+package object coursier {
+  implicit def coursierSyncFromCatsEffectSync[F[_]](implicit
+      parallel: Parallel[F],
+      F: Sync[F]
+  ): _root_.coursier.util.Sync[F] =
+    new _root_.coursier.util.Sync[F] {
+      override def delay[A](a: => A): F[A] =
+        F.delay(a)
+
+      override def handle[A](a: F[A])(f: PartialFunction[Throwable, A]): F[A] =
+        F.recover(a)(f)
+
+      override def fromAttempt[A](a: Either[Throwable, A]): F[A] =
+        F.fromEither(a)
+
+      override def gather[A](elems: Seq[F[A]]): F[Seq[A]] =
+        elems.parSequence
+
+      override def point[A](a: A): F[A] =
+        F.pure(a)
+
+      override def bind[A, B](elem: F[A])(f: A => F[B]): F[B] =
+        F.flatMap(elem)(f)
+
+      override def schedule[A](pool: ExecutorService)(f: => A): F[A] =
+        F.blocking(f)
+    }
+}
diff --git a/modules/core/src/main/scala/org/scalasteward/core/edit/EditAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/edit/EditAlg.scala
index 9f27f66a..7ade1435 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/edit/EditAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/edit/EditAlg.scala
@@ -17,9 +17,8 @@
 package org.scalasteward.core.edit
 
 import better.files.File
-import cats.effect.MonadThrow
+import cats.effect.Concurrent
 import cats.syntax.all._
-import fs2.Stream
 import org.scalasteward.core.buildtool.BuildToolDispatcher
 import org.scalasteward.core.data.RepoData
 import org.scalasteward.core.data.Update
@@ -45,9 +44,8 @@ final class EditAlg[F[_]](implicit
     hookExecutor: HookExecutor[F],
     logger: Logger[F],
     scalafixMigrationsFinder: ScalafixMigrationsFinder,
-    streamCompiler: Stream.Compiler[F, F],
     workspaceAlg: WorkspaceAlg[F],
-    F: MonadThrow[F]
+    F: Concurrent[F]
 ) {
   def applyUpdate(data: RepoData, update: Update, preCommit: F[Unit] = F.unit): F[List[Commit]] =
     findFilesContainingCurrentVersion(data.repo, data.config, update).flatMap {
diff --git a/modules/core/src/main/scala/org/scalasteward/core/git/FileGitAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/git/FileGitAlg.scala
index d6e696a5..c1c9e3e4 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/git/FileGitAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/git/FileGitAlg.scala
@@ -17,7 +17,7 @@
 package org.scalasteward.core.git
 
 import better.files.File
-import cats.effect.BracketThrow
+import cats.effect.MonadCancelThrow
 import cats.syntax.all._
 import org.http4s.Uri
 import org.scalasteward.core.application.Config.GitCfg
@@ -29,7 +29,7 @@ final class FileGitAlg[F[_]](config: GitCfg)(implicit
     fileAlg: FileAlg[F],
     processAlg: ProcessAlg[F],
     workspaceAlg: WorkspaceAlg[F],
-    F: BracketThrow[F]
+    F: MonadCancelThrow[F]
 ) extends GenGitAlg[F, File] {
   override def branchAuthors(repo: File, branch: Branch, base: Branch): F[List[String]] =
     git("log", "--pretty=format:'%an'", dotdot(base, branch))(repo)
@@ -78,7 +78,7 @@ final class FileGitAlg[F[_]](config: GitCfg)(implicit
     val abortMerge = git("merge", "--abort")(repo).void
 
     returnToCurrentBranch(repo) {
-      checkoutBranch(repo, base) >> F.guarantee(tryMerge)(abortMerge).attempt.map(_.isLeft)
+      checkoutBranch(repo, base) >> F.guarantee(tryMerge, abortMerge).attempt.map(_.isLeft)
     }
   }
 
diff --git a/modules/core/src/main/scala/org/scalasteward/core/git/GenGitAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/git/GenGitAlg.scala
index bba23a1d..19d0b6a5 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/git/GenGitAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/git/GenGitAlg.scala
@@ -16,7 +16,7 @@
 
 package org.scalasteward.core.git
 
-import cats.effect.{Bracket, BracketThrow}
+import cats.effect.{MonadCancel, MonadCancelThrow}
 import cats.syntax.all._
 import cats.{FlatMap, Monad}
 import org.http4s.Uri
@@ -74,7 +74,7 @@ trait GenGitAlg[F[_], Repo] {
   ): F[Option[Commit]] =
     containsChanges(repo).ifM(commitAll(repo, message, messages: _*).map(Some.apply), F.pure(None))
 
-  final def returnToCurrentBranch[A, E](repo: Repo)(fa: F[A])(implicit F: Bracket[F, E]): F[A] =
+  final def returnToCurrentBranch[A, E](repo: Repo)(fa: F[A])(implicit F: MonadCancel[F, E]): F[A] =
     F.bracket(currentBranch(repo))(_ => fa)(checkoutBranch(repo, _))
 
   final def contramapRepoF[A](f: A => F[Repo])(implicit F: FlatMap[F]): GenGitAlg[F, A] = {
@@ -151,7 +151,7 @@ object GenGitAlg {
       fileAlg: FileAlg[F],
       processAlg: ProcessAlg[F],
       workspaceAlg: WorkspaceAlg[F],
-      F: BracketThrow[F]
+      F: MonadCancelThrow[F]
   ): GitAlg[F] =
     new FileGitAlg[F](config).contramapRepoF(workspaceAlg.repoDir)
 }
diff --git a/modules/core/src/main/scala/org/scalasteward/core/io/FileAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/io/FileAlg.scala
index 5f90e894..9cf0bf7b 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/io/FileAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/io/FileAlg.scala
@@ -17,14 +17,15 @@
 package org.scalasteward.core.io
 
 import better.files.File
-import cats.effect.{Bracket, Resource, Sync}
+import cats.effect.{Concurrent, MonadCancel, Resource, Sync}
 import cats.syntax.all._
-import cats.{Functor, MonadThrow, Traverse}
+import cats.{MonadThrow, Traverse}
 import fs2.Stream
 import org.apache.commons.io.FileUtils
 import org.http4s.Uri
 import org.http4s.implicits.http4sLiteralsSyntax
 import org.typelevel.log4cats.Logger
+
 import scala.io.Source
 
 trait FileAlg[F[_]] {
@@ -52,7 +53,7 @@ trait FileAlg[F[_]] {
 
   final def createTemporarily[A, E](file: File, content: String)(
       fa: F[A]
-  )(implicit F: Bracket[F, E]): F[A] = {
+  )(implicit F: MonadCancel[F, E]): F[A] = {
     val delete = deleteForce(file)
     val create = writeFile(file, content).onError(_ => delete)
     F.bracket(create)(_ => fa)(_ => delete)
@@ -75,10 +76,7 @@ trait FileAlg[F[_]] {
       dir: File,
       fileFilter: File => Boolean,
       contentFilter: String => Boolean
-  )(implicit
-      streamCompiler: Stream.Compiler[F, F],
-      F: Functor[F]
-  ): F[List[File]] =
+  )(implicit F: Concurrent[F]): F[List[File]] =
     walk(dir)
       .evalFilter(isRegularFile)
       .filter(fileFilter)
@@ -94,13 +92,13 @@ object FileAlg {
   def create[F[_]](implicit logger: Logger[F], F: Sync[F]): FileAlg[F] =
     new FileAlg[F] {
       override def deleteForce(file: File): F[Unit] =
-        F.delay {
+        F.blocking {
           if (file.exists) FileUtils.forceDelete(file.toJava)
           if (file.exists) file.delete()
         }
 
       override def ensureExists(dir: File): F[File] =
-        F.delay {
+        F.blocking {
           if (!dir.exists) dir.createDirectories()
           dir
         }
@@ -109,14 +107,14 @@ object FileAlg {
         F.delay(File.home)
 
       override def isDirectory(file: File): F[Boolean] =
-        F.delay(file.isDirectory(File.LinkOptions.noFollow))
+        F.blocking(file.isDirectory(File.LinkOptions.noFollow))
 
       override def isRegularFile(file: File): F[Boolean] =
-        F.delay(file.isRegularFile(File.LinkOptions.noFollow))
+        F.blocking(file.isRegularFile(File.LinkOptions.noFollow))
 
       override def removeTemporarily[A](file: File)(fa: F[A]): F[A] =
         F.bracket {
-          F.delay {
+          F.blocking {
             val copyOptions = File.CopyOptions(overwrite = true)
             if (file.exists) Some(file.moveTo(File.newTemporaryFile())(copyOptions)) else None
           }
@@ -126,7 +124,7 @@ object FileAlg {
         }
 
       override def readFile(file: File): F[Option[String]] =
-        F.delay(if (file.exists) Some(file.contentAsString) else None)
+        F.blocking(if (file.exists) Some(file.contentAsString) else None)
 
       override def readResource(resource: String): F[String] =
         readSource(Source.fromResource(resource))
@@ -141,11 +139,11 @@ object FileAlg {
         Resource.fromAutoCloseable(F.delay(source)).use(src => F.delay(src.mkString))
 
       override def walk(dir: File): Stream[F, File] =
-        Stream.eval(F.delay(dir.walk())).flatMap(Stream.fromIterator(_))
+        Stream.eval(F.delay(dir.walk())).flatMap(Stream.fromBlockingIterator(_, 1))
 
       override def writeFile(file: File, content: String): F[Unit] =
         logger.debug(s"Write $file") >>
           file.parentOption.fold(F.unit)(ensureExists(_).void) >>
-          F.delay(file.write(content)).void
+          F.blocking(file.write(content)).void
     }
 }
diff --git a/modules/core/src/main/scala/org/scalasteward/core/io/ProcessAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/io/ProcessAlg.scala
index 7fde2386..ca6f3efa 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/io/ProcessAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/io/ProcessAlg.scala
@@ -17,7 +17,7 @@
 package org.scalasteward.core.io
 
 import better.files.File
-import cats.effect.{Blocker, Concurrent, ContextShift, Timer}
+import cats.effect.Async
 import cats.syntax.all._
 import org.scalasteward.core.application.Config.ProcessCfg
 import org.scalasteward.core.io.process.Args
@@ -84,15 +84,12 @@ object ProcessAlg {
     else
       new NoSandbox[F](config)(execImpl)
 
-  def create[F[_]](blocker: Blocker, config: ProcessCfg)(implicit
-      contextShift: ContextShift[F],
+  def create[F[_]](config: ProcessCfg)(implicit
       logger: Logger[F],
-      timer: Timer[F],
-      F: Concurrent[F]
+      F: Async[F]
   ): ProcessAlg[F] =
     fromExecImpl(config) { args =>
       logger.debug(s"Execute ${process.showCmd(args)}") >>
-        process
-          .slurp[F](args, config.processTimeout, config.maxBufferSize, logger.trace(_), blocker)
+        process.slurp[F](args, config.processTimeout, config.maxBufferSize, logger.trace(_))
     }
 }
diff --git a/modules/core/src/main/scala/org/scalasteward/core/io/process.scala b/modules/core/src/main/scala/org/scalasteward/core/io/process.scala
index 5b61ede0..74f873a5 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/io/process.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/io/process.scala
@@ -20,8 +20,9 @@ import better.files.File
 import cats.effect._
 import cats.syntax.all._
 import fs2.Stream
-import java.io.{IOException, InputStream}
 import org.scalasteward.core.util._
+
+import java.io.{IOException, InputStream}
 import scala.collection.mutable.ListBuffer
 import scala.concurrent.TimeoutException
 import scala.concurrent.duration.FiniteDuration
@@ -38,20 +39,19 @@ object process {
       args: Args,
       timeout: FiniteDuration,
       maxBufferSize: Int,
-      log: String => F[Unit],
-      blocker: Blocker
-  )(implicit contextShift: ContextShift[F], timer: Timer[F], F: Concurrent[F]): F[List[String]] =
+      log: String => F[Unit]
+  )(implicit F: Async[F]): F[List[String]] =
     createProcess(args).flatMap { process =>
       F.delay(new ListBuffer[String]).flatMap { buffer =>
         val readOut = {
-          val out = readInputStream[F](process.getInputStream, blocker)
+          val out = readInputStream[F](process.getInputStream)
           out
             .evalMap(line => F.delay(appendBounded(buffer, line, maxBufferSize)) >> log(line))
             .compile
             .drain
         }
 
-        val result = readOut >> blocker.delay(process.waitFor()) >>= { exitValue =>
+        val result = readOut >> F.blocking(process.waitFor()) >>= { exitValue =>
           if (exitValue === 0) F.pure(buffer.toList)
           else {
             val msg = s"'${showCmd(args)}' exited with code $exitValue"
@@ -64,7 +64,7 @@ object process {
           F.raiseError[List[String]](new TimeoutException(makeMessage(msg, buffer.toList)))
         }
 
-        Concurrent.timeoutTo(result, timeout, fallback)
+        F.timeoutTo(result, timeout, fallback)
       }
     }
 
@@ -85,12 +85,9 @@ object process {
       p
     }
 
-  private def readInputStream[F[_]](is: InputStream, blocker: Blocker)(implicit
-      F: Sync[F],
-      cs: ContextShift[F]
-  ): Stream[F, String] =
+  private def readInputStream[F[_]](is: InputStream)(implicit F: Sync[F]): Stream[F, String] =
     fs2.io
-      .readInputStream(F.pure(is), chunkSize = 4096, blocker)
+      .readInputStream(F.pure(is), chunkSize = 4096)
       .through(fs2.text.utf8Decode)
       .through(fs2.text.lines)
 
diff --git a/modules/core/src/main/scala/org/scalasteward/core/nurture/NurtureAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/nurture/NurtureAlg.scala
index 1ef56fe6..c506e7db 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/nurture/NurtureAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/nurture/NurtureAlg.scala
@@ -16,26 +16,25 @@
 
 package org.scalasteward.core.nurture
 
-import cats.Applicative
-import cats.effect.BracketThrow
+import cats.effect.Concurrent
 import cats.implicits._
 import eu.timepit.refined.types.numeric.NonNegInt
 import fs2.Stream
-import org.typelevel.log4cats.Logger
 import org.http4s.Uri
 import org.scalasteward.core.application.Config
 import org.scalasteward.core.coursier.CoursierAlg
 import org.scalasteward.core.data.ProcessResult.{Created, Ignored, Updated}
 import org.scalasteward.core.data._
 import org.scalasteward.core.edit.EditAlg
+import org.scalasteward.core.edit.scalafix.ScalafixMigrationsFinder
 import org.scalasteward.core.git.{Branch, Commit, GitAlg}
 import org.scalasteward.core.repoconfig.PullRequestUpdateStrategy
-import org.scalasteward.core.edit.scalafix.ScalafixMigrationsFinder
 import org.scalasteward.core.util.UrlChecker
 import org.scalasteward.core.util.logger.LoggerOps
 import org.scalasteward.core.vcs.data._
 import org.scalasteward.core.vcs.{VCSApiAlg, VCSExtraAlg, VCSRepoAlg}
 import org.scalasteward.core.{git, util, vcs}
+import org.typelevel.log4cats.Logger
 
 final class NurtureAlg[F[_]](config: Config)(implicit
     coursierAlg: CoursierAlg[F],
@@ -47,9 +46,8 @@ final class NurtureAlg[F[_]](config: Config)(implicit
     vcsApiAlg: VCSApiAlg[F],
     vcsExtraAlg: VCSExtraAlg[F],
     vcsRepoAlg: VCSRepoAlg[F],
-    streamCompiler: Stream.Compiler[F, F],
     urlChecker: UrlChecker[F],
-    F: BracketThrow[F]
+    F: Concurrent[F]
 ) {
   def nurture(data: RepoData, fork: RepoOut, updates: List[Update.Single]): F[Unit] =
     for {
@@ -249,7 +247,7 @@ object NurtureAlg {
       updates: List[Update],
       updateF: Update => F[ProcessResult],
       updatesLimit: Option[NonNegInt]
-  )(implicit streamCompiler: Stream.Compiler[F, F], F: Applicative[F]): F[Unit] =
+  )(implicit F: Concurrent[F]): F[Unit] =
     updatesLimit match {
       case None => updates.traverse_(updateF)
       case Some(limit) =>
diff --git a/modules/core/src/main/scala/org/scalasteward/core/persistence/CachingKeyValueStore.scala b/modules/core/src/main/scala/org/scalasteward/core/persistence/CachingKeyValueStore.scala
index 236d46c8..6ad27fb9 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/persistence/CachingKeyValueStore.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/persistence/CachingKeyValueStore.scala
@@ -16,8 +16,7 @@
 
 package org.scalasteward.core.persistence
 
-import cats.effect.Sync
-import cats.effect.concurrent.Ref
+import cats.effect.{Ref, Sync}
 import cats.syntax.all._
 import cats.{Eq, Monad}
 
diff --git a/modules/core/src/main/scala/org/scalasteward/core/repocache/RefreshErrorAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/repocache/RefreshErrorAlg.scala
index 398f1c15..afbeb61e 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/repocache/RefreshErrorAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/repocache/RefreshErrorAlg.scala
@@ -16,7 +16,7 @@
 
 package org.scalasteward.core.repocache
 
-import cats.effect.MonadThrow
+import cats.MonadThrow
 import cats.syntax.all._
 import io.circe.Codec
 import io.circe.generic.semiauto.deriveCodec
@@ -25,6 +25,7 @@ import org.scalasteward.core.repocache.RefreshErrorAlg.Entry
 import org.scalasteward.core.util.dateTime.showDuration
 import org.scalasteward.core.util.{DateTimeAlg, Timestamp}
 import org.scalasteward.core.vcs.data.Repo
+
 import scala.concurrent.duration._
 import scala.util.control.NoStackTrace
 
diff --git a/modules/core/src/main/scala/org/scalasteward/core/util/HttpJsonClient.scala b/modules/core/src/main/scala/org/scalasteward/core/util/HttpJsonClient.scala
index 133f7f9b..9a187775 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/util/HttpJsonClient.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/util/HttpJsonClient.scala
@@ -16,7 +16,7 @@
 
 package org.scalasteward.core.util
 
-import cats.effect.Sync
+import cats.effect.Concurrent
 import cats.syntax.all._
 import io.circe.{Decoder, Encoder}
 import org.http4s.Method.{GET, PATCH, POST, PUT}
@@ -25,10 +25,12 @@ import org.http4s._
 import org.http4s.circe.{jsonEncoderOf, jsonOf}
 import org.http4s.client.Client
 import org.http4s.headers.Link
+
 import scala.util.control.NoStackTrace
 
-final class HttpJsonClient[F[_]: Sync](implicit
-    client: Client[F]
+final class HttpJsonClient[F[_]](implicit
+    client: Client[F],
+    F: Concurrent[F]
 ) {
   type ModReq = Request[F] => F[Request[F]]
 
@@ -44,7 +46,7 @@ final class HttpJsonClient[F[_]: Sync](implicit
       modify: ModReq,
       xs: List[A]
   ): F[List[A]] =
-    requestWithHeader[A](method, uri, modify, Link).flatMap {
+    requestWithHeader[A, Link](method, uri, modify).flatMap {
       case (res, Some(linkHeader)) =>
         linkHeader.values.find(_.rel === Option("next")) match {
           case Some(link) =>
@@ -77,19 +79,16 @@ final class HttpJsonClient[F[_]: Sync](implicit
   def patchWithBody[A: Decoder, B: Encoder](uri: Uri, body: B, modify: ModReq): F[A] =
     patch[A](uri, modify.compose(_.withEntity(body)(jsonEncoderOf[F, B])))
 
-  private[this] def requestWithHeader[A: Decoder](
+  private[this] def requestWithHeader[A, H](
       method: Method,
       uri: Uri,
-      modify: ModReq,
-      header: HeaderKey.Extractable
-  ): F[(A, Option[header.HeaderT])] = {
+      modify: ModReq
+  )(implicit d: Decoder[A], hs: Header.Select[H]): F[(A, Option[hs.F[H]])] = {
     val decoder = jsonOf[F, A].transform(_.leftMap(failure => JsonParseError(uri, method, failure)))
     modify(Request[F](method, uri))
       .flatMap(client.run(_).use {
         case Successful(resp) =>
-          decoder.decode(resp, strict = false).rethrowT.map {
-            _ -> resp.headers.get(header)
-          }
+          decoder.decode(resp, strict = false).rethrowT.map(_ -> resp.headers.get[H])
         case resp =>
           toUnexpectedResponse(uri, method, resp).flatMap(_.raiseError)
       })
diff --git a/modules/core/src/main/scala/org/scalasteward/core/util/UrlChecker.scala b/modules/core/src/main/scala/org/scalasteward/core/util/UrlChecker.scala
index 3cd1a932..94f47179 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/util/UrlChecker.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/util/UrlChecker.scala
@@ -19,11 +19,10 @@ package org.scalasteward.core.util
 import cats.effect.{Async, Sync}
 import cats.syntax.all._
 import com.github.benmanes.caffeine.cache.Caffeine
-import org.typelevel.log4cats.Logger
 import org.http4s.client.Client
 import org.http4s.{Method, Request, Status, Uri}
 import org.scalasteward.core.application.Config
-import scalacache.CatsEffect.modes._
+import org.typelevel.log4cats.Logger
 import scalacache.caffeine.CaffeineCache
 import scalacache.{Async => _, Sync => _, _}
 
@@ -60,4 +59,34 @@ object UrlChecker {
           }
       }
     }
+
+  implicit def modeFromCatsEffectAsync[F[_]](implicit F: Async[F]): Mode[F] =
+    new Mode[F] {
+      override def M: scalacache.Async[F] =
+        new scalacache.Async[F] {
+          override def async[A](register: (Either[Throwable, A] => Unit) => Unit): F[A] =
+            F.async_(register)
+
+          override def delay[A](thunk: => A): F[A] =
+            F.delay(thunk)
+
+          override def suspend[A](thunk: => F[A]): F[A] =
+            F.defer(thunk)
+
+          override def pure[A](a: A): F[A] =
+            F.pure(a)
+
+          override def map[A, B](fa: F[A])(f: A => B): F[B] =
+            F.map(fa)(f)
+
+          override def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] =
+            F.flatMap(fa)(f)
+
+          override def raiseError[A](t: Throwable): F[A] =
+            F.raiseError(t)
+
+          override def handleNonFatal[A](fa: => F[A])(f: Throwable => A): F[A] =
+            F.handleError(fa)(f)
+        }
+    }
 }
diff --git a/modules/core/src/main/scala/org/scalasteward/core/vcs/VCSSelection.scala b/modules/core/src/main/scala/org/scalasteward/core/vcs/VCSSelection.scala
index 36aa64c3..41bde8f1 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/vcs/VCSSelection.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/vcs/VCSSelection.scala
@@ -26,6 +26,7 @@ import org.scalasteward.core.vcs.bitbucketserver.BitbucketServerApiAlg
 import org.scalasteward.core.vcs.data.AuthenticatedUser
 import org.scalasteward.core.vcs.github.GitHubApiAlg
 import org.scalasteward.core.vcs.gitlab.GitLabApiAlg
+import org.typelevel.ci._
 import org.typelevel.log4cats.Logger
 
 final class VCSSelection[F[_]](config: Config, user: AuthenticatedUser)(implicit
@@ -56,7 +57,7 @@ final class VCSSelection[F[_]](config: Config, user: AuthenticatedUser)(implicit
   private def bitbucketServerApiAlg: BitbucketServerApiAlg[F] = {
     // Bypass the server-side XSRF check, see
     // https://github.com/scala-steward-org/scala-steward/pull/1863#issuecomment-754538364
-    val xAtlassianToken = Header("X-Atlassian-Token", "no-check")
+    val xAtlassianToken = Header.Raw(ci"X-Atlassian-Token", "no-check")
 
     new BitbucketServerApiAlg[F](
       config.vcsApiHost,
diff --git a/modules/core/src/main/scala/org/scalasteward/core/vcs/bitbucketserver/Json.scala b/modules/core/src/main/scala/org/scalasteward/core/vcs/bitbucketserver/Json.scala
index 1f8990b6..8cf26a61 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/vcs/bitbucketserver/Json.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/vcs/bitbucketserver/Json.scala
@@ -16,8 +16,8 @@
 
 package org.scalasteward.core.vcs.bitbucketserver
 
+import cats.ApplicativeThrow
 import cats.data.NonEmptyList
-import cats.effect.ApplicativeThrow
 import io.circe.generic.semiauto.{deriveCodec, deriveDecoder, deriveEncoder}
 import io.circe.{Codec, Decoder, Encoder}
 import org.http4s.Uri
diff --git a/modules/core/src/main/scala/org/scalasteward/core/vcs/github/GitHubAppApiAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/vcs/github/GitHubAppApiAlg.scala
index 55fdca58..69bc9777 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/vcs/github/GitHubAppApiAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/vcs/github/GitHubAppApiAlg.scala
@@ -20,6 +20,7 @@ import cats.Applicative
 import cats.syntax.functor._
 import org.http4s.{Header, Uri}
 import org.scalasteward.core.util.HttpJsonClient
+import org.typelevel.ci._
 
 class GitHubAppApiAlg[F[_]: Applicative](
     gitHubApiHost: Uri
@@ -28,13 +29,13 @@ class GitHubAppApiAlg[F[_]: Applicative](
 ) {
 
   private[this] val acceptHeader =
-    Header("Accept", "application/vnd.github.v3+json")
+    Header.Raw(ci"Accept", "application/vnd.github.v3+json")
 
   private[this] def addHeaders(jwt: String): client.ModReq =
     req =>
       Applicative[F].point(
         req.putHeaders(
-          Header("Authorization", s"Bearer $jwt"),
+          Header.Raw(ci"Authorization", s"Bearer $jwt"),
           acceptHeader
         )
       )
@@ -65,7 +66,7 @@ class GitHubAppApiAlg[F[_]: Applicative](
         req =>
           Applicative[F].point(
             req.putHeaders(
-              Header("Authorization", s"token ${token}"),
+              Header.Raw(ci"Authorization", s"token $token"),
               acceptHeader
             )
           )
diff --git a/modules/core/src/main/scala/org/scalasteward/core/vcs/gitlab/authentication.scala b/modules/core/src/main/scala/org/scalasteward/core/vcs/gitlab/authentication.scala
index 014a24da..843f8f04 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/vcs/gitlab/authentication.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/vcs/gitlab/authentication.scala
@@ -20,8 +20,9 @@ import cats.Applicative
 import cats.syntax.all._
 import org.http4s.{Header, Request}
 import org.scalasteward.core.vcs.data.AuthenticatedUser
+import org.typelevel.ci._
 
 object authentication {
   def addCredentials[F[_]: Applicative](user: AuthenticatedUser): Request[F] => F[Request[F]] =
-    _.putHeaders(Header("Private-Token", user.accessToken)).pure[F]
+    _.putHeaders(Header.Raw(ci"Private-Token", user.accessToken)).pure[F]
 }
diff --git a/modules/core/src/main/scala/org/scalasteward/core/vcs/package.scala b/modules/core/src/main/scala/org/scalasteward/core/vcs/package.scala
index 1e283cde..c8dbccd6 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/vcs/package.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/vcs/package.scala
@@ -26,7 +26,7 @@ import org.scalasteward.core.vcs.data.{PullRequestNumber, Repo}
 package object vcs {
   def extractPullRequestNumberFrom(uri: Uri): Option[PullRequestNumber] = {
     val regex = raw".*/(pull|pullrequests|merge_requests)/(\d+)".r
-    uri.path match {
+    uri.path.toString match {
       case regex(_, id) => scala.util.Try(PullRequestNumber(id.toInt)).toOption
       case _            => None
     }
diff --git a/project/Dependencies.scala b/project/Dependencies.scala
index 36c8e3f7..b5608915 100644
--- a/project/Dependencies.scala
+++ b/project/Dependencies.scala
@@ -8,30 +8,29 @@ object Dependencies {
   val betterFiles = "com.github.pathikrit" %% "better-files" % "3.9.1"
   val betterMonadicFor = "com.olegpy" %% "better-monadic-for" % "0.3.1"
   val caseApp = "com.github.alexarchambault" %% "case-app" % "2.0.4"
-  val catsEffect = "org.typelevel" %% "cats-effect" % "2.4.1"
+  val catsEffect = "org.typelevel" %% "cats-effect" % "3.0.1"
   val catsCore = "org.typelevel" %% "cats-core" % "2.5.0"
   val catsLaws = "org.typelevel" %% "cats-laws" % catsCore.revision
   val catsParse = "org.typelevel" %% "cats-parse" % "0.3.2"
   val circeConfig = "io.circe" %% "circe-config" % "0.8.0"
-  val circeGeneric = "io.circe" %% "circe-generic" % "0.13.0"
+  val circeGeneric = "io.circe" %% "circe-generic" % "0.14.0-M4"
   val circeGenericExtras = "io.circe" %% "circe-generic-extras" % "0.13.0"
   val circeLiteral = "io.circe" %% "circe-literal" % circeGeneric.revision
   val circeParser = "io.circe" %% "circe-parser" % circeGeneric.revision
   val circeRefined = "io.circe" %% "circe-refined" % circeGeneric.revision
   val commonsIo = "commons-io" % "commons-io" % "2.8.0"
   val coursierCore = "io.get-coursier" %% "coursier" % "2.0.16"
-  val coursierCatsInterop = "io.get-coursier" %% "coursier-cats-interop" % coursierCore.revision
   val cron4sCore = "com.github.alonsodomin.cron4s" %% "cron4s-core" % "0.6.1"
   val disciplineMunit = "org.typelevel" %% "discipline-munit" % "1.0.7"
-  val fs2Core = "co.fs2" %% "fs2-core" % "2.5.4"
+  val fs2Core = "co.fs2" %% "fs2-core" % "3.0.0"
   val fs2Io = "co.fs2" %% "fs2-io" % fs2Core.revision
-  val http4sCore = "org.http4s" %% "http4s-core" % "0.21.21"
+  val http4sCore = "org.http4s" %% "http4s-core" % "1.0.0-M20"
   val http4sCirce = "org.http4s" %% "http4s-circe" % http4sCore.revision
   val http4sClient = "org.http4s" %% "http4s-client" % http4sCore.revision
   val http4sDsl = "org.http4s" %% "http4s-dsl" % http4sCore.revision
   val http4sOkhttpClient = "org.http4s" %% "http4s-okhttp-client" % http4sCore.revision
   val kindProjector = "org.typelevel" % "kind-projector" % "0.11.3"
-  val log4catsSlf4j = "org.typelevel" %% "log4cats-slf4j" % "1.2.2"
+  val log4catsSlf4j = "org.typelevel" %% "log4cats-slf4j" % "2.0.0"
   val logbackClassic = "ch.qos.logback" % "logback-classic" % "1.2.3"
   val jjwtApi = "io.jsonwebtoken" % "jjwt-api" % "0.11.2"
   val jjwtImpl = "io.jsonwebtoken" % "jjwt-impl" % jjwtApi.revision
@@ -44,7 +43,5 @@ object Dependencies {
   val refined = "eu.timepit" %% "refined" % "0.9.23"
   val refinedScalacheck = "eu.timepit" %% "refined-scalacheck" % refined.revision
   val scalacacheCaffeine = "com.github.cb372" %% "scalacache-caffeine" % "0.28.0"
-  val scalacacheCatsEffect =
-    "com.github.cb372" %% "scalacache-cats-effect" % scalacacheCaffeine.revision
   val scalacheck = "org.scalacheck" %% "scalacheck" % "1.15.3"
 }


Test patch:
diff --git a/modules/core/src/test/scala/org/scalasteward/core/TestInstances.scala b/modules/core/src/test/scala/org/scalasteward/core/TestInstances.scala
index 3e18ba23..b6cb0f9c 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/TestInstances.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/TestInstances.scala
@@ -2,7 +2,7 @@ package org.scalasteward.core
 
 import _root_.org.typelevel.log4cats.Logger
 import _root_.org.typelevel.log4cats.slf4j.Slf4jLogger
-import cats.effect.{ContextShift, IO, Timer}
+import cats.effect.IO
 import eu.timepit.refined.scalacheck.numeric._
 import eu.timepit.refined.types.numeric.NonNegInt
 import org.scalacheck.{Arbitrary, Cogen, Gen}
@@ -16,7 +16,7 @@ import org.scalasteward.core.repoconfig.PullRequestFrequency.{Asap, Timespan}
 import org.scalasteward.core.repoconfig._
 import org.scalasteward.core.util.Change.{Changed, Unchanged}
 import org.scalasteward.core.util.{Change, Nel}
-import scala.concurrent.ExecutionContext
+
 import scala.concurrent.duration.FiniteDuration
 
 object TestInstances {
@@ -30,15 +30,9 @@ object TestInstances {
   implicit def changeArbitrary[T](implicit arbT: Arbitrary[T]): Arbitrary[Change[T]] =
     Arbitrary(arbT.arbitrary.flatMap(t => Gen.oneOf(Changed(t), Unchanged(t))))
 
-  implicit val ioContextShift: ContextShift[IO] =
-    IO.contextShift(ExecutionContext.global)
-
   implicit val ioLogger: Logger[IO] =
     Slf4jLogger.getLogger[IO]
 
-  implicit val ioTimer: Timer[IO] =
-    IO.timer(ExecutionContext.global)
-
   implicit def scopeArbitrary[T](implicit arbT: Arbitrary[T]): Arbitrary[Scope[T]] =
     Arbitrary(
       arbT.arbitrary.flatMap { t =>
diff --git a/modules/core/src/test/scala/org/scalasteward/core/application/CliTest.scala b/modules/core/src/test/scala/org/scalasteward/core/application/CliTest.scala
index fda255ed..f9e894bc 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/application/CliTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/application/CliTest.scala
@@ -6,6 +6,7 @@ import org.http4s.syntax.literals._
 import org.scalasteward.core.application.Cli.EnvVar
 import org.scalasteward.core.application.Cli.ParseResult._
 import org.scalasteward.core.vcs.VCSType
+
 import scala.concurrent.duration._
 
 class CliTest extends FunSuite {
diff --git a/modules/core/src/test/scala/org/scalasteward/core/application/StewardAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/application/StewardAlgTest.scala
index 9424f4cc..ffb054d2 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/application/StewardAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/application/StewardAlgTest.scala
@@ -1,6 +1,7 @@
 package org.scalasteward.core.application
 
 import cats.effect.ExitCode
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.scalasteward.core.mock.MockContext.context.stewardAlg
 import org.scalasteward.core.mock.MockState
diff --git a/modules/core/src/test/scala/org/scalasteward/core/buildtool/BuildToolDispatcherTest.scala b/modules/core/src/test/scala/org/scalasteward/core/buildtool/BuildToolDispatcherTest.scala
index 5882f9da..0cb57c0b 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/buildtool/BuildToolDispatcherTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/buildtool/BuildToolDispatcherTest.scala
@@ -1,10 +1,11 @@
 package org.scalasteward.core.buildtool
 
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.scalasteward.core.buildtool.sbt.command._
 import org.scalasteward.core.buildtool.sbt.data.SbtVersion
 import org.scalasteward.core.data.{Resolver, Scope, Version}
-import org.scalasteward.core.mock.MockContext.config
+import org.scalasteward.core.mock.MockConfig.config
 import org.scalasteward.core.mock.MockContext.context.buildToolDispatcher
 import org.scalasteward.core.mock.MockState
 import org.scalasteward.core.mock.MockState.TraceEntry.Cmd
@@ -24,7 +25,7 @@ class BuildToolDispatcherTest extends FunSuite {
       )
       .unsafeRunSync()
     val (state, deps) =
-      buildToolDispatcher.getDependencies(repo, repoConfig).run(initial).unsafeRunSync()
+      buildToolDispatcher.getDependencies(repo, repoConfig).runSA(initial).unsafeRunSync()
 
     val expectedState = initial.copy(trace =
       Vector(
diff --git a/modules/core/src/test/scala/org/scalasteward/core/buildtool/maven/MavenAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/buildtool/maven/MavenAlgTest.scala
index cfea483a..cbbfaba4 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/buildtool/maven/MavenAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/buildtool/maven/MavenAlgTest.scala
@@ -1,17 +1,17 @@
 package org.scalasteward.core.buildtool.maven
 
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
-import org.scalasteward.core.mock.MockContext._
 import org.scalasteward.core.mock.MockContext.context.mavenAlg
-import org.scalasteward.core.mock.MockState
 import org.scalasteward.core.mock.MockState.TraceEntry.Cmd
+import org.scalasteward.core.mock.{MockConfig, MockState}
 import org.scalasteward.core.vcs.data.{BuildRoot, Repo}
 
 class MavenAlgTest extends FunSuite {
   test("getDependencies") {
     val repo = Repo("namespace", "repo-name")
     val buildRoot = BuildRoot(repo, ".")
-    val repoDir = config.workspace / repo.show
+    val repoDir = MockConfig.config.workspace / repo.show
 
     val state = mavenAlg.getDependencies(buildRoot).runS(MockState.empty).unsafeRunSync()
     val expected = MockState.empty.copy(
diff --git a/modules/core/src/test/scala/org/scalasteward/core/buildtool/mill/MillAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/buildtool/mill/MillAlgTest.scala
index 4b7e43ae..fa3ef4d1 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/buildtool/mill/MillAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/buildtool/mill/MillAlgTest.scala
@@ -1,8 +1,9 @@
 package org.scalasteward.core.buildtool.mill
 
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.scalasteward.core.buildtool.mill.MillAlg.extractDeps
-import org.scalasteward.core.mock.MockContext.config
+import org.scalasteward.core.mock.MockConfig.config
 import org.scalasteward.core.mock.MockContext.context.millAlg
 import org.scalasteward.core.mock.MockState
 import org.scalasteward.core.mock.MockState.TraceEntry.Cmd
diff --git a/modules/core/src/test/scala/org/scalasteward/core/buildtool/sbt/SbtAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/buildtool/sbt/SbtAlgTest.scala
index 975cb77a..ebf1c885 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/buildtool/sbt/SbtAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/buildtool/sbt/SbtAlgTest.scala
@@ -1,12 +1,13 @@
 package org.scalasteward.core.buildtool.sbt
 
-import cats.data.StateT
+import cats.data.Kleisli
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.scalasteward.core.buildtool.sbt.command._
 import org.scalasteward.core.data.{GroupId, Version}
 import org.scalasteward.core.edit.scalafix.ScalafixMigration
+import org.scalasteward.core.mock.MockConfig.{config, mockRoot}
 import org.scalasteward.core.mock.MockContext.context.sbtAlg
-import org.scalasteward.core.mock.MockContext.{config, mockRoot}
 import org.scalasteward.core.mock.MockState
 import org.scalasteward.core.mock.MockState.TraceEntry.{Cmd, Log}
 import org.scalasteward.core.util.Nel
@@ -15,7 +16,7 @@ import org.scalasteward.core.vcs.data.{BuildRoot, Repo}
 class SbtAlgTest extends FunSuite {
   test("addGlobalPlugins") {
     val obtained = sbtAlg
-      .addGlobalPlugins(StateT.modify(_.exec(List("fa"))))
+      .addGlobalPlugins(Kleisli(_.update(_.exec(List("fa")))))
       .runS(MockState.empty)
       .unsafeRunSync()
     val expected = MockState.empty.copy(
diff --git a/modules/core/src/test/scala/org/scalasteward/core/coursier/CoursierAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/coursier/CoursierAlgTest.scala
index adfd5cc4..d33e79c3 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/coursier/CoursierAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/coursier/CoursierAlgTest.scala
@@ -1,5 +1,6 @@
 package org.scalasteward.core.coursier
 
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.http4s.syntax.literals._
 import org.scalasteward.core.TestSyntax._
@@ -14,7 +15,7 @@ class CoursierAlgTest extends FunSuite {
       Dependency(GroupId("org.typelevel"), ArtifactId("cats-effect", "cats-effect_2.12"), "1.0.0")
     val (state, result) = coursierAlg
       .getArtifactUrl(dep.withMavenCentral)
-      .run(MockState.empty)
+      .runSA(MockState.empty)
       .unsafeRunSync()
     assertEquals(state, MockState.empty)
     assertEquals(result, Some(uri"https://github.com/typelevel/cats-effect"))
@@ -28,7 +29,7 @@ class CoursierAlgTest extends FunSuite {
     )
     val (state, result) = coursierAlg
       .getArtifactUrl(dep.withMavenCentral)
-      .run(MockState.empty)
+      .runSA(MockState.empty)
       .unsafeRunSync()
     assertEquals(state, MockState.empty)
     assertEquals(result, Some(uri"https://github.com/playframework/play-ws"))
@@ -42,7 +43,7 @@ class CoursierAlgTest extends FunSuite {
     )
     val (state, result) = coursierAlg
       .getArtifactUrl(dep.withMavenCentral)
-      .run(MockState.empty)
+      .runSA(MockState.empty)
       .unsafeRunSync()
     assertEquals(state, MockState.empty)
     assertEquals(result, Some(uri"http://msgpack.org/"))
@@ -56,7 +57,7 @@ class CoursierAlgTest extends FunSuite {
     )
     val (state, result) = coursierAlg
       .getArtifactUrl(dep.withMavenCentral)
-      .run(MockState.empty)
+      .runSA(MockState.empty)
       .unsafeRunSync()
     assertEquals(state, MockState.empty)
     assertEquals(result, Some(uri"http://code.google.com/p/flying-saucer/"))
@@ -70,7 +71,7 @@ class CoursierAlgTest extends FunSuite {
     )
     val (state, result) = coursierAlg
       .getArtifactUrl(dep.withMavenCentral)
-      .run(MockState.empty)
+      .runSA(MockState.empty)
       .unsafeRunSync()
     assertEquals(state, MockState.empty)
     assertEquals(result, Some(uri"https://bytebuddy.net"))
@@ -84,7 +85,7 @@ class CoursierAlgTest extends FunSuite {
     )
     val (state, result) = coursierAlg
       .getArtifactUrl(dep.withMavenCentral)
-      .run(MockState.empty)
+      .runSA(MockState.empty)
       .unsafeRunSync()
     assertEquals(state, MockState.empty)
     assertEquals(result, None)
@@ -100,7 +101,7 @@ class CoursierAlgTest extends FunSuite {
     )
     val (state, result) = coursierAlg
       .getArtifactUrl(dep.withMavenCentral)
-      .run(MockState.empty)
+      .runSA(MockState.empty)
       .unsafeRunSync()
     assertEquals(state, MockState.empty)
     assertEquals(result, Some(uri"https://github.com/xerial/sbt-sonatype"))
@@ -115,7 +116,7 @@ class CoursierAlgTest extends FunSuite {
       Some(ScalaVersion("2.12"))
     )
     val (state, result) =
-      coursierAlg.getArtifactUrl(dep.withSbtPluginReleases).run(MockState.empty).unsafeRunSync()
+      coursierAlg.getArtifactUrl(dep.withSbtPluginReleases).runSA(MockState.empty).unsafeRunSync()
     assertEquals(state, MockState.empty)
     assertEquals(result, Some(uri"https://github.com/sbt/sbt-release"))
   }
@@ -127,7 +128,7 @@ class CoursierAlgTest extends FunSuite {
     )
     val (state, result) = coursierAlg
       .getArtifactIdUrlMapping(dependencies.withMavenCentral)
-      .run(MockState.empty)
+      .runSA(MockState.empty)
       .unsafeRunSync()
     assertEquals(state, MockState.empty)
     assertEquals(
diff --git a/modules/core/src/test/scala/org/scalasteward/core/data/VersionTest.scala b/modules/core/src/test/scala/org/scalasteward/core/data/VersionTest.scala
index 8e2cc745..c010bf49 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/data/VersionTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/data/VersionTest.scala
@@ -6,6 +6,7 @@ import munit.DisciplineSuite
 import org.scalacheck.Prop._
 import org.scalasteward.core.TestInstances._
 import org.scalasteward.core.data.Version.Component
+
 import scala.util.Random
 
 class VersionTest extends DisciplineSuite {
diff --git a/modules/core/src/test/scala/org/scalasteward/core/edit/EditAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/edit/EditAlgTest.scala
index 5b1ed83d..5c13654d 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/edit/EditAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/edit/EditAlgTest.scala
@@ -1,11 +1,12 @@
 package org.scalasteward.core.edit
 
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.scalasteward.core.TestInstances.dummyRepoCache
 import org.scalasteward.core.TestSyntax._
 import org.scalasteward.core.data.{GroupId, RepoData, Update}
+import org.scalasteward.core.mock.MockConfig.{config, envVars}
 import org.scalasteward.core.mock.MockContext.context.editAlg
-import org.scalasteward.core.mock.MockContext.{config, envVars}
 import org.scalasteward.core.mock.MockState
 import org.scalasteward.core.mock.MockState.TraceEntry.{Cmd, Log}
 import org.scalasteward.core.repoconfig.RepoConfig
diff --git a/modules/core/src/test/scala/org/scalasteward/core/edit/hooks/HookExecutorTest.scala b/modules/core/src/test/scala/org/scalasteward/core/edit/hooks/HookExecutorTest.scala
index fc4e270c..9fbe4da1 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/edit/hooks/HookExecutorTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/edit/hooks/HookExecutorTest.scala
@@ -1,11 +1,12 @@
 package org.scalasteward.core.edit.hooks
 
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.scalasteward.core.TestInstances.dummyRepoCache
 import org.scalasteward.core.TestSyntax._
 import org.scalasteward.core.data.{RepoData, Update}
+import org.scalasteward.core.mock.MockConfig.envVars
 import org.scalasteward.core.mock.MockContext.context.{hookExecutor, workspaceAlg}
-import org.scalasteward.core.mock.MockContext.envVars
 import org.scalasteward.core.mock.MockState
 import org.scalasteward.core.mock.MockState.TraceEntry.{Cmd, Log}
 import org.scalasteward.core.repoconfig.{RepoConfig, ScalafmtConfig}
diff --git a/modules/core/src/test/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsLoaderTest.scala b/modules/core/src/test/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsLoaderTest.scala
index a0baf2cd..2ec747e9 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsLoaderTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsLoaderTest.scala
@@ -1,13 +1,14 @@
 package org.scalasteward.core.edit.scalafix
 
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.http4s.Uri
 import org.scalasteward.core.application.Config.ScalafixCfg
 import org.scalasteward.core.data.{GroupId, Version}
 import org.scalasteward.core.edit.scalafix.ScalafixMigrationsLoaderTest.mockState
 import org.scalasteward.core.io.FileAlgTest.ioFileAlg
+import org.scalasteward.core.mock.MockConfig.mockRoot
 import org.scalasteward.core.mock.MockContext.context.scalafixMigrationsLoader
-import org.scalasteward.core.mock.MockContext.mockRoot
 import org.scalasteward.core.mock.MockState
 import org.scalasteward.core.util.Nel
 
diff --git a/modules/core/src/test/scala/org/scalasteward/core/git/FileGitAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/git/FileGitAlgTest.scala
index 0a5bff02..e811db2a 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/git/FileGitAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/git/FileGitAlgTest.scala
@@ -3,6 +3,7 @@ package org.scalasteward.core.git
 import better.files.File
 import cats.Monad
 import cats.effect.IO
+import cats.effect.unsafe.implicits.global
 import cats.syntax.all._
 import munit.FunSuite
 import org.scalasteward.core.TestInstances.ioLogger
@@ -10,7 +11,7 @@ import org.scalasteward.core.git.FileGitAlgTest.{master, Supplement}
 import org.scalasteward.core.io.FileAlgTest.ioFileAlg
 import org.scalasteward.core.io.ProcessAlgTest.ioProcessAlg
 import org.scalasteward.core.io.{FileAlg, ProcessAlg, WorkspaceAlg}
-import org.scalasteward.core.mock.MockContext.{config, mockRoot}
+import org.scalasteward.core.mock.MockConfig.{config, mockRoot}
 import org.scalasteward.core.util.Nel
 
 class FileGitAlgTest extends FunSuite {
diff --git a/modules/core/src/test/scala/org/scalasteward/core/io/FileAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/io/FileAlgTest.scala
index 9663fe71..4de780ac 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/io/FileAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/io/FileAlgTest.scala
@@ -2,13 +2,14 @@ package org.scalasteward.core.io
 
 import better.files.File
 import cats.effect.IO
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.http4s.Uri
 import org.scalacheck.Arbitrary
 import org.scalasteward.core.TestInstances.ioLogger
 import org.scalasteward.core.io.FileAlgTest.ioFileAlg
+import org.scalasteward.core.mock.MockConfig.mockRoot
 import org.scalasteward.core.mock.MockContext.context.fileAlg
-import org.scalasteward.core.mock.MockContext.mockRoot
 import org.scalasteward.core.mock.MockState
 import org.scalasteward.core.mock.MockState.TraceEntry.Cmd
 
@@ -58,7 +59,7 @@ class FileAlgTest extends FunSuite {
     val (state, edited) = (for {
       home <- fileAlg.home
       edited <- fileAlg.editFile(home / "does-not-exists.txt", Some.apply)
-    } yield edited).run(MockState.empty).unsafeRunSync()
+    } yield edited).runSA(MockState.empty).unsafeRunSync()
 
     val expected =
       MockState.empty.copy(trace = Vector(Cmd("read", s"$mockRoot/does-not-exists.txt")))
@@ -72,7 +73,7 @@ class FileAlgTest extends FunSuite {
       _ <- fileAlg.writeFile(file, "123")
       edit = (s: String) => Some(s.replace("2", "4"))
       edited <- fileAlg.editFile(file, edit)
-    } yield edited).run(MockState.empty).unsafeRunSync()
+    } yield edited).runSA(MockState.empty).unsafeRunSync()
 
     val expected = MockState.empty.copy(
       trace = Vector(
diff --git a/modules/core/src/test/scala/org/scalasteward/core/io/MockFileAlg.scala b/modules/core/src/test/scala/org/scalasteward/core/io/MockFileAlg.scala
index 7f7ba79c..c2ecf937 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/io/MockFileAlg.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/io/MockFileAlg.scala
@@ -1,69 +1,61 @@
 package org.scalasteward.core.io
 
 import better.files.File
-import cats.data.StateT
+import cats.data.Kleisli
 import cats.effect.IO
-import cats.syntax.all._
 import fs2.Stream
 import org.http4s.Uri
 import org.scalasteward.core.io.FileAlgTest.ioFileAlg
-import org.scalasteward.core.mock.{MockContext, MockEff, MockState}
+import org.scalasteward.core.mock.{getFlatMapSet, MockConfig, MockEff}
 
 class MockFileAlg extends FileAlg[MockEff] {
   override def deleteForce(file: File): MockEff[Unit] =
-    StateT.modifyF[IO, MockState](_.exec(List("rm", "-rf", file.pathAsString)).rmFile(file))
+    Kleisli(getFlatMapSet(_.exec(List("rm", "-rf", file.pathAsString)).rmFile(file)))
 
   override def ensureExists(dir: File): MockEff[File] =
-    StateT.modify[IO, MockState](_.exec(List("mkdir", "-p", dir.pathAsString))) >>
-      StateT.liftF(ioFileAlg.ensureExists(dir))
+    Kleisli(_.update(_.exec(List("mkdir", "-p", dir.pathAsString))) >> ioFileAlg.ensureExists(dir))
 
   override def home: MockEff[File] =
-    StateT.pure(MockContext.mockRoot)
+    Kleisli.pure(MockConfig.mockRoot)
 
   override def isDirectory(file: File): MockEff[Boolean] =
-    StateT.modify[IO, MockState](_.exec(List("test", "-d", file.pathAsString))) >>
-      StateT.liftF(ioFileAlg.isDirectory(file))
+    Kleisli(_.update(_.exec(List("test", "-d", file.pathAsString))) >> ioFileAlg.isDirectory(file))
 
   override def isRegularFile(file: File): MockEff[Boolean] =
-    StateT.modify[IO, MockState](_.exec(List("test", "-f", file.pathAsString))) >>
-      StateT.liftF(ioFileAlg.isRegularFile(file))
+    Kleisli {
+      _.update(_.exec(List("test", "-f", file.pathAsString))) >> ioFileAlg.isRegularFile(file)
+    }
 
   override def removeTemporarily[A](file: File)(fa: MockEff[A]): MockEff[A] =
-    for {
-      _ <- StateT.modify[IO, MockState](_.exec(List("rm", file.pathAsString)))
-      s1 <- StateT.get[IO, MockState]
-      (s2, a) <- StateT.liftF(ioFileAlg.removeTemporarily(file)(fa.run(s1)))
-      _ <- StateT.set[IO, MockState](s2)
-      _ <- StateT.modify[IO, MockState](_.exec(List("restore", file.pathAsString)))
-    } yield a
+    Kleisli { ref =>
+      for {
+        _ <- ref.update(_.exec(List("rm", file.pathAsString)))
+        a <- ioFileAlg.removeTemporarily(file)(fa.run(ref))
+        _ <- ref.update(_.exec(List("restore", file.pathAsString)))
+      } yield a
+    }
 
   override def readFile(file: File): MockEff[Option[String]] =
-    StateT.modify[IO, MockState](_.exec(List("read", file.pathAsString))) >>
-      StateT.liftF(ioFileAlg.readFile(file))
+    Kleisli(_.update(_.exec(List("read", file.pathAsString))) >> ioFileAlg.readFile(file))
 
   override def readResource(resource: String): MockEff[String] =
-    StateT.modify[IO, MockState](_.exec(List("read", s"classpath:$resource"))) >>
-      StateT.liftF(ioFileAlg.readResource(resource))
+    Kleisli {
+      _.update(_.exec(List("read", s"classpath:$resource"))) >> ioFileAlg.readResource(resource)
+    }
 
   override def readUri(uri: Uri): MockEff[String] =
-    for {
-      _ <- StateT.modify[IO, MockState](_.exec(List("read", uri.renderString)))
-      s <- StateT.get[IO, MockState]
-      content <- StateT.liftF[IO, MockState, String](s.uris.get(uri) match {
-        case Some(content) => IO.pure(content)
-        case None          => IO.raiseError(new Throwable("URL not found"))
-      })
-    } yield content
+    Kleisli {
+      _.updateAndGet(_.exec(List("read", uri.renderString))).flatMap {
+        _.uris.get(uri) match {
+          case Some(content) => IO.pure(content)
+          case None          => IO.raiseError(new Throwable(s"URI $uri not found"))
+        }
+      }
+    }
 
   override def walk(dir: File): Stream[MockEff, File] =
-    Stream.evals(
-      StateT.liftF[IO, MockState, List[File]](
-        ioFileAlg.walk(dir).compile.toList.map(_.sortBy(_.pathAsString))
-      )
-    )
+    Stream.evals(Kleisli.liftF(ioFileAlg.walk(dir).compile.toList.map(_.sortBy(_.pathAsString))))
 
   override def writeFile(file: File, content: String): MockEff[Unit] =
-    StateT.modifyF[IO, MockState](
-      _.exec(List("write", file.pathAsString)).addFiles(file -> content)
-    )
+    Kleisli(getFlatMapSet(_.exec(List("write", file.pathAsString)).addFiles(file -> content)))
 }
diff --git a/modules/core/src/test/scala/org/scalasteward/core/io/MockProcessAlg.scala b/modules/core/src/test/scala/org/scalasteward/core/io/MockProcessAlg.scala
index bdc34f8b..b066a22f 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/io/MockProcessAlg.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/io/MockProcessAlg.scala
@@ -1,16 +1,19 @@
 package org.scalasteward.core.io
 
+import cats.data.Kleisli
 import org.scalasteward.core.application.Config.ProcessCfg
-import org.scalasteward.core.mock.{applyPure, MockEff}
+import org.scalasteward.core.mock.MockEff
 
 object MockProcessAlg {
   def create(config: ProcessCfg): ProcessAlg[MockEff] =
     ProcessAlg.fromExecImpl(config) { args =>
-      applyPure { s =>
-        val cmd = args.workingDirectory.map(_.toString).toList ++ args.command.toList
-        val s1 = s.exec(cmd, args.extraEnv: _*)
-        val a = s.commandOutputs.getOrElse(args.command.toList, List.empty)
-        (s1, a)
+      Kleisli {
+        _.modify { s =>
+          val cmd = args.workingDirectory.map(_.toString).toList ++ args.command.toList
+          val s1 = s.exec(cmd, args.extraEnv: _*)
+          val a = s.commandOutputs.getOrElse(args.command.toList, List.empty)
+          (s1, a)
+        }
       }
     }
 }
diff --git a/modules/core/src/test/scala/org/scalasteward/core/io/MockWorkspaceAlg.scala b/modules/core/src/test/scala/org/scalasteward/core/io/MockWorkspaceAlg.scala
index 912706e2..987b6722 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/io/MockWorkspaceAlg.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/io/MockWorkspaceAlg.scala
@@ -1,16 +1,16 @@
 package org.scalasteward.core.io
 
 import better.files.File
-import cats.data.StateT
-import org.scalasteward.core.mock.{MockContext, MockEff}
+import cats.data.Kleisli
+import org.scalasteward.core.mock.{MockConfig, MockEff}
 import org.scalasteward.core.vcs.data.{BuildRoot, Repo}
 
 class MockWorkspaceAlg extends WorkspaceAlg[MockEff] {
   override def cleanWorkspace: MockEff[Unit] =
-    StateT.pure(())
+    Kleisli.pure(())
 
   override def rootDir: MockEff[File] =
-    StateT.pure(MockContext.config.workspace)
+    Kleisli.pure(MockConfig.config.workspace)
 
   override def repoDir(repo: Repo): MockEff[File] =
     rootDir.map(_ / repo.owner / repo.repo)
diff --git a/modules/core/src/test/scala/org/scalasteward/core/io/ProcessAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/io/ProcessAlgTest.scala
index 47732b4f..6b9e4353 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/io/ProcessAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/io/ProcessAlgTest.scala
@@ -1,16 +1,17 @@
 package org.scalasteward.core.io
 
 import better.files.File
-import cats.effect.{Blocker, IO}
-import java.util.concurrent.Executors
+import cats.effect.IO
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.scalasteward.core.TestInstances._
 import org.scalasteward.core.application.Config.{ProcessCfg, SandboxCfg}
 import org.scalasteward.core.io.ProcessAlgTest.ioProcessAlg
-import org.scalasteward.core.mock.MockContext.{config, mockRoot}
+import org.scalasteward.core.mock.MockConfig.{config, mockRoot}
 import org.scalasteward.core.mock.MockState
 import org.scalasteward.core.mock.MockState.TraceEntry.Cmd
 import org.scalasteward.core.util.Nel
+
 import scala.concurrent.duration.Duration
 
 class ProcessAlgTest extends FunSuite {
@@ -65,6 +66,5 @@ class ProcessAlgTest extends FunSuite {
 }
 
 object ProcessAlgTest {
-  val blocker: Blocker = Blocker.liftExecutorService(Executors.newCachedThreadPool())
-  implicit val ioProcessAlg: ProcessAlg[IO] = ProcessAlg.create[IO](blocker, config.processCfg)
+  implicit val ioProcessAlg: ProcessAlg[IO] = ProcessAlg.create[IO](config.processCfg)
 }
diff --git a/modules/core/src/test/scala/org/scalasteward/core/io/processTest.scala b/modules/core/src/test/scala/org/scalasteward/core/io/processTest.scala
index 4da26713..b7548ffb 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/io/processTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/io/processTest.scala
@@ -1,19 +1,19 @@
 package org.scalasteward.core.io
 
 import cats.effect.IO
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
-import org.scalasteward.core.TestInstances._
-import org.scalasteward.core.io.ProcessAlgTest.blocker
 import org.scalasteward.core.io.process.Args
 import org.scalasteward.core.util.Nel
+
 import scala.concurrent.duration._
 
 class processTest extends FunSuite {
   def slurp1(cmd: Nel[String]): IO[List[String]] =
-    process.slurp[IO](Args(cmd), 1.minute, 8192, _ => IO.unit, blocker)
+    process.slurp[IO](Args(cmd), 1.minute, 8192, _ => IO.unit)
 
   def slurp2(cmd: Nel[String], timeout: FiniteDuration): IO[List[String]] =
-    process.slurp[IO](Args(cmd), timeout, 8192, _ => IO.unit, blocker)
+    process.slurp[IO](Args(cmd), timeout, 8192, _ => IO.unit)
 
   test("echo hello") {
     assertEquals(slurp1(Nel.of("echo", "-n", "hello")).unsafeRunSync(), List("hello"))
diff --git a/modules/core/src/test/scala/org/scalasteward/core/mock/MockConfig.scala b/modules/core/src/test/scala/org/scalasteward/core/mock/MockConfig.scala
new file mode 100644
index 00000000..5e1c228a
--- /dev/null
+++ b/modules/core/src/test/scala/org/scalasteward/core/mock/MockConfig.scala
@@ -0,0 +1,31 @@
+package org.scalasteward.core.mock
+
+import better.files.File
+import org.http4s.Uri
+import org.scalasteward.core.application.Cli.EnvVar
+import org.scalasteward.core.application.{Cli, Config}
+import org.scalasteward.core.vcs.VCSType
+import org.scalasteward.core.vcs.data.AuthenticatedUser
+
+import scala.concurrent.duration._
+
+object MockConfig {
+  val mockRoot: File = File.temp / "scala-steward"
+  val args: Cli.Args = Cli.Args(
+    workspace = mockRoot / "workspace",
+    reposFile = mockRoot / "repos.md",
+    defaultRepoConf = Some(mockRoot / "default.scala-steward.conf"),
+    gitAuthorName = "Bot Doe",
+    gitAuthorEmail = "bot@example.org",
+    vcsType = VCSType.GitHub,
+    vcsApiHost = Uri(),
+    vcsLogin = "bot-doe",
+    gitAskPass = mockRoot / "askpass.sh",
+    enableSandbox = Some(true),
+    envVar = List(EnvVar("VAR1", "val1"), EnvVar("VAR2", "val2")),
+    cacheTtl = 1.hour
+  )
+  val config: Config = Config.from(args)
+  val envVars = List(s"GIT_ASKPASS=${config.gitCfg.gitAskPass}", "VAR1=val1", "VAR2=val2")
+  val user: AuthenticatedUser = AuthenticatedUser("scala-steward", "token")
+}
diff --git a/modules/core/src/test/scala/org/scalasteward/core/mock/MockContext.scala b/modules/core/src/test/scala/org/scalasteward/core/mock/MockContext.scala
index 979e846e..6f503a3d 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/mock/MockContext.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/mock/MockContext.scala
@@ -1,43 +1,15 @@
 package org.scalasteward.core.mock
 
-import better.files.File
-import cats.Parallel
-import cats.effect.{BracketThrow, Sync}
+import cats.effect.unsafe.implicits.global
+import org.http4s.HttpApp
 import org.http4s.client.Client
-import org.http4s.{HttpApp, Uri}
-import org.scalasteward.core.TestInstances.ioContextShift
-import org.scalasteward.core.application.Cli.EnvVar
-import org.scalasteward.core.application.{Cli, Config, Context}
+import org.scalasteward.core.application.Context
 import org.scalasteward.core.edit.scalafix.ScalafixMigrationsLoaderTest
 import org.scalasteward.core.io._
-import org.scalasteward.core.vcs.VCSType
-import org.scalasteward.core.vcs.data.AuthenticatedUser
+import org.scalasteward.core.mock.MockConfig.config
 import org.typelevel.log4cats.Logger
-import scala.concurrent.duration._
 
 object MockContext {
-  val mockRoot: File = File.temp / "scala-steward"
-  val args: Cli.Args = Cli.Args(
-    workspace = mockRoot / "workspace",
-    reposFile = mockRoot / "repos.md",
-    defaultRepoConf = Some(mockRoot / "default.scala-steward.conf"),
-    gitAuthorName = "Bot Doe",
-    gitAuthorEmail = "bot@example.org",
-    vcsType = VCSType.GitHub,
-    vcsApiHost = Uri(),
-    vcsLogin = "bot-doe",
-    gitAskPass = mockRoot / "askpass.sh",
-    enableSandbox = Some(true),
-    envVar = List(EnvVar("VAR1", "val1"), EnvVar("VAR2", "val2")),
-    cacheTtl = 1.hour
-  )
-  val config: Config = Config.from(args)
-  val envVars = List(s"GIT_ASKPASS=${config.gitCfg.gitAskPass}", "VAR1=val1", "VAR2=val2")
-  val user: AuthenticatedUser = AuthenticatedUser("scala-steward", "token")
-
-  implicit val mockEffBracketThrow: BracketThrow[MockEff] = Sync[MockEff]
-  implicit val mockEffParallel: Parallel[MockEff] = Parallel.identity
-
   implicit private val client: Client[MockEff] = Client.fromHttpApp(HttpApp.notFound)
   implicit private val fileAlg: FileAlg[MockEff] = new MockFileAlg
   implicit private val logger: Logger[MockEff] = new MockLogger
@@ -45,5 +17,5 @@ object MockContext {
   implicit private val workspaceAlg: WorkspaceAlg[MockEff] = new MockWorkspaceAlg
 
   val context: Context[MockEff] =
-    Context.step1[MockEff](config).runA(ScalafixMigrationsLoaderTest.mockState).unsafeRunSync()
+    ScalafixMigrationsLoaderTest.mockState.toRef.flatMap(Context.step1(config).run).unsafeRunSync()
 }
diff --git a/modules/core/src/test/scala/org/scalasteward/core/mock/MockLogger.scala b/modules/core/src/test/scala/org/scalasteward/core/mock/MockLogger.scala
index a8bad4fa..fb63a5db 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/mock/MockLogger.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/mock/MockLogger.scala
@@ -1,6 +1,6 @@
 package org.scalasteward.core.mock
 
-import cats.data.StateT
+import cats.data.Kleisli
 import org.typelevel.log4cats.Logger
 
 class MockLogger extends Logger[MockEff] {
@@ -35,5 +35,5 @@ class MockLogger extends Logger[MockEff] {
     impl(None, message)
 
   def impl(maybeThrowable: Option[Throwable], message: String): MockEff[Unit] =
-    StateT.modify(_.log(maybeThrowable, message))
+    Kleisli(_.update(_.log(maybeThrowable, message)))
 }
diff --git a/modules/core/src/test/scala/org/scalasteward/core/mock/MockState.scala b/modules/core/src/test/scala/org/scalasteward/core/mock/MockState.scala
index fe7e6a8c..4d835ce8 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/mock/MockState.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/mock/MockState.scala
@@ -1,7 +1,7 @@
 package org.scalasteward.core.mock
 
 import better.files.File
-import cats.effect.IO
+import cats.effect.{IO, Ref}
 import cats.syntax.all._
 import org.http4s.Uri
 import org.scalasteward.core.io.FileAlgTest.ioFileAlg
@@ -30,6 +30,9 @@ final case class MockState(
 
   def log(maybeThrowable: Option[Throwable], msg: String): MockState =
     copy(trace = trace :+ Log((maybeThrowable, msg)))
+
+  def toRef: IO[Ref[IO, MockState]] =
+    Ref[IO].of(this)
 }
 
 object MockState {
diff --git a/modules/core/src/test/scala/org/scalasteward/core/mock/package.scala b/modules/core/src/test/scala/org/scalasteward/core/mock/package.scala
index 0484e06a..5eca59c8 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/mock/package.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/mock/package.scala
@@ -1,13 +1,24 @@
 package org.scalasteward.core
 
-import cats.Applicative
-import cats.data.StateT
-import cats.effect.IO
+import cats.FlatMap
+import cats.data.Kleisli
+import cats.effect.{IO, Ref}
 import cats.syntax.all._
 
 package object mock {
-  type MockEff[A] = StateT[IO, MockState, A]
+  type MockEff[A] = Kleisli[IO, Ref[IO, MockState], A]
 
-  def applyPure[F[_]: Applicative, S, A](f: S => (S, A)): StateT[F, S, A] =
-    StateT.apply(s => f(s).pure[F])
+  implicit class MockEffOps[A](private val fa: MockEff[A]) extends AnyVal {
+    def runA(state: MockState): IO[A] =
+      state.toRef.flatMap(fa.run)
+
+    def runS(state: MockState): IO[MockState] =
+      state.toRef.flatMap(ref => fa.run(ref) >> ref.get)
+
+    def runSA(state: MockState): IO[(MockState, A)] =
+      state.toRef.flatMap(ref => fa.run(ref).flatMap(a => ref.get.map(s => (s, a))))
+  }
+
+  def getFlatMapSet[F[_], A, B](f: A => F[A])(ref: Ref[F, A])(implicit F: FlatMap[F]): F[Unit] =
+    ref.get.flatMap(f).flatMap(ref.set)
 }
diff --git a/modules/core/src/test/scala/org/scalasteward/core/nurture/NurtureAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/nurture/NurtureAlgTest.scala
deleted file mode 100644
index cdc80497..00000000
--- a/modules/core/src/test/scala/org/scalasteward/core/nurture/NurtureAlgTest.scala
+++ /dev/null
@@ -1,45 +0,0 @@
-package org.scalasteward.core.nurture
-
-import cats.data.StateT
-import cats.effect.IO
-import eu.timepit.refined.types.numeric.NonNegInt
-import munit.ScalaCheckSuite
-import org.scalacheck.Prop._
-import org.scalasteward.core.TestInstances._
-import org.scalasteward.core.data.ProcessResult.{Ignored, Updated}
-import org.scalasteward.core.data.{ProcessResult, Update}
-
-class NurtureAlgTest extends ScalaCheckSuite {
-  test("processUpdates with No Limiting") {
-    forAll { updates: List[Update] =>
-      val obtained = NurtureAlg
-        .processUpdates(
-          updates,
-          _ => StateT[IO, Int, ProcessResult](actionAcc => IO.pure(actionAcc + 1 -> Ignored)),
-          None
-        )
-        .runS(0)
-        .unsafeRunSync()
-      assertEquals(obtained, updates.size)
-    }
-  }
-
-  test("processUpdates with Limiting should process all updates up to the limit") {
-    forAll { updates: Set[Update] =>
-      val (ignorableUpdates, appliableUpdates) = updates.toList.splitAt(updates.size / 2)
-      val f: Update => StateT[IO, Int, ProcessResult] = update =>
-        StateT[IO, Int, ProcessResult](actionAcc =>
-          IO.pure(actionAcc + 1 -> (if (ignorableUpdates.contains(update)) Ignored else Updated))
-        )
-      val obtained = NurtureAlg
-        .processUpdates(
-          ignorableUpdates ++ appliableUpdates,
-          f,
-          NonNegInt.unapply(appliableUpdates.size)
-        )
-        .runS(0)
-        .unsafeRunSync()
-      assertEquals(obtained, updates.size)
-    }
-  }
-}
diff --git a/modules/core/src/test/scala/org/scalasteward/core/nurture/PullRequestRepositoryTest.scala b/modules/core/src/test/scala/org/scalasteward/core/nurture/PullRequestRepositoryTest.scala
index 83ff4a0b..7cbe1786 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/nurture/PullRequestRepositoryTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/nurture/PullRequestRepositoryTest.scala
@@ -1,12 +1,13 @@
 package org.scalasteward.core.nurture
 
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.http4s.syntax.literals._
 import org.scalasteward.core.TestSyntax._
 import org.scalasteward.core.data.Update
 import org.scalasteward.core.git.Sha1
 import org.scalasteward.core.git.Sha1.HexString
-import org.scalasteward.core.mock.MockContext.config
+import org.scalasteward.core.mock.MockConfig.config
 import org.scalasteward.core.mock.MockContext.context.pullRequestRepository
 import org.scalasteward.core.mock.MockState
 import org.scalasteward.core.mock.MockState.TraceEntry
@@ -38,7 +39,7 @@ class PullRequestRepositoryTest extends FunSuite {
       result <- pullRequestRepository.findLatestPullRequest(repo, update.crossDependency, "1.0.0")
       createdAt <- pullRequestRepository.lastPullRequestCreatedAt(repo)
     } yield (result, createdAt)
-    val (state, (result, createdAt)) = p.run(MockState.empty).unsafeRunSync()
+    val (state, (result, createdAt)) = p.runSA(MockState.empty).unsafeRunSync()
 
     val store = config.workspace / s"store/pull_requests/v2/github/${repo.show}/pull_requests.json"
     assertEquals(result, Some((url, sha1, PullRequestState.Open)))
@@ -72,7 +73,7 @@ class PullRequestRepositoryTest extends FunSuite {
       _ <- pullRequestRepository.changeState(repo, url, PullRequestState.Closed)
       closedResult <- pullRequestRepository.getObsoleteOpenPullRequests(repo, nextUpdate)
     } yield (emptyResult, result, closedResult)
-    val (state, (emptyResult, result, closedResult)) = p.run(MockState.empty).unsafeRunSync()
+    val (state, (emptyResult, result, closedResult)) = p.runSA(MockState.empty).unsafeRunSync()
     val store = config.workspace / s"store/pull_requests/v2/github/${repo.show}/pull_requests.json"
     assertEquals(emptyResult, List.empty)
     assertEquals(closedResult, List.empty)
@@ -104,7 +105,7 @@ class PullRequestRepositoryTest extends FunSuite {
       )
       result <- pullRequestRepository.getObsoleteOpenPullRequests(repo, update)
     } yield (emptyResult, result)
-    val (state, (emptyResult, result)) = p.run(MockState.empty).unsafeRunSync()
+    val (state, (emptyResult, result)) = p.runSA(MockState.empty).unsafeRunSync()
     val store = config.workspace / s"store/pull_requests/v2/github/${repo.show}/pull_requests.json"
     assertEquals(emptyResult, List.empty)
     assertEquals(result, List.empty)
@@ -135,7 +136,7 @@ class PullRequestRepositoryTest extends FunSuite {
       )
       result <- pullRequestRepository.getObsoleteOpenPullRequests(repo, newUpdate)
     } yield (emptyResult, result)
-    val (state, (emptyResult, result)) = p.run(MockState.empty).unsafeRunSync()
+    val (state, (emptyResult, result)) = p.runSA(MockState.empty).unsafeRunSync()
     val store = config.workspace / s"store/pull_requests/v2/github/${repo.show}/pull_requests.json"
     assertEquals(emptyResult, List.empty)
     assertEquals(result, List.empty)
diff --git a/modules/core/src/test/scala/org/scalasteward/core/persistence/JsonKeyValueStoreTest.scala b/modules/core/src/test/scala/org/scalasteward/core/persistence/JsonKeyValueStoreTest.scala
index c3306a7a..5ce16091 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/persistence/JsonKeyValueStoreTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/persistence/JsonKeyValueStoreTest.scala
@@ -1,8 +1,9 @@
 package org.scalasteward.core.persistence
 
+import cats.effect.unsafe.implicits.global
 import cats.syntax.all._
 import munit.FunSuite
-import org.scalasteward.core.mock.MockContext.config
+import org.scalasteward.core.mock.MockConfig.config
 import org.scalasteward.core.mock.MockContext.context._
 import org.scalasteward.core.mock.MockState.TraceEntry.Cmd
 import org.scalasteward.core.mock.{MockEff, MockState}
@@ -16,7 +17,7 @@ class JsonKeyValueStoreTest extends FunSuite {
       _ <- kvStore.put("k2", "v2")
       v3 <- kvStore.get("k3")
     } yield (v1, v3)
-    val (state, value) = p.run(MockState.empty).unsafeRunSync()
+    val (state, value) = p.runSA(MockState.empty).unsafeRunSync()
     assertEquals(value, (Some("v1"), None))
 
     val k1File = config.workspace / "store" / "test-1" / "v0" / "k1" / "test-1.json"
@@ -44,7 +45,7 @@ class JsonKeyValueStoreTest extends FunSuite {
       v1 <- kvStore.get("k1")
       _ <- kvStore.set("k1", None)
     } yield v1
-    val (state, value) = p.run(MockState.empty).unsafeRunSync()
+    val (state, value) = p.runSA(MockState.empty).unsafeRunSync()
     assertEquals(value, Some("v0"))
 
     val k1File = config.workspace / "store" / "test-2" / "v0" / "k1" / "test-2.json"
@@ -68,7 +69,7 @@ class JsonKeyValueStoreTest extends FunSuite {
       v1 <- kvStore.get("k1")
       v2 <- kvStore.get("k2")
     } yield (v1, v2)
-    val (state, value) = p.run(MockState.empty).unsafeRunSync()
+    val (state, value) = p.runSA(MockState.empty).unsafeRunSync()
     assertEquals(value, (Some("v1"), None))
 
     val k1File = config.workspace / "store" / "test-3" / "v0" / "k1" / "test-3.json"
diff --git a/modules/core/src/test/scala/org/scalasteward/core/repoconfig/PullRequestFrequencyTest.scala b/modules/core/src/test/scala/org/scalasteward/core/repoconfig/PullRequestFrequencyTest.scala
index 4f4576de..980e349a 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/repoconfig/PullRequestFrequencyTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/repoconfig/PullRequestFrequencyTest.scala
@@ -4,6 +4,7 @@ import io.circe.parser
 import io.circe.syntax._
 import munit.FunSuite
 import org.scalasteward.core.util.Timestamp
+
 import scala.concurrent.duration._
 
 class PullRequestFrequencyTest extends FunSuite {
diff --git a/modules/core/src/test/scala/org/scalasteward/core/repoconfig/RepoConfigAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/repoconfig/RepoConfigAlgTest.scala
index a2670a4b..fac14f69 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/repoconfig/RepoConfigAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/repoconfig/RepoConfigAlgTest.scala
@@ -1,20 +1,22 @@
 package org.scalasteward.core.repoconfig
 
+import cats.effect.unsafe.implicits.global
 import eu.timepit.refined.types.numeric.NonNegInt
 import munit.FunSuite
 import org.scalasteward.core.TestSyntax._
 import org.scalasteward.core.data.{GroupId, Update}
 import org.scalasteward.core.mock.MockContext.context.repoConfigAlg
 import org.scalasteward.core.mock.MockState.TraceEntry.Log
-import org.scalasteward.core.mock.{MockContext, MockState}
+import org.scalasteward.core.mock.{MockConfig, MockState}
 import org.scalasteward.core.util.Nel
 import org.scalasteward.core.vcs.data.Repo
+
 import scala.concurrent.duration._
 
 class RepoConfigAlgTest extends FunSuite {
   test("config with all fields set") {
     val repo = Repo("fthomas", "scala-steward")
-    val configFile = MockContext.config.workspace / "fthomas/scala-steward/.scala-steward.conf"
+    val configFile = MockConfig.config.workspace / "fthomas/scala-steward/.scala-steward.conf"
     val content =
       """|updates.allow  = [ { groupId = "eu.timepit"} ]
          |updates.pin  = [
@@ -208,10 +210,10 @@ class RepoConfigAlgTest extends FunSuite {
 
   test("malformed config") {
     val repo = Repo("fthomas", "scala-steward")
-    val configFile = MockContext.config.workspace / "fthomas/scala-steward/.scala-steward.conf"
+    val configFile = MockConfig.config.workspace / "fthomas/scala-steward/.scala-steward.conf"
     val initialState =
       MockState.empty.addFiles(configFile -> """updates.ignore = [ "foo """).unsafeRunSync()
-    val (state, config) = repoConfigAlg.readRepoConfig(repo).run(initialState).unsafeRunSync()
+    val (state, config) = repoConfigAlg.readRepoConfig(repo).runSA(initialState).unsafeRunSync()
 
     assertEquals(config, None)
     val log = state.trace.collectFirst { case Log((_, msg)) => msg }.getOrElse("")
diff --git a/modules/core/src/test/scala/org/scalasteward/core/scalafmt/ScalafmtAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/scalafmt/ScalafmtAlgTest.scala
index 00d727cb..a0bc21f4 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/scalafmt/ScalafmtAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/scalafmt/ScalafmtAlgTest.scala
@@ -1,8 +1,9 @@
 package org.scalasteward.core.scalafmt
 
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.scalasteward.core.data.Version
-import org.scalasteward.core.mock.MockContext._
+import org.scalasteward.core.mock.MockConfig.config
 import org.scalasteward.core.mock.MockContext.context.scalafmtAlg
 import org.scalasteward.core.mock.MockState
 import org.scalasteward.core.mock.MockState.TraceEntry.Cmd
@@ -21,7 +22,7 @@ class ScalafmtAlgTest extends FunSuite {
                                   |""".stripMargin)
       .unsafeRunSync()
     val (state, maybeVersion) =
-      scalafmtAlg.getScalafmtVersion(buildRoot).run(initialState).unsafeRunSync()
+      scalafmtAlg.getScalafmtVersion(buildRoot).runSA(initialState).unsafeRunSync()
     val expectedState = initialState.copy(
       trace = Vector(Cmd("read", s"$repoDir/.scalafmt.conf"))
     )
@@ -42,7 +43,7 @@ class ScalafmtAlgTest extends FunSuite {
                                   |""".stripMargin)
       .unsafeRunSync()
     val (_, maybeVersion) =
-      scalafmtAlg.getScalafmtVersion(buildRoot).run(initialState).unsafeRunSync()
+      scalafmtAlg.getScalafmtVersion(buildRoot).runSA(initialState).unsafeRunSync()
     assertEquals(maybeVersion, Some(Version("2.0.0-RC8")))
   }
 }
diff --git a/modules/core/src/test/scala/org/scalasteward/core/update/ArtifactMigrationsTest.scala b/modules/core/src/test/scala/org/scalasteward/core/update/ArtifactMigrationsTest.scala
index 0ddb9969..c5012758 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/update/ArtifactMigrationsTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/update/ArtifactMigrationsTest.scala
@@ -1,5 +1,6 @@
 package org.scalasteward.core.update
 
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.scalasteward.core.TestSyntax._
 import org.scalasteward.core.data.{ArtifactId, GroupId, Update}
diff --git a/modules/core/src/test/scala/org/scalasteward/core/update/FilterAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/update/FilterAlgTest.scala
index dc724d86..255b2f55 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/update/FilterAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/update/FilterAlgTest.scala
@@ -1,5 +1,6 @@
 package org.scalasteward.core.update
 
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.scalasteward.core.TestSyntax._
 import org.scalasteward.core.data.Update.Single
@@ -64,7 +65,7 @@ class FilterAlgTest extends FunSuite {
 
     val initialState = MockState.empty
     val (state, filtered) =
-      filterAlg.localFilterMany(config, List(update1, update2)).run(initialState).unsafeRunSync()
+      filterAlg.localFilterMany(config, List(update1, update2)).runSA(initialState).unsafeRunSync()
 
     assertEquals(filtered, List(update1))
     val expected = initialState.copy(
diff --git a/modules/core/src/test/scala/org/scalasteward/core/update/PruningAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/update/PruningAlgTest.scala
index 697a0009..95777dd1 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/update/PruningAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/update/PruningAlgTest.scala
@@ -1,12 +1,13 @@
 package org.scalasteward.core.update
 
+import cats.effect.unsafe.implicits.global
 import io.circe.parser.decode
 import munit.FunSuite
 import org.scalasteward.core.TestInstances.dummyRepoCache
 import org.scalasteward.core.TestSyntax._
 import org.scalasteward.core.data.Resolver.MavenRepository
 import org.scalasteward.core.data.{DependencyInfo, RepoData, Scope}
-import org.scalasteward.core.mock.MockContext._
+import org.scalasteward.core.mock.MockConfig.config
 import org.scalasteward.core.mock.MockContext.context.pruningAlg
 import org.scalasteward.core.mock.MockState
 import org.scalasteward.core.mock.MockState.TraceEntry.{Cmd, Log}
diff --git a/modules/core/src/test/scala/org/scalasteward/core/util/dateTimeTest.scala b/modules/core/src/test/scala/org/scalasteward/core/util/dateTimeTest.scala
index e4f5cdcf..d247aeb9 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/util/dateTimeTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/util/dateTimeTest.scala
@@ -4,6 +4,7 @@ import cats.syntax.all._
 import munit.ScalaCheckSuite
 import org.scalacheck.Prop._
 import org.scalasteward.core.util.dateTime._
+
 import scala.concurrent.duration._
 
 class dateTimeTest extends ScalaCheckSuite {
diff --git a/modules/core/src/test/scala/org/scalasteward/core/util/loggerTest.scala b/modules/core/src/test/scala/org/scalasteward/core/util/loggerTest.scala
index 03c3e490..8a0ae6ab 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/util/loggerTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/util/loggerTest.scala
@@ -1,5 +1,6 @@
 package org.scalasteward.core.util
 
+import cats.effect.unsafe.implicits.global
 import cats.{Applicative, ApplicativeThrow}
 import munit.FunSuite
 import org.scalasteward.core.mock.MockContext.context._
diff --git a/modules/core/src/test/scala/org/scalasteward/core/util/utilTest.scala b/modules/core/src/test/scala/org/scalasteward/core/util/utilTest.scala
index 8ee8d498..ebab125d 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/util/utilTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/util/utilTest.scala
@@ -1,9 +1,11 @@
 package org.scalasteward.core.util
 
 import cats.effect.IO
+import cats.effect.unsafe.implicits.global
 import munit.ScalaCheckSuite
 import org.scalacheck.Gen
 import org.scalacheck.Prop._
+
 import scala.collection.mutable.ListBuffer
 
 class utilTest extends ScalaCheckSuite {
diff --git a/modules/core/src/test/scala/org/scalasteward/core/vcs/VCSExtraAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/vcs/VCSExtraAlgTest.scala
index d0ede26a..eaa9441b 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/vcs/VCSExtraAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/vcs/VCSExtraAlgTest.scala
@@ -1,6 +1,7 @@
 package org.scalasteward.core.vcs
 
 import cats.effect.IO
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.http4s.HttpRoutes
 import org.http4s.client.Client
@@ -9,7 +10,7 @@ import org.http4s.implicits._
 import org.scalasteward.core.TestInstances.ioLogger
 import org.scalasteward.core.TestSyntax._
 import org.scalasteward.core.data.{ReleaseRelatedUrl, Update}
-import org.scalasteward.core.mock.MockContext
+import org.scalasteward.core.mock.MockConfig
 import org.scalasteward.core.util.{Nel, UrlChecker}
 
 class VCSExtraAlgTest extends FunSuite {
@@ -22,14 +23,14 @@ class VCSExtraAlgTest extends FunSuite {
 
   implicit val client: Client[IO] = Client.fromHttpApp[IO](routes.orNotFound)
   implicit val urlChecker: UrlChecker[IO] =
-    UrlChecker.create[IO](MockContext.config).unsafeRunSync()
+    UrlChecker.create[IO](MockConfig.config).unsafeRunSync()
 
   private val updateFoo = Update.Single("com.example" % "foo" % "0.1.0", Nel.of("0.2.0"))
   private val updateBar = Update.Single("com.example" % "bar" % "0.1.0", Nel.of("0.2.0"))
   private val updateBuz = Update.Single("com.example" % "buz" % "0.1.0", Nel.of("0.2.0"))
 
   test("getBranchCompareUrl: std vsc") {
-    val vcsExtraAlg = VCSExtraAlg.create[IO](MockContext.config)
+    val vcsExtraAlg = VCSExtraAlg.create[IO](MockConfig.config)
 
     assertEquals(
       vcsExtraAlg
@@ -56,7 +57,7 @@ class VCSExtraAlgTest extends FunSuite {
   }
 
   test("getBranchCompareUrl: github on prem") {
-    val config = MockContext.config.copy(
+    val config = MockConfig.config.copy(
       vcsType = VCSType.GitHub,
       vcsApiHost = uri"https://github.on-prem.com/"
     )
diff --git a/modules/core/src/test/scala/org/scalasteward/core/vcs/VCSPackageTest.scala b/modules/core/src/test/scala/org/scalasteward/core/vcs/VCSPackageTest.scala
index 0498ed2a..1d99f8ca 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/vcs/VCSPackageTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/vcs/VCSPackageTest.scala
@@ -120,7 +120,7 @@ class VCSPackageTest extends FunSuite {
       possibleCompareUrls(
         GitHub,
         onPremVCSUri,
-        onPremVCSUri.addPath("/foo/bar"),
+        onPremVCSUri.addPath("foo/bar"),
         update
       ).map(_.url.renderString),
       List(
diff --git a/modules/core/src/test/scala/org/scalasteward/core/vcs/VCSRepoAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/vcs/VCSRepoAlgTest.scala
index 7847064a..3ed39939 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/vcs/VCSRepoAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/vcs/VCSRepoAlgTest.scala
@@ -1,12 +1,13 @@
 package org.scalasteward.core.vcs
 
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.http4s.syntax.literals._
 import org.scalasteward.core.git.Branch
+import org.scalasteward.core.mock.MockConfig.{config, envVars}
 import org.scalasteward.core.mock.MockContext.context.{gitAlg, logger, vcsRepoAlg}
-import org.scalasteward.core.mock.MockContext.{config, envVars}
 import org.scalasteward.core.mock.MockState.TraceEntry.{Cmd, Log}
-import org.scalasteward.core.mock.{MockContext, MockEff, MockState}
+import org.scalasteward.core.mock.{MockConfig, MockEff, MockState}
 import org.scalasteward.core.vcs.data.{Repo, RepoOut, UserOut}
 
 class VCSRepoAlgTest extends FunSuite {
@@ -52,7 +53,7 @@ class VCSRepoAlgTest extends FunSuite {
   }
 
   test("cloneAndSync: doNotFork = true") {
-    val config = MockContext.config.copy(doNotFork = true)
+    val config = MockConfig.config.copy(doNotFork = true)
     val state = new VCSRepoAlg[MockEff](config)
       .cloneAndSync(repo, parentRepoOut)
       .runS(MockState.empty)
diff --git a/modules/core/src/test/scala/org/scalasteward/core/vcs/bitbucket/BitbucketApiAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/vcs/bitbucket/BitbucketApiAlgTest.scala
index 1842df6a..bae9fa3d 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/vcs/bitbucket/BitbucketApiAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/vcs/bitbucket/BitbucketApiAlgTest.scala
@@ -1,6 +1,7 @@
 package org.scalasteward.core.vcs.bitbucket
 
 import cats.effect.IO
+import cats.effect.unsafe.implicits.global
 import io.circe.literal._
 import munit.FunSuite
 import org.http4s._
@@ -10,7 +11,7 @@ import org.http4s.dsl.io._
 import org.http4s.implicits._
 import org.scalasteward.core.git.Sha1.HexString
 import org.scalasteward.core.git._
-import org.scalasteward.core.mock.MockContext.config
+import org.scalasteward.core.mock.MockConfig.config
 import org.scalasteward.core.util.HttpJsonClient
 import org.scalasteward.core.vcs.data._
 
diff --git a/modules/core/src/test/scala/org/scalasteward/core/vcs/bitbucketserver/BitbucketServerApiAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/vcs/bitbucketserver/BitbucketServerApiAlgTest.scala
index 8dd2b7bc..a1a980ec 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/vcs/bitbucketserver/BitbucketServerApiAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/vcs/bitbucketserver/BitbucketServerApiAlgTest.scala
@@ -1,6 +1,7 @@
 package org.scalasteward.core.vcs.bitbucketserver
 
 import cats.effect.IO
+import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.http4s.client.Client
 import org.http4s.dsl.io._
@@ -8,7 +9,7 @@ import org.http4s.implicits._
 import org.http4s.{HttpRoutes, Uri}
 import org.scalasteward.core.application.Config.BitbucketServerCfg
 import org.scalasteward.core.git.Branch
-import org.scalasteward.core.mock.MockContext.config
+import org.scalasteward.core.mock.MockConfig.config
 import org.scalasteward.core.util.HttpJsonClient
 import org.scalasteward.core.vcs.data._
 
diff --git a/modules/core/src/test/scala/org/scalasteward/core/vcs/data/BranchOutTest.scala b/modules/core/src/test/scala/org/scalasteward/core/vcs/data/BranchOutTest.scala
index 264b3555..0459e41c 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/vcs/data/BranchOutTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/vcs/data/BranchOutTest.scala
@@ -4,6 +4,7 @@ import io.circe.parser
 import munit.FunSuite
 import org.scalasteward.core.git.Sha1.HexString
 import org.scalasteward.core.git.{Branch, Sha1}
+
 import scala.io.Source
 
 class BranchOutTest extends FunSuite {
diff --git a/modules/core/src/test/scala/org/scalasteward/core/vcs/data/PullRequestOutTest.scala b/modules/core/src/test/scala/org/scalasteward/core/vcs/data/PullRequestOutTest.scala
index 5ad5a2e0..a12b476c 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/vcs/data/PullRequestOutTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/vcs/data/PullRequestOutTest.scala
@@ -4,6 +4,7 @@ import io.circe.parser
 import munit.FunSuite
 import org.http4s.syntax.literals._
 import org.scalasteward.core.vcs.data.PullRequestState.Open
+
 import scala.io.Source
 
 class PullRequestOutTest extends FunSuite {
diff --git a/modules/core/src/test/scala/org/scalasteward/core/vcs/data/RepoOutTest.scala b/modules/core/src/test/scala/org/scalasteward/core/vcs/data/RepoOutTest.scala
index 2f8ac114..f27d69bd 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/vcs/data/RepoOutTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/vcs/data/RepoOutTest.scala
@@ -1,10 +1,12 @@
 package org.scalasteward.core.vcs.data
 
 import cats.effect.IO
+import cats.effect.unsafe.implicits.global
 import io.circe.parser
 import munit.FunSuite
 import org.http4s.syntax.literals._
 import org.scalasteward.core.git.Branch
+
 import scala.io.Source
 
 class RepoOutTest extends FunSuite {
diff --git a/modules/core/src/test/scala/org/scalasteward/core/vcs/github/GitHubApiAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/vcs/github/GitHubApiAlgTest.scala
index 15b5e516..a338fcf8 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/vcs/github/GitHubApiAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/vcs/github/GitHubApiAlgTest.scala
@@ -1,6 +1,7 @@
 package org.scalasteward.core.vcs.github
 
 import cats.effect.IO
+import cats.effect.unsafe.implicits.global
 import io.circe.literal._
 import munit.FunSuite
 import org.http4s.HttpRoutes
@@ -10,7 +11,7 @@ import org.http4s.dsl.io._
 import org.http4s.implicits._
 import org.scalasteward.core.git.Sha1.HexString
 import org.scalasteward.core.git.{Branch, Sha1}
-import org.scalasteward.core.mock.MockContext.config
+import org.scalasteward.core.mock.MockConfig.config
 import org.scalasteward.core.util.HttpJsonClient
 import org.scalasteward.core.vcs.data._
 
diff --git a/modules/core/src/test/scala/org/scalasteward/core/vcs/github/authenticationTest.scala b/modules/core/src/test/scala/org/scalasteward/core/vcs/github/authenticationTest.scala
index ccee0734..8b84b2f6 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/vcs/github/authenticationTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/vcs/github/authenticationTest.scala
@@ -10,11 +10,11 @@ class authenticationTest extends FunSuite {
   test("addCredentials") {
     val request = authentication
       .addCredentials[Id](AuthenticatedUser("user", "pass"))
-      .apply(Request(headers = Headers.of(Accept(MediaType.text.plain))))
+      .apply(Request(headers = Headers(Accept(MediaType.text.plain))))
 
     assertEquals(
       request.headers,
-      Headers.of(Accept(MediaType.text.plain), Authorization(BasicCredentials("user", "pass")))
+      Headers(Accept(MediaType.text.plain), Authorization(BasicCredentials("user", "pass")))
     )
   }
 }
diff --git a/modules/core/src/test/scala/org/scalasteward/core/vcs/gitlab/GitLabApiAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/vcs/gitlab/GitLabApiAlgTest.scala
index 8be09bac..997ae821 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/vcs/gitlab/GitLabApiAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/vcs/gitlab/GitLabApiAlgTest.scala
@@ -1,6 +1,7 @@
 package org.scalasteward.core.vcs.gitlab
 
-import cats.effect.IO
+import cats.effect.unsafe.implicits.global
+import cats.effect.{Concurrent, IO}
 import cats.implicits._
 import io.circe.literal._
 import io.circe.parser._
@@ -16,7 +17,7 @@ import org.scalasteward.core.TestSyntax._
 import org.scalasteward.core.application.Config.GitLabCfg
 import org.scalasteward.core.data.{RepoData, Update, UpdateData}
 import org.scalasteward.core.git.{Branch, Sha1}
-import org.scalasteward.core.mock.MockContext.{config, user}
+import org.scalasteward.core.mock.MockConfig.{config, user}
 import org.scalasteward.core.repoconfig.RepoConfig
 import org.scalasteward.core.util.{HttpJsonClient, Nel}
 import org.scalasteward.core.vcs.data._
@@ -184,7 +185,7 @@ class GitLabApiAlgTest extends FunSuite {
         } <+> routes).orNotFound
       )
     val errorJsonClient: HttpJsonClient[IO] =
-      new HttpJsonClient[IO]()(implicitly, errorClient)
+      new HttpJsonClient[IO]()(errorClient, Concurrent[IO])
 
     val gitlabApiAlgNoFork =
       new GitLabApiAlg[IO](
diff --git a/modules/core/src/test/scala/org/scalasteward/core/vcs/gitlab/MergeRequestPayloadTest.scala b/modules/core/src/test/scala/org/scalasteward/core/vcs/gitlab/MergeRequestPayloadTest.scala
index 99677dac..0e83f3dd 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/vcs/gitlab/MergeRequestPayloadTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/vcs/gitlab/MergeRequestPayloadTest.scala
@@ -1,7 +1,7 @@
 package org.scalasteward.core.vcs.gitlab
 
-import io.circe.syntax._
 import io.circe.literal._
+import io.circe.syntax._
 import munit.FunSuite
 import org.scalasteward.core.git.Branch
 import org.scalasteward.core.vcs.data.NewPullRequestData