@zerodawn/pi-ping
v0.1.3
Published
Multi-instance PI status + notifications via tmux statusline, window colour, and dunst
Maintainers
Readme
pi-ping
PI extension for multi-instance status + desktop notifications.
Each running PI session writes its state (RUNNING / READY / WAITING_GUARD /
IDLE) to ~/.cache/pi-core/pi-ping/instances/<session_id>.json. A tiny CLI
reads those files for:
- tmux statusline — append an
AGENTSblock viapi-ping render --inline - tmux window colour — per-window highlight via
pi-ping window-style - desktop notifications — gated
notify-sendonagent_end, cooldown + dunst dismissal detection
Install
npm install -g @zerodawn/pi-ping # CLI on PATH
pi install @zerodawn/pi-ping # register as extensionActivate tmux integration by sourcing the snippet from your tmux config, before any plugin loads (continuum, etc):
# Ensure ~/.local/bin (npm install -g target) is on tmux's PATH
set-environment -g PATH "$HOME/.local/bin:/usr/local/bin:/usr/bin"
source-file ~/.local/lib/node_modules/@zerodawn/pi-ping/tmux/pi-ping.tmuxThe snippet:
- Appends a per-state, per-agent badge list to
status-right - Adapts: above 150 cols you get full pane-title labels, below it collapses
to per-state counters (
● 2 ✓ 4) - Uses
client_widthternary so it switches live as you resize - Bumps
status-right-lengthto 200 if you had it shorter
For monorepo dev, hardcode the absolute path in your own copy of the
snippet — tmux does not expand #{user-options} inside #(), so we can’t
parameterise the binary path via a tmux option.
CLI
pi-ping notify <tag> <state> gated desktop notification
pi-ping render [--no-colour] multi-line AGENTS block
[--no-header]
[--inline] one-line variant for status-right
[--counter] per-state counters (`● 2 ✓ 4`)
pi-ping window-style <selector> tmux style fragment
selector: <session>:<window> | %<pane-id>
pi-ping helpState ∈ RUNNING | READY | WAITING_GUARD | IDLE. Inline/counter modes hide
IDLE entries to keep the bar quiet.
Data exposure
pi-ping is data-first — build your own bar on top of it:
# All instance state, JSON one-per-file:
ls ~/.cache/pi-core/pi-ping/instances/*.json
# Quick counters via jq:
jq -r .state ~/.cache/pi-core/pi-ping/instances/*.json | sort | uniq -cThe CLI is just a convenience layer over those files — nothing stops you from rolling your own format string off the same data.
Label resolution: when an instance is tied to a tmux pane, the pane title
is used and stripped of the common π - <NAME> - <project> pi-shell
decoration. Falls back to the cwd-derived tag. Stale instance files
(pane crashed, pane recycled) are GC’d automatically on each render.
Config (via pi-core)
{
"pi-ping": {
"tag": "myproject",
"cooldownMinutes": 5,
"daemon": "dunst",
"notifications": true,
"colours": {
"RUNNING": "orange",
"READY": "green",
"WAITING_GUARD": "red",
"IDLE": "green"
}
}
}Defaults to basename(cwd) as tag, 5-minute cooldown, dunst daemon.
Layout
src/
index.ts entry point, delegates to modules/lifecycle
types.ts PingState, InstanceFile, NotifEntry
config.ts defaults + mergeConfig
paths.ts cacheDir("pi-ping") resolver via pi-core
modules/lifecycle.ts PI lifecycle hooks → ops + fire-and-forget notify
ops/ pure: fs, shell, pi-core only (no PI API)
instance-file.ts read/write/patch/delete InstanceFile
notifs.ts notifs.json cooldown bookkeeping
dunst.ts probeDunst() + parseHistoryIds()
notify-send.ts sendNotification() (captures --print-id)
gating.ts decideGate() — pure decision logic
tmux.ts detectTmux() via TMUX_PANE env
render.ts listInstances() + formatAgents() (multi/inline)
window-style.ts matchInstances() + pickDominant() + windowStyleFor()
cli-path.ts resolve absolute path to bin/pi-ping
cli/ subcommand dispatch
index.ts argv router
notify.ts runNotify()
render.ts runRender()
window-style.ts runWindowStyle()
bin/
pi-ping shell wrapper → jiti cli/index.ts
tmux/
pi-ping.tmux source-file snippet for ~/.tmux.conf
smoke.ts ~80 asserts incl. CLI shelloutsExternal integrations
@zerodawn/pi-coreconfig + cacheDir@earendil-works/pi-coding-agent(peerDep) — PI lifecycle APInotify-send+dunstctldesktop notifications (shelled)tmux display-messagepane → session/window resolution
Architecture rules followed
.pi/docs/zerodawn/architecture/shared-lib-pattern.md(cacheDir + config via pi-core).pi/docs/zerodawn/architecture/pure-ops-layer.md(ops/ has no PI imports).pi/docs/zerodawn/architecture/smoke-test.md(singlesmoke.ts).pi/docs/zerodawn/architecture/npm-scope.md(@zerodawn/*scope)
Deep context
.pi/docs/pi-ping/plans/mvp.md— full design, gating logic, build order
