@pushary/agent-hooks 1.9.15 → 1.9.16
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.
- package/CHANGELOG.md +18 -0
- package/dist/bin/pushary-bell-hook.js +21 -21
- package/dist/bin/pushary-bell.js +9 -9
- package/dist/bin/pushary-claude.js +20 -20
- package/dist/bin/pushary-clean.js +26 -26
- package/dist/bin/pushary-codex-bridge.js +15 -15
- package/dist/bin/pushary-codex-hook.js +24 -24
- package/dist/bin/pushary-codex.js +10 -10
- package/dist/bin/pushary-connect.js +22 -22
- package/dist/bin/pushary-cowork.js +3 -3
- package/dist/bin/pushary-daemon.js +27 -27
- package/dist/bin/pushary-disconnect.js +21 -21
- package/dist/bin/pushary-doctor.js +30 -30
- package/dist/bin/pushary-elicitation-hook.js +21 -21
- package/dist/bin/pushary-gemini-bridge.js +11 -11
- package/dist/bin/pushary-gemini-hook.js +22 -22
- package/dist/bin/pushary-hook.js +24 -24
- package/dist/bin/pushary-login.js +12 -12
- package/dist/bin/pushary-logout.js +10 -10
- package/dist/bin/pushary-mcp.js +8 -8
- package/dist/bin/pushary-mode.js +12 -12
- package/dist/bin/pushary-notification-hook.js +20 -20
- package/dist/bin/pushary-opencode-hook.js +21 -21
- package/dist/bin/pushary-permission-denied-hook.js +23 -23
- package/dist/bin/pushary-permission-hook.js +23 -23
- package/dist/bin/pushary-post-hook.js +20 -20
- package/dist/bin/pushary-prompt-hook.js +20 -20
- package/dist/bin/pushary-session-end-hook.js +20 -20
- package/dist/bin/pushary-session-start-hook.js +24 -24
- package/dist/bin/pushary-setup.js +440 -114
- package/dist/bin/pushary-stats.js +3 -3
- package/dist/bin/pushary-status.js +24 -24
- package/dist/bin/pushary-stop-hook.js +20 -20
- package/dist/bin/pushary-stopfailure-hook.js +20 -20
- package/dist/bin/pushary-suggestions.js +12 -12
- package/dist/bin/pushary-transcript-register.js +13 -13
- package/dist/bin/pushary-transcripts.js +6 -6
- package/dist/bin/pushary-upgrade.js +27 -27
- package/dist/bin/pushary-wait.js +12 -12
- package/dist/bin/pushary.js +9 -6
- package/dist/{chunk-3FQCZSEQ.js → chunk-3DZG5EXY.js} +2 -2
- package/dist/{chunk-YOHPJNFW.js → chunk-4MOOSU5Y.js} +35 -24
- package/dist/{chunk-C2OUUGCW.js → chunk-4PQGFWPO.js} +1 -1
- package/dist/{chunk-HJL5RBOU.js → chunk-5ETPCIG4.js} +22 -3
- package/dist/{chunk-7QZZK2YU.js → chunk-65OI53N7.js} +5 -5
- package/dist/{chunk-COZE23R3.js → chunk-7BNU5AVD.js} +1 -1
- package/dist/{chunk-5BIMNGRQ.js → chunk-7DE5BZMB.js} +6 -6
- package/dist/{chunk-YL6HU2KF.js → chunk-7EBZRHIH.js} +4 -4
- package/dist/{chunk-PSWFYNOX.js → chunk-BARUIIUR.js} +2 -2
- package/dist/{chunk-Q4JD6WNB.js → chunk-COGQIULO.js} +1 -1
- package/dist/{chunk-2DCGUCPZ.js → chunk-CXXYHPN7.js} +1 -1
- package/dist/{chunk-6LORREOI.js → chunk-DMJPRZVJ.js} +1 -1
- package/dist/{chunk-5EWNGYFD.js → chunk-DUDI3Z7F.js} +2 -2
- package/dist/{chunk-VP6WDFVO.js → chunk-EDEIIKCV.js} +1 -1
- package/dist/{chunk-6WECKO24.js → chunk-EDXJEQCK.js} +3 -3
- package/dist/{chunk-U4TMAANR.js → chunk-FO3MDD26.js} +4 -4
- package/dist/{chunk-NDKFHLJI.js → chunk-HBDZYQZX.js} +3 -3
- package/dist/{chunk-NDZBDXU3.js → chunk-HDQAN2C3.js} +27 -8
- package/dist/{chunk-H5YC7H6V.js → chunk-HKSH4KWI.js} +3 -3
- package/dist/{chunk-OIESPH3R.js → chunk-ICEMM4H2.js} +9 -9
- package/dist/{chunk-IQCNOEQL.js → chunk-IHPSFUL2.js} +6 -6
- package/dist/{chunk-LJJWNHUW.js → chunk-ISJ5ROXM.js} +1 -1
- package/dist/{chunk-WJO7SENK.js → chunk-J36EWRVL.js} +5 -5
- package/dist/{chunk-HSVJ62BE.js → chunk-JF2XRQR2.js} +1 -1
- package/dist/{chunk-6MLSXBNR.js → chunk-JNZU2F5B.js} +1 -1
- package/dist/{chunk-5LQ7QUVF.js → chunk-JQC7ZFHM.js} +1 -1
- package/dist/{chunk-JEJSAI6Z.js → chunk-L52HDK35.js} +3 -3
- package/dist/{chunk-ZMUDVPOT.js → chunk-LJJLMU5B.js} +2 -2
- package/dist/{chunk-CU7Y7Y4L.js → chunk-LYEXTD64.js} +2 -2
- package/dist/{chunk-6GRUERVL.js → chunk-MN2QJA7K.js} +1 -1
- package/dist/{chunk-WBQK6KD5.js → chunk-NM6IHHRO.js} +7 -7
- package/dist/{chunk-3YCYTGGK.js → chunk-OEMDXBV6.js} +1 -1
- package/dist/{chunk-PNUWMEIY.js → chunk-OIAZ2QAC.js} +2 -1
- package/dist/{chunk-SDDKVY4I.js → chunk-OLJ6YZME.js} +4 -4
- package/dist/{chunk-HTO2XULO.js → chunk-PJNZJPPX.js} +1 -1
- package/dist/{chunk-ME55HQOI.js → chunk-PVOOKOKX.js} +3 -3
- package/dist/{chunk-3QXCTYMG.js → chunk-PYPZ3MYC.js} +2 -2
- package/dist/{chunk-TFV6RATK.js → chunk-PZ33VQ54.js} +4 -4
- package/dist/{chunk-57VUNV32.js → chunk-QINDG6HO.js} +1 -1
- package/dist/{chunk-7VOEZPJ4.js → chunk-QJYBHKHO.js} +1 -1
- package/dist/{chunk-TMQMUGSN.js → chunk-R2FHKTD3.js} +1 -1
- package/dist/{chunk-SYLJL63X.js → chunk-S2LU6HIZ.js} +3 -3
- package/dist/{chunk-VKTDXQGH.js → chunk-VKYDON4A.js} +1 -1
- package/dist/{chunk-JC3AGMOP.js → chunk-W2AUU35K.js} +1 -1
- package/dist/{chunk-D72OJS4S.js → chunk-WVSECXIM.js} +2 -2
- package/dist/{chunk-NA5D62OI.js → chunk-XIJMMY6M.js} +1 -1
- package/dist/{chunk-Y6KG5JZP.js → chunk-YHHUYJQN.js} +1 -1
- package/dist/{chunk-FZW7Q7GM.js → chunk-ZOMVMLMU.js} +8 -13
- package/dist/{global-upgrade-MOBLBPIJ.js → global-upgrade-4XWM5RXK.js} +5 -5
- package/dist/{paths-55SPLYW5.js → paths-2RE6MBKF.js} +1 -1
- package/dist/{reapply-SOIJJKGO.js → reapply-Y5PSM7U7.js} +17 -17
- package/dist/src/index.js +16 -16
- package/dist/{upgrade-lock-FER4DMDA.js → upgrade-lock-HVWZN4BZ.js} +2 -2
- package/package.json +1 -1
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runBrowserLogin
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-DMJPRZVJ.js";
|
|
5
5
|
import {
|
|
6
6
|
coworkOutput,
|
|
7
7
|
coworkSelection
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-R2FHKTD3.js";
|
|
9
9
|
import "../chunk-PUZZELE6.js";
|
|
10
10
|
import {
|
|
11
11
|
clearDeclinedAgent,
|
|
12
12
|
declinedAgentForSetupChoice
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-CXXYHPN7.js";
|
|
14
14
|
import {
|
|
15
15
|
CURSOR_GATE_SCRIPT,
|
|
16
16
|
describeVersionManagerPin,
|
|
@@ -20,17 +20,17 @@ import {
|
|
|
20
20
|
codexTrustOutcome,
|
|
21
21
|
describeCodexTrustConfirmation,
|
|
22
22
|
needsCodexTrustStep
|
|
23
|
-
} from "../chunk-
|
|
23
|
+
} from "../chunk-LYEXTD64.js";
|
|
24
24
|
import {
|
|
25
25
|
writeStdoutFully
|
|
26
26
|
} from "../chunk-EO23EUOK.js";
|
|
27
27
|
import {
|
|
28
28
|
ensureCodexTrustsPusharyHooks
|
|
29
|
-
} from "../chunk-
|
|
29
|
+
} from "../chunk-ISJ5ROXM.js";
|
|
30
30
|
import {
|
|
31
31
|
readManagedControlEvidence,
|
|
32
32
|
waitForMachineReadiness
|
|
33
|
-
} from "../chunk-
|
|
33
|
+
} from "../chunk-65OI53N7.js";
|
|
34
34
|
import {
|
|
35
35
|
describeSetupSideEffects,
|
|
36
36
|
installAgentSkill,
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
soleGateFile,
|
|
45
45
|
soleGateReceipt,
|
|
46
46
|
soleGateReceiptFile
|
|
47
|
-
} from "../chunk-
|
|
47
|
+
} from "../chunk-HKSH4KWI.js";
|
|
48
48
|
import {
|
|
49
49
|
HERMES_PIP_PACKAGE,
|
|
50
50
|
describeDetection,
|
|
@@ -57,7 +57,7 @@ import {
|
|
|
57
57
|
runHermesConfigScript,
|
|
58
58
|
shortenHome,
|
|
59
59
|
vscodeSettingsTargets
|
|
60
|
-
} from "../chunk-
|
|
60
|
+
} from "../chunk-LJJLMU5B.js";
|
|
61
61
|
import {
|
|
62
62
|
AgentConfigError,
|
|
63
63
|
FX_PUSHARY_TOOLS_RULE,
|
|
@@ -68,12 +68,14 @@ import {
|
|
|
68
68
|
agentFailureWire,
|
|
69
69
|
configFailureKind,
|
|
70
70
|
configureFxSettings,
|
|
71
|
+
describeMacAccountMismatch,
|
|
71
72
|
describedAgentFailure,
|
|
72
73
|
failedAgentsContext,
|
|
73
74
|
fxIgnoresInstructionsFile,
|
|
74
75
|
fxInstructionsBody,
|
|
75
76
|
fxPusharyEntry,
|
|
76
77
|
inspectFxInstallation,
|
|
78
|
+
matchMacAccountStep,
|
|
77
79
|
readFxProfileForSetup,
|
|
78
80
|
renderAgentInstructions,
|
|
79
81
|
renderProjectAgentInstructions,
|
|
@@ -81,10 +83,10 @@ import {
|
|
|
81
83
|
withFxPusharyServer,
|
|
82
84
|
writeFxProfile,
|
|
83
85
|
writeInstructionBlock
|
|
84
|
-
} from "../chunk-
|
|
86
|
+
} from "../chunk-HDQAN2C3.js";
|
|
85
87
|
import {
|
|
86
88
|
MCP_BRIDGE_BINARY
|
|
87
|
-
} from "../chunk-
|
|
89
|
+
} from "../chunk-WVSECXIM.js";
|
|
88
90
|
import {
|
|
89
91
|
checkCodexInstall,
|
|
90
92
|
detectProviderLiveCapabilities,
|
|
@@ -92,14 +94,14 @@ import {
|
|
|
92
94
|
hasSpawnProvider,
|
|
93
95
|
nodeCodexInstallProbe,
|
|
94
96
|
resolveControlPolicy
|
|
95
|
-
} from "../chunk-
|
|
97
|
+
} from "../chunk-W2AUU35K.js";
|
|
96
98
|
import {
|
|
97
99
|
detectClaudeVersion
|
|
98
100
|
} from "../chunk-RIVNNBEK.js";
|
|
99
101
|
import {
|
|
100
102
|
describeAutoUpdateAnnouncement,
|
|
101
103
|
takeAutoUpdateAnnouncement
|
|
102
|
-
} from "../chunk-
|
|
104
|
+
} from "../chunk-JNZU2F5B.js";
|
|
103
105
|
import {
|
|
104
106
|
DAEMON_COLD_START_TIMEOUT_MS,
|
|
105
107
|
clearDaemonNeedsLogin,
|
|
@@ -113,29 +115,29 @@ import {
|
|
|
113
115
|
replaceDaemonService,
|
|
114
116
|
stopDaemonService,
|
|
115
117
|
waitForDaemonRemoteProof
|
|
116
|
-
} from "../chunk-
|
|
118
|
+
} from "../chunk-PZ33VQ54.js";
|
|
117
119
|
import {
|
|
118
120
|
transcriptPreferenceForSetup
|
|
119
|
-
} from "../chunk-
|
|
121
|
+
} from "../chunk-JF2XRQR2.js";
|
|
120
122
|
import "../chunk-XHKBHWLX.js";
|
|
121
123
|
import {
|
|
122
124
|
BROWSER_CONNECT_COMMAND,
|
|
123
125
|
confirmAppConnection,
|
|
124
126
|
connectDevice,
|
|
125
127
|
connectViaAppPairing,
|
|
126
|
-
|
|
128
|
+
describeRoundTripOutcome,
|
|
127
129
|
pairingEscapeApplies,
|
|
128
130
|
printConnectInstructions,
|
|
129
131
|
roundTripEvidence,
|
|
130
132
|
verifyRoundTrip
|
|
131
|
-
} from "../chunk-
|
|
133
|
+
} from "../chunk-4MOOSU5Y.js";
|
|
132
134
|
import "../chunk-3EGEA4KH.js";
|
|
133
135
|
import {
|
|
134
136
|
setHumanStream
|
|
135
137
|
} from "../chunk-QCGNGEGE.js";
|
|
136
138
|
import {
|
|
137
139
|
readMacAppAgentKey
|
|
138
|
-
} from "../chunk-
|
|
140
|
+
} from "../chunk-EDXJEQCK.js";
|
|
139
141
|
import {
|
|
140
142
|
OPENCODE_HOOK_BINARY,
|
|
141
143
|
addOpenCodeMcpServer,
|
|
@@ -151,12 +153,12 @@ import {
|
|
|
151
153
|
openCodePluginDir,
|
|
152
154
|
openCodePluginFile,
|
|
153
155
|
openCodeWired
|
|
154
|
-
} from "../chunk-
|
|
156
|
+
} from "../chunk-HBDZYQZX.js";
|
|
155
157
|
import {
|
|
156
158
|
ansiPainter,
|
|
157
159
|
createIo,
|
|
158
160
|
useColor
|
|
159
|
-
} from "../chunk-
|
|
161
|
+
} from "../chunk-FO3MDD26.js";
|
|
160
162
|
import {
|
|
161
163
|
addClaudeMcpServer,
|
|
162
164
|
addCompatibleHooks,
|
|
@@ -173,7 +175,7 @@ import {
|
|
|
173
175
|
hasCompatibleHooks,
|
|
174
176
|
isClaudeMcpSnapshot,
|
|
175
177
|
updateClaudeMcpSnapshot
|
|
176
|
-
} from "../chunk-
|
|
178
|
+
} from "../chunk-PVOOKOKX.js";
|
|
177
179
|
import {
|
|
178
180
|
KEEP_HINT,
|
|
179
181
|
captureHookTakeover,
|
|
@@ -186,19 +188,19 @@ import {
|
|
|
186
188
|
mcpBearerKey,
|
|
187
189
|
planHooks,
|
|
188
190
|
pusharyHookExecutable
|
|
189
|
-
} from "../chunk-
|
|
191
|
+
} from "../chunk-ZOMVMLMU.js";
|
|
190
192
|
import {
|
|
191
193
|
GEMINI_HOOK_BINARY,
|
|
192
194
|
addGeminiHooks,
|
|
193
195
|
addGeminiMcpServer
|
|
194
|
-
} from "../chunk-
|
|
196
|
+
} from "../chunk-EDEIIKCV.js";
|
|
195
197
|
import {
|
|
196
198
|
AGENT_CHOICES,
|
|
197
199
|
effectiveControlMode,
|
|
198
200
|
effectiveVerify,
|
|
199
201
|
parseSetupOptions
|
|
200
202
|
} from "../chunk-YKYFFCB5.js";
|
|
201
|
-
import "../chunk-
|
|
203
|
+
import "../chunk-QJYBHKHO.js";
|
|
202
204
|
import "../chunk-GMXKITVA.js";
|
|
203
205
|
import {
|
|
204
206
|
compareVersion,
|
|
@@ -216,28 +218,28 @@ import {
|
|
|
216
218
|
recordMacAppKeyPrefix,
|
|
217
219
|
resolveShellRc,
|
|
218
220
|
writeKey
|
|
219
|
-
} from "../chunk-
|
|
221
|
+
} from "../chunk-DUDI3Z7F.js";
|
|
220
222
|
import {
|
|
221
223
|
reportEvent
|
|
222
|
-
} from "../chunk-
|
|
224
|
+
} from "../chunk-IHPSFUL2.js";
|
|
223
225
|
import "../chunk-52JA2WTH.js";
|
|
224
|
-
import "../chunk-
|
|
226
|
+
import "../chunk-7EBZRHIH.js";
|
|
225
227
|
import "../chunk-POFBE6ZY.js";
|
|
226
|
-
import "../chunk-
|
|
228
|
+
import "../chunk-S2LU6HIZ.js";
|
|
227
229
|
import {
|
|
228
230
|
checkApiKey,
|
|
229
231
|
describeKeyCheck,
|
|
230
232
|
samePusharyAccount
|
|
231
|
-
} from "../chunk-
|
|
232
|
-
import "../chunk-
|
|
233
|
-
import "../chunk-
|
|
233
|
+
} from "../chunk-BARUIIUR.js";
|
|
234
|
+
import "../chunk-3DZG5EXY.js";
|
|
235
|
+
import "../chunk-XIJMMY6M.js";
|
|
234
236
|
import {
|
|
235
237
|
UsageError
|
|
236
238
|
} from "../chunk-7QLSKOSU.js";
|
|
237
239
|
import {
|
|
238
240
|
EXIT
|
|
239
241
|
} from "../chunk-KZERVKTD.js";
|
|
240
|
-
import "../chunk-
|
|
242
|
+
import "../chunk-VKYDON4A.js";
|
|
241
243
|
import {
|
|
242
244
|
NpmMissingError,
|
|
243
245
|
addCodexHookTrust,
|
|
@@ -274,7 +276,7 @@ import {
|
|
|
274
276
|
hermesConfigReceipt,
|
|
275
277
|
hookTakeoverReceipt,
|
|
276
278
|
installGlobally,
|
|
277
|
-
|
|
279
|
+
npmInstallFailure,
|
|
278
280
|
plannedGlobalPackage,
|
|
279
281
|
pusharyConfigFile,
|
|
280
282
|
readCodexMcpAuth,
|
|
@@ -282,18 +284,18 @@ import {
|
|
|
282
284
|
resolveGlobalBinary,
|
|
283
285
|
vscodePluginDir,
|
|
284
286
|
vscodePluginMcp
|
|
285
|
-
} from "../chunk-
|
|
287
|
+
} from "../chunk-5ETPCIG4.js";
|
|
286
288
|
import {
|
|
287
289
|
backupFile,
|
|
288
290
|
readJsonSafe,
|
|
289
291
|
writeFileAtomic,
|
|
290
292
|
writeJsonAtomic
|
|
291
293
|
} from "../chunk-T7E75EKA.js";
|
|
292
|
-
import "../chunk-
|
|
294
|
+
import "../chunk-PJNZJPPX.js";
|
|
293
295
|
import {
|
|
294
296
|
NPX_LATEST_COMMAND,
|
|
295
297
|
renderCommandHelp
|
|
296
|
-
} from "../chunk-
|
|
298
|
+
} from "../chunk-OIAZ2QAC.js";
|
|
297
299
|
import {
|
|
298
300
|
HOOK_COMPATIBLE_PROFILES,
|
|
299
301
|
PRETOOLUSE_GATED_TOOLS,
|
|
@@ -321,6 +323,270 @@ import { parse as parseTOML, stringify as stringifyTOML } from "smol-toml";
|
|
|
321
323
|
// src/cli/exit.ts
|
|
322
324
|
var isExitPromptError = (err) => err instanceof Error && (err.name === "ExitPromptError" || err.message.includes("User force closed") || /force closed the prompt/i.test(err.message));
|
|
323
325
|
|
|
326
|
+
// ../contracts/src/billing.ts
|
|
327
|
+
var PARTNER_SELF_SERVE_PLANS = ["partner_launch", "partner_growth", "partner_scale"];
|
|
328
|
+
var PARTNER_PLAN_TYPES = ["partner", ...PARTNER_SELF_SERVE_PLANS];
|
|
329
|
+
var PLAN_TYPES = ["free", "agent", "agent_pro", "team", "partner", "starter", "growth", "pro", "enterprise", ...PARTNER_SELF_SERVE_PLANS];
|
|
330
|
+
var PAID_PLAN_TYPES = ["agent", "agent_pro", "team", "partner", "starter", "growth", "pro", ...PARTNER_SELF_SERVE_PLANS];
|
|
331
|
+
var PLAN_CONFIGS = {
|
|
332
|
+
free: {
|
|
333
|
+
name: "Free",
|
|
334
|
+
price: 0,
|
|
335
|
+
priceId: null,
|
|
336
|
+
limits: {
|
|
337
|
+
subscribers: 100,
|
|
338
|
+
notifications: 500,
|
|
339
|
+
sites: 1,
|
|
340
|
+
members: 1,
|
|
341
|
+
campaigns: 25,
|
|
342
|
+
dataRetentionDays: 7
|
|
343
|
+
},
|
|
344
|
+
features: {
|
|
345
|
+
abTesting: false,
|
|
346
|
+
apiAccess: false,
|
|
347
|
+
prioritySupport: false
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
agent: {
|
|
351
|
+
name: "Agent",
|
|
352
|
+
price: 9.99,
|
|
353
|
+
priceId: null,
|
|
354
|
+
limits: {
|
|
355
|
+
subscribers: 3,
|
|
356
|
+
notifications: 5e3,
|
|
357
|
+
sites: 1,
|
|
358
|
+
members: 1,
|
|
359
|
+
campaigns: 0,
|
|
360
|
+
dataRetentionDays: 30
|
|
361
|
+
},
|
|
362
|
+
features: {
|
|
363
|
+
abTesting: false,
|
|
364
|
+
apiAccess: true,
|
|
365
|
+
prioritySupport: false
|
|
366
|
+
}
|
|
367
|
+
},
|
|
368
|
+
agent_pro: {
|
|
369
|
+
name: "Agent Pro",
|
|
370
|
+
price: 19.99,
|
|
371
|
+
priceId: null,
|
|
372
|
+
limits: {
|
|
373
|
+
subscribers: 5,
|
|
374
|
+
notifications: Infinity,
|
|
375
|
+
sites: 1,
|
|
376
|
+
members: 5,
|
|
377
|
+
campaigns: 0,
|
|
378
|
+
dataRetentionDays: 90
|
|
379
|
+
},
|
|
380
|
+
features: {
|
|
381
|
+
abTesting: false,
|
|
382
|
+
apiAccess: true,
|
|
383
|
+
prioritySupport: true
|
|
384
|
+
}
|
|
385
|
+
},
|
|
386
|
+
team: {
|
|
387
|
+
name: "Team",
|
|
388
|
+
price: 59.99,
|
|
389
|
+
priceId: null,
|
|
390
|
+
limits: {
|
|
391
|
+
subscribers: 25,
|
|
392
|
+
notifications: Infinity,
|
|
393
|
+
sites: 1,
|
|
394
|
+
members: 10,
|
|
395
|
+
campaigns: 0,
|
|
396
|
+
dataRetentionDays: 365
|
|
397
|
+
},
|
|
398
|
+
features: {
|
|
399
|
+
abTesting: false,
|
|
400
|
+
apiAccess: true,
|
|
401
|
+
prioritySupport: true
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
partner: {
|
|
405
|
+
name: "Partner",
|
|
406
|
+
price: 99,
|
|
407
|
+
priceId: null,
|
|
408
|
+
limits: {
|
|
409
|
+
subscribers: 25e3,
|
|
410
|
+
notifications: 1e5,
|
|
411
|
+
sites: 1,
|
|
412
|
+
members: 10,
|
|
413
|
+
campaigns: 0,
|
|
414
|
+
dataRetentionDays: 365
|
|
415
|
+
},
|
|
416
|
+
features: {
|
|
417
|
+
abTesting: false,
|
|
418
|
+
apiAccess: true,
|
|
419
|
+
prioritySupport: true
|
|
420
|
+
}
|
|
421
|
+
},
|
|
422
|
+
partner_launch: {
|
|
423
|
+
name: "Partner Launch",
|
|
424
|
+
price: 99,
|
|
425
|
+
priceId: null,
|
|
426
|
+
limits: {
|
|
427
|
+
subscribers: 5e3,
|
|
428
|
+
// Closed until request admission and fan-out accounting ship. Never sell
|
|
429
|
+
// human requests against the legacy notification-delivery counter.
|
|
430
|
+
notifications: 0,
|
|
431
|
+
humanDecisionRequests: 25e3,
|
|
432
|
+
sites: 1,
|
|
433
|
+
members: 3,
|
|
434
|
+
campaigns: 0,
|
|
435
|
+
dataRetentionDays: 90
|
|
436
|
+
},
|
|
437
|
+
features: { abTesting: false, apiAccess: true, prioritySupport: false }
|
|
438
|
+
},
|
|
439
|
+
partner_growth: {
|
|
440
|
+
name: "Partner Growth",
|
|
441
|
+
price: 299,
|
|
442
|
+
priceId: null,
|
|
443
|
+
limits: {
|
|
444
|
+
subscribers: 25e3,
|
|
445
|
+
// Closed until request admission and fan-out accounting ship. Never sell
|
|
446
|
+
// human requests against the legacy notification-delivery counter.
|
|
447
|
+
notifications: 0,
|
|
448
|
+
humanDecisionRequests: 1e5,
|
|
449
|
+
sites: 1,
|
|
450
|
+
members: 10,
|
|
451
|
+
campaigns: 0,
|
|
452
|
+
dataRetentionDays: 365
|
|
453
|
+
},
|
|
454
|
+
features: { abTesting: false, apiAccess: true, prioritySupport: true }
|
|
455
|
+
},
|
|
456
|
+
partner_scale: {
|
|
457
|
+
name: "Partner Scale",
|
|
458
|
+
price: 799,
|
|
459
|
+
priceId: null,
|
|
460
|
+
limits: {
|
|
461
|
+
subscribers: 1e5,
|
|
462
|
+
// Closed until request admission and fan-out accounting ship. Never sell
|
|
463
|
+
// human requests against the legacy notification-delivery counter.
|
|
464
|
+
notifications: 0,
|
|
465
|
+
humanDecisionRequests: 5e5,
|
|
466
|
+
sites: 1,
|
|
467
|
+
members: 25,
|
|
468
|
+
campaigns: 0,
|
|
469
|
+
dataRetentionDays: 730
|
|
470
|
+
},
|
|
471
|
+
features: { abTesting: false, apiAccess: true, prioritySupport: true }
|
|
472
|
+
},
|
|
473
|
+
starter: {
|
|
474
|
+
name: "Starter",
|
|
475
|
+
price: 29,
|
|
476
|
+
priceId: null,
|
|
477
|
+
limits: {
|
|
478
|
+
subscribers: 5e3,
|
|
479
|
+
notifications: 25e3,
|
|
480
|
+
sites: 3,
|
|
481
|
+
members: 5,
|
|
482
|
+
campaigns: 250,
|
|
483
|
+
dataRetentionDays: 30
|
|
484
|
+
},
|
|
485
|
+
features: {
|
|
486
|
+
abTesting: true,
|
|
487
|
+
apiAccess: true,
|
|
488
|
+
prioritySupport: false
|
|
489
|
+
}
|
|
490
|
+
},
|
|
491
|
+
growth: {
|
|
492
|
+
name: "Growth",
|
|
493
|
+
price: 99,
|
|
494
|
+
priceId: null,
|
|
495
|
+
limits: {
|
|
496
|
+
subscribers: 25e3,
|
|
497
|
+
notifications: 1e5,
|
|
498
|
+
sites: 10,
|
|
499
|
+
members: 15,
|
|
500
|
+
campaigns: Infinity,
|
|
501
|
+
dataRetentionDays: 90
|
|
502
|
+
},
|
|
503
|
+
features: {
|
|
504
|
+
abTesting: true,
|
|
505
|
+
apiAccess: true,
|
|
506
|
+
prioritySupport: true
|
|
507
|
+
}
|
|
508
|
+
},
|
|
509
|
+
pro: {
|
|
510
|
+
name: "Pro",
|
|
511
|
+
price: 149,
|
|
512
|
+
priceId: null,
|
|
513
|
+
limits: {
|
|
514
|
+
subscribers: 1e5,
|
|
515
|
+
notifications: 5e5,
|
|
516
|
+
sites: 25,
|
|
517
|
+
members: 50,
|
|
518
|
+
campaigns: Infinity,
|
|
519
|
+
dataRetentionDays: 180
|
|
520
|
+
},
|
|
521
|
+
features: {
|
|
522
|
+
abTesting: true,
|
|
523
|
+
apiAccess: true,
|
|
524
|
+
prioritySupport: true
|
|
525
|
+
}
|
|
526
|
+
},
|
|
527
|
+
enterprise: {
|
|
528
|
+
name: "Enterprise",
|
|
529
|
+
price: -1,
|
|
530
|
+
priceId: null,
|
|
531
|
+
limits: {
|
|
532
|
+
subscribers: Infinity,
|
|
533
|
+
notifications: Infinity,
|
|
534
|
+
sites: Infinity,
|
|
535
|
+
members: Infinity,
|
|
536
|
+
campaigns: Infinity,
|
|
537
|
+
dataRetentionDays: Infinity
|
|
538
|
+
},
|
|
539
|
+
features: {
|
|
540
|
+
abTesting: true,
|
|
541
|
+
apiAccess: true,
|
|
542
|
+
prioritySupport: true
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
// src/setup/key-account.ts
|
|
548
|
+
var agentConfigKeySource = (macAppInstalled) => macAppInstalled ? "mac-app" : "agent-settings";
|
|
549
|
+
var pickReusableKey = (candidates) => {
|
|
550
|
+
if (candidates.storedKey !== null && candidates.storedCheck !== null) {
|
|
551
|
+
return { source: "stored", key: candidates.storedKey, check: candidates.storedCheck };
|
|
552
|
+
}
|
|
553
|
+
if (candidates.envKey && candidates.envCheck !== null) {
|
|
554
|
+
return { source: "environment", key: candidates.envKey, check: candidates.envCheck };
|
|
555
|
+
}
|
|
556
|
+
if (candidates.agentConfigKey !== null && candidates.agentConfigCheck !== null) {
|
|
557
|
+
return { source: agentConfigKeySource(candidates.macAppInstalled), key: candidates.agentConfigKey, check: candidates.agentConfigCheck };
|
|
558
|
+
}
|
|
559
|
+
return null;
|
|
560
|
+
};
|
|
561
|
+
var REUSED_KEY_SOURCE_LABELS = {
|
|
562
|
+
stored: "the key saved on this machine",
|
|
563
|
+
environment: "the key in PUSHARY_API_KEY",
|
|
564
|
+
"mac-app": "the key Pushary for Mac is signed in with",
|
|
565
|
+
"agent-settings": "a key found in your agent settings"
|
|
566
|
+
};
|
|
567
|
+
var maskKey = (key) => `${key.slice(0, 8)}...${key.slice(-4)}`;
|
|
568
|
+
var describeFoundKey = (reusable) => `Found ${REUSED_KEY_SOURCE_LABELS[reusable.source]}: ${maskKey(reusable.key)}`;
|
|
569
|
+
var describeUsedKey = (reusable) => `Using ${REUSED_KEY_SOURCE_LABELS[reusable.source]}: ${maskKey(reusable.key)}`;
|
|
570
|
+
var keyReuseConfirmation = (context) => context.stdoutIsTty && !context.nonInteractive && !context.dryRun && context.canPairWithApp ? "ask" : "announce";
|
|
571
|
+
var accountHandleOf = (identity) => identity.siteSlug ? `@${identity.siteSlug}` : identity.siteName || null;
|
|
572
|
+
var keyAccountHandle = (check2) => check2.kind === "ok" ? accountHandleOf(check2.identity) : null;
|
|
573
|
+
var continueAsQuestion = (account) => account ? `Continue as ${account}?` : "Continue with this key?";
|
|
574
|
+
var WRONG_ACCOUNT_HINT = `Wrong account? Run ${NPX_LATEST_COMMAND} setup --connect app`;
|
|
575
|
+
var planNameOf = (plan) => {
|
|
576
|
+
const known = PLAN_TYPES.find((type) => type === plan);
|
|
577
|
+
return known ? PLAN_CONFIGS[known].name : null;
|
|
578
|
+
};
|
|
579
|
+
var describeSignedIn = (identity) => {
|
|
580
|
+
const account = accountHandleOf(identity) ?? "your account";
|
|
581
|
+
const planName = planNameOf(identity.plan);
|
|
582
|
+
return planName ? `Signed in to ${account} (${planName} plan)` : `Signed in to ${account}`;
|
|
583
|
+
};
|
|
584
|
+
var describeLockedKeyAccount = (key, account) => account ? `${account} has no active plan.` : `The key ${maskKey(key)} is on an account with no active plan.`;
|
|
585
|
+
|
|
586
|
+
// src/setup/service-notice.ts
|
|
587
|
+
var PHONE_START_OPT_OUT = "Turn it off with --control off.";
|
|
588
|
+
var describeServiceInstall = (servicePresent) => servicePresent ? `Updating the background service that lets your phone start agents. ${PHONE_START_OPT_OUT}` : `Installing a background service so your phone can start agents. ${PHONE_START_OPT_OUT}`;
|
|
589
|
+
|
|
324
590
|
// src/setup/phone-check.ts
|
|
325
591
|
var planPhoneCheck = (context) => {
|
|
326
592
|
if (context.locked) return "locked";
|
|
@@ -334,6 +600,23 @@ var planPhoneCheck = (context) => {
|
|
|
334
600
|
|
|
335
601
|
// src/setup/closing.ts
|
|
336
602
|
var ACTIVITY_URL = "pushary.com/dashboard/agent/activity";
|
|
603
|
+
var TRANSCRIPT_SYNC_NOTICE = `Transcripts sync redacted and encrypted. Your phone can decrypt them; authorized Pushary compliance admins can recover them for documented legal obligations. Turn off: ${NPX_LATEST_COMMAND} setup --transcripts off`;
|
|
604
|
+
var PAIR_PHONE_APP_HINT = `${NPX_LATEST_COMMAND} setup --connect app pair the Pushary app on your phone`;
|
|
605
|
+
var RESTART_AGENTS_LINE = "Restart any open agent sessions so they pick up Pushary.";
|
|
606
|
+
var ANSWERING_DEVICES = {
|
|
607
|
+
mobile_app: "Your phone",
|
|
608
|
+
mobile_background: "Your phone",
|
|
609
|
+
mac_app: "Your Mac"
|
|
610
|
+
};
|
|
611
|
+
var SIMULATED_ANSWER_HEADLINE = "Agents configured. The test answer was simulated.";
|
|
612
|
+
var answerSeconds = (latencyMs) => Math.max(1, Math.round(latencyMs / 1e3));
|
|
613
|
+
var describeAnsweredHeadline = (answer) => {
|
|
614
|
+
if (!answer) return "You're set. The test question was answered.";
|
|
615
|
+
if (answer.answerSource === "sandbox") return SIMULATED_ANSWER_HEADLINE;
|
|
616
|
+
const device = answer.answerSource ? ANSWERING_DEVICES[answer.answerSource] : void 0;
|
|
617
|
+
const seconds = answerSeconds(answer.latencyMs);
|
|
618
|
+
return device ? `You're set. ${device} answered in ${seconds}s.` : `You're set. The test question was answered in ${seconds}s.`;
|
|
619
|
+
};
|
|
337
620
|
var COMMAND_SURFACE = [
|
|
338
621
|
{ command: "pushary status", summary: "what this machine is connected to" },
|
|
339
622
|
{ command: "pushary mode", summary: "choose where approval requests appear" },
|
|
@@ -353,14 +636,13 @@ var nextSteps = (facts, reachable) => {
|
|
|
353
636
|
lines.push("Transcripts: disabled on this machine.");
|
|
354
637
|
lines.push("pushary setup --transcripts on enable encrypted transcript sync");
|
|
355
638
|
} else {
|
|
356
|
-
lines.push(
|
|
357
|
-
lines.push("pushary setup --transcripts off disable transcript sync on this machine");
|
|
639
|
+
lines.push(TRANSCRIPT_SYNC_NOTICE);
|
|
358
640
|
}
|
|
359
641
|
if (facts.completed.includes("claude_code")) {
|
|
360
642
|
lines.push("pushary claude launch a managed Claude Code session");
|
|
361
643
|
}
|
|
362
644
|
if (!reachable) {
|
|
363
|
-
lines.push(
|
|
645
|
+
lines.push(PAIR_PHONE_APP_HINT);
|
|
364
646
|
}
|
|
365
647
|
lines.push("pushary doctor re-check everything");
|
|
366
648
|
return lines;
|
|
@@ -415,8 +697,8 @@ var describeClosing = (facts) => {
|
|
|
415
697
|
if (facts.roundTripAnswered === true) {
|
|
416
698
|
return {
|
|
417
699
|
ok: true,
|
|
418
|
-
headline:
|
|
419
|
-
next: [
|
|
700
|
+
headline: describeAnsweredHeadline(facts.roundTripAnswer),
|
|
701
|
+
next: [RESTART_AGENTS_LINE, ...nextSteps(facts, reachable), "", `Approvals: ${ACTIVITY_URL}`],
|
|
420
702
|
exitCode: EXIT.OK,
|
|
421
703
|
reason: "synthetic-answer"
|
|
422
704
|
};
|
|
@@ -473,13 +755,26 @@ var describeClosing = (facts) => {
|
|
|
473
755
|
};
|
|
474
756
|
var RETRY_AGENT_LABEL = "Retry just this agent:";
|
|
475
757
|
var INSTALL_NODE_STEP = "Install the current Node.js LTS, which includes npm, then run setup again.";
|
|
476
|
-
var
|
|
758
|
+
var NPM_PREFIX_STEP = "npm can't install globally here. Use nvm, or run: npm config set prefix ~/.npm-global, then run setup again.";
|
|
759
|
+
var nextStepFor = (failure) => {
|
|
760
|
+
switch (failure.remedy) {
|
|
761
|
+
case "install-node":
|
|
762
|
+
return { kind: "install-node", instruction: INSTALL_NODE_STEP };
|
|
763
|
+
case "fix-npm-prefix":
|
|
764
|
+
return { kind: "fix-npm-prefix", instruction: NPM_PREFIX_STEP };
|
|
765
|
+
case "match-mac-account":
|
|
766
|
+
return { kind: "match-mac-account", instruction: matchMacAccountStep(failure.agent, null) };
|
|
767
|
+
case "retry-agent":
|
|
768
|
+
return { kind: "retry-agent", command: retryAgentCommand(failure.agent) };
|
|
769
|
+
}
|
|
770
|
+
};
|
|
477
771
|
var describeAgentFailures = (failures, agentName) => failures.map((failure) => ({
|
|
478
772
|
summary: `${agentName(failure.agent)}: ${failure.detail}`,
|
|
479
773
|
next: nextStepFor(failure)
|
|
480
774
|
}));
|
|
481
775
|
var agentFailureFollowUps = (failures) => [
|
|
482
776
|
...failures.some((failure) => failure.remedy === "install-node") ? ["install-node"] : [],
|
|
777
|
+
...failures.some((failure) => failure.remedy === "fix-npm-prefix") ? ["fix-npm-prefix"] : [],
|
|
483
778
|
...failures.some((failure) => failure.remedy === "retry-agent") ? ["run-doctor"] : []
|
|
484
779
|
];
|
|
485
780
|
var unverifiedKeyClosingReason = (facts) => {
|
|
@@ -791,7 +1086,7 @@ var formatError = (err) => {
|
|
|
791
1086
|
if (err instanceof Error) {
|
|
792
1087
|
const errWithSignal = err;
|
|
793
1088
|
if (errWithSignal.killed && errWithSignal.signal === "SIGTERM") {
|
|
794
|
-
return "timed out
|
|
1089
|
+
return "timed out, check your network connection";
|
|
795
1090
|
}
|
|
796
1091
|
return err.message;
|
|
797
1092
|
}
|
|
@@ -823,7 +1118,7 @@ var installGlobally2 = async () => {
|
|
|
823
1118
|
try {
|
|
824
1119
|
await installGlobally({ version });
|
|
825
1120
|
} catch (err) {
|
|
826
|
-
throw err instanceof NpmMissingError ? err :
|
|
1121
|
+
throw err instanceof NpmMissingError ? err : npmInstallFailure(err);
|
|
827
1122
|
}
|
|
828
1123
|
});
|
|
829
1124
|
globalInstallReady = true;
|
|
@@ -1568,10 +1863,10 @@ var setupCustom = async (apiKey, context) => {
|
|
|
1568
1863
|
console.log(` ${dim(`Use the key saved in ${PUSHARY_CONFIG_FILE} wherever`)} ${cyan("$PUSHARY_API_KEY")} ${dim("appears below.")}`);
|
|
1569
1864
|
}
|
|
1570
1865
|
console.log();
|
|
1571
|
-
console.log(` ${dim("MCP clients (Windsurf, LangChain, custom)
|
|
1866
|
+
console.log(` ${dim("For MCP clients (Windsurf, LangChain, custom), add this server:")}`);
|
|
1572
1867
|
console.log(` ${cyan("https://pushary.com/api/mcp/mcp")} ${dim("with header")} ${cyan("Authorization: Bearer $PUSHARY_API_KEY")}`);
|
|
1573
1868
|
console.log();
|
|
1574
|
-
console.log(` ${dim("
|
|
1869
|
+
console.log(` ${dim("For no-code or HTTP (n8n, Zapier, scripts), ask a human and wait:")}`);
|
|
1575
1870
|
console.log(` ${dim("POST")} ${cyan("https://pushary.com/api/v1/server/ask")} ${dim("body")} ${cyan('{"question":"Approve?","type":"confirm","wait":true}')}`);
|
|
1576
1871
|
console.log();
|
|
1577
1872
|
console.log(` ${dim("Full guide:")} ${cyan("https://pushary.com/docs/agents/connect-any-agent")}`);
|
|
@@ -1870,7 +2165,7 @@ var offerProjectInstructions = async (agents, options) => {
|
|
|
1870
2165
|
if (targets.length === 0 || !process.stdout.isTTY || options.nonInteractive) return;
|
|
1871
2166
|
console.log();
|
|
1872
2167
|
const wanted = await confirm({
|
|
1873
|
-
message:
|
|
2168
|
+
message: `Add a Pushary section to ${targets.map((target) => target.file).join(" and ")} in this folder? It tells agents here to ask through Pushary.`,
|
|
1874
2169
|
default: false
|
|
1875
2170
|
});
|
|
1876
2171
|
if (!wanted) return;
|
|
@@ -1890,7 +2185,7 @@ var offerClaudeAlias = async (options) => {
|
|
|
1890
2185
|
return;
|
|
1891
2186
|
}
|
|
1892
2187
|
const wanted = await confirm({
|
|
1893
|
-
message: `
|
|
2188
|
+
message: `Start ${bold("claude")} through Pushary, so your phone can reach idle sessions? This adds an alias to ${basename(rc.path)}.`,
|
|
1894
2189
|
default: false
|
|
1895
2190
|
});
|
|
1896
2191
|
if (!wanted) return;
|
|
@@ -1924,8 +2219,7 @@ var verifyKeyOrExit = async (apiKey, options, precomputed) => {
|
|
|
1924
2219
|
process.exit(await abortWith("key-refused", report.exitCode, result.kind));
|
|
1925
2220
|
}
|
|
1926
2221
|
if (result.kind === "ok") {
|
|
1927
|
-
|
|
1928
|
-
console.log(` ${check} Key verified ${dim(`(${siteSlug || siteName} \xB7 plan ${plan})`)}`);
|
|
2222
|
+
console.log(` ${check} ${describeSignedIn(result.identity)}`);
|
|
1929
2223
|
} else {
|
|
1930
2224
|
console.log(` ${yellow("!")} ${report.message}`);
|
|
1931
2225
|
for (const line of report.next) console.log(` ${dim(line)}`);
|
|
@@ -1954,6 +2248,14 @@ var usableStoredKey = async (apiKey) => {
|
|
|
1954
2248
|
}
|
|
1955
2249
|
return result.kind === "rejected" || result.kind === "malformed" ? null : result;
|
|
1956
2250
|
};
|
|
2251
|
+
var acceptReusableKey = async (reusable, confirmation) => {
|
|
2252
|
+
if (confirmation === "announce") {
|
|
2253
|
+
console.log(` ${check} ${describeUsedKey(reusable)}`);
|
|
2254
|
+
return true;
|
|
2255
|
+
}
|
|
2256
|
+
console.log(` ${describeFoundKey(reusable)}`);
|
|
2257
|
+
return confirm({ message: continueAsQuestion(keyAccountHandle(reusable.check)), default: true });
|
|
2258
|
+
};
|
|
1957
2259
|
var AGENT_NAMES = {
|
|
1958
2260
|
claude_code: "Claude Code",
|
|
1959
2261
|
codex: "Codex",
|
|
@@ -1980,6 +2282,22 @@ var AGENT_CAPABILITIES = {
|
|
|
1980
2282
|
};
|
|
1981
2283
|
var failedAgentNames = (failures) => failures.map((failure) => AGENT_NAMES[failure.agent]);
|
|
1982
2284
|
var agentFailureNextLine = (next) => next.kind === "retry-agent" ? `${dim(RETRY_AGENT_LABEL)} ${cyan(next.command)}` : next.instruction;
|
|
2285
|
+
var NO_ANSWER_YET = "No answer yet";
|
|
2286
|
+
var roundTripAnswerOf = (outcome) => outcome?.kind === "answered" ? { latencyMs: outcome.latencyMs, answerSource: outcome.answerSource } : null;
|
|
2287
|
+
var roundTripSpinnerEnd = (outcome) => {
|
|
2288
|
+
const report = describeRoundTripOutcome(outcome);
|
|
2289
|
+
return report.ok ? { ok: true, label: report.message } : { ok: false, label: NO_ANSWER_YET };
|
|
2290
|
+
};
|
|
2291
|
+
var agentFailureFollowUpLine = (followUp) => {
|
|
2292
|
+
switch (followUp) {
|
|
2293
|
+
case "install-node":
|
|
2294
|
+
return INSTALL_NODE_STEP;
|
|
2295
|
+
case "fix-npm-prefix":
|
|
2296
|
+
return NPM_PREFIX_STEP;
|
|
2297
|
+
case "run-doctor":
|
|
2298
|
+
return `${dim("Run")} ${NPX_LATEST_COMMAND} doctor ${dim("for the reason, or send it to")} ${SUPPORT_EMAIL}`;
|
|
2299
|
+
}
|
|
2300
|
+
};
|
|
1983
2301
|
var printAgentFailures = (failures) => {
|
|
1984
2302
|
for (const failure of describeAgentFailures(failures, (agent) => AGENT_NAMES[agent])) {
|
|
1985
2303
|
console.log(` ${yellow("!")} ${failure.summary}`);
|
|
@@ -2062,10 +2380,10 @@ var AGENT_TARGETS = {
|
|
|
2062
2380
|
};
|
|
2063
2381
|
var reportDryRun = (apiKey, agents, keyCheck, controlMode) => {
|
|
2064
2382
|
console.log();
|
|
2065
|
-
console.log(` ${bold("Dry run")} ${dim("
|
|
2383
|
+
console.log(` ${bold("Dry run.")} ${dim("Nothing below has been written.")}`);
|
|
2066
2384
|
console.log();
|
|
2067
2385
|
console.log(
|
|
2068
|
-
apiKey ? ` ${dim("Key:")} ${dim(`${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`)} ${dim(`(${keyCheck?.kind ?? "not verified"})`)}` : ` ${dim("Key:")} ${dim("none on this machine
|
|
2386
|
+
apiKey ? ` ${dim("Key:")} ${dim(`${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`)} ${dim(`(${keyCheck?.kind ?? "not verified"})`)}` : ` ${dim("Key:")} ${dim("none on this machine. A real run would acquire one.")}`
|
|
2069
2387
|
);
|
|
2070
2388
|
console.log(` ${dim("Key store:")} ${PUSHARY_CONFIG_FILE}`);
|
|
2071
2389
|
console.log(` ${dim("Control:")} ${controlMode}`);
|
|
@@ -2153,37 +2471,35 @@ var main = async () => {
|
|
|
2153
2471
|
storedKey !== envKey ? await usableStoredKey(storedKey) : null;
|
|
2154
2472
|
const appKey = ambientEligible && envCheck === null && storedCheck === null ? pickAppKey({ fromAgents: AGENT_CHOICES.map(appMcpKeyIfReadable), storedKey, envKey }) : null;
|
|
2155
2473
|
const appKeyCheck = appKey === null ? null : await usableStoredKey(appKey);
|
|
2474
|
+
const appBridgeAvailable = macAppBridgeAvailable();
|
|
2475
|
+
const canPairWithApp = canShowPairingQr() && !options.skipPhone;
|
|
2476
|
+
const keyReuse = keyReuseConfirmation({
|
|
2477
|
+
stdoutIsTty: process.stdout.isTTY === true,
|
|
2478
|
+
nonInteractive: options.nonInteractive,
|
|
2479
|
+
dryRun: options.dryRun,
|
|
2480
|
+
canPairWithApp
|
|
2481
|
+
});
|
|
2482
|
+
const reusable = pickReusableKey({
|
|
2483
|
+
storedKey,
|
|
2484
|
+
storedCheck,
|
|
2485
|
+
envKey,
|
|
2486
|
+
envCheck,
|
|
2487
|
+
agentConfigKey: appKey,
|
|
2488
|
+
agentConfigCheck: appKeyCheck,
|
|
2489
|
+
macAppInstalled: appBridgeAvailable
|
|
2490
|
+
});
|
|
2491
|
+
const reuseAccepted = reusable !== null && await acceptReusableKey(reusable, keyReuse);
|
|
2492
|
+
const reuseDeclined = reusable !== null && !reuseAccepted;
|
|
2156
2493
|
let storedKeyCheck = null;
|
|
2494
|
+
let pairedHandle = null;
|
|
2157
2495
|
if (flagKey) {
|
|
2158
2496
|
const masked = `${flagKey.slice(0, 8)}...${flagKey.slice(-4)}`;
|
|
2159
2497
|
console.log(` ${check} Using API key: ${dim(masked)}`);
|
|
2160
2498
|
console.log();
|
|
2161
2499
|
trimmedKey = flagKey;
|
|
2162
|
-
} else if (
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
console.log(` ${dim(PUSHARY_CONFIG_FILE)}`);
|
|
2166
|
-
console.log();
|
|
2167
|
-
trimmedKey = storedKey;
|
|
2168
|
-
storedKeyCheck = storedCheck;
|
|
2169
|
-
} else if (envKey && envCheck !== null) {
|
|
2170
|
-
const masked = `${envKey.slice(0, 8)}...${envKey.slice(-4)}`;
|
|
2171
|
-
console.log(` ${check} Found API key in environment: ${dim(masked)}`);
|
|
2172
|
-
console.log();
|
|
2173
|
-
const useExisting = options.nonInteractive || options.dryRun ? true : await confirm({ message: "Use this key?", default: true });
|
|
2174
|
-
if (useExisting) {
|
|
2175
|
-
trimmedKey = envKey;
|
|
2176
|
-
storedKeyCheck = envCheck;
|
|
2177
|
-
} else {
|
|
2178
|
-
const apiKey = await input({ message: "API key:" });
|
|
2179
|
-
trimmedKey = apiKey.trim();
|
|
2180
|
-
}
|
|
2181
|
-
} else if (appKey !== null && appKeyCheck !== null) {
|
|
2182
|
-
const masked = `${appKey.slice(0, 8)}...${appKey.slice(-4)}`;
|
|
2183
|
-
console.log(` ${check} Using the key the Pushary Mac app is signed in with: ${dim(masked)}`);
|
|
2184
|
-
console.log();
|
|
2185
|
-
trimmedKey = appKey;
|
|
2186
|
-
storedKeyCheck = appKeyCheck;
|
|
2500
|
+
} else if (reusable !== null && reuseAccepted) {
|
|
2501
|
+
trimmedKey = reusable.key;
|
|
2502
|
+
storedKeyCheck = reusable.check;
|
|
2187
2503
|
} else if (options.dryRun) {
|
|
2188
2504
|
console.log(` ${dim("No key on this machine. A real run would connect one first.")}`);
|
|
2189
2505
|
console.log();
|
|
@@ -2192,18 +2508,16 @@ var main = async () => {
|
|
|
2192
2508
|
reportDryRun(null, plannedAgents, null, controlMode);
|
|
2193
2509
|
await emitJson(options, { ok: true, dryRun: true, agents: plannedAgents, control: controlMode, keyCheck: "skipped", key: "none" });
|
|
2194
2510
|
return;
|
|
2195
|
-
} else if (connectMode === "app" &&
|
|
2196
|
-
console.log(
|
|
2197
|
-
console.log(` ${dim("No app yet? Get it at")} ${cyan("https://pushary.com/download")}${dim(", this keeps waiting.")}`);
|
|
2198
|
-
console.log(` ${dim("No phone? Ctrl-C, then:")} ${cyan(BROWSER_CONNECT_COMMAND)}`);
|
|
2511
|
+
} else if (connectMode === "app" && canPairWithApp) {
|
|
2512
|
+
if (reuseDeclined) console.log();
|
|
2199
2513
|
markStep("pair");
|
|
2200
2514
|
const previous = readKeySource();
|
|
2201
2515
|
const computer = pairingComputerOf(hostname(), process.platform, detectedAgentChoices());
|
|
2202
2516
|
const paired = await connectViaAppPairing({
|
|
2203
2517
|
computer,
|
|
2204
|
-
onCancelled: async () => {
|
|
2518
|
+
onCancelled: async (exitCode2) => {
|
|
2205
2519
|
printPairingEscape();
|
|
2206
|
-
await reportSetupAbort("pairing-cancelled",
|
|
2520
|
+
await reportSetupAbort("pairing-cancelled", exitCode2);
|
|
2207
2521
|
}
|
|
2208
2522
|
});
|
|
2209
2523
|
if (paired.kind === "failed") {
|
|
@@ -2212,8 +2526,9 @@ var main = async () => {
|
|
|
2212
2526
|
}
|
|
2213
2527
|
trimmedKey = paired.apiKey;
|
|
2214
2528
|
keyFromPairing = true;
|
|
2215
|
-
|
|
2216
|
-
|
|
2529
|
+
pairedHandle = paired.handle ? `@${paired.handle}` : null;
|
|
2530
|
+
if (pairedHandle) {
|
|
2531
|
+
console.log(` ${check} Connected to ${cyan(pairedHandle)}`);
|
|
2217
2532
|
}
|
|
2218
2533
|
if (previous.key && previous.key !== trimmedKey) {
|
|
2219
2534
|
console.log(` ${yellow("!")} The key this machine used before (${keyPrefix(previous.key)}) is still active.`);
|
|
@@ -2275,24 +2590,26 @@ var main = async () => {
|
|
|
2275
2590
|
if (!options.dryRun) recordSetupKey(trimmedKey);
|
|
2276
2591
|
markStep("verify-key");
|
|
2277
2592
|
const keyCheck = await verifyKeyOrExit(trimmedKey, options, storedKeyCheck ?? void 0);
|
|
2278
|
-
|
|
2279
|
-
const agents = await resolveAgents(options);
|
|
2593
|
+
if (reuseAccepted && keyReuse === "announce") console.log(` ${dim(WRONG_ACCOUNT_HINT)}`);
|
|
2280
2594
|
if (options.dryRun) {
|
|
2281
|
-
|
|
2282
|
-
await
|
|
2595
|
+
markStep("resolve-agents");
|
|
2596
|
+
const plannedAgents = await resolveAgents(options);
|
|
2597
|
+
reportDryRun(trimmedKey, plannedAgents, keyCheck, controlMode);
|
|
2598
|
+
await emitJson(options, { ok: true, dryRun: true, agents: plannedAgents, control: controlMode, keyCheck: keyCheck?.kind ?? "skipped" });
|
|
2283
2599
|
return;
|
|
2284
2600
|
}
|
|
2285
2601
|
markStep("save-key");
|
|
2286
2602
|
const transcriptSync = transcriptPreferenceForSetup(options.transcripts);
|
|
2287
2603
|
if (transcriptSync) {
|
|
2288
2604
|
console.log();
|
|
2289
|
-
console.log(
|
|
2605
|
+
console.log(` ${TRANSCRIPT_SYNC_NOTICE}`);
|
|
2290
2606
|
}
|
|
2291
2607
|
const rc = await saveApiKey(trimmedKey, controlMode, transcriptSync);
|
|
2292
2608
|
if (trimmedKey === appKey) recordMacAppKeyPrefix(trimmedKey);
|
|
2293
2609
|
if (keyCheck.kind === "ok") clearDaemonNeedsLogin();
|
|
2610
|
+
markStep("resolve-agents");
|
|
2611
|
+
const agents = await resolveAgents(options);
|
|
2294
2612
|
const context = { rc };
|
|
2295
|
-
const appBridgeAvailable = macAppBridgeAvailable();
|
|
2296
2613
|
const accountChecks = /* @__PURE__ */ new Map();
|
|
2297
2614
|
if (keyCheck) accountChecks.set(trimmedKey, Promise.resolve(keyCheck));
|
|
2298
2615
|
const accountCheckFor = (key) => {
|
|
@@ -2302,15 +2619,20 @@ var main = async () => {
|
|
|
2302
2619
|
accountChecks.set(key, pending);
|
|
2303
2620
|
return pending;
|
|
2304
2621
|
};
|
|
2305
|
-
const
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
if (
|
|
2622
|
+
const setupAccount = keyAccountHandle(keyCheck);
|
|
2623
|
+
const compareAppAccount = async (agent) => {
|
|
2624
|
+
const wiringKey = appWiringAccountKeyFor(agent);
|
|
2625
|
+
if (!wiringKey) return { matches: false, setupAccount, macAccount: null };
|
|
2626
|
+
if (wiringKey === trimmedKey) return { matches: true, setupAccount, macAccount: setupAccount };
|
|
2309
2627
|
const [cliAccount, appAccount] = await Promise.all([
|
|
2310
2628
|
accountCheckFor(trimmedKey),
|
|
2311
|
-
accountCheckFor(
|
|
2629
|
+
accountCheckFor(wiringKey)
|
|
2312
2630
|
]);
|
|
2313
|
-
return
|
|
2631
|
+
return {
|
|
2632
|
+
matches: samePusharyAccount(cliAccount, appAccount),
|
|
2633
|
+
setupAccount: keyAccountHandle(cliAccount),
|
|
2634
|
+
macAccount: keyAccountHandle(appAccount)
|
|
2635
|
+
};
|
|
2314
2636
|
};
|
|
2315
2637
|
const staleEnvironmentKey = Boolean(envKey && envKey !== trimmedKey);
|
|
2316
2638
|
if (envKey && staleEnvironmentKey) {
|
|
@@ -2335,14 +2657,19 @@ var main = async () => {
|
|
|
2335
2657
|
const plan = planHooks({ owner: ownerBefore, takeOverHooks: options.takeOverHooks, nonInteractive: options.nonInteractive });
|
|
2336
2658
|
const keepAppWiring = plan === "keep";
|
|
2337
2659
|
if (keepAppWiring) {
|
|
2338
|
-
|
|
2660
|
+
const account = await compareAppAccount(agent);
|
|
2661
|
+
if (!account.matches) {
|
|
2339
2662
|
hookOwners.push({ agent, owner: "app", kept: true });
|
|
2340
|
-
|
|
2341
|
-
|
|
2663
|
+
failures.push(describedAgentFailure(agent, "app-account-mismatch"));
|
|
2664
|
+
const [summary, ...steps] = describeMacAccountMismatch({
|
|
2665
|
+
agent,
|
|
2666
|
+
agentName: AGENT_NAMES[agent],
|
|
2667
|
+
setupAccount: account.setupAccount,
|
|
2668
|
+
macAccount: account.macAccount
|
|
2669
|
+
});
|
|
2342
2670
|
console.log(`
|
|
2343
|
-
${yellow("!")} ${
|
|
2344
|
-
console.log(` ${dim(
|
|
2345
|
-
console.log(` ${dim("Or pass --take-over-hooks if you intentionally want the CLI to own these hooks.")}`);
|
|
2671
|
+
${yellow("!")} ${summary}`);
|
|
2672
|
+
for (const step of steps) console.log(` ${dim(step)}`);
|
|
2346
2673
|
continue;
|
|
2347
2674
|
}
|
|
2348
2675
|
console.log(`
|
|
@@ -2382,10 +2709,7 @@ var main = async () => {
|
|
|
2382
2709
|
console.log();
|
|
2383
2710
|
const configured = failedAgentsContext(completed.map((agent) => AGENT_NAMES[agent]));
|
|
2384
2711
|
console.log(` ${yellow("!")} Failed: ${failedAgentNames(failures).join(", ")}${configured ? ` ${dim(configured)}` : ""}`);
|
|
2385
|
-
for (const followUp of agentFailureFollowUps(failures)) {
|
|
2386
|
-
if (followUp === "install-node") console.log(` ${INSTALL_NODE_STEP}`);
|
|
2387
|
-
else console.log(` ${dim("Run")} ${NPX_LATEST_COMMAND} doctor ${dim("for the reason, or send it to")} ${SUPPORT_EMAIL}`);
|
|
2388
|
-
}
|
|
2712
|
+
for (const followUp of agentFailureFollowUps(failures)) console.log(` ${agentFailureFollowUpLine(followUp)}`);
|
|
2389
2713
|
}
|
|
2390
2714
|
markStep("project-instructions");
|
|
2391
2715
|
await offerProjectInstructions(agents, options);
|
|
@@ -2458,12 +2782,12 @@ var main = async () => {
|
|
|
2458
2782
|
// being a thing they have to know to run.
|
|
2459
2783
|
(phone?.reachesYou || phone?.outcome?.kind === "unattributable")) {
|
|
2460
2784
|
console.log();
|
|
2461
|
-
console.log(` ${dim("
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
const report =
|
|
2466
|
-
console.log(` ${
|
|
2785
|
+
console.log(` ${dim("Answer the test question on your phone.")}`);
|
|
2786
|
+
const answer = verifyRoundTrip(trimmedKey);
|
|
2787
|
+
await spinner("Waiting for you to tap the notification", async () => roundTripSpinnerEnd(await answer));
|
|
2788
|
+
roundTrip = await answer;
|
|
2789
|
+
const report = describeRoundTripOutcome(roundTrip);
|
|
2790
|
+
if (!report.ok) console.log(` ${yellow("!")} ${report.message}`);
|
|
2467
2791
|
for (const line of report.next) console.log(` ${dim(line)}`);
|
|
2468
2792
|
} else if (verifyMode === "roundtrip" && keyCheck.kind === "ok") {
|
|
2469
2793
|
console.log();
|
|
@@ -2472,7 +2796,7 @@ var main = async () => {
|
|
|
2472
2796
|
console.log();
|
|
2473
2797
|
if (keyCheck.kind === "locked" || keyCheck.kind === "unreachable") {
|
|
2474
2798
|
const report = describeKeyCheck(keyCheck);
|
|
2475
|
-
const next = [...report.next, "Finish activation: pushary setup (reuses the saved key)."];
|
|
2799
|
+
const next = keyCheck.kind === "locked" ? [...report.next, describeLockedKeyAccount(trimmedKey, pairedHandle), WRONG_ACCOUNT_HINT] : [...report.next, "Finish activation: pushary setup (reuses the saved key)."];
|
|
2476
2800
|
const exitCode2 = failures.length > 0 || controlLifecycleFailure ? EXIT.PROBLEMS_FOUND : report.exitCode;
|
|
2477
2801
|
printManualSteps();
|
|
2478
2802
|
console.log(` ${yellow(bold(keyCheck.kind === "locked" ? "Agents configured, approvals inactive." : "Configuration saved, activation unverified."))}`);
|
|
@@ -2577,6 +2901,7 @@ var main = async () => {
|
|
|
2577
2901
|
let controlFailureStage = null;
|
|
2578
2902
|
let daemon = null;
|
|
2579
2903
|
if (keyIsTrusted && controlPolicy === "enabled") {
|
|
2904
|
+
console.log(` ${dim(describeServiceInstall(servicePresent))}`);
|
|
2580
2905
|
try {
|
|
2581
2906
|
controlFailureStage = "package-install";
|
|
2582
2907
|
await installGlobally2();
|
|
@@ -2632,7 +2957,8 @@ var main = async () => {
|
|
|
2632
2957
|
transcriptSync,
|
|
2633
2958
|
// null when the check did not run, so it changes nothing. Only an outright
|
|
2634
2959
|
// `false` is allowed to hold back "Setup complete.".
|
|
2635
|
-
roundTripAnswered: roundTrip === null ? null : roundTrip.kind === "answered" ? true : roundTrip.kind === "unanswered" ? false : null
|
|
2960
|
+
roundTripAnswered: roundTrip === null ? null : roundTrip.kind === "answered" ? true : roundTrip.kind === "unanswered" ? false : null,
|
|
2961
|
+
roundTripAnswer: roundTripAnswerOf(roundTrip)
|
|
2636
2962
|
});
|
|
2637
2963
|
console.log(` ${closing.ok ? green(bold(closing.headline)) : yellow(bold(closing.headline))}`);
|
|
2638
2964
|
if (failures.length > 0) {
|