claude-remote-guard 1.0.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.
Files changed (82) hide show
  1. package/README.md +433 -0
  2. package/dist/bin/cli.d.ts +3 -0
  3. package/dist/bin/cli.d.ts.map +1 -0
  4. package/dist/bin/cli.js +427 -0
  5. package/dist/bin/cli.js.map +1 -0
  6. package/dist/bin/hook.d.ts +3 -0
  7. package/dist/bin/hook.d.ts.map +1 -0
  8. package/dist/bin/hook.js +136 -0
  9. package/dist/bin/hook.js.map +1 -0
  10. package/dist/index.d.ts +6 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +6 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/lib/claude-settings.d.ts +11 -0
  15. package/dist/lib/claude-settings.d.ts.map +1 -0
  16. package/dist/lib/claude-settings.js +96 -0
  17. package/dist/lib/claude-settings.js.map +1 -0
  18. package/dist/lib/config.d.ts +47 -0
  19. package/dist/lib/config.d.ts.map +1 -0
  20. package/dist/lib/config.js +177 -0
  21. package/dist/lib/config.js.map +1 -0
  22. package/dist/lib/edge-function.d.ts +14 -0
  23. package/dist/lib/edge-function.d.ts.map +1 -0
  24. package/dist/lib/edge-function.js +521 -0
  25. package/dist/lib/edge-function.js.map +1 -0
  26. package/dist/lib/firebase.d.ts +27 -0
  27. package/dist/lib/firebase.d.ts.map +1 -0
  28. package/dist/lib/firebase.js +136 -0
  29. package/dist/lib/firebase.js.map +1 -0
  30. package/dist/lib/messenger/base.d.ts +6 -0
  31. package/dist/lib/messenger/base.d.ts.map +1 -0
  32. package/dist/lib/messenger/base.js +34 -0
  33. package/dist/lib/messenger/base.js.map +1 -0
  34. package/dist/lib/messenger/factory.d.ts +15 -0
  35. package/dist/lib/messenger/factory.d.ts.map +1 -0
  36. package/dist/lib/messenger/factory.js +37 -0
  37. package/dist/lib/messenger/factory.js.map +1 -0
  38. package/dist/lib/messenger/index.d.ts +7 -0
  39. package/dist/lib/messenger/index.d.ts.map +1 -0
  40. package/dist/lib/messenger/index.js +9 -0
  41. package/dist/lib/messenger/index.js.map +1 -0
  42. package/dist/lib/messenger/slack.d.ts +14 -0
  43. package/dist/lib/messenger/slack.d.ts.map +1 -0
  44. package/dist/lib/messenger/slack.js +169 -0
  45. package/dist/lib/messenger/slack.js.map +1 -0
  46. package/dist/lib/messenger/telegram.d.ts +15 -0
  47. package/dist/lib/messenger/telegram.d.ts.map +1 -0
  48. package/dist/lib/messenger/telegram.js +120 -0
  49. package/dist/lib/messenger/telegram.js.map +1 -0
  50. package/dist/lib/messenger/types.d.ts +21 -0
  51. package/dist/lib/messenger/types.d.ts.map +1 -0
  52. package/dist/lib/messenger/types.js +2 -0
  53. package/dist/lib/messenger/types.js.map +1 -0
  54. package/dist/lib/messenger/whatsapp.d.ts +16 -0
  55. package/dist/lib/messenger/whatsapp.d.ts.map +1 -0
  56. package/dist/lib/messenger/whatsapp.js +103 -0
  57. package/dist/lib/messenger/whatsapp.js.map +1 -0
  58. package/dist/lib/rules.d.ts +17 -0
  59. package/dist/lib/rules.d.ts.map +1 -0
  60. package/dist/lib/rules.js +138 -0
  61. package/dist/lib/rules.js.map +1 -0
  62. package/dist/lib/rules.test.d.ts +2 -0
  63. package/dist/lib/rules.test.d.ts.map +1 -0
  64. package/dist/lib/rules.test.js +144 -0
  65. package/dist/lib/rules.test.js.map +1 -0
  66. package/dist/lib/setup-instructions.d.ts +3 -0
  67. package/dist/lib/setup-instructions.d.ts.map +1 -0
  68. package/dist/lib/setup-instructions.js +55 -0
  69. package/dist/lib/setup-instructions.js.map +1 -0
  70. package/dist/lib/slack.d.ts +18 -0
  71. package/dist/lib/slack.d.ts.map +1 -0
  72. package/dist/lib/slack.js +21 -0
  73. package/dist/lib/slack.js.map +1 -0
  74. package/dist/lib/supabase.d.ts +33 -0
  75. package/dist/lib/supabase.d.ts.map +1 -0
  76. package/dist/lib/supabase.js +169 -0
  77. package/dist/lib/supabase.js.map +1 -0
  78. package/package.json +67 -0
  79. package/supabase/functions/slack-callback/index.ts +198 -0
  80. package/supabase/functions/telegram-callback/index.ts +209 -0
  81. package/supabase/functions/whatsapp-callback/index.ts +180 -0
  82. package/supabase/migrations/001_create_approval_requests.sql +91 -0
@@ -0,0 +1,427 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import chalk from 'chalk';
4
+ import inquirer from 'inquirer';
5
+ import { loadConfig, saveConfig, getConfigPath, configExists, deleteConfig, } from '../lib/config.js';
6
+ import { registerHook, unregisterHook, isHookRegistered } from '../lib/claude-settings.js';
7
+ import { sendTestNotification } from '../lib/slack.js';
8
+ import { testConnection as testSupabaseConnection, shutdownSupabase } from '../lib/supabase.js';
9
+ import { createEdgeFunctionFiles, getEdgeFunctionEnvVars, getEdgeFunctionName } from '../lib/edge-function.js';
10
+ import { printSupabaseSetupInstructions } from '../lib/setup-instructions.js';
11
+ const program = new Command();
12
+ program
13
+ .name('guard')
14
+ .description('Claude Guard - Remote approval system for Claude Code CLI')
15
+ .version('1.0.0');
16
+ program
17
+ .command('init')
18
+ .description('Initialize Claude Guard with interactive setup')
19
+ .action(async () => {
20
+ console.log(chalk.blue('\n🛡️ Claude Guard Setup\n'));
21
+ if (configExists()) {
22
+ const { overwrite } = await inquirer.prompt([
23
+ {
24
+ type: 'confirm',
25
+ name: 'overwrite',
26
+ message: 'Configuration already exists. Overwrite?',
27
+ default: false,
28
+ },
29
+ ]);
30
+ if (!overwrite) {
31
+ console.log(chalk.yellow('Setup cancelled.'));
32
+ return;
33
+ }
34
+ }
35
+ // Step 1: Select messenger type
36
+ const { messengerType } = await inquirer.prompt([
37
+ {
38
+ type: 'list',
39
+ name: 'messengerType',
40
+ message: 'Select notification messenger:',
41
+ choices: [
42
+ { name: 'Slack', value: 'slack' },
43
+ { name: 'Telegram', value: 'telegram' },
44
+ { name: 'WhatsApp (Twilio)', value: 'whatsapp' },
45
+ ],
46
+ default: 'slack',
47
+ },
48
+ ]);
49
+ // Step 2: Messenger-specific configuration
50
+ let messengerConfig;
51
+ if (messengerType === 'slack') {
52
+ const slackAnswers = await inquirer.prompt([
53
+ {
54
+ type: 'input',
55
+ name: 'webhookUrl',
56
+ message: 'Slack Webhook URL:',
57
+ validate: (input) => {
58
+ if (!input.startsWith('https://hooks.slack.com/')) {
59
+ return 'Please enter a valid Slack webhook URL';
60
+ }
61
+ return true;
62
+ },
63
+ },
64
+ {
65
+ type: 'input',
66
+ name: 'channelId',
67
+ message: 'Slack Channel ID (optional):',
68
+ default: '',
69
+ },
70
+ ]);
71
+ messengerConfig = {
72
+ type: 'slack',
73
+ slack: {
74
+ webhookUrl: slackAnswers.webhookUrl,
75
+ channelId: slackAnswers.channelId || undefined,
76
+ },
77
+ };
78
+ }
79
+ else if (messengerType === 'telegram') {
80
+ const telegramAnswers = await inquirer.prompt([
81
+ {
82
+ type: 'input',
83
+ name: 'botToken',
84
+ message: 'Telegram Bot Token:',
85
+ validate: (input) => {
86
+ if (!input || input.length < 10) {
87
+ return 'Please enter a valid Telegram Bot Token';
88
+ }
89
+ return true;
90
+ },
91
+ },
92
+ {
93
+ type: 'input',
94
+ name: 'chatId',
95
+ message: 'Telegram Chat ID:',
96
+ validate: (input) => {
97
+ if (!input || input.length === 0) {
98
+ return 'Please enter a valid Chat ID';
99
+ }
100
+ return true;
101
+ },
102
+ },
103
+ ]);
104
+ messengerConfig = {
105
+ type: 'telegram',
106
+ telegram: {
107
+ botToken: telegramAnswers.botToken,
108
+ chatId: telegramAnswers.chatId,
109
+ },
110
+ };
111
+ }
112
+ else {
113
+ // WhatsApp (Twilio)
114
+ const whatsappAnswers = await inquirer.prompt([
115
+ {
116
+ type: 'input',
117
+ name: 'accountSid',
118
+ message: 'Twilio Account SID:',
119
+ validate: (input) => {
120
+ if (!input || !input.startsWith('AC')) {
121
+ return 'Please enter a valid Twilio Account SID (starts with AC)';
122
+ }
123
+ return true;
124
+ },
125
+ },
126
+ {
127
+ type: 'input',
128
+ name: 'authToken',
129
+ message: 'Twilio Auth Token:',
130
+ validate: (input) => {
131
+ if (!input || input.length < 20) {
132
+ return 'Please enter a valid Twilio Auth Token';
133
+ }
134
+ return true;
135
+ },
136
+ },
137
+ {
138
+ type: 'input',
139
+ name: 'fromNumber',
140
+ message: 'WhatsApp From Number (e.g., whatsapp:+14155238886):',
141
+ validate: (input) => {
142
+ if (!input.startsWith('whatsapp:+')) {
143
+ return 'Please enter a valid WhatsApp number (format: whatsapp:+1234567890)';
144
+ }
145
+ return true;
146
+ },
147
+ },
148
+ {
149
+ type: 'input',
150
+ name: 'toNumber',
151
+ message: 'WhatsApp To Number (e.g., whatsapp:+1234567890):',
152
+ validate: (input) => {
153
+ if (!input.startsWith('whatsapp:+')) {
154
+ return 'Please enter a valid WhatsApp number (format: whatsapp:+1234567890)';
155
+ }
156
+ return true;
157
+ },
158
+ },
159
+ ]);
160
+ messengerConfig = {
161
+ type: 'whatsapp',
162
+ whatsapp: {
163
+ accountSid: whatsappAnswers.accountSid,
164
+ authToken: whatsappAnswers.authToken,
165
+ fromNumber: whatsappAnswers.fromNumber,
166
+ toNumber: whatsappAnswers.toNumber,
167
+ },
168
+ };
169
+ }
170
+ // Step 3: Common configuration (Supabase and Rules)
171
+ const answers = await inquirer.prompt([
172
+ {
173
+ type: 'input',
174
+ name: 'supabaseUrl',
175
+ message: 'Supabase Project URL (https://xxx.supabase.co):',
176
+ validate: (input) => {
177
+ if (!input.startsWith('https://') || !input.includes('.supabase.co')) {
178
+ return 'Please enter a valid Supabase URL (https://xxx.supabase.co)';
179
+ }
180
+ return true;
181
+ },
182
+ },
183
+ {
184
+ type: 'input',
185
+ name: 'supabaseAnonKey',
186
+ message: 'Supabase Anon Key:',
187
+ validate: (input) => {
188
+ if (!input || input.length < 20) {
189
+ return 'Please enter a valid Supabase Anon Key';
190
+ }
191
+ return true;
192
+ },
193
+ },
194
+ {
195
+ type: 'number',
196
+ name: 'timeoutSeconds',
197
+ message: 'Approval timeout (seconds):',
198
+ default: 300,
199
+ validate: (input) => {
200
+ if (input < 10 || input > 3600) {
201
+ return 'Timeout must be between 10 and 3600 seconds';
202
+ }
203
+ return true;
204
+ },
205
+ },
206
+ {
207
+ type: 'list',
208
+ name: 'defaultAction',
209
+ message: 'Default action on timeout:',
210
+ choices: [
211
+ { name: 'Deny (safer)', value: 'deny' },
212
+ { name: 'Allow', value: 'allow' },
213
+ ],
214
+ default: 'deny',
215
+ },
216
+ ]);
217
+ const config = {
218
+ messenger: messengerConfig,
219
+ supabase: {
220
+ url: answers.supabaseUrl,
221
+ anonKey: answers.supabaseAnonKey,
222
+ },
223
+ rules: {
224
+ timeoutSeconds: answers.timeoutSeconds,
225
+ defaultAction: answers.defaultAction,
226
+ },
227
+ };
228
+ saveConfig(config);
229
+ console.log(chalk.green(`\n✓ Configuration saved to ${getConfigPath()}`));
230
+ // Register hook
231
+ const hookResult = registerHook();
232
+ if (hookResult.success) {
233
+ console.log(chalk.green(`✓ ${hookResult.message}`));
234
+ }
235
+ else {
236
+ console.log(chalk.red(`✗ ${hookResult.message}`));
237
+ }
238
+ // Test connections
239
+ const { testNow } = await inquirer.prompt([
240
+ {
241
+ type: 'confirm',
242
+ name: 'testNow',
243
+ message: 'Test connections now?',
244
+ default: true,
245
+ },
246
+ ]);
247
+ if (testNow) {
248
+ await runTests(config);
249
+ }
250
+ // Edge Function setup prompt
251
+ const { setupEdgeFunction } = await inquirer.prompt([
252
+ {
253
+ type: 'confirm',
254
+ name: 'setupEdgeFunction',
255
+ message: 'Do you want to set up Supabase Edge Function?',
256
+ default: true,
257
+ },
258
+ ]);
259
+ if (setupEdgeFunction) {
260
+ const result = createEdgeFunctionFiles(process.cwd(), messengerType);
261
+ if (result.success) {
262
+ const funcName = getEdgeFunctionName(messengerType);
263
+ const envVars = getEdgeFunctionEnvVars(messengerType);
264
+ console.log(chalk.green(`\n✓ Edge Function files created at ./${result.path}/`));
265
+ console.log(chalk.blue('\nNext steps:'));
266
+ console.log(chalk.gray(' 1. supabase login'));
267
+ console.log(chalk.gray(' 2. supabase link --project-ref <your-project-ref>'));
268
+ console.log(chalk.gray(` 3. Set environment variable(s):`));
269
+ for (const envVar of envVars) {
270
+ console.log(chalk.cyan(` supabase secrets set ${envVar}=<your-${envVar.toLowerCase().replace(/_/g, '-')}>`));
271
+ }
272
+ console.log(chalk.gray(` 4. supabase functions deploy ${funcName}`));
273
+ console.log(chalk.gray(` 5. Set webhook URL to:`));
274
+ console.log(chalk.cyan(` https://<project-ref>.supabase.co/functions/v1/${funcName}`));
275
+ // Messenger-specific setup instructions
276
+ if (messengerType === 'slack') {
277
+ console.log(chalk.yellow('\n⚠️ Slack Setup:'));
278
+ console.log(chalk.gray(' Get your Signing Secret from:'));
279
+ console.log(chalk.gray(' Slack App Settings > Basic Information > App Credentials > Signing Secret'));
280
+ console.log(chalk.gray(' Set Interactivity URL in: Slack App Settings > Interactivity & Shortcuts'));
281
+ }
282
+ else if (messengerType === 'telegram') {
283
+ console.log(chalk.yellow('\n⚠️ Telegram Setup:'));
284
+ console.log(chalk.gray(' 1. Generate a random secret (e.g., openssl rand -hex 32)'));
285
+ console.log(chalk.gray(' 2. Set webhook with secret_token:'));
286
+ console.log(chalk.cyan(' curl -X POST "https://api.telegram.org/bot<BOT_TOKEN>/setWebhook" \\'));
287
+ console.log(chalk.cyan(' -d "url=https://<project-ref>.supabase.co/functions/v1/telegram-callback" \\'));
288
+ console.log(chalk.cyan(' -d "secret_token=<YOUR_WEBHOOK_SECRET>"'));
289
+ }
290
+ else if (messengerType === 'whatsapp') {
291
+ console.log(chalk.yellow('\n⚠️ WhatsApp (Twilio) Setup:'));
292
+ console.log(chalk.gray(' Set webhook URL in: Twilio Console > Messaging > Settings > WhatsApp Sandbox'));
293
+ console.log(chalk.gray(' When a message comes in: https://<project-ref>.supabase.co/functions/v1/whatsapp-callback'));
294
+ }
295
+ }
296
+ else {
297
+ console.log(chalk.red(`\n✗ Failed to create Edge Function files: ${result.error}`));
298
+ }
299
+ }
300
+ // Always show SQL setup instructions
301
+ printSupabaseSetupInstructions();
302
+ console.log(chalk.green('\n🎉 Setup complete! Claude Guard is now active.\n'));
303
+ });
304
+ program
305
+ .command('status')
306
+ .description('Check Claude Guard status and connections')
307
+ .action(async () => {
308
+ console.log(chalk.blue('\n🛡️ Claude Guard Status\n'));
309
+ // Check config
310
+ const config = loadConfig();
311
+ if (!config) {
312
+ console.log(chalk.red('✗ Configuration not found or invalid'));
313
+ console.log(chalk.gray(` Run ${chalk.cyan('guard init')} to set up`));
314
+ return;
315
+ }
316
+ console.log(chalk.green('✓ Configuration loaded'));
317
+ // Check hook registration
318
+ if (isHookRegistered()) {
319
+ console.log(chalk.green('✓ Hook registered in Claude settings'));
320
+ }
321
+ else {
322
+ console.log(chalk.yellow('⚠ Hook not registered'));
323
+ console.log(chalk.gray(` Run ${chalk.cyan('guard init')} to register`));
324
+ }
325
+ // Test Supabase
326
+ console.log(chalk.gray(' Testing Supabase connection...'));
327
+ const sbResult = await testSupabaseConnection(config);
328
+ if (sbResult.ok) {
329
+ console.log(chalk.green('✓ Supabase connection OK'));
330
+ }
331
+ else {
332
+ console.log(chalk.red(`✗ Supabase connection failed: ${sbResult.error}`));
333
+ }
334
+ await shutdownSupabase();
335
+ console.log('');
336
+ });
337
+ program
338
+ .command('test')
339
+ .description('Send a test notification')
340
+ .action(async () => {
341
+ const config = loadConfig();
342
+ if (!config) {
343
+ console.log(chalk.red('Configuration not found. Run guard init first.'));
344
+ return;
345
+ }
346
+ const messengerType = config.messenger.type;
347
+ console.log(chalk.blue(`Sending test notification via ${messengerType}...`));
348
+ if (messengerType === 'slack' && config.messenger.slack) {
349
+ const result = await sendTestNotification(config.messenger.slack.webhookUrl);
350
+ if (result.ok) {
351
+ console.log(chalk.green('✓ Test notification sent successfully!'));
352
+ }
353
+ else {
354
+ console.log(chalk.red(`✗ Failed to send notification: ${result.error}`));
355
+ }
356
+ }
357
+ else if (messengerType === 'telegram') {
358
+ // TODO: Implement Telegram test notification
359
+ console.log(chalk.yellow('⚠ Telegram test notification not yet implemented'));
360
+ }
361
+ else if (messengerType === 'whatsapp') {
362
+ // TODO: Implement WhatsApp test notification
363
+ console.log(chalk.yellow('⚠ WhatsApp test notification not yet implemented'));
364
+ }
365
+ else {
366
+ console.log(chalk.red('✗ Unknown messenger type or missing configuration'));
367
+ }
368
+ });
369
+ program
370
+ .command('uninstall')
371
+ .description('Remove Claude Guard configuration and hooks')
372
+ .action(async () => {
373
+ const { confirm } = await inquirer.prompt([
374
+ {
375
+ type: 'confirm',
376
+ name: 'confirm',
377
+ message: 'Are you sure you want to uninstall Claude Guard?',
378
+ default: false,
379
+ },
380
+ ]);
381
+ if (!confirm) {
382
+ console.log(chalk.yellow('Uninstall cancelled.'));
383
+ return;
384
+ }
385
+ // Unregister hook
386
+ const hookResult = unregisterHook();
387
+ console.log(hookResult.success ? chalk.green(`✓ ${hookResult.message}`) : chalk.red(`✗ ${hookResult.message}`));
388
+ // Delete config
389
+ deleteConfig();
390
+ console.log(chalk.green('✓ Configuration deleted'));
391
+ console.log(chalk.blue('\nClaude Guard has been uninstalled.\n'));
392
+ });
393
+ async function runTests(config) {
394
+ console.log(chalk.blue('\nTesting connections...\n'));
395
+ // Test messenger based on type
396
+ const messengerType = config.messenger.type;
397
+ console.log(chalk.gray(`Testing ${messengerType} connection...`));
398
+ if (messengerType === 'slack' && config.messenger.slack) {
399
+ const slackResult = await sendTestNotification(config.messenger.slack.webhookUrl);
400
+ if (slackResult.ok) {
401
+ console.log(chalk.green('✓ Slack webhook OK'));
402
+ }
403
+ else {
404
+ console.log(chalk.red(`✗ Slack webhook failed: ${slackResult.error}`));
405
+ }
406
+ }
407
+ else if (messengerType === 'telegram') {
408
+ // TODO: Implement Telegram test
409
+ console.log(chalk.yellow('⚠ Telegram connection test not yet implemented'));
410
+ }
411
+ else if (messengerType === 'whatsapp') {
412
+ // TODO: Implement WhatsApp test
413
+ console.log(chalk.yellow('⚠ WhatsApp connection test not yet implemented'));
414
+ }
415
+ // Test Supabase
416
+ console.log(chalk.gray('Testing Supabase connection...'));
417
+ const sbResult = await testSupabaseConnection(config);
418
+ if (sbResult.ok) {
419
+ console.log(chalk.green('✓ Supabase connection OK'));
420
+ }
421
+ else {
422
+ console.log(chalk.red(`✗ Supabase connection failed: ${sbResult.error}`));
423
+ }
424
+ await shutdownSupabase();
425
+ }
426
+ program.parse();
427
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/bin/hook.ts"],"names":[],"mappings":""}
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env node
2
+ import { v4 as uuidv4 } from 'uuid';
3
+ import { loadConfig } from '../lib/config.js';
4
+ import { analyzeCommand } from '../lib/rules.js';
5
+ import { MessengerFactory } from '../lib/messenger/factory.js';
6
+ import { initializeSupabase, createRequest, listenForApproval, shutdownSupabase, } from '../lib/supabase.js';
7
+ async function readStdin() {
8
+ return new Promise((resolve) => {
9
+ let data = '';
10
+ process.stdin.setEncoding('utf8');
11
+ process.stdin.on('data', (chunk) => {
12
+ data += chunk;
13
+ });
14
+ process.stdin.on('end', () => {
15
+ resolve(data);
16
+ });
17
+ });
18
+ }
19
+ function output(result) {
20
+ console.log(JSON.stringify(result));
21
+ }
22
+ async function main() {
23
+ try {
24
+ // Read input from stdin
25
+ const input = await readStdin();
26
+ if (!input.trim()) {
27
+ // Empty input is suspicious - deny for safety
28
+ output({ decision: 'deny', reason: 'Empty input received' });
29
+ return;
30
+ }
31
+ let hookInput;
32
+ try {
33
+ hookInput = JSON.parse(input);
34
+ }
35
+ catch {
36
+ // Invalid JSON could be an attack - deny for safety
37
+ output({ decision: 'deny', reason: 'Invalid JSON input' });
38
+ return;
39
+ }
40
+ // Only process Bash commands
41
+ if (hookInput.tool_name !== 'Bash') {
42
+ output({ decision: 'allow' });
43
+ return;
44
+ }
45
+ const command = hookInput.tool_input.command;
46
+ if (!command || typeof command !== 'string') {
47
+ output({ decision: 'allow' });
48
+ return;
49
+ }
50
+ // Load config
51
+ const config = loadConfig();
52
+ if (!config) {
53
+ // No config, allow all commands
54
+ output({ decision: 'allow' });
55
+ return;
56
+ }
57
+ // Analyze command for danger
58
+ const analysis = analyzeCommand(command, config.rules.customPatterns?.map((p) => ({
59
+ pattern: new RegExp(p.pattern, 'i'),
60
+ severity: p.severity,
61
+ reason: p.reason,
62
+ })), config.rules.whitelist);
63
+ if (!analysis.isDangerous) {
64
+ output({ decision: 'allow' });
65
+ return;
66
+ }
67
+ // Command is dangerous - request approval
68
+ const requestId = uuidv4();
69
+ const cwd = process.cwd();
70
+ try {
71
+ // Initialize Supabase
72
+ initializeSupabase(config);
73
+ // Create request in Supabase
74
+ await createRequest(requestId, {
75
+ command,
76
+ dangerReason: analysis.reason,
77
+ severity: analysis.severity,
78
+ cwd,
79
+ });
80
+ // Send notification via configured messenger
81
+ const messenger = MessengerFactory.create(config.messenger);
82
+ const messengerLabel = MessengerFactory.getMessengerTypeLabel(config.messenger.type);
83
+ const notificationResult = await messenger.sendNotification({
84
+ requestId,
85
+ command,
86
+ reason: analysis.reason,
87
+ severity: analysis.severity,
88
+ cwd,
89
+ timestamp: Date.now(),
90
+ });
91
+ if (!notificationResult.ok) {
92
+ // Failed to send notification, use default action
93
+ const decision = config.rules.defaultAction === 'allow' ? 'allow' : 'deny';
94
+ output({
95
+ decision,
96
+ reason: `Failed to send notification: ${notificationResult.error}`,
97
+ });
98
+ await shutdownSupabase();
99
+ return;
100
+ }
101
+ // Wait for approval
102
+ const timeoutMs = config.rules.timeoutSeconds * 1000;
103
+ const status = await new Promise((resolve) => {
104
+ listenForApproval(requestId, timeoutMs, (status) => {
105
+ resolve(status);
106
+ });
107
+ });
108
+ await shutdownSupabase();
109
+ if (status === 'approved') {
110
+ output({ decision: 'allow', reason: `Approved via ${messengerLabel}` });
111
+ }
112
+ else if (status === 'rejected') {
113
+ output({ decision: 'deny', reason: `Rejected via ${messengerLabel}` });
114
+ }
115
+ else {
116
+ // Timeout - use default action
117
+ const decision = config.rules.defaultAction === 'allow' ? 'allow' : 'deny';
118
+ output({ decision, reason: 'Approval timed out' });
119
+ }
120
+ }
121
+ catch (error) {
122
+ await shutdownSupabase().catch(() => { });
123
+ // On error, use default action
124
+ const decision = config.rules.defaultAction === 'allow' ? 'allow' : 'deny';
125
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
126
+ output({ decision, reason: `Error: ${errorMessage}` });
127
+ }
128
+ }
129
+ catch (error) {
130
+ // Critical error, deny for safety
131
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
132
+ output({ decision: 'deny', reason: `Critical error: ${errorMessage}` });
133
+ }
134
+ }
135
+ main();
136
+ //# sourceMappingURL=hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook.js","sourceRoot":"","sources":["../../src/bin/hook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { loadConfig, saveConfig, getConfigPath, type Config } from './lib/config.js';
2
+ export { analyzeCommand, type RuleResult, type Severity } from './lib/rules.js';
3
+ export { sendSlackNotification, type SlackMessage } from './lib/slack.js';
4
+ export { initializeSupabase, createRequest, listenForApproval, type ApprovalRequest, type ApprovalStatus, } from './lib/supabase.js';
5
+ export { registerHook, unregisterHook } from './lib/claude-settings.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,cAAc,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,qBAAqB,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,KAAK,eAAe,EACpB,KAAK,cAAc,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export { loadConfig, saveConfig, getConfigPath } from './lib/config.js';
2
+ export { analyzeCommand } from './lib/rules.js';
3
+ export { sendSlackNotification } from './lib/slack.js';
4
+ export { initializeSupabase, createRequest, listenForApproval, } from './lib/supabase.js';
5
+ export { registerHook, unregisterHook } from './lib/claude-settings.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAe,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,cAAc,EAAkC,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,qBAAqB,EAAqB,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,iBAAiB,GAGlB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,11 @@
1
+ export declare function isHookRegistered(): boolean;
2
+ export declare function registerHook(): {
3
+ success: boolean;
4
+ message: string;
5
+ };
6
+ export declare function unregisterHook(): {
7
+ success: boolean;
8
+ message: string;
9
+ };
10
+ export declare function getClaudeSettingsPath(): string;
11
+ //# sourceMappingURL=claude-settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-settings.d.ts","sourceRoot":"","sources":["../../src/lib/claude-settings.ts"],"names":[],"mappings":"AA0DA,wBAAgB,gBAAgB,IAAI,OAAO,CAQ1C;AAED,wBAAgB,YAAY,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CA0BpE;AAED,wBAAgB,cAAc,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CA8BtE;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C"}