@pushary/agent-hooks 0.38.0 → 0.39.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.
|
@@ -148,14 +148,22 @@ var main = async () => {
|
|
|
148
148
|
const settings = readJson(CLAUDE_SETTINGS);
|
|
149
149
|
if (settings) {
|
|
150
150
|
const hooks = settings.hooks;
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
151
|
+
const CLAUDE_HOOK_CHECKS = [
|
|
152
|
+
{ event: "PreToolUse", needle: "pushary-hook", label: "PreToolUse hook" },
|
|
153
|
+
{ event: "PostToolUse", needle: "pushary-post-hook", label: "PostToolUse hook" },
|
|
154
|
+
{ event: "UserPromptSubmit", needle: "pushary-prompt-hook", label: "UserPromptSubmit hook" },
|
|
155
|
+
{ event: "Stop", needle: "pushary-stop-hook", label: "Stop hook" },
|
|
156
|
+
{ event: "StopFailure", needle: "pushary-stopfailure-hook", label: "StopFailure hook" },
|
|
157
|
+
{ event: "Notification", needle: "pushary-notification-hook", label: "Notification hook" },
|
|
158
|
+
{ event: "SessionStart", needle: "pushary-session-start-hook", label: "SessionStart hook" },
|
|
159
|
+
{ event: "SessionEnd", needle: "pushary-session-end-hook", label: "SessionEnd hook" },
|
|
160
|
+
{ event: "PermissionRequest", needle: "pushary-permission-hook", label: "PermissionRequest hook" },
|
|
161
|
+
{ event: "PermissionDenied", needle: "pushary-permission-denied-hook", label: "PermissionDenied hook" }
|
|
162
|
+
];
|
|
163
|
+
for (const { event, needle, label } of CLAUDE_HOOK_CHECKS) {
|
|
164
|
+
const present = JSON.stringify(hooks?.[event] ?? []).includes(needle);
|
|
165
|
+
check(present, `Claude Code: ${label}`, present ? void 0 : "missing \u2014 run npx @pushary/agent-hooks@latest upgrade");
|
|
166
|
+
}
|
|
159
167
|
const preHookCommand = extractHookCommand(hooks?.PreToolUse, "pushary-hook");
|
|
160
168
|
if (preHookCommand) {
|
|
161
169
|
const resolves = commandResolves(preHookCommand);
|
|
@@ -481,7 +481,7 @@ var setupClaudeCode = async (apiKey) => {
|
|
|
481
481
|
addPusharyToolPermissions(settings);
|
|
482
482
|
});
|
|
483
483
|
await installGlobally();
|
|
484
|
-
await spinner("Adding hooks (
|
|
484
|
+
await spinner("Adding hooks (approvals, activity, presence, and lifecycle events)", async () => {
|
|
485
485
|
addPusharyHooks(settings, resolveGlobalBinDir("pushary-hook"));
|
|
486
486
|
});
|
|
487
487
|
await spinner(`Writing ${CLAUDE_SETTINGS}`, async () => {
|
|
@@ -1,8 +1,67 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
execNpm,
|
|
4
|
-
npmErrorMessage
|
|
4
|
+
npmErrorMessage,
|
|
5
|
+
resolveGlobalBinDir
|
|
5
6
|
} from "../chunk-J7JWI3KU.js";
|
|
7
|
+
import {
|
|
8
|
+
addClaudeMcpServer,
|
|
9
|
+
addPusharyHooks,
|
|
10
|
+
addPusharyToolPermissions
|
|
11
|
+
} from "../chunk-7EW3USQF.js";
|
|
12
|
+
import "../chunk-Z5PL3K7C.js";
|
|
13
|
+
import {
|
|
14
|
+
getApiKey
|
|
15
|
+
} from "../chunk-NKXSILEW.js";
|
|
16
|
+
|
|
17
|
+
// src/reapply.ts
|
|
18
|
+
import { join, dirname } from "path";
|
|
19
|
+
import { homedir } from "os";
|
|
20
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
21
|
+
var CLAUDE_SETTINGS = join(homedir(), ".claude", "settings.json");
|
|
22
|
+
var CLAUDE_JSON = join(homedir(), ".claude.json");
|
|
23
|
+
var readJson = (filePath) => {
|
|
24
|
+
try {
|
|
25
|
+
return JSON.parse(readFileSync(filePath, "utf-8"));
|
|
26
|
+
} catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
var writeJson = (filePath, data) => {
|
|
31
|
+
const dir = dirname(filePath);
|
|
32
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
33
|
+
writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
34
|
+
};
|
|
35
|
+
var hasPusharyClaudeHooks = (settings) => JSON.stringify(settings.hooks ?? {}).includes("pushary-hook");
|
|
36
|
+
var hasPusharyMcp = (claudeJson) => !!claudeJson.mcpServers?.pushary;
|
|
37
|
+
var reapplyClaudeSettings = (apiKey, paths = {}) => {
|
|
38
|
+
const settingsPath = paths.settingsPath ?? CLAUDE_SETTINGS;
|
|
39
|
+
const claudeJsonPath = paths.claudeJsonPath ?? CLAUDE_JSON;
|
|
40
|
+
const settings = readJson(settingsPath);
|
|
41
|
+
const claudeJson = readJson(claudeJsonPath);
|
|
42
|
+
const configured = settings != null && hasPusharyClaudeHooks(settings) || claudeJson != null && hasPusharyMcp(claudeJson);
|
|
43
|
+
if (!configured) return { reapplied: false, hooks: false, mcp: false };
|
|
44
|
+
let hooks = false;
|
|
45
|
+
let mcp = false;
|
|
46
|
+
try {
|
|
47
|
+
const s = settings ?? {};
|
|
48
|
+
addPusharyToolPermissions(s);
|
|
49
|
+
addPusharyHooks(s, resolveGlobalBinDir("pushary-hook"));
|
|
50
|
+
writeJson(settingsPath, s);
|
|
51
|
+
hooks = true;
|
|
52
|
+
} catch {
|
|
53
|
+
}
|
|
54
|
+
if (apiKey) {
|
|
55
|
+
try {
|
|
56
|
+
const cj = claudeJson ?? {};
|
|
57
|
+
addClaudeMcpServer(cj, apiKey);
|
|
58
|
+
writeJson(claudeJsonPath, cj);
|
|
59
|
+
mcp = true;
|
|
60
|
+
} catch {
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return { reapplied: hooks || mcp, hooks, mcp };
|
|
64
|
+
};
|
|
6
65
|
|
|
7
66
|
// bin/pushary-upgrade.ts
|
|
8
67
|
var getInstalledVersion = () => {
|
|
@@ -52,7 +111,20 @@ var main = async () => {
|
|
|
52
111
|
console.error(`Upgrade failed: ${npmErrorMessage(err)}`);
|
|
53
112
|
process.exit(1);
|
|
54
113
|
}
|
|
55
|
-
|
|
114
|
+
let apiKey;
|
|
115
|
+
try {
|
|
116
|
+
apiKey = getApiKey();
|
|
117
|
+
} catch {
|
|
118
|
+
apiKey = void 0;
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
const result = reapplyClaudeSettings(apiKey);
|
|
122
|
+
if (result.reapplied) {
|
|
123
|
+
console.log("Refreshed Claude Code hooks and settings so the new hook set is active now.");
|
|
124
|
+
}
|
|
125
|
+
} catch {
|
|
126
|
+
}
|
|
127
|
+
console.log("Done. Your hooks point at the global install and settings were refreshed.");
|
|
56
128
|
console.log("Verify with: pushary doctor");
|
|
57
129
|
};
|
|
58
130
|
main();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pushary/agent-hooks",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.39.0",
|
|
4
4
|
"description": "Permission hooks for AI coding agents: route tool approvals through Pushary push notifications",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pushary",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"scripts": {
|
|
73
73
|
"build": "node scripts/bundle-plugin.mjs && tsup",
|
|
74
74
|
"dev": "tsup --watch",
|
|
75
|
-
"test": "bun test src/api.test.ts && bun test src/claude-config.test.ts && bun test src/config.test.ts && bun test src/mcp-http.test.ts && bun test src/retry.test.ts && bun test src/usage.test.ts && bun test src/validate.test.ts && bun test src/policy.test.ts && bun test src/npm.test.ts && bun test src/identity.test.ts && bun test src/pending.test.ts && bun test src/events.test.ts && bun test src/describe.test.ts && bun test src/suggestions.test.ts && bun test src/safe-commands.test.ts && bun test src/hook.test.ts && bun test src/codex-adapter.test.ts && bun test src/codex-config.test.ts && bun test src/gemini-adapter.test.ts && bun test src/gemini-config.test.ts && bun test src/instruction-file.test.ts && bun test src/pairing.test.ts && bun test src/wait-ladder.test.ts && bun test src/ledger.test.ts && bun test src/wrapper/wrapper.test.ts"
|
|
75
|
+
"test": "bun test src/api.test.ts && bun test src/claude-config.test.ts && bun test src/config.test.ts && bun test src/mcp-http.test.ts && bun test src/retry.test.ts && bun test src/usage.test.ts && bun test src/validate.test.ts && bun test src/policy.test.ts && bun test src/npm.test.ts && bun test src/identity.test.ts && bun test src/pending.test.ts && bun test src/events.test.ts && bun test src/describe.test.ts && bun test src/reapply.test.ts && bun test src/suggestions.test.ts && bun test src/safe-commands.test.ts && bun test src/hook.test.ts && bun test src/codex-adapter.test.ts && bun test src/codex-config.test.ts && bun test src/gemini-adapter.test.ts && bun test src/gemini-config.test.ts && bun test src/instruction-file.test.ts && bun test src/pairing.test.ts && bun test src/wait-ladder.test.ts && bun test src/ledger.test.ts && bun test src/wrapper/wrapper.test.ts"
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
78
|
"@inquirer/prompts": "^8.4.2",
|