{-# LANGUAGE CPP #-} --{-# LANGUAGE MultilineStrings #-} module Main where import System.IO import System.Exit import Options.Applicative import qualified Control.Exception.Safe as E import Paths_pty_mcp_server (version) import Data.Version (showVersion) import qualified PMS.Application.Service.App.Control as A import qualified PMS.Application.Service.DM.Type as A import qualified PMS.UI.Request.App.Control as URQ import qualified PMS.UI.Response.App.Control as URS import qualified PMS.UI.Notification.App.Control as UNO import qualified PMS.Infra.CmdRun.App.Control as ICR import qualified PMS.Infra.ProcSpawn.App.Control as IPS import qualified PMS.Infra.Serial.App.Control as SER import qualified PMS.Infra.Socket.App.Control as SCK import qualified PMS.Infra.Watch.App.Control as IWA import qualified PMS.Domain.Service.App.Control as DSR #ifdef mingw32_HOST_OS #else import qualified PMS.Infrastructure.App.Control as INF #endif -- | -- main :: IO () main = getArgs >>= \args -> do #ifdef mingw32_HOST_OS let apps = [URQ.run, URS.run, UNO.run, ICR.run, IPS.run, IWA.run, DSR.run, SCK.run, SER.run] #else let apps = [URQ.run, URS.run, UNO.run, ICR.run, IPS.run, IWA.run, DSR.run, SCK.run, SER.run, INF.run] #endif flip E.catchAny exception $ flip E.finally finalize $ A.run args apps where finalize = do hPutStrLn stderr "-----------------------------------------------------------------------------" hPutStrLn stderr "Finalize called." hPutStrLn stderr "-----------------------------------------------------------------------------" exception e = do hPutStrLn stderr "-----------------------------------------------------------------------------" hPutStrLn stderr "ERROR exit." hPutStrLn stderr $ show e hPutStrLn stderr "-----------------------------------------------------------------------------" exitFailure ------------------------------------------------------------------------------- -- | -- optparse-applicative -- getArgs :: IO A.ArgData getArgs = execParser parseInfo -- | -- parseInfo :: ParserInfo A.ArgData parseInfo = info (helper <*> verOpt <*> options) $ mconcat [ fullDesc , header "pty-mcp-server - Pseudo-terminal MCP Server" , footer "Copyright (c) 2025 phoityne. All rights reserved." , progDesc "A minimal PTY-based server for running shell commands in MCP style.\n Designed for AI to control interactive programs like GHCi or bash." ] -- | -- verOpt :: Parser (a -> a) verOpt = infoOption msg $ mconcat [ short 'v' , long "version" , help "Show version" ] where msg = "pty-mcp-server-" ++ showVersion version -- | -- options :: Parser A.ArgData options = (<*>) helper $ A.ArgData <$> confOption -- | -- confOption :: Parser (Maybe FilePath) confOption = optional $ strOption $ mconcat [ short 'y', long "yaml" , help "config file" , metavar "FILE" ]