diff --git a/CalamityCommands/Dsl.hs b/CalamityCommands/Dsl.hs
--- a/CalamityCommands/Dsl.hs
+++ b/CalamityCommands/Dsl.hs
@@ -18,6 +18,7 @@
     groupA,
     groupA',
     DSLState,
+    DSLC,
     raiseDSL,
     fetchHandler,
 ) where
@@ -89,6 +90,18 @@
                                         ': r
     )
 
+type DSLC m c a r = P.Members [
+  LocalWriter (LH.HashMap T.Text (Command m c a, AliasType))
+        , LocalWriter (LH.HashMap T.Text (Group m c a, AliasType))
+            , P.Reader (Maybe (Group m c a))
+                , P.Tagged "hidden" (P.Reader Bool)
+                    , P.Reader (c -> T.Text)
+                        , P.Tagged "original-help" (P.Reader (c -> T.Text))
+                            , P.Reader [Check m c]
+                                , P.Reader (CommandHandler m c a)
+                                    , P.Fixpoint
+                              ] r
+
 raiseDSL :: P.Sem r x -> P.Sem (DSLState m c a r) x
 raiseDSL = P.raise . P.raise . P.raise . P.raise . P.raise . P.raise . P.raise . P.raise . P.raise
 
@@ -100,7 +113,7 @@
  reader context.
 -}
 command' ::
-    (Monad m, P.Member (P.Final m) r) =>
+    (Monad m, P.Member (P.Final m) r, DSLC m c a r) =>
     -- | The name of the command
     T.Text ->
     -- | The command's parameter metadata
@@ -109,7 +122,7 @@
     (c -> P.Sem r (Either CommandError p)) ->
     -- | The callback for this command
     ((c, p) -> P.Sem (P.Fail ': r) a) ->
-    P.Sem (DSLState m c a r) (Command m c a)
+    P.Sem r (Command m c a)
 command' name params parser cb = commandA' name [] params parser cb
 
 {- | Given the command name, aliases, and parameter names, @parser@ and @callback@
@@ -121,7 +134,7 @@
 -}
 commandA' ::
     forall p c a m r.
-    (Monad m, P.Member (P.Final m) r) =>
+    (Monad m, P.Member (P.Final m) r, DSLC m c a r) =>
     -- | The name of the command
     T.Text ->
     -- | The aliases for the command
@@ -132,13 +145,13 @@
     (c -> P.Sem r (Either CommandError p)) ->
     -- | The callback for this command
     ((c, p) -> P.Sem (P.Fail ': r) a) ->
-    P.Sem (DSLState m c a r) (Command m c a)
+    P.Sem r (Command m c a)
 commandA' name aliases params parser cb = do
     parent <- P.ask @(Maybe (Group m c a))
     hidden <- P.tag $ P.ask @Bool
     checks <- P.ask @[Check m c]
     help' <- P.ask @(c -> T.Text)
-    cmd <- raiseDSL $ buildCommand' (name :| aliases) parent hidden checks params help' parser cb
+    cmd <- buildCommand' (name :| aliases) parent hidden checks params help' parser cb
     ltell $ LH.singleton name (cmd, Original)
     ltell $ LH.fromList [(name, (cmd, Alias)) | name <- aliases]
     pure cmd
@@ -167,6 +180,7 @@
     forall ps c a m r.
     ( Monad m
     , P.Member (P.Final m) r
+    , DSLC m c a r
     , TypedCommandC ps c a r
     , CommandContext m c a
     ) =>
@@ -174,7 +188,7 @@
     T.Text ->
     -- | The callback for this command
     (c -> CommandForParsers ps r a) ->
-    P.Sem (DSLState m c a r) (Command m c a)
+    P.Sem r (Command m c a)
 command name cmd = commandA @ps name [] cmd
 
 {- | Given the name and aliases of a command and a callback, and a type level list of
@@ -197,6 +211,7 @@
     forall ps c a m r.
     ( Monad m
     , P.Member (P.Final m) r
+    , DSLC m c a r
     , TypedCommandC ps c a r
     , CommandContext m c a
     ) =>
@@ -206,13 +221,13 @@
     [T.Text] ->
     -- | The callback for this command
     (c -> CommandForParsers ps r a) ->
-    P.Sem (DSLState m c a r) (Command m c a)
+    P.Sem r (Command m c a)
 commandA name aliases cmd = do
     parent <- P.ask @(Maybe (Group m c a))
     hidden <- P.tag $ P.ask @Bool
     checks <- P.ask @[Check m c]
     help' <- P.ask @(c -> T.Text)
-    cmd' <- raiseDSL $ buildCommand @ps (name :| aliases) parent hidden checks help' cmd
+    cmd' <- buildCommand @ps (name :| aliases) parent hidden checks help' cmd
     ltell $ LH.singleton name (cmd', Original)
     ltell $ LH.fromList [(name, (cmd', Alias)) | name <- aliases]
     pure cmd'
@@ -246,10 +261,10 @@
 {- | Add to the list of checks for any commands registered inside the given
  action.
 -}
-requires ::
+requires :: DSLC m c a r =>
     [Check m c] ->
-    P.Sem (DSLState m c a r) x ->
-    P.Sem (DSLState m c a r) x
+    P.Sem r x ->
+    P.Sem r x
 requires = P.local . (<>)
 
 {- | Construct a check and add it to the list of checks for any commands
@@ -258,15 +273,15 @@
  Refer to 'CalamityCommands.Check.Check' for more info on checks.
 -}
 requires' ::
-    (Monad m, P.Member (P.Final m) r) =>
+    (Monad m, P.Member (P.Final m) r, DSLC m c a r) =>
     -- | The name of the check
     T.Text ->
     -- | The callback for the check
     (c -> P.Sem r (Maybe T.Text)) ->
-    P.Sem (DSLState m c a r) x ->
-    P.Sem (DSLState m c a r) x
+    P.Sem r x ->
+    P.Sem r x
 requires' name cb m = do
-    check <- raiseDSL $ buildCheck name cb
+    check <- buildCheck name cb
     requires [check] m
 
 {- | Construct some pure checks and add them to the list of checks for any
@@ -283,11 +298,11 @@
  @
 -}
 requiresPure ::
-    Monad m =>
+    (Monad m, DSLC m c a r) =>
     [(T.Text, c -> Maybe T.Text)] ->
     -- A list of check names and check callbacks
-    P.Sem (DSLState m c a r) x ->
-    P.Sem (DSLState m c a r) x
+    P.Sem r x ->
+    P.Sem r x
 requiresPure checks = requires $ map (uncurry buildCheckPure) checks
 
 {- | Construct a group and place any commands registered in the given action
@@ -297,11 +312,11 @@
  'group'' if you don't want that (i.e. your help function is context aware).
 -}
 group ::
-    (Monad m, P.Member (P.Final m) r) =>
+    (Monad m, P.Member (P.Final m) r, DSLC m c a r) =>
     -- | The name of the group
     T.Text ->
-    P.Sem (DSLState m c a r) x ->
-    P.Sem (DSLState m c a r) x
+    P.Sem r x ->
+    P.Sem r x
 group name m = groupA name [] m
 
 {- | Construct a group with aliases and place any commands registered in the
@@ -315,13 +330,13 @@
 -}
 groupA ::
     forall x c m a r.
-    (Monad m, P.Member (P.Final m) r) =>
+    (Monad m, P.Member (P.Final m) r, DSLC m c a r) =>
     -- | The name of the group
     T.Text ->
     -- | The aliases of the group
     [T.Text] ->
-    P.Sem (DSLState m c a r) x ->
-    P.Sem (DSLState m c a r) x
+    P.Sem r x ->
+    P.Sem r x
 groupA name aliases m = mdo
     parent <- P.ask @(Maybe (Group m c a))
     hidden <- P.tag $ P.ask @Bool
@@ -351,11 +366,11 @@
  value.
 -}
 group' ::
-    P.Member (P.Final m) r =>
+    (P.Member (P.Final m) r, DSLC m c a r) =>
     -- | The name of the group
     T.Text ->
-    P.Sem (DSLState m c a r) x ->
-    P.Sem (DSLState m c a r) x
+    P.Sem r x ->
+    P.Sem r x
 group' name m = groupA' name [] m
 
 {- | Construct a group with aliases and place any commands registered in the given action
@@ -369,13 +384,13 @@
 -}
 groupA' ::
     forall x c m a r.
-    P.Member (P.Final m) r =>
+    (P.Member (P.Final m) r, DSLC m c a r) =>
     -- | The name of the group
     T.Text ->
     -- | The aliases of the group
     [T.Text] ->
-    P.Sem (DSLState m c a r) x ->
-    P.Sem (DSLState m c a r) x
+    P.Sem r x ->
+    P.Sem r x
 groupA' name aliases m = mdo
     parent <- P.ask @(Maybe (Group m c a))
     hidden <- P.tag $ P.ask @Bool
@@ -391,5 +406,5 @@
     pure res
 
 -- | Retrieve the final command handler for this block
-fetchHandler :: P.Sem (DSLState m c a r) (CommandHandler m c a)
+fetchHandler :: DSLC m c a r => P.Sem r (CommandHandler m c a)
 fetchHandler = P.ask
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
 
 <p align="center">
   <a href="https://hackage.haskell.org/package/calamity-commands"><img src="https://img.shields.io/hackage/v/calamity-commands" alt="Hackage"></a>
-  <a href="https://gitlab.com/simmsb/calamity/pipelines"><img src="https://img.shields.io/gitlab/pipeline/simmsb/calamity" alt="Gitlab pipeline status"></a>
+  <a href="https://github.com/simmsb/calamity/actions/workflows/build.yml"><img src="https://github.com/simmsb/calamity/actions/workflows/build.yml/badge.svg" alt="Build Status"></a>
   <a href="https://github.com/simmsb/calamity/blob/master/LICENSE"><img src="https://img.shields.io/github/license/simmsb/calamity" alt="License"></a>
   <a href="https://hackage.haskell.org/package/calamity"><img src="https://img.shields.io/hackage-deps/v/calamity" alt="Hackage-Deps"></a>
   <a href="https://discord.gg/NGCThCY"><img src="https://discord.com/api/guilds/754446998077178088/widget.png?style=shield" alt="Discord Invite"></a>
diff --git a/calamity-commands.cabal b/calamity-commands.cabal
--- a/calamity-commands.cabal
+++ b/calamity-commands.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           calamity-commands
-version:        0.2.0.0
+version:        0.3.0.0
 synopsis:       A library for declaring, parsing, and invoking text-input based commands
 description:    Please see the README on GitHub at <https://github.com/simmsb/calamity#readme>
 category:       Utils
@@ -49,8 +49,6 @@
       CalamityCommands.ParsePrefix
       CalamityCommands.Parser
       CalamityCommands.Utils
-  other-modules:
-      Paths_calamity_commands
   hs-source-dirs:
       ./
   default-extensions:
