Skip to content

v2.9.0: PTY mode, ANSI in logs, custom stop signals, on_output hook

Choose a tag to compare

@mise-en-dev mise-en-dev released this 03 May 15:07
· 85 commits to main since this release
Immutable release. Only release title and notes can be modified.
ee767ff

⚠️ Windows binaries did not ship with this release. The release pipeline failed on both Windows targets because two of the PRs below introduced Unix-only code without cfg gating. The patch release v2.9.1 restores the Windows build and ships the binaries. macOS and Linux artifacts are unaffected.

Pitchfork v2.9.0 keeps ANSI color in stored logs, adds an opt-in PTY mode for daemons that check isatty(), lets each daemon customize its stop signal and graceful-shutdown timeout, and introduces an on_output hook that fires when daemon output matches a pattern.

Added

  • PTY mode for daemons -- Set pty = true on a daemon and the supervisor allocates a real pseudo-terminal pair via openpty(3) and dups the slave onto the child's stdin/stdout/stderr. Programs that probe isatty() (most CLI tools that emit color, render progress bars, or prompt interactively) now behave as if they were run from a terminal. Falls back to pipes with a warning if PTY allocation fails. Unix-only. (#408) - @gaojunran

    [daemons.dev]
    run = "npm run dev"
    pty = true
  • ANSI color preserved in logs by default -- Daemon output is now written to log files with ANSI escapes intact, and stripping happens at display time in pitchfork logs. Color is kept when the terminal supports it and stripped automatically with --raw or when colors are disabled (e.g. piping to a file, NO_COLOR). The on_output / ready_output matchers run against ANSI-stripped output, so existing patterns keep working. (#408) - @gaojunran

  • Configurable stop signal and per-daemon stop timeout -- Override the signal used for graceful shutdown per daemon, with an optional timeout before the supervisor escalates to SIGKILL. Accepts a bare signal name or a { signal, timeout } object. (#406) - @gaojunran

    [daemons.api]
    run = "npm run dev"
    stop_signal = "SIGINT"
    
    [daemons.worker]
    run = "./worker"
    stop_signal = { signal = "SIGTERM", timeout = "10s" }

    Supported signals: SIGTERM, SIGINT, SIGQUIT, SIGHUP, SIGUSR1, SIGUSR2. The per-daemon timeout overrides the global settings.supervisor.stop_timeout for that daemon only.

  • on_output hook -- Run a command when the daemon emits output matching a substring or regex, with built-in debouncing so chatty daemons don't fire the hook on every line. (#399) - @gaojunran

    [daemons.api]
    run = "npm run dev"
    on_output = { run = "notify-send 'API ready'", filter = "listening on" }
    
    [daemons.tail]
    run = "tail -F /var/log/app.log"
    on_output = { run = "page-oncall.sh", regex = "ERROR|FATAL", debounce = "30s" }

    At most one of filter (substring) or regex (regex) may be set; with neither, the hook fires on every line subject to debouncing (default 1000ms). Pattern matching is performed against ANSI-stripped output covering both stdout and stderr.

Full Changelog: v2.8.0...v2.9.0

💚 Sponsor pitchfork

pitchfork is built by @jdx at en.dev — an independent studio shipping developer tools like mise, aube, hk, pitchfork, and more. Development is sustained by sponsorships.

If pitchfork has a place in your dev workflow, please consider sponsoring at en.dev. Individual and company sponsorships are what keep the project healthy and moving forward.