@pushary/agent-hooks 1.9.7 → 1.9.9

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 (111) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +3 -3
  3. package/data/cursor-plugin/README.md +3 -7
  4. package/data/vscode-plugin/README.md +1 -1
  5. package/dist/bin/pushary-bell-hook.js +22 -24
  6. package/dist/bin/pushary-bell.js +13 -13
  7. package/dist/bin/pushary-claude.js +28 -30
  8. package/dist/bin/pushary-clean.js +113 -94
  9. package/dist/bin/pushary-codex-bridge.js +20 -20
  10. package/dist/bin/pushary-codex-hook.js +36 -38
  11. package/dist/bin/pushary-codex.js +13 -13
  12. package/dist/bin/pushary-connect.js +48 -22
  13. package/dist/bin/pushary-cowork.js +5 -5
  14. package/dist/bin/pushary-daemon.js +50 -40
  15. package/dist/bin/pushary-disconnect.js +188 -56
  16. package/dist/bin/pushary-doctor.js +105 -85
  17. package/dist/bin/pushary-elicitation-hook.js +25 -27
  18. package/dist/bin/pushary-gemini-bridge.js +13 -13
  19. package/dist/bin/pushary-gemini-hook.js +31 -33
  20. package/dist/bin/pushary-hook.js +36 -39
  21. package/dist/bin/pushary-login.js +12 -12
  22. package/dist/bin/pushary-logout.js +105 -42
  23. package/dist/bin/pushary-mcp.js +9 -9
  24. package/dist/bin/pushary-mode.js +28 -31
  25. package/dist/bin/pushary-notification-hook.js +29 -32
  26. package/dist/bin/pushary-opencode-hook.js +30 -32
  27. package/dist/bin/pushary-permission-denied-hook.js +30 -33
  28. package/dist/bin/pushary-permission-hook.js +33 -36
  29. package/dist/bin/pushary-post-hook.js +30 -33
  30. package/dist/bin/pushary-prompt-hook.js +29 -32
  31. package/dist/bin/pushary-session-end-hook.js +29 -32
  32. package/dist/bin/pushary-session-start-hook.js +33 -36
  33. package/dist/bin/pushary-setup.js +168 -160
  34. package/dist/bin/pushary-stats.js +5 -5
  35. package/dist/bin/pushary-status.js +65 -19
  36. package/dist/bin/pushary-stop-hook.js +29 -32
  37. package/dist/bin/pushary-stopfailure-hook.js +29 -32
  38. package/dist/bin/pushary-suggestions.js +19 -21
  39. package/dist/bin/pushary-transcript-register.js +18 -20
  40. package/dist/bin/pushary-transcripts.js +7 -7
  41. package/dist/bin/pushary-upgrade.js +50 -26
  42. package/dist/bin/pushary-wait.js +23 -19
  43. package/dist/bin/pushary.js +15 -14
  44. package/dist/{chunk-4FK6RZVJ.js → chunk-462EQA6K.js} +1 -1
  45. package/dist/{chunk-STQRUH3S.js → chunk-5DCDQ5VW.js} +59 -15
  46. package/dist/{chunk-JXISQ7DT.js → chunk-5N5L6DNN.js} +3 -3
  47. package/dist/{chunk-QR6VE5ME.js → chunk-5RGA636G.js} +79 -17
  48. package/dist/{chunk-L76HTPU6.js → chunk-6AYSKVLL.js} +3 -3
  49. package/dist/{chunk-NIBFSARF.js → chunk-6EBGOHDJ.js} +33 -13
  50. package/dist/{chunk-QQ4HBXZC.js → chunk-6W5M3MSE.js} +84 -673
  51. package/dist/{chunk-R3YW55MY.js → chunk-AI7RMFVV.js} +29 -26
  52. package/dist/{chunk-AUUXS44H.js → chunk-APP43AW7.js} +1 -1
  53. package/dist/{chunk-RQGODFQN.js → chunk-AZOKPWVI.js} +1 -1
  54. package/dist/{chunk-3GNUXXDZ.js → chunk-B5NMSP3V.js} +2 -2
  55. package/dist/{chunk-4D2AYNSE.js → chunk-BNSKVIAW.js} +2 -2
  56. package/dist/chunk-BYLKCZ2G.js +367 -0
  57. package/dist/{chunk-X5NXPCIC.js → chunk-BZLHTMT6.js} +89 -7
  58. package/dist/{chunk-BTQGAXZ3.js → chunk-COQ64C4F.js} +10 -10
  59. package/dist/{chunk-N4EUSDKX.js → chunk-DCCSULXK.js} +14 -14
  60. package/dist/{chunk-JWKBDSPF.js → chunk-DP3WX7FW.js} +2 -2
  61. package/dist/chunk-E5HOHIUV.js +52 -0
  62. package/dist/{chunk-GU3EJCVV.js → chunk-EA5NWDK7.js} +4 -0
  63. package/dist/chunk-EIAEUG7G.js +46 -0
  64. package/dist/{chunk-EB4XGVBG.js → chunk-EUW7JL2K.js} +0 -32
  65. package/dist/{chunk-T7Y5EADL.js → chunk-F7R3SZ4Q.js} +2 -2
  66. package/dist/{chunk-H37L7TT3.js → chunk-G7RIDXAT.js} +2 -2
  67. package/dist/{chunk-W2KI5KPD.js → chunk-H5T27W7M.js} +2 -2
  68. package/dist/chunk-HBWYMRR5.js +94 -0
  69. package/dist/{chunk-CBQACHKY.js → chunk-IIVZZMSO.js} +1 -1
  70. package/dist/{chunk-Z6HPS67T.js → chunk-IRHABAQT.js} +1 -1
  71. package/dist/{chunk-QTO6HEZD.js → chunk-K545B734.js} +2 -2
  72. package/dist/{chunk-KYO45G5L.js → chunk-KOWFRUIT.js} +1 -1
  73. package/dist/{chunk-QFEM7R6T.js → chunk-KQFTBQ66.js} +11 -11
  74. package/dist/chunk-LENBKYRB.js +50 -0
  75. package/dist/{chunk-JCWZ23MJ.js → chunk-M3STIAGU.js} +3 -3
  76. package/dist/{chunk-6DJTDHBI.js → chunk-MD4SVNT6.js} +1 -1
  77. package/dist/{chunk-7264S5HZ.js → chunk-MLGIVVSG.js} +1 -1
  78. package/dist/{chunk-H7MMU64M.js → chunk-NGKUXZID.js} +2 -2
  79. package/dist/{chunk-JWQZSYCK.js → chunk-NUVGDBZC.js} +1 -1
  80. package/dist/{chunk-AQ55ZSSS.js → chunk-OAYWO5NP.js} +1 -1
  81. package/dist/chunk-Q6C6ILUS.js +49 -0
  82. package/dist/{chunk-MBK7N46B.js → chunk-QIOIO7VN.js} +6 -6
  83. package/dist/{chunk-KFKL3FHS.js → chunk-QRXPWW3M.js} +4 -3
  84. package/dist/{chunk-7OIWWZAD.js → chunk-QTIUJZRX.js} +3 -3
  85. package/dist/{chunk-XWAYAO3V.js → chunk-R5RIVOPL.js} +2 -2
  86. package/dist/{chunk-ADSQDYYG.js → chunk-REU2VQPH.js} +54 -5
  87. package/dist/{chunk-GKI6LFAV.js → chunk-RQ32ADJP.js} +2 -2
  88. package/dist/{chunk-VXRXFU6Q.js → chunk-SZ4Q6ZVS.js} +14 -7
  89. package/dist/{chunk-KT5E2RLS.js → chunk-T6ZN4TEF.js} +1 -1
  90. package/dist/{chunk-UFVGSEWH.js → chunk-TO3PS646.js} +2 -2
  91. package/dist/chunk-UAP5DS6P.js +599 -0
  92. package/dist/{chunk-MZPXVH4A.js → chunk-UF6RBP5V.js} +204 -28
  93. package/dist/{chunk-AVNKVF7N.js → chunk-UPIZSCYD.js} +4 -4
  94. package/dist/{chunk-3PVDOCFI.js → chunk-VHPFNLRS.js} +5 -5
  95. package/dist/{chunk-HPRZJKRO.js → chunk-VIIHC42X.js} +1 -1
  96. package/dist/{chunk-D6S5EKXA.js → chunk-WRPYCIV2.js} +8 -12
  97. package/dist/{chunk-ZUTU43FT.js → chunk-Z23ZBYDW.js} +6 -4
  98. package/dist/{chunk-SBLPHUEB.js → chunk-ZGADIZDS.js} +8 -6
  99. package/dist/{global-upgrade-E2HUEB4B.js → global-upgrade-H272QOGD.js} +6 -6
  100. package/dist/{paths-QVTEGNZV.js → paths-HMVOTFUN.js} +2 -2
  101. package/dist/reapply-Q5NHDTVU.js +55 -0
  102. package/dist/src/index.d.ts +1 -0
  103. package/dist/src/index.js +19 -20
  104. package/dist/{upgrade-lock-JCIDZMHF.js → upgrade-lock-L3GHFIRW.js} +3 -3
  105. package/package.json +1 -1
  106. package/dist/chunk-4YO4T5FV.js +0 -149
  107. package/dist/chunk-ANEAA37E.js +0 -197
  108. package/dist/chunk-MNWRUGMH.js +0 -86
  109. package/dist/chunk-RQSOEB4S.js +0 -44
  110. package/dist/chunk-SD3272LS.js +0 -143
  111. package/dist/reapply-5QVKM6LA.js +0 -38
@@ -1,106 +1,86 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runBrowserLogin
4
- } from "../chunk-AQ55ZSSS.js";
4
+ } from "../chunk-OAYWO5NP.js";
5
5
  import {
6
6
  coworkOutput,
7
7
  coworkSelection
8
- } from "../chunk-7OIWWZAD.js";
8
+ } from "../chunk-QTIUJZRX.js";
9
9
  import "../chunk-PUZZELE6.js";
10
10
  import {
11
+ clearDeclinedAgent,
12
+ declinedAgentForSetupChoice
13
+ } from "../chunk-EIAEUG7G.js";
14
+ import {
15
+ CURSOR_GATE_SCRIPT,
11
16
  describeVersionManagerPin,
12
17
  versionManagerOf
13
- } from "../chunk-GU3EJCVV.js";
18
+ } from "../chunk-EA5NWDK7.js";
14
19
  import {
15
20
  codexTrustOutcome,
16
21
  describeCodexTrustConfirmation,
17
22
  needsCodexTrustStep
18
- } from "../chunk-JWKBDSPF.js";
23
+ } from "../chunk-DP3WX7FW.js";
19
24
  import {
20
25
  writeStdoutFully
21
26
  } from "../chunk-EO23EUOK.js";
22
27
  import {
23
28
  ensureCodexTrustsPusharyHooks
24
- } from "../chunk-H7MMU64M.js";
29
+ } from "../chunk-NGKUXZID.js";
25
30
  import {
26
31
  readManagedControlEvidence,
27
32
  waitForMachineReadiness
28
- } from "../chunk-MBK7N46B.js";
33
+ } from "../chunk-QIOIO7VN.js";
29
34
  import {
30
35
  describeSetupSideEffects,
31
36
  installAgentSkill,
32
- installSkillViaSkillsCli,
37
+ installSkillViaSkillsCli
38
+ } from "../chunk-EUW7JL2K.js";
39
+ import {
40
+ CURSOR_PLUGIN_BACKUP_INFIX,
41
+ CURSOR_PLUGIN_STAGING_PREFIX,
33
42
  registerCursorGate
34
- } from "../chunk-EB4XGVBG.js";
43
+ } from "../chunk-LENBKYRB.js";
44
+ import {
45
+ HERMES_PIP_PACKAGE,
46
+ describeDetection,
47
+ detectAllAgents,
48
+ isDetected,
49
+ isHermesConfigReceipt,
50
+ pluginLocationSnippet,
51
+ registerPluginLocation,
52
+ resolveHermesPython,
53
+ runHermesConfigScript,
54
+ shortenHome,
55
+ vscodeSettingsTargets
56
+ } from "../chunk-UAP5DS6P.js";
35
57
  import {
36
58
  AgentConfigError,
37
59
  FX_PUSHARY_TOOLS_RULE,
38
60
  FX_QUESTION_TOOL,
39
- FX_TOOL_DISCOVERY_NOTE,
40
- HERMES_PIP_PACKAGE,
41
61
  SHARED_AGENTS_MD_LABEL,
42
62
  afterAgentFailureNote,
43
63
  agentFailureFromError,
44
64
  agentFailureWire,
45
65
  configFailureKind,
46
66
  configureFxSettings,
47
- describeDetection,
48
67
  describedAgentFailure,
49
- detectAllAgents,
50
68
  failedAgentsContext,
51
69
  fxIgnoresInstructionsFile,
70
+ fxInstructionsBody,
52
71
  fxPusharyEntry,
53
72
  inspectFxInstallation,
54
- isDetected,
55
- isHermesConfigReceipt,
56
- pluginLocationSnippet,
57
73
  readFxProfileForSetup,
58
- registerPluginLocation,
59
74
  renderAgentInstructions,
60
75
  renderProjectAgentInstructions,
61
- resolveHermesPython,
62
76
  retryAgentCommand,
63
- runHermesConfigScript,
64
- shortenHome,
65
- vscodeSettingsTargets,
66
77
  withFxPusharyServer,
67
78
  writeFxProfile,
68
79
  writeInstructionBlock
69
- } from "../chunk-QQ4HBXZC.js";
80
+ } from "../chunk-6W5M3MSE.js";
70
81
  import {
71
82
  MCP_BRIDGE_BINARY
72
- } from "../chunk-W2KI5KPD.js";
73
- import {
74
- addCompatibleHooks,
75
- addCompatibleMcpServer,
76
- addCompatibleToolPermissions,
77
- compatibleConfigFile,
78
- compatibleHookEvents,
79
- compatibleInstructionsFile,
80
- compatibleMcpFile,
81
- compatiblePermissionRuleFile,
82
- hasCompatibleHooks
83
- } from "../chunk-MZPXVH4A.js";
84
- import {
85
- OPENCODE_HOOK_BINARY,
86
- addOpenCodeMcpServer,
87
- installOpenCodePlugin,
88
- openCodeConfigDir,
89
- openCodeConfigFile,
90
- openCodeHookArgv,
91
- openCodeInstructionsFile,
92
- openCodePluginDir,
93
- openCodePluginFile,
94
- openCodeWired
95
- } from "../chunk-X5NXPCIC.js";
96
- import {
97
- addClaudeMcpServer,
98
- addPusharyHooks,
99
- addPusharyToolPermissions,
100
- captureClaudeMcpServer,
101
- isClaudeMcpSnapshot,
102
- updateClaudeMcpSnapshot
103
- } from "../chunk-ANEAA37E.js";
83
+ } from "../chunk-H5T27W7M.js";
104
84
  import {
105
85
  checkCodexInstall,
106
86
  detectProviderLiveCapabilities,
@@ -108,40 +88,14 @@ import {
108
88
  hasSpawnProvider,
109
89
  nodeCodexInstallProbe,
110
90
  resolveControlPolicy
111
- } from "../chunk-T7Y5EADL.js";
91
+ } from "../chunk-F7R3SZ4Q.js";
112
92
  import {
113
93
  detectClaudeVersion
114
94
  } from "../chunk-RIVNNBEK.js";
115
95
  import {
116
96
  describeAutoUpdateAnnouncement,
117
97
  takeAutoUpdateAnnouncement
118
- } from "../chunk-QTO6HEZD.js";
119
- import {
120
- KEEP_HINT,
121
- captureHookTakeover,
122
- captureMcpServer,
123
- describeAppOwnership,
124
- describeHookOwnership,
125
- hookOwnerOf,
126
- mcpBearerKey,
127
- planHooks
128
- } from "../chunk-SD3272LS.js";
129
- import {
130
- AGENT_CHOICES,
131
- effectiveControlMode,
132
- effectiveVerify,
133
- parseSetupOptions
134
- } from "../chunk-SBLPHUEB.js";
135
- import {
136
- liveBridgeProbe,
137
- resolveBridgeStub
138
- } from "../chunk-MNWRUGMH.js";
139
- import {
140
- claudeWired,
141
- codexWired,
142
- geminiWired,
143
- pusharyHookExecutable
144
- } from "../chunk-4YO4T5FV.js";
98
+ } from "../chunk-K545B734.js";
145
99
  import {
146
100
  DAEMON_COLD_START_TIMEOUT_MS,
147
101
  clearDaemonNeedsLogin,
@@ -155,29 +109,11 @@ import {
155
109
  replaceDaemonService,
156
110
  stopDaemonService,
157
111
  waitForDaemonRemoteProof
158
- } from "../chunk-VXRXFU6Q.js";
159
- import {
160
- GEMINI_HOOK_BINARY,
161
- addGeminiHooks,
162
- addGeminiMcpServer
163
- } from "../chunk-JCWZ23MJ.js";
164
- import "../chunk-7264S5HZ.js";
112
+ } from "../chunk-SZ4Q6ZVS.js";
165
113
  import {
166
114
  transcriptPreferenceForSetup
167
- } from "../chunk-HPRZJKRO.js";
115
+ } from "../chunk-VIIHC42X.js";
168
116
  import "../chunk-XHKBHWLX.js";
169
- import {
170
- compareVersion,
171
- parseVersion
172
- } from "../chunk-6ICPEJY5.js";
173
- import {
174
- reportEvent
175
- } from "../chunk-QFEM7R6T.js";
176
- import "../chunk-N6IOSZOE.js";
177
- import "../chunk-6DJTDHBI.js";
178
- import "../chunk-D6S5EKXA.js";
179
- import "../chunk-AVNKVF7N.js";
180
- import "../chunk-POFBE6ZY.js";
181
117
  import {
182
118
  BROWSER_CONNECT_COMMAND,
183
119
  confirmAppConnection,
@@ -188,17 +124,78 @@ import {
188
124
  printConnectInstructions,
189
125
  roundTripEvidence,
190
126
  verifyRoundTrip
191
- } from "../chunk-N4EUSDKX.js";
127
+ } from "../chunk-DCCSULXK.js";
192
128
  import "../chunk-3EGEA4KH.js";
193
129
  import {
194
130
  setHumanStream
195
131
  } from "../chunk-QCGNGEGE.js";
132
+ import {
133
+ OPENCODE_HOOK_BINARY,
134
+ addOpenCodeMcpServer,
135
+ agentHookFile,
136
+ agentHookOwner,
137
+ installOpenCodePlugin,
138
+ macAppBridgeAvailable,
139
+ openCodeConfigDir,
140
+ openCodeConfigFile,
141
+ openCodeHookArgv,
142
+ openCodeInstructionsFile,
143
+ openCodePluginDir,
144
+ openCodePluginFile,
145
+ openCodeWired
146
+ } from "../chunk-BZLHTMT6.js";
147
+ import {
148
+ addClaudeMcpServer,
149
+ addCompatibleHooks,
150
+ addCompatibleMcpServer,
151
+ addCompatibleToolPermissions,
152
+ addPusharyHooks,
153
+ addPusharyToolPermissions,
154
+ captureClaudeMcpServer,
155
+ compatibleConfigFile,
156
+ compatibleHookEvents,
157
+ compatibleInstructionsFile,
158
+ compatibleMcpFile,
159
+ compatiblePermissionRuleFile,
160
+ hasCompatibleHooks,
161
+ isClaudeMcpSnapshot,
162
+ updateClaudeMcpSnapshot
163
+ } from "../chunk-UF6RBP5V.js";
196
164
  import {
197
165
  ansiPainter,
198
166
  createIo,
199
167
  useColor
200
168
  } from "../chunk-U4TMAANR.js";
169
+ import {
170
+ KEEP_HINT,
171
+ captureHookTakeover,
172
+ captureMcpServer,
173
+ claudeWired,
174
+ codexWired,
175
+ describeAppOwnership,
176
+ describeHookOwnership,
177
+ geminiWired,
178
+ mcpBearerKey,
179
+ planHooks,
180
+ pusharyHookExecutable
181
+ } from "../chunk-BYLKCZ2G.js";
182
+ import {
183
+ GEMINI_HOOK_BINARY,
184
+ addGeminiHooks,
185
+ addGeminiMcpServer
186
+ } from "../chunk-M3STIAGU.js";
187
+ import {
188
+ AGENT_CHOICES,
189
+ effectiveControlMode,
190
+ effectiveVerify,
191
+ parseSetupOptions
192
+ } from "../chunk-ZGADIZDS.js";
193
+ import "../chunk-MLGIVVSG.js";
201
194
  import "../chunk-GMXKITVA.js";
195
+ import {
196
+ compareVersion,
197
+ parseVersion
198
+ } from "../chunk-6ICPEJY5.js";
202
199
  import {
203
200
  KEY_FILE_MODE,
204
201
  exportLine,
@@ -208,24 +205,33 @@ import {
208
205
  readConfigFileKey,
209
206
  readControlMode,
210
207
  readKeySource,
208
+ recordMacAppKeyPrefix,
211
209
  resolveShellRc,
212
210
  writeKey
213
- } from "../chunk-ADSQDYYG.js";
214
- import "../chunk-L76HTPU6.js";
211
+ } from "../chunk-REU2VQPH.js";
212
+ import {
213
+ reportEvent
214
+ } from "../chunk-KQFTBQ66.js";
215
+ import "../chunk-N6IOSZOE.js";
216
+ import "../chunk-MD4SVNT6.js";
217
+ import "../chunk-WRPYCIV2.js";
218
+ import "../chunk-6AYSKVLL.js";
215
219
  import {
216
220
  checkApiKey,
217
221
  describeKeyCheck,
218
222
  samePusharyAccount
219
- } from "../chunk-KFKL3FHS.js";
220
- import "../chunk-JXISQ7DT.js";
221
- import "../chunk-KYO45G5L.js";
223
+ } from "../chunk-QRXPWW3M.js";
224
+ import "../chunk-UPIZSCYD.js";
225
+ import "../chunk-POFBE6ZY.js";
226
+ import "../chunk-5N5L6DNN.js";
227
+ import "../chunk-KOWFRUIT.js";
222
228
  import {
223
229
  UsageError
224
230
  } from "../chunk-7QLSKOSU.js";
225
231
  import {
226
232
  EXIT
227
233
  } from "../chunk-KZERVKTD.js";
228
- import "../chunk-4D2AYNSE.js";
234
+ import "../chunk-BNSKVIAW.js";
229
235
  import {
230
236
  NpmMissingError,
231
237
  addCodexHookTrust,
@@ -257,6 +263,7 @@ import {
257
263
  geminiSettings,
258
264
  guardBinary,
259
265
  guardCursorGate,
266
+ guardNodeScript,
260
267
  guardedArgv,
261
268
  hermesConfigReceipt,
262
269
  hookTakeoverReceipt,
@@ -264,27 +271,25 @@ import {
264
271
  npmErrorMessage,
265
272
  plannedGlobalPackage,
266
273
  pusharyConfigFile,
267
- pusharyDir,
268
274
  readCodexMcpAuth,
269
275
  resolveGlobalBinDir,
270
276
  resolveGlobalBinary,
271
277
  vscodePluginDir,
272
278
  vscodePluginMcp
273
- } from "../chunk-ZUTU43FT.js";
279
+ } from "../chunk-Z23ZBYDW.js";
274
280
  import {
275
281
  backupFile,
276
282
  readJsonSafe,
277
283
  writeFileAtomic,
278
284
  writeJsonAtomic
279
285
  } from "../chunk-T7E75EKA.js";
280
- import "../chunk-Z6HPS67T.js";
286
+ import "../chunk-IRHABAQT.js";
281
287
  import {
282
288
  NPX_LATEST_COMMAND,
283
289
  renderCommandHelp
284
- } from "../chunk-STQRUH3S.js";
290
+ } from "../chunk-5DCDQ5VW.js";
285
291
  import {
286
292
  HOOK_COMPATIBLE_PROFILES,
287
- HOOK_LOCATOR_BINARY,
288
293
  PRETOOLUSE_GATED_TOOLS,
289
294
  SUPPORT_EMAIL,
290
295
  compatibleTargetFiles,
@@ -296,7 +301,7 @@ import {
296
301
  isValidApiKey,
297
302
  launchedPackage,
298
303
  ownPackageName
299
- } from "../chunk-QR6VE5ME.js";
304
+ } from "../chunk-5RGA636G.js";
300
305
 
301
306
  // bin/pushary-setup.ts
302
307
  import { existsSync, readFileSync, writeFileSync, mkdirSync, cpSync, rmSync, renameSync, realpathSync, statSync, openSync, readSync, closeSync } from "fs";
@@ -349,7 +354,7 @@ var nextSteps = (facts, reachable) => {
349
354
  lines.push("pushary claude launch a managed Claude Code session");
350
355
  }
351
356
  if (!reachable) {
352
- lines.push("pushary connect connect a phone without re-running setup");
357
+ lines.push("pushary pair pair a phone without re-running setup");
353
358
  }
354
359
  lines.push("pushary doctor re-check everything");
355
360
  return lines;
@@ -637,6 +642,24 @@ var pickAppKey = (candidates) => candidates.fromAgents.find(
637
642
  (candidate) => typeof candidate === "string" && candidate !== candidates.storedKey && candidate !== candidates.envKey && isValidApiKey(candidate)
638
643
  ) ?? null;
639
644
 
645
+ // src/vscode-gate-hooks.ts
646
+ var isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
647
+ var runsTheGate = (entry) => typeof entry.command === "string" && (pusharyHookExecutable(entry.command)?.endsWith(CURSOR_GATE_SCRIPT) ?? false);
648
+ var guardedEntry = (entry, command) => isRecord(entry) && runsTheGate(entry) ? { ...entry, command } : entry;
649
+ var guardVsCodeGateHooks = (document, gateScript) => {
650
+ if (!isRecord(document) || !isRecord(document.hooks)) {
651
+ return { kind: "invalid", reason: "bundled VS Code hooks.json has no hooks map" };
652
+ }
653
+ const hooks = document.hooks;
654
+ const preToolUse = hooks.PreToolUse;
655
+ if (!Array.isArray(preToolUse) || preToolUse.length === 0) {
656
+ return { kind: "invalid", reason: "bundled VS Code hooks.json is missing a PreToolUse entry" };
657
+ }
658
+ const command = guardNodeScript(gateScript);
659
+ const guarded = Object.fromEntries(Object.entries(hooks).map(([event, entries]) => [event, Array.isArray(entries) ? entries.map((entry) => guardedEntry(entry, command)) : entries]));
660
+ return { kind: "guarded", document: { ...document, hooks: guarded } };
661
+ };
662
+
640
663
  // src/setup/pairing-computer.ts
641
664
  var LOCAL_NETWORK_SUFFIX = /\.local$/i;
642
665
  var computerNameOfHost = (host) => host.replace(LOCAL_NETWORK_SUFFIX, "").trim() || null;
@@ -1244,8 +1267,8 @@ var setupCursor = async (apiKey) => {
1244
1267
  const source = resolveBundledPlugin();
1245
1268
  if (!source) throw new Error("bundled Cursor plugin not found in this package");
1246
1269
  await spinner("Installing Pushary plugin", async () => {
1247
- const staging = join3(dirname2(CURSOR_PLUGIN_DIR), `.pushary-staging-${process.pid}`);
1248
- const backup = `${CURSOR_PLUGIN_DIR}.pushary-backup-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
1270
+ const staging = join3(dirname2(CURSOR_PLUGIN_DIR), `${CURSOR_PLUGIN_STAGING_PREFIX}${process.pid}`);
1271
+ const backup = `${CURSOR_PLUGIN_DIR}${CURSOR_PLUGIN_BACKUP_INFIX}${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
1249
1272
  rmSync(staging, { recursive: true, force: true });
1250
1273
  try {
1251
1274
  cpSync(source, staging, {
@@ -1301,16 +1324,11 @@ var resolveBundledVsCodePlugin = () => {
1301
1324
  ];
1302
1325
  return candidates.find((p) => existsSync(join3(p, ".claude-plugin", "plugin.json"))) ?? null;
1303
1326
  };
1304
- var pinVsCodeGatePath = (pluginDir) => {
1327
+ var pinGuardedVsCodeGate = (pluginDir) => {
1305
1328
  const hooksPath = join3(pluginDir, "hooks", "hooks.json");
1306
- const data = readJson(hooksPath);
1307
- const entries = data.hooks?.PreToolUse;
1308
- if (!Array.isArray(entries) || entries.length === 0) {
1309
- throw new Error("bundled VS Code hooks.json is missing a PreToolUse entry");
1310
- }
1311
- const gate = join3(pluginDir, "scripts", "pushary-gate.mjs");
1312
- data.hooks.PreToolUse = entries.map((entry) => ({ ...entry, command: `node "${gate}"` }));
1313
- writeJson(hooksPath, data);
1329
+ const guarded = guardVsCodeGateHooks(readJson(hooksPath), join3(pluginDir, "scripts", CURSOR_GATE_SCRIPT));
1330
+ if (guarded.kind === "invalid") throw new Error(guarded.reason);
1331
+ writeJson(hooksPath, guarded.document);
1314
1332
  };
1315
1333
  var registerVsCodePlugin = (pluginDir) => {
1316
1334
  const written = [];
@@ -1372,7 +1390,7 @@ var setupVsCode = async (apiKey) => {
1372
1390
  mcp.mcpServers = servers;
1373
1391
  writeJsonAtomic(mcpPath, mcp, KEY_FILE_MODE);
1374
1392
  }
1375
- pinVsCodeGatePath(VSCODE_PLUGIN_DIR);
1393
+ pinGuardedVsCodeGate(VSCODE_PLUGIN_DIR);
1376
1394
  });
1377
1395
  let registration = { written: [], manual: [] };
1378
1396
  await spinner("Registering the plugin with VS Code", async () => {
@@ -1410,7 +1428,7 @@ var saveApiKey = async (apiKey, controlMode, transcriptSync) => {
1410
1428
  let result;
1411
1429
  await spinner("Saving your API key", async () => {
1412
1430
  result = writeKey(apiKey, {
1413
- ...controlMode === null ? {} : { controlMode },
1431
+ controlMode,
1414
1432
  transcriptsEnabled: transcriptSync
1415
1433
  });
1416
1434
  });
@@ -1488,9 +1506,7 @@ var reportFxSettings = (outcome) => {
1488
1506
  };
1489
1507
  var teachFxToAskViaPush = () => {
1490
1508
  if (fxIgnoresInstructionsFile(fxAgentsMd(), fxConfigDir())) return false;
1491
- writeInstructionBlock(fxAgentsMd(), `${renderAgentInstructions("fx")}
1492
-
1493
- ${FX_TOOL_DISCOVERY_NOTE}`);
1509
+ writeInstructionBlock(fxAgentsMd(), fxInstructionsBody());
1494
1510
  return true;
1495
1511
  };
1496
1512
  var fxWired = () => inspectFxInstallation(fxMcpProfile(), fxSettings(), process.env).configured;
@@ -1624,32 +1640,24 @@ var compatibleRecord = (of) => HOOK_COMPATIBLE_PROFILES.reduce(
1624
1640
  (record, profile) => ({ ...record, [profile.agentType]: of(profile) }),
1625
1641
  {}
1626
1642
  );
1627
- var HOOK_FILES = {
1628
- claude_code: () => CLAUDE_SETTINGS,
1629
- codex: () => CODEX_HOOKS_JSON,
1630
- gemini_cli: () => GEMINI_SETTINGS,
1631
- cursor: () => CURSOR_USER_HOOKS,
1632
- vscode: () => join3(VSCODE_PLUGIN_DIR, "hooks", "hooks.json"),
1633
- ...compatibleRecord((profile) => () => compatibleConfigFile(profile))
1634
- };
1635
- var hookOwnerFor = (agent, appAvailable = true) => {
1636
- const file = HOOK_FILES[agent]?.();
1637
- if (!file) return "none";
1638
- const document = readJsonSafe(file);
1639
- const profile = hookCompatibleProfile(agent);
1640
- return hookOwnerOf(
1641
- document.kind === "ok" ? document.value : null,
1642
- appAvailable,
1643
- profile ? profile.hooksKeyPath : void 0
1644
- );
1643
+ var clearSetupChoiceDecline = (agent) => {
1644
+ const declined = declinedAgentForSetupChoice(agent);
1645
+ if (declined) clearDeclinedAgent(declined);
1646
+ };
1647
+ var APP_MCP_ENTRIES = {
1648
+ claude_code: { file: () => CLAUDE_JSON, container: "mcpServers" },
1649
+ gemini_cli: { file: () => GEMINI_SETTINGS, container: "mcpServers" },
1650
+ cursor: { file: cursorUserMcp, container: "mcpServers" },
1651
+ vscode: { file: () => VSCODE_PLUGIN_MCP, container: "mcpServers" },
1652
+ opencode: { file: openCodeConfigFile, container: "mcp" }
1645
1653
  };
1646
1654
  var appMcpKeyFor = (agent) => {
1647
1655
  if (agent === "codex") {
1648
1656
  const auth = readCodexMcpAuth(readAgentToml(codexConfigToml()));
1649
1657
  return auth?.method === "embedded" ? auth.key : null;
1650
1658
  }
1651
- const file = agent === "claude_code" ? CLAUDE_JSON : agent === "gemini_cli" ? GEMINI_SETTINGS : agent === "cursor" ? cursorUserMcp() : agent === "vscode" ? VSCODE_PLUGIN_MCP : null;
1652
- return file ? mcpBearerKey(readAgentJson(file), "mcpServers", "headers") : null;
1659
+ const entry = APP_MCP_ENTRIES[agent];
1660
+ return entry ? mcpBearerKey(readAgentJson(entry.file()), entry.container, "headers") : null;
1653
1661
  };
1654
1662
  var appMcpKeyIfReadable = (agent) => {
1655
1663
  try {
@@ -1659,7 +1667,7 @@ var appMcpKeyIfReadable = (agent) => {
1659
1667
  }
1660
1668
  };
1661
1669
  var captureTakeoverReceipt = (agent) => {
1662
- const hookFile = HOOK_FILES[agent]?.();
1670
+ const hookFile = agentHookFile(agent);
1663
1671
  if (!hookFile) return;
1664
1672
  const document = readAgentJson(hookFile);
1665
1673
  const captured = captureHookTakeover(agent, document);
@@ -2016,7 +2024,7 @@ var reportDryRun = (apiKey, agents, keyCheck, controlMode) => {
2016
2024
  apiKey ? ` ${dim("Key:")} ${dim(`${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`)} ${dim(`(${keyCheck?.kind ?? "not verified"})`)}` : ` ${dim("Key:")} ${dim("none on this machine \u2014 a real run would acquire one")}`
2017
2025
  );
2018
2026
  console.log(` ${dim("Key store:")} ${PUSHARY_CONFIG_FILE}`);
2019
- console.log(` ${dim("Control:")} ${controlMode ?? "unchanged (legacy install)"}`);
2027
+ console.log(` ${dim("Control:")} ${controlMode}`);
2020
2028
  const rc = resolveShellRc();
2021
2029
  console.log(` ${dim("Shell rc:")} ${rc ? rc.path : dim("none for this shell; the key would stay in Pushary's config only")}`);
2022
2030
  console.log();
@@ -2070,7 +2078,7 @@ var main = async () => {
2070
2078
  `);
2071
2079
  process.exit(EXIT.OK);
2072
2080
  }
2073
- const controlMode = effectiveControlMode(options, readControlMode(), existsSync(PUSHARY_CONFIG_FILE));
2081
+ const controlMode = effectiveControlMode(options, readControlMode());
2074
2082
  recordSetupOptions(options);
2075
2083
  if (options.json) {
2076
2084
  jsonMode = true;
@@ -2237,12 +2245,10 @@ var main = async () => {
2237
2245
  console.log(" Transcript sync: enabling locally redacted, encrypted sync for Pushary-launched sessions. Your phone can decrypt it; authorized Pushary compliance admins can recover it for documented legal obligations. Disable with pushary setup --transcripts off.");
2238
2246
  }
2239
2247
  const rc = await saveApiKey(trimmedKey, controlMode, transcriptSync);
2248
+ if (trimmedKey === appKey) recordMacAppKeyPrefix(trimmedKey);
2240
2249
  if (keyCheck.kind === "ok") clearDaemonNeedsLogin();
2241
2250
  const context = { rc };
2242
- const appBridgeAvailable = resolveBridgeStub(
2243
- join3(pusharyDir(), "bin", HOOK_LOCATOR_BINARY),
2244
- liveBridgeProbe()
2245
- ).kind === "bundle";
2251
+ const appBridgeAvailable = macAppBridgeAvailable();
2246
2252
  const accountChecks = /* @__PURE__ */ new Map();
2247
2253
  if (keyCheck) accountChecks.set(trimmedKey, Promise.resolve(keyCheck));
2248
2254
  const accountCheckFor = (key) => {
@@ -2281,7 +2287,7 @@ var main = async () => {
2281
2287
  for (const [index, agent] of agents.entries()) {
2282
2288
  markStep(`configure:${agent}`);
2283
2289
  try {
2284
- const ownerBefore = hookOwnerFor(agent, appBridgeAvailable);
2290
+ const ownerBefore = agentHookOwner(agent, appBridgeAvailable);
2285
2291
  const plan = planHooks({ owner: ownerBefore, takeOverHooks: options.takeOverHooks, nonInteractive: options.nonInteractive });
2286
2292
  const keepAppWiring = plan === "keep";
2287
2293
  if (keepAppWiring) {
@@ -2299,6 +2305,7 @@ var main = async () => {
2299
2305
  ${check} ${AGENT_NAMES[agent]}: ${describeAppOwnership(AGENT_NAMES[agent])} ${dim(KEEP_HINT)}`);
2300
2306
  hookOwners.push({ agent, owner: "app", kept: true });
2301
2307
  completed.push(agent);
2308
+ clearSetupChoiceDecline(agent);
2302
2309
  continue;
2303
2310
  }
2304
2311
  if (ownerBefore === "app") captureTakeoverReceipt(agent);
@@ -2307,7 +2314,8 @@ var main = async () => {
2307
2314
  skipped.push(agent);
2308
2315
  } else if (agentIsWired(agent)) {
2309
2316
  completed.push(agent);
2310
- hookOwners.push({ agent, owner: hookOwnerFor(agent, appBridgeAvailable), kept: false });
2317
+ clearSetupChoiceDecline(agent);
2318
+ hookOwners.push({ agent, owner: agentHookOwner(agent, appBridgeAvailable), kept: false });
2311
2319
  } else {
2312
2320
  const failure = describedAgentFailure(agent, "not-wired");
2313
2321
  failures.push(failure);
@@ -1,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  readLedgerSummary
4
- } from "../chunk-CBQACHKY.js";
4
+ } from "../chunk-IIVZZMSO.js";
5
5
  import {
6
6
  exitOnHelpFlag
7
- } from "../chunk-UFVGSEWH.js";
7
+ } from "../chunk-TO3PS646.js";
8
8
  import "../chunk-KZERVKTD.js";
9
9
  import {
10
10
  getApiKey
11
- } from "../chunk-Z6HPS67T.js";
12
- import "../chunk-STQRUH3S.js";
13
- import "../chunk-QR6VE5ME.js";
11
+ } from "../chunk-IRHABAQT.js";
12
+ import "../chunk-5DCDQ5VW.js";
13
+ import "../chunk-5RGA636G.js";
14
14
 
15
15
  // bin/pushary-stats.ts
16
16
  exitOnHelpFlag("stats");