@pushary/agent-hooks 0.89.12 → 0.90.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +77 -0
- package/README.md +1 -0
- package/data/SKILL.md +1 -1
- package/data/cursor-plugin/skills/pushary/SKILL.md +1 -1
- package/data/vscode-plugin/skills/pushary/SKILL.md +1 -1
- package/dist/bin/pushary-bell-hook.js +4 -4
- package/dist/bin/pushary-bell.js +8 -8
- package/dist/bin/pushary-claude.js +194 -38
- package/dist/bin/pushary-clean.js +15 -32
- package/dist/bin/pushary-codex-bridge.js +37 -12
- package/dist/bin/pushary-codex-hook.js +45 -12
- package/dist/bin/pushary-codex.js +7 -7
- package/dist/bin/pushary-connect.js +11 -10
- package/dist/bin/pushary-daemon.js +186 -62
- package/dist/bin/pushary-disconnect.js +8 -8
- package/dist/bin/pushary-doctor.js +108 -25
- package/dist/bin/pushary-elicitation-hook.js +4 -4
- package/dist/bin/pushary-gemini-bridge.js +33 -11
- package/dist/bin/pushary-gemini-hook.js +21 -10
- package/dist/bin/pushary-hook.js +13 -13
- package/dist/bin/pushary-login.js +18 -7
- package/dist/bin/pushary-logout.js +6 -6
- package/dist/bin/pushary-mode.js +28 -21
- package/dist/bin/pushary-notification-hook.js +7 -7
- package/dist/bin/pushary-opencode-hook.js +8 -8
- package/dist/bin/pushary-permission-denied-hook.js +11 -11
- package/dist/bin/pushary-permission-hook.js +11 -11
- package/dist/bin/pushary-post-hook.js +14 -8
- package/dist/bin/pushary-prompt-hook.js +7 -7
- package/dist/bin/pushary-session-end-hook.js +7 -7
- package/dist/bin/pushary-session-start-hook.js +7 -7
- package/dist/bin/pushary-setup.js +168 -45
- package/dist/bin/pushary-stats.js +4 -4
- package/dist/bin/pushary-status.js +11 -10
- package/dist/bin/pushary-stop-hook.js +14 -8
- package/dist/bin/pushary-stopfailure-hook.js +7 -7
- package/dist/bin/pushary-suggestions.js +2 -2
- package/dist/bin/pushary-transcripts.d.ts +1 -0
- package/dist/bin/pushary-transcripts.js +79 -0
- package/dist/bin/pushary-upgrade.js +15 -15
- package/dist/bin/pushary-wait.js +5 -5
- package/dist/bin/pushary.js +3 -2
- package/dist/{chunk-KVHP5ZME.js → chunk-2LAHXHBR.js} +1 -1
- package/dist/{chunk-RLQWNEPM.js → chunk-43GMYSS4.js} +15 -0
- package/dist/{chunk-5NDB3YOE.js → chunk-54ELC7D7.js} +1 -1
- package/dist/{chunk-VPLQFXCH.js → chunk-5NAZ7SFS.js} +1 -1
- package/dist/chunk-7FE2KABY.js +156 -0
- package/dist/{chunk-DHR4F2CR.js → chunk-7TPQEWUZ.js} +1 -1
- package/dist/{chunk-Y4WVZIEI.js → chunk-AJYV3VGU.js} +1 -1
- package/dist/{chunk-QFJZHVVL.js → chunk-AZPIQG4G.js} +35 -1
- package/dist/{chunk-OCMOTJTW.js → chunk-B7UZHEBL.js} +29 -22
- package/dist/{chunk-7HYJPOGG.js → chunk-BQBEH6TV.js} +5 -5
- package/dist/{chunk-OTPJ4FUR.js → chunk-BVBEURWJ.js} +1 -1
- package/dist/{chunk-7DK3ZH3N.js → chunk-CELX75MW.js} +1 -1
- package/dist/{chunk-6VXNA5JB.js → chunk-CNPAT3HL.js} +3 -2
- package/dist/{chunk-327YMKP5.js → chunk-DYP6SMOR.js} +1 -1
- package/dist/chunk-DZDI62LY.js +145 -0
- package/dist/{chunk-VF3RTVWY.js → chunk-EZIEXHYM.js} +15 -7
- package/dist/{chunk-PS7DQ2SU.js → chunk-F2ICEWZL.js} +101 -19
- package/dist/{chunk-3XSP5SML.js → chunk-FQL5E6NG.js} +2 -2
- package/dist/{chunk-JHJHCMAF.js → chunk-FXEVRLHC.js} +20 -2
- package/dist/{chunk-6V7ZDH3A.js → chunk-GL3FFM7A.js} +7 -4
- package/dist/{chunk-NBRM3FMD.js → chunk-H2QZRQR2.js} +1 -1
- package/dist/{chunk-GKPURU7P.js → chunk-I463AEG3.js} +1 -1
- package/dist/{chunk-XREW7RQ3.js → chunk-JW4KO5AF.js} +1 -1
- package/dist/{chunk-OVEGEQSB.js → chunk-KUZWXPUS.js} +3 -2
- package/dist/{chunk-JVZX5YRJ.js → chunk-L4E2BIJ2.js} +80 -7
- package/dist/{chunk-RNKPLUWC.js → chunk-OSALSIUF.js} +1 -1
- package/dist/{chunk-MFNQ5IMW.js → chunk-PYA4FLKI.js} +32 -21
- package/dist/chunk-QCGNGEGE.js +15 -0
- package/dist/chunk-S6LYP7QA.js +127 -0
- package/dist/{chunk-OADGBOP7.js → chunk-TDZFPMSZ.js} +70 -11
- package/dist/{chunk-JJV5Q4KG.js → chunk-UZNKVRLE.js} +1 -1
- package/dist/{chunk-FCUUVHTS.js → chunk-VHWCVD42.js} +1 -1
- package/dist/{chunk-3MCEES6Z.js → chunk-VNMKIJZB.js} +15 -2
- package/dist/{chunk-6GU55AQQ.js → chunk-Y6BWPERV.js} +90 -7
- package/dist/chunk-YKLCWWEI.js +76 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.js +11 -11
- package/package.json +3 -2
- package/dist/chunk-NESKLV6R.js +0 -72
- package/dist/chunk-WDVQ6O4C.js +0 -84
|
@@ -2,9 +2,17 @@
|
|
|
2
2
|
import {
|
|
3
3
|
describeWaitLadder
|
|
4
4
|
} from "../chunk-IIENZE2J.js";
|
|
5
|
+
import {
|
|
6
|
+
describeBridgeResolution,
|
|
7
|
+
isBridgeLocator,
|
|
8
|
+
liveBridgeProbe,
|
|
9
|
+
readServiceExecPath,
|
|
10
|
+
resolveBridgeStub,
|
|
11
|
+
versionManagerOf
|
|
12
|
+
} from "../chunk-S6LYP7QA.js";
|
|
5
13
|
import {
|
|
6
14
|
readMachineReadiness
|
|
7
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-7TPQEWUZ.js";
|
|
8
16
|
import {
|
|
9
17
|
CURSOR_GATE_SCRIPT,
|
|
10
18
|
agentProbes,
|
|
@@ -14,34 +22,44 @@ import {
|
|
|
14
22
|
isDetected,
|
|
15
23
|
isPluginRegistered,
|
|
16
24
|
vscodeSettingsTargets
|
|
17
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-FQL5E6NG.js";
|
|
18
26
|
import {
|
|
27
|
+
claudeOtherHolders,
|
|
19
28
|
claudeWired,
|
|
29
|
+
codexOtherHolders,
|
|
20
30
|
codexWired,
|
|
21
31
|
cursorMcpAuthorization,
|
|
32
|
+
cursorOtherHolders,
|
|
22
33
|
cursorWired,
|
|
34
|
+
describeHoldSentence,
|
|
35
|
+
describeOtherHolder,
|
|
36
|
+
geminiOtherHolders,
|
|
23
37
|
geminiWired,
|
|
38
|
+
holdsLong,
|
|
24
39
|
pusharyHookExecutable
|
|
25
|
-
} from "../chunk-
|
|
40
|
+
} from "../chunk-DZDI62LY.js";
|
|
26
41
|
import {
|
|
27
42
|
OPENCODE_PLUGIN_PLACEHOLDER,
|
|
28
43
|
openCodePluginDir,
|
|
29
44
|
openCodePluginFile,
|
|
30
45
|
openCodeWired
|
|
31
|
-
} from "../chunk-
|
|
46
|
+
} from "../chunk-CELX75MW.js";
|
|
32
47
|
import {
|
|
33
48
|
GEMINI_HOOK_BINARY,
|
|
34
49
|
hasGeminiHooks,
|
|
35
50
|
missingGeminiHookEvents
|
|
36
|
-
} from "../chunk-
|
|
37
|
-
import "../chunk-
|
|
38
|
-
import "../chunk-
|
|
51
|
+
} from "../chunk-GL3FFM7A.js";
|
|
52
|
+
import "../chunk-2LAHXHBR.js";
|
|
53
|
+
import "../chunk-EZIEXHYM.js";
|
|
39
54
|
import {
|
|
40
55
|
daemonHasRemoteProof,
|
|
41
56
|
daemonServiceManagerAvailable,
|
|
57
|
+
describeDaemonLoginBlock,
|
|
42
58
|
hasDaemonServiceDefinition,
|
|
43
|
-
|
|
44
|
-
|
|
59
|
+
readDaemonNeedsLogin,
|
|
60
|
+
readDaemonStatus,
|
|
61
|
+
readInstalledDaemonService
|
|
62
|
+
} from "../chunk-F2ICEWZL.js";
|
|
45
63
|
import {
|
|
46
64
|
detectProviderLiveCapabilities,
|
|
47
65
|
hasSpawnProvider,
|
|
@@ -53,11 +71,11 @@ import {
|
|
|
53
71
|
} from "../chunk-L4ZCFMWW.js";
|
|
54
72
|
import {
|
|
55
73
|
readLedgerSummary
|
|
56
|
-
} from "../chunk-
|
|
57
|
-
import "../chunk-
|
|
74
|
+
} from "../chunk-VHWCVD42.js";
|
|
75
|
+
import "../chunk-L4E2BIJ2.js";
|
|
58
76
|
import {
|
|
59
77
|
getMachineId
|
|
60
|
-
} from "../chunk-
|
|
78
|
+
} from "../chunk-54ELC7D7.js";
|
|
61
79
|
import {
|
|
62
80
|
claudeJson,
|
|
63
81
|
claudeSettings,
|
|
@@ -78,19 +96,20 @@ import {
|
|
|
78
96
|
readCodexMcpAuth,
|
|
79
97
|
untrustedCodexHookEvents,
|
|
80
98
|
vscodePluginDir
|
|
81
|
-
} from "../chunk-
|
|
99
|
+
} from "../chunk-KUZWXPUS.js";
|
|
82
100
|
import {
|
|
83
101
|
describeReach,
|
|
84
102
|
describeRoundTrip,
|
|
85
103
|
fetchChannels,
|
|
86
104
|
reachVerdict,
|
|
87
105
|
verifyRoundTrip
|
|
88
|
-
} from "../chunk-
|
|
106
|
+
} from "../chunk-PYA4FLKI.js";
|
|
89
107
|
import "../chunk-3EGEA4KH.js";
|
|
90
108
|
import {
|
|
91
109
|
checkApiKey,
|
|
92
110
|
describeKeyCheck
|
|
93
|
-
} from "../chunk-
|
|
111
|
+
} from "../chunk-AJYV3VGU.js";
|
|
112
|
+
import "../chunk-QCGNGEGE.js";
|
|
94
113
|
import {
|
|
95
114
|
createIo
|
|
96
115
|
} from "../chunk-5RUIFDTP.js";
|
|
@@ -99,8 +118,8 @@ import {
|
|
|
99
118
|
} from "../chunk-GMXKITVA.js";
|
|
100
119
|
import {
|
|
101
120
|
exitOnHelpFlag
|
|
102
|
-
} from "../chunk-
|
|
103
|
-
import "../chunk-
|
|
121
|
+
} from "../chunk-BVBEURWJ.js";
|
|
122
|
+
import "../chunk-43GMYSS4.js";
|
|
104
123
|
import {
|
|
105
124
|
getPackageVersion
|
|
106
125
|
} from "../chunk-DINDL2CF.js";
|
|
@@ -108,7 +127,7 @@ import {
|
|
|
108
127
|
keyPrefix,
|
|
109
128
|
readControlMode,
|
|
110
129
|
readKeySource
|
|
111
|
-
} from "../chunk-
|
|
130
|
+
} from "../chunk-OSALSIUF.js";
|
|
112
131
|
import "../chunk-BC3VCZ3E.js";
|
|
113
132
|
import {
|
|
114
133
|
callMcpTool,
|
|
@@ -121,7 +140,7 @@ import {
|
|
|
121
140
|
import {
|
|
122
141
|
EXIT
|
|
123
142
|
} from "../chunk-KZERVKTD.js";
|
|
124
|
-
import "../chunk-
|
|
143
|
+
import "../chunk-JW4KO5AF.js";
|
|
125
144
|
import "../chunk-4LL6LG5X.js";
|
|
126
145
|
import {
|
|
127
146
|
getBaseUrl
|
|
@@ -129,7 +148,7 @@ import {
|
|
|
129
148
|
import {
|
|
130
149
|
CURSOR_GATE_EVENTS,
|
|
131
150
|
HOOK_LOCATOR_BINARY
|
|
132
|
-
} from "../chunk-
|
|
151
|
+
} from "../chunk-VNMKIJZB.js";
|
|
133
152
|
|
|
134
153
|
// bin/pushary-doctor.ts
|
|
135
154
|
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -192,6 +211,15 @@ var resolveDoctorExit = ({ keyExit, failures }) => {
|
|
|
192
211
|
return EXIT.PROBLEMS_FOUND;
|
|
193
212
|
};
|
|
194
213
|
|
|
214
|
+
// src/diagnostics/roundtrip-plan.ts
|
|
215
|
+
var planRoundTrip = (context) => {
|
|
216
|
+
if (context.roundtrip) return { kind: "always" };
|
|
217
|
+
if (context.noPush) return { kind: "never", why: "--no-push" };
|
|
218
|
+
if (context.json) return { kind: "never", why: "--json" };
|
|
219
|
+
if (!context.stdinIsTty) return { kind: "never", why: "not a terminal" };
|
|
220
|
+
return { kind: "ask", defaultAnswer: true };
|
|
221
|
+
};
|
|
222
|
+
|
|
195
223
|
// src/setup/agent-exec.ts
|
|
196
224
|
var firstToken = (command) => {
|
|
197
225
|
const trimmed = command.trim();
|
|
@@ -295,6 +323,21 @@ var check = (passed, label, detail, kind = "config") => {
|
|
|
295
323
|
var probes = agentProbes();
|
|
296
324
|
var installed = (agent) => isDetected(detectAgent(probes[agent]));
|
|
297
325
|
var agentsChecked = [];
|
|
326
|
+
var otherHoldersByAgent = {};
|
|
327
|
+
var bridgeStub = null;
|
|
328
|
+
var noteHookTarget = (command) => {
|
|
329
|
+
const executable = command ? pusharyHookExecutable(command) : null;
|
|
330
|
+
if (isBridgeLocator(executable)) bridgeStub = executable;
|
|
331
|
+
};
|
|
332
|
+
var reportOtherHolders = (agentLabel, holders) => {
|
|
333
|
+
if (holders.length === 0) return;
|
|
334
|
+
otherHoldersByAgent[agentLabel] = holders;
|
|
335
|
+
for (const holder of holders) {
|
|
336
|
+
const icon = holdsLong(holder) ? warn : dim("\u2013");
|
|
337
|
+
console.log(` ${icon} ${agentLabel}: ${describeOtherHolder(holder)}`);
|
|
338
|
+
}
|
|
339
|
+
console.log(` ${dim(describeHoldSentence(agentLabel))}`);
|
|
340
|
+
};
|
|
298
341
|
var skipped = (label, why) => {
|
|
299
342
|
console.log(` ${dim("\u2013")} ${label} ${dim(`(${why})`)}`);
|
|
300
343
|
};
|
|
@@ -418,6 +461,8 @@ var main = async () => {
|
|
|
418
461
|
const resolves = commandResolves(preHookCommand);
|
|
419
462
|
check(resolves, "Claude Code: hook command resolves", resolves ? preHookCommand : `not on PATH \u2014 ${preHookCommand}`);
|
|
420
463
|
}
|
|
464
|
+
noteHookTarget(preHookCommand);
|
|
465
|
+
reportOtherHolders("Claude Code", claudeOtherHolders(settings));
|
|
421
466
|
const permissions = settings.permissions;
|
|
422
467
|
const hasWildcard = permissions?.allow?.some((r) => r === "mcp__pushary__*" || r === "MCP(pushary:*)") ?? false;
|
|
423
468
|
check(hasWildcard, "Claude Code: Pushary tools auto-allowed", hasWildcard ? "mcp__pushary__*" : "missing");
|
|
@@ -485,6 +530,8 @@ var main = async () => {
|
|
|
485
530
|
const resolves = commandResolves(hookCommand);
|
|
486
531
|
check(resolves, "Codex: hook command resolves", resolves ? hookCommand : `not on PATH: ${hookCommand}`);
|
|
487
532
|
}
|
|
533
|
+
noteHookTarget(hookCommand);
|
|
534
|
+
reportOtherHolders("Codex", codexOtherHolders(codexHooksConfig));
|
|
488
535
|
const features = codexParsed.features;
|
|
489
536
|
const hooksFeatureDisabled = !!features && typeof features === "object" && features.hooks === false;
|
|
490
537
|
check(!hooksFeatureDisabled, "Codex: hooks feature enabled", hooksFeatureDisabled ? "[features].hooks = false in config.toml" : void 0);
|
|
@@ -547,11 +594,13 @@ var main = async () => {
|
|
|
547
594
|
const resolves = commandResolves(hookCommand);
|
|
548
595
|
check(resolves, "Gemini CLI: hook command resolves", resolves ? hookCommand : `not on PATH: ${hookCommand}`);
|
|
549
596
|
}
|
|
597
|
+
noteHookTarget(hookCommand);
|
|
550
598
|
const geminiTimeout = extractHookTimeout(geminiHooks?.BeforeTool, GEMINI_HOOK_BINARY) ?? extractHookTimeout(geminiHooks?.BeforeTool, HOOK_LOCATOR_BINARY);
|
|
551
599
|
if (typeof geminiTimeout === "number") {
|
|
552
600
|
const ok = geminiTimeout >= 3e4;
|
|
553
601
|
check(ok, "Gemini CLI: hook timeout", ok ? `${geminiTimeout}ms` : `${geminiTimeout}ms too short (Gemini timeouts are milliseconds) \u2014 re-run setup`);
|
|
554
602
|
}
|
|
603
|
+
reportOtherHolders("Gemini CLI", geminiOtherHolders(geminiSettings2));
|
|
555
604
|
} else {
|
|
556
605
|
check(false, "Gemini CLI: native hooks installed", "no Pushary hooks in ~/.gemini/settings.json \u2014 re-run setup");
|
|
557
606
|
}
|
|
@@ -570,6 +619,7 @@ var main = async () => {
|
|
|
570
619
|
const controlSupported = hasSpawnProvider(controlCapabilities);
|
|
571
620
|
const controlMode = readControlMode();
|
|
572
621
|
const daemon = readDaemonStatus();
|
|
622
|
+
const loginBlock = readDaemonNeedsLogin();
|
|
573
623
|
const serviceDefined = hasDaemonServiceDefinition();
|
|
574
624
|
const managerAvailable = daemonServiceManagerAvailable();
|
|
575
625
|
const controlPolicy = resolveControlPolicy({
|
|
@@ -581,8 +631,9 @@ var main = async () => {
|
|
|
581
631
|
const controlRequired = controlPolicy === "enabled";
|
|
582
632
|
const controlUnsupported = controlMode === "on" && controlPolicy !== "enabled";
|
|
583
633
|
const daemonOk = controlUnsupported ? false : controlPolicy === "disabled" ? daemon.kind === "absent" && !serviceDefined : controlPolicy === "enabled" ? daemonHasRemoteProof(daemon) : controlPolicy === "legacy" ? false : daemon.kind === "absent" && !serviceDefined;
|
|
584
|
-
const
|
|
585
|
-
const
|
|
634
|
+
const needsLogin = loginBlock.kind === "blocked" ? `needs login: ${describeDaemonLoginBlock(loginBlock.record)}` : null;
|
|
635
|
+
const daemonFailure = daemonOk ? null : needsLogin ?? (controlUnsupported ? "control is required but no usable provider/service-manager pair is available" : controlPolicy === "enabled" && daemon.kind === "running" ? "the daemon has not completed an authenticated heartbeat and control poll" : controlPolicy === "disabled" ? `control is disabled but ${serviceDefined ? "the service definition remains" : `local state is ${daemon.kind}`}` : controlPolicy === "legacy" ? "a legacy service exists without a usable provider/service-manager pair" : `local state is ${daemon.kind}`);
|
|
636
|
+
const daemonDetail = daemonFailure ? needsLogin ? daemonFailure : controlUnsupported ? `${daemonFailure}; re-run setup with \`--control off\`, or restore both requirements` : controlPolicy === "disabled" ? `${daemonFailure}; re-run setup with \`--control off\`` : controlPolicy === "legacy" ? `${daemonFailure}; run setup with \`--control off\`, or restore both requirements` : `${daemonFailure}; run \`pushary daemon install\` to install or repair the background service` : controlPolicy === "disabled" ? "disabled by setup" : controlPolicy === "preserve-absent" ? "legacy absence preserved" : !controlRequired && daemon.kind === "absent" ? "managed control is unsupported on this provider or operating-system session" : null;
|
|
586
637
|
check(
|
|
587
638
|
daemonOk,
|
|
588
639
|
"Remote-control daemon",
|
|
@@ -594,9 +645,23 @@ var main = async () => {
|
|
|
594
645
|
`installed ${daemon.installedVersion}`,
|
|
595
646
|
`machine ${daemon.machineId ?? "none"}`,
|
|
596
647
|
`heartbeat ${daemon.lastSuccessfulHeartbeatAt ?? "none yet"}`,
|
|
597
|
-
`control ${daemon.lastSuccessfulControlAt ?? "none yet"}
|
|
648
|
+
`control ${daemon.lastSuccessfulControlAt ?? "none yet"}`,
|
|
649
|
+
daemon.lastError ? `last error ${daemon.lastError.message} at ${daemon.lastError.at}` : null
|
|
598
650
|
].filter((value) => value !== null).join(" \xB7 ")
|
|
599
651
|
);
|
|
652
|
+
const serviceFile = serviceDefined ? readInstalledDaemonService() : null;
|
|
653
|
+
const serviceNode = serviceFile ? readServiceExecPath(serviceFile.contents, process.platform) : null;
|
|
654
|
+
if (serviceFile && serviceNode) {
|
|
655
|
+
const present = existsSync(serviceNode);
|
|
656
|
+
const manager = versionManagerOf(serviceNode);
|
|
657
|
+
check(
|
|
658
|
+
present,
|
|
659
|
+
"Remote-control service runtime",
|
|
660
|
+
present ? `${serviceNode}${manager ? ` (managed by ${manager}; a version switch strands the service)` : ""}` : `${serviceNode} is gone${manager ? ` (${manager} switched Node since setup)` : ""}; run \`pushary daemon install\` to repin the service`
|
|
661
|
+
);
|
|
662
|
+
} else if (serviceFile) {
|
|
663
|
+
console.log(` ${warn} Remote-control service runtime ${dim(`(could not read the node path out of ${serviceFile.path})`)}`);
|
|
664
|
+
}
|
|
600
665
|
if (controlPolicy === "enabled" && apiKey && daemon.machineId) {
|
|
601
666
|
const serverProof = await readMachineReadiness(apiKey, ["spawn", ...controlCapabilities], {
|
|
602
667
|
machineId: daemon.machineId
|
|
@@ -639,7 +704,9 @@ var main = async () => {
|
|
|
639
704
|
"Cursor: permission gate registered",
|
|
640
705
|
broken.length === 0 ? `~/.cursor/hooks.json \u2192 ${paths_[0]} (${gateEntries.length} events)` : `gate script not found: ${broken[0]} \u2014 re-run setup`
|
|
641
706
|
);
|
|
707
|
+
noteHookTarget(String(gateEntries[0].entry.command));
|
|
642
708
|
}
|
|
709
|
+
reportOtherHolders("Cursor", cursorOtherHolders(cursorUserHooksJson));
|
|
643
710
|
const { authorization: cursorAuth, source: cursorMcpSource } = cursorMcpAuthorization(
|
|
644
711
|
readJson(join(cursorPluginDir2, "mcp.json")),
|
|
645
712
|
cursorUserMcpJson
|
|
@@ -679,6 +746,7 @@ var main = async () => {
|
|
|
679
746
|
"VS Code: permission gate present",
|
|
680
747
|
resolves ? scriptPath : `gate script not found: ${scriptPath || gateCommand} \u2014 re-run setup`
|
|
681
748
|
);
|
|
749
|
+
noteHookTarget(gateCommand);
|
|
682
750
|
}
|
|
683
751
|
const vscodeMcp = readJson(join(vscodePluginDir2, ".mcp.json"));
|
|
684
752
|
const vscodeServers = vscodeMcp?.mcpServers ?? {};
|
|
@@ -737,6 +805,10 @@ var main = async () => {
|
|
|
737
805
|
} else {
|
|
738
806
|
skipped("OpenCode", installed("opencode") ? "installed, but Pushary is not set up for it" : "not installed");
|
|
739
807
|
}
|
|
808
|
+
if (bridgeStub) {
|
|
809
|
+
const resolution = resolveBridgeStub(bridgeStub, liveBridgeProbe());
|
|
810
|
+
check(resolution.kind === "bundle", "Mac app behind pushary-bridge", describeBridgeResolution(resolution));
|
|
811
|
+
}
|
|
740
812
|
check(
|
|
741
813
|
agentsChecked.length > 0,
|
|
742
814
|
"Wired to at least one agent",
|
|
@@ -886,7 +958,16 @@ var main = async () => {
|
|
|
886
958
|
const msg = err instanceof Error ? err.message : "network error";
|
|
887
959
|
check(false, "Push notification sent", msg);
|
|
888
960
|
}
|
|
889
|
-
const
|
|
961
|
+
const roundTripPlan = planRoundTrip({
|
|
962
|
+
roundtrip: options.roundtrip,
|
|
963
|
+
noPush: options.noPush,
|
|
964
|
+
json: options.json,
|
|
965
|
+
stdinIsTty: process.stdin.isTTY === true
|
|
966
|
+
});
|
|
967
|
+
const testQuestion = roundTripPlan.kind === "always" ? true : roundTripPlan.kind === "never" ? false : await confirm({
|
|
968
|
+
message: "Test question roundtrip? (sends a push notification; the only check that proves you can answer one)",
|
|
969
|
+
default: roundTripPlan.defaultAnswer
|
|
970
|
+
});
|
|
890
971
|
if (testQuestion) {
|
|
891
972
|
console.log();
|
|
892
973
|
console.log(` ${dim("Question Roundtrip")}`);
|
|
@@ -964,9 +1045,11 @@ var main = async () => {
|
|
|
964
1045
|
exitCode,
|
|
965
1046
|
keyCheck: keyVerdict?.kind ?? null,
|
|
966
1047
|
daemon,
|
|
1048
|
+
daemonNeedsLogin: loginBlock.kind === "blocked" ? loginBlock.record : null,
|
|
967
1049
|
passed: results.filter((r) => r.passed).length,
|
|
968
1050
|
failed: failed.length,
|
|
969
|
-
checks: results.map((r) => ({ label: r.label, passed: r.passed, detail: r.detail ?? null }))
|
|
1051
|
+
checks: results.map((r) => ({ label: r.label, passed: r.passed, detail: r.detail ?? null })),
|
|
1052
|
+
otherHolders: otherHoldersByAgent
|
|
970
1053
|
}, null, 2)}
|
|
971
1054
|
`);
|
|
972
1055
|
}
|
|
@@ -11,11 +11,11 @@ import {
|
|
|
11
11
|
cancelQuestion,
|
|
12
12
|
pollForAnswer,
|
|
13
13
|
savePendingQuestion
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-FXEVRLHC.js";
|
|
15
15
|
import {
|
|
16
16
|
getMachineId
|
|
17
|
-
} from "../chunk-
|
|
18
|
-
import "../chunk-
|
|
17
|
+
} from "../chunk-54ELC7D7.js";
|
|
18
|
+
import "../chunk-KUZWXPUS.js";
|
|
19
19
|
import "../chunk-BSZYIAZL.js";
|
|
20
20
|
import "../chunk-SAF6HGAA.js";
|
|
21
21
|
import "../chunk-7QLSKOSU.js";
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
planElicitationAsk,
|
|
35
35
|
readElicitationFields,
|
|
36
36
|
renderElicitationOutput
|
|
37
|
-
} from "../chunk-
|
|
37
|
+
} from "../chunk-VNMKIJZB.js";
|
|
38
38
|
|
|
39
39
|
// bin/pushary-elicitation-hook.ts
|
|
40
40
|
import { basename } from "path";
|
|
@@ -5,16 +5,19 @@ import {
|
|
|
5
5
|
postLiveSession,
|
|
6
6
|
postLiveSessionUntilAccepted,
|
|
7
7
|
startLiveSessionHeartbeat
|
|
8
|
-
} from "../chunk-
|
|
9
|
-
import "../chunk-
|
|
8
|
+
} from "../chunk-CNPAT3HL.js";
|
|
9
|
+
import "../chunk-7FE2KABY.js";
|
|
10
10
|
import "../chunk-QZCFVWA7.js";
|
|
11
11
|
import {
|
|
12
12
|
transcriptsEnabled
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-UZNKVRLE.js";
|
|
14
14
|
import {
|
|
15
|
+
SESSION_IDLE_TIMEOUT_MS,
|
|
16
|
+
describeIdleWindow,
|
|
17
|
+
idleDeadlinePassed,
|
|
15
18
|
startProcessOwnership,
|
|
16
19
|
withSpawnProcessOwnership
|
|
17
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-Y6BWPERV.js";
|
|
18
21
|
import {
|
|
19
22
|
spawnClaude
|
|
20
23
|
} from "../chunk-XHKBHWLX.js";
|
|
@@ -23,17 +26,17 @@ import {
|
|
|
23
26
|
} from "../chunk-L4ZCFMWW.js";
|
|
24
27
|
import {
|
|
25
28
|
getMachineId
|
|
26
|
-
} from "../chunk-
|
|
27
|
-
import "../chunk-
|
|
28
|
-
import "../chunk-
|
|
29
|
+
} from "../chunk-54ELC7D7.js";
|
|
30
|
+
import "../chunk-KUZWXPUS.js";
|
|
31
|
+
import "../chunk-OSALSIUF.js";
|
|
29
32
|
import "../chunk-BC3VCZ3E.js";
|
|
30
|
-
import "../chunk-
|
|
33
|
+
import "../chunk-JW4KO5AF.js";
|
|
31
34
|
import "../chunk-4LL6LG5X.js";
|
|
32
35
|
import {
|
|
33
36
|
getApiKey,
|
|
34
37
|
getBaseUrl
|
|
35
38
|
} from "../chunk-2UMNXADU.js";
|
|
36
|
-
import "../chunk-
|
|
39
|
+
import "../chunk-VNMKIJZB.js";
|
|
37
40
|
|
|
38
41
|
// bin/pushary-gemini-bridge.ts
|
|
39
42
|
import { existsSync } from "fs";
|
|
@@ -158,11 +161,15 @@ var runGeminiTurn = (options) => new Promise((resolve, reject) => {
|
|
|
158
161
|
});
|
|
159
162
|
var runGeminiBridge = async (options) => {
|
|
160
163
|
const sessionId = options.resumeSessionId ?? randomUUID();
|
|
164
|
+
const now = options.now ?? Date.now;
|
|
165
|
+
const idleTimeoutMs = options.idleTimeoutMs ?? SESSION_IDLE_TIMEOUT_MS;
|
|
161
166
|
const ownership = startProcessOwnership({ sessionId, pid: process.pid, spawnId: options.spawnId });
|
|
162
167
|
let linked = false;
|
|
163
168
|
let stopHeartbeat = () => {
|
|
164
169
|
};
|
|
165
170
|
let firstTurn = !options.resumeSessionId;
|
|
171
|
+
let idleSince = now();
|
|
172
|
+
let idledOut = false;
|
|
166
173
|
const relay = options.transcripts === false ? null : new LiveTranscriptRelay(options, sessionId);
|
|
167
174
|
const reportBody = (event, action) => ({
|
|
168
175
|
event,
|
|
@@ -185,7 +192,12 @@ var runGeminiBridge = async (options) => {
|
|
|
185
192
|
reportBody("session_start", options.resumeSessionId ? "Session resumed" : "Session started")
|
|
186
193
|
);
|
|
187
194
|
linked = true;
|
|
188
|
-
stopHeartbeat = startLiveSessionHeartbeat(
|
|
195
|
+
stopHeartbeat = startLiveSessionHeartbeat(
|
|
196
|
+
options,
|
|
197
|
+
reportBody("heartbeat", "Session online"),
|
|
198
|
+
void 0,
|
|
199
|
+
() => ownership.touch()
|
|
200
|
+
);
|
|
189
201
|
};
|
|
190
202
|
const turn = (text, commandId) => {
|
|
191
203
|
const result = runGeminiTurn({
|
|
@@ -210,9 +222,14 @@ var runGeminiBridge = async (options) => {
|
|
|
210
222
|
if (!linked) throw error;
|
|
211
223
|
await report("turn_error", "Gemini turn failed").catch(() => null);
|
|
212
224
|
}
|
|
225
|
+
idleSince = now();
|
|
213
226
|
}
|
|
214
227
|
let pendingAck = null;
|
|
215
228
|
while (!options.signal.aborted) {
|
|
229
|
+
if (idleDeadlinePassed(idleSince, now(), idleTimeoutMs)) {
|
|
230
|
+
idledOut = true;
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
216
233
|
try {
|
|
217
234
|
if (pendingAck) {
|
|
218
235
|
const acknowledged = await postLiveSession(options, "/api/agent/command/ack", pendingAck);
|
|
@@ -232,8 +249,10 @@ var runGeminiBridge = async (options) => {
|
|
|
232
249
|
const commandId = string(command?.id);
|
|
233
250
|
const text = string(command?.text);
|
|
234
251
|
if (commandId && text) {
|
|
252
|
+
idleSince = now();
|
|
235
253
|
try {
|
|
236
254
|
const outcome2 = await turn(text, commandId);
|
|
255
|
+
idleSince = now();
|
|
237
256
|
if (outcome2 === "aborted") break;
|
|
238
257
|
void report("stop", "Turn completed").catch(() => null);
|
|
239
258
|
pendingAck = {
|
|
@@ -260,7 +279,10 @@ var runGeminiBridge = async (options) => {
|
|
|
260
279
|
await liveSessionSleep(options.pollIntervalMs ?? 2e3, options.signal);
|
|
261
280
|
}
|
|
262
281
|
await relay?.flush();
|
|
263
|
-
await report(
|
|
282
|
+
await report(
|
|
283
|
+
"session_closed",
|
|
284
|
+
idledOut ? `Session ended after ${describeIdleWindow(idleTimeoutMs)} idle` : "Session stopped"
|
|
285
|
+
).catch(() => null);
|
|
264
286
|
return "stopped";
|
|
265
287
|
} catch (error) {
|
|
266
288
|
if (!linked && options.claimId) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
isGatingMoment,
|
|
4
4
|
recordKeylessMoment
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-VHWCVD42.js";
|
|
6
6
|
import {
|
|
7
7
|
readHookInput
|
|
8
8
|
} from "../chunk-6CUUA7HO.js";
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
fetchModeState,
|
|
15
15
|
getPolicy,
|
|
16
16
|
handlePostToolUse,
|
|
17
|
+
handleSessionEnd,
|
|
17
18
|
handleStop,
|
|
18
19
|
handleUserPrompt,
|
|
19
20
|
policyRequestFor,
|
|
@@ -21,7 +22,7 @@ import {
|
|
|
21
22
|
readLastUserPrompt,
|
|
22
23
|
repoKeyFor,
|
|
23
24
|
reportEvent
|
|
24
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-TDZFPMSZ.js";
|
|
25
26
|
import {
|
|
26
27
|
DEFAULT_SESSION,
|
|
27
28
|
askUser,
|
|
@@ -29,7 +30,7 @@ import {
|
|
|
29
30
|
savePendingQuestion,
|
|
30
31
|
sendNotification,
|
|
31
32
|
waitForAnswer
|
|
32
|
-
} from "../chunk-
|
|
33
|
+
} from "../chunk-FXEVRLHC.js";
|
|
33
34
|
import {
|
|
34
35
|
UNNAMED_ACTION,
|
|
35
36
|
deriveActionBody,
|
|
@@ -37,16 +38,16 @@ import {
|
|
|
37
38
|
deriveToolTarget,
|
|
38
39
|
describeToolCall,
|
|
39
40
|
scopePathFor
|
|
40
|
-
} from "../chunk-
|
|
41
|
+
} from "../chunk-L4E2BIJ2.js";
|
|
41
42
|
import {
|
|
42
43
|
getMachineId
|
|
43
|
-
} from "../chunk-
|
|
44
|
-
import "../chunk-
|
|
44
|
+
} from "../chunk-54ELC7D7.js";
|
|
45
|
+
import "../chunk-KUZWXPUS.js";
|
|
45
46
|
import "../chunk-BSZYIAZL.js";
|
|
46
47
|
import "../chunk-SAF6HGAA.js";
|
|
47
48
|
import "../chunk-7QLSKOSU.js";
|
|
48
49
|
import "../chunk-KZERVKTD.js";
|
|
49
|
-
import "../chunk-
|
|
50
|
+
import "../chunk-JW4KO5AF.js";
|
|
50
51
|
import "../chunk-4LL6LG5X.js";
|
|
51
52
|
import {
|
|
52
53
|
getApiKey
|
|
@@ -59,7 +60,7 @@ import {
|
|
|
59
60
|
hookWaitClamped,
|
|
60
61
|
hookWaitDeadline,
|
|
61
62
|
resolveGate
|
|
62
|
-
} from "../chunk-
|
|
63
|
+
} from "../chunk-VNMKIJZB.js";
|
|
63
64
|
|
|
64
65
|
// bin/pushary-gemini-hook.ts
|
|
65
66
|
import { basename } from "path";
|
|
@@ -327,12 +328,22 @@ var main = async () => {
|
|
|
327
328
|
session_id: input.session_id
|
|
328
329
|
}, GEMINI_AGENT));
|
|
329
330
|
break;
|
|
330
|
-
case "
|
|
331
|
+
case "AfterAgent":
|
|
331
332
|
if (geminiOwnsLifecycle(process.env.PUSHARY_GEMINI_BRIDGE)) {
|
|
332
333
|
await handleStop({
|
|
333
334
|
cwd: input.cwd,
|
|
334
335
|
session_id: input.session_id,
|
|
335
|
-
transcript_path: input.transcript_path
|
|
336
|
+
transcript_path: input.transcript_path,
|
|
337
|
+
last_assistant_message: input.prompt_response
|
|
338
|
+
}, GEMINI_AGENT);
|
|
339
|
+
}
|
|
340
|
+
break;
|
|
341
|
+
case "SessionEnd":
|
|
342
|
+
if (geminiOwnsLifecycle(process.env.PUSHARY_GEMINI_BRIDGE)) {
|
|
343
|
+
await handleSessionEnd({
|
|
344
|
+
cwd: input.cwd,
|
|
345
|
+
session_id: input.session_id,
|
|
346
|
+
reason: input.reason
|
|
336
347
|
}, GEMINI_AGENT);
|
|
337
348
|
}
|
|
338
349
|
break;
|
package/dist/bin/pushary-hook.js
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handlePreToolUse
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-B7UZHEBL.js";
|
|
5
|
+
import "../chunk-2LAHXHBR.js";
|
|
6
|
+
import "../chunk-I463AEG3.js";
|
|
7
|
+
import "../chunk-VHWCVD42.js";
|
|
8
8
|
import {
|
|
9
9
|
readHookInput
|
|
10
10
|
} from "../chunk-6CUUA7HO.js";
|
|
11
11
|
import "../chunk-YHG74UFF.js";
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
12
|
+
import "../chunk-TDZFPMSZ.js";
|
|
13
|
+
import "../chunk-FXEVRLHC.js";
|
|
14
|
+
import "../chunk-L4E2BIJ2.js";
|
|
15
|
+
import "../chunk-54ELC7D7.js";
|
|
16
|
+
import "../chunk-KUZWXPUS.js";
|
|
17
17
|
import {
|
|
18
18
|
exitOnHelpFlag
|
|
19
|
-
} from "../chunk-
|
|
20
|
-
import "../chunk-
|
|
19
|
+
} from "../chunk-BVBEURWJ.js";
|
|
20
|
+
import "../chunk-43GMYSS4.js";
|
|
21
21
|
import "../chunk-DINDL2CF.js";
|
|
22
22
|
import "../chunk-BSZYIAZL.js";
|
|
23
23
|
import "../chunk-SAF6HGAA.js";
|
|
24
24
|
import "../chunk-7QLSKOSU.js";
|
|
25
25
|
import "../chunk-KZERVKTD.js";
|
|
26
|
-
import "../chunk-
|
|
26
|
+
import "../chunk-JW4KO5AF.js";
|
|
27
27
|
import "../chunk-4LL6LG5X.js";
|
|
28
28
|
import "../chunk-2UMNXADU.js";
|
|
29
|
-
import "../chunk-
|
|
29
|
+
import "../chunk-VNMKIJZB.js";
|
|
30
30
|
|
|
31
31
|
// bin/pushary-hook.ts
|
|
32
32
|
exitOnHelpFlag("hook");
|
|
@@ -2,11 +2,18 @@
|
|
|
2
2
|
import {
|
|
3
3
|
runBrowserLogin
|
|
4
4
|
} from "../chunk-Z3Z4VK5F.js";
|
|
5
|
+
import {
|
|
6
|
+
recoverDaemonAfterLogin
|
|
7
|
+
} from "../chunk-F2ICEWZL.js";
|
|
8
|
+
import "../chunk-XHKBHWLX.js";
|
|
9
|
+
import "../chunk-L4ZCFMWW.js";
|
|
10
|
+
import "../chunk-54ELC7D7.js";
|
|
11
|
+
import "../chunk-KUZWXPUS.js";
|
|
5
12
|
import "../chunk-3EGEA4KH.js";
|
|
6
13
|
import {
|
|
7
14
|
checkApiKey,
|
|
8
15
|
describeKeyCheck
|
|
9
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-AJYV3VGU.js";
|
|
10
17
|
import {
|
|
11
18
|
createIo
|
|
12
19
|
} from "../chunk-5RUIFDTP.js";
|
|
@@ -15,15 +22,15 @@ import {
|
|
|
15
22
|
} from "../chunk-GMXKITVA.js";
|
|
16
23
|
import {
|
|
17
24
|
exitOnHelpFlag
|
|
18
|
-
} from "../chunk-
|
|
19
|
-
import "../chunk-
|
|
25
|
+
} from "../chunk-BVBEURWJ.js";
|
|
26
|
+
import "../chunk-43GMYSS4.js";
|
|
20
27
|
import {
|
|
21
28
|
getPackageVersion
|
|
22
29
|
} from "../chunk-DINDL2CF.js";
|
|
23
30
|
import {
|
|
24
31
|
readKeySource,
|
|
25
32
|
writeKey
|
|
26
|
-
} from "../chunk-
|
|
33
|
+
} from "../chunk-OSALSIUF.js";
|
|
27
34
|
import "../chunk-BC3VCZ3E.js";
|
|
28
35
|
import "../chunk-SAF6HGAA.js";
|
|
29
36
|
import {
|
|
@@ -32,12 +39,12 @@ import {
|
|
|
32
39
|
import {
|
|
33
40
|
EXIT
|
|
34
41
|
} from "../chunk-KZERVKTD.js";
|
|
35
|
-
import "../chunk-
|
|
42
|
+
import "../chunk-JW4KO5AF.js";
|
|
36
43
|
import "../chunk-4LL6LG5X.js";
|
|
37
44
|
import "../chunk-2UMNXADU.js";
|
|
38
45
|
import {
|
|
39
46
|
isValidApiKey
|
|
40
|
-
} from "../chunk-
|
|
47
|
+
} from "../chunk-VNMKIJZB.js";
|
|
41
48
|
|
|
42
49
|
// bin/pushary-login.ts
|
|
43
50
|
exitOnHelpFlag("login");
|
|
@@ -89,7 +96,11 @@ var store = (apiKey, siteSlug, keyName) => {
|
|
|
89
96
|
} else if (result.rc.kind === "declined") {
|
|
90
97
|
say(` ${yellow("!")} ${dim(`Left ${result.rc.path} alone: line ${result.rc.declinedLine} already sets PUSHARY_API_KEY.`)}`);
|
|
91
98
|
}
|
|
92
|
-
|
|
99
|
+
const daemon = recoverDaemonAfterLogin();
|
|
100
|
+
if (daemon.cleared) {
|
|
101
|
+
say(daemon.restarted ? ` ${check} ${dim("Background daemon restarted with the new key.")}` : ` ${yellow("!")} ${dim(`Background daemon may start again${daemon.detail ? ` (${daemon.detail})` : ""}`)}`);
|
|
102
|
+
}
|
|
103
|
+
emit({ ok: true, siteSlug, keyName, configPath: result.configPath, rc: result.rc.kind, daemon });
|
|
93
104
|
};
|
|
94
105
|
var loginWithToken = async () => {
|
|
95
106
|
const token = await readStdin();
|