effectful-cli: CLI helpers for the effectful ecosystem

[ cli, gpl, library ] [ Propose Tags ] [ Report a vulnerability ]
Versions [RSS] 0.1.0.0, 0.1.0.1, 0.1.0.2, 0.2.0.0, 0.2.1.0, 0.2.2.0, 0.2.3.0, 0.2.4.0, 0.2.4.1, 0.2.4.2, 0.2.5.0, 0.2.6.0, 0.2.7.0, 0.2.8.0, 0.2.9.0
Change log CHANGELOG.md
Dependencies base (>=4.20 && <4.22), containers (>=0.6.8 && <0.8), directory (>=1.3.8 && <1.4), effectful (>=2.6.1 && <2.8), effectful-core (>=2.6.1 && <2.8), filepath (>=1.4.300 && <1.6), hs-opentelemetry-api (>=1.0 && <1.1), hs-opentelemetry-instrumentation-monad-logger (>=1.0 && <1.1), http-client-effectful (>=1.0 && <1.1), megaparsec (>=9.7 && <9.8), monad-logger (>=0.3.42 && <0.4), optparse-applicative (>=0.18.1 && <0.20), table-layout (>=1.0 && <1.1), text (>=2.1 && <2.2), time (>=1.12.2 && <1.15), toml-parser (>=2.0.1 && <2.1), uuid (>=1.3.16 && <1.4) [details]
License GPL-3.0-only
Copyright 2026 drlkf
Author drlkf
Maintainer drlkf <drlkf@drlkf.net>
Uploaded by drlkf at 2026-11-09T22:53:51Z
Category CLI
Distributions
Downloads 57 total (57 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user
Build status unknown [no reports yet]

Readme for effectful-cli-0.2.9.0

[back to package description]

effectful-cli

Small helpers for writing CLIs with effectful: effect constraints, concurrency, prompts, sleep/time, optparse-applicative helpers and a monad-logger bridge (stderr or OpenTelemetry).

Quick start

Add the dependencies to package.yaml:

dependencies:
  - effectful
  - effectful-cli
  - http-client-effectful
  - monad-logger
  - optparse-applicative
  - text

Minimal Main.hs, one hello subcommand logging to stderr:

{-# LANGUAGE OverloadedStrings #-}

import Control.Monad.Logger (logInfoN)
import Data.CLI.Class
import Data.CLI.Impl (execCLIParser, mkCommand, usage)
import Data.Error.CLI (CLIError, displayCLIError)
import Data.Text qualified as T
import Data.Text.IO qualified as T
import Effectful
import Effectful.Error.Static (runErrorNoCallStack)
import Effectful.HttpClient (runHttpClientTls)
import Effectful.Logger (runStderrLogger)
import Effectful.Reader.Static (runReader)
import Options.Applicative (hsubparser, strArgument)

data Config = Config

instance CLIConfig Config where
  autoAccept _ = False
  autoDecline _ = False

newtype Hello = Hello String

instance Command Config CLIError Hello where
  cmdname _ = "hello"
  doc _ = "greet someone"
  parser _ = Hello <$> strArgument mempty
  runner (Hello name) = logInfoN ("hello " <> T.pack name)

main :: IO ()
main = do
  cmd <- execCLIParser
         (usage "hello" "0.1.0" "greeter" (hsubparser (mkCommand (Hello ""))))
  res <-
    runEff .
    runHttpClientTls .
    runStderrLogger .
    runReader Config .
    runErrorNoCallStack @CLIError .
    runErrorNoCallStack @CLIError $
    runner cmd
  either (T.putStrLn . displayCLIError) pure (res >>= id)
stack run -- hello world

See the Effectful.CLI module docs for the walkthrough.

Build

stack build --test

Release

Requires just and a Hackage token in HACKAGE_KEY.

just docs       # build Haddock tarball
just candidate  # upload package + docs as Hackage candidate
just release    # publish package + docs to Hackage