monitor-inbox
Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
The rest of pushover-commander only sends; its audit log (po-audit.jsonl)
can never show what arrived. This skill wraps the Pushover Open Client API
(the REST surface the desktop/mobile apps use to receive) so a session can read
incoming notifications. Core: _lib/pushover_inbox.ts.
Model = on-demand pull (run pull when asked; no background daemon).
Commands
CORE="$(cc-plugin-root pushover-commander)/skills/_lib/pushover_inbox.ts"
# One-time, INTERACTIVE — mints a receive-device. Prompts for the Pushover ACCOUNT
# email + password (password is MASKED, used once in-memory, NEVER stored). Only the
# derived client secret + device_id are persisted, to the SCS vault scope `pushover`.
env -u HTTPS_PROXY -u HTTP_PROXY bun "$CORE" register [--name claude-mac] [--force]
# On demand — fetch new messages → append to po-inbox.jsonl → ack (update_highest).
env -u HTTPS_PROXY -u HTTP_PROXY bun "$CORE" pull [--json] [--limit N]
# Read back the local inbox (NO network).
bun "$CORE" list [--limit N] [--json]
# Health: creds present? device registered? API reachable / how many waiting?
env -u HTTPS_PROXY -u HTTP_PROXY bun "$CORE" doctor
One-time setup (operator must run register)
Only the operator can type the account password, so guide them to run register
themselves (or run it and let them type into the masked prompt). After that,
pull/list/doctor all work headlessly — no password, no Touch ID — because the
client secret + device_id live in the vault automation tier (agent-readable).
Secret handling (SCS doctrine — cc-skills/docs/self-custody-secrets.md)
| Secret | Class | Where it lives |
|---|---|---|
| Account email + password | crown jewel | masked prompt, in-memory only — never stored / never sent / never in argv or transcript |
client secret + device_id | automation token | SCS vault scope pushover (agent-readable, so headless pull needs no prompt) |
Never Pushover, email, commit, or otherwise transmit any of these off-machine.
Caveats (verified 2026-07-05)
- No history back-fill. A freshly-registered Open-Client device only receives messages sent after registration. It will NOT pull the alerts already sitting in the native Pushover.app. Register first, then future alerts arrive.
- IMAP-style queue.
messages.jsonreturns the pending queue;pullcallsupdate_highestto ack, else the same messages re-download every time. - Desktop/Open-Client license. Registering a receive-device may require a
Pushover Desktop license on the account. If so,
/1/devices.jsonerrors — the message is surfaced verbatim byregister. - 2FA. If the account has two-factor enabled,
registerre-prompts for the code and retries login. - Proxies. Always
env -u HTTPS_PROXY -u HTTP_PROXYfor the network commands, so Pushover HTTPS bypasses the sandbox MITM proxy (otherwise 502).
Files
- Core:
_lib/pushover_inbox.ts - Inbox log:
~/.local/state/pushover/po-inbox.jsonl(UUID-keyed, sits beside the send-sidepo-audit.jsonl); override withPUSHOVER_INBOX_PATH. - Creds: SCS vault scope
pushover→client.secret,client.device_id,client.device_name.
Post-Execution Reflection
After this skill completes, check before closing:
- Did
pullactually ack? If the same messages reappear on the nextpull,update_highestisn't landing — fix the ack path, not the reader. - Did the operator expect an alert that didn't arrive? Confirm it was sent
after
register(no back-fill) before assuming a bug. - Any credential leak surface? The account password must never appear in a log, argv, the inbox JSONL, or a transcript. If it did, that's a real defect — fix now.
Only update if the issue is real and reproducible — not speculative.