pushary 1.9.87 → 1.9.88

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/data/SKILL.md +35 -24
  3. package/data/cowork/SKILL.md +4 -4
  4. package/data/cursor-plugin/.cursor-plugin/plugin.json +1 -1
  5. package/data/cursor-plugin/CHANGELOG.md +8 -0
  6. package/data/cursor-plugin/skills/pushary/SKILL.md +34 -23
  7. package/data/vscode-plugin/.claude-plugin/plugin.json +1 -1
  8. package/data/vscode-plugin/CHANGELOG.md +8 -0
  9. package/data/vscode-plugin/skills/pushary/SKILL.md +34 -23
  10. package/dist/{api-ZDMC22LN.js → api-BE4B7HBE.js} +7 -7
  11. package/dist/bin/pushary-bell-hook.js +18 -18
  12. package/dist/bin/pushary-bell.js +5 -5
  13. package/dist/bin/pushary-claude.js +19 -19
  14. package/dist/bin/pushary-clean.js +26 -26
  15. package/dist/bin/pushary-codex-bridge.js +14 -14
  16. package/dist/bin/pushary-codex-hook.js +21 -21
  17. package/dist/bin/pushary-codex-session.js +6 -6
  18. package/dist/bin/pushary-codex.js +8 -8
  19. package/dist/bin/pushary-connect.js +19 -19
  20. package/dist/bin/pushary-daemon.js +30 -30
  21. package/dist/bin/pushary-disconnect.js +18 -18
  22. package/dist/bin/pushary-display-hook.js +10 -10
  23. package/dist/bin/pushary-doctor.js +32 -32
  24. package/dist/bin/pushary-elicitation-hook.js +18 -18
  25. package/dist/bin/pushary-gemini-bridge.js +9 -9
  26. package/dist/bin/pushary-gemini-hook.js +19 -19
  27. package/dist/bin/pushary-hook.js +20 -20
  28. package/dist/bin/pushary-login.js +13 -13
  29. package/dist/bin/pushary-logout.js +16 -16
  30. package/dist/bin/pushary-mcp.js +8 -8
  31. package/dist/bin/pushary-mode.js +9 -9
  32. package/dist/bin/pushary-notification-hook.js +17 -17
  33. package/dist/bin/pushary-opencode-hook.js +18 -18
  34. package/dist/bin/pushary-permission-denied-hook.js +20 -20
  35. package/dist/bin/pushary-permission-hook.js +20 -20
  36. package/dist/bin/pushary-post-hook.js +17 -17
  37. package/dist/bin/pushary-prompt-hook.js +17 -17
  38. package/dist/bin/pushary-session-end-hook.js +19 -19
  39. package/dist/bin/pushary-session-start-hook.js +27 -27
  40. package/dist/bin/pushary-setup.js +38 -38
  41. package/dist/bin/pushary-status.js +23 -23
  42. package/dist/bin/pushary-stop-hook.js +17 -17
  43. package/dist/bin/pushary-stopfailure-hook.js +17 -17
  44. package/dist/bin/pushary-suggestions.js +9 -9
  45. package/dist/bin/pushary-transcript-register.js +11 -11
  46. package/dist/bin/pushary-transcripts.js +18 -18
  47. package/dist/bin/pushary-upgrade.js +32 -32
  48. package/dist/bin/pushary-wait.js +9 -9
  49. package/dist/bin/pushary.js +4 -4
  50. package/dist/{chunk-TQ43EX2E.js → chunk-2HTE4ECJ.js} +1 -1
  51. package/dist/{chunk-R5SANCZC.js → chunk-2NJNC26C.js} +4 -4
  52. package/dist/{chunk-SLMCMHVY.js → chunk-3BG5S7MB.js} +2 -2
  53. package/dist/{chunk-RHDHLXUK.js → chunk-3C4UGMIV.js} +3 -3
  54. package/dist/{chunk-7AH6F44G.js → chunk-3XJL2M7H.js} +3 -3
  55. package/dist/{chunk-6OVWYAET.js → chunk-3ZE7VQOU.js} +3 -3
  56. package/dist/{chunk-UAB3K3TA.js → chunk-4C7OJLSL.js} +3 -3
  57. package/dist/{chunk-VADZ6C26.js → chunk-4TT2ZFWZ.js} +1 -1
  58. package/dist/{chunk-CT2HRZLL.js → chunk-4Z7MR5FE.js} +2 -2
  59. package/dist/{chunk-42KJLBX2.js → chunk-6GDZ4RYR.js} +5 -5
  60. package/dist/{chunk-YRQWA4ZS.js → chunk-6RFDH4JU.js} +1 -1
  61. package/dist/{chunk-XGW7J7KT.js → chunk-A2F7T3IR.js} +1 -1
  62. package/dist/{chunk-3ZWJBPQ5.js → chunk-B4NVYPX5.js} +1 -1
  63. package/dist/{chunk-7SY2F6JA.js → chunk-BC2HT6JP.js} +2 -2
  64. package/dist/{chunk-FQ2EBMDA.js → chunk-BOWXZWHG.js} +6 -6
  65. package/dist/{chunk-K34J2V5G.js → chunk-BSTZ66FA.js} +2 -2
  66. package/dist/{chunk-XPE745FL.js → chunk-CAXE3TYX.js} +5 -5
  67. package/dist/{chunk-4RZXECJS.js → chunk-DHVVEH2K.js} +5 -5
  68. package/dist/{chunk-K4I2LESS.js → chunk-DM5LNEGJ.js} +2 -2
  69. package/dist/{chunk-X5INK4OE.js → chunk-FFIDXKQ7.js} +8 -8
  70. package/dist/{chunk-B34K6NXW.js → chunk-FK2EK27I.js} +2 -2
  71. package/dist/{chunk-QN2EFKXV.js → chunk-FRUKY6KV.js} +2 -2
  72. package/dist/{chunk-FE3I7SCA.js → chunk-FUVVGIXZ.js} +4 -4
  73. package/dist/{chunk-M66W7UD7.js → chunk-GJXRYXMC.js} +2 -2
  74. package/dist/{chunk-VU5PKE2N.js → chunk-I6MNMAS7.js} +1 -1
  75. package/dist/{chunk-GVMOTYFU.js → chunk-IXOCJHJW.js} +2 -2
  76. package/dist/{chunk-IOJZPPDB.js → chunk-JOULYVW6.js} +1 -1
  77. package/dist/{chunk-JILOKJ3W.js → chunk-JQMOQLM2.js} +7 -7
  78. package/dist/{chunk-D766FEAS.js → chunk-JQPY2B2H.js} +1 -1
  79. package/dist/{chunk-IXUJCONI.js → chunk-LAYKEYZE.js} +1 -1
  80. package/dist/{chunk-VNYSGRCL.js → chunk-LH3SNS6H.js} +9 -9
  81. package/dist/{chunk-GAYYYXMU.js → chunk-LHXJYSNX.js} +1 -1
  82. package/dist/{chunk-7LRY76MV.js → chunk-LXFBSMAE.js} +4 -4
  83. package/dist/{chunk-NW3GZBQA.js → chunk-M4UXDYNJ.js} +4 -4
  84. package/dist/{chunk-S33CCO4J.js → chunk-MQKXQWXA.js} +1 -1
  85. package/dist/{chunk-UOM5SUWJ.js → chunk-N7OMDSXK.js} +1 -1
  86. package/dist/{chunk-YLWPJ2MP.js → chunk-NOGDU4XS.js} +2 -2
  87. package/dist/{chunk-GVZAEST7.js → chunk-NWLGRSGE.js} +3 -3
  88. package/dist/{chunk-4VHT5SWU.js → chunk-O53SJBBB.js} +3 -3
  89. package/dist/{chunk-NFKB7ZHA.js → chunk-OBS7O22Q.js} +2 -2
  90. package/dist/{chunk-7TZDVGMC.js → chunk-OMLR56J5.js} +1 -1
  91. package/dist/{chunk-XMRCP7TM.js → chunk-PG5WFIHE.js} +1 -1
  92. package/dist/{chunk-E5DZ74QT.js → chunk-PYI2EFRH.js} +4 -4
  93. package/dist/{chunk-5YDIHB67.js → chunk-QOMIFKQL.js} +3 -3
  94. package/dist/{chunk-UDYWZ4DI.js → chunk-QQCGYHYG.js} +1 -1
  95. package/dist/{chunk-LXTTFH4P.js → chunk-RX5FSSQK.js} +5 -5
  96. package/dist/{chunk-MY6CX7WE.js → chunk-TBPMI4LY.js} +4 -4
  97. package/dist/{chunk-ZLO3K5TP.js → chunk-VIDB26GQ.js} +4 -4
  98. package/dist/{chunk-VNROKR2K.js → chunk-WBZA72O5.js} +2 -2
  99. package/dist/{chunk-RKN7BJRQ.js → chunk-YN4IXOFK.js} +1 -1
  100. package/dist/{chunk-NFQCFVKJ.js → chunk-Z2LYELNQ.js} +5 -5
  101. package/dist/{chunk-2CJNGJQS.js → chunk-ZEPS4KIK.js} +2 -2
  102. package/dist/{chunk-GPP7AUCM.js → chunk-ZP5AB6R5.js} +3 -3
  103. package/dist/{chunk-WJ2APMU5.js → chunk-ZXDHPPGI.js} +3 -3
  104. package/dist/{codex-app-cards-switch-ARYZG5DV.js → codex-app-cards-switch-XLSLVXDP.js} +7 -7
  105. package/dist/{codex-desktop-launch-6P2IXUIZ.js → codex-desktop-launch-HRE6YP56.js} +1 -1
  106. package/dist/{codex-session-launch-WUZSHGSI.js → codex-session-launch-7RGYGW32.js} +12 -12
  107. package/dist/{global-upgrade-QGHGUP5V.js → global-upgrade-VR76ZRWG.js} +8 -8
  108. package/dist/{identity-WRUYTQ4O.js → identity-NJAXA45Q.js} +3 -3
  109. package/dist/{live-capabilities-AJJILIIZ.js → live-capabilities-5UTM55OC.js} +4 -4
  110. package/dist/{paths-Q5A6GBRA.js → paths-BX4DXC3B.js} +2 -2
  111. package/dist/{reapply-BMNUBJ3Z.js → reapply-PMCMNTED.js} +21 -21
  112. package/dist/src/index.js +20 -20
  113. package/dist/{upgrade-lock-NGCFJRRN.js → upgrade-lock-2G2S3FH7.js} +3 -3
  114. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.88
4
+
5
+ - The bundled Pushary skill is 0.13.1. It says what each `status --json` exit code means, when to follow plain `status` instead and where its printed steps need care, lists every agent id setup accepts, and says that when `status --json` reports `connectedThroughMacApp: true`, agents other than Cline are connected in the Mac app.
6
+ - An agent still asks an approval it cannot continue without after three pushes, wherever you are, instead of waiting in a chat nobody reads.
7
+ - The skill's reminder and notification guidance matches the server: a reminder body over 180 characters fails, and an agent does not say it notified you when nothing was pushed.
8
+ - The bundled Cowork and Hermes skills say a Partner customer can answer on a Mac they connected from their phone. They used to say they could not. Hermes plugin 0.9.2 carries the same fix.
9
+ - The instruction block setup writes no longer says the Mac notch answers only personal questions. `pushary upgrade` refreshes it for Codex, Gemini CLI, OpenCode, fx, Cline, Qwen Code, CodeBuddy and Grok Build. Agents the Mac app connected get it with the next Mac release, and a project CLAUDE.md or AGENTS.md keeps the old line until setup writes it again.
10
+
3
11
  ## 1.9.87
4
12
 
5
13
  - On Node.js older than 22.20, setup installs the Pushary skill with skills.sh CLI 1.5.0. Newer versions of that CLI need Node 22.20, so on older Node every setup failed there, fell back to the bundled copy, and spent several seconds doing it.
package/data/SKILL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: pushary
3
- version: 0.13.0
3
+ version: 0.13.1
4
4
  description: Push notifications and human-in-the-loop for AI agents. Use this whenever a running agent needs a person who may not be at the terminal, such as before an irreversible or destructive action, before spending money, deploying, force-pushing or deleting, when blocked on a decision outside your authority, when running unattended and you hit a genuine ambiguity, when another skill's workflow says to confirm with the user, and when a long task finishes or fails with nobody watching. Also use it when the user says things like keep going and ping me on my phone if you need anything, notify me when my agent needs me, approve from my phone, ask me questions while I am away from the terminal, run this overnight, keep working while I am in a meeting, I am stepping away, or do not wait for me, or wants a long task to run unattended. Ask yes/no, multiple choice or free-text questions on their phone and get the answer back, and send an update when a task finishes or fails. Use these tools proactively, without waiting to be asked. Every question and answer is recorded, so an unattended run stays reviewable afterwards. Works with Claude Code, Codex, Cursor, VS Code, Gemini CLI, Windsurf, Hermes, Lovable, or any MCP client; no Claude Max subscription required. Pushary is a hosted, paid service; web and native store checkout have different price and trial terms.
5
5
  metadata:
6
6
  hermes:
@@ -32,7 +32,7 @@ Nobody has to say "ping me". When one of these moments is true, act now: ask in
32
32
  - **Another skill tells you to confirm with the user.** That instruction assumes someone watches the terminal. Often nobody does. Ask it where the user is, as for every moment here, so the run continues when they answer.
33
33
  - **A long task finished or failed and nobody is watching.** Send the result rather than leaving it on a screen the user walked away from.
34
34
 
35
- When no device is connected, follow the handoff in the result. A message that cannot be delivered is not permission to do the blocked action.
35
+ When no device is connected, follow the handoff in the result and keep doing approved work that does not depend on the answer. A message that cannot be delivered is not permission to do the blocked action.
36
36
 
37
37
  ## Ask Less, Ask Well
38
38
 
@@ -85,8 +85,9 @@ A round holds every decision whose inputs you already know. A decision that depe
85
85
  - **Silence is not agreement.** No answer approves nothing. An irreversible step, spending money or a decision outside your authority still gets its own question unless the user already approved it.
86
86
  - **One `select` with the real options beats three `confirm` questions.**
87
87
  - **Ask at the boundary, not once for each item.** Ask about deleting files, not about each file.
88
- - **Send at most three pushes per task** unless the user asks for more. Questions asked as chat text in the terminal do not count. The cap never waives an approval: past it, ask in the current client and wait.
89
- - **When the requested work is done, report it and stop.** Do not ask what to do next unless the user asked you to.
88
+ - **Write for someone glancing at a phone.** Name the exact thing and the number: "Delete the 3 unused migration files?" beats "Should I clean up?"
89
+ - **Send at most three pushes per task** unless the user asks for more. Questions asked as chat text do not count. The cap never holds back an approval the run cannot continue without: ask it where the user is.
90
+ - **When the requested work is done, report it and stop.** Do not ask what to do next unless the user asked you to. Work blocked on a choice only the user can make is not done: ask that choice.
90
91
 
91
92
  ## Setup
92
93
 
@@ -133,16 +134,24 @@ When Node and npm are available, run `npx pushary@latest status --json`. The exi
133
134
  | --- | --- |
134
135
  | 0 | Ready. If the JSON says `connectedThroughMacApp: true`, the Mac app holds the key: check the account, plan and phone in the Pushary Mac app. |
135
136
  | 1 | The command failed. |
136
- | 2 | A malformed key or an unknown flag. |
137
+ | 2 | A malformed key, an unknown flag, or a Node version that is too old. |
137
138
  | 3 | Not set up on this machine. |
138
139
  | 4 | The key was rejected or signed out. |
139
- | 5 | A problem was found: two keys that disagree, or no active plan. Read the JSON. |
140
- | 6 | Nothing proves a question reaches this user: no phone of theirs is paired, or only a teammate's devices are. Have them install the Pushary app from https://pushary.com/download and sign in to the same account, then run `status --json` again. |
141
- | 8 | Pushary could not be reached. |
140
+ | 5 | Two keys that disagree, or no active plan. |
141
+ | 6 | Nothing proves a question reaches this user: no phone of theirs is paired, or only a teammate's devices are. |
142
+ | 8 | Pushary could not be reached. Check again later; do not run setup. |
142
143
 
143
- For `mac-app` without Node or npm, open the Pushary Mac app. Check the account, the plan and the Agents connection there, and connect or repair agents in the app. Do not install Node to inspect a native setup, and do not claim an exit code when no CLI ran.
144
+ For any code but 0 or 8, run `npx pushary@latest status` without `--json` and follow the steps it prints, with these changes:
144
145
 
145
- To add an agent to a working install, run `npx pushary@latest setup --agents <id>`. It reuses the key and does not pair again. If the Mac app owns this machine's hooks, setup keeps them; point the user at the Pushary app for hook changes.
146
+ - Run a printed `pushary …` command as `npx pushary@latest …`, and a printed setup as in "Running setup yourself". Where it says to get or copy a key, run setup instead. Never ask the user for one.
147
+ - **`mac-app` printed and the code is 3:** have the user sign in to the Pushary Mac app, then check again.
148
+ - **Status says the key was signed out on this Mac:** have the user sign in again to the Pushary Mac app, open Settings > Agents and press Repair on every agent that offers it (if none does yet, have them close Settings, wait a minute and open it again), then run setup as in "Running setup yourself". It reuses the key the app wrote into the agents' settings; if the first one it finds does not work, it pairs instead. If status then shows the old key `from $PUSHARY_API_KEY`, have the user restart this agent from a new terminal.
149
+ - **The Key line says `from $PUSHARY_API_KEY`, the code is 2 or 4, and status does not say signed out on this Mac:** this shell exports a bad key, and it wins over any key setup saves. Run setup at most once. If status still fails or shows `Key drift`, have the user delete every `export PUSHARY_API_KEY` line that still sets the old key from their shell startup files, such as ~/.zshrc, ~/.zprofile, ~/.bashrc and ~/.bash_profile, including any setup said it could not update, then restart this agent from a new terminal.
150
+ - **Code 6, instead of the steps status prints:** have them install the Pushary app from https://pushary.com/download, sign in to the account this machine uses and allow notifications, then check again. A user who does not use a phone always gets 6: say so and stop. If it still says 6, offer to pair the phone: in the Pushary Mac app under Settings > Phone > Pair when `mac-app` printed, otherwise with setup `--connect app` as in "Running setup yourself", which creates a new key.
151
+
152
+ For `mac-app` without Node or npm, or with a Node version the CLI refuses, open the Pushary Mac app. Check the account, the plan and the Agents connection there, and connect or repair agents in the app. Do not install Node to inspect a native setup, and do not claim an exit code when no CLI ran.
153
+
154
+ To add an agent to a working install, run `npx pushary@latest setup --agents <id>`; it reuses the key and does not pair again. When status reported `connectedThroughMacApp: true`, connect the agent in the Pushary Mac app instead, except Cline. Setup keeps hooks the Mac app owns; pass `--take-over-hooks` only when the user wants the command line to own them.
146
155
 
147
156
  ### Branch 2. `Darwin`, no key, no `mac-app`
148
157
 
@@ -166,18 +175,18 @@ In PowerShell, type `npx.cmd` instead of `npx`. Node 20.17+, 22.13+ or 23.5+ is
166
175
 
167
176
  ### Running setup yourself
168
177
 
169
- Before you run it, tell the user what it does: it pairs their phone, then configures MCP, hooks and the skill for the agents you name. It also installs the `pushary` command globally, starts a background service so the phone can start sessions (`--control off` skips it), and turns on session history (`--transcripts off` turns it off). It needs a paid plan; the phone app shows the price and any trial.
178
+ Before you run it, tell the user what it does: it pairs their phone, then configures MCP, hooks and the skill for the agents you name. It may also install the `pushary` command globally and start a background service so the phone can start sessions (`--control off` skips it). It turns on session history (`--transcripts off` turns it off). It needs a paid plan; the phone app shows the price and any trial.
170
179
 
171
- 1. **Name the agents.** Pass `--agents` with your own id: `claude_code`, `codex`, `cursor`, `gemini_cli`, `vscode`, `opencode`, `hermes`, or a comma-separated list. Without it, setup run from an agent's shell configures every agent it detects.
180
+ 1. **Name the agents.** Pass `--agents` with your own id: `claude_code`, `codex`, `gemini_cli`, `cursor`, `vscode`, `opencode`, `hermes`, `cline`, `antigravity_cli`, `qwen_code`, `codebuddy`, `qoder`, `droid`, `devin`, `grok`, `fx` or `custom`, or a comma-separated list. `custom` (Windsurf or any other MCP client) gets a key like any other id but configures no client: it prints the server URL and an `Authorization: Bearer $PUSHARY_API_KEY` header. Add both to that client's MCP settings before you report it connected; if the client cannot read environment variables, use the key saved in ~/.pushary/config.json. Without `--agents`, setup run from an agent's shell configures every agent it detects.
172
181
  2. **Run it in the background.** It waits up to 15 minutes for the phone, longer than most agents let a foreground command run, and a killed setup kills the pairing code with it. Start it as a background process that writes to a log, read the short link, the QR and the fingerprint from that log, show them to the user as they print, and keep checking the log until setup exits. Do not summarise them. The link survives where the QR renders badly. Start while the user can still read your messages: until they approve, nothing is configured and you have no other way to reach them.
173
182
  3. **Walk the user through it.** They open the link or scan the QR. If they do not have the Pushary app, they install it from https://pushary.com/download, then return to the original link and tap Open Pushary; they do the same if the app restarts during sign-in or payment. The app shows a fingerprint that must match the one in your output. On a first install the app asks them to sign in and choose a plan. Then they approve, and setup finishes on its own. If the code expires, run setup again.
174
- 4. **Report the result plainly.** If setup exits without pairing, nothing was configured. Say so.
183
+ 4. **Report the result plainly.** If setup exits without pairing, nothing was configured. Say so. If it exits 6, the agents are configured but nothing proves a phone of theirs can receive yet: follow code 6 above, but if setup just paired, do not pair again.
175
184
 
176
- Never ask the user for an API key, and never send them to a signup page first. If `PUSHARY_API_KEY` is already set or an agent configuration holds a key, setup uses it and skips pairing.
185
+ Never ask the user for an API key, and never send them to a signup page first. If a working key is already set or stored on this machine, setup reuses it and skips pairing. `--connect app` always pairs and creates a new key unless `--key` or `--key-stdin` is passed. If this machine had a key, tell the user it stays active until they revoke it under API keys at https://pushary.com/dashboard/agent/settings.
177
186
 
178
187
  Manual MCP configuration also works, but it needs a key from https://pushary.com/sign-up?utm_source=skill&utm_medium=setup. Prefer setup.
179
188
 
180
- Setup itself sends only a test notification, because it cannot tell whether the user is there to answer. Right after it finishes, while the user still has their phone in hand, test a question and answer: for a CLI setup, run `npx pushary@latest doctor --roundtrip`. A returned answer proves the question path, not hook enforcement. Restart the agent and follow its approval check at https://pushary.com/docs/agents/supported-agents. For a Mac app setup, use the app's connection tests and ask one harmless question from the current agent.
189
+ Setup itself sends only a test notification, because it cannot tell whether the user is there to answer. Right after it finishes, while the user still has their phone in hand, test a question and answer: for a CLI setup, run `npx pushary@latest doctor --roundtrip`. It needs a CLI key, sends a test push and one question, and waits about a minute for the answer. Its exit code also covers unrelated checks, so read the Synthetic answer test line. A returned answer proves the question path, not hook enforcement. Restart the agent and follow its approval check at https://pushary.com/docs/agents/supported-agents. For a Mac app setup, use the app's connection tests and ask one harmless question from the current agent.
181
190
 
182
191
  ## Pricing and Free Alternatives
183
192
 
@@ -191,7 +200,7 @@ Your client already holds each tool's schema, with every parameter and returned
191
200
 
192
201
  ### ask_user
193
202
 
194
- Asks a question and waits. Use `confirm` for yes or no, `select` for 2 to 6 known options, and `input` when the options cannot be listed. A question stays open until it is answered or cancelled, except through a connector, by signing in or with a connector key (Claude.ai, Claude Desktop, Cowork, ChatGPT, Grok Bot, Cline signed in, or Claude Code through the Pushary for Claude plugin): then it closes 10 minutes after it is sent. One call waits at most 55 seconds and may return at once. The user's delivery mode decides how long:
203
+ Asks a question and waits. Use `confirm` for yes or no, `select` for 2 to 6 known options, and `input` when the options cannot be listed. A question stays open until it is answered or cancelled, except one asked through a connector, by signing in or with a connector key, which closes 10 minutes after it is sent: Claude.ai, Claude Desktop, Cowork, ChatGPT, Grok Bot, signed-in Cline, and the Pushary for Claude and Pushary for Cowork plugins. One call waits at most 55 seconds and may return at once. The user's delivery mode decides how long:
195
204
 
196
205
  | Mode | The phone | The call |
197
206
  |---|---|---|
@@ -200,9 +209,9 @@ Asks a question and waits. Use `confirm` for yes or no, `select` for 2 to 6 know
200
209
  | **Alert only** (`notify_only`) | Told, not asked | Returns at once with `status: "notified"` |
201
210
  | **In agent** (`terminal_only`) | Nothing is sent | Returns at once with `status: "terminal"` |
202
211
 
203
- `timeoutMs` sets this call's wait, longer or shorter than the policy, up to 55000. Read `answered`; it is absent when you pass `wait: false`, which returns at once with `status: "pending"`. When work that does not depend on the answer remains, pass `wait: false`, do that work, then poll with `wait_for_answer`.
212
+ `timeoutMs` sets this call's wait, longer or shorter than the policy, up to 55000. Read `answered`; it is absent when you pass `wait: false`, which returns at once, normally with `status: "pending"`. When work that does not depend on the answer remains, pass `wait: false`, do that work, then poll with `wait_for_answer`.
204
213
 
205
- **Approvals.** Pass `toolName`, `toolTarget` (the command head) and the full command in `actionBody` whenever the question approves a tool call, and never leave them out to make a question approvable. When the command is destructive, such as a recursive delete, a force-push, a hard reset, a dropped table, a deploy or a publish, the phone offers only deny and `defer` ("Handle on your machine"). `defer` on any question means the user will decide at the computer: treat it as no answer and ask in the current client.
214
+ **Approvals.** Pass `toolName`, `toolTarget` (the command head) and the full command in `actionBody` whenever the question approves a tool call, and never leave them out to make a question approvable. When the command is destructive or ships something, such as a recursive delete, a force-push, a hard reset, a dropped or truncated table, `sudo`, or any deploy, publish or release, the phone offers only deny and `defer` ("Handle on your machine"). `defer` on any question means the user will decide at the computer: treat it as no answer and ask in the current client.
206
215
 
207
216
  **Answers.** `value` is "yes" or "no" for confirm, the chosen option for select, and the typed text for input. Read `note` too: a denial with a note carries the reason or a condition. A select or input value containing "yes" is answer data, not approval of a separate action.
208
217
 
@@ -228,7 +237,7 @@ Read `answered`, `status` and `handoffAction` on every response. Follow `handoff
228
237
 
229
238
  **Moving a live question to the current chat:** cancel it first. If cancellation returns `handoffAction: "stop"`, stop. Otherwise, if it returns `cancelled: false`, poll once for 1 second and honor the answer that won the race. If the user answers in chat while a phone question is live, do the same before acting.
230
239
 
231
- `noDevices: true` means nothing could receive the question: tell the user what the `warning` field says to connect, and follow the handoff. `paused: true` means phone approvals for this session are paused after earlier ones went unanswered: say so, and follow the handoff.
240
+ `noDevices: true` means nothing could receive the question: tell the user what the `warning` field says to connect, and follow the handoff. `paused: true` means this question was not pushed because earlier phone approvals went unanswered: three in this session, or 20 on this workspace in 14 days. Say so, and follow the handoff. A session pause sends the phone one notice; approving it resumes.
232
241
 
233
242
  ### send_notification
234
243
 
@@ -236,6 +245,8 @@ Tells the user something. Nothing is awaited. Send it for a requested update or
236
245
 
237
246
  Always pass `context.type`: `task_complete`, `error` or `info`. It marks the notification as a task update, so the user's setting for where updates land can route it. Keep the title under 60 characters and the body under 180; the phone cuts the body there. Put detail in `context`.
238
247
 
248
+ Only `sent` above 0 says a device was reached. `sent: 0` or a `suppressed` reason means no phone or browser got a push: tell the user what `warning` or `suppressed` says, not that you notified them. `status: "recorded"` means the turn's completion update was recorded, not that a device got it: only the first one per turn is sent, following the user's update settings. Do not tell the user you notified them on `recorded` alone. `status: "ignored"` means nothing was sent.
249
+
239
250
  ```json
240
251
  {
241
252
  "title": "Refactoring complete",
@@ -262,7 +273,7 @@ Retracts a pending question, for example when you found the answer another way.
262
273
 
263
274
  ### schedule_reminder
264
275
 
265
- When the user asks "remind me later", set a one-time personal reminder with `body` and either `inMinutes` or `at` (an ISO timestamp with an explicit UTC offset or Z). Confirm the returned `fireAt` in their local time and never guess their timezone. For example, `{"body":"Check the deploy","inMinutes":30}`. It reaches the user after you exit, but it does not schedule agent work. Call it with no arguments to list pending reminders, or pass `cancelReminderId` to cancel one; `cancelled:false` means it may already be dispatching. Limits: 30 days ahead, 25 pending per user. Do not use `ask_user` for reminders.
276
+ When the user asks "remind me later", set a one-time personal reminder with `body` (180 characters at most, or the call fails) and either `inMinutes` or `at` (an ISO timestamp with an explicit UTC offset or Z). Confirm the returned `fireAt` in their local time and never guess their timezone. For example, `{"body":"Check the deploy","inMinutes":30}`. It goes to their phone and the Pushary Mac app; with no phone connected, only to the Mac app if they have one. Tell the user any `warning` in the result. It usually arrives within a minute of `fireAt`, even after you exit. It does not schedule agent work. Call it with no arguments to list pending reminders, or pass `cancelReminderId` to cancel one; `cancelled: false` means nothing was cancelled: it was not found, already settled, or already sending. Limits: 30 days ahead, 25 pending per user in each workspace. Do not use `ask_user` for reminders.
266
277
 
267
278
  ### propose_scope
268
279
 
@@ -274,7 +285,7 @@ Agree the boundary of a run once, before the first edit. The user sees the paths
274
285
 
275
286
  **Write paths as globs.** The matcher compares text. A word like `hubspot` matches no file and makes every edit ask; it belongs in `promises`. Write `docs/**`, not `docs`. Letter case matters. Use forward slashes and no leading `./`. For a run that changes no files, call it with no paths and put the whole boundary in `promises`.
276
287
 
277
- **Read the result.** An empty `enforces` means nothing is checked automatically: tell the user. `hookSeen: false` means no hook has reported this `sessionId`, so the contract will never be found: fix the id or say the boundary is only a promise. Answered but not `ratified` means the user declined: ask which boundary they want. Use the `sessionId` your client reports for this run. If it reports none and you have `list_sessions`, call it and take the session whose working directory matches yours with the newest `lastSeenAt`. If another live session shares that folder, on this machine or another, or you cannot tell, skip the scope and tell the user the boundary is only a promise. Never invent an id.
288
+ **Read the result.** An empty `enforces` means nothing is checked automatically: tell the user. `hookSeen: false` means no hook has reported this `sessionId`, so the contract will never be found: fix the id or say the boundary is only a promise. Answered but not `ratified` means the user declined: ask which boundary they want. A yes typed in the chat does not ratify a scope; the boundary is then only a promise. Use the `sessionId` your client reports for this run. If it reports none and you have `list_sessions`, call it and take the session whose working directory matches yours with the newest `lastSeenAt`. If another live session shares that folder, on this machine or another, or you cannot tell, skip the scope and tell the user the boundary is only a promise. Never invent an id.
278
289
 
279
290
  A scope lasts for the session, up to 12 hours, and ends at session end. A later ratified proposal replaces it.
280
291
 
@@ -285,18 +296,18 @@ Read-only. Shows your live agent sessions and any questions still waiting. If an
285
296
  ## Limits
286
297
 
287
298
  - 8 open questions per agent session and 25 per workspace. When a question is refused for this, answer or cancel an open one.
288
- - 10 notifications per 5 minutes per workspace.
299
+ - 10 notifications per 5 minutes per workspace. Every `schedule_reminder` call, including a list or a cancel, counts toward it.
289
300
 
290
301
  ## Answer Surfaces and Account Boundaries
291
302
 
292
303
  | Surface | What the user can do |
293
304
  | --- | --- |
294
305
  | Mobile app | Answer confirm, select and input questions. Confirm notifications offer approve and deny on the lock screen, except for risky commands. Choices and text open the app. |
295
- | Mac notch | Answer personal account questions with confirm, select, input and question-set controls, including keyboard controls. |
306
+ | Mac notch | Answer confirm, select, input and question-set questions, including keyboard controls. |
296
307
  | Slack | Answer through buttons, menus or text modals when the integration and recipient are configured. |
297
308
  | Browser | Open the decision page as a fallback; browser notifications need permission. |
298
309
 
299
- Partner customers use scoped enrollment links issued by their application. Do not enroll them into the operator's account or send their decisions through personal tools. The Mac notch uses the personal account; do not promise a Partner customer inbox on Mac. See https://pushary.com/docs/agents/embed for Partner setup.
310
+ Partner customers use scoped enrollment links issued by their application. Do not enroll them into the operator's account or send their decisions through personal tools. They answer on their enrolled phone, and in the Mac notch once they connect the Mac from the phone app. See https://pushary.com/docs/agents/embed for Partner setup.
300
311
 
301
312
  ## Identifying Your Agent
302
313
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: pushary-cowork
3
- version: 0.7.0
3
+ version: 0.7.1
4
4
  description: Use Pushary in Claude Chat, Cowork, or Claude Code when the user asks for phone updates, a missing decision blocks work, an action needs approval outside existing authorization, or meaningful unattended work finishes or fails. Send task updates and confirm, choice, or text questions to the user's connected devices, then read the returned answer and handoff. Requires the Pushary connector and a paid Pushary account. This skill does not install native permission hooks.
5
5
  metadata:
6
6
  tags: notifications, push, mcp, human-in-the-loop, cowork, claude, alerts, approvals
@@ -42,7 +42,7 @@ Do not create a question just to keep the turn alive or ask for optional feedbac
42
42
 
43
43
  Read `answered`, `status` and `handoffAction` (falling back to `nextAction`) on every response. Only `pending` is live; expired, cancelled, missing and unavailable are not new timeouts. Keep waiting with the same correlationId while pending. A poll ending does not expire the question; never cancel just because a poll returned without an answer. Before moving a live question to the current chat, cancel it. If cancellation says `stop`, stop; if it loses a race, poll once for one second and honor the winning answer. Silence is never consent. A select or input value containing “yes” is answer data, not approval of a separate action.
44
44
 
45
- Delivery is controlled by the user's policy: `push_first` uses presence, `push_only` requests push every time, `notify_only` leaves the decision in the current client, and `terminal_only` avoids push. Do not override the mode or duplicate a question on every surface. The runtime owns delivery, expiry and settlement; do not claim that a reply can restart an ended agent turn.
45
+ Delivery is controlled by the user's policy: `push_first` (When away) still sends your questions to the phone and lets only hook approvals skip it while the user is at the computer, `push_only` requests push every time, `notify_only` leaves the decision in the current client, and `terminal_only` avoids push. Do not override the mode or duplicate a question on every surface. The runtime owns delivery, expiry and settlement; do not claim that a reply can restart an ended agent turn.
46
46
 
47
47
  - If a poll ends while pending, keep waiting with the same question id. Cancel only when explicitly handing off or the answer is no longer needed. If cancellation returns `handoffAction: "stop"`, stop. Otherwise, if cancellation returns false, poll once for 1 second and honor the answer that won the race.
48
48
  - Ask with `ask_user`, not with `send_notification` and `context.askQuestion`. Do not promise an overnight wait or a reply after the turn ends.
@@ -53,13 +53,13 @@ Delivery is controlled by the user's policy: `push_first` uses presence, `push_o
53
53
  | Surface | What the user can do |
54
54
  | --- | --- |
55
55
  | Mobile app | Answer confirm, select and input questions. Supported confirm notifications offer approve/deny actions on the lock screen; arbitrary choices and text open the app. |
56
- | Mac notch | Answer personal account questions with confirm, select, input and question-set controls, including keyboard controls. Presence and delivery policy determine when the phone is also reached. |
56
+ | Mac notch | Answer confirm, select, input and question-set questions, including keyboard controls. Presence and delivery policy determine when the phone is also reached. |
57
57
  | Slack | Answer through buttons, menus or text modals when the integration and intended recipient are configured. |
58
58
  | Browser | Open the decision page as a fallback; browser notification delivery requires permission. |
59
59
 
60
60
  Personal setup connects the operator's devices. The operator installs the Pushary phone or Mac app from https://pushary.com/download and signs in with the same account as the connector. In Chat or Cowork, connect Pushary from the plugin's Connectors tab or add `https://pushary.com/api/mcp/mcp` under Customize > Connectors. In Claude Code, check the connector with `/mcp` and follow its OAuth sign-in prompt. No CLI installer or API key is needed. Ask one harmless test question in the app being tested, answer it from Pushary, and verify Claude receives the answer. CLI doctor checks do not verify a hosted connector. Test phone fallback while away from the Mac; do not infer delivery from a successful API call alone.
61
61
 
62
- Partner customers use scoped enrollment links issued by their application. Do not enroll them into the operator's account or send their decisions through personal tools. The Mac notch currently uses the personal account/session API; do not promise a Partner customer inbox on Mac. See https://pushary.com/docs/agents/embed for Partner setup.
62
+ Partner customers use scoped enrollment links issued by their application. Do not enroll them into the operator's account or send their decisions through personal tools. They answer on their enrolled phone, and in the Mac notch once they connect the Mac from the phone app. See https://pushary.com/docs/agents/embed for Partner setup.
63
63
 
64
64
  ## Conventions
65
65
 
@@ -2,7 +2,7 @@
2
2
  "name": "pushary",
3
3
  "displayName": "Pushary — Control Panel for AI Agents",
4
4
  "description": "Push notifications, human-in-the-loop questions, and permission gating for your AI coding agent. Get a push when a task finishes, answer the agent from your phone, and approve risky commands before they run.",
5
- "version": "0.2.9",
5
+ "version": "0.2.10",
6
6
  "minClientVersions": {
7
7
  "grokbot": "never",
8
8
  "sand": "never"
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.10
4
+
5
+ - The bundled Pushary skill is 0.13.1. It gives the next step for each `status --json` exit code, lists every agent id setup accepts, and keeps the Mac app in charge of the agents it connected.
6
+ - An approval the run cannot continue without is still asked after three pushes, wherever you are, instead of waiting in a chat nobody reads.
7
+ - Reminders: a body over 180 characters fails the call, and a reminder reaches you on your phone, or only in the Mac app when no phone is connected.
8
+ - The skill tells the agent not to say it notified you when nothing was pushed.
9
+ - A Partner customer can answer on a Mac they connected from their phone. The skill used to say they could not.
10
+
3
11
  ## 0.2.9
4
12
 
5
13
  - The always-on rule no longer sends every question to your phone or asks you to approve a plan for work you already asked for. It asks in the chat when you are there and through `ask_user` when you are away.
@@ -25,7 +25,7 @@ Nobody has to say "ping me". When one of these moments is true, act now: ask in
25
25
  - **Another skill tells you to confirm with the user.** That instruction assumes someone watches the terminal. Often nobody does. Ask it where the user is, as for every moment here, so the run continues when they answer.
26
26
  - **A long task finished or failed and nobody is watching.** Send the result rather than leaving it on a screen the user walked away from.
27
27
 
28
- When no device is connected, follow the handoff in the result. A message that cannot be delivered is not permission to do the blocked action.
28
+ When no device is connected, follow the handoff in the result and keep doing approved work that does not depend on the answer. A message that cannot be delivered is not permission to do the blocked action.
29
29
 
30
30
  ## Ask Less, Ask Well
31
31
 
@@ -78,8 +78,9 @@ A round holds every decision whose inputs you already know. A decision that depe
78
78
  - **Silence is not agreement.** No answer approves nothing. An irreversible step, spending money or a decision outside your authority still gets its own question unless the user already approved it.
79
79
  - **One `select` with the real options beats three `confirm` questions.**
80
80
  - **Ask at the boundary, not once for each item.** Ask about deleting files, not about each file.
81
- - **Send at most three pushes per task** unless the user asks for more. Questions asked as chat text in the terminal do not count. The cap never waives an approval: past it, ask in the current client and wait.
82
- - **When the requested work is done, report it and stop.** Do not ask what to do next unless the user asked you to.
81
+ - **Write for someone glancing at a phone.** Name the exact thing and the number: "Delete the 3 unused migration files?" beats "Should I clean up?"
82
+ - **Send at most three pushes per task** unless the user asks for more. Questions asked as chat text do not count. The cap never holds back an approval the run cannot continue without: ask it where the user is.
83
+ - **When the requested work is done, report it and stop.** Do not ask what to do next unless the user asked you to. Work blocked on a choice only the user can make is not done: ask that choice.
83
84
 
84
85
  ## Setup
85
86
 
@@ -126,16 +127,24 @@ When Node and npm are available, run `npx pushary@latest status --json`. The exi
126
127
  | --- | --- |
127
128
  | 0 | Ready. If the JSON says `connectedThroughMacApp: true`, the Mac app holds the key: check the account, plan and phone in the Pushary Mac app. |
128
129
  | 1 | The command failed. |
129
- | 2 | A malformed key or an unknown flag. |
130
+ | 2 | A malformed key, an unknown flag, or a Node version that is too old. |
130
131
  | 3 | Not set up on this machine. |
131
132
  | 4 | The key was rejected or signed out. |
132
- | 5 | A problem was found: two keys that disagree, or no active plan. Read the JSON. |
133
- | 6 | Nothing proves a question reaches this user: no phone of theirs is paired, or only a teammate's devices are. Have them install the Pushary app from https://pushary.com/download and sign in to the same account, then run `status --json` again. |
134
- | 8 | Pushary could not be reached. |
133
+ | 5 | Two keys that disagree, or no active plan. |
134
+ | 6 | Nothing proves a question reaches this user: no phone of theirs is paired, or only a teammate's devices are. |
135
+ | 8 | Pushary could not be reached. Check again later; do not run setup. |
135
136
 
136
- For `mac-app` without Node or npm, open the Pushary Mac app. Check the account, the plan and the Agents connection there, and connect or repair agents in the app. Do not install Node to inspect a native setup, and do not claim an exit code when no CLI ran.
137
+ For any code but 0 or 8, run `npx pushary@latest status` without `--json` and follow the steps it prints, with these changes:
137
138
 
138
- To add an agent to a working install, run `npx pushary@latest setup --agents <id>`. It reuses the key and does not pair again. If the Mac app owns this machine's hooks, setup keeps them; point the user at the Pushary app for hook changes.
139
+ - Run a printed `pushary …` command as `npx pushary@latest …`, and a printed setup as in "Running setup yourself". Where it says to get or copy a key, run setup instead. Never ask the user for one.
140
+ - **`mac-app` printed and the code is 3:** have the user sign in to the Pushary Mac app, then check again.
141
+ - **Status says the key was signed out on this Mac:** have the user sign in again to the Pushary Mac app, open Settings > Agents and press Repair on every agent that offers it (if none does yet, have them close Settings, wait a minute and open it again), then run setup as in "Running setup yourself". It reuses the key the app wrote into the agents' settings; if the first one it finds does not work, it pairs instead. If status then shows the old key `from $PUSHARY_API_KEY`, have the user restart this agent from a new terminal.
142
+ - **The Key line says `from $PUSHARY_API_KEY`, the code is 2 or 4, and status does not say signed out on this Mac:** this shell exports a bad key, and it wins over any key setup saves. Run setup at most once. If status still fails or shows `Key drift`, have the user delete every `export PUSHARY_API_KEY` line that still sets the old key from their shell startup files, such as ~/.zshrc, ~/.zprofile, ~/.bashrc and ~/.bash_profile, including any setup said it could not update, then restart this agent from a new terminal.
143
+ - **Code 6, instead of the steps status prints:** have them install the Pushary app from https://pushary.com/download, sign in to the account this machine uses and allow notifications, then check again. A user who does not use a phone always gets 6: say so and stop. If it still says 6, offer to pair the phone: in the Pushary Mac app under Settings > Phone > Pair when `mac-app` printed, otherwise with setup `--connect app` as in "Running setup yourself", which creates a new key.
144
+
145
+ For `mac-app` without Node or npm, or with a Node version the CLI refuses, open the Pushary Mac app. Check the account, the plan and the Agents connection there, and connect or repair agents in the app. Do not install Node to inspect a native setup, and do not claim an exit code when no CLI ran.
146
+
147
+ To add an agent to a working install, run `npx pushary@latest setup --agents <id>`; it reuses the key and does not pair again. When status reported `connectedThroughMacApp: true`, connect the agent in the Pushary Mac app instead, except Cline. Setup keeps hooks the Mac app owns; pass `--take-over-hooks` only when the user wants the command line to own them.
139
148
 
140
149
  ### Branch 2. `Darwin`, no key, no `mac-app`
141
150
 
@@ -159,18 +168,18 @@ In PowerShell, type `npx.cmd` instead of `npx`. Node 20.17+, 22.13+ or 23.5+ is
159
168
 
160
169
  ### Running setup yourself
161
170
 
162
- Before you run it, tell the user what it does: it pairs their phone, then configures MCP, hooks and the skill for the agents you name. It also installs the `pushary` command globally, starts a background service so the phone can start sessions (`--control off` skips it), and turns on session history (`--transcripts off` turns it off). It needs a paid plan; the phone app shows the price and any trial.
171
+ Before you run it, tell the user what it does: it pairs their phone, then configures MCP, hooks and the skill for the agents you name. It may also install the `pushary` command globally and start a background service so the phone can start sessions (`--control off` skips it). It turns on session history (`--transcripts off` turns it off). It needs a paid plan; the phone app shows the price and any trial.
163
172
 
164
- 1. **Name the agents.** Pass `--agents` with your own id: `claude_code`, `codex`, `cursor`, `gemini_cli`, `vscode`, `opencode`, `hermes`, or a comma-separated list. Without it, setup run from an agent's shell configures every agent it detects.
173
+ 1. **Name the agents.** Pass `--agents` with your own id: `claude_code`, `codex`, `gemini_cli`, `cursor`, `vscode`, `opencode`, `hermes`, `cline`, `antigravity_cli`, `qwen_code`, `codebuddy`, `qoder`, `droid`, `devin`, `grok`, `fx` or `custom`, or a comma-separated list. `custom` (Windsurf or any other MCP client) gets a key like any other id but configures no client: it prints the server URL and an `Authorization: Bearer $PUSHARY_API_KEY` header. Add both to that client's MCP settings before you report it connected; if the client cannot read environment variables, use the key saved in ~/.pushary/config.json. Without `--agents`, setup run from an agent's shell configures every agent it detects.
165
174
  2. **Run it in the background.** It waits up to 15 minutes for the phone, longer than most agents let a foreground command run, and a killed setup kills the pairing code with it. Start it as a background process that writes to a log, read the short link, the QR and the fingerprint from that log, show them to the user as they print, and keep checking the log until setup exits. Do not summarise them. The link survives where the QR renders badly. Start while the user can still read your messages: until they approve, nothing is configured and you have no other way to reach them.
166
175
  3. **Walk the user through it.** They open the link or scan the QR. If they do not have the Pushary app, they install it from https://pushary.com/download, then return to the original link and tap Open Pushary; they do the same if the app restarts during sign-in or payment. The app shows a fingerprint that must match the one in your output. On a first install the app asks them to sign in and choose a plan. Then they approve, and setup finishes on its own. If the code expires, run setup again.
167
- 4. **Report the result plainly.** If setup exits without pairing, nothing was configured. Say so.
176
+ 4. **Report the result plainly.** If setup exits without pairing, nothing was configured. Say so. If it exits 6, the agents are configured but nothing proves a phone of theirs can receive yet: follow code 6 above, but if setup just paired, do not pair again.
168
177
 
169
- Never ask the user for an API key, and never send them to a signup page first. If `PUSHARY_API_KEY` is already set or an agent configuration holds a key, setup uses it and skips pairing.
178
+ Never ask the user for an API key, and never send them to a signup page first. If a working key is already set or stored on this machine, setup reuses it and skips pairing. `--connect app` always pairs and creates a new key unless `--key` or `--key-stdin` is passed. If this machine had a key, tell the user it stays active until they revoke it under API keys at https://pushary.com/dashboard/agent/settings.
170
179
 
171
180
  Manual MCP configuration also works, but it needs a key from https://pushary.com/sign-up?utm_source=skill&utm_medium=setup. Prefer setup.
172
181
 
173
- Setup itself sends only a test notification, because it cannot tell whether the user is there to answer. Right after it finishes, while the user still has their phone in hand, test a question and answer: for a CLI setup, run `npx pushary@latest doctor --roundtrip`. A returned answer proves the question path, not hook enforcement. Restart the agent and follow its approval check at https://pushary.com/docs/agents/supported-agents. For a Mac app setup, use the app's connection tests and ask one harmless question from the current agent.
182
+ Setup itself sends only a test notification, because it cannot tell whether the user is there to answer. Right after it finishes, while the user still has their phone in hand, test a question and answer: for a CLI setup, run `npx pushary@latest doctor --roundtrip`. It needs a CLI key, sends a test push and one question, and waits about a minute for the answer. Its exit code also covers unrelated checks, so read the Synthetic answer test line. A returned answer proves the question path, not hook enforcement. Restart the agent and follow its approval check at https://pushary.com/docs/agents/supported-agents. For a Mac app setup, use the app's connection tests and ask one harmless question from the current agent.
174
183
 
175
184
  ## Pricing and Free Alternatives
176
185
 
@@ -184,7 +193,7 @@ Your client already holds each tool's schema, with every parameter and returned
184
193
 
185
194
  ### ask_user
186
195
 
187
- Asks a question and waits. Use `confirm` for yes or no, `select` for 2 to 6 known options, and `input` when the options cannot be listed. A question stays open until it is answered or cancelled, except through a connector, by signing in or with a connector key (Claude.ai, Claude Desktop, Cowork, ChatGPT, Grok Bot, Cline signed in, or Claude Code through the Pushary for Claude plugin): then it closes 10 minutes after it is sent. One call waits at most 55 seconds and may return at once. The user's delivery mode decides how long:
196
+ Asks a question and waits. Use `confirm` for yes or no, `select` for 2 to 6 known options, and `input` when the options cannot be listed. A question stays open until it is answered or cancelled, except one asked through a connector, by signing in or with a connector key, which closes 10 minutes after it is sent: Claude.ai, Claude Desktop, Cowork, ChatGPT, Grok Bot, signed-in Cline, and the Pushary for Claude and Pushary for Cowork plugins. One call waits at most 55 seconds and may return at once. The user's delivery mode decides how long:
188
197
 
189
198
  | Mode | The phone | The call |
190
199
  |---|---|---|
@@ -193,9 +202,9 @@ Asks a question and waits. Use `confirm` for yes or no, `select` for 2 to 6 know
193
202
  | **Alert only** (`notify_only`) | Told, not asked | Returns at once with `status: "notified"` |
194
203
  | **In agent** (`terminal_only`) | Nothing is sent | Returns at once with `status: "terminal"` |
195
204
 
196
- `timeoutMs` sets this call's wait, longer or shorter than the policy, up to 55000. Read `answered`; it is absent when you pass `wait: false`, which returns at once with `status: "pending"`. When work that does not depend on the answer remains, pass `wait: false`, do that work, then poll with `wait_for_answer`.
205
+ `timeoutMs` sets this call's wait, longer or shorter than the policy, up to 55000. Read `answered`; it is absent when you pass `wait: false`, which returns at once, normally with `status: "pending"`. When work that does not depend on the answer remains, pass `wait: false`, do that work, then poll with `wait_for_answer`.
197
206
 
198
- **Approvals.** Pass `toolName`, `toolTarget` (the command head) and the full command in `actionBody` whenever the question approves a tool call, and never leave them out to make a question approvable. When the command is destructive, such as a recursive delete, a force-push, a hard reset, a dropped table, a deploy or a publish, the phone offers only deny and `defer` ("Handle on your machine"). `defer` on any question means the user will decide at the computer: treat it as no answer and ask in the current client.
207
+ **Approvals.** Pass `toolName`, `toolTarget` (the command head) and the full command in `actionBody` whenever the question approves a tool call, and never leave them out to make a question approvable. When the command is destructive or ships something, such as a recursive delete, a force-push, a hard reset, a dropped or truncated table, `sudo`, or any deploy, publish or release, the phone offers only deny and `defer` ("Handle on your machine"). `defer` on any question means the user will decide at the computer: treat it as no answer and ask in the current client.
199
208
 
200
209
  **Answers.** `value` is "yes" or "no" for confirm, the chosen option for select, and the typed text for input. Read `note` too: a denial with a note carries the reason or a condition. A select or input value containing "yes" is answer data, not approval of a separate action.
201
210
 
@@ -221,7 +230,7 @@ Read `answered`, `status` and `handoffAction` on every response. Follow `handoff
221
230
 
222
231
  **Moving a live question to the current chat:** cancel it first. If cancellation returns `handoffAction: "stop"`, stop. Otherwise, if it returns `cancelled: false`, poll once for 1 second and honor the answer that won the race. If the user answers in chat while a phone question is live, do the same before acting.
223
232
 
224
- `noDevices: true` means nothing could receive the question: tell the user what the `warning` field says to connect, and follow the handoff. `paused: true` means phone approvals for this session are paused after earlier ones went unanswered: say so, and follow the handoff.
233
+ `noDevices: true` means nothing could receive the question: tell the user what the `warning` field says to connect, and follow the handoff. `paused: true` means this question was not pushed because earlier phone approvals went unanswered: three in this session, or 20 on this workspace in 14 days. Say so, and follow the handoff. A session pause sends the phone one notice; approving it resumes.
225
234
 
226
235
  ### send_notification
227
236
 
@@ -229,6 +238,8 @@ Tells the user something. Nothing is awaited. Send it for a requested update or
229
238
 
230
239
  Always pass `context.type`: `task_complete`, `error` or `info`. It marks the notification as a task update, so the user's setting for where updates land can route it. Keep the title under 60 characters and the body under 180; the phone cuts the body there. Put detail in `context`.
231
240
 
241
+ Only `sent` above 0 says a device was reached. `sent: 0` or a `suppressed` reason means no phone or browser got a push: tell the user what `warning` or `suppressed` says, not that you notified them. `status: "recorded"` means the turn's completion update was recorded, not that a device got it: only the first one per turn is sent, following the user's update settings. Do not tell the user you notified them on `recorded` alone. `status: "ignored"` means nothing was sent.
242
+
232
243
  ```json
233
244
  {
234
245
  "title": "Refactoring complete",
@@ -255,7 +266,7 @@ Retracts a pending question, for example when you found the answer another way.
255
266
 
256
267
  ### schedule_reminder
257
268
 
258
- When the user asks "remind me later", set a one-time personal reminder with `body` and either `inMinutes` or `at` (an ISO timestamp with an explicit UTC offset or Z). Confirm the returned `fireAt` in their local time and never guess their timezone. For example, `{"body":"Check the deploy","inMinutes":30}`. It reaches the user after you exit, but it does not schedule agent work. Call it with no arguments to list pending reminders, or pass `cancelReminderId` to cancel one; `cancelled:false` means it may already be dispatching. Limits: 30 days ahead, 25 pending per user. Do not use `ask_user` for reminders.
269
+ When the user asks "remind me later", set a one-time personal reminder with `body` (180 characters at most, or the call fails) and either `inMinutes` or `at` (an ISO timestamp with an explicit UTC offset or Z). Confirm the returned `fireAt` in their local time and never guess their timezone. For example, `{"body":"Check the deploy","inMinutes":30}`. It goes to their phone and the Pushary Mac app; with no phone connected, only to the Mac app if they have one. Tell the user any `warning` in the result. It usually arrives within a minute of `fireAt`, even after you exit. It does not schedule agent work. Call it with no arguments to list pending reminders, or pass `cancelReminderId` to cancel one; `cancelled: false` means nothing was cancelled: it was not found, already settled, or already sending. Limits: 30 days ahead, 25 pending per user in each workspace. Do not use `ask_user` for reminders.
259
270
 
260
271
  ### propose_scope
261
272
 
@@ -267,7 +278,7 @@ Agree the boundary of a run once, before the first edit. The user sees the paths
267
278
 
268
279
  **Write paths as globs.** The matcher compares text. A word like `hubspot` matches no file and makes every edit ask; it belongs in `promises`. Write `docs/**`, not `docs`. Letter case matters. Use forward slashes and no leading `./`. For a run that changes no files, call it with no paths and put the whole boundary in `promises`.
269
280
 
270
- **Read the result.** An empty `enforces` means nothing is checked automatically: tell the user. `hookSeen: false` means no hook has reported this `sessionId`, so the contract will never be found: fix the id or say the boundary is only a promise. Answered but not `ratified` means the user declined: ask which boundary they want. Use the `sessionId` your client reports for this run. If it reports none and you have `list_sessions`, call it and take the session whose working directory matches yours with the newest `lastSeenAt`. If another live session shares that folder, on this machine or another, or you cannot tell, skip the scope and tell the user the boundary is only a promise. Never invent an id.
281
+ **Read the result.** An empty `enforces` means nothing is checked automatically: tell the user. `hookSeen: false` means no hook has reported this `sessionId`, so the contract will never be found: fix the id or say the boundary is only a promise. Answered but not `ratified` means the user declined: ask which boundary they want. A yes typed in the chat does not ratify a scope; the boundary is then only a promise. Use the `sessionId` your client reports for this run. If it reports none and you have `list_sessions`, call it and take the session whose working directory matches yours with the newest `lastSeenAt`. If another live session shares that folder, on this machine or another, or you cannot tell, skip the scope and tell the user the boundary is only a promise. Never invent an id.
271
282
 
272
283
  A scope lasts for the session, up to 12 hours, and ends at session end. A later ratified proposal replaces it.
273
284
 
@@ -278,18 +289,18 @@ Read-only. Shows your live agent sessions and any questions still waiting. If an
278
289
  ## Limits
279
290
 
280
291
  - 8 open questions per agent session and 25 per workspace. When a question is refused for this, answer or cancel an open one.
281
- - 10 notifications per 5 minutes per workspace.
292
+ - 10 notifications per 5 minutes per workspace. Every `schedule_reminder` call, including a list or a cancel, counts toward it.
282
293
 
283
294
  ## Answer Surfaces and Account Boundaries
284
295
 
285
296
  | Surface | What the user can do |
286
297
  | --- | --- |
287
298
  | Mobile app | Answer confirm, select and input questions. Confirm notifications offer approve and deny on the lock screen, except for risky commands. Choices and text open the app. |
288
- | Mac notch | Answer personal account questions with confirm, select, input and question-set controls, including keyboard controls. |
299
+ | Mac notch | Answer confirm, select, input and question-set questions, including keyboard controls. |
289
300
  | Slack | Answer through buttons, menus or text modals when the integration and recipient are configured. |
290
301
  | Browser | Open the decision page as a fallback; browser notifications need permission. |
291
302
 
292
- Partner customers use scoped enrollment links issued by their application. Do not enroll them into the operator's account or send their decisions through personal tools. The Mac notch uses the personal account; do not promise a Partner customer inbox on Mac. See https://pushary.com/docs/agents/embed for Partner setup.
303
+ Partner customers use scoped enrollment links issued by their application. Do not enroll them into the operator's account or send their decisions through personal tools. They answer on their enrolled phone, and in the Mac notch once they connect the Mac from the phone app. See https://pushary.com/docs/agents/embed for Partner setup.
293
304
 
294
305
  ## Identifying Your Agent
295
306
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pushary",
3
3
  "description": "Push notifications, human-in-the-loop questions, and permission gating for your AI agent. Get a push when a task finishes, answer the agent from your phone, and approve risky commands before they run.",
4
- "version": "0.2.5",
4
+ "version": "0.2.6",
5
5
  "author": {
6
6
  "name": "Pushary",
7
7
  "email": "business@pushary.com",
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.6
4
+
5
+ - The bundled Pushary skill is 0.13.1. It gives the next step for each `status --json` exit code, lists every agent id setup accepts, and keeps the Mac app in charge of the agents it connected.
6
+ - An approval the run cannot continue without is still asked after three pushes, wherever you are, instead of waiting in a chat nobody reads.
7
+ - Reminders: a body over 180 characters fails the call, and a reminder reaches you on your phone, or only in the Mac app when no phone is connected.
8
+ - The skill tells the agent not to say it notified you when nothing was pushed.
9
+ - A Partner customer can answer on a Mac they connected from their phone. The skill used to say they could not.
10
+
3
11
  ## 0.2.5
4
12
 
5
13
  - Carries the skill changes since 0.2.4: personal reminders with `schedule_reminder`, questions that stay open until answered, and the current setup and pairing steps.