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 @@
1
+ {"version":3,"file":"firebase.js","sourceRoot":"","sources":["../../src/lib/firebase.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type Severity } from '../rules.js';
2
+ export declare function maskSensitiveInfo(text: string): string;
3
+ export declare function truncateCommand(command: string, maxLength?: number): string;
4
+ export declare function getSeverityEmoji(severity: Severity): string;
5
+ export declare function getSeverityColor(severity: Severity): string;
6
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/lib/messenger/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8D,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAgBxG,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,GAAE,MAAY,GAAG,MAAM,CAKhF;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAE3D;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAE3D"}
@@ -0,0 +1,34 @@
1
+ import { getSeverityEmoji as getEmoji, getSeverityColor as getColor } from '../rules.js';
2
+ // Patterns that may contain sensitive information
3
+ const SENSITIVE_PATTERNS = [
4
+ // API keys, tokens, secrets in various formats
5
+ { pattern: /([?&])(api[_-]?key|token|secret|password|auth|key|access[_-]?token)=([^&\s'"]+)/gi, replacement: '$1$2=[REDACTED]' },
6
+ // Authorization headers
7
+ { pattern: /(Authorization:\s*)(Bearer\s+)?[^\s'"]+/gi, replacement: '$1$2[REDACTED]' },
8
+ // Environment variable assignments with sensitive names
9
+ { pattern: /(export\s+)?(AWS_SECRET_ACCESS_KEY|AWS_ACCESS_KEY_ID|API_KEY|SECRET_KEY|PRIVATE_KEY|DATABASE_URL|DB_PASSWORD|SLACK_TOKEN|GITHUB_TOKEN|NPM_TOKEN)=([^\s'"]+)/gi, replacement: '$1$2=[REDACTED]' },
10
+ // Connection strings with passwords
11
+ { pattern: /:\/\/([^:]+):([^@]+)@/g, replacement: '://$1:[REDACTED]@' },
12
+ // Base64 encoded credentials (likely in headers)
13
+ { pattern: /(Basic\s+)[A-Za-z0-9+/=]{20,}/gi, replacement: '$1[REDACTED]' },
14
+ ];
15
+ export function maskSensitiveInfo(text) {
16
+ let masked = text;
17
+ for (const { pattern, replacement } of SENSITIVE_PATTERNS) {
18
+ masked = masked.replace(pattern, replacement);
19
+ }
20
+ return masked;
21
+ }
22
+ export function truncateCommand(command, maxLength = 500) {
23
+ if (command.length <= maxLength) {
24
+ return command;
25
+ }
26
+ return command.substring(0, maxLength - 3) + '...';
27
+ }
28
+ export function getSeverityEmoji(severity) {
29
+ return getEmoji(severity);
30
+ }
31
+ export function getSeverityColor(severity) {
32
+ return getColor(severity);
33
+ }
34
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/lib/messenger/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,IAAI,QAAQ,EAAE,gBAAgB,IAAI,QAAQ,EAAiB,MAAM,aAAa,CAAC;AAExG,kDAAkD;AAClD,MAAM,kBAAkB,GAAoD;IAC1E,+CAA+C;IAC/C,EAAE,OAAO,EAAE,mFAAmF,EAAE,WAAW,EAAE,iBAAiB,EAAE;IAChI,wBAAwB;IACxB,EAAE,OAAO,EAAE,2CAA2C,EAAE,WAAW,EAAE,gBAAgB,EAAE;IACvF,wDAAwD;IACxD,EAAE,OAAO,EAAE,+JAA+J,EAAE,WAAW,EAAE,iBAAiB,EAAE;IAC5M,oCAAoC;IACpC,EAAE,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,mBAAmB,EAAE;IACvE,iDAAiD;IACjD,EAAE,OAAO,EAAE,iCAAiC,EAAE,WAAW,EAAE,cAAc,EAAE;CAC5E,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,KAAK,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,kBAAkB,EAAE,CAAC;QAC1D,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,YAAoB,GAAG;IACtE,IAAI,OAAO,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;QAChC,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAkB;IACjD,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAkB;IACjD,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { Messenger, MessengerType } from './types.js';
2
+ import { type SlackConfig } from './slack.js';
3
+ import { type TelegramConfig } from './telegram.js';
4
+ import { type WhatsAppConfig } from './whatsapp.js';
5
+ export interface MessengerConfig {
6
+ type: MessengerType;
7
+ slack?: SlackConfig;
8
+ telegram?: TelegramConfig;
9
+ whatsapp?: WhatsAppConfig;
10
+ }
11
+ export declare class MessengerFactory {
12
+ static create(config: MessengerConfig): Messenger;
13
+ static getMessengerTypeLabel(type: MessengerType): string;
14
+ }
15
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/lib/messenger/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAEvE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,qBAAa,gBAAgB;IAC3B,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS;IAyBjD,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM;CAU1D"}
@@ -0,0 +1,37 @@
1
+ import { SlackMessenger } from './slack.js';
2
+ import { TelegramMessenger } from './telegram.js';
3
+ import { WhatsAppMessenger } from './whatsapp.js';
4
+ export class MessengerFactory {
5
+ static create(config) {
6
+ switch (config.type) {
7
+ case 'slack':
8
+ if (!config.slack) {
9
+ throw new Error('Slack configuration is required when type is "slack"');
10
+ }
11
+ return new SlackMessenger(config.slack);
12
+ case 'telegram':
13
+ if (!config.telegram) {
14
+ throw new Error('Telegram configuration is required when type is "telegram"');
15
+ }
16
+ return new TelegramMessenger(config.telegram);
17
+ case 'whatsapp':
18
+ if (!config.whatsapp) {
19
+ throw new Error('WhatsApp configuration is required when type is "whatsapp"');
20
+ }
21
+ return new WhatsAppMessenger(config.whatsapp);
22
+ default:
23
+ throw new Error(`Unknown messenger type: ${config.type}`);
24
+ }
25
+ }
26
+ static getMessengerTypeLabel(type) {
27
+ switch (type) {
28
+ case 'slack':
29
+ return 'Slack';
30
+ case 'telegram':
31
+ return 'Telegram';
32
+ case 'whatsapp':
33
+ return 'WhatsApp (Twilio)';
34
+ }
35
+ }
36
+ }
37
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/lib/messenger/factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAoB,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAuB,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAuB,MAAM,eAAe,CAAC;AASvE,MAAM,OAAO,gBAAgB;IAC3B,MAAM,CAAC,MAAM,CAAC,MAAuB;QACnC,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;YACpB,KAAK,OAAO;gBACV,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;oBAClB,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;gBAC1E,CAAC;gBACD,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAE1C,KAAK,UAAU;gBACb,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;oBACrB,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;gBAChF,CAAC;gBACD,OAAO,IAAI,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAEhD,KAAK,UAAU;gBACb,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;oBACrB,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;gBAChF,CAAC;gBACD,OAAO,IAAI,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAEhD;gBACE,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,MAAM,CAAC,qBAAqB,CAAC,IAAmB;QAC9C,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,OAAO;gBACV,OAAO,OAAO,CAAC;YACjB,KAAK,UAAU;gBACb,OAAO,UAAU,CAAC;YACpB,KAAK,UAAU;gBACb,OAAO,mBAAmB,CAAC;QAC/B,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ export type { Messenger, MessengerMessage, MessengerResult, MessengerType } from './types.js';
2
+ export { maskSensitiveInfo, truncateCommand, getSeverityEmoji, getSeverityColor } from './base.js';
3
+ export { SlackMessenger, type SlackConfig } from './slack.js';
4
+ export { TelegramMessenger, type TelegramConfig } from './telegram.js';
5
+ export { WhatsAppMessenger, type WhatsAppConfig } from './whatsapp.js';
6
+ export { MessengerFactory, type MessengerConfig } from './factory.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/messenger/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG9F,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAGnG,OAAO,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAGvE,OAAO,EAAE,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,9 @@
1
+ // Base utilities
2
+ export { maskSensitiveInfo, truncateCommand, getSeverityEmoji, getSeverityColor } from './base.js';
3
+ // Messenger implementations
4
+ export { SlackMessenger } from './slack.js';
5
+ export { TelegramMessenger } from './telegram.js';
6
+ export { WhatsAppMessenger } from './whatsapp.js';
7
+ // Factory
8
+ export { MessengerFactory } from './factory.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/messenger/index.ts"],"names":[],"mappings":"AAGA,iBAAiB;AACjB,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAEnG,4BAA4B;AAC5B,OAAO,EAAE,cAAc,EAAoB,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAuB,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAuB,MAAM,eAAe,CAAC;AAEvE,UAAU;AACV,OAAO,EAAE,gBAAgB,EAAwB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { Messenger, MessengerMessage, MessengerResult } from './types.js';
2
+ export interface SlackConfig {
3
+ webhookUrl: string;
4
+ channelId?: string;
5
+ }
6
+ export declare class SlackMessenger implements Messenger {
7
+ readonly type: "slack";
8
+ private config;
9
+ constructor(config: SlackConfig);
10
+ validateConfig(): boolean;
11
+ sendNotification(message: MessengerMessage): Promise<MessengerResult>;
12
+ sendTestNotification(): Promise<MessengerResult>;
13
+ }
14
+ //# sourceMappingURL=slack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../../src/lib/messenger/slack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAG/E,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAoID,qBAAa,cAAe,YAAW,SAAS;IAC9C,QAAQ,CAAC,IAAI,EAAG,OAAO,CAAU;IACjC,OAAO,CAAC,MAAM,CAAc;gBAEhB,MAAM,EAAE,WAAW;IAI/B,cAAc,IAAI,OAAO;IAOnB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAwBrE,oBAAoB,IAAI,OAAO,CAAC,eAAe,CAAC;CAkDvD"}
@@ -0,0 +1,169 @@
1
+ import { maskSensitiveInfo, truncateCommand, getSeverityEmoji, getSeverityColor } from './base.js';
2
+ function escapeSlackText(text) {
3
+ return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
4
+ }
5
+ function buildSlackBlocks(message) {
6
+ const emoji = getSeverityEmoji(message.severity);
7
+ const color = getSeverityColor(message.severity);
8
+ // Mask sensitive information before displaying
9
+ const maskedCommand = maskSensitiveInfo(message.command);
10
+ const escapedCommand = escapeSlackText(truncateCommand(maskedCommand));
11
+ const escapedCwd = escapeSlackText(message.cwd);
12
+ const escapedReason = escapeSlackText(message.reason);
13
+ return {
14
+ blocks: [
15
+ {
16
+ type: 'header',
17
+ text: {
18
+ type: 'plain_text',
19
+ text: `${emoji} Claude Guard: Approval Required`,
20
+ emoji: true,
21
+ },
22
+ },
23
+ {
24
+ type: 'section',
25
+ text: {
26
+ type: 'mrkdwn',
27
+ text: `*Reason:* ${escapedReason}\n*Severity:* ${message.severity.toUpperCase()}`,
28
+ },
29
+ },
30
+ {
31
+ type: 'section',
32
+ text: {
33
+ type: 'mrkdwn',
34
+ text: `*Command:*\n\`\`\`${escapedCommand}\`\`\``,
35
+ },
36
+ },
37
+ {
38
+ type: 'section',
39
+ text: {
40
+ type: 'mrkdwn',
41
+ text: `*Working Directory:*\n\`${escapedCwd}\``,
42
+ },
43
+ },
44
+ {
45
+ type: 'actions',
46
+ elements: [
47
+ {
48
+ type: 'button',
49
+ text: {
50
+ type: 'plain_text',
51
+ text: 'Approve',
52
+ emoji: true,
53
+ },
54
+ style: 'primary',
55
+ action_id: 'approve_command',
56
+ value: message.requestId,
57
+ },
58
+ {
59
+ type: 'button',
60
+ text: {
61
+ type: 'plain_text',
62
+ text: 'Reject',
63
+ emoji: true,
64
+ },
65
+ style: 'danger',
66
+ action_id: 'reject_command',
67
+ value: message.requestId,
68
+ },
69
+ ],
70
+ },
71
+ {
72
+ type: 'context',
73
+ elements: [
74
+ {
75
+ type: 'mrkdwn',
76
+ text: `Request ID: \`${message.requestId}\` | Time: <!date^${Math.floor(message.timestamp / 1000)}^{date_short_pretty} {time}|${new Date(message.timestamp).toISOString()}>`,
77
+ },
78
+ ],
79
+ },
80
+ ],
81
+ attachments: [
82
+ {
83
+ color: color,
84
+ blocks: [],
85
+ },
86
+ ],
87
+ };
88
+ }
89
+ export class SlackMessenger {
90
+ type = 'slack';
91
+ config;
92
+ constructor(config) {
93
+ this.config = config;
94
+ }
95
+ validateConfig() {
96
+ return (typeof this.config.webhookUrl === 'string' &&
97
+ this.config.webhookUrl.startsWith('https://hooks.slack.com/'));
98
+ }
99
+ async sendNotification(message) {
100
+ try {
101
+ const payload = buildSlackBlocks(message);
102
+ const response = await fetch(this.config.webhookUrl, {
103
+ method: 'POST',
104
+ headers: {
105
+ 'Content-Type': 'application/json',
106
+ },
107
+ body: JSON.stringify(payload),
108
+ });
109
+ if (!response.ok) {
110
+ const text = await response.text();
111
+ return { ok: false, error: `Slack API error: ${response.status} ${text}` };
112
+ }
113
+ return { ok: true };
114
+ }
115
+ catch (error) {
116
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
117
+ return { ok: false, error: errorMessage };
118
+ }
119
+ }
120
+ async sendTestNotification() {
121
+ try {
122
+ const payload = {
123
+ blocks: [
124
+ {
125
+ type: 'header',
126
+ text: {
127
+ type: 'plain_text',
128
+ text: '✅ Claude Guard Test Notification',
129
+ emoji: true,
130
+ },
131
+ },
132
+ {
133
+ type: 'section',
134
+ text: {
135
+ type: 'mrkdwn',
136
+ text: 'This is a test notification from Claude Guard.\nIf you see this message, your Slack integration is working correctly!',
137
+ },
138
+ },
139
+ {
140
+ type: 'context',
141
+ elements: [
142
+ {
143
+ type: 'mrkdwn',
144
+ text: `Sent at: <!date^${Math.floor(Date.now() / 1000)}^{date_short_pretty} {time}|${new Date().toISOString()}>`,
145
+ },
146
+ ],
147
+ },
148
+ ],
149
+ };
150
+ const response = await fetch(this.config.webhookUrl, {
151
+ method: 'POST',
152
+ headers: {
153
+ 'Content-Type': 'application/json',
154
+ },
155
+ body: JSON.stringify(payload),
156
+ });
157
+ if (!response.ok) {
158
+ const text = await response.text();
159
+ return { ok: false, error: `Slack API error: ${response.status} ${text}` };
160
+ }
161
+ return { ok: true };
162
+ }
163
+ catch (error) {
164
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
165
+ return { ok: false, error: errorMessage };
166
+ }
167
+ }
168
+ }
169
+ //# sourceMappingURL=slack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.js","sourceRoot":"","sources":["../../../src/lib/messenger/slack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { Messenger, MessengerMessage, MessengerResult } from './types.js';
2
+ export interface TelegramConfig {
3
+ botToken: string;
4
+ chatId: string;
5
+ }
6
+ export declare class TelegramMessenger implements Messenger {
7
+ readonly type: "telegram";
8
+ private config;
9
+ private baseUrl;
10
+ constructor(config: TelegramConfig);
11
+ validateConfig(): boolean;
12
+ sendNotification(message: MessengerMessage): Promise<MessengerResult>;
13
+ sendTestNotification(): Promise<MessengerResult>;
14
+ }
15
+ //# sourceMappingURL=telegram.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram.d.ts","sourceRoot":"","sources":["../../../src/lib/messenger/telegram.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAG/E,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAmDD,qBAAa,iBAAkB,YAAW,SAAS;IACjD,QAAQ,CAAC,IAAI,EAAG,UAAU,CAAU;IACpC,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,cAAc;IAKlC,cAAc,IAAI,OAAO;IASnB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IA+BrE,oBAAoB,IAAI,OAAO,CAAC,eAAe,CAAC;CAmCvD"}
@@ -0,0 +1,120 @@
1
+ import { maskSensitiveInfo, truncateCommand, getSeverityEmoji } from './base.js';
2
+ // Telegram MarkdownV2에서 이스케이프가 필요한 문자
3
+ function escapeTelegramMarkdownV2(text) {
4
+ // eslint-disable-next-line no-useless-escape
5
+ return text.replace(/[_*\[\]()~`>#+\-=|{}.!\\]/g, '\\$&');
6
+ }
7
+ function buildTelegramMessage(message) {
8
+ const emoji = getSeverityEmoji(message.severity);
9
+ const maskedCommand = maskSensitiveInfo(message.command);
10
+ const truncatedCommand = truncateCommand(maskedCommand, 300);
11
+ // MarkdownV2 형식으로 메시지 구성
12
+ const lines = [
13
+ `${emoji} *Claude Guard: Approval Required*`,
14
+ '',
15
+ `*Reason:* ${escapeTelegramMarkdownV2(message.reason)}`,
16
+ `*Severity:* ${message.severity.toUpperCase()}`,
17
+ '',
18
+ `*Command:*`,
19
+ '```',
20
+ escapeTelegramMarkdownV2(truncatedCommand),
21
+ '```',
22
+ '',
23
+ `*Working Directory:*`,
24
+ `\`${escapeTelegramMarkdownV2(message.cwd)}\``,
25
+ '',
26
+ `_Request ID: ${escapeTelegramMarkdownV2(message.requestId)}_`,
27
+ ];
28
+ return lines.join('\n');
29
+ }
30
+ function buildInlineKeyboard(requestId) {
31
+ return {
32
+ inline_keyboard: [
33
+ [
34
+ {
35
+ text: '✅ Approve',
36
+ callback_data: `approve:${requestId}`,
37
+ },
38
+ {
39
+ text: '❌ Reject',
40
+ callback_data: `reject:${requestId}`,
41
+ },
42
+ ],
43
+ ],
44
+ };
45
+ }
46
+ export class TelegramMessenger {
47
+ type = 'telegram';
48
+ config;
49
+ baseUrl;
50
+ constructor(config) {
51
+ this.config = config;
52
+ this.baseUrl = `https://api.telegram.org/bot${config.botToken}`;
53
+ }
54
+ validateConfig() {
55
+ return (typeof this.config.botToken === 'string' &&
56
+ this.config.botToken.length > 0 &&
57
+ typeof this.config.chatId === 'string' &&
58
+ this.config.chatId.length > 0);
59
+ }
60
+ async sendNotification(message) {
61
+ try {
62
+ const text = buildTelegramMessage(message);
63
+ const replyMarkup = buildInlineKeyboard(message.requestId);
64
+ const response = await fetch(`${this.baseUrl}/sendMessage`, {
65
+ method: 'POST',
66
+ headers: {
67
+ 'Content-Type': 'application/json',
68
+ },
69
+ body: JSON.stringify({
70
+ chat_id: this.config.chatId,
71
+ text,
72
+ parse_mode: 'MarkdownV2',
73
+ reply_markup: replyMarkup,
74
+ }),
75
+ });
76
+ const result = await response.json();
77
+ if (!result.ok) {
78
+ return { ok: false, error: `Telegram API error: ${result.description || 'Unknown error'}` };
79
+ }
80
+ return { ok: true };
81
+ }
82
+ catch (error) {
83
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
84
+ return { ok: false, error: errorMessage };
85
+ }
86
+ }
87
+ async sendTestNotification() {
88
+ try {
89
+ const text = [
90
+ '✅ *Claude Guard Test Notification*',
91
+ '',
92
+ 'This is a test notification from Claude Guard\\.',
93
+ 'If you see this message, your Telegram integration is working correctly\\!',
94
+ '',
95
+ `_Sent at: ${escapeTelegramMarkdownV2(new Date().toISOString())}_`,
96
+ ].join('\n');
97
+ const response = await fetch(`${this.baseUrl}/sendMessage`, {
98
+ method: 'POST',
99
+ headers: {
100
+ 'Content-Type': 'application/json',
101
+ },
102
+ body: JSON.stringify({
103
+ chat_id: this.config.chatId,
104
+ text,
105
+ parse_mode: 'MarkdownV2',
106
+ }),
107
+ });
108
+ const result = await response.json();
109
+ if (!result.ok) {
110
+ return { ok: false, error: `Telegram API error: ${result.description || 'Unknown error'}` };
111
+ }
112
+ return { ok: true };
113
+ }
114
+ catch (error) {
115
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
116
+ return { ok: false, error: errorMessage };
117
+ }
118
+ }
119
+ }
120
+ //# sourceMappingURL=telegram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../../src/lib/messenger/telegram.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { Severity } from '../rules.js';
2
+ export type MessengerType = 'slack' | 'telegram' | 'whatsapp';
3
+ export interface MessengerMessage {
4
+ requestId: string;
5
+ command: string;
6
+ reason: string;
7
+ severity: Severity;
8
+ cwd: string;
9
+ timestamp: number;
10
+ }
11
+ export interface MessengerResult {
12
+ ok: boolean;
13
+ error?: string;
14
+ }
15
+ export interface Messenger {
16
+ readonly type: MessengerType;
17
+ sendNotification(message: MessengerMessage): Promise<MessengerResult>;
18
+ sendTestNotification(): Promise<MessengerResult>;
19
+ validateConfig(): boolean;
20
+ }
21
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/messenger/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACtE,oBAAoB,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;IACjD,cAAc,IAAI,OAAO,CAAC;CAC3B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/messenger/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ import type { Messenger, MessengerMessage, MessengerResult } from './types.js';
2
+ export interface WhatsAppConfig {
3
+ accountSid: string;
4
+ authToken: string;
5
+ fromNumber: string;
6
+ toNumber: string;
7
+ }
8
+ export declare class WhatsAppMessenger implements Messenger {
9
+ readonly type: "whatsapp";
10
+ private config;
11
+ constructor(config: WhatsAppConfig);
12
+ validateConfig(): boolean;
13
+ sendNotification(message: MessengerMessage): Promise<MessengerResult>;
14
+ sendTestNotification(): Promise<MessengerResult>;
15
+ }
16
+ //# sourceMappingURL=whatsapp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whatsapp.d.ts","sourceRoot":"","sources":["../../../src/lib/messenger/whatsapp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAG/E,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AA0BD,qBAAa,iBAAkB,YAAW,SAAS;IACjD,QAAQ,CAAC,IAAI,EAAG,UAAU,CAAU;IACpC,OAAO,CAAC,MAAM,CAAiB;gBAEnB,MAAM,EAAE,cAAc;IAIlC,cAAc,IAAI,OAAO;IAanB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAkCrE,oBAAoB,IAAI,OAAO,CAAC,eAAe,CAAC;CAwCvD"}