claude-telegram-mirror 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.
Files changed (99) hide show
  1. package/README.md +331 -0
  2. package/dist/bot/commands.d.ts +41 -0
  3. package/dist/bot/commands.d.ts.map +1 -0
  4. package/dist/bot/commands.js +231 -0
  5. package/dist/bot/commands.js.map +1 -0
  6. package/dist/bot/formatting.d.ts +62 -0
  7. package/dist/bot/formatting.d.ts.map +1 -0
  8. package/dist/bot/formatting.js +295 -0
  9. package/dist/bot/formatting.js.map +1 -0
  10. package/dist/bot/telegram.d.ts +93 -0
  11. package/dist/bot/telegram.d.ts.map +1 -0
  12. package/dist/bot/telegram.js +378 -0
  13. package/dist/bot/telegram.js.map +1 -0
  14. package/dist/bot/types.d.ts +28 -0
  15. package/dist/bot/types.d.ts.map +1 -0
  16. package/dist/bot/types.js +5 -0
  17. package/dist/bot/types.js.map +1 -0
  18. package/dist/bridge/daemon.d.ts +93 -0
  19. package/dist/bridge/daemon.d.ts.map +1 -0
  20. package/dist/bridge/daemon.js +626 -0
  21. package/dist/bridge/daemon.js.map +1 -0
  22. package/dist/bridge/index.d.ts +10 -0
  23. package/dist/bridge/index.d.ts.map +1 -0
  24. package/dist/bridge/index.js +9 -0
  25. package/dist/bridge/index.js.map +1 -0
  26. package/dist/bridge/injector.d.ts +97 -0
  27. package/dist/bridge/injector.d.ts.map +1 -0
  28. package/dist/bridge/injector.js +289 -0
  29. package/dist/bridge/injector.js.map +1 -0
  30. package/dist/bridge/session.d.ts +108 -0
  31. package/dist/bridge/session.d.ts.map +1 -0
  32. package/dist/bridge/session.js +381 -0
  33. package/dist/bridge/session.js.map +1 -0
  34. package/dist/bridge/socket.d.ts +97 -0
  35. package/dist/bridge/socket.d.ts.map +1 -0
  36. package/dist/bridge/socket.js +436 -0
  37. package/dist/bridge/socket.js.map +1 -0
  38. package/dist/bridge/types.d.ts +38 -0
  39. package/dist/bridge/types.d.ts.map +1 -0
  40. package/dist/bridge/types.js +5 -0
  41. package/dist/bridge/types.js.map +1 -0
  42. package/dist/cli.d.ts +7 -0
  43. package/dist/cli.d.ts.map +1 -0
  44. package/dist/cli.js +332 -0
  45. package/dist/cli.js.map +1 -0
  46. package/dist/hooks/handler.d.ts +94 -0
  47. package/dist/hooks/handler.d.ts.map +1 -0
  48. package/dist/hooks/handler.js +431 -0
  49. package/dist/hooks/handler.js.map +1 -0
  50. package/dist/hooks/index.d.ts +8 -0
  51. package/dist/hooks/index.d.ts.map +1 -0
  52. package/dist/hooks/index.js +7 -0
  53. package/dist/hooks/index.js.map +1 -0
  54. package/dist/hooks/installer.d.ts +46 -0
  55. package/dist/hooks/installer.d.ts.map +1 -0
  56. package/dist/hooks/installer.js +317 -0
  57. package/dist/hooks/installer.js.map +1 -0
  58. package/dist/hooks/types.d.ts +88 -0
  59. package/dist/hooks/types.d.ts.map +1 -0
  60. package/dist/hooks/types.js +6 -0
  61. package/dist/hooks/types.js.map +1 -0
  62. package/dist/index.d.ts +19 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +20 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/service/doctor.d.ts +10 -0
  67. package/dist/service/doctor.d.ts.map +1 -0
  68. package/dist/service/doctor.js +424 -0
  69. package/dist/service/doctor.js.map +1 -0
  70. package/dist/service/manager.d.ts +48 -0
  71. package/dist/service/manager.d.ts.map +1 -0
  72. package/dist/service/manager.js +584 -0
  73. package/dist/service/manager.js.map +1 -0
  74. package/dist/service/setup.d.ts +10 -0
  75. package/dist/service/setup.d.ts.map +1 -0
  76. package/dist/service/setup.js +266 -0
  77. package/dist/service/setup.js.map +1 -0
  78. package/dist/utils/chunker.d.ts +24 -0
  79. package/dist/utils/chunker.d.ts.map +1 -0
  80. package/dist/utils/chunker.js +123 -0
  81. package/dist/utils/chunker.js.map +1 -0
  82. package/dist/utils/config.d.ts +48 -0
  83. package/dist/utils/config.d.ts.map +1 -0
  84. package/dist/utils/config.js +154 -0
  85. package/dist/utils/config.js.map +1 -0
  86. package/dist/utils/logger.d.ts +7 -0
  87. package/dist/utils/logger.d.ts.map +1 -0
  88. package/dist/utils/logger.js +28 -0
  89. package/dist/utils/logger.js.map +1 -0
  90. package/package.json +88 -0
  91. package/postinstall.cjs +76 -0
  92. package/scripts/claude-wrapper.sh +122 -0
  93. package/scripts/doctor.sh +433 -0
  94. package/scripts/get-chat-id.sh +64 -0
  95. package/scripts/global-hooks.sh +39 -0
  96. package/scripts/install.sh +831 -0
  97. package/scripts/start-daemon.sh +49 -0
  98. package/scripts/telegram-hook.sh +449 -0
  99. package/scripts/uninstall.sh +261 -0
@@ -0,0 +1,266 @@
1
+ /**
2
+ * Interactive Setup Wizard
3
+ * Guides users through configuring claude-telegram-mirror
4
+ */
5
+ import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
6
+ import { join } from 'path';
7
+ import { homedir } from 'os';
8
+ import { createInterface } from 'readline';
9
+ const CONFIG_DIR = join(homedir(), '.config', 'claude-telegram-mirror');
10
+ const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
11
+ // ANSI color codes (works in Node.js terminal)
12
+ const colors = {
13
+ reset: '\x1b[0m',
14
+ bold: '\x1b[1m',
15
+ dim: '\x1b[2m',
16
+ cyan: '\x1b[36m',
17
+ green: '\x1b[32m',
18
+ yellow: '\x1b[33m',
19
+ red: '\x1b[31m',
20
+ blue: '\x1b[34m',
21
+ gray: '\x1b[90m',
22
+ };
23
+ function cyan(text) { return `${colors.cyan}${text}${colors.reset}`; }
24
+ function green(text) { return `${colors.green}${text}${colors.reset}`; }
25
+ function yellow(text) { return `${colors.yellow}${text}${colors.reset}`; }
26
+ function red(text) { return `${colors.red}${text}${colors.reset}`; }
27
+ function gray(text) { return `${colors.gray}${text}${colors.reset}`; }
28
+ function bold(text) { return `${colors.bold}${text}${colors.reset}`; }
29
+ /**
30
+ * Simple readline prompt
31
+ */
32
+ async function prompt(question, defaultValue) {
33
+ const rl = createInterface({
34
+ input: process.stdin,
35
+ output: process.stdout,
36
+ });
37
+ return new Promise((resolve) => {
38
+ const defaultHint = defaultValue ? gray(` (${defaultValue})`) : '';
39
+ rl.question(`${question}${defaultHint}: `, (answer) => {
40
+ rl.close();
41
+ resolve(answer.trim() || defaultValue || '');
42
+ });
43
+ });
44
+ }
45
+ /**
46
+ * Yes/No prompt
47
+ */
48
+ async function confirm(question, defaultValue = true) {
49
+ const hint = defaultValue ? '[Y/n]' : '[y/N]';
50
+ const answer = await prompt(`${question} ${gray(hint)}`);
51
+ if (!answer)
52
+ return defaultValue;
53
+ return answer.toLowerCase().startsWith('y');
54
+ }
55
+ /**
56
+ * Test Telegram bot token
57
+ */
58
+ async function testBotToken(token) {
59
+ try {
60
+ const response = await fetch(`https://api.telegram.org/bot${token}/getMe`);
61
+ const data = await response.json();
62
+ if (data.ok) {
63
+ return { valid: true, username: data.result?.username };
64
+ }
65
+ return { valid: false, error: data.description || 'Invalid token' };
66
+ }
67
+ catch (error) {
68
+ return { valid: false, error: 'Network error - check your connection' };
69
+ }
70
+ }
71
+ /**
72
+ * Test chat ID by sending a message
73
+ */
74
+ async function testChatId(token, chatId) {
75
+ try {
76
+ const response = await fetch(`https://api.telegram.org/bot${token}/sendMessage`, {
77
+ method: 'POST',
78
+ headers: { 'Content-Type': 'application/json' },
79
+ body: JSON.stringify({
80
+ chat_id: chatId,
81
+ text: '🧪 Test message from Claude Telegram Mirror setup wizard.\n\nIf you see this, your configuration is correct!',
82
+ parse_mode: 'Markdown'
83
+ })
84
+ });
85
+ const data = await response.json();
86
+ if (data.ok) {
87
+ return { valid: true };
88
+ }
89
+ return { valid: false, error: data.description || 'Failed to send message' };
90
+ }
91
+ catch (error) {
92
+ return { valid: false, error: 'Network error' };
93
+ }
94
+ }
95
+ /**
96
+ * Run interactive setup wizard
97
+ */
98
+ export async function runSetup() {
99
+ console.log('');
100
+ console.log(cyan('╔════════════════════════════════════════════════════════════╗'));
101
+ console.log(cyan('║') + bold(' Claude Telegram Mirror - Setup Wizard ') + cyan('║'));
102
+ console.log(cyan('╚════════════════════════════════════════════════════════════╝'));
103
+ console.log('');
104
+ // Load existing config if present
105
+ let existingConfig = {};
106
+ if (existsSync(CONFIG_FILE)) {
107
+ try {
108
+ existingConfig = JSON.parse(readFileSync(CONFIG_FILE, 'utf-8'));
109
+ console.log(green('✓') + ' Found existing configuration');
110
+ console.log('');
111
+ }
112
+ catch {
113
+ // Ignore
114
+ }
115
+ }
116
+ // Step 1: Bot Token
117
+ console.log(yellow('Step 1: Telegram Bot Token'));
118
+ console.log(gray('─'.repeat(50)));
119
+ console.log('');
120
+ console.log('Create a bot via @BotFather on Telegram:');
121
+ console.log(' 1. Open Telegram and search for @BotFather');
122
+ console.log(' 2. Send /newbot and follow the prompts');
123
+ console.log(' 3. Copy the API token provided');
124
+ console.log('');
125
+ let botToken = '';
126
+ let botUsername = '';
127
+ while (!botToken) {
128
+ const token = await prompt('Enter your bot token', existingConfig.botToken);
129
+ if (!token) {
130
+ console.log(red('Bot token is required'));
131
+ continue;
132
+ }
133
+ process.stdout.write('Verifying token... ');
134
+ const result = await testBotToken(token);
135
+ if (result.valid) {
136
+ console.log(green('✓ Valid'));
137
+ console.log(`Bot: @${result.username}`);
138
+ botToken = token;
139
+ botUsername = result.username || '';
140
+ }
141
+ else {
142
+ console.log(red('✗ Invalid'));
143
+ console.log(red(`Error: ${result.error}`));
144
+ }
145
+ }
146
+ console.log('');
147
+ // Step 2: Chat ID
148
+ console.log(yellow('Step 2: Telegram Chat ID'));
149
+ console.log(gray('─'.repeat(50)));
150
+ console.log('');
151
+ console.log('Get your chat ID:');
152
+ console.log(` 1. Message your bot @${botUsername} on Telegram`);
153
+ console.log(' 2. Visit: ' + cyan(`https://api.telegram.org/bot${botToken}/getUpdates`));
154
+ console.log(' 3. Look for "chat":{"id":XXXXXXXX} in the response');
155
+ console.log('');
156
+ console.log(gray('Tip: For a group/supergroup, the ID starts with -100'));
157
+ console.log('');
158
+ let chatId = '';
159
+ while (!chatId) {
160
+ const id = await prompt('Enter your chat ID', existingConfig.chatId?.toString());
161
+ if (!id) {
162
+ console.log(red('Chat ID is required'));
163
+ continue;
164
+ }
165
+ process.stdout.write('Testing chat access... ');
166
+ const result = await testChatId(botToken, id);
167
+ if (result.valid) {
168
+ console.log(green('✓ Message sent'));
169
+ console.log('Check your Telegram for the test message!');
170
+ chatId = id;
171
+ }
172
+ else {
173
+ console.log(red('✗ Failed'));
174
+ console.log(red(`Error: ${result.error}`));
175
+ console.log(gray('Make sure you have started a chat with your bot first.'));
176
+ }
177
+ }
178
+ console.log('');
179
+ // Step 3: Options
180
+ console.log(yellow('Step 3: Configuration Options'));
181
+ console.log(gray('─'.repeat(50)));
182
+ console.log('');
183
+ const useThreads = await confirm('Enable forum threads for per-session topics?', existingConfig.useThreads ?? true);
184
+ const installHooks = await confirm('Install Claude Code hooks?', true);
185
+ const installService = await confirm('Install as systemd service (auto-start)?', true);
186
+ console.log('');
187
+ // Save configuration
188
+ console.log(yellow('Saving configuration...'));
189
+ console.log(gray('─'.repeat(50)));
190
+ // Create config directory
191
+ if (!existsSync(CONFIG_DIR)) {
192
+ mkdirSync(CONFIG_DIR, { recursive: true });
193
+ console.log(green('✓') + ' Created config directory');
194
+ }
195
+ // Save config file
196
+ const config = {
197
+ botToken,
198
+ chatId: parseInt(chatId, 10),
199
+ enabled: true,
200
+ useThreads,
201
+ verbose: true,
202
+ approvals: true,
203
+ };
204
+ writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
205
+ console.log(green('✓') + ' Saved config to ' + gray(CONFIG_FILE));
206
+ // Also suggest environment variables
207
+ console.log('');
208
+ console.log(yellow('Environment variables (add to ~/.bashrc or ~/.zshrc):'));
209
+ console.log('');
210
+ console.log(gray(' export TELEGRAM_BOT_TOKEN="') + botToken + gray('"'));
211
+ console.log(gray(' export TELEGRAM_CHAT_ID="') + chatId + gray('"'));
212
+ console.log(gray(' export TELEGRAM_MIRROR=true'));
213
+ console.log('');
214
+ // Install hooks if requested
215
+ if (installHooks) {
216
+ console.log(yellow('Installing Claude Code hooks...'));
217
+ try {
218
+ // Import dynamically to avoid circular dependencies
219
+ const { installHooks: doInstallHooks } = await import('../hooks/installer.js');
220
+ const result = doInstallHooks({ force: false });
221
+ if (result.success) {
222
+ console.log(green('✓') + ' Hooks installed');
223
+ }
224
+ else {
225
+ console.log(yellow('⚠') + ' Hook installation: ' + result.error);
226
+ }
227
+ }
228
+ catch (error) {
229
+ console.log(yellow('⚠') + ' Could not install hooks: ' + error.message);
230
+ }
231
+ }
232
+ // Install service if requested
233
+ if (installService) {
234
+ console.log(yellow('Installing systemd service...'));
235
+ try {
236
+ const { installService: doInstallService } = await import('./manager.js');
237
+ const result = doInstallService();
238
+ if (result.success) {
239
+ console.log(green('✓') + ' Service installed');
240
+ console.log(gray(' Start with: ctm service start'));
241
+ }
242
+ else {
243
+ console.log(yellow('⚠') + ' Service installation: ' + result.message);
244
+ }
245
+ }
246
+ catch (error) {
247
+ console.log(yellow('⚠') + ' Could not install service: ' + error.message);
248
+ }
249
+ }
250
+ // Final summary
251
+ console.log('');
252
+ console.log(cyan('╔════════════════════════════════════════════════════════════╗'));
253
+ console.log(cyan('║') + green(' Setup Complete! ') + cyan('║'));
254
+ console.log(cyan('╚════════════════════════════════════════════════════════════╝'));
255
+ console.log('');
256
+ console.log('Next steps:');
257
+ console.log('');
258
+ console.log(' 1. ' + cyan('ctm start') + ' Start the daemon');
259
+ console.log(' 2. ' + cyan('ctm service start') + ' Start via systemd');
260
+ console.log(' 3. ' + cyan('ctm doctor') + ' Verify everything works');
261
+ console.log('');
262
+ console.log(gray('Run ctm --help for all available commands.'));
263
+ console.log('');
264
+ }
265
+ export default runSetup;
266
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/service/setup.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,wBAAwB,CAAC,CAAC;AACxE,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEpD,+CAA+C;AAC/C,MAAM,MAAM,GAAG;IACb,KAAK,EAAE,SAAS;IAChB,IAAI,EAAE,SAAS;IACf,GAAG,EAAE,SAAS;IACd,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,UAAU;IACjB,MAAM,EAAE,UAAU;IAClB,GAAG,EAAE,UAAU;IACf,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,UAAU;CACjB,CAAC;AAEF,SAAS,IAAI,CAAC,IAAY,IAAY,OAAO,GAAG,MAAM,CAAC,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AACtF,SAAS,KAAK,CAAC,IAAY,IAAY,OAAO,GAAG,MAAM,CAAC,KAAK,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AACxF,SAAS,MAAM,CAAC,IAAY,IAAY,OAAO,GAAG,MAAM,CAAC,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAC1F,SAAS,GAAG,CAAC,IAAY,IAAY,OAAO,GAAG,MAAM,CAAC,GAAG,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AACpF,SAAS,IAAI,CAAC,IAAY,IAAY,OAAO,GAAG,MAAM,CAAC,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AACtF,SAAS,IAAI,CAAC,IAAY,IAAY,OAAO,GAAG,MAAM,CAAC,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAEtF;;GAEG;AACH,KAAK,UAAU,MAAM,CAAC,QAAgB,EAAE,YAAqB;IAC3D,MAAM,EAAE,GAAG,eAAe,CAAC;QACzB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IAEH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,EAAE,CAAC,QAAQ,CAAC,GAAG,QAAQ,GAAG,WAAW,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE;YACpD,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,YAAY,IAAI,EAAE,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,OAAO,CAAC,QAAgB,EAAE,eAAwB,IAAI;IACnE,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IAC9C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEzD,IAAI,CAAC,MAAM;QAAE,OAAO,YAAY,CAAC;IACjC,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,YAAY,CAAC,KAAa;IACvC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,+BAA+B,KAAK,QAAQ,CAAC,CAAC;QAC3E,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA0E,CAAC;QAE3G,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;QAC1D,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,IAAI,eAAe,EAAE,CAAC;IACtE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,uCAAuC,EAAE,CAAC;IAC1E,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,UAAU,CAAC,KAAa,EAAE,MAAc;IACrD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,+BAA+B,KAAK,cAAc,EAAE;YAC/E,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,OAAO,EAAE,MAAM;gBACf,IAAI,EAAE,8GAA8G;gBACpH,UAAU,EAAE,UAAU;aACvB,CAAC;SACH,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA2C,CAAC;QAE5E,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACzB,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,IAAI,wBAAwB,EAAE,CAAC;IAC/E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;IAClD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC,CAAC;IACpF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,8DAA8D,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1G,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC,CAAC;IACpF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,kCAAkC;IAClC,IAAI,cAAc,GAA4B,EAAE,CAAC;IACjD,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;YAChE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,+BAA+B,CAAC,CAAC;YAC1D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,IAAI,QAAQ,GAAG,EAAE,CAAC;IAClB,IAAI,WAAW,GAAG,EAAE,CAAC;IAErB,OAAO,CAAC,QAAQ,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,sBAAsB,EAAE,cAAc,CAAC,QAAkB,CAAC,CAAC;QAEtF,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC;YAC1C,SAAS;QACX,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,CAAC;QAEzC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YACxC,QAAQ,GAAG,KAAK,CAAC;YACjB,WAAW,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,kBAAkB;IAClB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,0BAA0B,WAAW,cAAc,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC,+BAA+B,QAAQ,aAAa,CAAC,CAAC,CAAC;IACzF,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,OAAO,CAAC,MAAM,EAAE,CAAC;QACf,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,EAAE,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QAEjF,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC;YACxC,SAAS;QACX,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAE9C,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC;YACrC,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;YACzD,MAAM,GAAG,EAAE,CAAC;QACd,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,wDAAwD,CAAC,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,kBAAkB;IAClB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,+BAA+B,CAAC,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,UAAU,GAAG,MAAM,OAAO,CAC9B,8CAA8C,EAC7C,cAAc,CAAC,UAAsB,IAAI,IAAI,CAC/C,CAAC;IAEF,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,4BAA4B,EAAE,IAAI,CAAC,CAAC;IACvE,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,0CAA0C,EAAE,IAAI,CAAC,CAAC;IAEvF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,qBAAqB;IACrB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAElC,0BAA0B;IAC1B,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,2BAA2B,CAAC,CAAC;IACxD,CAAC;IAED,mBAAmB;IACnB,MAAM,MAAM,GAAG;QACb,QAAQ;QACR,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;QAC5B,OAAO,EAAE,IAAI;QACb,UAAU;QACV,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,IAAI;KAChB,CAAC;IAEF,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,mBAAmB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAElE,qCAAqC;IACrC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,uDAAuD,CAAC,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,+BAA+B,CAAC,GAAG,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,6BAA6B,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,6BAA6B;IAC7B,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,iCAAiC,CAAC,CAAC,CAAC;QACvD,IAAI,CAAC;YACH,oDAAoD;YACpD,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;YAC/E,MAAM,MAAM,GAAG,cAAc,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YAChD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,kBAAkB,CAAC,CAAC;YAC/C,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,sBAAsB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,4BAA4B,GAAI,KAAe,CAAC,OAAO,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;IAED,+BAA+B;IAC/B,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,+BAA+B,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC;YACH,MAAM,EAAE,cAAc,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;YAC1E,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;YAClC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,oBAAoB,CAAC,CAAC;gBAC/C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC,CAAC;YACvD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,yBAAyB,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,8BAA8B,GAAI,KAAe,CAAC,OAAO,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IAED,gBAAgB;IAChB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC,CAAC;IACpF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,6DAA6D,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1G,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC,CAAC;IACpF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC3B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,6BAA6B,CAAC,CAAC;IACzE,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,sBAAsB,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,mCAAmC,CAAC,CAAC;IAChF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Message Chunking Utilities
3
+ * Handles splitting long messages for Telegram's 4096 char limit
4
+ */
5
+ declare const DEFAULT_MAX_LENGTH = 4000;
6
+ interface ChunkOptions {
7
+ maxLength?: number;
8
+ preserveCodeBlocks?: boolean;
9
+ addPartHeaders?: boolean;
10
+ }
11
+ /**
12
+ * Chunk a message into parts that fit Telegram's limit
13
+ */
14
+ export declare function chunkMessage(text: string, options?: ChunkOptions): string[];
15
+ /**
16
+ * Estimate the number of chunks a message will need
17
+ */
18
+ export declare function estimateChunks(text: string, maxLength?: number): number;
19
+ /**
20
+ * Check if a message needs chunking
21
+ */
22
+ export declare function needsChunking(text: string, maxLength?: number): boolean;
23
+ export { DEFAULT_MAX_LENGTH };
24
+ //# sourceMappingURL=chunker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunker.d.ts","sourceRoot":"","sources":["../../src/utils/chunker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,QAAA,MAAM,kBAAkB,OAAO,CAAC;AAEhC,UAAU,YAAY;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAmFD;;GAEG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,YAAiB,GACzB,MAAM,EAAE,CAqDV;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,MAA2B,GAAG,MAAM,CAE3F;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,MAA2B,GAAG,OAAO,CAE3F;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Message Chunking Utilities
3
+ * Handles splitting long messages for Telegram's 4096 char limit
4
+ */
5
+ const DEFAULT_MAX_LENGTH = 4000; // Leave room for part headers
6
+ /**
7
+ * Find all code block positions in the text
8
+ */
9
+ function findCodeBlocks(text) {
10
+ const blocks = [];
11
+ let match;
12
+ const regex = /```[\s\S]*?```/g;
13
+ while ((match = regex.exec(text)) !== null) {
14
+ blocks.push({
15
+ start: match.index,
16
+ end: match.index + match[0].length
17
+ });
18
+ }
19
+ return blocks;
20
+ }
21
+ /**
22
+ * Check if a position is inside a code block
23
+ */
24
+ function isInsideCodeBlock(position, codeBlocks) {
25
+ return codeBlocks.some(block => position > block.start && position < block.end);
26
+ }
27
+ /**
28
+ * Find the best split point near the target position
29
+ */
30
+ function findBestSplitPoint(text, targetPosition, codeBlocks) {
31
+ // If we're inside a code block, try to split before it
32
+ for (const block of codeBlocks) {
33
+ if (targetPosition > block.start && targetPosition < block.end) {
34
+ // Try to split before this code block if there's room
35
+ if (block.start > 100) {
36
+ return block.start;
37
+ }
38
+ // Otherwise, split after this code block
39
+ return Math.min(block.end, text.length);
40
+ }
41
+ }
42
+ // Look for natural break points (newlines, sentence ends)
43
+ const searchStart = Math.max(0, targetPosition - 200);
44
+ const searchEnd = Math.min(text.length, targetPosition + 50);
45
+ const searchText = text.slice(searchStart, searchEnd);
46
+ // Priority: double newline > single newline > period > space
47
+ const breakPoints = [
48
+ { pattern: /\n\n/g, offset: 2 },
49
+ { pattern: /\n/g, offset: 1 },
50
+ { pattern: /\. /g, offset: 2 },
51
+ { pattern: / /g, offset: 1 }
52
+ ];
53
+ for (const { pattern, offset } of breakPoints) {
54
+ let match;
55
+ let bestMatch = -1;
56
+ while ((match = pattern.exec(searchText)) !== null) {
57
+ const absolutePos = searchStart + match.index + offset;
58
+ if (absolutePos <= targetPosition && !isInsideCodeBlock(absolutePos, codeBlocks)) {
59
+ bestMatch = absolutePos;
60
+ }
61
+ }
62
+ if (bestMatch !== -1) {
63
+ return bestMatch;
64
+ }
65
+ }
66
+ // Fallback to target position
67
+ return targetPosition;
68
+ }
69
+ /**
70
+ * Chunk a message into parts that fit Telegram's limit
71
+ */
72
+ export function chunkMessage(text, options = {}) {
73
+ const { maxLength = DEFAULT_MAX_LENGTH, preserveCodeBlocks = true, addPartHeaders = true } = options;
74
+ // If it fits, return as-is
75
+ if (text.length <= maxLength) {
76
+ return [text];
77
+ }
78
+ const chunks = [];
79
+ const codeBlocks = preserveCodeBlocks ? findCodeBlocks(text) : [];
80
+ let remaining = text;
81
+ let chunkIndex = 0;
82
+ while (remaining.length > 0) {
83
+ chunkIndex++;
84
+ if (remaining.length <= maxLength) {
85
+ chunks.push(remaining);
86
+ break;
87
+ }
88
+ // Find best split point
89
+ const splitPoint = findBestSplitPoint(remaining, maxLength, codeBlocks);
90
+ // Extract chunk
91
+ let chunk = remaining.slice(0, splitPoint).trim();
92
+ remaining = remaining.slice(splitPoint).trim();
93
+ // Update code block positions for remaining text
94
+ codeBlocks.forEach(block => {
95
+ block.start -= splitPoint;
96
+ block.end -= splitPoint;
97
+ });
98
+ // Remove blocks that are now fully before the split
99
+ while (codeBlocks.length > 0 && codeBlocks[0].end < 0) {
100
+ codeBlocks.shift();
101
+ }
102
+ chunks.push(chunk);
103
+ }
104
+ // Add part headers if needed
105
+ if (addPartHeaders && chunks.length > 1) {
106
+ return chunks.map((chunk, i) => `📄 *Part ${i + 1}/${chunks.length}*\n\n${chunk}`);
107
+ }
108
+ return chunks;
109
+ }
110
+ /**
111
+ * Estimate the number of chunks a message will need
112
+ */
113
+ export function estimateChunks(text, maxLength = DEFAULT_MAX_LENGTH) {
114
+ return Math.ceil(text.length / maxLength);
115
+ }
116
+ /**
117
+ * Check if a message needs chunking
118
+ */
119
+ export function needsChunking(text, maxLength = DEFAULT_MAX_LENGTH) {
120
+ return text.length > maxLength;
121
+ }
122
+ export { DEFAULT_MAX_LENGTH };
123
+ //# sourceMappingURL=chunker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunker.js","sourceRoot":"","sources":["../../src/utils/chunker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Configuration Management
3
+ * Loads configuration from environment variables and optional config file
4
+ */
5
+ export interface TelegramMirrorConfig {
6
+ botToken: string;
7
+ chatId: number;
8
+ enabled: boolean;
9
+ verbose: boolean;
10
+ approvals: boolean;
11
+ socketPath: string;
12
+ useThreads: boolean;
13
+ forumEnabled: boolean;
14
+ chunkSize: number;
15
+ rateLimit: number;
16
+ sessionTimeout: number;
17
+ configPath: string;
18
+ }
19
+ declare class ConfigurationError extends Error {
20
+ constructor(message: string);
21
+ }
22
+ /**
23
+ * Validate and load configuration
24
+ */
25
+ export declare function loadConfig(requireAuth?: boolean): TelegramMirrorConfig;
26
+ /**
27
+ * Check if mirroring is enabled
28
+ */
29
+ export declare function isMirrorEnabled(): boolean;
30
+ /**
31
+ * Get config directory path
32
+ */
33
+ export declare function getConfigDir(): string;
34
+ export declare const config: TelegramMirrorConfig;
35
+ /**
36
+ * Reset config (useful for testing)
37
+ */
38
+ export declare function resetConfig(): void;
39
+ /**
40
+ * Validate configuration
41
+ */
42
+ export declare function validateConfig(config: TelegramMirrorConfig): {
43
+ valid: boolean;
44
+ errors: string[];
45
+ warnings: string[];
46
+ };
47
+ export { ConfigurationError };
48
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,oBAAoB;IAEnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IAGf,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IAGnB,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IAGtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IAGvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAmBD,cAAM,kBAAmB,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM;CAI5B;AAwCD;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,GAAE,OAAc,GAAG,oBAAoB,CA+E5E;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAIzC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAOD,eAAO,MAAM,MAAM,sBAOjB,CAAC;AAEH;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG;IAC5D,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CA2BA;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Configuration Management
3
+ * Loads configuration from environment variables and optional config file
4
+ */
5
+ import { existsSync, readFileSync } from 'fs';
6
+ import { join } from 'path';
7
+ import { homedir } from 'os';
8
+ import logger from './logger.js';
9
+ const CONFIG_DIR = join(homedir(), '.config', 'claude-telegram-mirror');
10
+ const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
11
+ const DEFAULT_SOCKET_PATH = join(CONFIG_DIR, 'bridge.sock');
12
+ class ConfigurationError extends Error {
13
+ constructor(message) {
14
+ super(message);
15
+ this.name = 'ConfigurationError';
16
+ }
17
+ }
18
+ /**
19
+ * Load configuration from config file if it exists
20
+ */
21
+ function loadConfigFile() {
22
+ if (!existsSync(CONFIG_FILE)) {
23
+ return {};
24
+ }
25
+ try {
26
+ const content = readFileSync(CONFIG_FILE, 'utf-8');
27
+ return JSON.parse(content);
28
+ }
29
+ catch (error) {
30
+ logger.warn(`Failed to parse config file: ${CONFIG_FILE}`, { error });
31
+ return {};
32
+ }
33
+ }
34
+ /**
35
+ * Parse boolean from environment variable
36
+ */
37
+ function parseEnvBool(value, defaultValue) {
38
+ if (value === undefined || value === '') {
39
+ return defaultValue;
40
+ }
41
+ return value.toLowerCase() === 'true' || value === '1';
42
+ }
43
+ /**
44
+ * Parse number from environment variable
45
+ */
46
+ function parseEnvNumber(value, defaultValue) {
47
+ if (value === undefined || value === '') {
48
+ return defaultValue;
49
+ }
50
+ const num = parseInt(value, 10);
51
+ return isNaN(num) ? defaultValue : num;
52
+ }
53
+ /**
54
+ * Validate and load configuration
55
+ */
56
+ export function loadConfig(requireAuth = true) {
57
+ const fileConfig = loadConfigFile();
58
+ // Get values with priority: env vars > config file > defaults
59
+ const botToken = process.env.TELEGRAM_BOT_TOKEN || fileConfig.botToken || '';
60
+ const chatIdStr = process.env.TELEGRAM_CHAT_ID || fileConfig.chatId?.toString() || '';
61
+ const chatId = parseInt(chatIdStr, 10);
62
+ // Validate required fields only if auth is required
63
+ if (requireAuth) {
64
+ if (!botToken) {
65
+ throw new ConfigurationError('TELEGRAM_BOT_TOKEN is required.\n' +
66
+ 'Get one from @BotFather on Telegram and set:\n' +
67
+ ' export TELEGRAM_BOT_TOKEN="your-token-here"');
68
+ }
69
+ if (!chatIdStr || isNaN(chatId)) {
70
+ throw new ConfigurationError('TELEGRAM_CHAT_ID is required.\n' +
71
+ 'Get your chat ID by messaging your bot and visiting:\n' +
72
+ ` https://api.telegram.org/bot${botToken}/getUpdates\n` +
73
+ 'Then set:\n' +
74
+ ' export TELEGRAM_CHAT_ID="your-chat-id"');
75
+ }
76
+ }
77
+ const config = {
78
+ botToken,
79
+ chatId: isNaN(chatId) ? 0 : chatId,
80
+ enabled: parseEnvBool(process.env.TELEGRAM_MIRROR, fileConfig.enabled ?? false),
81
+ verbose: parseEnvBool(process.env.TELEGRAM_MIRROR_VERBOSE, fileConfig.verbose ?? true),
82
+ approvals: parseEnvBool(process.env.TELEGRAM_MIRROR_APPROVALS, fileConfig.approvals ?? true),
83
+ socketPath: process.env.TELEGRAM_BRIDGE_SOCKET ||
84
+ fileConfig.socketPath ||
85
+ DEFAULT_SOCKET_PATH,
86
+ useThreads: parseEnvBool(process.env.TELEGRAM_USE_THREADS, fileConfig.useThreads ?? true),
87
+ forumEnabled: false, // Detected at runtime
88
+ chunkSize: parseEnvNumber(process.env.TELEGRAM_CHUNK_SIZE, fileConfig.chunkSize ?? 4000),
89
+ rateLimit: parseEnvNumber(process.env.TELEGRAM_RATE_LIMIT, fileConfig.rateLimit ?? 1),
90
+ sessionTimeout: parseEnvNumber(process.env.TELEGRAM_SESSION_TIMEOUT, fileConfig.sessionTimeout ?? 30),
91
+ configPath: CONFIG_FILE
92
+ };
93
+ return config;
94
+ }
95
+ /**
96
+ * Check if mirroring is enabled
97
+ */
98
+ export function isMirrorEnabled() {
99
+ return parseEnvBool(process.env.TELEGRAM_MIRROR, false) &&
100
+ !!process.env.TELEGRAM_BOT_TOKEN &&
101
+ !!process.env.TELEGRAM_CHAT_ID;
102
+ }
103
+ /**
104
+ * Get config directory path
105
+ */
106
+ export function getConfigDir() {
107
+ return CONFIG_DIR;
108
+ }
109
+ /**
110
+ * Singleton config instance (lazy loaded)
111
+ */
112
+ let _config = null;
113
+ export const config = new Proxy({}, {
114
+ get(_target, prop) {
115
+ if (!_config) {
116
+ _config = loadConfig(false);
117
+ }
118
+ return _config[prop];
119
+ }
120
+ });
121
+ /**
122
+ * Reset config (useful for testing)
123
+ */
124
+ export function resetConfig() {
125
+ _config = null;
126
+ }
127
+ /**
128
+ * Validate configuration
129
+ */
130
+ export function validateConfig(config) {
131
+ const errors = [];
132
+ const warnings = [];
133
+ // Check required fields
134
+ if (!config.botToken) {
135
+ errors.push('TELEGRAM_BOT_TOKEN is not set');
136
+ }
137
+ if (!config.chatId) {
138
+ errors.push('TELEGRAM_CHAT_ID is not set');
139
+ }
140
+ // Check warnings
141
+ if (!config.enabled) {
142
+ warnings.push('TELEGRAM_MIRROR is not enabled');
143
+ }
144
+ if (config.chunkSize < 1000 || config.chunkSize > 4096) {
145
+ warnings.push(`Chunk size ${config.chunkSize} may cause issues (recommended: 1000-4096)`);
146
+ }
147
+ return {
148
+ valid: errors.length === 0,
149
+ errors,
150
+ warnings
151
+ };
152
+ }
153
+ export { ConfigurationError };
154
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}