@malcomsonbrothers/claude-code-permission-hook 0.1.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/LICENSE +21 -0
- package/README.md +209 -0
- package/bin/cc-approve.js +3 -0
- package/dist/cache.d.ts +13 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +153 -0
- package/dist/cache.js.map +1 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +68 -0
- package/dist/config.js.map +1 -0
- package/dist/fast-decisions.d.ts +6 -0
- package/dist/fast-decisions.d.ts.map +1 -0
- package/dist/fast-decisions.js +137 -0
- package/dist/fast-decisions.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +529 -0
- package/dist/index.js.map +1 -0
- package/dist/llm-client.d.ts +3 -0
- package/dist/llm-client.d.ts.map +1 -0
- package/dist/llm-client.js +67 -0
- package/dist/llm-client.js.map +1 -0
- package/dist/logger.d.ts +9 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +45 -0
- package/dist/logger.js.map +1 -0
- package/dist/permission-handler.d.ts +8 -0
- package/dist/permission-handler.d.ts.map +1 -0
- package/dist/permission-handler.js +119 -0
- package/dist/permission-handler.js.map +1 -0
- package/dist/project.d.ts +6 -0
- package/dist/project.d.ts.map +1 -0
- package/dist/project.js +35 -0
- package/dist/project.js.map +1 -0
- package/dist/types.d.ts +117 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +120 -0
- package/dist/types.js.map +1 -0
- package/package.json +58 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
import { homedir } from "os";
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
import inquirer from "inquirer";
|
|
8
|
+
import { handlePermissionRequest } from "./permission-handler.js";
|
|
9
|
+
import { loadConfig, saveConfig, getConfigPath, getConfigDir, } from "./config.js";
|
|
10
|
+
import { clearCache, clearCacheByDecision, clearCacheByKey, clearCacheByGrep, listCacheEntries, getCacheStats, } from "./cache.js";
|
|
11
|
+
import { DEFAULT_SYSTEM_PROMPT } from "./types.js";
|
|
12
|
+
import { resolveProjectRoot } from "./project.js";
|
|
13
|
+
const program = new Command();
|
|
14
|
+
program
|
|
15
|
+
.name("cc-approve")
|
|
16
|
+
.description("Claude Code Permission Hook - Intelligent auto-approval for Claude Code")
|
|
17
|
+
.version("0.1.0");
|
|
18
|
+
// Main permission handler command
|
|
19
|
+
program
|
|
20
|
+
.command("permission")
|
|
21
|
+
.description("Handle a PermissionRequest hook (reads from stdin)")
|
|
22
|
+
.action(async () => {
|
|
23
|
+
try {
|
|
24
|
+
// Read input from stdin
|
|
25
|
+
const chunks = [];
|
|
26
|
+
for await (const chunk of process.stdin) {
|
|
27
|
+
chunks.push(chunk);
|
|
28
|
+
}
|
|
29
|
+
const rawInput = Buffer.concat(chunks).toString("utf-8");
|
|
30
|
+
const input = JSON.parse(rawInput);
|
|
31
|
+
// Process the permission request
|
|
32
|
+
const result = await handlePermissionRequest(input);
|
|
33
|
+
// Handle passthrough: null means exit 0 with no output
|
|
34
|
+
// This triggers Claude Code's native permission dialog
|
|
35
|
+
if (result === null) {
|
|
36
|
+
process.exit(0);
|
|
37
|
+
}
|
|
38
|
+
// Output result to stdout for allow/deny
|
|
39
|
+
console.log(JSON.stringify(result));
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
// On any error, output a deny response
|
|
43
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
44
|
+
const denyResponse = {
|
|
45
|
+
hookSpecificOutput: {
|
|
46
|
+
hookEventName: "PermissionRequest",
|
|
47
|
+
decision: {
|
|
48
|
+
behavior: "deny",
|
|
49
|
+
message: `Hook error: ${errorMessage}`,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
console.log(JSON.stringify(denyResponse));
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
// Install command
|
|
58
|
+
program
|
|
59
|
+
.command("install")
|
|
60
|
+
.description("Install the hook into Claude Code settings")
|
|
61
|
+
.action(async () => {
|
|
62
|
+
// Welcome message
|
|
63
|
+
console.log(chalk.cyan("╔══════════════════════════════════════════════════════════════╗"));
|
|
64
|
+
console.log(chalk.cyan("║ Claude Code Permission Hook - Auto-approval for Claude ║"));
|
|
65
|
+
console.log(chalk.cyan("╚══════════════════════════════════════════════════════════════╝"));
|
|
66
|
+
console.log();
|
|
67
|
+
console.log("This hook automatically approves safe development operations");
|
|
68
|
+
console.log("and blocks destructive commands.");
|
|
69
|
+
console.log();
|
|
70
|
+
// Provider selection
|
|
71
|
+
const { provider } = await inquirer.prompt([
|
|
72
|
+
{
|
|
73
|
+
type: "list",
|
|
74
|
+
name: "provider",
|
|
75
|
+
message: "Choose your LLM provider:",
|
|
76
|
+
choices: [
|
|
77
|
+
{
|
|
78
|
+
name: "OpenRouter (recommended - lowest latency)",
|
|
79
|
+
value: "openrouter",
|
|
80
|
+
},
|
|
81
|
+
{ name: "OpenAI", value: "openai" },
|
|
82
|
+
{ name: "Anthropic", value: "anthropic" },
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
]);
|
|
86
|
+
// API key input
|
|
87
|
+
const { apiKey } = await inquirer.prompt([
|
|
88
|
+
{
|
|
89
|
+
type: "password",
|
|
90
|
+
name: "apiKey",
|
|
91
|
+
message: "Enter your API key:",
|
|
92
|
+
mask: "X",
|
|
93
|
+
validate: (input) => {
|
|
94
|
+
if (!input || input.trim() === "") {
|
|
95
|
+
return "API key is required";
|
|
96
|
+
}
|
|
97
|
+
return true;
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
]);
|
|
101
|
+
// Set provider-specific defaults
|
|
102
|
+
let baseUrl;
|
|
103
|
+
let model = "gpt-4o-mini";
|
|
104
|
+
if (provider === "openrouter") {
|
|
105
|
+
baseUrl = "https://openrouter.ai/api/v1";
|
|
106
|
+
}
|
|
107
|
+
else if (provider === "anthropic") {
|
|
108
|
+
baseUrl = "https://api.anthropic.com/v1";
|
|
109
|
+
model = "claude-3-5-sonnet-20241022";
|
|
110
|
+
}
|
|
111
|
+
// OpenAI uses default baseUrl (undefined)
|
|
112
|
+
// Test API key
|
|
113
|
+
console.log(chalk.gray("\nValidating API key..."));
|
|
114
|
+
try {
|
|
115
|
+
const OpenAI = (await import("openai")).default;
|
|
116
|
+
const testClient = new OpenAI({
|
|
117
|
+
apiKey: apiKey.trim(),
|
|
118
|
+
baseURL: baseUrl,
|
|
119
|
+
});
|
|
120
|
+
await testClient.chat.completions.create({
|
|
121
|
+
model,
|
|
122
|
+
messages: [{ role: "user", content: "test" }],
|
|
123
|
+
max_tokens: 1,
|
|
124
|
+
});
|
|
125
|
+
console.log(chalk.green("✓ API key validated"));
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
129
|
+
console.log(chalk.red("✗ API key validation failed: " + message));
|
|
130
|
+
console.log(chalk.yellow("Please check your API key and try again."));
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
// Save config
|
|
134
|
+
const newConfig = {
|
|
135
|
+
llm: {
|
|
136
|
+
provider,
|
|
137
|
+
apiKey: apiKey.trim(),
|
|
138
|
+
model,
|
|
139
|
+
baseUrl,
|
|
140
|
+
systemPrompt: DEFAULT_SYSTEM_PROMPT,
|
|
141
|
+
},
|
|
142
|
+
cache: {
|
|
143
|
+
enabled: true,
|
|
144
|
+
ttlHours: 168,
|
|
145
|
+
},
|
|
146
|
+
logging: {
|
|
147
|
+
enabled: true,
|
|
148
|
+
level: "info",
|
|
149
|
+
},
|
|
150
|
+
customAllowPatterns: [],
|
|
151
|
+
customDenyPatterns: [],
|
|
152
|
+
customPassthroughPatterns: [],
|
|
153
|
+
};
|
|
154
|
+
saveConfig(newConfig);
|
|
155
|
+
// Find Claude Code settings
|
|
156
|
+
const settingsLocations = [
|
|
157
|
+
join(homedir(), ".claude", "settings.json"),
|
|
158
|
+
join(homedir(), "AppData", "Roaming", "Claude", "settings.json"),
|
|
159
|
+
];
|
|
160
|
+
let settingsPath = null;
|
|
161
|
+
for (const loc of settingsLocations) {
|
|
162
|
+
if (existsSync(loc)) {
|
|
163
|
+
settingsPath = loc;
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (!settingsPath) {
|
|
168
|
+
// Create default location
|
|
169
|
+
settingsPath = settingsLocations[0];
|
|
170
|
+
const dir = join(homedir(), ".claude");
|
|
171
|
+
if (!existsSync(dir)) {
|
|
172
|
+
const { mkdirSync } = await import("fs");
|
|
173
|
+
mkdirSync(dir, { recursive: true });
|
|
174
|
+
}
|
|
175
|
+
writeFileSync(settingsPath, JSON.stringify({ hooks: {} }, null, 2));
|
|
176
|
+
}
|
|
177
|
+
// Read and update settings
|
|
178
|
+
const settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
|
|
179
|
+
if (!settings.hooks) {
|
|
180
|
+
settings.hooks = {};
|
|
181
|
+
}
|
|
182
|
+
settings.hooks.PermissionRequest = [
|
|
183
|
+
{
|
|
184
|
+
matcher: "*",
|
|
185
|
+
hooks: [
|
|
186
|
+
{
|
|
187
|
+
type: "command",
|
|
188
|
+
command: "cc-approve permission",
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
];
|
|
193
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
194
|
+
console.log();
|
|
195
|
+
console.log(chalk.green("✓ Hook installed to " + settingsPath));
|
|
196
|
+
console.log(chalk.green("✓ Configuration saved to " + getConfigPath()));
|
|
197
|
+
console.log();
|
|
198
|
+
console.log(chalk.gray("Run 'cc-approve doctor' to verify setup."));
|
|
199
|
+
});
|
|
200
|
+
// Uninstall command
|
|
201
|
+
program
|
|
202
|
+
.command("uninstall")
|
|
203
|
+
.description("Remove the hook from Claude Code settings")
|
|
204
|
+
.action(async () => {
|
|
205
|
+
const settingsPath = join(homedir(), ".claude", "settings.json");
|
|
206
|
+
if (!existsSync(settingsPath)) {
|
|
207
|
+
console.log(chalk.yellow("Settings file not found"));
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
|
|
211
|
+
if (settings.hooks?.PermissionRequest) {
|
|
212
|
+
delete settings.hooks.PermissionRequest;
|
|
213
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
214
|
+
console.log(chalk.green("✓ Uninstalled successfully!"));
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
console.log(chalk.yellow("Hook was not installed"));
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
// Config command
|
|
221
|
+
program
|
|
222
|
+
.command("config")
|
|
223
|
+
.description("Configure API keys and settings")
|
|
224
|
+
.option("--model <model>", "Set the LLM model without running full interactive setup")
|
|
225
|
+
.action(async (options) => {
|
|
226
|
+
// Quick model update
|
|
227
|
+
if (options.model) {
|
|
228
|
+
const config = loadConfig();
|
|
229
|
+
const DEFAULT_MODEL = "gpt-4o-mini";
|
|
230
|
+
const model = options.model === "default" ? DEFAULT_MODEL : options.model;
|
|
231
|
+
config.llm.model = model;
|
|
232
|
+
saveConfig(config);
|
|
233
|
+
if (options.model === "default") {
|
|
234
|
+
console.log(chalk.green(`✓ Model reset to default (${DEFAULT_MODEL})`));
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
console.log(chalk.green(`✓ Model set to ${model}`));
|
|
238
|
+
}
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
const config = loadConfig();
|
|
242
|
+
// Provider selection
|
|
243
|
+
const { provider } = await inquirer.prompt([
|
|
244
|
+
{
|
|
245
|
+
type: "list",
|
|
246
|
+
name: "provider",
|
|
247
|
+
message: "Choose your LLM provider:",
|
|
248
|
+
choices: [
|
|
249
|
+
{
|
|
250
|
+
name: "OpenRouter (recommended - lowest latency)",
|
|
251
|
+
value: "openrouter",
|
|
252
|
+
},
|
|
253
|
+
{ name: "OpenAI", value: "openai" },
|
|
254
|
+
{ name: "Anthropic", value: "anthropic" },
|
|
255
|
+
],
|
|
256
|
+
default: config.llm.provider,
|
|
257
|
+
},
|
|
258
|
+
]);
|
|
259
|
+
// API key input
|
|
260
|
+
const { apiKey } = await inquirer.prompt([
|
|
261
|
+
{
|
|
262
|
+
type: "password",
|
|
263
|
+
name: "apiKey",
|
|
264
|
+
message: "Enter your API key:",
|
|
265
|
+
mask: "X",
|
|
266
|
+
validate: (input) => {
|
|
267
|
+
if (!input || input.trim() === "") {
|
|
268
|
+
return "API key is required";
|
|
269
|
+
}
|
|
270
|
+
return true;
|
|
271
|
+
},
|
|
272
|
+
},
|
|
273
|
+
]);
|
|
274
|
+
// Set provider-specific defaults
|
|
275
|
+
let baseUrl;
|
|
276
|
+
let model = "gpt-4o-mini";
|
|
277
|
+
if (provider === "openrouter") {
|
|
278
|
+
baseUrl = "https://openrouter.ai/api/v1";
|
|
279
|
+
}
|
|
280
|
+
else if (provider === "anthropic") {
|
|
281
|
+
baseUrl = "https://api.anthropic.com/v1";
|
|
282
|
+
model = "claude-3-5-sonnet-20241022";
|
|
283
|
+
}
|
|
284
|
+
// Test API key
|
|
285
|
+
console.log(chalk.gray("\nValidating API key..."));
|
|
286
|
+
try {
|
|
287
|
+
const OpenAI = (await import("openai")).default;
|
|
288
|
+
const testClient = new OpenAI({
|
|
289
|
+
apiKey: apiKey.trim(),
|
|
290
|
+
baseURL: baseUrl,
|
|
291
|
+
});
|
|
292
|
+
await testClient.chat.completions.create({
|
|
293
|
+
model,
|
|
294
|
+
messages: [{ role: "user", content: "test" }],
|
|
295
|
+
max_tokens: 1,
|
|
296
|
+
});
|
|
297
|
+
console.log(chalk.green("✓ API key validated"));
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
301
|
+
console.log(chalk.red("✗ API key validation failed: " + message));
|
|
302
|
+
console.log(chalk.yellow("Please check your API key and try again."));
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const newConfig = {
|
|
306
|
+
llm: {
|
|
307
|
+
provider,
|
|
308
|
+
apiKey: apiKey.trim(),
|
|
309
|
+
model,
|
|
310
|
+
baseUrl,
|
|
311
|
+
systemPrompt: config.llm?.systemPrompt || DEFAULT_SYSTEM_PROMPT,
|
|
312
|
+
},
|
|
313
|
+
cache: {
|
|
314
|
+
enabled: true,
|
|
315
|
+
ttlHours: 168,
|
|
316
|
+
},
|
|
317
|
+
logging: {
|
|
318
|
+
enabled: true,
|
|
319
|
+
level: "info",
|
|
320
|
+
},
|
|
321
|
+
customAllowPatterns: config.customAllowPatterns || [],
|
|
322
|
+
customDenyPatterns: config.customDenyPatterns || [],
|
|
323
|
+
customPassthroughPatterns: config.customPassthroughPatterns || [],
|
|
324
|
+
};
|
|
325
|
+
saveConfig(newConfig);
|
|
326
|
+
console.log(chalk.green("✓ Configuration saved!"));
|
|
327
|
+
console.log(chalk.gray(` Config file: ${getConfigPath()}`));
|
|
328
|
+
});
|
|
329
|
+
// Clear cache command
|
|
330
|
+
program
|
|
331
|
+
.command("clear-cache")
|
|
332
|
+
.description("Clear cached decisions (all by default, or selectively)")
|
|
333
|
+
.option("--deny-only", "Only clear entries with 'deny' decision")
|
|
334
|
+
.option("--allow-only", "Only clear entries with 'allow' decision")
|
|
335
|
+
.option("--key <hash>", "Clear a specific entry by its SHA256 key")
|
|
336
|
+
.option("--grep <substring>", "Clear entries matching a substring in toolName, reason, or input")
|
|
337
|
+
.action((options) => {
|
|
338
|
+
if (options.key) {
|
|
339
|
+
const found = clearCacheByKey(options.key);
|
|
340
|
+
if (found) {
|
|
341
|
+
console.log(chalk.green(`✓ Cleared cache entry with key ${options.key}`));
|
|
342
|
+
}
|
|
343
|
+
else {
|
|
344
|
+
console.log(chalk.yellow(`No cache entry found with key ${options.key}`));
|
|
345
|
+
}
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
if (options.grep) {
|
|
349
|
+
const count = clearCacheByGrep(options.grep);
|
|
350
|
+
console.log(chalk.green(`✓ Cleared ${count} cached decisions matching "${options.grep}"`));
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
if (options.denyOnly) {
|
|
354
|
+
const count = clearCacheByDecision("deny");
|
|
355
|
+
console.log(chalk.green(`✓ Cleared ${count} denied cached decisions`));
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
if (options.allowOnly) {
|
|
359
|
+
const count = clearCacheByDecision("allow");
|
|
360
|
+
console.log(chalk.green(`✓ Cleared ${count} allowed cached decisions`));
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
// Default: clear all
|
|
364
|
+
const count = clearCache();
|
|
365
|
+
console.log(chalk.green(`✓ Cleared ${count} cached decisions`));
|
|
366
|
+
});
|
|
367
|
+
// Cache list command
|
|
368
|
+
program
|
|
369
|
+
.command("cache")
|
|
370
|
+
.description("View cached decisions for the current project")
|
|
371
|
+
.option("--page <number>", "Page number", "1")
|
|
372
|
+
.option("--per-page <number>", "Entries per page", "20")
|
|
373
|
+
.option("--all", "Show all projects, not just the current one")
|
|
374
|
+
.action((options) => {
|
|
375
|
+
const page = Math.max(1, parseInt(options.page, 10) || 1);
|
|
376
|
+
const perPage = Math.max(1, parseInt(options.perPage, 10) || 20);
|
|
377
|
+
const projectRoot = options.all
|
|
378
|
+
? undefined
|
|
379
|
+
: resolveProjectRoot(process.cwd());
|
|
380
|
+
const entries = listCacheEntries(projectRoot);
|
|
381
|
+
if (entries.length === 0) {
|
|
382
|
+
if (options.all) {
|
|
383
|
+
console.log(chalk.yellow("No cached decisions found."));
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
console.log(chalk.yellow(`No cached decisions for project: ${projectRoot}`));
|
|
387
|
+
console.log(chalk.gray("Use --all to see entries for all projects."));
|
|
388
|
+
}
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
const totalPages = Math.ceil(entries.length / perPage);
|
|
392
|
+
const start = (page - 1) * perPage;
|
|
393
|
+
const pageEntries = entries.slice(start, start + perPage);
|
|
394
|
+
if (!options.all) {
|
|
395
|
+
console.log(chalk.bold(`Project: ${projectRoot}`));
|
|
396
|
+
}
|
|
397
|
+
console.log(chalk.bold(`Cache entries: ${entries.length} total (page ${page}/${totalPages})\n`));
|
|
398
|
+
for (const entry of pageEntries) {
|
|
399
|
+
const age = formatAge(Date.now() - entry.timestamp);
|
|
400
|
+
const decisionColor = entry.decision === "allow" ? chalk.green : chalk.red;
|
|
401
|
+
console.log(` ${decisionColor(entry.decision.toUpperCase().padEnd(5))} ${chalk.cyan(entry.toolName)} ${chalk.gray(age)}`);
|
|
402
|
+
console.log(` ${chalk.gray(entry.reason)}`);
|
|
403
|
+
if (entry.toolInput) {
|
|
404
|
+
const inputStr = summarizeInput(entry.toolInput);
|
|
405
|
+
if (inputStr) {
|
|
406
|
+
console.log(` ${chalk.dim(inputStr)}`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
if (options.all && entry.projectRoot) {
|
|
410
|
+
console.log(` ${chalk.dim("project: " + entry.projectRoot)}`);
|
|
411
|
+
}
|
|
412
|
+
console.log(` ${chalk.dim("key: " + entry.key)}`);
|
|
413
|
+
console.log();
|
|
414
|
+
}
|
|
415
|
+
if (totalPages > 1) {
|
|
416
|
+
console.log(chalk.gray(`Page ${page} of ${totalPages}. Use --page ${page + 1} to see more.`));
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
// Doctor command
|
|
420
|
+
program
|
|
421
|
+
.command("doctor")
|
|
422
|
+
.description("Diagnose configuration and connectivity")
|
|
423
|
+
.action(async () => {
|
|
424
|
+
console.log(chalk.blue("Running diagnostics...\n"));
|
|
425
|
+
// Check config
|
|
426
|
+
console.log(chalk.bold("Configuration:"));
|
|
427
|
+
const config = loadConfig();
|
|
428
|
+
console.log(` Provider: ${config.llm.provider}`);
|
|
429
|
+
console.log(` Model: ${config.llm.model}`);
|
|
430
|
+
console.log(` API Key: ${config.llm.apiKey ? "✓ Set in config" : "✗ Not in config"}`);
|
|
431
|
+
console.log(` Base URL: ${config.llm.baseUrl || "Default"}`);
|
|
432
|
+
console.log(` Cache: ${config.cache.enabled ? `Enabled (${config.cache.ttlHours}h TTL)` : "Disabled"}`);
|
|
433
|
+
// Check cache stats
|
|
434
|
+
console.log(chalk.bold("\nCache Stats:"));
|
|
435
|
+
const cacheStats = getCacheStats();
|
|
436
|
+
console.log(` Entries: ${cacheStats.entries}`);
|
|
437
|
+
if (cacheStats.oldestTimestamp) {
|
|
438
|
+
const age = Math.round((Date.now() - cacheStats.oldestTimestamp) / 1000 / 60 / 60);
|
|
439
|
+
console.log(` Oldest entry: ${age} hours ago`);
|
|
440
|
+
}
|
|
441
|
+
// Check settings installation across all locations
|
|
442
|
+
console.log(chalk.bold("\nInstallation:"));
|
|
443
|
+
const settingsLocations = [
|
|
444
|
+
{
|
|
445
|
+
label: "User settings",
|
|
446
|
+
path: join(homedir(), ".claude", "settings.json"),
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
label: "Project settings",
|
|
450
|
+
path: join(process.cwd(), ".claude", "settings.json"),
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
label: "Project local",
|
|
454
|
+
path: join(process.cwd(), ".claude", "settings.local.json"),
|
|
455
|
+
},
|
|
456
|
+
];
|
|
457
|
+
let anyInstalled = false;
|
|
458
|
+
for (const { label, path } of settingsLocations) {
|
|
459
|
+
if (existsSync(path)) {
|
|
460
|
+
try {
|
|
461
|
+
const settings = JSON.parse(readFileSync(path, "utf-8"));
|
|
462
|
+
const installed = settings.hooks?.PermissionRequest != null;
|
|
463
|
+
if (installed) {
|
|
464
|
+
console.log(` ${label}: ${chalk.green("✓ Hook configured")}`);
|
|
465
|
+
anyInstalled = true;
|
|
466
|
+
}
|
|
467
|
+
else {
|
|
468
|
+
console.log(` ${label}: ${chalk.yellow("File exists, hook not configured")}`);
|
|
469
|
+
}
|
|
470
|
+
console.log(chalk.gray(` ${path}`));
|
|
471
|
+
}
|
|
472
|
+
catch {
|
|
473
|
+
console.log(` ${label}: ${chalk.red("✗ File exists but could not be parsed")}`);
|
|
474
|
+
console.log(chalk.gray(` ${path}`));
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
else {
|
|
478
|
+
console.log(` ${label}: ${chalk.gray("- File not found")}`);
|
|
479
|
+
console.log(chalk.gray(` ${path}`));
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
if (!anyInstalled) {
|
|
483
|
+
console.log(chalk.yellow("\n ⚠ Hook not found in any settings file. Run 'cc-approve install' to set up."));
|
|
484
|
+
}
|
|
485
|
+
// Check API connectivity
|
|
486
|
+
console.log(chalk.bold("\nConnectivity:"));
|
|
487
|
+
const { getApiKey } = await import("./config.js");
|
|
488
|
+
const apiKey = getApiKey();
|
|
489
|
+
console.log(` API Key available: ${apiKey ? "✓ Yes" : "✗ No"}`);
|
|
490
|
+
console.log(chalk.bold("\nPaths:"));
|
|
491
|
+
console.log(` Config dir: ${getConfigDir()}`);
|
|
492
|
+
console.log(` Config file: ${getConfigPath()}`);
|
|
493
|
+
});
|
|
494
|
+
// Status command (show current config)
|
|
495
|
+
program
|
|
496
|
+
.command("status")
|
|
497
|
+
.description("Show current configuration status")
|
|
498
|
+
.action(() => {
|
|
499
|
+
const config = loadConfig();
|
|
500
|
+
console.log(chalk.blue("Claude Code Permission Hook Status\n"));
|
|
501
|
+
console.log(JSON.stringify(config, null, 2));
|
|
502
|
+
});
|
|
503
|
+
function formatAge(ms) {
|
|
504
|
+
const seconds = Math.floor(ms / 1000);
|
|
505
|
+
if (seconds < 60)
|
|
506
|
+
return `${seconds}s ago`;
|
|
507
|
+
const minutes = Math.floor(seconds / 60);
|
|
508
|
+
if (minutes < 60)
|
|
509
|
+
return `${minutes}m ago`;
|
|
510
|
+
const hours = Math.floor(minutes / 60);
|
|
511
|
+
if (hours < 24)
|
|
512
|
+
return `${hours}h ago`;
|
|
513
|
+
const days = Math.floor(hours / 24);
|
|
514
|
+
return `${days}d ago`;
|
|
515
|
+
}
|
|
516
|
+
function summarizeInput(toolInput) {
|
|
517
|
+
const command = toolInput.command;
|
|
518
|
+
if (typeof command === "string") {
|
|
519
|
+
const truncated = command.length > 100 ? command.slice(0, 100) + "..." : command;
|
|
520
|
+
return `$ ${truncated}`;
|
|
521
|
+
}
|
|
522
|
+
const filePath = toolInput.file_path || toolInput.filePath;
|
|
523
|
+
if (typeof filePath === "string") {
|
|
524
|
+
return filePath;
|
|
525
|
+
}
|
|
526
|
+
return "";
|
|
527
|
+
}
|
|
528
|
+
program.parse();
|
|
529
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-client.d.ts","sourceRoot":"","sources":["../src/llm-client.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAqB,MAAM,YAAY,CAAC;AAE5D,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,WAAW,CAAC,CA2EtB"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import OpenAI from "openai";
|
|
2
|
+
import { loadConfig, getApiKey } from "./config.js";
|
|
3
|
+
import { LLMResponseSchema } from "./types.js";
|
|
4
|
+
export async function queryLLM(toolName, toolInput, projectRoot) {
|
|
5
|
+
const config = loadConfig();
|
|
6
|
+
const apiKey = getApiKey();
|
|
7
|
+
if (!apiKey) {
|
|
8
|
+
// No API key, conservative deny
|
|
9
|
+
return {
|
|
10
|
+
decision: "deny",
|
|
11
|
+
reason: "No LLM API key configured - cannot make intelligent decision",
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const client = new OpenAI({
|
|
15
|
+
apiKey,
|
|
16
|
+
baseURL: config.llm.baseUrl,
|
|
17
|
+
});
|
|
18
|
+
// Use configurable system prompt from config
|
|
19
|
+
const systemPrompt = config.llm.systemPrompt;
|
|
20
|
+
const userPrompt = `Evaluate this tool request for auto-approval:
|
|
21
|
+
|
|
22
|
+
Tool: ${toolName}
|
|
23
|
+
Project Root: ${projectRoot || "unknown"}
|
|
24
|
+
Input: ${JSON.stringify(toolInput, null, 2)}
|
|
25
|
+
|
|
26
|
+
Should this be automatically approved or denied?`;
|
|
27
|
+
try {
|
|
28
|
+
// Models that support reasoning control via OpenRouter
|
|
29
|
+
const REASONING_MODELS = new Set([
|
|
30
|
+
"openai/gpt-5.2",
|
|
31
|
+
]);
|
|
32
|
+
const params = {
|
|
33
|
+
model: config.llm.model,
|
|
34
|
+
messages: [
|
|
35
|
+
{ role: "system", content: systemPrompt },
|
|
36
|
+
{ role: "user", content: userPrompt },
|
|
37
|
+
],
|
|
38
|
+
temperature: 0,
|
|
39
|
+
max_tokens: 200,
|
|
40
|
+
response_format: { type: "json_object" },
|
|
41
|
+
};
|
|
42
|
+
if (config.llm.provider === "openrouter" &&
|
|
43
|
+
REASONING_MODELS.has(config.llm.model)) {
|
|
44
|
+
params.reasoning = { effort: "none" };
|
|
45
|
+
}
|
|
46
|
+
const response = await client.chat.completions.create(params);
|
|
47
|
+
const content = response.choices[0]?.message?.content;
|
|
48
|
+
if (!content) {
|
|
49
|
+
return {
|
|
50
|
+
decision: "deny",
|
|
51
|
+
reason: "Empty LLM response",
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
// Parse and validate response
|
|
55
|
+
const parsed = JSON.parse(content);
|
|
56
|
+
return LLMResponseSchema.parse(parsed);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
// On any error, conservative deny
|
|
60
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
61
|
+
return {
|
|
62
|
+
decision: "deny",
|
|
63
|
+
reason: `LLM error: ${message}`,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=llm-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-client.js","sourceRoot":"","sources":["../src/llm-client.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAe,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE5D,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,QAAgB,EAChB,SAAkC,EAClC,WAAoB;IAEpB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAE3B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,gCAAgC;QAChC,OAAO;YACL,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,8DAA8D;SACvE,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;QACxB,MAAM;QACN,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,OAAO;KAC5B,CAAC,CAAC;IAEH,6CAA6C;IAC7C,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC;IAE7C,MAAM,UAAU,GAAG;;QAEb,QAAQ;gBACA,WAAW,IAAI,SAAS;SAC/B,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;;iDAEM,CAAC;IAEhD,IAAI,CAAC;QACH,uDAAuD;QACvD,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;YAC/B,gBAAgB;SACjB,CAAC,CAAC;QAEH,MAAM,MAAM,GAA4B;YACtC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK;YACvB,QAAQ,EAAE;gBACR,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE;gBACzC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE;aACtC;YACD,WAAW,EAAE,CAAC;YACd,UAAU,EAAE,GAAG;YACf,eAAe,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE;SACzC,CAAC;QAEF,IACE,MAAM,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;YACpC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EACtC,CAAC;YACD,MAAM,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QACxC,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CACnD,MAAkE,CACnE,CAAC;QAEF,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC;QACtD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,QAAQ,EAAE,MAAM;gBAChB,MAAM,EAAE,oBAAoB;aAC7B,CAAC;QACJ,CAAC;QAED,8BAA8B;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO,iBAAiB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,kCAAkC;QAClC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACzE,OAAO;YACL,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,cAAc,OAAO,EAAE;SAChC,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { LogEntry } from "./types.js";
|
|
2
|
+
export declare function logDecision(entry: Omit<LogEntry, "timestamp">): void;
|
|
3
|
+
export declare function getLogPath_(): string;
|
|
4
|
+
export declare function logExists(): boolean;
|
|
5
|
+
export declare function getLogStats(): {
|
|
6
|
+
entries: number;
|
|
7
|
+
sizeBytes: number;
|
|
8
|
+
} | null;
|
|
9
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAQtC,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,IAAI,CAepE;AAED,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED,wBAAgB,WAAW,IAAI;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAkB3E"}
|