Skip to content

v2.13.0: Settings, log rotation, and a new web UI

Choose a tag to compare

@mise-en-dev mise-en-dev released this 08 Jun 21:40
· 38 commits to main since this release
Immutable release. Only release title and notes can be modified.
0566047

A feature-heavy release that ships a real settings CLI, log rotation backed by SQLite, a fully rewritten Vue web UI, and finer control over cron startup behavior.

Highlights

  • A new pf settings command and a renamed pf daemons command (formerly pf config) bring proper, scope-aware configuration management to the CLI.
  • Logs move into a single SQLite database with built-in time- and count-based rotation, replacing the old per-daemon text files.
  • The web UI is now a Vue SPA against a documented REST API, and cron daemons gain explicit control over whether they fire on startup.

Added

  • pf settings command (#471) — @gaojunran. View and modify pitchfork settings without hand-editing TOML:

    pitchfork settings                          # show all current settings
    pitchfork settings list --group web         # list available settings in a group
    pitchfork settings get general.log_level
    pitchfork settings set general.log_level debug
    pitchfork settings set web.auto_start true --global
    pitchfork settings set supervisor.stop_timeout 10s --local

    --global, --local, and --project choose between ~/.config/pitchfork/config.toml, pitchfork.local.toml, and pitchfork.toml. The supervisor now reloads settings at runtime after a write, so changes take effect without restarting.

  • Log rotation (#470) — @gaojunran. New [settings.logs] options let the supervisor prune old log data automatically (hourly):

    [settings.logs]
    time_retention = "7d"        # delete entries older than 7 days
    line_retention = 10000       # keep only the most recent 10,000 entries per daemon

    Both can be combined, and individual daemons can override them with per-daemon time_retention / line_retention fields. Environment variables PITCHFORK_LOG_TIME_RETENTION and PITCHFORK_LOG_LINE_RETENTION are also supported.

  • cron.immediate config (#461) — @gaojunran. Cron daemons now have an explicit knob for what happens when the supervisor starts up. By default, the first run is deferred until the next scheduled time. Opt back in to the old "look back 10 seconds and fire if a slot has just passed" behavior with:

    [daemons.backup]
    run = "./backup.sh"
    cron = { schedule = "0 0 2 * * *", immediate = true }

    Also available as --cron-immediate on pf daemons add.

  • pf sponsors command (#458) — @jdx. Prints the companies sponsoring pitchfork and the en.dev project family.

  • Fully-qualified daemon names in pf list (#467) — @gaojunran. pitchfork ls now always shows namespace/name, even when there's no local conflict, so it's clear which project a daemon belongs to. Short-ID resolution also falls back to the state file when no local config matches, so commands targeting globally-running daemons work from anywhere; ambiguous matches now list all candidates in the error. Resolves #465.

Changed

  • pf config renamed to pf daemons (#471) — @gaojunran. The old name was confusing now that pitchfork has actual settings. The new pf daemons (alias daemon) keeps add and remove subcommands and adds --local / --project flags to target pitchfork.local.toml or pitchfork.toml explicitly. Old shell scripts using pf config will need updating.

  • Cron daemons no longer fire on startup by default (#461) — @gaojunran. Previously, starting a cron daemon would trigger it immediately if a scheduled time had passed in the prior 10 seconds. The default is now to wait for the next scheduled time; set immediate = true on the cron config to restore the old behavior. Resolves #460.

  • Web UI rewritten as a Vue SPA (#457, #473) — @gaojunran. The dashboard, daemon views, proxy views, and log views are now rendered client-side from a documented REST API (daemons, logs with tail/stream, proxies, namespaces, processes, stats). The API server can optionally run standalone with token-based auth and auto-start, and a published JSON schema describes every endpoint. The legacy htmx server-rendered pages and styles have been removed. Includes orphaned-daemon cleanup on supervisor startup and descendant-aware active-port detection.

  • Logs stored in SQLite (#470) — @gaojunran. All daemon logs now live in a single SQLite database at ~/.local/state/pitchfork/logs/logs.db (WAL mode for concurrent readers), with millisecond-precision timestamps for fast time-based filtering. The CLI, TUI, Web UI, and API all read from the same store; SSE log streams emit a clear event when logs are wiped. Legacy text log files from earlier versions are imported on first access and then deleted.

Breaking Changes

  • pf config is now pf daemons. The cfg alias is gone; use daemon instead. Scripts and aliases referencing pitchfork config add / pitchfork config remove need to be updated. (#471)
  • Cron daemons no longer fire on pitchfork start if a scheduled time happened to fall within the previous 10 seconds. Add immediate = true to the cron config (or pass --cron-immediate when adding the daemon) to restore the previous behavior. (#461)
  • Log files are no longer written to ~/.local/state/pitchfork/logs/<namespace>--<name>/<namespace>--<name>.log. Tools that tail those files directly should switch to pitchfork logs <id> or query the SQLite database at ~/.local/state/pitchfork/logs/logs.db. (#470)

Full Changelog: v2.12.1...v2.13.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.