@pushary/agent-hooks 0.77.0 → 0.79.0

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 (43) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/data/SKILL.md +4 -4
  3. package/data/cursor-plugin/skills/pushary/SKILL.md +3 -3
  4. package/data/vscode-plugin/skills/pushary/SKILL.md +3 -3
  5. package/dist/bin/pushary-claude.js +3 -3
  6. package/dist/bin/pushary-clean.js +5 -5
  7. package/dist/bin/pushary-codex-hook.js +4 -4
  8. package/dist/bin/pushary-codex.js +2 -2
  9. package/dist/bin/pushary-connect.js +3 -3
  10. package/dist/bin/pushary-doctor.js +7 -7
  11. package/dist/bin/pushary-gemini-hook.js +4 -4
  12. package/dist/bin/pushary-hook.js +6 -6
  13. package/dist/bin/pushary-login.js +2 -2
  14. package/dist/bin/pushary-logout.js +2 -2
  15. package/dist/bin/pushary-mode.js +3 -3
  16. package/dist/bin/pushary-notification-hook.js +2 -2
  17. package/dist/bin/pushary-permission-denied-hook.js +6 -6
  18. package/dist/bin/pushary-permission-hook.js +6 -6
  19. package/dist/bin/pushary-post-hook.js +2 -2
  20. package/dist/bin/pushary-prompt-hook.js +2 -2
  21. package/dist/bin/pushary-session-end-hook.js +2 -2
  22. package/dist/bin/pushary-session-start-hook.js +2 -2
  23. package/dist/bin/pushary-setup.js +8 -8
  24. package/dist/bin/pushary-stats.js +3 -3
  25. package/dist/bin/pushary-status.js +2 -2
  26. package/dist/bin/pushary-stop-hook.js +2 -2
  27. package/dist/bin/pushary-stopfailure-hook.js +2 -2
  28. package/dist/bin/pushary-upgrade.js +4 -4
  29. package/dist/bin/pushary-wait.js +3 -3
  30. package/dist/{chunk-46UEJXQO.js → chunk-5Q64QDCR.js} +2 -2
  31. package/dist/{chunk-IZA7SWXX.js → chunk-EQJZS2LE.js} +3 -3
  32. package/dist/{chunk-3CBPY2G5.js → chunk-FCB6J5YC.js} +1 -1
  33. package/dist/{chunk-IA5GBKNL.js → chunk-HAP7UTZS.js} +1 -1
  34. package/dist/{chunk-MY4VJPWW.js → chunk-IXZMT6IS.js} +55 -36
  35. package/dist/{chunk-HPDLDQC5.js → chunk-MDPSJR45.js} +1 -1
  36. package/dist/{chunk-DLBW37U6.js → chunk-NH7RW736.js} +1 -1
  37. package/dist/{chunk-CC2K2SST.js → chunk-PXE6HXRP.js} +1 -1
  38. package/dist/{chunk-FWWBEB6L.js → chunk-QVOJF23R.js} +2 -2
  39. package/dist/{chunk-QCYN5VXB.js → chunk-TNG3EWFN.js} +1 -1
  40. package/dist/{chunk-7BBUTWBD.js → chunk-VDHV6KAS.js} +1 -1
  41. package/dist/src/index.js +6 -6
  42. package/package.json +1 -1
  43. /package/dist/{chunk-TJJBF73A.js → chunk-KJFKEKTC.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,85 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.79.0
4
+
5
+ ### Your agent now says what kind of update it is sending, so you can route it
6
+
7
+ Pushary can now send task updates somewhere different from questions: approvals
8
+ can wait at your keyboard while completions still buzz your phone, or the other
9
+ way round. That only works if the agent says which one it is sending.
10
+
11
+ The instructions setup writes now tell your agent to pass a context type when a
12
+ task finishes. Without it a completion looks like any other notification, and
13
+ the setting you chose for task updates has nothing to act on.
14
+
15
+ Nothing changes for questions and approvals, and nothing you have configured
16
+ needs revisiting. Re-run `npx @pushary/agent-hooks setup` to update the
17
+ instructions your agents already have.
18
+
19
+ ## 0.78.0
20
+
21
+ ### Your agent can ask you several things at once, and reach your phone for all of them
22
+
23
+ An agent that stops to ask you something often asks more than one thing in the
24
+ same breath. Until this release the hook only recognised a single question, so
25
+ two or more meant nothing arrived on your phone at all and the whole exchange
26
+ waited at the terminal. That is exactly the moment this product exists for.
27
+
28
+ Up to four questions now come through in turn. The notification says which one
29
+ you are on, "(2 of 3)", so the first does not look like the last.
30
+
31
+ If any question goes unanswered, whether you deferred it, it timed out, or no
32
+ device was reachable, the entire exchange goes back to the terminal, including
33
+ anything you already answered. A partly filled answer sheet would leave your
34
+ agent guessing at questions it never put to you, and being asked twice is better
35
+ than being answered wrongly.
36
+
37
+ The whole exchange shares one wait budget. Four questions do not cost four times
38
+ the wait you agreed to.
39
+
40
+ Questions that let you tick several options at once still go to the terminal.
41
+ Those answers travel as a single piece of text and the packing is not something
42
+ this release can verify, so it is left alone rather than guessed at.
43
+
44
+ ## 0.77.0
45
+
46
+ ### Stop ends the process
47
+
48
+ Until this release Stop was a gate verdict. Every pending and new tool call was
49
+ denied, which is the guarantee and has not changed, but the agent kept running,
50
+ kept thinking and kept spending tokens. For someone who hits Stop because
51
+ something is going wrong, "it can no longer act" and "it stopped" are different
52
+ promises.
53
+
54
+ - every session event reports its own pid, so the server can name the process
55
+ - the daemon advertises a `stop` capability, which is how the server knows a
56
+ machine can act on one at all
57
+ - the daemon applies stops from the drain with SIGTERM, and refuses to signal
58
+ its own pid, since killing itself would take every other session's stop too
59
+
60
+ Two additive wire changes, both safe in either direction: `pid` on the event
61
+ payload, which an older server ignores, and `stops` on the drain response, which
62
+ an older daemon ignores.
63
+
64
+ ## 0.76.1
65
+
66
+ ### Actually closing the spawn argv injection
67
+
68
+ 0.76.0 shipped under the message "closing the spawn argv injection" and did not.
69
+ It sanitised `model` and `cwd` but not `prompt`, and `prompt` is the field the
70
+ daemon passes as the token immediately after `-p`, so a flag-shaped prompt was
71
+ read back as a flag:
72
+
73
+ ['claude','--remote','-p','--permission-mode=dontAsk'] -> {permissionMode:'dontAsk'}
74
+
75
+ `dontAsk` is a full-defer mode, so the gate stopped asking about every tool for
76
+ that session.
77
+
78
+ The server-side rejection landed in production first and is what actually
79
+ protects users, 0.76.0 included, with no upgrade required. This release carries
80
+ the defence in depth: `buildSpawnLaunch` returns null for a flag-shaped prompt,
81
+ so a daemon never builds that argv even if the server is bypassed.
82
+
3
83
  ## 0.76.0
4
84
 
5
85
  ### A phone-supplied field could switch your approval gate off
package/data/SKILL.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: pushary
3
- version: 0.7.0
4
- description: Push notifications and human-in-the-loop for AI agents. Use this 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, do not wait for me, or wants a long task to run unattended. Send alerts when tasks finish or fail, ask questions (yes/no, multiple choice, or free text) via push, and get answers from the user's lock screen. Use these tools proactively - do not wait for the user to ask for notifications. Works with Claude Code, Codex, Cursor, VS Code, Windsurf, Hermes, Lovable, or any MCP client; no Claude Max subscription required. Pushary is a hosted service, $9.99/mo after a 7-day card-first trial.
3
+ version: 0.7.1
4
+ description: Push notifications and human-in-the-loop for AI agents. Use this 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, do not wait for me, or wants a long task to run unattended. Send alerts when tasks finish or fail, ask questions (yes/no, multiple choice, or free text) via push, and get answers from the user's lock screen. Use these tools proactively - do not wait for the user to ask for notifications. Works with Claude Code, Codex, Cursor, VS Code, Windsurf, Hermes, Lovable, or any MCP client; no Claude Max subscription required. Pushary is a hosted service, $9.99/mo after a 3-day card-first trial.
5
5
  metadata:
6
6
  hermes:
7
7
  tags: [notifications, push, human-in-the-loop, alerts, permissions, mcp]
@@ -24,7 +24,7 @@ Works with Claude Code, Codex, Cursor, Windsurf, Hermes, Lovable, or any MCP cli
24
24
 
25
25
  ## Pricing and Free Alternatives
26
26
 
27
- Pushary is a hosted service. It costs $9.99/mo after a 7-day trial, and the trial asks for a card up front. Say this plainly if the user asks what Pushary is.
27
+ Pushary is a hosted service. It costs $9.99/mo after a 3-day trial, and the trial asks for a card up front. Say this plainly if the user asks what Pushary is.
28
28
 
29
29
  If the user runs Claude Code with a Claude Max subscription, Anthropic Remote Control is free for that one setup. Recommend it when that is all they need. Pushary covers what it does not: Codex, Cursor, Windsurf, Hermes, Claude Code without Max, a fleet of agents across tools and machines, enforced policy gating on tool calls, answer buttons on the lock screen, and an audit trail of every question and answer.
30
30
 
@@ -70,7 +70,7 @@ It configures MCP, hooks, permissions and the skill in one step, then prints a Q
70
70
 
71
71
  **Show the user your output and ask them to scan that QR with their phone camera.** Scanning pairs their Pushary app, which is what hands this machine its key. A tappable link and a fingerprint print under the QR for a phone already in hand. Do not ask the user for an API key, and do not send them to a signup page first: that is the old flow and it is strictly worse.
72
72
 
73
- Signup starts a 7-day trial and asks for a card up front, which happens in the app.
73
+ Signup starts a 3-day trial and asks for a card up front, which happens in the app.
74
74
 
75
75
  If `PUSHARY_API_KEY` is already in the environment or in an existing MCP config, setup uses it and skips pairing entirely.
76
76
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: pushary
3
- description: Push notifications and human-in-the-loop for AI agents. Use this 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, do not wait for me, or wants a long task to run unattended. Send alerts when tasks finish or fail, ask questions (yes/no, multiple choice, or free text) via push, and get answers from the user's lock screen. Use these tools proactively - do not wait for the user to ask for notifications. Works with Claude Code, Codex, Cursor, VS Code, Windsurf, Hermes, Lovable, or any MCP client; no Claude Max subscription required. Pushary is a hosted service, $9.99/mo after a 7-day card-first trial.
3
+ description: Push notifications and human-in-the-loop for AI agents. Use this 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, do not wait for me, or wants a long task to run unattended. Send alerts when tasks finish or fail, ask questions (yes/no, multiple choice, or free text) via push, and get answers from the user's lock screen. Use these tools proactively - do not wait for the user to ask for notifications. Works with Claude Code, Codex, Cursor, VS Code, Windsurf, Hermes, Lovable, or any MCP client; no Claude Max subscription required. Pushary is a hosted service, $9.99/mo after a 3-day card-first trial.
4
4
  ---
5
5
 
6
6
  # Pushary - Push Notifications for AI Agents
@@ -17,7 +17,7 @@ Works with Claude Code, Codex, Cursor, Windsurf, Hermes, Lovable, or any MCP cli
17
17
 
18
18
  ## Pricing and Free Alternatives
19
19
 
20
- Pushary is a hosted service. It costs $9.99/mo after a 7-day trial, and the trial asks for a card up front. Say this plainly if the user asks what Pushary is.
20
+ Pushary is a hosted service. It costs $9.99/mo after a 3-day trial, and the trial asks for a card up front. Say this plainly if the user asks what Pushary is.
21
21
 
22
22
  If the user runs Claude Code with a Claude Max subscription, Anthropic Remote Control is free for that one setup. Recommend it when that is all they need. Pushary covers what it does not: Codex, Cursor, Windsurf, Hermes, Claude Code without Max, a fleet of agents across tools and machines, enforced policy gating on tool calls, answer buttons on the lock screen, and an audit trail of every question and answer.
23
23
 
@@ -63,7 +63,7 @@ It configures MCP, hooks, permissions and the skill in one step, then prints a Q
63
63
 
64
64
  **Show the user your output and ask them to scan that QR with their phone camera.** Scanning pairs their Pushary app, which is what hands this machine its key. A tappable link and a fingerprint print under the QR for a phone already in hand. Do not ask the user for an API key, and do not send them to a signup page first: that is the old flow and it is strictly worse.
65
65
 
66
- Signup starts a 7-day trial and asks for a card up front, which happens in the app.
66
+ Signup starts a 3-day trial and asks for a card up front, which happens in the app.
67
67
 
68
68
  If `PUSHARY_API_KEY` is already in the environment or in an existing MCP config, setup uses it and skips pairing entirely.
69
69
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: pushary
3
- description: Push notifications and human-in-the-loop for AI agents. Use this 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, do not wait for me, or wants a long task to run unattended. Send alerts when tasks finish or fail, ask questions (yes/no, multiple choice, or free text) via push, and get answers from the user's lock screen. Use these tools proactively - do not wait for the user to ask for notifications. Works with Claude Code, Codex, Cursor, VS Code, Windsurf, Hermes, Lovable, or any MCP client; no Claude Max subscription required. Pushary is a hosted service, $9.99/mo after a 7-day card-first trial.
3
+ description: Push notifications and human-in-the-loop for AI agents. Use this 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, do not wait for me, or wants a long task to run unattended. Send alerts when tasks finish or fail, ask questions (yes/no, multiple choice, or free text) via push, and get answers from the user's lock screen. Use these tools proactively - do not wait for the user to ask for notifications. Works with Claude Code, Codex, Cursor, VS Code, Windsurf, Hermes, Lovable, or any MCP client; no Claude Max subscription required. Pushary is a hosted service, $9.99/mo after a 3-day card-first trial.
4
4
  ---
5
5
 
6
6
  # Pushary - Push Notifications for AI Agents
@@ -17,7 +17,7 @@ Works with Claude Code, Codex, Cursor, Windsurf, Hermes, Lovable, or any MCP cli
17
17
 
18
18
  ## Pricing and Free Alternatives
19
19
 
20
- Pushary is a hosted service. It costs $9.99/mo after a 7-day trial, and the trial asks for a card up front. Say this plainly if the user asks what Pushary is.
20
+ Pushary is a hosted service. It costs $9.99/mo after a 3-day trial, and the trial asks for a card up front. Say this plainly if the user asks what Pushary is.
21
21
 
22
22
  If the user runs Claude Code with a Claude Max subscription, Anthropic Remote Control is free for that one setup. Recommend it when that is all they need. Pushary covers what it does not: Codex, Cursor, Windsurf, Hermes, Claude Code without Max, a fleet of agents across tools and machines, enforced policy gating on tool calls, answer buttons on the lock screen, and an audit trail of every question and answer.
23
23
 
@@ -63,7 +63,7 @@ It configures MCP, hooks, permissions and the skill in one step, then prints a Q
63
63
 
64
64
  **Show the user your output and ask them to scan that QR with their phone camera.** Scanning pairs their Pushary app, which is what hands this machine its key. A tappable link and a fingerprint print under the QR for a phone already in hand. Do not ask the user for an API key, and do not send them to a signup page first: that is the old flow and it is strictly worse.
65
65
 
66
- Signup starts a 7-day trial and asks for a card up front, which happens in the app.
66
+ Signup starts a 3-day trial and asks for a card up front, which happens in the app.
67
67
 
68
68
  If `PUSHARY_API_KEY` is already in the environment or in an existing MCP config, setup uses it and skips pairing entirely.
69
69
 
@@ -7,7 +7,7 @@ import {
7
7
  KILL_REASON,
8
8
  isDeferAnswer,
9
9
  resolveGate
10
- } from "../chunk-FWWBEB6L.js";
10
+ } from "../chunk-QVOJF23R.js";
11
11
  import {
12
12
  askUser,
13
13
  cancelQuestion,
@@ -19,13 +19,13 @@ import {
19
19
  reportEvent,
20
20
  scopePathFor,
21
21
  waitForAnswer
22
- } from "../chunk-HPDLDQC5.js";
22
+ } from "../chunk-MDPSJR45.js";
23
23
  import "../chunk-BSZYIAZL.js";
24
24
  import "../chunk-SAF6HGAA.js";
25
25
  import "../chunk-7QLSKOSU.js";
26
26
  import {
27
27
  redactSecrets
28
- } from "../chunk-TJJBF73A.js";
28
+ } from "../chunk-KJFKEKTC.js";
29
29
  import {
30
30
  getMachineId
31
31
  } from "../chunk-RN3NOEJF.js";
@@ -2,16 +2,16 @@
2
2
  import {
3
3
  removeClaudeMcpServers,
4
4
  removePusharySettings
5
- } from "../chunk-3CBPY2G5.js";
5
+ } from "../chunk-FCB6J5YC.js";
6
6
  import {
7
7
  removeInstructionBlock,
8
8
  shortenHome,
9
9
  unregisterPluginLocation,
10
10
  vscodeSettingsTargets
11
- } from "../chunk-IZA7SWXX.js";
11
+ } from "../chunk-EQJZS2LE.js";
12
12
  import {
13
13
  removeGeminiSettings
14
- } from "../chunk-CC2K2SST.js";
14
+ } from "../chunk-PXE6HXRP.js";
15
15
  import {
16
16
  claudeJson,
17
17
  claudeSettings,
@@ -29,7 +29,7 @@ import {
29
29
  pusharyDir,
30
30
  removeCodexHooks,
31
31
  vscodePluginDir
32
- } from "../chunk-QCYN5VXB.js";
32
+ } from "../chunk-TNG3EWFN.js";
33
33
  import {
34
34
  removeClaudeAlias
35
35
  } from "../chunk-BC3VCZ3E.js";
@@ -44,7 +44,7 @@ import {
44
44
  } from "../chunk-BBK3TTU2.js";
45
45
  import "../chunk-7OYGFJYZ.js";
46
46
  import "../chunk-7QLSKOSU.js";
47
- import "../chunk-TJJBF73A.js";
47
+ import "../chunk-KJFKEKTC.js";
48
48
  import {
49
49
  EXIT
50
50
  } from "../chunk-KZERVKTD.js";
@@ -4,7 +4,7 @@ import {
4
4
  denyReasonFrom,
5
5
  isDeferAnswer,
6
6
  resolveGate
7
- } from "../chunk-FWWBEB6L.js";
7
+ } from "../chunk-QVOJF23R.js";
8
8
  import {
9
9
  CODEX_AGENT,
10
10
  DEFAULT_SESSION,
@@ -35,11 +35,11 @@ import {
35
35
  toPolicyLookup,
36
36
  toPolicyLookups,
37
37
  waitForAnswer
38
- } from "../chunk-HPDLDQC5.js";
38
+ } from "../chunk-MDPSJR45.js";
39
39
  import {
40
40
  isGatingMoment,
41
41
  recordKeylessMoment
42
- } from "../chunk-IA5GBKNL.js";
42
+ } from "../chunk-HAP7UTZS.js";
43
43
  import "../chunk-BSZYIAZL.js";
44
44
  import "../chunk-SAF6HGAA.js";
45
45
  import "../chunk-7QLSKOSU.js";
@@ -48,7 +48,7 @@ import {
48
48
  effectiveWaitSeconds,
49
49
  hookWaitClamped,
50
50
  hookWaitDeadline
51
- } from "../chunk-TJJBF73A.js";
51
+ } from "../chunk-KJFKEKTC.js";
52
52
  import {
53
53
  getMachineId
54
54
  } from "../chunk-RN3NOEJF.js";
@@ -3,11 +3,11 @@ import {
3
3
  askUser,
4
4
  reportEvent,
5
5
  waitForAnswer
6
- } from "../chunk-HPDLDQC5.js";
6
+ } from "../chunk-MDPSJR45.js";
7
7
  import "../chunk-BSZYIAZL.js";
8
8
  import "../chunk-SAF6HGAA.js";
9
9
  import "../chunk-7QLSKOSU.js";
10
- import "../chunk-TJJBF73A.js";
10
+ import "../chunk-KJFKEKTC.js";
11
11
  import {
12
12
  getMachineId
13
13
  } from "../chunk-RN3NOEJF.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  printKeyCheck
4
- } from "../chunk-7BBUTWBD.js";
4
+ } from "../chunk-VDHV6KAS.js";
5
5
  import {
6
6
  confirmAppConnection,
7
7
  connectDevice,
@@ -14,7 +14,7 @@ import {
14
14
  import "../chunk-6MTNS63X.js";
15
15
  import {
16
16
  checkApiKey
17
- } from "../chunk-DLBW37U6.js";
17
+ } from "../chunk-NH7RW736.js";
18
18
  import {
19
19
  createIo
20
20
  } from "../chunk-TX7KBKT7.js";
@@ -31,7 +31,7 @@ import "../chunk-SAF6HGAA.js";
31
31
  import {
32
32
  UsageError
33
33
  } from "../chunk-7QLSKOSU.js";
34
- import "../chunk-TJJBF73A.js";
34
+ import "../chunk-KJFKEKTC.js";
35
35
  import "../chunk-2UMNXADU.js";
36
36
  import {
37
37
  EXIT
@@ -6,7 +6,7 @@ import {
6
6
  claudeWired,
7
7
  codexWired,
8
8
  geminiWired
9
- } from "../chunk-46UEJXQO.js";
9
+ } from "../chunk-5Q64QDCR.js";
10
10
  import {
11
11
  agentProbes,
12
12
  detectAgent,
@@ -15,12 +15,12 @@ import {
15
15
  isDetected,
16
16
  isPluginRegistered,
17
17
  vscodeSettingsTargets
18
- } from "../chunk-IZA7SWXX.js";
18
+ } from "../chunk-EQJZS2LE.js";
19
19
  import {
20
20
  GEMINI_HOOK_BINARY,
21
21
  hasGeminiHooks,
22
22
  missingGeminiHookEvents
23
- } from "../chunk-CC2K2SST.js";
23
+ } from "../chunk-PXE6HXRP.js";
24
24
  import {
25
25
  claudeJson,
26
26
  claudeSettings,
@@ -39,7 +39,7 @@ import {
39
39
  readCodexMcpAuth,
40
40
  untrustedCodexHookEvents,
41
41
  vscodePluginDir
42
- } from "../chunk-QCYN5VXB.js";
42
+ } from "../chunk-TNG3EWFN.js";
43
43
  import {
44
44
  describeReach,
45
45
  fetchChannels,
@@ -54,7 +54,7 @@ import "../chunk-6MTNS63X.js";
54
54
  import {
55
55
  checkApiKey,
56
56
  describeKeyCheck
57
- } from "../chunk-DLBW37U6.js";
57
+ } from "../chunk-NH7RW736.js";
58
58
  import {
59
59
  createIo
60
60
  } from "../chunk-TX7KBKT7.js";
@@ -73,7 +73,7 @@ import {
73
73
  } from "../chunk-7OYGFJYZ.js";
74
74
  import {
75
75
  readLedgerSummary
76
- } from "../chunk-IA5GBKNL.js";
76
+ } from "../chunk-HAP7UTZS.js";
77
77
  import {
78
78
  callMcpTool,
79
79
  sendMcpRequest
@@ -82,7 +82,7 @@ import "../chunk-SAF6HGAA.js";
82
82
  import {
83
83
  UsageError
84
84
  } from "../chunk-7QLSKOSU.js";
85
- import "../chunk-TJJBF73A.js";
85
+ import "../chunk-KJFKEKTC.js";
86
86
  import {
87
87
  getMachineId
88
88
  } from "../chunk-RN3NOEJF.js";
@@ -4,7 +4,7 @@ import {
4
4
  denyReasonFrom,
5
5
  isDeferAnswer,
6
6
  resolveGate
7
- } from "../chunk-FWWBEB6L.js";
7
+ } from "../chunk-QVOJF23R.js";
8
8
  import {
9
9
  DEFAULT_SESSION,
10
10
  askUser,
@@ -26,11 +26,11 @@ import {
26
26
  scopePathFor,
27
27
  sendNotification,
28
28
  waitForAnswer
29
- } from "../chunk-HPDLDQC5.js";
29
+ } from "../chunk-MDPSJR45.js";
30
30
  import {
31
31
  isGatingMoment,
32
32
  recordKeylessMoment
33
- } from "../chunk-IA5GBKNL.js";
33
+ } from "../chunk-HAP7UTZS.js";
34
34
  import "../chunk-BSZYIAZL.js";
35
35
  import "../chunk-SAF6HGAA.js";
36
36
  import "../chunk-7QLSKOSU.js";
@@ -39,7 +39,7 @@ import {
39
39
  effectiveWaitSeconds,
40
40
  hookWaitClamped,
41
41
  hookWaitDeadline
42
- } from "../chunk-TJJBF73A.js";
42
+ } from "../chunk-KJFKEKTC.js";
43
43
  import {
44
44
  getMachineId
45
45
  } from "../chunk-RN3NOEJF.js";
@@ -1,19 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePreToolUse
4
- } from "../chunk-MY4VJPWW.js";
5
- import "../chunk-3CBPY2G5.js";
4
+ } from "../chunk-IXZMT6IS.js";
5
+ import "../chunk-FCB6J5YC.js";
6
6
  import {
7
7
  exitOnHelpFlag
8
8
  } from "../chunk-BBK3TTU2.js";
9
9
  import "../chunk-7OYGFJYZ.js";
10
- import "../chunk-FWWBEB6L.js";
11
- import "../chunk-HPDLDQC5.js";
12
- import "../chunk-IA5GBKNL.js";
10
+ import "../chunk-QVOJF23R.js";
11
+ import "../chunk-MDPSJR45.js";
12
+ import "../chunk-HAP7UTZS.js";
13
13
  import "../chunk-BSZYIAZL.js";
14
14
  import "../chunk-SAF6HGAA.js";
15
15
  import "../chunk-7QLSKOSU.js";
16
- import "../chunk-TJJBF73A.js";
16
+ import "../chunk-KJFKEKTC.js";
17
17
  import "../chunk-RN3NOEJF.js";
18
18
  import "../chunk-2UMNXADU.js";
19
19
  import "../chunk-KZERVKTD.js";
@@ -11,7 +11,7 @@ import "../chunk-6MTNS63X.js";
11
11
  import {
12
12
  checkApiKey,
13
13
  describeKeyCheck
14
- } from "../chunk-DLBW37U6.js";
14
+ } from "../chunk-NH7RW736.js";
15
15
  import {
16
16
  createIo
17
17
  } from "../chunk-TX7KBKT7.js";
@@ -31,7 +31,7 @@ import {
31
31
  } from "../chunk-7QLSKOSU.js";
32
32
  import {
33
33
  isValidApiKey
34
- } from "../chunk-TJJBF73A.js";
34
+ } from "../chunk-KJFKEKTC.js";
35
35
  import "../chunk-2UMNXADU.js";
36
36
  import {
37
37
  EXIT
@@ -4,7 +4,7 @@ import {
4
4
  codexConfigToml,
5
5
  cursorUserMcp,
6
6
  geminiSettings
7
- } from "../chunk-QCYN5VXB.js";
7
+ } from "../chunk-TNG3EWFN.js";
8
8
  import {
9
9
  clearKey,
10
10
  readKeySource
@@ -24,7 +24,7 @@ import "../chunk-7OYGFJYZ.js";
24
24
  import {
25
25
  UsageError
26
26
  } from "../chunk-7QLSKOSU.js";
27
- import "../chunk-TJJBF73A.js";
27
+ import "../chunk-KJFKEKTC.js";
28
28
  import {
29
29
  getBaseUrl
30
30
  } from "../chunk-2UMNXADU.js";
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  exitOnFailedResponse
4
- } from "../chunk-7BBUTWBD.js";
5
- import "../chunk-DLBW37U6.js";
4
+ } from "../chunk-VDHV6KAS.js";
5
+ import "../chunk-NH7RW736.js";
6
6
  import {
7
7
  createIo
8
8
  } from "../chunk-TX7KBKT7.js";
@@ -17,7 +17,7 @@ import "../chunk-SAF6HGAA.js";
17
17
  import {
18
18
  UsageError
19
19
  } from "../chunk-7QLSKOSU.js";
20
- import "../chunk-TJJBF73A.js";
20
+ import "../chunk-KJFKEKTC.js";
21
21
  import {
22
22
  getApiKey,
23
23
  getBaseUrl
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleNotification
4
- } from "../chunk-HPDLDQC5.js";
4
+ } from "../chunk-MDPSJR45.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
8
- import "../chunk-TJJBF73A.js";
8
+ import "../chunk-KJFKEKTC.js";
9
9
  import "../chunk-RN3NOEJF.js";
10
10
  import "../chunk-2UMNXADU.js";
11
11
  import "../chunk-KZERVKTD.js";
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePermissionDenied
4
- } from "../chunk-MY4VJPWW.js";
5
- import "../chunk-3CBPY2G5.js";
6
- import "../chunk-FWWBEB6L.js";
7
- import "../chunk-HPDLDQC5.js";
8
- import "../chunk-IA5GBKNL.js";
4
+ } from "../chunk-IXZMT6IS.js";
5
+ import "../chunk-FCB6J5YC.js";
6
+ import "../chunk-QVOJF23R.js";
7
+ import "../chunk-MDPSJR45.js";
8
+ import "../chunk-HAP7UTZS.js";
9
9
  import "../chunk-BSZYIAZL.js";
10
10
  import "../chunk-SAF6HGAA.js";
11
11
  import "../chunk-7QLSKOSU.js";
12
- import "../chunk-TJJBF73A.js";
12
+ import "../chunk-KJFKEKTC.js";
13
13
  import "../chunk-RN3NOEJF.js";
14
14
  import "../chunk-2UMNXADU.js";
15
15
  import "../chunk-KZERVKTD.js";
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePermissionRequest
4
- } from "../chunk-MY4VJPWW.js";
5
- import "../chunk-3CBPY2G5.js";
6
- import "../chunk-FWWBEB6L.js";
7
- import "../chunk-HPDLDQC5.js";
8
- import "../chunk-IA5GBKNL.js";
4
+ } from "../chunk-IXZMT6IS.js";
5
+ import "../chunk-FCB6J5YC.js";
6
+ import "../chunk-QVOJF23R.js";
7
+ import "../chunk-MDPSJR45.js";
8
+ import "../chunk-HAP7UTZS.js";
9
9
  import "../chunk-BSZYIAZL.js";
10
10
  import "../chunk-SAF6HGAA.js";
11
11
  import "../chunk-7QLSKOSU.js";
12
- import "../chunk-TJJBF73A.js";
12
+ import "../chunk-KJFKEKTC.js";
13
13
  import "../chunk-RN3NOEJF.js";
14
14
  import "../chunk-2UMNXADU.js";
15
15
  import "../chunk-KZERVKTD.js";
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePostToolUse
4
- } from "../chunk-HPDLDQC5.js";
4
+ } from "../chunk-MDPSJR45.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
8
- import "../chunk-TJJBF73A.js";
8
+ import "../chunk-KJFKEKTC.js";
9
9
  import "../chunk-RN3NOEJF.js";
10
10
  import "../chunk-2UMNXADU.js";
11
11
  import "../chunk-KZERVKTD.js";
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleUserPrompt
4
- } from "../chunk-HPDLDQC5.js";
4
+ } from "../chunk-MDPSJR45.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
8
- import "../chunk-TJJBF73A.js";
8
+ import "../chunk-KJFKEKTC.js";
9
9
  import "../chunk-RN3NOEJF.js";
10
10
  import "../chunk-2UMNXADU.js";
11
11
  import "../chunk-KZERVKTD.js";
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleSessionEnd
4
- } from "../chunk-HPDLDQC5.js";
4
+ } from "../chunk-MDPSJR45.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
8
- import "../chunk-TJJBF73A.js";
8
+ import "../chunk-KJFKEKTC.js";
9
9
  import "../chunk-RN3NOEJF.js";
10
10
  import "../chunk-2UMNXADU.js";
11
11
  import "../chunk-KZERVKTD.js";
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleSessionStart
4
- } from "../chunk-HPDLDQC5.js";
4
+ } from "../chunk-MDPSJR45.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
8
- import "../chunk-TJJBF73A.js";
8
+ import "../chunk-KJFKEKTC.js";
9
9
  import "../chunk-RN3NOEJF.js";
10
10
  import "../chunk-2UMNXADU.js";
11
11
  import "../chunk-KZERVKTD.js";
@@ -6,12 +6,12 @@ import {
6
6
  addClaudeMcpServer,
7
7
  addPusharyHooks,
8
8
  addPusharyToolPermissions
9
- } from "../chunk-3CBPY2G5.js";
9
+ } from "../chunk-FCB6J5YC.js";
10
10
  import {
11
11
  claudeWired,
12
12
  codexWired,
13
13
  geminiWired
14
- } from "../chunk-46UEJXQO.js";
14
+ } from "../chunk-5Q64QDCR.js";
15
15
  import {
16
16
  describeDetection,
17
17
  detectAllAgents,
@@ -23,12 +23,12 @@ import {
23
23
  shortenHome,
24
24
  vscodeSettingsTargets,
25
25
  writeInstructionBlock
26
- } from "../chunk-IZA7SWXX.js";
26
+ } from "../chunk-EQJZS2LE.js";
27
27
  import {
28
28
  GEMINI_HOOK_BINARY,
29
29
  addGeminiHooks,
30
30
  addGeminiMcpServer
31
- } from "../chunk-CC2K2SST.js";
31
+ } from "../chunk-PXE6HXRP.js";
32
32
  import {
33
33
  addCodexHookTrust,
34
34
  addCodexHooks,
@@ -46,7 +46,7 @@ import {
46
46
  geminiSettings,
47
47
  pusharyConfigFile,
48
48
  vscodePluginDir
49
- } from "../chunk-QCYN5VXB.js";
49
+ } from "../chunk-TNG3EWFN.js";
50
50
  import {
51
51
  confirmAppConnection,
52
52
  connectDevice,
@@ -72,7 +72,7 @@ import {
72
72
  import {
73
73
  checkApiKey,
74
74
  describeKeyCheck
75
- } from "../chunk-DLBW37U6.js";
75
+ } from "../chunk-NH7RW736.js";
76
76
  import {
77
77
  installClaudeAlias,
78
78
  resolveShellRc
@@ -94,7 +94,7 @@ import {
94
94
  } from "../chunk-7OYGFJYZ.js";
95
95
  import {
96
96
  reportEvent
97
- } from "../chunk-HPDLDQC5.js";
97
+ } from "../chunk-MDPSJR45.js";
98
98
  import "../chunk-BSZYIAZL.js";
99
99
  import "../chunk-SAF6HGAA.js";
100
100
  import {
@@ -102,7 +102,7 @@ import {
102
102
  } from "../chunk-7QLSKOSU.js";
103
103
  import {
104
104
  isValidApiKey
105
- } from "../chunk-TJJBF73A.js";
105
+ } from "../chunk-KJFKEKTC.js";
106
106
  import "../chunk-RN3NOEJF.js";
107
107
  import "../chunk-2UMNXADU.js";
108
108
  import {
@@ -5,8 +5,8 @@ import {
5
5
  import "../chunk-7OYGFJYZ.js";
6
6
  import {
7
7
  readLedgerSummary
8
- } from "../chunk-IA5GBKNL.js";
9
- import "../chunk-TJJBF73A.js";
8
+ } from "../chunk-HAP7UTZS.js";
9
+ import "../chunk-KJFKEKTC.js";
10
10
  import {
11
11
  getApiKey
12
12
  } from "../chunk-2UMNXADU.js";
@@ -40,5 +40,5 @@ if (connected) {
40
40
  console.log("A key is configured now, so new moments reach your phone instead of waiting in the terminal.");
41
41
  } else {
42
42
  console.log("Each of those sat in the terminal until you noticed. With Pushary they land on your lock screen as a yes or no.");
43
- console.log("7-day trial: https://pushary.com/sign-up?utm_source=cli&utm_medium=stats");
43
+ console.log("3-day trial: https://pushary.com/sign-up?utm_source=cli&utm_medium=stats");
44
44
  }
@@ -16,7 +16,7 @@ import "../chunk-6MTNS63X.js";
16
16
  import {
17
17
  checkApiKey,
18
18
  describeKeyCheck
19
- } from "../chunk-DLBW37U6.js";
19
+ } from "../chunk-NH7RW736.js";
20
20
  import {
21
21
  createIo
22
22
  } from "../chunk-TX7KBKT7.js";
@@ -33,7 +33,7 @@ import "../chunk-SAF6HGAA.js";
33
33
  import {
34
34
  UsageError
35
35
  } from "../chunk-7QLSKOSU.js";
36
- import "../chunk-TJJBF73A.js";
36
+ import "../chunk-KJFKEKTC.js";
37
37
  import "../chunk-RN3NOEJF.js";
38
38
  import "../chunk-2UMNXADU.js";
39
39
  import {
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleStop
4
- } from "../chunk-HPDLDQC5.js";
4
+ } from "../chunk-MDPSJR45.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
8
- import "../chunk-TJJBF73A.js";
8
+ import "../chunk-KJFKEKTC.js";
9
9
  import "../chunk-RN3NOEJF.js";
10
10
  import "../chunk-2UMNXADU.js";
11
11
  import "../chunk-KZERVKTD.js";
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleStopFailure
4
- } from "../chunk-HPDLDQC5.js";
4
+ } from "../chunk-MDPSJR45.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
8
- import "../chunk-TJJBF73A.js";
8
+ import "../chunk-KJFKEKTC.js";
9
9
  import "../chunk-RN3NOEJF.js";
10
10
  import "../chunk-2UMNXADU.js";
11
11
  import "../chunk-KZERVKTD.js";
@@ -3,13 +3,13 @@ import {
3
3
  addClaudeMcpServer,
4
4
  addPusharyHooks,
5
5
  addPusharyToolPermissions
6
- } from "../chunk-3CBPY2G5.js";
6
+ } from "../chunk-FCB6J5YC.js";
7
7
  import {
8
8
  GEMINI_HOOK_BINARY,
9
9
  addGeminiHooks,
10
10
  addGeminiMcpServer,
11
11
  hasGeminiHooks
12
- } from "../chunk-CC2K2SST.js";
12
+ } from "../chunk-PXE6HXRP.js";
13
13
  import {
14
14
  CODEX_HOOK_BINARY,
15
15
  addCodexHookTrust,
@@ -23,7 +23,7 @@ import {
23
23
  hasCodexHooks,
24
24
  vscodePluginDir,
25
25
  vscodePluginMcp
26
- } from "../chunk-QCYN5VXB.js";
26
+ } from "../chunk-TNG3EWFN.js";
27
27
  import {
28
28
  readJsonSafe
29
29
  } from "../chunk-6MTNS63X.js";
@@ -40,7 +40,7 @@ import {
40
40
  import {
41
41
  isNewerVersion
42
42
  } from "../chunk-7OYGFJYZ.js";
43
- import "../chunk-TJJBF73A.js";
43
+ import "../chunk-KJFKEKTC.js";
44
44
  import {
45
45
  getApiKey
46
46
  } from "../chunk-2UMNXADU.js";
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  exitOnFailedResponse
4
- } from "../chunk-7BBUTWBD.js";
4
+ } from "../chunk-VDHV6KAS.js";
5
5
  import {
6
6
  describeWaitLadder
7
7
  } from "../chunk-IIENZE2J.js";
8
- import "../chunk-DLBW37U6.js";
8
+ import "../chunk-NH7RW736.js";
9
9
  import {
10
10
  createIo
11
11
  } from "../chunk-TX7KBKT7.js";
@@ -20,7 +20,7 @@ import "../chunk-SAF6HGAA.js";
20
20
  import {
21
21
  UsageError
22
22
  } from "../chunk-7QLSKOSU.js";
23
- import "../chunk-TJJBF73A.js";
23
+ import "../chunk-KJFKEKTC.js";
24
24
  import {
25
25
  getApiKey,
26
26
  getBaseUrl
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  hasGeminiHooks
3
- } from "./chunk-CC2K2SST.js";
3
+ } from "./chunk-PXE6HXRP.js";
4
4
  import {
5
5
  hasCodexHooks
6
- } from "./chunk-QCYN5VXB.js";
6
+ } from "./chunk-TNG3EWFN.js";
7
7
 
8
8
  // src/diagnostics/wiring.ts
9
9
  var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  codexHomeFrom
3
- } from "./chunk-QCYN5VXB.js";
3
+ } from "./chunk-TNG3EWFN.js";
4
4
 
5
5
  // src/vscode-config.ts
6
6
  import { homedir } from "os";
@@ -255,13 +255,13 @@ You have Pushary MCP tools that reach the user on their phone. Use them proactiv
255
255
  - Before any risky or irreversible step (deleting files, force pushing, spending money, sending external messages), call \`ask_user\` with type "confirm" and wait for approval.
256
256
  - Before starting a multi-step run that will change several files, call \`propose_scope\` once with the paths you expect to change, anything you promise not to touch, and what done means. The user agrees to the boundary in one tap, and after that only work outside it needs approving. Skip it for a single quick edit, and do not propose a new scope mid-run just to widen one: if you need to go outside the agreed scope, do the work and let the approval that follows widen it.
257
257
  - When you are blocked, stuck, or hit an error you cannot resolve on your own, call \`send_notification\` so the user knows, and call \`ask_user\` if you need a decision to continue.
258
- - When a task that took several steps finishes, call \`send_notification\` so the user knows it is done.
258
+ - When a task that took several steps finishes, call \`send_notification\` so the user knows it is done. Always pass \`context\` with a \`type\` of "task_complete", "error" or "info": it is what tells Pushary this is a task update, so the user's own setting for where updates land can route it.
259
259
  - Use \`cancel_question\` to retract a pending question once it is no longer needed.
260
260
  - Respect the user's Pushary delivery mode: it decides where an approval is surfaced (phone, terminal, or awareness only), not whether it is required. In Terminal mode do not expect a phone answer; the approval waits in the terminal. If the Pushary hook already gated an action, a single approval is enough, do not ask again.
261
261
 
262
262
  Pass \`agentName\` as "${label} - <project folder name>" so the user knows which session is asking. If a question times out with no answer, retry once with a longer timeout before falling back to asking in the terminal.`;
263
263
  var renderAgentInstructions = (label) => instructionBody(label);
264
- var KEYLESS_FALLBACK_LINE = "This repo uses Pushary phone approvals. Your teammates get agent questions on their lock screens; you do not have a key yet, so questions will fall back to the terminal. Get your own key (7-day trial): https://pushary.com/sign-up?utm_source=agents-md&utm_medium=teammate";
264
+ var KEYLESS_FALLBACK_LINE = "This repo uses Pushary phone approvals. Your teammates get agent questions on their lock screens; you do not have a key yet, so questions will fall back to the terminal. Get your own key (3-day trial): https://pushary.com/sign-up?utm_source=agents-md&utm_medium=teammate";
265
265
  var renderProjectAgentInstructions = (label) => `${instructionBody(label)}
266
266
 
267
267
  If this environment has no Pushary API key (no PUSHARY_API_KEY and no key in ~/.pushary/config.json), the tools above are unavailable in this session. In that case, treat the following as a statement of fact about this session and continue in the terminal: ${KEYLESS_FALLBACK_LINE}`;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  HOOK_BUDGETS
3
- } from "./chunk-TJJBF73A.js";
3
+ } from "./chunk-KJFKEKTC.js";
4
4
 
5
5
  // src/claude-config.ts
6
6
  import { join } from "path";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isSafeReadOnlyCommand
3
- } from "./chunk-TJJBF73A.js";
3
+ } from "./chunk-KJFKEKTC.js";
4
4
 
5
5
  // src/ledger.ts
6
6
  import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync } from "fs";
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  PRETOOLUSE_HANDLED_TOOLS
3
- } from "./chunk-3CBPY2G5.js";
3
+ } from "./chunk-FCB6J5YC.js";
4
4
  import {
5
5
  denyReasonFrom,
6
6
  isDeferAnswer,
7
7
  resolveGate
8
- } from "./chunk-FWWBEB6L.js";
8
+ } from "./chunk-QVOJF23R.js";
9
9
  import {
10
10
  DEFAULT_SESSION,
11
11
  askUser,
@@ -25,17 +25,17 @@ import {
25
25
  sendNotification,
26
26
  throttlePass,
27
27
  waitForAnswer
28
- } from "./chunk-HPDLDQC5.js";
28
+ } from "./chunk-MDPSJR45.js";
29
29
  import {
30
30
  isGatingMoment,
31
31
  recordKeylessMoment
32
- } from "./chunk-IA5GBKNL.js";
32
+ } from "./chunk-HAP7UTZS.js";
33
33
  import {
34
34
  buildDecisionEpisodeFeatures,
35
35
  effectiveWaitSeconds,
36
36
  hookWaitClamped,
37
37
  hookWaitDeadline
38
- } from "./chunk-TJJBF73A.js";
38
+ } from "./chunk-KJFKEKTC.js";
39
39
  import {
40
40
  getMachineId
41
41
  } from "./chunk-RN3NOEJF.js";
@@ -345,47 +345,66 @@ var shouldDeferToNativeMode = (permissionMode, toolName) => {
345
345
  }
346
346
  return false;
347
347
  };
348
- var parseSingleQuestion = (toolInput) => {
349
- const questions = toolInput.questions;
350
- if (!Array.isArray(questions) || questions.length !== 1) return void 0;
351
- const q = questions[0];
348
+ var MAX_PHONE_QUESTIONS = 4;
349
+ var parseQuestion = (raw) => {
350
+ const q = raw;
352
351
  if (!q || typeof q.question !== "string" || q.multiSelect === true) return void 0;
353
352
  const labels = Array.isArray(q.options) ? q.options.map((o) => o && typeof o === "object" ? o.label : void 0).filter((l) => typeof l === "string" && l.length > 0) : [];
354
353
  if (labels.length < 2) return void 0;
355
354
  return { question: q.question, header: typeof q.header === "string" ? q.header : void 0, labels };
356
355
  };
356
+ var parseQuestions = (toolInput) => {
357
+ const questions = toolInput.questions;
358
+ if (!Array.isArray(questions) || questions.length === 0) return void 0;
359
+ if (questions.length > MAX_PHONE_QUESTIONS) return void 0;
360
+ const parsed = [];
361
+ for (const raw of questions) {
362
+ const one = parseQuestion(raw);
363
+ if (!one) return void 0;
364
+ parsed.push(one);
365
+ }
366
+ return parsed;
367
+ };
368
+ var questionContext = (q, index, total, project) => {
369
+ const subject = q.header ? `${q.header}: your agent is asking in ${project}` : `Your agent is asking in ${project}`;
370
+ return total > 1 ? `${subject} (${index + 1} of ${total})` : subject;
371
+ };
357
372
  var handleAskUserQuestion = async (apiKey, input) => {
358
- const parsed = parseSingleQuestion(input.tool_input ?? {});
373
+ const parsed = parseQuestions(input.tool_input ?? {});
359
374
  if (!parsed) return void 0;
360
375
  const projectName = basename(input.cwd ?? process.cwd());
361
- let result;
362
- try {
363
- result = await askUser(apiKey, {
364
- question: parsed.question,
365
- type: "select",
366
- options: [...parsed.labels],
367
- context: parsed.header ? `${parsed.header}: your agent is asking in ${projectName}` : `Your agent is asking in ${projectName}`,
368
- agentName: `Claude Code - ${projectName}`,
369
- sessionId: input.session_id,
370
- machineId: getMachineId(),
371
- toolName: "AskUserQuestion"
372
- });
373
- } catch {
374
- return void 0;
375
- }
376
- if (result.suppressed || result.noDevices) {
377
- await cancelQuestion(apiKey, result.correlationId).catch(() => {
378
- });
379
- return void 0;
380
- }
381
376
  const deadline = hookWaitDeadline(START_MS, effectiveWaitSeconds("wait", 0, "claude"), "claude", Date.now());
382
- const answer = await pollForAnswer(apiKey, result.correlationId, deadline);
383
- const value = answer.answered ? (answer.value ?? "").trim() : "";
384
- if (!value || isDeferAnswer(answer.value)) {
385
- savePendingQuestion(input.session_id || DEFAULT_SESSION, result.correlationId);
386
- return void 0;
377
+ const answers = {};
378
+ for (const [index, question] of parsed.entries()) {
379
+ let result;
380
+ try {
381
+ result = await askUser(apiKey, {
382
+ question: question.question,
383
+ type: "select",
384
+ options: [...question.labels],
385
+ context: questionContext(question, index, parsed.length, projectName),
386
+ agentName: `Claude Code - ${projectName}`,
387
+ sessionId: input.session_id,
388
+ machineId: getMachineId(),
389
+ toolName: "AskUserQuestion"
390
+ });
391
+ } catch {
392
+ return void 0;
393
+ }
394
+ if (result.suppressed || result.noDevices) {
395
+ await cancelQuestion(apiKey, result.correlationId).catch(() => {
396
+ });
397
+ return void 0;
398
+ }
399
+ const answer = await pollForAnswer(apiKey, result.correlationId, deadline);
400
+ const value = answer.answered ? (answer.value ?? "").trim() : "";
401
+ if (!value || isDeferAnswer(answer.value)) {
402
+ savePendingQuestion(input.session_id || DEFAULT_SESSION, result.correlationId);
403
+ return void 0;
404
+ }
405
+ answers[question.question] = value;
387
406
  }
388
- return allowWithInput({ ...input.tool_input ?? {}, answers: { [parsed.question]: value } });
407
+ return allowWithInput({ ...input.tool_input ?? {}, answers });
389
408
  };
390
409
  var handleKeyless = (input) => {
391
410
  try {
@@ -20,7 +20,7 @@ import {
20
20
  policyArgForms,
21
21
  redactSecrets,
22
22
  redactSecretsDeep
23
- } from "./chunk-TJJBF73A.js";
23
+ } from "./chunk-KJFKEKTC.js";
24
24
  import {
25
25
  getMachineId
26
26
  } from "./chunk-RN3NOEJF.js";
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-7QLSKOSU.js";
7
7
  import {
8
8
  isValidApiKey
9
- } from "./chunk-TJJBF73A.js";
9
+ } from "./chunk-KJFKEKTC.js";
10
10
  import {
11
11
  getBaseUrl
12
12
  } from "./chunk-2UMNXADU.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  HOOK_BUDGETS
3
- } from "./chunk-TJJBF73A.js";
3
+ } from "./chunk-KJFKEKTC.js";
4
4
 
5
5
  // src/gemini-config.ts
6
6
  var GEMINI_HOOK_BINARY = "pushary-gemini-hook";
@@ -4,12 +4,12 @@ import {
4
4
  isModeStateDegraded,
5
5
  resolveAutoResolveOrigin,
6
6
  resolvePolicyAcross
7
- } from "./chunk-HPDLDQC5.js";
7
+ } from "./chunk-MDPSJR45.js";
8
8
  import {
9
9
  evaluateScope,
10
10
  scopeChangeReason,
11
11
  scopeRequiresHuman
12
- } from "./chunk-TJJBF73A.js";
12
+ } from "./chunk-KJFKEKTC.js";
13
13
 
14
14
  // src/answer.ts
15
15
  var denyReasonFrom = (value, note) => {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  HOOK_BUDGETS
3
- } from "./chunk-TJJBF73A.js";
3
+ } from "./chunk-KJFKEKTC.js";
4
4
 
5
5
  // src/codex-config.ts
6
6
  import { createHash } from "crypto";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  describeKeyCheck,
3
3
  keyCheckFromResponse
4
- } from "./chunk-DLBW37U6.js";
4
+ } from "./chunk-NH7RW736.js";
5
5
  import {
6
6
  createIo
7
7
  } from "./chunk-TX7KBKT7.js";
package/dist/src/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  handlePreToolUse
3
- } from "../chunk-MY4VJPWW.js";
4
- import "../chunk-3CBPY2G5.js";
5
- import "../chunk-FWWBEB6L.js";
3
+ } from "../chunk-IXZMT6IS.js";
4
+ import "../chunk-FCB6J5YC.js";
5
+ import "../chunk-QVOJF23R.js";
6
6
  import {
7
7
  askUser,
8
8
  cancelQuestion,
@@ -15,12 +15,12 @@ import {
15
15
  reportEvent,
16
16
  resolvePolicy,
17
17
  waitForAnswer
18
- } from "../chunk-HPDLDQC5.js";
19
- import "../chunk-IA5GBKNL.js";
18
+ } from "../chunk-MDPSJR45.js";
19
+ import "../chunk-HAP7UTZS.js";
20
20
  import "../chunk-BSZYIAZL.js";
21
21
  import "../chunk-SAF6HGAA.js";
22
22
  import "../chunk-7QLSKOSU.js";
23
- import "../chunk-TJJBF73A.js";
23
+ import "../chunk-KJFKEKTC.js";
24
24
  import "../chunk-RN3NOEJF.js";
25
25
  import {
26
26
  getApiKey,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushary/agent-hooks",
3
- "version": "0.77.0",
3
+ "version": "0.79.0",
4
4
  "description": "Permission hooks for AI coding agents: route tool approvals through Pushary push notifications",
5
5
  "keywords": [
6
6
  "pushary",
File without changes