omp packages

pi-idle-bark0.3.0

Presence-aware Bark notifications for the Pi coding agent — only pushes to your iPhone if a session has been waiting for you beyond a threshold.

hankangshuai Published 7 days ago MIT ~491 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-idle-bark

Presence-aware Bark notifications for the Pi coding agent.

Most Bark extensions push on every agent turn — so while you are sitting at the terminal, your phone buzzes for every single reply. pi-idle-bark is built on the opposite premise:

Only reach the phone when the session has actually been waiting for you.

  • ⏳ Fires only after the agent has settled (or a blocking prompt opened) with no input for thresholdMinutes (default 5). Normal back-and-forth at the desk = complete silence.
  • 🔁 Still away? Re-pings with exponential backoff (default 5m → ×2 → capped at 1h, unlimited repeats), fully configurable.
  • ✨ Optional smart mode: an in-process Pi sub-session (your default model, or a configured provider/modelId) reads the last few assistant messages and writes a short, humanized push — in your conversation's language. One model call per waiting period; repeats reuse the cached text. Any failure falls back to the plain template.
  • ✋ Any new input — typing, Escape, starting a run — cancels the pending alert instantly.
  • 🚫 Aborted runs never notify (you just pressed a key, you're obviously there).
  • 🧩 Works with the official api.day.app Bark server or any self-hosted bark-server.
  • ⚡ Zero dependencies, zero build step (plain TypeScript loaded by Pi's jiti).

Install

pi install npm:pi-idle-bark

Configure

Create ~/.pi/agent/idle-bark.json:

{
  "enabled": true,
  "endpoint": "https://api.day.app",
  "deviceKey": "YOUR_BARK_DEVICE_KEY",
  "thresholdMinutes": 5,
  "repeat": { "strategy": "exponential", "baseMinutes": 5, "factor": 2, "capMinutes": 60, "maxRepeats": 5 },
  "smart": { "enabled": false },
  "params": { "group": "pi", "sound": "bellina", "level": "timeSensitive" }
}
  • endpoint — Bark server base URL. Self-hosted? Use e.g. https://bark.example.com.
  • deviceKey — the key shown in the Bark iOS app. Required; without it the extension stays dormant.
  • params — arbitrary extra Bark payload fields (group/sound/level/icon/…), merged into every push.

Repeat strategy

"repeat": {
  "strategy": "exponential",  // or "fixed"
  "baseMinutes": 5,            // first gap; "fixed" uses it for every gap
  "factor": 2,                // exponential only: gap ×factor each time
  "capMinutes": 60,            // exponential only: gap ceiling
  "maxRepeats": 5             // total repeats; 0 = unlimited
}
  • exponential (default): gaps grow 5m → 10m → 20m → … capped at capMinutes.
  • fixed: constant baseMinutes gaps.
  • Legacy top-level repeatMinutes / maxRepeats (30m × 3) still work when no repeat object is present.

Smart notifications

"smart": {
  "enabled": true,
  "model": "provider/modelId",      // omit → Pi default model
  "titleMode": "model",             // "model": LLM writes the title; "fixed": title stays ⏳ Pi is waiting
  "contextMessages": 2,             // recent assistant messages fed to the model
  "contextChars": 800,              // per-message truncation
  "includeMeta": true,              // cwd / wait time / pending-question hints
  "language": "auto",              // or an ISO code like "zh" / "en"
  "thinkingLevel": "low",
  "timeoutMs": 30000,
  "repeatMode": "cached",
  "prompt": null
}
  • repeatMode — what repeats send: cached (default) reuses the first crafted text, regenerate re-runs the model per repeat (it knows the reminder index and total, so it can escalate Duolingo-style: "只说一次" → "好吧再通知你一次" → dramatic final ultimatum), template falls back to the plain template for repeats.
  • prompt — full custom instruction block replacing the built-in one (context/messages are still appended automatically).

The sub-session runs toolless and in-memory in the same process; template fallback on timeout or parse failure. Note the last few replies are sent to the model provider you configure — keep that in mind for sensitive repos.

Environment overrides (win over the file): PI_IDLE_BARK_ENABLED, PI_IDLE_BARK_ENDPOINT, PI_IDLE_BARK_KEY, PI_IDLE_BARK_MINUTES, PI_IDLE_BARK_SMART, PI_IDLE_BARK_SMART_MODEL, PI_IDLE_BARK_REPEAT_STRATEGY, PI_IDLE_BARK_REPEAT_BASE_MINUTES, PI_IDLE_BARK_REPEAT_FACTOR, PI_IDLE_BARK_REPEAT_CAP_MINUTES, PI_IDLE_BARK_REPEAT_MAX_REPEATS (setting any of these activates the repeat block), plus legacy PI_IDLE_BARK_REPEAT_MINUTES / PI_IDLE_BARK_MAX_REPEATS. PI_IDLE_BARK_DEBUG=1 logs smart-craft and repeat diagnostics to ~/idle-bark-debug.log.

Environment overrides (win over the file): PI_IDLE_BARK_ENABLED, PI_IDLE_BARK_ENDPOINT, PI_IDLE_BARK_KEY, PI_IDLE_BARK_MINUTES, PI_IDLE_BARK_REPEAT_MINUTES, PI_IDLE_BARK_MAX_REPEATS.

How it works

Pi event Effect
agent_settled (not aborted) arm the idle timer
ui_prompt_start (blocking prompts, incl. ask-user dialogs) arm the idle timer
message_end (assistant) remember last reply text for the snippet
input / agent_start / ui_prompt_end cancel any pending alert
agent_settled (aborted) ignored — the user is at the keyboard

Push body (template mode): No input for 12m: <last assistant reply snippet>. In smart mode the sub-session writes title + body instead.

Why not push immediately?

Two great packages already do that — @henryqw/pi-bark and @herbertgao/pi-bark. Use those if you want a push per turn. pi-idle-bark exists for the walk-away-from-the-desk workflow: long-running agent tasks (multi-hour refactors, eval sweeps, big test suites) where an immediate push is pointless — you aren't near the phone either — and per-turn pushes are pure spam.

License

MIT