omp packages

@qcts33/pi-ios-notify0.4.0

Send iOS push notifications via Bark when pi completes agent turns

qcts33 Published 12 days ago MIT ~158 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-ios-notify ๐Ÿ“ฑ

Send iOS push notifications via Bark when pi completes agent turns. Get notified right on your iPhone when long-running tasks finish, errors occur, or after each individual turn โ€” without watching the terminal.

Notifications are off until you run /ios-notify on in the session you want to hear from. Every other session โ€” including the pi child process of a subagent โ€” stays silent. See Activation.

Package: @qcts33/pi-ios-notify Repository: forgejo.horse-carat.ts.net/qcts33/pi-extensions (tailnet-only), package packages/pi-ios-notify

How it works

pi (your Mac)
  โ”‚
  โ”‚ agent completes a turn โ†’ extension fires
  โ”‚
  โ–ผ
pi-ios-notify extension
  โ”‚
  โ”‚ POST https://api.day.app/YOUR_KEY
  โ”‚ { title: "โœ… pi Complete", body: "โ€ฆ" }
  โ”‚
  โ–ผ
Bark server โ†’ Apple Push Notification service โ†’ Your iPhone ๐Ÿ“ฑ

Prerequisites

  1. Bark iOS app โ€” Free on the App Store
  2. A computer running pi (macOS, Linux, or Windows)
  3. Pi 1.x (floor 1.0.0, tested on 1.2.0) โ€” the extension uses native fetch and ExtensionAPI. Below the floor a session shows one warning at session start; the rest of the extension still runs.

Installation

via npm

pi install npm:@qcts33/pi-ios-notify

from a local checkout

pi install /path/to/pi-extensions/packages/pi-ios-notify

Quick test (no install)

pi -e /path/to/pi-extensions/packages/pi-ios-notify

The upstream package @aslamplr/pi-ios-notify still exists on npm. Installing it gets upstream's 0.1.1, without the changes listed under Fork provenance.

Setup

1. Get your Bark device key

  1. Install Bark on your iPhone
  2. Open the app โ€” you'll see your device key URL, like:
    https://api.day.app/YOUR_DEVICE_KEY_HERE
    
  3. Copy the YOUR_DEVICE_KEY_HERE part (the UUID string)

2. Configure the extension

Inside pi, run:

/ios-notify setup

Paste your Bark device key when prompted.

3. Test it

/ios-notify test

You should receive a "๐Ÿ”” Test" notification on your iPhone within a second or two.

Activation

Notifications are off by default and every session starts off. Only a session you activate sends:

/ios-notify on

The state lives in the running pi process and is never written to disk, so each of these starts you inactive again: /reload, --resume, /new, a fork, a session switch, a restart. Run /ios-notify on again after any of them. While the session is active the footer shows ๐Ÿ“ฑ, and /ios-notify off clears it.

/ios-notify test ignores the gate: it sends whenever you ask it to.

The events toggles below choose which events an active session may send. They never make an inactive session send.

Commands

Command Description
/ios-notify on Activate notifications for the current session
/ios-notify off Deactivate notifications for the current session
/ios-notify setup Enter your Bark device key
/ios-notify test Send a test notification
/ios-notify status Show current configuration
/ios-notify events <type> <true|false> Enable/disable notification types (agent-end, agent-settled, prompt-tools, turn-end, error)
/ios-notify prompt-tools list List configured prompt tool names and labels
/ios-notify prompt-tools add <name> [label] Add a tool name to watch with optional label
/ios-notify prompt-tools remove <name> Remove a tool from the watch list
/ios-notify prompt-tools clear Remove all prompt tools
/ios-notify sound <name> Set notification sound
`/ios-notify icon <url pi
/ios-notify url <value> Set optional URL to open when notification is tapped (URL scheme, e.g. ssh://user@host)
/ios-notify debug <on|off> Enable/disable debug logging
/ios-notify hostname <true|false> Append hostname to notifications
/ios-notify body-content <prompt|output> Set whether the Complete notification shows the agent's last output or your prompt

Notification events

An active session sends the events switched on here. These toggles do not make an inactive session send; see Activation.

Event Default Description
agent-end โœ… on Notify when agent finishes a response
agent-settled โŒ off Notify only when the agent is truly idle (no auto retry/compaction/continuation). More accurate than agent-end; recommended with agent-end disabled
prompt-tools โœ… on Notify mid-turn when a configured tool calls for user input
turn-end โŒ off Notify after each individual LLM turn (can be noisy!)
error โœ… on Notify when a tool execution fails

Note: Enabling both agent-end and agent-settled sends duplicate completion notifications โ€” one per agent_end run plus one when the agent fully settles. For a single, accurate completion signal, use agent-end=false + agent-settled=true.

Toggle with:

/ios-notify events agent-end false
/ios-notify events agent-settled true
/ios-notify events prompt-tools false
/ios-notify events turn-end true
/ios-notify events error false

Notification body content

The "โœ… Complete" notification body can show either the agent's last output or your original prompt:

  • output (default) โ€” the agent's final natural-language reply, truncated to 120 characters. The notification itself tells you what the agent concluded.
  • prompt โ€” the prompt you typed, with the turn count (legacy behavior).

If the agent's final turn produced no text (e.g. it ended on pure tool calls or thinking blocks), output mode falls back to showing your prompt so the notification body is never empty. Thinking content is never captured.

Toggle with:

/ios-notify body-content output
/ios-notify body-content prompt

Check the current value with /ios-notify status.

Prompt tools

Prompt tools are tools registered by extensions that may ask for user input mid-turn (e.g. ask_user from pi-ask-user, safe_shell_approve from pi-safe-shell). When the LLM calls one of these tools, you get notified immediately.

Configure which tools to watch:

/ios-notify prompt-tools list
/ios-notify prompt-tools add my_custom_tool "My Label"
/ios-notify prompt-tools remove ask_user

The label is shown as the notification title suffix. Default configured tools:

Tool Label Source
ask_user Asking pi-ask-user extension
ask-user Asking pi-ask-user extension
safe_shell_approve Permission pi-safe-shell extension

Cross-extension notifications

Any extension can send a push notification by emitting an event on pi's shared event bus:

pi.events.emit("pi-ios-notify:notify", {
  title: "๐Ÿ”’ Approval needed",
  body: "bash: rm -rf node_modules",
  source: "safe-shell", // optional
});

pi-ios-notify listens for pi-ios-notify:notify and forwards the title and body to Bark. The emitter controls the notification content entirely. Requires an active session (see Activation) and the prompt-tools event toggle to be enabled.

See the companion extension @aslamplr/pi-safe-shell for a usage example โ€” it emits pi-ios-notify:notify before blocking on user approval prompts.

Custom icon

/ios-notify icon https://example.com/my-icon.png

Use default to reset to Bark's default icon, or pi to use the pi logo:

/ios-notify icon pi
/ios-notify icon default

Notification URL

Set a URL that opens when the notification is tapped. Supports any URL scheme:

/ios-notify url ssh://user@myserver          # opens Termius/Blink (SSH)
/ios-notify url https://my-dashboard.com      # opens Safari
/ios-notify url pi://settings                 # custom scheme
/ios-notify url ""                            # clear (no-op on tap)

Debug mode

Enable debug logging to see why notifications are or aren't firing:

/ios-notify debug on

Debug output appears as informative notifications in pi's UI, each prefixed with ๐Ÿ”. Each event handler logs its name, the session gate, config state and throttle flags:

๐Ÿ” tool_call active=true name=ask_user inPromptTools=true promptTools=true throttled=false
๐Ÿ” agent_end active=true agentEnd=true

When nothing reaches the phone, the logged active= says whether the activation gate or the event's own toggle stopped it.

Turn off with:

/ios-notify debug off

Notification sounds

Bark supports various iOS notification sounds. Change with:

/ios-notify sound birdsong

Common sounds: default, minuet, alarm, anticipate, birdsong, bloom, calypso, chime, descant, electronic, fanfare, horn, ladder, mazurka, nightingale, piano, rocket, sirius, strums, suspense, telegraph, tiptoes, tritone, tuberose, twinkle.

Configuration file

The extension stores its config at ~/.pi/ios-notify.json. You can edit it directly:

{
  "barkKey": "YOUR_DEVICE_KEY",
  "barkServer": "https://api.day.app",
  "events": {
    "agentEnd": true,
    "agentSettled": false,
    "promptTools": true,
    "turnEnd": false,
    "error": true
  },
  "promptTools": {
    "ask_user": "Asking",
    "ask-user": "Asking",
    "safe_shell_approve": "Permission"
  },
  "sound": "default",
  "title": "pi",
  "bodyContent": "output",
  "icon": "",
  "showHostname": false,
  "url": "",
  "debug": false
}

Add more tools directly in the config:

{
  "promptTools": {
    "ask_user": "Asking",
    "safe_shell_approve": "Permission",
    "my_custom_tool": "Waiting"
  }
}

Custom Bark server

If you self-host Bark, set the server:

{
  "barkServer": "https://bark.yourdomain.com",
  "barkKey": "YOUR_KEY"
}

What notifications look like

Event Notification
Agent completes response โœ… pi Complete โ€” "refactor the auth module to use JWT" (3 turns)
Prompt tool called mid-turn ๐Ÿ’ฌ pi Asking โ€” ask_user
Prompt tool called mid-turn ๐Ÿ’ฌ pi Permission โ€” safe_shell_approve
Cross-extension event emit ๐Ÿ’ฌ pi {emitter's title} โ€” {emitter's body}
Each turn ๐Ÿ”„ pi Turn โ€” Turn 3 finished
Tool error โš ๏ธ pi Error โ€” Error in bash: command not found: foobar (includes error detail)

Privacy

  • Only the Bark device key and notification content are sent to the Bark server
  • The notification body โ€” your prompt, or the agent's last text truncated to 120 characters โ€” is the only conversation content that leaves the machine
  • Bark stores notification content encrypted on their server
  • You can optionally set up end-to-end encryption in the Bark app

Project structure

pi-ios-notify/
โ”œโ”€โ”€ index.ts        # Extension entry point (no compilation needed)
โ”œโ”€โ”€ utils.ts        # Pure utility functions
โ”œโ”€โ”€ test/           # Vitest suite for the pure utilities
โ”œโ”€โ”€ defaults.json   # Default icons/images
โ”œโ”€โ”€ package.json    # Package manifest with pi.extensions entry
โ””โ”€โ”€ README.md       # This file

Standard npm package layout โ€” the pi.extensions field in package.json tells pi where to find entry points.

Development

This package is a workspace member of the pi-extensions monorepo. Everything runs from the repo root through npm workspaces:

npm install          # once, at the repo root
npm test             # vitest for this package, node --test for the others
npm run verify       # lint + typecheck + tests + pack check

Load for testing:

pi -e /path/to/pi-extensions/packages/pi-ios-notify

Reload changes:

/reload

Tests

npm test

Runs vitest on the extracted utility functions (test/utils.test.ts):

  • formatPrompt โ€” truncation, edge cases
  • pluralize โ€” singular, plural, auto-pluralize
  • onOff โ€” boolean to on/off
  • parseBool โ€” all truthy/falsy strings, edge cases

โš–๏ธ No Warranty

THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. The authors make no representations that this extension will deliver notifications reliably or in a timely manner. You are responsible for testing notification delivery and configuring appropriate settings.


License

MIT โ€” see LICENSE, which carries upstream's copyright notice as well as this fork's.

Fork provenance

This package is qcts33's fork of aslamplr/pi-ios-notify, taken from upstream 0.1.1 and published under the @qcts33 scope. On top of upstream's 0.1.1 it adds:

  • an agent-settled event, driven by pi's agent_settled event, as a more accurate completion signal than agent-end
  • a body-content setting that puts the agent's last output in the notification body instead of your prompt
  • a 5-second fetch timeout and fire-and-forget delivery, so a slow Bark server cannot stall the agent loop
  • notifications only in a session the user activated with /ios-notify on; every other session, including the child pi process of a subagent, starts silent

Upstream is kept as a read-only remote: upstream fixes are cherry-picked into this fork, and this fork's changes are not upstreamed automatically.

Credits