pushary 1.9.57 → 1.9.58

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 (92) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/{api-RQAY3A5V.js → api-WVXBM4MR.js} +7 -7
  3. package/dist/bin/pushary-bell-hook.js +15 -15
  4. package/dist/bin/pushary-bell.js +3 -3
  5. package/dist/bin/pushary-claude.js +15 -15
  6. package/dist/bin/pushary-clean.js +39 -36
  7. package/dist/bin/pushary-codex-bridge.js +10 -10
  8. package/dist/bin/pushary-codex-hook.js +19 -19
  9. package/dist/bin/pushary-codex-session.js +8 -6
  10. package/dist/bin/pushary-codex.js +8 -8
  11. package/dist/bin/pushary-connect.js +17 -16
  12. package/dist/bin/pushary-daemon.js +23 -23
  13. package/dist/bin/pushary-disconnect.js +17 -17
  14. package/dist/bin/pushary-doctor.js +28 -26
  15. package/dist/bin/pushary-elicitation-hook.js +16 -16
  16. package/dist/bin/pushary-gemini-bridge.js +5 -5
  17. package/dist/bin/pushary-gemini-hook.js +17 -17
  18. package/dist/bin/pushary-hook.js +18 -18
  19. package/dist/bin/pushary-login.js +6 -6
  20. package/dist/bin/pushary-logout.js +16 -16
  21. package/dist/bin/pushary-mcp.js +8 -8
  22. package/dist/bin/pushary-mode.js +6 -6
  23. package/dist/bin/pushary-notification-hook.js +15 -15
  24. package/dist/bin/pushary-opencode-hook.js +16 -16
  25. package/dist/bin/pushary-permission-denied-hook.js +18 -18
  26. package/dist/bin/pushary-permission-hook.js +18 -18
  27. package/dist/bin/pushary-post-hook.js +15 -15
  28. package/dist/bin/pushary-prompt-hook.js +15 -15
  29. package/dist/bin/pushary-session-end-hook.js +15 -15
  30. package/dist/bin/pushary-session-start-hook.js +21 -21
  31. package/dist/bin/pushary-setup.js +52 -255
  32. package/dist/bin/pushary-status.js +21 -19
  33. package/dist/bin/pushary-stop-hook.js +15 -15
  34. package/dist/bin/pushary-stopfailure-hook.js +15 -15
  35. package/dist/bin/pushary-suggestions.js +6 -6
  36. package/dist/bin/pushary-transcript-register.js +8 -8
  37. package/dist/bin/pushary-upgrade.js +97 -48
  38. package/dist/bin/pushary-wait.js +6 -6
  39. package/dist/bin/pushary.js +4 -4
  40. package/dist/{chunk-DDQRYX2L.js → chunk-3KOPY2UQ.js} +1 -1
  41. package/dist/{chunk-ZU6L34DQ.js → chunk-3WNOO7BM.js} +3 -3
  42. package/dist/{chunk-RFAF3TOX.js → chunk-4JJ3T7IE.js} +93 -14
  43. package/dist/{chunk-JCMSISCC.js → chunk-4LUPZ347.js} +1 -1
  44. package/dist/{chunk-HCIB4YNB.js → chunk-5DZHKNBU.js} +1 -1
  45. package/dist/{chunk-QQYUWTYS.js → chunk-ATUZX4K7.js} +1 -1
  46. package/dist/{chunk-CB565EVO.js → chunk-CK5BCFQF.js} +1 -1
  47. package/dist/{chunk-AN6TVB2H.js → chunk-CSQJCXPX.js} +3 -3
  48. package/dist/chunk-CZULJ647.js +378 -0
  49. package/dist/{chunk-6QM54CSJ.js → chunk-DQ565WFA.js} +3 -3
  50. package/dist/chunk-FAGDOPQI.js +266 -0
  51. package/dist/{chunk-QLDTBZBP.js → chunk-HRHAZ3GE.js} +5 -5
  52. package/dist/{chunk-NQDEMRAS.js → chunk-HUWLEVL2.js} +2 -2
  53. package/dist/{chunk-SQ5G6A6K.js → chunk-IJ6XKKQW.js} +1 -1
  54. package/dist/{chunk-BAJ3A3BU.js → chunk-JZKEC4XJ.js} +4 -1
  55. package/dist/{chunk-ZZB4J6CX.js → chunk-K5CAURU5.js} +3 -3
  56. package/dist/{chunk-7OQ4AJC7.js → chunk-KIH5BDH5.js} +2 -7
  57. package/dist/{chunk-CUEUANIU.js → chunk-KSVCCSAO.js} +3 -3
  58. package/dist/{chunk-D2EETYAL.js → chunk-KW6EYFZV.js} +11 -366
  59. package/dist/{chunk-LW7IWGSV.js → chunk-MCHOBQHE.js} +4 -4
  60. package/dist/{chunk-TWLWDIFB.js → chunk-MYBCXDIL.js} +3 -1
  61. package/dist/{chunk-4QD7VE4E.js → chunk-OHD35NPC.js} +1 -1
  62. package/dist/{chunk-3IBUZQKM.js → chunk-PZOFPAPG.js} +1 -1
  63. package/dist/{chunk-YKYVDHIY.js → chunk-QDFLBTUP.js} +1 -1
  64. package/dist/{chunk-Z7Q36I4K.js → chunk-QP3XPS5U.js} +8 -4
  65. package/dist/{chunk-4YTFYILS.js → chunk-RF74KBF5.js} +4 -4
  66. package/dist/{chunk-K5SDLOFS.js → chunk-RGQEULXD.js} +6 -6
  67. package/dist/{chunk-FBKVCODG.js → chunk-S54YLXWW.js} +1 -1
  68. package/dist/{chunk-PZDMZ7LM.js → chunk-T2AC5VFQ.js} +3 -3
  69. package/dist/{chunk-OLNBYAPI.js → chunk-T2BEIPK2.js} +2 -2
  70. package/dist/{chunk-W6363YYZ.js → chunk-TN74MUMB.js} +3 -3
  71. package/dist/{chunk-2NIRYGTK.js → chunk-UMVVQXAC.js} +2 -2
  72. package/dist/{chunk-K45CFSYV.js → chunk-VLJ5C6IT.js} +1 -1
  73. package/dist/{chunk-LVZYIUSR.js → chunk-VPZ5K72D.js} +1 -1
  74. package/dist/{chunk-AEXACKDR.js → chunk-WVP6UQG3.js} +3 -3
  75. package/dist/{chunk-T45PAPOG.js → chunk-X6F4BQEE.js} +3 -3
  76. package/dist/{chunk-2PJENKRJ.js → chunk-XEJV3QSS.js} +76 -29
  77. package/dist/{chunk-IBSRULIY.js → chunk-XFUKCBPU.js} +8 -8
  78. package/dist/{chunk-UPFFO4F6.js → chunk-XWY4UW62.js} +3 -3
  79. package/dist/{chunk-DS6OR5OS.js → chunk-ZEHUWE3X.js} +3 -3
  80. package/dist/{chunk-OZSP4RIQ.js → chunk-ZJNU32VE.js} +21 -6
  81. package/dist/{chunk-A54W5A74.js → chunk-ZL3UR6M5.js} +2 -2
  82. package/dist/{codex-app-cards-switch-SVGTZ2UN.js → codex-app-cards-switch-TVKXJWXE.js} +16 -14
  83. package/dist/{codex-desktop-launch-SH7OUEEC.js → codex-desktop-launch-ROTJEEGF.js} +3 -1
  84. package/dist/{codex-session-launch-IQ57OL3N.js → codex-session-launch-VL6ZQA3N.js} +10 -10
  85. package/dist/{global-upgrade-SRCWQE7N.js → global-upgrade-IPWV5PTM.js} +13 -5
  86. package/dist/{identity-6KRUO2YO.js → identity-ARPAUNGN.js} +3 -3
  87. package/dist/{live-capabilities-RKUHAWT6.js → live-capabilities-EWTRY2HA.js} +2 -2
  88. package/dist/{paths-MUPQZNLG.js → paths-IZTNMJAQ.js} +4 -2
  89. package/dist/{reapply-YZXZCWCI.js → reapply-ILKOYYKA.js} +17 -17
  90. package/dist/src/index.js +13 -13
  91. package/dist/{upgrade-lock-JXP27UKI.js → upgrade-lock-ML73QXIG.js} +3 -5
  92. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  exitOnFailedSettingsRequest
4
- } from "../chunk-K45CFSYV.js";
4
+ } from "../chunk-VLJ5C6IT.js";
5
5
  import "../chunk-4YNNAF53.js";
6
6
  import {
7
7
  createIo
@@ -13,9 +13,9 @@ import {
13
13
  rejectUnknownFlags
14
14
  } from "../chunk-GMXKITVA.js";
15
15
  import "../chunk-IRZ5FVWG.js";
16
- import "../chunk-FBKVCODG.js";
17
- import "../chunk-HCIB4YNB.js";
18
- import "../chunk-SQ5G6A6K.js";
16
+ import "../chunk-S54YLXWW.js";
17
+ import "../chunk-5DZHKNBU.js";
18
+ import "../chunk-IJ6XKKQW.js";
19
19
  import {
20
20
  UsageError
21
21
  } from "../chunk-7QLSKOSU.js";
@@ -23,8 +23,8 @@ import {
23
23
  EXIT
24
24
  } from "../chunk-KZERVKTD.js";
25
25
  import "../chunk-7RZO6VWD.js";
26
- import "../chunk-TWLWDIFB.js";
27
- import "../chunk-AEXACKDR.js";
26
+ import "../chunk-MYBCXDIL.js";
27
+ import "../chunk-WVP6UQG3.js";
28
28
  import "../chunk-QENTGE75.js";
29
29
  import {
30
30
  getApiKey,
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  registerTranscript
4
- } from "../chunk-W6363YYZ.js";
4
+ } from "../chunk-TN74MUMB.js";
5
5
  import "../chunk-QW3FRUFB.js";
6
- import "../chunk-Z7Q36I4K.js";
7
- import "../chunk-CUEUANIU.js";
8
- import "../chunk-QQYUWTYS.js";
6
+ import "../chunk-QP3XPS5U.js";
7
+ import "../chunk-KSVCCSAO.js";
8
+ import "../chunk-ATUZX4K7.js";
9
9
  import "../chunk-ECJJKDP7.js";
10
- import "../chunk-YKYVDHIY.js";
10
+ import "../chunk-QDFLBTUP.js";
11
11
  import "../chunk-GMXKITVA.js";
12
12
  import "../chunk-JSQOHMNJ.js";
13
13
  import "../chunk-N3NSWWNU.js";
@@ -16,12 +16,12 @@ import "../chunk-XHKBHWLX.js";
16
16
  import "../chunk-6ICPEJY5.js";
17
17
  import "../chunk-IRZ5FVWG.js";
18
18
  import "../chunk-QTCFEKLJ.js";
19
- import "../chunk-SQ5G6A6K.js";
19
+ import "../chunk-IJ6XKKQW.js";
20
20
  import "../chunk-7QLSKOSU.js";
21
21
  import "../chunk-KZERVKTD.js";
22
22
  import "../chunk-7RZO6VWD.js";
23
- import "../chunk-TWLWDIFB.js";
24
- import "../chunk-AEXACKDR.js";
23
+ import "../chunk-MYBCXDIL.js";
24
+ import "../chunk-WVP6UQG3.js";
25
25
  import "../chunk-QENTGE75.js";
26
26
  import "../chunk-LVDC3RUE.js";
27
27
  import "../chunk-5SFM6XB4.js";
@@ -1,42 +1,52 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  FINISH_UPGRADE_FLAG,
4
+ describeUnreadyService,
4
5
  finishGlobalUpgrade,
5
6
  finishUpgradeWithLock,
7
+ forgetUnfinishedUpgrade,
6
8
  instructionsLeftNoteOf,
9
+ phoneStartFellShortWithoutFailing,
10
+ phoneStartServiceAfter,
7
11
  readGlobalUpgradeSubject,
12
+ recordUnfinishedUpgrade,
8
13
  refreshedPartsOf,
9
14
  runAutoUpdate,
15
+ serviceStaysOwedBack,
10
16
  upgradeFinishExitCode,
11
17
  upgradeFinishOutcome,
12
18
  upgradeInstalledPackage,
13
19
  wasRefreshed,
14
20
  withUpgradeLock
15
- } from "../chunk-RFAF3TOX.js";
21
+ } from "../chunk-4JJ3T7IE.js";
16
22
  import {
17
23
  installWithUpgradeLock
18
- } from "../chunk-7OQ4AJC7.js";
24
+ } from "../chunk-KIH5BDH5.js";
25
+ import {
26
+ phoneStartFellShortLine
27
+ } from "../chunk-FAGDOPQI.js";
19
28
  import {
20
29
  ensureCodexTrustAfterReapply,
21
30
  reapplyAllAgents
22
- } from "../chunk-IBSRULIY.js";
31
+ } from "../chunk-XFUKCBPU.js";
23
32
  import {
24
33
  describeCodexTrustConfirmation
25
- } from "../chunk-4QD7VE4E.js";
34
+ } from "../chunk-OHD35NPC.js";
35
+ import "../chunk-CZULJ647.js";
26
36
  import {
27
37
  waitForMachineReadiness
28
- } from "../chunk-AN6TVB2H.js";
29
- import "../chunk-2NIRYGTK.js";
38
+ } from "../chunk-CSQJCXPX.js";
39
+ import "../chunk-UMVVQXAC.js";
30
40
  import {
31
41
  readMacAppAgentKey
32
- } from "../chunk-OLNBYAPI.js";
42
+ } from "../chunk-T2BEIPK2.js";
33
43
  import {
34
44
  fxServerHolder,
35
45
  macAppFxBridge,
36
46
  retryAgentCommand
37
- } from "../chunk-NQDEMRAS.js";
38
- import "../chunk-JCMSISCC.js";
39
- import "../chunk-PZDMZ7LM.js";
47
+ } from "../chunk-HUWLEVL2.js";
48
+ import "../chunk-4LUPZ347.js";
49
+ import "../chunk-T2AC5VFQ.js";
40
50
  import {
41
51
  exitOnHelpFlag
42
52
  } from "../chunk-M7NX25ZA.js";
@@ -45,7 +55,7 @@ import {
45
55
  expectedLaunchCapabilities,
46
56
  hasSpawnProvider,
47
57
  resolveControlPolicy
48
- } from "../chunk-DDQRYX2L.js";
58
+ } from "../chunk-3KOPY2UQ.js";
49
59
  import "../chunk-LVWXRXT7.js";
50
60
  import "../chunk-VUFHYMSP.js";
51
61
  import {
@@ -57,11 +67,12 @@ import {
57
67
  parseAutoUpdateFlag,
58
68
  readAutoUpdateState,
59
69
  updateAutoUpdateState
60
- } from "../chunk-BAJ3A3BU.js";
61
- import "../chunk-UPFFO4F6.js";
70
+ } from "../chunk-JZKEC4XJ.js";
71
+ import "../chunk-XWY4UW62.js";
62
72
  import {
63
73
  DAEMON_COLD_START_TIMEOUT_MS,
64
74
  daemonHasRemoteProof,
75
+ daemonProcessIsThere,
65
76
  daemonServiceManagerAvailable,
66
77
  disableDaemonService,
67
78
  ensureDaemonRunning,
@@ -70,11 +81,11 @@ import {
70
81
  replaceDaemonService,
71
82
  stopDaemonService,
72
83
  waitForDaemonRemoteProof
73
- } from "../chunk-Z7Q36I4K.js";
74
- import "../chunk-CUEUANIU.js";
75
- import "../chunk-QQYUWTYS.js";
84
+ } from "../chunk-QP3XPS5U.js";
85
+ import "../chunk-KSVCCSAO.js";
86
+ import "../chunk-ATUZX4K7.js";
76
87
  import "../chunk-ECJJKDP7.js";
77
- import "../chunk-YKYVDHIY.js";
88
+ import "../chunk-QDFLBTUP.js";
78
89
  import "../chunk-GMXKITVA.js";
79
90
  import "../chunk-XHKBHWLX.js";
80
91
  import "../chunk-6ICPEJY5.js";
@@ -82,15 +93,15 @@ import {
82
93
  readControlMode,
83
94
  recordMacAppKeyPrefix
84
95
  } from "../chunk-IRZ5FVWG.js";
85
- import "../chunk-4YTFYILS.js";
96
+ import "../chunk-RF74KBF5.js";
86
97
  import "../chunk-QTCFEKLJ.js";
87
98
  import "../chunk-XXNT4FGA.js";
88
- import "../chunk-6QM54CSJ.js";
89
- import "../chunk-A54W5A74.js";
99
+ import "../chunk-DQ565WFA.js";
100
+ import "../chunk-ZL3UR6M5.js";
90
101
  import "../chunk-POFBE6ZY.js";
91
- import "../chunk-FBKVCODG.js";
92
- import "../chunk-HCIB4YNB.js";
93
- import "../chunk-SQ5G6A6K.js";
102
+ import "../chunk-S54YLXWW.js";
103
+ import "../chunk-5DZHKNBU.js";
104
+ import "../chunk-IJ6XKKQW.js";
94
105
  import "../chunk-7QLSKOSU.js";
95
106
  import {
96
107
  EXIT
@@ -104,13 +115,16 @@ import {
104
115
  fxMcpProfile,
105
116
  geminiSettings,
106
117
  pusharyDir,
118
+ serviceOwedBackMark,
107
119
  vscodePluginDir
108
- } from "../chunk-TWLWDIFB.js";
120
+ } from "../chunk-MYBCXDIL.js";
109
121
  import {
110
122
  LATEST_TAG,
111
123
  fetchLatestPublishedVersion
112
- } from "../chunk-AEXACKDR.js";
113
- import "../chunk-QENTGE75.js";
124
+ } from "../chunk-WVP6UQG3.js";
125
+ import {
126
+ writeFileAtomic
127
+ } from "../chunk-QENTGE75.js";
114
128
  import {
115
129
  getApiKey
116
130
  } from "../chunk-LVDC3RUE.js";
@@ -125,9 +139,26 @@ import {
125
139
  import "../chunk-GZL3KEPC.js";
126
140
 
127
141
  // bin/pushary-upgrade.ts
128
- import { existsSync } from "fs";
142
+ import { existsSync as existsSync2 } from "fs";
129
143
  import { homedir } from "os";
130
144
  import { join } from "path";
145
+
146
+ // src/service-owed-back.ts
147
+ import { existsSync, mkdirSync, rmSync } from "fs";
148
+ import { dirname } from "path";
149
+ var MARK_MODE = 384;
150
+ var serviceIsOwedBack = (markPath) => existsSync(markPath);
151
+ var recordWhetherTheServiceIsOwedBack = (markPath, owed) => {
152
+ if (owed === serviceIsOwedBack(markPath)) return;
153
+ if (!owed) {
154
+ rmSync(markPath, { force: true });
155
+ return;
156
+ }
157
+ mkdirSync(dirname(markPath), { recursive: true });
158
+ writeFileAtomic(markPath, "", MARK_MODE);
159
+ };
160
+
161
+ // bin/pushary-upgrade.ts
131
162
  exitOnHelpFlag("upgrade");
132
163
  var fxWiredByCli = () => fxServerHolder(fxMcpProfile(), macAppFxBridge(pusharyDir())) === "cli";
133
164
  var detectInstallModes = () => {
@@ -135,32 +166,32 @@ var detectInstallModes = () => {
135
166
  {
136
167
  label: "Cursor plugin",
137
168
  upgrade: "updates itself through Cursor",
138
- present: existsSync(cursorPluginDir())
169
+ present: existsSync2(cursorPluginDir())
139
170
  },
140
171
  {
141
172
  label: "VS Code plugin",
142
173
  upgrade: `${NPX_LATEST_COMMAND} setup --agents vscode`,
143
- present: existsSync(vscodePluginDir())
174
+ present: existsSync2(vscodePluginDir())
144
175
  },
145
176
  {
146
177
  label: "Codex config",
147
178
  upgrade: `${NPX_LATEST_COMMAND} setup --agents codex`,
148
- present: existsSync(codexConfigToml())
179
+ present: existsSync2(codexConfigToml())
149
180
  },
150
181
  {
151
182
  label: "Claude Code config",
152
183
  upgrade: `${NPX_LATEST_COMMAND} setup --agents claude_code`,
153
- present: existsSync(claudeJson())
184
+ present: existsSync2(claudeJson())
154
185
  },
155
186
  {
156
187
  label: "Gemini config",
157
188
  upgrade: `${NPX_LATEST_COMMAND} setup --agents gemini_cli`,
158
- present: existsSync(geminiSettings())
189
+ present: existsSync2(geminiSettings())
159
190
  },
160
191
  {
161
192
  label: "Hermes plugin (pip)",
162
193
  upgrade: `${NPX_LATEST_COMMAND} setup --agents hermes`,
163
- present: existsSync(join(homedir(), ".hermes"))
194
+ present: existsSync2(join(homedir(), ".hermes"))
164
195
  },
165
196
  {
166
197
  label: "fx config",
@@ -191,6 +222,7 @@ var finishUpgrade = async () => {
191
222
  const configuredControlProviders = inspectedAgents.filter((agent) => agent.result.configured && (agent.id === "claude" || agent.id === "codex" || agent.id === "gemini")).map((agent) => agent.id);
192
223
  const controlMode = readControlMode();
193
224
  const daemonStatus = readDaemonStatus();
225
+ const serviceWasOwedBack = serviceIsOwedBack(serviceOwedBackMark());
194
226
  const serviceWasPresent = daemonStatus.kind !== "absent" || hasDaemonServiceDefinition();
195
227
  const controlCapabilities = detectProviderLiveCapabilities(configuredControlProviders);
196
228
  const controlPolicy = resolveControlPolicy({
@@ -199,6 +231,8 @@ var finishUpgrade = async () => {
199
231
  managerAvailable: daemonServiceManagerAvailable(),
200
232
  servicePresent: serviceWasPresent
201
233
  });
234
+ const serviceWasRunning = daemonProcessIsThere(daemonStatus) || serviceWasOwedBack;
235
+ const serviceStart = controlPolicy === "enabled" && apiKey ? await replaceBackgroundService(apiKey, configuredControlProviders, serviceWasRunning) : "not_tried";
202
236
  let daemonReady = true;
203
237
  let legacyStopFailure = null;
204
238
  if (controlPolicy === "disabled" && serviceWasPresent) {
@@ -208,20 +242,14 @@ var finishUpgrade = async () => {
208
242
  legacyStopFailure = stopped.kind === "ok" ? null : stopped.detail;
209
243
  daemonReady = false;
210
244
  } else if (controlPolicy === "enabled") {
211
- if (!apiKey) {
212
- daemonReady = false;
213
- } else {
214
- const service = await replaceDaemonService();
215
- const daemon = service.kind === "ok" ? await ensureDaemonRunning({ spawnDaemon: () => {
216
- }, waitTimeoutMs: DAEMON_COLD_START_TIMEOUT_MS }) : null;
217
- const localProof = daemon?.kind === "running" || daemon?.kind === "started" ? await waitForDaemonRemoteProof() : null;
218
- const serverProof = localProof && daemonHasRemoteProof(localProof) ? await waitForMachineReadiness(apiKey, expectedLaunchCapabilities(configuredControlProviders)) : null;
219
- daemonReady = service.kind === "ok" && localProof !== null && daemonHasRemoteProof(localProof) && (serverProof?.kind === "ready" || serverProof?.kind === "unsupported");
220
- }
245
+ daemonReady = serviceStart === "verified";
221
246
  } else if (controlMode === "on" && controlPolicy === "unsupported") {
222
247
  daemonReady = false;
223
248
  }
224
- const finishOutcome = upgradeFinishOutcome({ controlMode, controlPolicy, daemonReady, failedRefreshCount: failedRefreshes.length });
249
+ const finishReadings = { controlMode, controlPolicy, daemonReady, serviceStart, serviceWasRunning, failedRefreshCount: failedRefreshes.length };
250
+ const finishOutcome = upgradeFinishOutcome(finishReadings);
251
+ recordWhetherTheServiceIsOwedBack(serviceOwedBackMark(), serviceStaysOwedBack(finishReadings, serviceWasOwedBack));
252
+ const phoneStartNote = phoneStartFellShortWithoutFailing(finishReadings) ? phoneStartFellShortLine(phoneStartServiceAfter(serviceStart)) : null;
225
253
  console.log();
226
254
  if (refreshed.length > 0) {
227
255
  console.log("Refreshed so this version is active now:");
@@ -250,20 +278,38 @@ var finishUpgrade = async () => {
250
278
  console.log(describeCodexTrustConfirmation(codexTrust));
251
279
  }
252
280
  console.log();
253
- if (!daemonReady) {
254
- console.error(controlPolicy === "disabled" ? "Upgrade installed, but the disabled background service could not be fully removed. Re-run setup with --control off." : controlPolicy === "legacy" ? legacyStopFailure ? `Upgrade installed, but the legacy background service could not be stopped: ${legacyStopFailure}. Run setup with --control off.` : "Upgrade installed and the legacy background service was stopped, but it cannot be safely adopted. Run setup with --control off, or restore its provider and native service manager." : controlPolicy === "enabled" && !apiKey ? "Upgrade installed, but phone-start could not be reconciled because no API key was readable. Re-run setup." : "Upgrade installed, but the background service did not start. Run: pushary daemon install");
281
+ if (!daemonReady && phoneStartNote === null) {
282
+ console.error(describeUnreadyService({ controlPolicy, legacyStopFailure, keyReadable: Boolean(apiKey), serviceStart }));
255
283
  process.exitCode = upgradeFinishExitCode(finishOutcome);
256
284
  return;
257
285
  }
258
286
  if (failedRefreshes.length > 0) {
287
+ if (phoneStartNote !== null) console.log(phoneStartNote);
259
288
  console.error(`Upgrade installed, but refreshing agent configuration failed for: ${failedRefreshes.map((agent) => agent.label).join(", ")}. Check the config files and run pushary upgrade again.`);
260
289
  process.exitCode = upgradeFinishExitCode(finishOutcome);
261
290
  return;
262
291
  }
263
- console.log(controlPolicy === "disabled" ? "Done. Your hooks use the new global install; phone-start remains disabled." : controlPolicy === "unsupported" || controlPolicy === "preserve-absent" ? "Done. Your hooks use the new global install; no background service was added." : "Done. Your hooks and background service use the new global install.");
292
+ console.log(controlPolicy === "disabled" ? "Done. Your hooks use the new global install; phone-start remains disabled." : controlPolicy === "unsupported" || controlPolicy === "preserve-absent" ? "Done. Your hooks use the new global install; no background service was added." : phoneStartNote === null ? "Done. Your hooks and background service use the new global install." : "Done. Your hooks use the new global install.");
293
+ if (phoneStartNote !== null) console.log(phoneStartNote);
264
294
  console.log("Verify with: pushary doctor");
265
295
  };
266
- var INSTRUCTIONS_LEFT_HEADING = "Pushary instructions left as they were. Fix the file, then run pushary upgrade again:";
296
+ var startBackgroundService = async (apiKey, providers) => {
297
+ const service = await replaceDaemonService();
298
+ if (service.kind !== "ok") return "did_not_start";
299
+ const daemon = await ensureDaemonRunning({ spawnDaemon: () => {
300
+ }, waitTimeoutMs: DAEMON_COLD_START_TIMEOUT_MS });
301
+ if (daemon.kind !== "running" && daemon.kind !== "started") return "did_not_start";
302
+ const localProof = await waitForDaemonRemoteProof();
303
+ if (localProof.kind !== "running") return "did_not_start";
304
+ if (!daemonHasRemoteProof(localProof)) return "started_unverified";
305
+ const serverProof = await waitForMachineReadiness(apiKey, expectedLaunchCapabilities(providers));
306
+ return serverProof.kind === "ready" || serverProof.kind === "unsupported" ? "verified" : "started_unverified";
307
+ };
308
+ var replaceBackgroundService = async (apiKey, providers, serviceWasRunning) => {
309
+ if (serviceWasRunning) recordWhetherTheServiceIsOwedBack(serviceOwedBackMark(), true);
310
+ return startBackgroundService(apiKey, providers);
311
+ };
312
+ var INSTRUCTIONS_LEFT_HEADING = "Pushary instructions left as they were. Fix the file and the next update refreshes them:";
267
313
  var KEPT_FOR_APP_HEADING = "Kept for the Pushary Mac app, which owns these agents. Nothing in their config was changed:";
268
314
  var AUTO_UPDATE_ON_MESSAGE = "Automatic updates are on. Pushary checks for a new version once a day, when an agent session starts.";
269
315
  var AUTO_UPDATE_OFF_MESSAGE = "Automatic updates are off. Turn them back on with: pushary upgrade --auto=on";
@@ -326,6 +372,7 @@ var reportNoGlobalInstall = () => {
326
372
  console.log();
327
373
  console.log("Check the result with: pushary doctor");
328
374
  };
375
+ var upgradeRecordNow = () => ({ statePath: autoUpdateState(), installed: readGlobalUpgradeSubject(), at: (/* @__PURE__ */ new Date()).toISOString() });
329
376
  var upgradeSubject = async (subject) => {
330
377
  const outcome = await upgradeInstalledPackage(subject, {
331
378
  fetchLatest: (packageName) => fetchLatestPublishedVersion({ packageName }),
@@ -333,6 +380,8 @@ var upgradeSubject = async (subject) => {
333
380
  recordFinished: () => {
334
381
  updateAutoUpdateState(autoUpdateState(), { lastResult: "updated", detail: void 0, announced: false, finishAttempts: void 0 });
335
382
  },
383
+ recordUnfinished: (unfinished) => recordUnfinishedUpgrade(upgradeRecordNow(), unfinished),
384
+ forgetUnfinished: () => forgetUnfinishedUpgrade(upgradeRecordNow(), subject.version),
336
385
  announce: (line) => console.log(line),
337
386
  install: (packageName) => installWithUpgradeLock({ packageName, version: LATEST_TAG, timeoutMs: 12e4 }),
338
387
  finish: (installedSubject) => finishGlobalUpgrade(installedSubject)
@@ -4,7 +4,7 @@ import {
4
4
  } from "../chunk-CVWG2N3Y.js";
5
5
  import {
6
6
  exitOnFailedSettingsRequest
7
- } from "../chunk-K45CFSYV.js";
7
+ } from "../chunk-VLJ5C6IT.js";
8
8
  import "../chunk-4YNNAF53.js";
9
9
  import {
10
10
  createIo
@@ -16,9 +16,9 @@ import {
16
16
  rejectUnknownFlags
17
17
  } from "../chunk-GMXKITVA.js";
18
18
  import "../chunk-IRZ5FVWG.js";
19
- import "../chunk-FBKVCODG.js";
20
- import "../chunk-HCIB4YNB.js";
21
- import "../chunk-SQ5G6A6K.js";
19
+ import "../chunk-S54YLXWW.js";
20
+ import "../chunk-5DZHKNBU.js";
21
+ import "../chunk-IJ6XKKQW.js";
22
22
  import {
23
23
  UsageError
24
24
  } from "../chunk-7QLSKOSU.js";
@@ -26,8 +26,8 @@ import {
26
26
  EXIT
27
27
  } from "../chunk-KZERVKTD.js";
28
28
  import "../chunk-7RZO6VWD.js";
29
- import "../chunk-TWLWDIFB.js";
30
- import "../chunk-AEXACKDR.js";
29
+ import "../chunk-MYBCXDIL.js";
30
+ import "../chunk-WVP6UQG3.js";
31
31
  import "../chunk-QENTGE75.js";
32
32
  import {
33
33
  getApiKey,
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  installNetworkDefaults
4
- } from "../chunk-HCIB4YNB.js";
5
- import "../chunk-SQ5G6A6K.js";
4
+ } from "../chunk-5DZHKNBU.js";
5
+ import "../chunk-IJ6XKKQW.js";
6
6
  import "../chunk-7QLSKOSU.js";
7
7
  import {
8
8
  EXIT
9
9
  } from "../chunk-KZERVKTD.js";
10
- import "../chunk-TWLWDIFB.js";
11
- import "../chunk-AEXACKDR.js";
10
+ import "../chunk-MYBCXDIL.js";
11
+ import "../chunk-WVP6UQG3.js";
12
12
  import "../chunk-QENTGE75.js";
13
13
  import "../chunk-LVDC3RUE.js";
14
14
  import {
@@ -13,7 +13,7 @@ import {
13
13
  resolvePackageVersionFromBinary,
14
14
  resolvePathBinary,
15
15
  resolvePathBinaryAsync
16
- } from "./chunk-AEXACKDR.js";
16
+ } from "./chunk-WVP6UQG3.js";
17
17
  import {
18
18
  MANAGED_PROVIDERS
19
19
  } from "./chunk-GZL3KEPC.js";
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  compatibleConfigFile,
3
3
  hasCompatibleHooks
4
- } from "./chunk-UPFFO4F6.js";
4
+ } from "./chunk-XWY4UW62.js";
5
5
  import {
6
6
  pusharyHookExecutable
7
- } from "./chunk-CUEUANIU.js";
7
+ } from "./chunk-KSVCCSAO.js";
8
8
  import {
9
9
  isProtectedByScope,
10
10
  registerHookEntry
11
- } from "./chunk-TWLWDIFB.js";
11
+ } from "./chunk-MYBCXDIL.js";
12
12
  import {
13
13
  isRecord
14
14
  } from "./chunk-GZL3KEPC.js";
@@ -1,20 +1,24 @@
1
1
  import {
2
2
  claimUpgradeLock,
3
- finishWithUpgradeLock,
4
3
  forkFinishWithUpgradeLock,
5
4
  installWithUpgradeLock,
6
5
  releaseAutoUpdateLock
7
- } from "./chunk-7OQ4AJC7.js";
6
+ } from "./chunk-KIH5BDH5.js";
7
+ import {
8
+ phoneStartIsRequired
9
+ } from "./chunk-3KOPY2UQ.js";
8
10
  import {
9
11
  describeAutoUpdateCheck,
10
12
  globalInstallLocation,
11
13
  hasRetryableUpgradeFinish,
12
14
  hasSettledUpgradeFinish,
15
+ holdsUnfinishedFinish,
13
16
  nextFinishAttempt,
17
+ pendingAutoUpdateAnnouncement,
14
18
  readAutoUpdateState,
15
19
  updateAutoUpdateState,
16
20
  upgradeEntryFor
17
- } from "./chunk-BAJ3A3BU.js";
21
+ } from "./chunk-JZKEC4XJ.js";
18
22
  import {
19
23
  EXIT
20
24
  } from "./chunk-KZERVKTD.js";
@@ -22,14 +26,14 @@ import {
22
26
  autoUpdateLock,
23
27
  autoUpdateLog,
24
28
  autoUpdateState
25
- } from "./chunk-TWLWDIFB.js";
29
+ } from "./chunk-MYBCXDIL.js";
26
30
  import {
27
31
  execNpm,
28
32
  fetchLatestPublishedVersion,
29
33
  npmErrorMessage,
30
34
  readGlobalCliInstallAt,
31
35
  readGlobalPrefix
32
- } from "./chunk-AEXACKDR.js";
36
+ } from "./chunk-WVP6UQG3.js";
33
37
  import {
34
38
  NPX_LATEST_COMMAND
35
39
  } from "./chunk-5SFM6XB4.js";
@@ -75,8 +79,29 @@ var instructionsLeftNoteOf = (agent) => {
75
79
  var RETRYABLE_UPGRADE_FINISH = { kind: "retryable" };
76
80
  var SETTLED_UPGRADE_FINISH = { kind: "settled" };
77
81
  var controlWaitsOnThePerson = (readings) => readings.controlPolicy === "legacy" || readings.controlMode === "on" && readings.controlPolicy === "unsupported";
82
+ var serviceStartFellShort = (start) => start === "did_not_start" || start === "started_unverified";
83
+ var aRunningServiceDidNotComeBack = (readings) => readings.serviceWasRunning && readings.serviceStart === "did_not_start";
84
+ var phoneStartFellShortWithoutFailing = (readings) => serviceStartFellShort(readings.serviceStart) && !aRunningServiceDidNotComeBack(readings) && !phoneStartIsRequired({ mode: readings.controlMode, policy: readings.controlPolicy, lifecycleFailed: false });
85
+ var serviceCameBack = (start) => start === "verified" || start === "started_unverified";
86
+ var serviceStaysOwedBack = (readings, owedBefore) => readings.controlPolicy !== "disabled" && !serviceCameBack(readings.serviceStart) && (owedBefore || aRunningServiceDidNotComeBack(readings));
87
+ var phoneStartServiceAfter = (start) => start === "started_unverified" ? "running_unverified" : "not_running";
88
+ var DISABLED_SERVICE_NOT_REMOVED = "Upgrade installed, but the disabled background service could not be fully removed. Re-run setup with --control off.";
89
+ var LEGACY_SERVICE_NOT_ADOPTED = "Upgrade installed and the legacy background service was stopped, but it cannot be safely adopted. Run setup with --control off, or restore its provider and native service manager.";
90
+ var NO_KEY_FOR_PHONE_START = "Upgrade installed, but phone-start could not be reconciled because no API key was readable. Re-run setup.";
91
+ var PHONE_START_CANNOT_RUN_HERE = "Upgrade installed, but phone-start is required on this computer and cannot run here yet. Run pushary doctor to see what it needs.";
92
+ var SERVICE_STARTED_UNVERIFIED = "Upgrade installed, and the background service started, but it was not verified in time. Check it with: pushary doctor";
93
+ var SERVICE_DID_NOT_START = "Upgrade installed, but the background service did not start. Run: pushary daemon install";
94
+ var describeLegacyService = (stopFailure) => stopFailure ? `Upgrade installed, but the legacy background service could not be stopped: ${stopFailure}. Run setup with --control off.` : LEGACY_SERVICE_NOT_ADOPTED;
95
+ var describeUnreadyService = (service) => {
96
+ if (service.controlPolicy === "disabled") return DISABLED_SERVICE_NOT_REMOVED;
97
+ if (service.controlPolicy === "legacy") return describeLegacyService(service.legacyStopFailure);
98
+ if (service.controlPolicy === "enabled" && !service.keyReadable) return NO_KEY_FOR_PHONE_START;
99
+ if (service.controlPolicy === "unsupported") return PHONE_START_CANNOT_RUN_HERE;
100
+ return service.serviceStart === "started_unverified" ? SERVICE_STARTED_UNVERIFIED : SERVICE_DID_NOT_START;
101
+ };
102
+ var serviceFailedTheFinish = (readings) => !readings.daemonReady && !phoneStartFellShortWithoutFailing(readings);
78
103
  var upgradeFinishOutcome = (readings) => {
79
- if (!readings.daemonReady) return controlWaitsOnThePerson(readings) ? SETTLED_UPGRADE_FINISH : RETRYABLE_UPGRADE_FINISH;
104
+ if (serviceFailedTheFinish(readings)) return controlWaitsOnThePerson(readings) ? SETTLED_UPGRADE_FINISH : RETRYABLE_UPGRADE_FINISH;
80
105
  return readings.failedRefreshCount > 0 ? SETTLED_UPGRADE_FINISH : FINISHED_UPGRADE;
81
106
  };
82
107
  var UPGRADE_FINISH_EXIT_CODES = {
@@ -244,15 +269,19 @@ var readGlobalUpgradeSubject = (platform = process.platform) => {
244
269
  const prefix = readGlobalPrefix();
245
270
  return globalUpgradeSubject(prefix, prefix === void 0 ? { kind: "unavailable" } : readGlobalCliInstallAt(prefix, platform));
246
271
  };
247
- var finishWithThisNode = (entry) => finishWithUpgradeLock({ entry, args: [FINISH_UPGRADE_FLAG] });
272
+ var finishWithThisNode = async (entry) => (await forkFinishWithUpgradeLock({ entry, args: [FINISH_UPGRADE_FLAG] })).code;
273
+ var NEVER_RAN = { kind: "failed", waitsOnThePerson: false };
274
+ var finishOutcomeOfExit = (code) => {
275
+ const outcome = upgradeFinishOutcomeOfExit(code);
276
+ return outcome.kind === "finished" ? { kind: "finished" } : { kind: "failed", waitsOnThePerson: outcome.kind === "settled" };
277
+ };
248
278
  var finishGlobalUpgrade = async (subject, platform = process.platform, runFinish = finishWithThisNode) => {
249
279
  const entry = globalUpgradeEntry(subject.prefix, subject.name, platform);
250
280
  if (!existsSync(entry)) return { kind: "entry_missing", entry };
251
281
  try {
252
- await runFinish(entry);
253
- return { kind: "finished" };
282
+ return finishOutcomeOfExit(await runFinish(entry));
254
283
  } catch {
255
- return { kind: "failed" };
284
+ return NEVER_RAN;
256
285
  }
257
286
  };
258
287
  var describeHeldUpgradeLock = (holderPid) => `Another Pushary upgrade is already running${holderPid === void 0 ? "" : ` (pid ${holderPid})`}. Try again when it has finished.`;
@@ -267,21 +296,62 @@ var withUpgradeLock = async (run, request = {}) => {
267
296
  }
268
297
  return { kind: "ran" };
269
298
  };
299
+ var upgradeOnRecordIsStillThisOne = (earlier, installedVersion) => earlier.to === installedVersion && (holdsUnfinishedFinish(earlier) || pendingAutoUpdateAnnouncement(earlier) !== null);
300
+ var startOfTheUpgradeOnRecord = (statePath, installedVersion) => {
301
+ const earlier = readAutoUpdateState(statePath);
302
+ return upgradeOnRecordIsStillThisOne(earlier, installedVersion) ? earlier.from : void 0;
303
+ };
270
304
  var finishUpgradeWithLock = async (run, request) => {
271
305
  const outcome = await withUpgradeLock(run, request);
272
306
  if (outcome.kind === "refused") {
273
- updateAutoUpdateState(request.statePath, { lastResult: "finish_pending", to: request.installedVersion, detail: outcome.message });
307
+ updateAutoUpdateState(request.statePath, {
308
+ lastResult: "finish_pending",
309
+ from: startOfTheUpgradeOnRecord(request.statePath, request.installedVersion),
310
+ to: request.installedVersion,
311
+ detail: outcome.message
312
+ });
274
313
  }
275
314
  return outcome;
276
315
  };
316
+ var FINISH_DID_NOT_FINISH_DETAIL = "installed, but refreshing the agent configs did not finish; run pushary upgrade again";
317
+ var FINISH_WAITS_ON_THE_PERSON_DETAIL = "installed, but refreshing the agent configs needs a change only you can make; make it, then run pushary upgrade again";
318
+ var waitsOnThePerson = (unfinished) => unfinished.kind === "failed" && unfinished.waitsOnThePerson;
319
+ var recordUnfinishedUpgrade = (record, unfinished) => {
320
+ if (record.installed.kind !== "installed") return;
321
+ const settled = waitsOnThePerson(unfinished);
322
+ updateAutoUpdateState(record.statePath, {
323
+ lastCheckAt: record.at,
324
+ lastResult: settled ? "finish_blocked" : "finish_pending",
325
+ from: startOfTheUpgradeOnRecord(record.statePath, record.installed.version),
326
+ to: record.installed.version,
327
+ at: record.at,
328
+ detail: settled ? FINISH_WAITS_ON_THE_PERSON_DETAIL : FINISH_DID_NOT_FINISH_DETAIL,
329
+ finishAttempts: void 0
330
+ });
331
+ };
332
+ var forgetUnfinishedUpgrade = (record, upgradedFrom) => {
333
+ if (record.installed.kind !== "installed" || !holdsUnfinishedFinish(readAutoUpdateState(record.statePath))) return;
334
+ updateAutoUpdateState(record.statePath, {
335
+ lastResult: "updated",
336
+ from: upgradedFrom,
337
+ to: record.installed.version,
338
+ at: record.at,
339
+ detail: void 0,
340
+ announced: true,
341
+ finishAttempts: void 0
342
+ });
343
+ };
277
344
  var describeUpgradeStart = (subject, latest) => `Upgrading ${subject.name} ${subject.version} -> ${latest ?? "latest"}`;
278
345
  var upgradeInstalledPackage = async (subject, effects) => {
279
346
  const pendingFinish = effects.hasPendingFinish(subject.version);
280
347
  const latest = await effects.fetchLatest(subject.name);
281
348
  const newerPublished = latest !== void 0 && isNewerVersion(latest, subject.version);
282
349
  if (pendingFinish && !newerPublished) {
283
- const finish = await effects.finish(subject);
284
- if (finish.kind !== "finished") return { kind: "pending_finish_failed", finish };
350
+ const finish2 = await effects.finish(subject);
351
+ if (finish2.kind !== "finished") {
352
+ effects.recordUnfinished(finish2);
353
+ return { kind: "pending_finish_failed", finish: finish2 };
354
+ }
285
355
  effects.recordFinished();
286
356
  }
287
357
  if (latest !== void 0 && !newerPublished) return { kind: "current", version: subject.version };
@@ -291,13 +361,20 @@ var upgradeInstalledPackage = async (subject, effects) => {
291
361
  } catch (error) {
292
362
  return { kind: "install_failed", detail: npmErrorMessage(error) };
293
363
  }
294
- return { kind: "installed", finish: await effects.finish(subject) };
364
+ const finish = await effects.finish(subject);
365
+ if (finish.kind === "finished") effects.forgetUnfinished();
366
+ else effects.recordUnfinished(finish);
367
+ return { kind: "installed", finish };
295
368
  };
296
369
 
297
370
  export {
298
371
  refreshedPartsOf,
299
372
  wasRefreshed,
300
373
  instructionsLeftNoteOf,
374
+ phoneStartFellShortWithoutFailing,
375
+ serviceStaysOwedBack,
376
+ phoneStartServiceAfter,
377
+ describeUnreadyService,
301
378
  upgradeFinishOutcome,
302
379
  upgradeFinishExitCode,
303
380
  FINISH_UPGRADE_FLAG,
@@ -307,5 +384,7 @@ export {
307
384
  finishGlobalUpgrade,
308
385
  withUpgradeLock,
309
386
  finishUpgradeWithLock,
387
+ recordUnfinishedUpgrade,
388
+ forgetUnfinishedUpgrade,
310
389
  upgradeInstalledPackage
311
390
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseSseMessages
3
- } from "./chunk-A54W5A74.js";
3
+ } from "./chunk-ZL3UR6M5.js";
4
4
  import {
5
5
  NPX_LATEST_COMMAND
6
6
  } from "./chunk-5SFM6XB4.js";