Skip to content

Latest commit

 

History

History

pi-daemon

README.md

pi-daemon

Background automation daemon for Pi — workflow discovery, file watchers, schedule rules, and task queue.

What it does

  • Workflow discovery: Auto-discovers workflows from packages/*/workflows/, .pi/workflows/, and workspace/workflows/
  • File watchers: Watch glob patterns for changes, record triggers
  • Rules engine: Evaluate trigger-based and schedule-based rules on heartbeat
  • Task queue: Sequential execution with retry, backoff, and crash recovery
  • Agent runner: Spawns Pi agents (pi --print) or runs scripts for each workflow
  • Live reload: daemon({ action: "reload" }) rediscovers workflows and rebuilds watchers/rules without a daemon restart
  • Control interface: Filesystem IPC — agents write JSON commands, daemon writes responses
  • Pi extension: daemon() tool + auto-start in tmux on session_start

Install

pi install npm:pi-daemon

Configuration

Create .pi/daemon.json (typically generated by just init from config.toml):

{
  "enabled": true,
  "heartbeat_interval_seconds": 60,
  "state_dir": ".bosun-daemon",
  "log_level": "info"
}

Workflows are auto-discovered — no manual rules or watchers needed in the config.

Workflows

Each workflow is a directory containing:

my-workflow/
├── config.toml           # Trigger, model, prompt, retry settings
├── agent.md              # Agent system prompt (for agent workflows)
├── validate-input.ts     # Optional: skip if conditions not met (exit 1)
└── validate-output.ts    # Optional: retry if output invalid (exit 1)

Workflow config.toml

[workflow]
name = "my-workflow"
description = "What this workflow does"
type = "agent"          # "agent" or "script"

[trigger]
schedule = "hourly"     # "hourly", "daily:HH", or omit
# watcher = "path/glob/**/*.json"  # File watcher pattern
# startup = true        # Run on daemon startup
# debounce_ms = 5000    # Watcher debounce

[agent]
model = "lite"          # Model tier from config.toml
prompt = "Task description for the agent"

[validators]
input = "validate-input.ts"
output = "validate-output.ts"

[retry]
max_attempts = 2

[timeout]
minutes = 10

Discovery locations (later overrides earlier)

  1. packages/*/workflows/*/ — packaged defaults
  2. .pi/workflows/*/ — repo-level customizations
  3. workspace/workflows/*/ — user-level overrides (gitignored)

daemon() tool

The Pi extension registers a daemon() tool:

daemon({ action: "status" })                         — show status, watchers, queue
daemon({ action: "trigger", handler: "my-workflow" }) — manually trigger a workflow
daemon({ action: "logs", lines: 100 })               — view recent log lines
daemon({ action: "reload" })                         — rediscover workflows/watchers/rules without restart
daemon({ action: "stop" })                           — stop daemon

Auto-start

When Pi starts inside tmux and .pi/daemon.json has enabled: true, the extension automatically spawns the daemon in a background tmux window named "daemon".

Architecture

reload command
  │
  └─► rediscover workflows → rebuild watchers/rules → continue heartbeats without restart

heartbeat (every N seconds)
  │
  ├─► evaluate rules (derived from currently loaded workflows)
  │     ├─ trigger rules: check triggers.json for pending watcher events
  │     └─ schedule rules: check time since last run
  │
  ├─► enqueue matching tasks (dedup by rule name)
  │
  └─► process next task in queue
        ├─ validate input (optional, exit 1 to skip)
        ├─ spawn agent (pi --print) or run script
        ├─ validate output (optional, exit 1 to retry)
        ├─ on success: move to history, clear triggers
        └─ on failure: retry with backoff

file change → watcher → triggers.json → heartbeat → rule matches → workflow runs

State files

All stored in state_dir (default .bosun-daemon/):

File Purpose
status.json Running state, PID, heartbeat, watchers
triggers.json Pending trigger records from watchers
rules-state.json Per-rule last run time and result
queue.json Task queue and history
daemon.log Log file
control/ Incoming command files (IPC)
responses/ Outgoing response files (IPC)

License

MIT