@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 hasPreHook = JSON.stringify(hooks?.PreToolUse ?? []).includes("pushary-hook");
152
- const hasPostHook = JSON.stringify(hooks?.PostToolUse ?? []).includes("pushary-post-hook");
153
- const hasStopHook = JSON.stringify(hooks?.Stop ?? []).includes("pushary-stop-hook");
154
- const hasPromptHook = JSON.stringify(hooks?.UserPromptSubmit ?? []).includes("pushary-prompt-hook");
155
- check(hasPreHook, "Claude Code: PreToolUse hook");
156
- check(hasPostHook, "Claude Code: PostToolUse hook");
157
- check(hasStopHook, "Claude Code: Stop hook");
158
- check(hasPromptHook, "Claude Code: UserPromptSubmit hook", hasPromptHook ? void 0 : "missing, re-run setup to register it");
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 (PreToolUse, PostToolUse, UserPromptSubmit, Stop)", async () => {
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
- console.log("Done. Your hooks point at the global install, so agents pick this up on their next tool call.");
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.38.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",