diff --git a/climb.cabal b/climb.cabal
--- a/climb.cabal
+++ b/climb.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 13958ca7b14089cca51ac048a8cea2d64d6e8e460fa1cddae5a3d4f5bd15ec68
+-- hash: f41c917ee50a977a56b9761e243421d7b49b0f973556aad566f526b406bf51d8
 
 name:           climb
-version:        0.4.0
+version:        0.4.1
 synopsis:       Building blocks for a GHCi-like REPL with colon-commands
 description:    Please see the README on GitHub at <https://github.com/ejconlon/climb#readme>
 category:       User Interfaces
diff --git a/src/Climb.hs b/src/Climb.hs
--- a/src/Climb.hs
+++ b/src/Climb.hs
@@ -12,6 +12,7 @@
   , noOptionCommands
   , noCompletion
   , runReplDef
+  , stepReplDef
   ) where
 
 import Control.Exception (Exception (..), SomeAsyncException (..), SomeException)
@@ -120,3 +121,8 @@
   liftIO (TIO.putStrLn greeting)
   liftIO (TIO.putStrLn "Enter `:quit` to exit or `:help` to see all commands.")
   replM onInterrupt prompt handledAction comp
+
+-- | Processes a single line of input. Useful for testing.
+-- (Note that this does not handle default option commands.)
+stepReplDef :: MonadThrow m => ReplDef m -> Text -> m ReplDirective
+stepReplDef (ReplDef _ _ _ opts exec _) = outerCommand opts exec
