@pushary/agent-hooks 1.5.0 → 1.6.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 +22 -0
- package/README.md +2 -1
- package/dist/bin/pushary-bell-hook.js +18 -18
- package/dist/bin/pushary-bell.js +6 -6
- package/dist/bin/pushary-claude.js +18 -18
- package/dist/bin/pushary-clean.js +19 -19
- package/dist/bin/pushary-codex-bridge.js +10 -10
- package/dist/bin/pushary-codex-hook.js +23 -23
- package/dist/bin/pushary-codex.js +6 -6
- package/dist/bin/pushary-connect.js +6 -6
- package/dist/bin/pushary-cowork.js +3 -3
- package/dist/bin/pushary-daemon.js +23 -22
- package/dist/bin/pushary-disconnect.js +10 -10
- package/dist/bin/pushary-doctor.js +52 -24
- package/dist/bin/pushary-elicitation-hook.js +17 -17
- package/dist/bin/pushary-gemini-bridge.js +9 -9
- package/dist/bin/pushary-gemini-hook.js +20 -20
- package/dist/bin/pushary-hook.js +23 -23
- package/dist/bin/pushary-login.js +7 -7
- package/dist/bin/pushary-logout.js +4 -4
- package/dist/bin/pushary-mode.js +3 -3
- package/dist/bin/pushary-notification-hook.js +20 -20
- package/dist/bin/pushary-opencode-hook.js +19 -19
- package/dist/bin/pushary-permission-denied-hook.js +24 -24
- 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 -23
- package/dist/bin/pushary-setup.js +63 -62
- package/dist/bin/pushary-stats.js +2 -2
- package/dist/bin/pushary-status.js +10 -10
- package/dist/bin/pushary-stop-hook.js +20 -20
- package/dist/bin/pushary-stopfailure-hook.js +20 -20
- package/dist/bin/pushary-transcript-register.js +16 -16
- package/dist/bin/pushary-transcripts.js +4 -4
- package/dist/bin/pushary-upgrade.js +80 -32
- package/dist/bin/pushary-wait.js +3 -3
- package/dist/{chunk-KEOLNHR3.js → chunk-5MH5P366.js} +2 -2
- package/dist/{chunk-HVBF35GT.js → chunk-5QCZYSYR.js} +1 -1
- package/dist/{chunk-IYTQ4B5I.js → chunk-644CGYOB.js} +66 -12
- package/dist/{chunk-FDHMNT24.js → chunk-66BIMA62.js} +6 -5
- package/dist/{chunk-UQHUUZ5H.js → chunk-7JSE6JTZ.js} +1 -1
- package/dist/{chunk-NFKVRMTM.js → chunk-A2GS2ENL.js} +6 -6
- package/dist/{chunk-TFKBFQCE.js → chunk-A5URWZTP.js} +1 -1
- package/dist/{chunk-MYP4UUFH.js → chunk-ALG3IBLB.js} +1 -1
- package/dist/{chunk-TUXFIVOH.js → chunk-B6TYEKJR.js} +1 -1
- package/dist/{chunk-CQYHOHOK.js → chunk-BE4P7ERZ.js} +3 -3
- package/dist/{chunk-EADZPVYW.js → chunk-BK5F3FGE.js} +3 -3
- package/dist/{chunk-F57RGL7K.js → chunk-BW3Y2D24.js} +4 -4
- package/dist/chunk-BY2CRWBO.js +38 -0
- package/dist/{chunk-43LJSM4F.js → chunk-CSW6A2EW.js} +1 -1
- package/dist/{chunk-7XT76LWT.js → chunk-DZ75BJ7V.js} +3 -3
- package/dist/{chunk-DTQNDR7C.js → chunk-E7MJBWSR.js} +1 -1
- package/dist/{chunk-DYHXOXUF.js → chunk-F2OPOBRO.js} +7 -21
- package/dist/{chunk-43ZDACBO.js → chunk-F4KRNFDE.js} +1 -1
- package/dist/{chunk-ORLJNJEO.js → chunk-FDF72XHK.js} +2 -2
- package/dist/{chunk-JF736N4C.js → chunk-FI3LQCUH.js} +5 -5
- package/dist/{chunk-DLJN5XEU.js → chunk-G5LENVCZ.js} +3 -3
- package/dist/{chunk-K3QVDAZW.js → chunk-GDXSCXQC.js} +1 -1
- package/dist/{chunk-5HYNICS7.js → chunk-GOXINLDU.js} +1 -1
- package/dist/{chunk-2QT3GCU4.js → chunk-GP6SFVEN.js} +1 -1
- package/dist/{chunk-J4J45VPZ.js → chunk-HWG7X3VI.js} +3 -3
- package/dist/{chunk-PCGZXWGQ.js → chunk-KZBGITM4.js} +4 -4
- package/dist/{chunk-NTQSICPJ.js → chunk-MOQOJOMD.js} +3 -3
- package/dist/{chunk-3NBODGQS.js → chunk-NDS27FXU.js} +1 -1
- package/dist/{chunk-H5LHTC5X.js → chunk-NYD7W7AT.js} +1 -1
- package/dist/{chunk-PNNBMH4E.js → chunk-OP7HFIWE.js} +28 -12
- package/dist/{chunk-SOCEY746.js → chunk-OR3A3RLH.js} +1 -1
- package/dist/{chunk-XWEONSLV.js → chunk-PCVVCS4A.js} +1 -1
- package/dist/{chunk-KJRALILH.js → chunk-PRZXYILJ.js} +2 -2
- package/dist/{chunk-OSSDK5RS.js → chunk-RBPJO4KG.js} +6 -2
- package/dist/{chunk-TIWURSLS.js → chunk-SFNRAEEW.js} +1 -1
- package/dist/{chunk-USQDVBEV.js → chunk-TDKE3V6W.js} +1 -1
- package/dist/{chunk-HU5LSYL2.js → chunk-VMNI33F5.js} +1 -1
- package/dist/{chunk-UYDTFCHW.js → chunk-VZANUMIF.js} +1 -1
- package/dist/{chunk-3ZSGKLSO.js → chunk-XGL5JC6U.js} +2 -2
- package/dist/chunk-XQOT4CCK.js +305 -0
- package/dist/{chunk-T4QY64OR.js → chunk-YFD7CRIZ.js} +376 -10
- package/dist/{reapply-D2TFN6XK.js → reapply-RRDVJATI.js} +12 -8
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +12 -12
- package/package.json +1 -1
|
@@ -1,27 +1,34 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
describeCodexTrustConfirmation
|
|
4
|
+
} from "../chunk-BY2CRWBO.js";
|
|
5
|
+
import {
|
|
6
|
+
ensureCodexTrustAfterReapply,
|
|
3
7
|
reapplyAllAgents
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
8
|
+
} from "../chunk-OP7HFIWE.js";
|
|
9
|
+
import "../chunk-NDS27FXU.js";
|
|
10
|
+
import "../chunk-XQOT4CCK.js";
|
|
6
11
|
import {
|
|
7
12
|
waitForMachineReadiness
|
|
8
|
-
} from "../chunk-
|
|
9
|
-
import "../chunk-
|
|
13
|
+
} from "../chunk-BW3Y2D24.js";
|
|
14
|
+
import "../chunk-HWG7X3VI.js";
|
|
10
15
|
import {
|
|
11
16
|
detectProviderLiveCapabilities,
|
|
12
17
|
hasSpawnProvider,
|
|
13
18
|
resolveControlPolicy
|
|
14
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-5MH5P366.js";
|
|
15
20
|
import {
|
|
16
21
|
AUTO_UPDATE_DISABLE_ENV,
|
|
17
22
|
describeAutoUpdateCheck,
|
|
18
23
|
globalInstallPrefix,
|
|
24
|
+
hasPendingUpgradeFinish,
|
|
19
25
|
isAutoUpdateDisabledByEnv,
|
|
20
26
|
parseAutoUpdateFlag,
|
|
27
|
+
readAutoUpdateState,
|
|
21
28
|
updateAutoUpdateState,
|
|
22
29
|
upgradeEntryFor
|
|
23
|
-
} from "../chunk-
|
|
24
|
-
import "../chunk-
|
|
30
|
+
} from "../chunk-RBPJO4KG.js";
|
|
31
|
+
import "../chunk-MOQOJOMD.js";
|
|
25
32
|
import {
|
|
26
33
|
daemonHasRemoteProof,
|
|
27
34
|
daemonServiceManagerAvailable,
|
|
@@ -32,13 +39,13 @@ import {
|
|
|
32
39
|
replaceDaemonService,
|
|
33
40
|
stopDaemonService,
|
|
34
41
|
waitForDaemonRemoteProof
|
|
35
|
-
} from "../chunk-
|
|
36
|
-
import "../chunk-
|
|
42
|
+
} from "../chunk-DZ75BJ7V.js";
|
|
43
|
+
import "../chunk-BK5F3FGE.js";
|
|
37
44
|
import {
|
|
38
45
|
needsShell
|
|
39
46
|
} from "../chunk-XHKBHWLX.js";
|
|
40
|
-
import "../chunk-
|
|
41
|
-
import "../chunk-
|
|
47
|
+
import "../chunk-VZANUMIF.js";
|
|
48
|
+
import "../chunk-7JSE6JTZ.js";
|
|
42
49
|
import {
|
|
43
50
|
LATEST_TAG,
|
|
44
51
|
autoUpdateLock,
|
|
@@ -54,22 +61,22 @@ import {
|
|
|
54
61
|
npmErrorMessage,
|
|
55
62
|
resolveGlobalBinary,
|
|
56
63
|
vscodePluginDir
|
|
57
|
-
} from "../chunk-
|
|
64
|
+
} from "../chunk-F2OPOBRO.js";
|
|
58
65
|
import {
|
|
59
66
|
exitOnHelpFlag
|
|
60
67
|
} from "../chunk-P4BNYJ5Q.js";
|
|
61
68
|
import {
|
|
62
69
|
readControlMode
|
|
63
|
-
} from "../chunk-
|
|
70
|
+
} from "../chunk-TDKE3V6W.js";
|
|
64
71
|
import {
|
|
65
72
|
EXIT
|
|
66
73
|
} from "../chunk-KZERVKTD.js";
|
|
67
|
-
import "../chunk-
|
|
74
|
+
import "../chunk-VMNI33F5.js";
|
|
68
75
|
import "../chunk-T7E75EKA.js";
|
|
69
76
|
import {
|
|
70
77
|
getApiKey
|
|
71
78
|
} from "../chunk-OSJEMXSR.js";
|
|
72
|
-
import "../chunk-
|
|
79
|
+
import "../chunk-YFD7CRIZ.js";
|
|
73
80
|
import {
|
|
74
81
|
NPX_LATEST_COMMAND
|
|
75
82
|
} from "../chunk-EA3IELHP.js";
|
|
@@ -172,12 +179,26 @@ var finishInNewInstall = (request) => {
|
|
|
172
179
|
};
|
|
173
180
|
var incompleteFinishDetail = (logPath) => `installed, but refreshing the agent configs did not finish cleanly; see ${logPath}`;
|
|
174
181
|
var newMajorDetail = (latest) => `${latest} is a new major version; run ${MANUAL_UPGRADE_COMMAND}`;
|
|
182
|
+
var finishInstalledUpgrade = (context, from, to) => {
|
|
183
|
+
const pending = { result: "finish_pending", from, to, detail: incompleteFinishDetail(context.logPath) };
|
|
184
|
+
recordAutoUpdateCheck(context.statePath, pending, new Date(context.now()).toISOString());
|
|
185
|
+
try {
|
|
186
|
+
context.finish({ entry: upgradeEntryFor(context.prefix), prefix: context.prefix, logPath: context.logPath });
|
|
187
|
+
return { result: "updated", from, to };
|
|
188
|
+
} catch {
|
|
189
|
+
return pending;
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
var isInstallableRelease = (latest, installed) => latest !== void 0 && isNewerVersion(latest, installed) && isSameMajorVersion(latest, installed);
|
|
175
193
|
var checkAndInstall = async (context) => {
|
|
176
194
|
const installed = packageVersionAt(context.packageRoot);
|
|
177
195
|
if (installed === void 0 || !isReleaseVersion(installed)) {
|
|
178
196
|
return { result: "failed", from: installed, detail: UNREADABLE_INSTALLED_VERSION };
|
|
179
197
|
}
|
|
198
|
+
const previous = readAutoUpdateState(context.statePath);
|
|
199
|
+
const pendingFinish = hasPendingUpgradeFinish(previous, installed);
|
|
180
200
|
const latest = await fetchLatestPublishedVersion({ fetchImpl: context.fetchImpl });
|
|
201
|
+
if (pendingFinish && !isInstallableRelease(latest, installed)) return finishInstalledUpgrade(context, previous.from, installed);
|
|
181
202
|
if (latest === void 0) return { result: "failed", from: installed, detail: UNREACHABLE_REGISTRY };
|
|
182
203
|
if (!isNewerVersion(latest, installed)) return { result: "current", from: installed };
|
|
183
204
|
if (!isSameMajorVersion(latest, installed)) {
|
|
@@ -187,14 +208,10 @@ var checkAndInstall = async (context) => {
|
|
|
187
208
|
try {
|
|
188
209
|
installAgentHooksGlobally({ version: latest, prefix: context.prefix, timeoutMs: INSTALL_TIMEOUT_MS }, context.runNpm);
|
|
189
210
|
} catch (error) {
|
|
211
|
+
if (pendingFinish) return finishInstalledUpgrade(context, previous.from, installed);
|
|
190
212
|
return { result: "failed", from: installed, to: latest, detail: npmErrorMessage(error) };
|
|
191
213
|
}
|
|
192
|
-
|
|
193
|
-
context.finish({ entry: upgradeEntryFor(context.prefix), prefix: context.prefix, logPath: context.logPath });
|
|
194
|
-
} catch {
|
|
195
|
-
return { result: "updated", from: installed, to: latest, detail: incompleteFinishDetail(context.logPath) };
|
|
196
|
-
}
|
|
197
|
-
return { result: "updated", from: installed, to: latest };
|
|
214
|
+
return finishInstalledUpgrade(context, installed, latest);
|
|
198
215
|
};
|
|
199
216
|
var recordAutoUpdateCheck = (statePath, check, at) => updateAutoUpdateState(statePath, {
|
|
200
217
|
lastCheckAt: at,
|
|
@@ -206,6 +223,7 @@ var recordAutoUpdateCheck = (statePath, check, at) => updateAutoUpdateState(stat
|
|
|
206
223
|
announced: check.result === "updated" ? false : void 0
|
|
207
224
|
});
|
|
208
225
|
var runAutoUpdate = async (run = {}) => {
|
|
226
|
+
if ((run.platform ?? process.platform) === "linux") return { kind: "linux" };
|
|
209
227
|
const packageRoot = run.packageRoot ?? ownPackageRoot();
|
|
210
228
|
const prefix = packageRoot === void 0 ? null : globalInstallPrefix(packageRoot);
|
|
211
229
|
if (packageRoot === void 0 || prefix === null) return { kind: "not_global_install" };
|
|
@@ -216,6 +234,7 @@ var runAutoUpdate = async (run = {}) => {
|
|
|
216
234
|
try {
|
|
217
235
|
const check = await checkAndInstall({
|
|
218
236
|
packageRoot,
|
|
237
|
+
statePath: run.statePath ?? autoUpdateState(),
|
|
219
238
|
prefix,
|
|
220
239
|
logPath,
|
|
221
240
|
now,
|
|
@@ -284,7 +303,9 @@ var finishUpgrade = async () => {
|
|
|
284
303
|
apiKey = void 0;
|
|
285
304
|
}
|
|
286
305
|
const inspectedAgents = reapplyAllAgents(apiKey);
|
|
306
|
+
const codexTrust = await ensureCodexTrustAfterReapply(inspectedAgents);
|
|
287
307
|
const refreshed = inspectedAgents.filter((agent) => agent.result.reapplied);
|
|
308
|
+
const failedRefreshes = inspectedAgents.filter((agent) => agent.result.failed);
|
|
288
309
|
const configuredControlProviders = inspectedAgents.filter((agent) => agent.result.configured && (agent.id === "claude" || agent.id === "codex" || agent.id === "gemini")).map((agent) => agent.id);
|
|
289
310
|
const controlMode = readControlMode();
|
|
290
311
|
const daemonStatus = readDaemonStatus();
|
|
@@ -329,21 +350,31 @@ var finishUpgrade = async () => {
|
|
|
329
350
|
console.log();
|
|
330
351
|
console.log("No key was readable here, so MCP entries kept the key they already had.");
|
|
331
352
|
}
|
|
332
|
-
} else {
|
|
353
|
+
} else if (failedRefreshes.length === 0) {
|
|
333
354
|
console.log("No agent config on this machine needed refreshing.");
|
|
334
355
|
}
|
|
356
|
+
if (codexTrust) {
|
|
357
|
+
console.log();
|
|
358
|
+
console.log(describeCodexTrustConfirmation(codexTrust));
|
|
359
|
+
}
|
|
335
360
|
console.log();
|
|
336
361
|
if (!daemonReady) {
|
|
337
362
|
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");
|
|
338
363
|
process.exitCode = 1;
|
|
339
364
|
return;
|
|
340
365
|
}
|
|
366
|
+
if (failedRefreshes.length > 0) {
|
|
367
|
+
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.`);
|
|
368
|
+
process.exitCode = 1;
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
341
371
|
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.");
|
|
342
372
|
console.log("Verify with: pushary doctor");
|
|
343
373
|
};
|
|
344
374
|
var AUTO_UPDATE_ON_MESSAGE = "Automatic updates are on. Pushary checks for a new version once a day, when an agent session starts.";
|
|
345
375
|
var AUTO_UPDATE_OFF_MESSAGE = "Automatic updates are off. Turn them back on with: pushary upgrade --auto=on";
|
|
346
376
|
var AUTO_UPDATE_RUN_MESSAGES = {
|
|
377
|
+
linux: `Automatic updates are paused on Linux to protect running sessions. When your sessions have finished, run: ${NPX_LATEST_COMMAND} upgrade`,
|
|
347
378
|
not_global_install: `This copy of Pushary is not a global npm install, so it does not update itself. Run: ${NPX_LATEST_COMMAND} upgrade`,
|
|
348
379
|
locked: "Another automatic update is already running."
|
|
349
380
|
};
|
|
@@ -361,7 +392,26 @@ var runAutomaticUpdate = async () => {
|
|
|
361
392
|
return;
|
|
362
393
|
}
|
|
363
394
|
console.log(`Automatic update: ${describeAutoUpdateCheck(outcome.state)}`);
|
|
364
|
-
if (outcome.state.lastResult === "failed") process.exitCode = 1;
|
|
395
|
+
if (outcome.state.lastResult === "failed" || outcome.state.lastResult === "finish_pending") process.exitCode = 1;
|
|
396
|
+
};
|
|
397
|
+
var FINISH_FAILED_MESSAGE = "Upgrade installed, but refreshing the agent configs did not finish. Fix the problem printed above, then run pushary upgrade again.";
|
|
398
|
+
var finishGlobalUpgrade = () => {
|
|
399
|
+
const upgradedBinary = resolveGlobalBinary("pushary-upgrade");
|
|
400
|
+
if (!upgradedBinary) {
|
|
401
|
+
console.error("Upgrade installed, but the new pushary-upgrade binary could not be found on PATH.");
|
|
402
|
+
process.exit(1);
|
|
403
|
+
}
|
|
404
|
+
try {
|
|
405
|
+
execFileSync2(upgradedBinary, [FINISH_UPGRADE_FLAG], {
|
|
406
|
+
stdio: "inherit",
|
|
407
|
+
shell: needsShell(upgradedBinary)
|
|
408
|
+
});
|
|
409
|
+
return true;
|
|
410
|
+
} catch {
|
|
411
|
+
console.error(FINISH_FAILED_MESSAGE);
|
|
412
|
+
process.exitCode = 1;
|
|
413
|
+
return false;
|
|
414
|
+
}
|
|
365
415
|
};
|
|
366
416
|
var main = async () => {
|
|
367
417
|
if (process.argv.includes(FINISH_UPGRADE_FLAG)) {
|
|
@@ -400,7 +450,13 @@ var main = async () => {
|
|
|
400
450
|
console.log("Check the result with: pushary doctor");
|
|
401
451
|
return;
|
|
402
452
|
}
|
|
453
|
+
const pendingFinish = hasPendingUpgradeFinish(readAutoUpdateState(autoUpdateState()), installed);
|
|
403
454
|
const latest = await fetchLatestPublishedVersion();
|
|
455
|
+
const newerPublished = latest !== void 0 && isNewerVersion(latest, installed);
|
|
456
|
+
if (pendingFinish && !newerPublished) {
|
|
457
|
+
if (!finishGlobalUpgrade()) return;
|
|
458
|
+
updateAutoUpdateState(autoUpdateState(), { lastResult: "updated", detail: void 0, announced: false });
|
|
459
|
+
}
|
|
404
460
|
if (latest && !isNewerVersion(latest, installed)) {
|
|
405
461
|
console.log(`Already on the latest version (${installed}).`);
|
|
406
462
|
return;
|
|
@@ -412,14 +468,6 @@ var main = async () => {
|
|
|
412
468
|
console.error(`Upgrade failed: ${npmErrorMessage(err)}`);
|
|
413
469
|
process.exit(1);
|
|
414
470
|
}
|
|
415
|
-
|
|
416
|
-
if (!upgradedBinary) {
|
|
417
|
-
console.error("Upgrade installed, but the new pushary-upgrade binary could not be found on PATH.");
|
|
418
|
-
process.exit(1);
|
|
419
|
-
}
|
|
420
|
-
execFileSync2(upgradedBinary, [FINISH_UPGRADE_FLAG], {
|
|
421
|
-
stdio: "inherit",
|
|
422
|
-
shell: needsShell(upgradedBinary)
|
|
423
|
-
});
|
|
471
|
+
finishGlobalUpgrade();
|
|
424
472
|
};
|
|
425
473
|
main();
|
package/dist/bin/pushary-wait.js
CHANGED
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
} from "../chunk-CVWG2N3Y.js";
|
|
5
5
|
import {
|
|
6
6
|
exitOnFailedResponse
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-PCVVCS4A.js";
|
|
8
|
+
import "../chunk-CSW6A2EW.js";
|
|
9
9
|
import {
|
|
10
10
|
createIo
|
|
11
11
|
} from "../chunk-5RUIFDTP.js";
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
getApiKey,
|
|
27
27
|
getBaseUrl
|
|
28
28
|
} from "../chunk-OSJEMXSR.js";
|
|
29
|
-
import "../chunk-
|
|
29
|
+
import "../chunk-YFD7CRIZ.js";
|
|
30
30
|
import "../chunk-EA3IELHP.js";
|
|
31
31
|
import "../chunk-HWJW3CPO.js";
|
|
32
32
|
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
resolveBinary,
|
|
3
3
|
resolveGlobalPackageVersion,
|
|
4
4
|
resolvePackageVersionFromBinary
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-F2OPOBRO.js";
|
|
6
6
|
import {
|
|
7
7
|
MANAGED_PROVIDERS
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-YFD7CRIZ.js";
|
|
9
9
|
|
|
10
10
|
// src/live-capabilities.ts
|
|
11
11
|
var CLAUDE_BRIDGE_CAPABILITY = "claude-bridge";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
activeHookSource,
|
|
3
3
|
activeIdentity
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-FI3LQCUH.js";
|
|
5
5
|
import {
|
|
6
6
|
blockedActionFingerprint,
|
|
7
7
|
defersToNativeMode,
|
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
hasBlockedActionHint,
|
|
10
10
|
recordBlockedActionHint,
|
|
11
11
|
reportMachineDenial
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-BE4P7ERZ.js";
|
|
13
13
|
import {
|
|
14
14
|
isGatingMoment,
|
|
15
15
|
recordKeylessMoment
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-F4KRNFDE.js";
|
|
17
17
|
import {
|
|
18
18
|
denyReasonFrom,
|
|
19
19
|
isDeferAnswer
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
reportEvent,
|
|
37
37
|
scopePathFor,
|
|
38
38
|
settleQuestionsForToolUse
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-66BIMA62.js";
|
|
40
40
|
import {
|
|
41
41
|
DECISION_STOP_REASON,
|
|
42
42
|
askUser,
|
|
@@ -51,7 +51,7 @@ import {
|
|
|
51
51
|
} from "./chunk-PYCQXCI5.js";
|
|
52
52
|
import {
|
|
53
53
|
getMachineId
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-7JSE6JTZ.js";
|
|
55
55
|
import {
|
|
56
56
|
getApiKey,
|
|
57
57
|
getBaseUrl
|
|
@@ -61,9 +61,13 @@ import {
|
|
|
61
61
|
GATE_BLOCK_REASON_MAX_LENGTH,
|
|
62
62
|
GATE_WIRE,
|
|
63
63
|
agentQuestionStrategy,
|
|
64
|
+
agentRulesAllowEveryInput,
|
|
64
65
|
buildDecisionEpisodeFeatures,
|
|
66
|
+
claudeAllowlistOwnsCall,
|
|
67
|
+
claudeConsultsItsAllowlist,
|
|
65
68
|
claudePermissionDeniedOutput,
|
|
66
69
|
claudePermissionRequestOutput,
|
|
70
|
+
claudePermissionRulesFromSettings,
|
|
67
71
|
claudePreToolUseOutput,
|
|
68
72
|
claudePromptsBeforeAnEdit,
|
|
69
73
|
editAsksAtTheAgentsPrompt,
|
|
@@ -79,7 +83,51 @@ import {
|
|
|
79
83
|
parseAgentQuestions,
|
|
80
84
|
resolveGate,
|
|
81
85
|
stoppedOutput
|
|
82
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-YFD7CRIZ.js";
|
|
87
|
+
|
|
88
|
+
// src/claude-permission-rules.ts
|
|
89
|
+
import { readFileSync, statSync } from "fs";
|
|
90
|
+
import { homedir } from "os";
|
|
91
|
+
import { join } from "path";
|
|
92
|
+
var MANAGED_CLAUDE_SETTINGS_BY_PLATFORM = {
|
|
93
|
+
darwin: "/Library/Application Support/ClaudeCode/managed-settings.json",
|
|
94
|
+
linux: "/etc/claude-code/managed-settings.json",
|
|
95
|
+
win32: "C:\\ProgramData\\ClaudeCode\\managed-settings.json"
|
|
96
|
+
};
|
|
97
|
+
var MAX_CLAUDE_SETTINGS_BYTES = 1048576;
|
|
98
|
+
var claudeSettingsLocationFor = (cwd, environment = process.env, home = homedir(), platform = process.platform) => ({
|
|
99
|
+
configDir: environment.CLAUDE_CONFIG_DIR || join(home, ".claude"),
|
|
100
|
+
projectDir: environment.CLAUDE_PROJECT_DIR || cwd || void 0,
|
|
101
|
+
managedSettingsPath: MANAGED_CLAUDE_SETTINGS_BY_PLATFORM[platform]
|
|
102
|
+
});
|
|
103
|
+
var claudeSettingsSources = (location) => [
|
|
104
|
+
...location.managedSettingsPath ? [{ path: location.managedSettingsPath, trust: "grants" }] : [],
|
|
105
|
+
{ path: join(location.configDir, "settings.json"), trust: "grants" },
|
|
106
|
+
...location.projectDir ? [
|
|
107
|
+
{ path: join(location.projectDir, ".claude", "settings.json"), trust: "restricts_only" },
|
|
108
|
+
{ path: join(location.projectDir, ".claude", "settings.local.json"), trust: "grants" }
|
|
109
|
+
] : []
|
|
110
|
+
];
|
|
111
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
112
|
+
var restrictionsOnly = (document) => {
|
|
113
|
+
if (!isRecord(document) || !isRecord(document.permissions)) return null;
|
|
114
|
+
const { ask: ask2, deny: deny2 } = document.permissions;
|
|
115
|
+
return { permissions: { ask: ask2, deny: deny2 } };
|
|
116
|
+
};
|
|
117
|
+
var readSettingsDocument = (path) => {
|
|
118
|
+
try {
|
|
119
|
+
const stats = statSync(path);
|
|
120
|
+
if (!stats.isFile() || stats.size > MAX_CLAUDE_SETTINGS_BYTES) return null;
|
|
121
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
122
|
+
} catch {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
var trustedDocument = ({ path, trust }) => {
|
|
127
|
+
const document = readSettingsDocument(path);
|
|
128
|
+
return trust === "grants" ? document : restrictionsOnly(document);
|
|
129
|
+
};
|
|
130
|
+
var readClaudePermissionRules = (location) => claudePermissionRulesFromSettings(claudeSettingsSources(location).map(trustedDocument));
|
|
83
131
|
|
|
84
132
|
// src/decision-episode.ts
|
|
85
133
|
var EPISODE_PATH = "/api/agent/decision-episode";
|
|
@@ -104,7 +152,7 @@ var reportDecisionEpisode = async (apiKey, input) => {
|
|
|
104
152
|
};
|
|
105
153
|
|
|
106
154
|
// src/hook.ts
|
|
107
|
-
import { basename, join } from "path";
|
|
155
|
+
import { basename, join as join2 } from "path";
|
|
108
156
|
import { tmpdir } from "os";
|
|
109
157
|
import { existsSync, writeFileSync } from "fs";
|
|
110
158
|
var START_MS = Date.now();
|
|
@@ -259,7 +307,8 @@ var dispatchModeHandler = async (apiKey, input, toolPolicy, machineId, trainingC
|
|
|
259
307
|
// The gate asks at most one question per tool call, so the runtime's id needs
|
|
260
308
|
// no suffix here. Absent on runtimes that do not send one, and the server then
|
|
261
309
|
// creates a fresh decision exactly as before.
|
|
262
|
-
toolUseId: input.tool_use_id
|
|
310
|
+
toolUseId: input.tool_use_id,
|
|
311
|
+
sessionToolAware: true
|
|
263
312
|
};
|
|
264
313
|
const signals = {};
|
|
265
314
|
const runHandler = () => {
|
|
@@ -298,7 +347,7 @@ var KEYLESS_NOTICE = "[pushary] Not connected (no API key), so your agent runs u
|
|
|
298
347
|
var oncePerSession = (kind, sessionId) => {
|
|
299
348
|
try {
|
|
300
349
|
const key = (sessionId || DEFAULT_SESSION).replace(/[^a-zA-Z0-9_-]/g, "");
|
|
301
|
-
const marker =
|
|
350
|
+
const marker = join2(tmpdir(), `pushary-${kind}-${key}`);
|
|
302
351
|
if (existsSync(marker)) return false;
|
|
303
352
|
writeFileSync(marker, "1", "utf-8");
|
|
304
353
|
return true;
|
|
@@ -457,6 +506,8 @@ var handleKeyless = (input) => {
|
|
|
457
506
|
}
|
|
458
507
|
return void 0;
|
|
459
508
|
};
|
|
509
|
+
var claudePermissionRulesFor = (input) => ACTIVE_SOURCE === "claude" ? readClaudePermissionRules(claudeSettingsLocationFor(input.cwd)) : null;
|
|
510
|
+
var claudeRulesMayCover = (input, rules) => rules !== null && claudeConsultsItsAllowlist(input.permission_mode) && agentRulesAllowEveryInput(rules, input.tool_name, [input.tool_input ?? {}], input.cwd);
|
|
460
511
|
var claudeGateInput = (modeState, config, input, canonical) => {
|
|
461
512
|
const toolName = canonical?.toolName ?? input.tool_name;
|
|
462
513
|
const toolInputs = canonical?.toolInputs ?? [input.tool_input ?? {}];
|
|
@@ -549,6 +600,7 @@ var handlePreToolUse = async (input, canonical) => {
|
|
|
549
600
|
if (!(verdict.kind === "gate" && verdict.scopeReason) && shouldDeferToNativeMode(input.permission_mode, input.tool_name)) {
|
|
550
601
|
return void 0;
|
|
551
602
|
}
|
|
603
|
+
if (claudeAllowlistOwnsCall(gateInput, verdict, input.permission_mode, claudePermissionRulesFor(input))) return void 0;
|
|
552
604
|
if (claudePromptsBeforeAnEdit(input.permission_mode) && editAsksAtTheAgentsPrompt(gateInput, verdict)) return handleTerminalOnly();
|
|
553
605
|
switch (verdict.kind) {
|
|
554
606
|
case "allow":
|
|
@@ -578,7 +630,8 @@ var toPermissionRequestOutput = (hookOutput) => {
|
|
|
578
630
|
return void 0;
|
|
579
631
|
};
|
|
580
632
|
var handlePermissionRequest = async (input, canonical) => {
|
|
581
|
-
|
|
633
|
+
const claudeRules = claudePermissionRulesFor(input);
|
|
634
|
+
if (canonical === void 0 && !claudeRulesMayCover(input, claudeRules) && isPermissionRequestOwnedByPreToolUse(input.tool_name, input.permission_mode, shouldDeferToNativeMode)) return void 0;
|
|
582
635
|
if (isPusharyOwnTool(input.tool_name)) return void 0;
|
|
583
636
|
let apiKey;
|
|
584
637
|
try {
|
|
@@ -589,7 +642,8 @@ var handlePermissionRequest = async (input, canonical) => {
|
|
|
589
642
|
try {
|
|
590
643
|
const modeState = await fetchModeState(apiKey, input.session_id);
|
|
591
644
|
const policy = await getPolicy(apiKey, modeState.policyVersion, ACTIVE_AGENT.type, true, input.session_id);
|
|
592
|
-
const
|
|
645
|
+
const gateInput = claudeGateInput(modeState, policy, input, canonical);
|
|
646
|
+
const verdict = resolveGate(gateInput);
|
|
593
647
|
if (verdict.kind === "kill") {
|
|
594
648
|
await reportMachineDenial(input, verdict, ACTIVE_AGENT);
|
|
595
649
|
return permReqHalted(verdict.reason);
|
|
@@ -601,7 +655,7 @@ var handlePermissionRequest = async (input, canonical) => {
|
|
|
601
655
|
if (canonical === null) return permReqDeny(unreadableReason);
|
|
602
656
|
if (agentQuestionStrategy(ACTIVE_SOURCE, "PermissionRequest", input.tool_name) === AGENT_QUESTION_STRATEGY.native) return void 0;
|
|
603
657
|
if (verdict.kind === "gate" && verdict.scopeReason && (canonical?.toolInputs.length ?? 0) > 1) return permReqDeny(batchScopeReason);
|
|
604
|
-
if (!(verdict.kind === "gate" && verdict.scopeReason) && isPermissionRequestOwnedByPreToolUse(input.tool_name, input.permission_mode, shouldDeferToNativeMode)) return void 0;
|
|
658
|
+
if (!(verdict.kind === "gate" && verdict.scopeReason) && !claudeAllowlistOwnsCall(gateInput, verdict, input.permission_mode, claudeRules) && isPermissionRequestOwnedByPreToolUse(input.tool_name, input.permission_mode, shouldDeferToNativeMode)) return void 0;
|
|
605
659
|
switch (verdict.kind) {
|
|
606
660
|
case "allow":
|
|
607
661
|
return permReqAllow();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NOTIFICATION_PUSH_TYPES,
|
|
3
3
|
POSTTOOLUSE_MIRROR_ONLY_TOOLS
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VZANUMIF.js";
|
|
5
5
|
import {
|
|
6
6
|
cancelQuestion,
|
|
7
7
|
isPolicyConfig,
|
|
@@ -10,13 +10,13 @@ import {
|
|
|
10
10
|
} from "./chunk-PYCQXCI5.js";
|
|
11
11
|
import {
|
|
12
12
|
getMachineId
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-7JSE6JTZ.js";
|
|
14
14
|
import {
|
|
15
15
|
withRetry
|
|
16
16
|
} from "./chunk-HETOKNIL.js";
|
|
17
17
|
import {
|
|
18
18
|
reportedInstallSource
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-VMNI33F5.js";
|
|
20
20
|
import {
|
|
21
21
|
getApiKey,
|
|
22
22
|
getBaseUrl
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
resolveAutoResolveOrigin,
|
|
45
45
|
resolvePolicy,
|
|
46
46
|
toToolLookup
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-YFD7CRIZ.js";
|
|
48
48
|
|
|
49
49
|
// src/policy.ts
|
|
50
50
|
import { createHash } from "crypto";
|
|
@@ -58,7 +58,7 @@ var policyRequestFor = (agentType) => ({
|
|
|
58
58
|
repoAware: REPO_AWARE_AGENTS.includes(agentType)
|
|
59
59
|
});
|
|
60
60
|
var policyCacheFile = (apiKey, agent, repoAware = false) => {
|
|
61
|
-
const parts = [apiKey, agent, repoAware ? "repoAware" : void 0].filter(Boolean);
|
|
61
|
+
const parts = [apiKey, agent, repoAware ? "repoAware" : void 0, "sessionToolAware"].filter(Boolean);
|
|
62
62
|
const hash = createHash("sha256").update(parts.join(":")).digest("hex").slice(0, 12);
|
|
63
63
|
return join(tmpdir(), `pushary-policy-${hash}.json`);
|
|
64
64
|
};
|
|
@@ -69,6 +69,7 @@ var fetchPolicy = async (apiKey, agent, repoAware = false, sessionId) => {
|
|
|
69
69
|
if (agent) params.set("agent", agent);
|
|
70
70
|
if (repoAware) params.set("repoAware", "1");
|
|
71
71
|
params.set("scopeAware", "1");
|
|
72
|
+
params.set("sessionToolAware", "1");
|
|
72
73
|
if (sessionId) params.set("sessionId", sessionId);
|
|
73
74
|
const query = params.toString();
|
|
74
75
|
const url = query ? `${baseUrl}/api/mcp/policy?${query}` : `${baseUrl}/api/mcp/policy`;
|
|
@@ -6,16 +6,16 @@ import {
|
|
|
6
6
|
} from "./chunk-SGZJ5LYH.js";
|
|
7
7
|
import {
|
|
8
8
|
hookOwnerOf
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-KZBGITM4.js";
|
|
10
10
|
import {
|
|
11
11
|
ensureDaemonRunning
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-DZ75BJ7V.js";
|
|
13
13
|
import {
|
|
14
14
|
buildTranscriptRecords,
|
|
15
15
|
decodePublicKey,
|
|
16
16
|
generateSessionKey,
|
|
17
17
|
wrapSessionKey
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-SFNRAEEW.js";
|
|
19
19
|
import {
|
|
20
20
|
fetchTranscriptRecipients,
|
|
21
21
|
uploadTranscriptRecords
|
|
@@ -23,14 +23,14 @@ import {
|
|
|
23
23
|
import {
|
|
24
24
|
transcriptEnvironmentPreference,
|
|
25
25
|
transcriptsEnabled
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-GP6SFVEN.js";
|
|
27
27
|
import {
|
|
28
28
|
codexHome,
|
|
29
29
|
pusharyDir
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-F2OPOBRO.js";
|
|
31
31
|
import {
|
|
32
32
|
readTranscriptPreference
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-TDKE3V6W.js";
|
|
34
34
|
import {
|
|
35
35
|
writeJsonAtomic
|
|
36
36
|
} from "./chunk-T7E75EKA.js";
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
COMPATIBLE_AGENT_TYPES,
|
|
9
9
|
isValidApiKey
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-YFD7CRIZ.js";
|
|
11
11
|
|
|
12
12
|
// src/setup/options.ts
|
|
13
13
|
var AGENT_CHOICES = ["claude_code", "codex", "gemini_cli", "hermes", "cursor", "vscode", "opencode", ...COMPATIBLE_AGENT_TYPES, "custom"];
|
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
permissionDeniedAction,
|
|
8
8
|
releaseThrottle,
|
|
9
9
|
reportEvent
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-66BIMA62.js";
|
|
11
11
|
import {
|
|
12
12
|
canonicalJson
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-F2OPOBRO.js";
|
|
14
14
|
import {
|
|
15
15
|
writeFileAtomic
|
|
16
16
|
} from "./chunk-T7E75EKA.js";
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
machineDecisionFor,
|
|
21
21
|
shouldDeferToNativeMode,
|
|
22
22
|
wireVerdictFor
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-YFD7CRIZ.js";
|
|
24
24
|
|
|
25
25
|
// src/machine-decision-audit.ts
|
|
26
26
|
import { basename } from "path";
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NOTIFICATION_MATCHED_TYPES,
|
|
3
3
|
POSTTOOLUSE_MIRRORED_TOOLS
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VZANUMIF.js";
|
|
5
5
|
import {
|
|
6
6
|
isProtectedByScope,
|
|
7
7
|
registerHookEntry
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-F2OPOBRO.js";
|
|
9
9
|
import {
|
|
10
10
|
CLAUDE_PRETOOLUSE_MATCHER,
|
|
11
11
|
HOOK_BUDGETS,
|
|
12
12
|
HOOK_LOCATOR_BINARY
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-YFD7CRIZ.js";
|
|
14
14
|
|
|
15
15
|
// src/gemini-config.ts
|
|
16
16
|
var GEMINI_HOOK_BINARY = "pushary-gemini-hook";
|
|
@@ -2,21 +2,21 @@ import {
|
|
|
2
2
|
detectProviderLiveCapabilities,
|
|
3
3
|
hasSpawnProvider,
|
|
4
4
|
resolveControlPolicy
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-5MH5P366.js";
|
|
6
6
|
import {
|
|
7
7
|
daemonHasRemoteProof,
|
|
8
8
|
daemonServiceManagerAvailable,
|
|
9
9
|
hasDaemonServiceDefinition,
|
|
10
10
|
readDaemonNeedsLogin,
|
|
11
11
|
readDaemonStatus
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-DZ75BJ7V.js";
|
|
13
13
|
import {
|
|
14
14
|
getMachineId
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-7JSE6JTZ.js";
|
|
16
16
|
import {
|
|
17
17
|
readControlMode,
|
|
18
18
|
readKeySource
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-TDKE3V6W.js";
|
|
20
20
|
import {
|
|
21
21
|
getBaseUrl
|
|
22
22
|
} from "./chunk-OSJEMXSR.js";
|