never executed always true always false
    1 module PureClaw.Channels.CLI
    2   ( -- * CLI channel
    3     mkCLIChannelHandle
    4   ) where
    5 
    6 import Data.Text qualified as T
    7 import Data.Text.IO qualified as TIO
    8 import System.Console.Haskeline qualified as HL
    9 import System.Directory (createDirectoryIfMissing)
   10 import System.IO (hFlush, stderr, stdout)
   11 
   12 import PureClaw.CLI.Config (getPureclawDir)
   13 import PureClaw.Core.Types
   14 import PureClaw.Handles.Channel
   15 
   16 -- | Create a channel handle that uses haskeline for line editing.
   17 -- Provides readline-style input: backspace, arrow keys, up/down history,
   18 -- Ctrl-A/E, etc. History is persisted to @~\/.pureclaw\/history@.
   19 mkCLIChannelHandle :: IO ChannelHandle
   20 mkCLIChannelHandle = do
   21   histPath <- haskelineHistoryPath
   22   let settings = HL.defaultSettings { HL.historyFile = Just histPath }
   23   pure ChannelHandle
   24     { _ch_receive = do
   25         mLine <- HL.runInputT settings (HL.getInputLine "> ")
   26         case mLine of
   27           Nothing   -> ioError (userError "EOF")  -- Ctrl-D: agent loop catches this
   28           Just line -> pure IncomingMessage
   29             { _im_userId  = UserId "cli-user"
   30             , _im_content = T.pack line
   31             }
   32     , _ch_send = \msg -> do
   33         TIO.putStrLn ""
   34         TIO.putStrLn (_om_content msg)
   35         TIO.putStrLn ""
   36     , _ch_sendError = \err ->
   37         TIO.hPutStrLn stderr $ "Error: " <> T.pack (show err)
   38     , _ch_sendChunk = \case
   39         ChunkText t -> do
   40           TIO.putStr t
   41           hFlush stdout
   42         ChunkDone -> TIO.putStrLn ""
   43     , _ch_streaming = True
   44     , _ch_readSecret = do
   45         mLine <- HL.runInputT settings (HL.getPassword Nothing "")
   46         pure (maybe "" T.pack mLine)
   47     , _ch_prompt = \promptText -> do
   48         mLine <- HL.runInputT settings (HL.getInputLine (T.unpack promptText))
   49         pure (maybe "" T.pack mLine)
   50     , _ch_promptSecret = \promptText -> do
   51         mLine <- HL.runInputT settings (HL.getPassword Nothing (T.unpack promptText))
   52         pure (maybe "" T.pack mLine)
   53     }
   54 
   55 -- | Path to the haskeline history file: @~\/.pureclaw\/history@.
   56 -- Creates the directory if it does not exist.
   57 haskelineHistoryPath :: IO FilePath
   58 haskelineHistoryPath = do
   59   dir <- getPureclawDir
   60   createDirectoryIfMissing True dir
   61   pure (dir <> "/history")