claude-tg 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/claude-tg.js CHANGED
@@ -249,6 +249,140 @@ program
249
249
  }
250
250
  });
251
251
 
252
+ program
253
+ .command('test')
254
+ .description('Test the full chain: config, daemon, hooks, Telegram')
255
+ .action(async () => {
256
+ const http = require('http');
257
+ let ok = true;
258
+
259
+ // 1. Config
260
+ console.log('\n--- Config ---');
261
+ const config = loadConfig();
262
+ if (config.botToken && config.chatId) {
263
+ console.log(` Bot token: ${config.botToken.slice(0, 8)}...`);
264
+ console.log(` Chat ID: ${config.chatId}`);
265
+ console.log(` Port: ${config.port}`);
266
+ } else {
267
+ console.log(' NOT CONFIGURED. Run: claude-tg setup');
268
+ ok = false;
269
+ }
270
+
271
+ // 2. Hooks
272
+ console.log('\n--- Hooks ---');
273
+ const settingsPath = path.join(process.env.HOME, '.claude', 'settings.json');
274
+ if (fs.existsSync(settingsPath)) {
275
+ try {
276
+ const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
277
+ const hooks = settings.hooks || {};
278
+
279
+ const permHooks = hooks.PermissionRequest || [];
280
+ const permCmd = permHooks[0]?.hooks?.[0]?.command || 'NOT FOUND';
281
+ console.log(` PermissionRequest: ${permCmd}`);
282
+ if (permCmd !== 'NOT FOUND') {
283
+ const scriptPath = permCmd.replace(/^node\s+/, '');
284
+ if (fs.existsSync(scriptPath)) {
285
+ console.log(' File exists: YES');
286
+ } else {
287
+ console.log(` File exists: NO — ${scriptPath}`);
288
+ ok = false;
289
+ }
290
+ }
291
+
292
+ const notifHooks = hooks.Notification || [];
293
+ const notifCmd = notifHooks[0]?.hooks?.[0]?.command || 'NOT FOUND';
294
+ console.log(` Notification: ${notifCmd}`);
295
+ if (notifCmd !== 'NOT FOUND') {
296
+ const scriptPath = notifCmd.replace(/^node\s+/, '');
297
+ if (fs.existsSync(scriptPath)) {
298
+ console.log(' File exists: YES');
299
+ } else {
300
+ console.log(` File exists: NO — ${scriptPath}`);
301
+ ok = false;
302
+ }
303
+ }
304
+ } catch (e) {
305
+ console.log(` Error reading settings: ${e.message}`);
306
+ ok = false;
307
+ }
308
+ } else {
309
+ console.log(' ~/.claude/settings.json not found. Run: claude-tg setup');
310
+ ok = false;
311
+ }
312
+
313
+ // 3. Daemon
314
+ console.log('\n--- Daemon ---');
315
+ try {
316
+ const health = await new Promise((resolve, reject) => {
317
+ const req = http.get(`http://127.0.0.1:${config.port}/api/health`, (res) => {
318
+ let data = '';
319
+ res.on('data', (chunk) => { data += chunk; });
320
+ res.on('end', () => {
321
+ try { resolve(JSON.parse(data)); } catch { reject(new Error('bad response')); }
322
+ });
323
+ });
324
+ req.on('error', reject);
325
+ req.setTimeout(3000, () => { req.destroy(); reject(new Error('timeout')); });
326
+ });
327
+ console.log(` Running: YES (${health.sessions} sessions, ${health.pending} pending)`);
328
+ } catch {
329
+ console.log(' Running: NO — start with: claude-tg daemon start');
330
+ ok = false;
331
+ }
332
+
333
+ // 4. Telegram
334
+ console.log('\n--- Telegram ---');
335
+ if (config.botToken && config.chatId) {
336
+ try {
337
+ const { Telegram } = require('telegraf');
338
+ const tg = new Telegram(config.botToken);
339
+ await tg.sendMessage(config.chatId, '🧪 claude-tg test — everything is working!');
340
+ console.log(' Test message sent: YES');
341
+ } catch (err) {
342
+ console.log(` Test message FAILED: ${err.message}`);
343
+ ok = false;
344
+ }
345
+ } else {
346
+ console.log(' Skipped (no config)');
347
+ }
348
+
349
+ // 5. Send test notification to daemon
350
+ if (ok) {
351
+ console.log('\n--- Hook simulation ---');
352
+ try {
353
+ const result = await new Promise((resolve, reject) => {
354
+ const payload = JSON.stringify({
355
+ session_id: 'test-' + Date.now(),
356
+ cwd: process.cwd(),
357
+ notification_type: 'idle_prompt',
358
+ message: 'Test notification from claude-tg test',
359
+ transcript_path: null,
360
+ tty_path: null,
361
+ });
362
+ const req = http.request({
363
+ hostname: '127.0.0.1', port: config.port,
364
+ path: '/api/notify', method: 'POST',
365
+ headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) },
366
+ timeout: 5000,
367
+ }, (res) => {
368
+ let data = '';
369
+ res.on('data', (c) => { data += c; });
370
+ res.on('end', () => resolve(data));
371
+ });
372
+ req.on('error', reject);
373
+ req.write(payload);
374
+ req.end();
375
+ });
376
+ console.log(' Notification sent to daemon: YES');
377
+ console.log(' Check Telegram — you should see a test idle notification');
378
+ } catch (err) {
379
+ console.log(` Notification FAILED: ${err.message}`);
380
+ }
381
+ }
382
+
383
+ console.log(`\n${ok ? 'All checks passed.' : 'Some checks FAILED — fix the issues above.'}\n`);
384
+ });
385
+
252
386
  program
253
387
  .command('uninstall')
254
388
  .description('Remove hooks from ~/.claude/settings.json')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-tg",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Control Claude Code from Telegram — approve permissions, answer questions, reply to idle sessions, send files, all from your phone",
5
5
  "bin": {
6
6
  "claude-tg": "./bin/claude-tg.js"
package/src/daemon.js CHANGED
@@ -938,6 +938,20 @@ function startBot() {
938
938
  }
939
939
  targetSessionId = mapping.sessionId;
940
940
  }
941
+
942
+ // Fallback: parse session number from the replied-to message text (survives daemon restarts)
943
+ if (!targetSessionId && ctx.message.reply_to_message?.text) {
944
+ const match = ctx.message.reply_to_message.text.match(/#(\d+)\s/);
945
+ if (match) {
946
+ const num = parseInt(match[1]);
947
+ for (const [sid] of sessions) {
948
+ if (getSessionLabel(sid) === num) {
949
+ targetSessionId = sid;
950
+ break;
951
+ }
952
+ }
953
+ }
954
+ }
941
955
  }
942
956
 
943
957
  // If no reply-to, try auto-routing