@pushary/agent-hooks 1.6.2 → 1.6.4

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 (88) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/bin/pushary-bell-hook.js +21 -18
  3. package/dist/bin/pushary-bell.js +8 -8
  4. package/dist/bin/pushary-claude.js +24 -22
  5. package/dist/bin/pushary-clean.js +38 -36
  6. package/dist/bin/pushary-codex-bridge.js +22 -21
  7. package/dist/bin/pushary-codex-hook.js +36 -30
  8. package/dist/bin/pushary-codex.js +11 -9
  9. package/dist/bin/pushary-connect.js +10 -8
  10. package/dist/bin/pushary-cowork.js +3 -3
  11. package/dist/bin/pushary-daemon.js +27 -27
  12. package/dist/bin/pushary-disconnect.js +20 -18
  13. package/dist/bin/pushary-doctor.js +53 -51
  14. package/dist/bin/pushary-elicitation-hook.js +23 -21
  15. package/dist/bin/pushary-gemini-bridge.js +9 -9
  16. package/dist/bin/pushary-gemini-hook.js +32 -26
  17. package/dist/bin/pushary-hook.js +34 -28
  18. package/dist/bin/pushary-login.js +8 -8
  19. package/dist/bin/pushary-logout.js +9 -9
  20. package/dist/bin/pushary-mode.js +7 -4
  21. package/dist/bin/pushary-notification-hook.js +25 -23
  22. package/dist/bin/pushary-opencode-hook.js +31 -25
  23. package/dist/bin/pushary-permission-denied-hook.js +29 -27
  24. package/dist/bin/pushary-permission-hook.js +28 -26
  25. package/dist/bin/pushary-post-hook.js +25 -23
  26. package/dist/bin/pushary-prompt-hook.js +25 -23
  27. package/dist/bin/pushary-session-end-hook.js +25 -23
  28. package/dist/bin/pushary-session-start-hook.js +29 -27
  29. package/dist/bin/pushary-setup.js +194 -105
  30. package/dist/bin/pushary-stats.js +2 -2
  31. package/dist/bin/pushary-status.js +12 -12
  32. package/dist/bin/pushary-stop-hook.js +25 -23
  33. package/dist/bin/pushary-stopfailure-hook.js +25 -23
  34. package/dist/bin/pushary-transcript-register.js +16 -16
  35. package/dist/bin/pushary-transcripts.js +4 -4
  36. package/dist/bin/pushary-upgrade.js +25 -24
  37. package/dist/bin/pushary-wait.js +7 -4
  38. package/dist/bin/pushary.js +8 -3
  39. package/dist/{chunk-N6AMKPDW.js → chunk-3LU74H52.js} +1 -1
  40. package/dist/{chunk-SB2CRLFK.js → chunk-3VZX4NSP.js} +1 -1
  41. package/dist/{chunk-ND43S2N4.js → chunk-53DN77WB.js} +1 -1
  42. package/dist/{chunk-KKZ5TDTB.js → chunk-5SWQZ6HY.js} +4 -4
  43. package/dist/{chunk-A6BENRKI.js → chunk-5U3FJ6YF.js} +7 -7
  44. package/dist/{chunk-CH4QMWBM.js → chunk-5UWV5GHM.js} +1 -1
  45. package/dist/{chunk-55AT5DJD.js → chunk-6NLWK6ZV.js} +2 -2
  46. package/dist/{chunk-HW2M7XAU.js → chunk-7CLTSZOL.js} +3 -3
  47. package/dist/{chunk-HETOKNIL.js → chunk-BJENQBMH.js} +3 -3
  48. package/dist/{chunk-A5ODW52C.js → chunk-CAS7GFWI.js} +75 -28
  49. package/dist/{chunk-M543MAUN.js → chunk-D3K2FPPJ.js} +8 -8
  50. package/dist/chunk-DESAUCH2.js +126 -0
  51. package/dist/{chunk-LH2N6VAN.js → chunk-DZTKLE7Q.js} +3 -1
  52. package/dist/{chunk-LVHGSD5E.js → chunk-EREBZHN2.js} +12 -6
  53. package/dist/{chunk-E72R2MHO.js → chunk-GBL4BTG3.js} +2 -2
  54. package/dist/{chunk-GKO7T4JM.js → chunk-H6XU22TN.js} +14 -8
  55. package/dist/{chunk-OXFWJIW4.js → chunk-HUB4Q35G.js} +1 -1
  56. package/dist/{chunk-NEUYPY3I.js → chunk-I2YUMZLE.js} +7 -6
  57. package/dist/{chunk-3PDQE66Q.js → chunk-I3XJATMR.js} +1 -1
  58. package/dist/{chunk-TCT4WUDP.js → chunk-JOGA3TL2.js} +6 -6
  59. package/dist/{chunk-ON7VIYOQ.js → chunk-K32C2RGK.js} +3 -1
  60. package/dist/{chunk-F5ENKWKY.js → chunk-LDRGVXLR.js} +1 -1
  61. package/dist/{chunk-TDXQQB55.js → chunk-LFMOYHPY.js} +1 -1
  62. package/dist/{chunk-572FZF7T.js → chunk-LJEL7IB5.js} +5 -5
  63. package/dist/{chunk-3HUDBDO7.js → chunk-LQI7W4RG.js} +1 -1
  64. package/dist/{chunk-RKSBBEGT.js → chunk-N62KAMMY.js} +1 -1
  65. package/dist/{chunk-LN3FETAC.js → chunk-NFH73H5B.js} +3 -3
  66. package/dist/{chunk-SD6SAIEV.js → chunk-NYMPLNV3.js} +3 -3
  67. package/dist/{chunk-KUQF2VO6.js → chunk-OZE2TQX5.js} +5 -5
  68. package/dist/{chunk-HYN2BILS.js → chunk-P4UYILQK.js} +5 -6
  69. package/dist/{chunk-HLY5W2P4.js → chunk-PBKEYMAO.js} +1 -1
  70. package/dist/{chunk-VQIINJ45.js → chunk-PJF7L7AA.js} +1 -1
  71. package/dist/chunk-POFBE6ZY.js +12 -0
  72. package/dist/{chunk-RKNA2L2J.js → chunk-R4HVHTNA.js} +1 -1
  73. package/dist/{chunk-2J63MNXV.js → chunk-UAP556WK.js} +5 -6
  74. package/dist/{chunk-HXKY6DFD.js → chunk-UGKDBJJX.js} +2 -2
  75. package/dist/{chunk-5KREBDUT.js → chunk-VA2R64I7.js} +1 -1
  76. package/dist/{chunk-NSG2Q4PI.js → chunk-VHNDE3ZD.js} +1 -1
  77. package/dist/chunk-VOCZHOXV.js +142 -0
  78. package/dist/{chunk-ZRLB3N37.js → chunk-XJG2FUWS.js} +3 -3
  79. package/dist/{chunk-7REOI7BC.js → chunk-XOMH53NB.js} +1 -1
  80. package/dist/{chunk-D5ORNUHK.js → chunk-YPONELWS.js} +6 -6
  81. package/dist/{chunk-XINNQCPW.js → chunk-YUGGNZSF.js} +1 -1
  82. package/dist/{chunk-D5PQGC5V.js → chunk-YXPGFRRW.js} +3 -3
  83. package/dist/{chunk-RK2MUM6Q.js → chunk-ZA5UXRNE.js} +3 -3
  84. package/dist/{reapply-KV6RTOQL.js → reapply-4DAJKNVP.js} +9 -9
  85. package/dist/src/index.d.ts +2 -2
  86. package/dist/src/index.js +17 -15
  87. package/package.json +1 -1
  88. package/dist/chunk-SAF6HGAA.js +0 -57
@@ -9,22 +9,22 @@ import {
9
9
  import {
10
10
  coworkOutput,
11
11
  coworkSelection
12
- } from "../chunk-55AT5DJD.js";
12
+ } from "../chunk-6NLWK6ZV.js";
13
13
  import "../chunk-PUZZELE6.js";
14
14
  import {
15
15
  detectClaudeVersion
16
- } from "../chunk-HLY5W2P4.js";
16
+ } from "../chunk-PBKEYMAO.js";
17
17
  import {
18
18
  describeVersionManagerPin,
19
19
  versionManagerOf
20
20
  } from "../chunk-GU3EJCVV.js";
21
21
  import {
22
22
  ensureCodexTrustsPusharyHooks
23
- } from "../chunk-ND43S2N4.js";
23
+ } from "../chunk-53DN77WB.js";
24
24
  import {
25
25
  readManagedControlEvidence,
26
26
  waitForMachineReadiness
27
- } from "../chunk-TCT4WUDP.js";
27
+ } from "../chunk-JOGA3TL2.js";
28
28
  import {
29
29
  HERMES_CONFIG_SCRIPT,
30
30
  HERMES_PIP_PACKAGE,
@@ -34,7 +34,7 @@ import {
34
34
  isHermesConfigReceipt,
35
35
  resolveHermesPython,
36
36
  runHermesPythonScript
37
- } from "../chunk-RKSBBEGT.js";
37
+ } from "../chunk-N62KAMMY.js";
38
38
  import {
39
39
  describeDetection,
40
40
  detectAllAgents,
@@ -46,7 +46,7 @@ import {
46
46
  shortenHome,
47
47
  vscodeSettingsTargets,
48
48
  writeInstructionBlock
49
- } from "../chunk-LN3FETAC.js";
49
+ } from "../chunk-NFH73H5B.js";
50
50
  import {
51
51
  OPENCODE_HOOK_BINARY,
52
52
  addOpenCodeMcpServer,
@@ -57,7 +57,7 @@ import {
57
57
  openCodePluginDir,
58
58
  openCodePluginFile,
59
59
  openCodeWired
60
- } from "../chunk-SB2CRLFK.js";
60
+ } from "../chunk-3VZX4NSP.js";
61
61
  import {
62
62
  addCompatibleHooks,
63
63
  addCompatibleMcpServer,
@@ -68,7 +68,7 @@ import {
68
68
  compatibleMcpFile,
69
69
  compatiblePermissionRuleFile,
70
70
  hasCompatibleHooks
71
- } from "../chunk-572FZF7T.js";
71
+ } from "../chunk-LJEL7IB5.js";
72
72
  import {
73
73
  addClaudeMcpServer,
74
74
  addPusharyHooks,
@@ -76,16 +76,16 @@ import {
76
76
  captureClaudeMcpServer,
77
77
  isClaudeMcpSnapshot,
78
78
  updateClaudeMcpSnapshot
79
- } from "../chunk-RK2MUM6Q.js";
79
+ } from "../chunk-ZA5UXRNE.js";
80
80
  import {
81
81
  detectProviderLiveCapabilities,
82
82
  hasSpawnProvider,
83
83
  resolveControlPolicy
84
- } from "../chunk-E72R2MHO.js";
84
+ } from "../chunk-GBL4BTG3.js";
85
85
  import {
86
86
  describeAutoUpdateAnnouncement,
87
87
  takeAutoUpdateAnnouncement
88
- } from "../chunk-HYN2BILS.js";
88
+ } from "../chunk-P4UYILQK.js";
89
89
  import {
90
90
  KEEP_HINT,
91
91
  captureHookTakeover,
@@ -95,23 +95,23 @@ import {
95
95
  hookOwnerOf,
96
96
  mcpBearerKey,
97
97
  planHooks
98
- } from "../chunk-KKZ5TDTB.js";
98
+ } from "../chunk-5SWQZ6HY.js";
99
99
  import {
100
100
  AGENT_CHOICES,
101
101
  effectiveControlMode,
102
102
  effectiveVerify,
103
103
  parseSetupOptions
104
- } from "../chunk-NEUYPY3I.js";
104
+ } from "../chunk-I2YUMZLE.js";
105
105
  import {
106
106
  liveBridgeProbe,
107
107
  resolveBridgeStub
108
- } from "../chunk-3PDQE66Q.js";
108
+ } from "../chunk-I3XJATMR.js";
109
109
  import {
110
110
  claudeWired,
111
111
  codexWired,
112
112
  geminiWired,
113
113
  pusharyHookExecutable
114
- } from "../chunk-D5PQGC5V.js";
114
+ } from "../chunk-YXPGFRRW.js";
115
115
  import {
116
116
  clearDaemonNeedsLogin,
117
117
  daemonHasRemoteProof,
@@ -124,64 +124,26 @@ import {
124
124
  replaceDaemonService,
125
125
  stopDaemonService,
126
126
  waitForDaemonRemoteProof
127
- } from "../chunk-KUQF2VO6.js";
127
+ } from "../chunk-OZE2TQX5.js";
128
128
  import {
129
129
  GEMINI_HOOK_BINARY,
130
130
  addGeminiHooks,
131
131
  addGeminiMcpServer,
132
132
  compareVersion,
133
133
  parseVersion
134
- } from "../chunk-HW2M7XAU.js";
135
- import "../chunk-3HUDBDO7.js";
134
+ } from "../chunk-7CLTSZOL.js";
135
+ import "../chunk-LQI7W4RG.js";
136
136
  import {
137
137
  transcriptPreferenceForSetup
138
- } from "../chunk-5KREBDUT.js";
138
+ } from "../chunk-VA2R64I7.js";
139
139
  import "../chunk-XHKBHWLX.js";
140
140
  import {
141
141
  reportEvent
142
- } from "../chunk-GKO7T4JM.js";
143
- import "../chunk-XINNQCPW.js";
144
- import "../chunk-LVHGSD5E.js";
145
- import "../chunk-LH2N6VAN.js";
146
- import {
147
- addCodexHookTrust,
148
- addCodexHooks,
149
- addCodexMcpServer,
150
- autoUpdateState,
151
- captureCodexHookTrust,
152
- claudeJson,
153
- claudeMcpReceipt,
154
- claudeSettings,
155
- claudeSkillDir,
156
- codexAgentsMd2 as codexAgentsMd,
157
- codexConfigToml,
158
- codexHome,
159
- codexHookPositions,
160
- codexSkillDir2 as codexSkillDir,
161
- codexVacatedIndexes,
162
- cursorPluginDir,
163
- cursorUserHooks,
164
- cursorUserMcp,
165
- dropVacatedCodexHookTrust,
166
- fetchLatestPublishedVersion,
167
- geminiMd,
168
- geminiSettings,
169
- guardBinary,
170
- guardCursorGate,
171
- guardedArgv,
172
- hermesConfigReceipt,
173
- hookTakeoverReceipt,
174
- installGlobally,
175
- npmErrorMessage,
176
- pusharyConfigFile,
177
- pusharyDir,
178
- readCodexMcpAuth,
179
- registerHookEntry,
180
- resolveGlobalBinDir,
181
- resolveGlobalBinary,
182
- vscodePluginDir,
183
- vscodePluginMcp
184
- } from "../chunk-ON7VIYOQ.js";
142
+ } from "../chunk-H6XU22TN.js";
143
+ import "../chunk-YUGGNZSF.js";
144
+ import "../chunk-EREBZHN2.js";
145
+ import "../chunk-VOCZHOXV.js";
146
+ import "../chunk-POFBE6ZY.js";
185
147
  import {
186
148
  BROWSER_CONNECT_COMMAND,
187
149
  confirmAppConnection,
@@ -192,13 +154,13 @@ import {
192
154
  printConnectInstructions,
193
155
  roundTripEvidence,
194
156
  verifyRoundTrip
195
- } from "../chunk-ZRLB3N37.js";
157
+ } from "../chunk-XJG2FUWS.js";
196
158
  import "../chunk-3EGEA4KH.js";
197
159
  import {
198
160
  checkApiKey,
199
161
  describeKeyCheck,
200
162
  samePusharyAccount
201
- } from "../chunk-HXKY6DFD.js";
163
+ } from "../chunk-UGKDBJJX.js";
202
164
  import {
203
165
  setHumanStream
204
166
  } from "../chunk-QCGNGEGE.js";
@@ -216,16 +178,56 @@ import {
216
178
  readKeySource,
217
179
  resolveShellRc,
218
180
  writeKey
219
- } from "../chunk-RKNA2L2J.js";
220
- import "../chunk-HETOKNIL.js";
221
- import "../chunk-SAF6HGAA.js";
181
+ } from "../chunk-R4HVHTNA.js";
182
+ import "../chunk-BJENQBMH.js";
183
+ import "../chunk-DESAUCH2.js";
184
+ import "../chunk-DZTKLE7Q.js";
222
185
  import {
223
186
  UsageError
224
187
  } from "../chunk-7QLSKOSU.js";
225
188
  import {
226
189
  EXIT
227
190
  } from "../chunk-KZERVKTD.js";
228
- import "../chunk-NSG2Q4PI.js";
191
+ import "../chunk-VHNDE3ZD.js";
192
+ import {
193
+ addCodexHookTrust,
194
+ addCodexHooks,
195
+ addCodexMcpServer,
196
+ autoUpdateState,
197
+ captureCodexHookTrust,
198
+ claudeJson,
199
+ claudeMcpReceipt,
200
+ claudeSettings,
201
+ claudeSkillDir,
202
+ codexAgentsMd2 as codexAgentsMd,
203
+ codexConfigToml,
204
+ codexHome,
205
+ codexHookPositions,
206
+ codexSkillDir2 as codexSkillDir,
207
+ codexVacatedIndexes,
208
+ cursorPluginDir,
209
+ cursorUserHooks,
210
+ cursorUserMcp,
211
+ dropVacatedCodexHookTrust,
212
+ fetchLatestPublishedVersion,
213
+ geminiMd,
214
+ geminiSettings,
215
+ guardBinary,
216
+ guardCursorGate,
217
+ guardedArgv,
218
+ hermesConfigReceipt,
219
+ hookTakeoverReceipt,
220
+ installGlobally,
221
+ npmErrorMessage,
222
+ pusharyConfigFile,
223
+ pusharyDir,
224
+ readCodexMcpAuth,
225
+ registerHookEntry,
226
+ resolveGlobalBinDir,
227
+ resolveGlobalBinary,
228
+ vscodePluginDir,
229
+ vscodePluginMcp
230
+ } from "../chunk-K32C2RGK.js";
229
231
  import {
230
232
  backupFile,
231
233
  readJsonSafe,
@@ -241,7 +243,7 @@ import {
241
243
  compatibleTargetFiles,
242
244
  hookCompatibleProfile,
243
245
  isValidApiKey
244
- } from "../chunk-A5ODW52C.js";
246
+ } from "../chunk-CAS7GFWI.js";
245
247
  import {
246
248
  NPX_LATEST_COMMAND,
247
249
  renderCommandHelp
@@ -278,6 +280,35 @@ var planPhoneCheck = (context) => {
278
280
  return "connect";
279
281
  };
280
282
 
283
+ // src/setup/agent-failure.ts
284
+ var AgentConfigError = class extends Error {
285
+ kind;
286
+ filePath;
287
+ constructor(kind, filePath, message) {
288
+ super(message);
289
+ this.name = "AgentConfigError";
290
+ this.kind = kind;
291
+ this.filePath = filePath;
292
+ }
293
+ };
294
+ var configFailureKind = (readFailure) => readFailure === "unparseable" ? "config-unparseable" : "config-unreadable";
295
+ var AGENT_FAILURE_DETAILS = {
296
+ "not-wired": "reported success but its config is not there.",
297
+ "app-account-mismatch": "Mac app hooks kept, but their Pushary account could not be matched to this setup."
298
+ };
299
+ var describedAgentFailure = (agent, kind) => ({
300
+ agent,
301
+ kind,
302
+ detail: AGENT_FAILURE_DETAILS[kind]
303
+ });
304
+ var agentFailureFromError = (agent, error, describeError) => ({
305
+ agent,
306
+ kind: error instanceof AgentConfigError ? error.kind : "installer-error",
307
+ detail: describeError(error)
308
+ });
309
+ var retryAgentCommand = (agent) => `${NPX_LATEST_COMMAND} setup --agents ${agent}`;
310
+ var agentFailureWire = (failures) => failures.map(({ agent, kind }) => ({ agent, kind }));
311
+
281
312
  // src/setup/closing.ts
282
313
  var ACTIVITY_URL = "pushary.com/dashboard/agent/activity";
283
314
  var COMMAND_SURFACE = [
@@ -318,7 +349,8 @@ var describeClosing = (facts) => {
318
349
  ok: false,
319
350
  headline: "Setup failed.",
320
351
  next: ["Nothing was configured. Run pushary doctor to see why."],
321
- exitCode: EXIT.FAILED
352
+ exitCode: EXIT.FAILED,
353
+ reason: "configured-nothing"
322
354
  };
323
355
  }
324
356
  if (facts.failed.length > 0) {
@@ -331,7 +363,8 @@ var describeClosing = (facts) => {
331
363
  "",
332
364
  `Approvals: ${ACTIVITY_URL}`
333
365
  ],
334
- exitCode: EXIT.PROBLEMS_FOUND
366
+ exitCode: EXIT.PROBLEMS_FOUND,
367
+ reason: "agents-failed"
335
368
  };
336
369
  }
337
370
  if (facts.staleEnvironmentKey) {
@@ -339,7 +372,8 @@ var describeClosing = (facts) => {
339
372
  ok: false,
340
373
  headline: "Agents configured. This terminal still selects the previous key.",
341
374
  next: nextSteps(facts, reachable),
342
- exitCode: EXIT.PROBLEMS_FOUND
375
+ exitCode: EXIT.PROBLEMS_FOUND,
376
+ reason: "stale-environment-key"
343
377
  };
344
378
  }
345
379
  if (facts.daemonReady === false) {
@@ -351,7 +385,8 @@ var describeClosing = (facts) => {
351
385
  "pushary daemon install install or repair the background service",
352
386
  "pushary doctor verify it became reachable"
353
387
  ],
354
- exitCode: EXIT.PROBLEMS_FOUND
388
+ exitCode: EXIT.PROBLEMS_FOUND,
389
+ reason: "control-unready"
355
390
  };
356
391
  }
357
392
  if (facts.roundTripAnswered === true) {
@@ -359,7 +394,8 @@ var describeClosing = (facts) => {
359
394
  ok: true,
360
395
  headline: "Agents configured. Synthetic answer returned.",
361
396
  next: ["Agent hook activation remains unverified.", ...nextSteps(facts, reachable), "", `Approvals: ${ACTIVITY_URL}`],
362
- exitCode: EXIT.OK
397
+ exitCode: EXIT.OK,
398
+ reason: "synthetic-answer"
363
399
  };
364
400
  }
365
401
  if (facts.reachChecked && !facts.reachesYou) {
@@ -371,7 +407,8 @@ var describeClosing = (facts) => {
371
407
  "",
372
408
  ...nextSteps(facts, false)
373
409
  ],
374
- exitCode: EXIT.NO_DEVICE
410
+ exitCode: EXIT.NO_DEVICE,
411
+ reason: "phone-unverified"
375
412
  };
376
413
  }
377
414
  if (facts.roundTripAnswered === false) {
@@ -386,7 +423,8 @@ var describeClosing = (facts) => {
386
423
  "",
387
424
  "If you simply were not looking, re-run setup or pass --verify push to skip this check."
388
425
  ],
389
- exitCode: EXIT.PROBLEMS_FOUND
426
+ exitCode: EXIT.PROBLEMS_FOUND,
427
+ reason: "roundtrip-unanswered"
390
428
  };
391
429
  }
392
430
  if (!facts.reachChecked) {
@@ -398,16 +436,28 @@ var describeClosing = (facts) => {
398
436
  "",
399
437
  ...nextSteps(facts, false)
400
438
  ],
401
- exitCode: EXIT.OK
439
+ exitCode: EXIT.OK,
440
+ reason: "phone-skipped"
402
441
  };
403
442
  }
404
443
  return {
405
444
  ok: true,
406
445
  headline: "Setup complete.",
407
446
  next: [...nextSteps(facts, true), "", `Approvals: ${ACTIVITY_URL}`],
408
- exitCode: EXIT.OK
447
+ exitCode: EXIT.OK,
448
+ reason: "complete"
409
449
  };
410
450
  };
451
+ var RETRY_AGENT_LABEL = "Retry just this agent:";
452
+ var describeAgentFailures = (failures, agentName) => failures.map((failure) => ({
453
+ summary: `${agentName(failure.agent)}: ${failure.detail}`,
454
+ retryCommand: retryAgentCommand(failure.agent)
455
+ }));
456
+ var unverifiedKeyClosingReason = (facts) => {
457
+ if (facts.failedCount > 0) return "agents-failed";
458
+ if (facts.controlLifecycleFailed) return "control-unready";
459
+ return facts.keyCheck === "locked" ? "plan-inactive" : "key-unverified";
460
+ };
411
461
 
412
462
  // src/setup/codex-version.ts
413
463
  import { dirname, join } from "path";
@@ -547,13 +597,20 @@ var recordCodexTrust = (outcome) => {
547
597
  recordedCodexTrust = outcome;
548
598
  };
549
599
  var emitted = false;
600
+ var SETUP_COMPLETED_EVENT = "agent_setup_completed";
601
+ var SETUP_AGENT_TYPE = "setup";
550
602
  var defaultDeps = { report: reportEvent };
551
- var emit = async (deps, props) => {
603
+ var completeBeacon = (run) => ({
604
+ ...run,
605
+ codexTrust: recordedCodexTrust,
606
+ cliVersion: getPackageVersion()
607
+ });
608
+ var emit = async (deps, run) => {
552
609
  if (emitted) return;
553
610
  emitted = true;
554
611
  try {
555
612
  await deps.report(
556
- { event: "agent_setup_completed", agentType: "setup", ...props, codexTrust: recordedCodexTrust },
613
+ { event: SETUP_COMPLETED_EVENT, agentType: SETUP_AGENT_TYPE, ...completeBeacon(run) },
557
614
  { maxAttempts: 1, timeoutMs: 2e3, ...recordedKey ? { apiKey: recordedKey } : {} }
558
615
  );
559
616
  } catch {
@@ -563,7 +620,9 @@ var reportSetupOutcomeWith = async (deps, outcome) => emit(deps, {
563
620
  agents: outcome.completed,
564
621
  connectMode: outcome.options.connectMode,
565
622
  connectOutcome: outcome.connectOutcome,
566
- failedAgents: outcome.failed.length,
623
+ failedAgents: outcome.failures.length,
624
+ agentFailures: agentFailureWire(outcome.failures),
625
+ closingReason: outcome.closingReason,
567
626
  skippedAgents: outcome.skipped,
568
627
  nonInteractive: outcome.options.nonInteractive,
569
628
  keyCheck: outcome.keyCheck,
@@ -581,6 +640,8 @@ var reportSetupAbortWith = async (deps, reason, exitCode, keyCheck = "unknown")
581
640
  connectMode: recordedOptions?.connectMode ?? null,
582
641
  connectOutcome: "skipped",
583
642
  failedAgents: 0,
643
+ agentFailures: [],
644
+ closingReason: null,
584
645
  skippedAgents: [],
585
646
  nonInteractive: recordedOptions?.nonInteractive ?? null,
586
647
  keyCheck,
@@ -676,7 +737,9 @@ var readAgentJson = (filePath) => {
676
737
  if (result.kind === "missing") return {};
677
738
  const backup = backupFile(filePath);
678
739
  const reason = result.kind === "unparseable" ? "is not valid JSON" : "could not be read";
679
- throw new Error(
740
+ throw new AgentConfigError(
741
+ configFailureKind(result.kind),
742
+ filePath,
680
743
  `${filePath} ${reason}, so it was left untouched. A copy is at ${backup}. Fix or remove the original, then re-run setup.`
681
744
  );
682
745
  };
@@ -691,14 +754,16 @@ var readAgentToml = (filePath) => {
691
754
  raw = readFileSync(filePath, "utf-8");
692
755
  } catch (err) {
693
756
  if (err.code === "ENOENT") return {};
694
- throw new Error(`${filePath} could not be read, so it was left untouched.`);
757
+ throw new AgentConfigError("config-unreadable", filePath, `${filePath} could not be read, so it was left untouched.`);
695
758
  }
696
759
  if (raw.trim() === "") return {};
697
760
  try {
698
761
  return parseTOML(raw);
699
762
  } catch {
700
763
  const backup = backupFile(filePath);
701
- throw new Error(
764
+ throw new AgentConfigError(
765
+ "config-unparseable",
766
+ filePath,
702
767
  `${filePath} is not valid TOML, so it was left untouched. A copy is at ${backup}. Fix or remove the original, then re-run setup.`
703
768
  );
704
769
  }
@@ -1178,13 +1243,15 @@ var installCursorUserHooks = (gateScript) => {
1178
1243
  if (existsSync(CURSOR_USER_HOOKS)) {
1179
1244
  const result = readJsonSafe(CURSOR_USER_HOOKS);
1180
1245
  if (result.kind === "ok") userHooks = result.value;
1181
- else {
1246
+ else if (result.kind !== "missing") {
1182
1247
  let backup = "";
1183
1248
  try {
1184
1249
  backup = backupFile(CURSOR_USER_HOOKS);
1185
1250
  } catch {
1186
1251
  }
1187
- throw new Error(
1252
+ throw new AgentConfigError(
1253
+ configFailureKind(result.kind),
1254
+ CURSOR_USER_HOOKS,
1188
1255
  `Could not parse or read Cursor hooks.json; left it untouched${backup ? ` and backed it up at ${backup}` : ""}. Fix the file, then re-run setup.`
1189
1256
  );
1190
1257
  }
@@ -1810,6 +1877,13 @@ var AGENT_CAPABILITIES = {
1810
1877
  ...compatibleRecord((profile) => profile.mcp ? "MCP + native hooks" : "native hooks"),
1811
1878
  custom: "any MCP or HTTP agent (Windsurf, n8n, custom)"
1812
1879
  };
1880
+ var failedAgentNames = (failures) => failures.map((failure) => AGENT_NAMES[failure.agent]);
1881
+ var printAgentFailures = (failures) => {
1882
+ for (const failure of describeAgentFailures(failures, (agent) => AGENT_NAMES[agent])) {
1883
+ console.log(` ${yellow("!")} ${failure.summary}`);
1884
+ console.log(` ${dim(RETRY_AGENT_LABEL)} ${cyan(failure.retryCommand)}`);
1885
+ }
1886
+ };
1813
1887
  var NAME_COLUMN = Math.max(...Object.values(AGENT_NAMES).map((name) => name.length)) + 2;
1814
1888
  var AGENT_LABELS = Object.fromEntries(
1815
1889
  Object.keys(AGENT_NAMES).map((agent) => [
@@ -2138,7 +2212,7 @@ var main = async () => {
2138
2212
  `This shell still exports the previous key (${keyPrefix(envKey)}), and it wins over the one just saved. Open a new terminal before starting an agent here, or re-export PUSHARY_API_KEY.`
2139
2213
  );
2140
2214
  }
2141
- const failed = [];
2215
+ const failures = [];
2142
2216
  const completed = [];
2143
2217
  const skipped = [];
2144
2218
  const hookOwners = [];
@@ -2157,9 +2231,10 @@ var main = async () => {
2157
2231
  if (keepAppWiring) {
2158
2232
  if (!await appAccountMatches(agent)) {
2159
2233
  hookOwners.push({ agent, owner: "app", kept: true });
2160
- failed.push(AGENT_NAMES[agent]);
2234
+ const failure = describedAgentFailure(agent, "app-account-mismatch");
2235
+ failures.push(failure);
2161
2236
  console.log(`
2162
- ${yellow("!")} ${AGENT_NAMES[agent]}: Mac app hooks kept, but their Pushary account could not be matched to this setup.`);
2237
+ ${yellow("!")} ${AGENT_NAMES[agent]}: ${failure.detail}`);
2163
2238
  console.log(` ${dim("Sign the Mac app into the same account and repair this agent, then re-run setup.")}`);
2164
2239
  console.log(` ${dim("Or pass --take-over-hooks if you intentionally want the CLI to own these hooks.")}`);
2165
2240
  continue;
@@ -2178,13 +2253,15 @@ var main = async () => {
2178
2253
  completed.push(agent);
2179
2254
  hookOwners.push({ agent, owner: hookOwnerFor(agent, appBridgeAvailable), kept: false });
2180
2255
  } else {
2181
- failed.push(AGENT_NAMES[agent]);
2182
- console.log(` ${yellow("!")} ${AGENT_NAMES[agent]} reported success but its config is not there.`);
2256
+ const failure = describedAgentFailure(agent, "not-wired");
2257
+ failures.push(failure);
2258
+ console.log(` ${yellow("!")} ${AGENT_NAMES[agent]} ${failure.detail}`);
2183
2259
  console.log(` ${dim("Re-run setup, then")} ${cyan("npx @pushary/agent-hooks@latest doctor")} ${dim("to see what is missing.")}`);
2184
2260
  }
2185
2261
  } catch (err) {
2186
- failed.push(AGENT_NAMES[agent]);
2187
- console.log(` ${yellow("!")} ${AGENT_NAMES[agent]} setup failed: ${formatError(err)}`);
2262
+ const failure = agentFailureFromError(agent, err, formatError);
2263
+ failures.push(failure);
2264
+ console.log(` ${yellow("!")} ${AGENT_NAMES[agent]} setup failed: ${failure.detail}`);
2188
2265
  console.log(` ${dim("Other agents will continue. Re-run setup to retry.")}`);
2189
2266
  }
2190
2267
  }
@@ -2192,9 +2269,9 @@ var main = async () => {
2192
2269
  console.log();
2193
2270
  console.log(` ${yellow("!")} Not configured: ${skipped.map((a) => a.replace("_", " ")).join(", ")} ${dim("(not installed on this machine)")}`);
2194
2271
  }
2195
- if (failed.length > 0) {
2272
+ if (failures.length > 0) {
2196
2273
  console.log();
2197
- console.log(` ${yellow("!")} Failed: ${failed.join(", ")} ${dim("(others completed successfully)")}`);
2274
+ console.log(` ${yellow("!")} Failed: ${failedAgentNames(failures).join(", ")} ${dim("(others completed successfully)")}`);
2198
2275
  console.log(` ${dim("Run")} npx @pushary/agent-hooks@latest doctor ${dim("for the reason, or send it to")} ${SUPPORT_EMAIL}`);
2199
2276
  }
2200
2277
  markStep("project-instructions");
@@ -2283,9 +2360,13 @@ var main = async () => {
2283
2360
  if (keyCheck.kind === "locked" || keyCheck.kind === "unreachable") {
2284
2361
  const report = describeKeyCheck(keyCheck);
2285
2362
  const next = [...report.next, "Finish activation: pushary setup (reuses the saved key)."];
2286
- const exitCode2 = failed.length > 0 || controlLifecycleFailure ? EXIT.PROBLEMS_FOUND : report.exitCode;
2363
+ const exitCode2 = failures.length > 0 || controlLifecycleFailure ? EXIT.PROBLEMS_FOUND : report.exitCode;
2287
2364
  printManualSteps();
2288
2365
  console.log(` ${yellow(bold(keyCheck.kind === "locked" ? "Agents configured, approvals inactive." : "Configuration saved, activation unverified."))}`);
2366
+ if (failures.length > 0) {
2367
+ console.log();
2368
+ printAgentFailures(failures);
2369
+ }
2289
2370
  console.log();
2290
2371
  console.log(` ${report.message}`);
2291
2372
  for (const line of next) console.log(` ${dim(line)}`);
@@ -2297,7 +2378,8 @@ var main = async () => {
2297
2378
  configured: completed,
2298
2379
  skipped,
2299
2380
  manualSteps,
2300
- failed,
2381
+ failed: failedAgentNames(failures),
2382
+ agentFailures: failures,
2301
2383
  keyCheck: keyCheck.kind,
2302
2384
  rc: rc.kind,
2303
2385
  control: controlMode,
@@ -2308,7 +2390,12 @@ var main = async () => {
2308
2390
  options,
2309
2391
  completed,
2310
2392
  skipped,
2311
- failed,
2393
+ failures,
2394
+ closingReason: unverifiedKeyClosingReason({
2395
+ failedCount: failures.length,
2396
+ controlLifecycleFailed: controlLifecycleFailure !== null,
2397
+ keyCheck: keyCheck.kind
2398
+ }),
2312
2399
  connectOutcome: "skipped",
2313
2400
  keyCheck: keyCheck.kind,
2314
2401
  exitCode: exitCode2
@@ -2317,7 +2404,7 @@ var main = async () => {
2317
2404
  }
2318
2405
  printManualSteps();
2319
2406
  const configuredNothing = agents.length > 0 && completed.length === 0;
2320
- const agentsOk = failed.length === 0 && !configuredNothing;
2407
+ const agentsOk = failures.length === 0 && !configuredNothing;
2321
2408
  const reachChecked = phone !== null;
2322
2409
  const reachesYou = phone?.reachesYou ?? true;
2323
2410
  markStep("closing");
@@ -2397,7 +2484,7 @@ var main = async () => {
2397
2484
  agentsOk,
2398
2485
  configuredNothing,
2399
2486
  completed,
2400
- failed,
2487
+ failed: failedAgentNames(failures),
2401
2488
  reachChecked,
2402
2489
  reachesYou,
2403
2490
  managedControlReady: !controlLifecycleFailure && managedControl.ready,
@@ -2408,10 +2495,10 @@ var main = async () => {
2408
2495
  roundTripAnswered: roundTrip === null ? null : roundTrip.kind === "answered" ? true : roundTrip.kind === "unanswered" ? false : null
2409
2496
  });
2410
2497
  console.log(` ${closing.ok ? green(bold(closing.headline)) : yellow(bold(closing.headline))}`);
2411
- if (failed.length > 0) {
2498
+ if (failures.length > 0) {
2412
2499
  console.log();
2413
2500
  for (const agent of completed) console.log(` ${check} ${AGENT_NAMES[agent] ?? agent}`);
2414
- for (const item of failed) console.log(` ${yellow("!")} ${item}`);
2501
+ printAgentFailures(failures);
2415
2502
  }
2416
2503
  const ownershipLine = describeHookOwnership(hookOwners, AGENT_NAMES);
2417
2504
  if (ownershipLine) console.log(` ${dim(ownershipLine)}`);
@@ -2426,7 +2513,8 @@ var main = async () => {
2426
2513
  options,
2427
2514
  completed,
2428
2515
  skipped,
2429
- failed,
2516
+ failures,
2517
+ closingReason: closing.reason,
2430
2518
  // 'answered' is finally reachable. It was in the enum from the start and
2431
2519
  // nothing produced it, because setup stopped at a delivered notification, so
2432
2520
  // the one value meaning "a human tapped" was never emitted by the command
@@ -2440,7 +2528,8 @@ var main = async () => {
2440
2528
  configured: completed,
2441
2529
  skipped,
2442
2530
  manualSteps,
2443
- failed,
2531
+ failed: failedAgentNames(failures),
2532
+ agentFailures: failures,
2444
2533
  hookOwners,
2445
2534
  keyCheck: keyCheck?.kind ?? "skipped",
2446
2535
  reach: phone === null ? "skipped" : phone.reachesYou ? "yours" : phone.outcome?.kind ?? phone.detail ?? "unreachable",
@@ -2460,7 +2549,7 @@ var main = async () => {
2460
2549
  exitCode
2461
2550
  });
2462
2551
  if (exitCode !== EXIT.OK) {
2463
- if (configuredNothing && failed.length === 0) {
2552
+ if (configuredNothing && failures.length === 0) {
2464
2553
  console.log(` ${yellow("!")} Nothing was configured: none of the agents you asked for are installed here.`);
2465
2554
  console.log(` ${dim("Your key is saved. Install one and re-run, or pass --agents none to accept this.")}`);
2466
2555
  console.log();
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  readLedgerSummary
4
- } from "../chunk-CH4QMWBM.js";
4
+ } from "../chunk-5UWV5GHM.js";
5
5
  import {
6
6
  exitOnHelpFlag
7
7
  } from "../chunk-P4BNYJ5Q.js";
@@ -9,7 +9,7 @@ import "../chunk-KZERVKTD.js";
9
9
  import {
10
10
  getApiKey
11
11
  } from "../chunk-OSJEMXSR.js";
12
- import "../chunk-A5ODW52C.js";
12
+ import "../chunk-CAS7GFWI.js";
13
13
  import "../chunk-EA3IELHP.js";
14
14
  import "../chunk-HWJW3CPO.js";
15
15