npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kky42/pievo

v0.5.6

Published

Durable loops for AI agents — run pi-flow workflows on a cadence, with daily quotas, an append-only ledger, and a live dashboard

Downloads

4,288

Readme

pievo

Durable loops for AI agents — run pi-flow workflows on a cadence, with daily quotas, an append-only ledger, and a live dashboard.

npm node license

pievo dashboard — loops overview

Pievo runs agent work that has to keep happening while you're not looking — knowledge-base refreshes, morning digests, issue triage, monitoring. You register a loop (one named workflow plus a cadence), and pievo runs it on schedule, records every run durably, and shows you exactly what happened.

  • Durable by construction. Every accepted run is committed to an append-only ledger before it executes and ends with exactly one terminal record — complete, blocked, error, or interrupted — even across crashes and daemon restarts. Startup recovery confirms stale workers are gone and closes out orphaned runs; it never guesses and never resumes half-finished work.
  • Spend under control. Per-loop daily quotas on runs, tokens, and cost; same-loop overlap is impossible; an error breaker blocks a loop after N consecutive failures instead of burning tokens all night.
  • Agent-first CLI, human-first dashboard. Every command prints one JSON envelope with stable shapes and exit codes, so agents and scripts can operate pievo directly. Humans get loop cards, statistics, run history, and live logs in the browser.
  • Honest state. The ledger is the only source of truth; everything else is a rebuildable copy. Unknown token counts display as unknown, never as a made-up zero.

Install

npm install -g @kky42/pievo

Requires Node.js >= 22.19. Workflows execute pi coding agents through pi-flow (both bundled as dependencies) and use your existing pi provider setup — if pi already works on your machine, pievo runs are ready to go.

Quickstart

1. Write a workflow. Workflows are plain JavaScript files in your project at .pi/workflows/<name>.js, with agent() calls doing the real work:

// ~/loops/.pi/workflows/kb-update.js
export const meta = { name: "kb-update", description: "Keep the knowledge base current." };

phase("Review sources");
const notes = await agent("Review notes changed since the last run and list stale entries.");

phase("Update entries");
await agent(`Update the knowledge base accordingly:\n${notes}`);

return { status: "complete", message: "Knowledge base refreshed." };

A workflow returns { status: "complete" | "blocked", message?, data? }. blocked is a strict, sticky intervention gate: use it only when authoritative evidence proves that an indispensable external action is outside the workflow's authority and rerunning cannot reasonably resolve it. Transient failures should error; safe no-ops and retry/reconciliation checkpoints should complete. See pi-flow for the full workflow API (agent, phase, parallel, schemas, subagent types).

2. Describe the loop.

# kb-update.yaml
version: 1
name: kb-update
objective: Keep the personal knowledge base current.
cwd: /Users/you/loops          # absolute path; workflows live under it
cadence:
  kind: delay                  # re-run 6h after each run finishes
  after_completion: 6h
workflow:
  name: kb-update
  timeout: 60m
quotas:
  max_runs_per_day: 8
  max_cost_usd_per_day: 5

3. Start the daemon and the loop.

pievo daemon start                  # prints the dashboard URL
pievo loop register kb-update.yaml
pievo loop start kb-update          # new loops register paused; this activates it

A due loop accepts a run immediately — the run_id is right there in the response. Commands never wait for execution: run-starting commands return at acceptance, and you poll for the outcome.

4. Watch it work.

pievo loop show kb-update           # config, quota usage, next due, recent runs
pievo run show <run-id>             # one run in full: state, result, usage
pievo run logs <run-id>             # lifecycle + workflow logs, live while executing

Or just open the dashboard:

pievo dashboard — loop detail

Cadences

  • delay — level-triggered: re-run after_completion after each run's terminal event, whatever the outcome. A fresh loop with no history is due immediately once started.
  • cron — edge-triggered: five fields, each *, a number, or a comma list (30 8 * * 1,2,3,4,5), evaluated in a configured IANA timezone. Missed ticks (downtime, paused, quota) are skipped, never replayed as a backlog.

Manual pievo loop run <name> works from any status and still respects overlap and quota (--ignore-quota to override quota once).

CLI

Every command prints exactly one JSON envelope: { ok, command, data, diagnostics, ... }. Exit codes: 0 ok, 1 expected failure, 2 usage error, 70 internal error. Reads work even with no daemon; mutations require it and never fall back to local writes.

| Command | What it does | |---|---| | pievo daemon start | stop | restart | status | Manage the per-home daemon (--foreground for supervisors). | | pievo doctor | Environment and state-root health checks. | | pievo loop register <config.yaml> | Create or update a loop by content hash. | | pievo loop list | Triage view: status, active/latest run, next due. | | pievo loop show <name> | Full view: config, quota usage, consecutive errors, recent runs. | | pievo loop start | pause <name> | Activate / stop future scheduling (pause never kills a running run). | | pievo loop run <name> | Accept one manual run now; returns its run_id. | | pievo loop interrupt <name> | Interrupt the active run (cooperative, then SIGTERM/SIGKILL). | | pievo loop remove <name> | Remove from current state; ledger and run history survive. | | pievo loop runs <name> | Recent run summaries, newest first. | | pievo run show <run-id> | One run in full, including the workflow's result.data. | | pievo run logs <run-id> | Tail lifecycle and workflow logs, live while it executes. |

Loop config reference

version: 1                   # schema version, always 1
name: kb-update              # stable key: ^[a-z0-9][a-z0-9_-]{0,63}$
objective: Keep the knowledge base current.
cwd: /abs/path/to/project    # must exist; workflow file lives under it
cadence:
  kind: delay                # …or: kind: cron
  after_completion: 6h       #     expr: "0 9 * * *"
                             #     timezone: Asia/Taipei
workflow:
  name: kb-update            # must match .pi/workflows/<name>.js meta.name
  args: {}                   # JSON args passed to the workflow
  timeout: 240m              # wall-clock cap enforced outside the worker (default 240m)
quotas:                      # optional daily gates, machine-local calendar day
  max_runs_per_day: 24
  max_tokens_per_day: 1000000
  max_cost_usd_per_day: 10
policy:
  max_consecutive_errors: 3  # errors in a row before the loop blocks (default 3)

Durations are <N>s|m|h|d strings. Unknown keys are rejected at every level, so a misspelled quota can never silently disappear. Registration is create-or-update by content hash — edit the YAML and register again; running runs keep the config they started with.

Loop lifecycle

A loop is active (scheduler may start runs), paused (operator said stop), or blocked (scheduling stopped for operator attention). Workflow-authored blocked is intentionally strict and sticky: transient failures should become error runs, while safe no-ops and retry/reconciliation checkpoints remain complete. The error breaker can also block a loop after max_consecutive_errors failures. pievo loop start clears blocked and resumes. To stop everything now: pause (future runs), then interrupt (the current one).

Dashboard

pievo daemon start serves the dashboard on loopback (127.0.0.1) by default — local access needs no token. To reach it from other machines, bind a host and set a token:

PIEVO_DASHBOARD_TOKEN=<secret> pievo daemon start --host 0.0.0.0 --port 7842

The token is env-only by design (flags leak into ps), and clients on a verified Tailscale tunnel get tokenless access. PIEVO_HOME (default ~/.pievo) selects the state root; one daemon owns one home.

Durability, briefly

PIEVO_HOME/ledger.jsonl is an append-only event log and the single source of truth — state.json, loops/*.yaml, and runs/<run_id>/result.json are rebuildable copies, and runs/<run_id>/logs.jsonl streams while the run executes. Core best-effort records workflow_started for invoked workflows and workflow_finished after normal terminal commit, including terminal state, concise message or diagnostic, and observed usage, even when the workflow emits no custom logs. Finalization failure is logged separately and never masquerades as a committed terminal outcome. Events are validated and fsynced before a command is acknowledged; torn tails are truncated, real corruption fails loudly rather than being "repaired". A new daemon epoch never adopts unfinished work: recovery kills confirmed-stale workers, writes their terminal events, and refuses to schedule anything if it cannot prove a worker is gone.

Upgrades are boring on purpose: pievo daemon stop, update the package, pievo daemon start, then compare pievo --version with pievo daemon status.

The full specification — terminology, event schemas, invariants — lives in CONTEXT.md.

Let your agent drive

The package ships an agent skill at skills/pievo/SKILL.md that teaches a coding agent to operate pievo through the JSON CLI — creating loops, polling runs, diagnosing blocked or over-quota loops. Load it with pi --skill <path-to>/skills/pievo, or copy it into your harness's skills directory (Claude Code: .claude/skills/pievo/).

License

MIT