From f608aed3c2ff8b933492401e4e91a57de3796e38 Mon Sep 17 00:00:00 2001 From: lsamc <2322176165@qq.com> Date: Thu, 4 Sep 2025 21:02:19 +0800 Subject: [PATCH] fixed telegram issues. --- config/channels.json | 31 +++- smart-monitor.js | 4 +- src/data/session-map.json | 279 +++++++++++++++++++++++++++++++ src/utils/controller-injector.js | 4 +- src/utils/tmux-monitor.js | 136 ++++++++------- test-extraction-fix.js | 22 +++ test-injection.js | 2 +- 7 files changed, 407 insertions(+), 71 deletions(-) create mode 100644 test-extraction-fix.js diff --git a/config/channels.json b/config/channels.json index f5bde88..214c04a 100644 --- a/config/channels.json +++ b/config/channels.json @@ -6,7 +6,32 @@ }, "email": { "type": "email", - "enabled": true + "enabled": true, + "config": { + "smtp": { + "host": "smtp.gmail.com", + "port": 465, + "secure": true, + "auth": { + "user": "2322176165lsa@gmail.com", + "pass": "frkxntpirpfrhqre" + } + }, + "imap": { + "host": "imap.gmail.com", + "port": 993, + "secure": true, + "auth": { + "user": "2322176165lsa@gmail.com", + "pass": "frkxntpirpfrhqre" + } + }, + "from": "2322176165lsa@gmail.com", + "to": "2322176165@qq.com", + "template": { + "checkInterval": 20 + } + } }, "discord": { "type": "chat", @@ -24,8 +49,8 @@ "botToken": "", "chatId": "", "groupId": "", - "whitelist": [], - "forceIPv4": false + "forceIPv4": false, + "whitelist": [] } }, "whatsapp": { diff --git a/smart-monitor.js b/smart-monitor.js index 31c5400..3513f72 100644 --- a/smart-monitor.js +++ b/smart-monitor.js @@ -20,7 +20,7 @@ const TelegramChannel = require('./src/channels/telegram/telegram'); class SmartMonitor { constructor() { - this.sessionName = process.env.TMUX_SESSION || 'claude-real'; + this.sessionName = process.env.TMUX_SESSION || 'claude-session'; this.lastOutput = ''; this.processedResponses = new Set(); // 記錄已處理的回應 this.checkInterval = 1000; // Check every 1 second @@ -290,4 +290,4 @@ process.on('SIGTERM', () => { }); // Start monitoring -monitor.start(); \ No newline at end of file +monitor.start(); diff --git a/src/data/session-map.json b/src/data/session-map.json index 2ca03b0..f224839 100644 --- a/src/data/session-map.json +++ b/src/data/session-map.json @@ -538,5 +538,284 @@ "sessionId": "10cd6e52-91a8-476a-af0a-1fe2c2929ab6", "tmuxSession": "claude-hook-test", "description": "completed - Claude-Code-Remote" + }, + "M4769IDR": { + "type": "pty", + "createdAt": 1756981849, + "expiresAt": 1757068249, + "cwd": "/home/lsamc/.local/src/Claude-Code-Remote", + "sessionId": "56e2eb19-9b1e-4b49-b3b3-f99149a9e244", + "tmuxSession": "test-session", + "description": "completed - Claude-Code-Remote-Test" + }, + "UG0HP8QJ": { + "type": "pty", + "createdAt": 1756982044, + "expiresAt": 1757068444, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "925e4a47-174f-4b48-a666-12ca707c18d1", + "tmuxSession": "claude-code-remote", + "description": "completed - ecllipse" + }, + "OGKAMMS0": { + "type": "pty", + "createdAt": 1756982145, + "expiresAt": 1757068545, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "2cf5a9ef-eb34-4cf0-8118-a2471f557320", + "tmuxSession": "0", + "description": "completed - ecllipse" + }, + "IJYBTZ1M": { + "type": "pty", + "createdAt": 1756982185, + "expiresAt": 1757068585, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "6474c5f8-4234-417b-8149-060e6a091035", + "tmuxSession": "0", + "description": "completed - ecllipse" + }, + "PQECZXRL": { + "type": "pty", + "createdAt": 1756983489, + "expiresAt": 1757069889, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "1b68620f-7199-40fe-b6fa-e57b3f36e346", + "tmuxSession": "claude-hook-test", + "description": "completed - ecllipse" + }, + "BTEAWB0A": { + "type": "pty", + "createdAt": 1756983654, + "expiresAt": 1757070054, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "6a21e7b9-f95b-419f-8267-c7ab939ebb64", + "tmuxSession": "claude-session", + "description": "completed - ecllipse" + }, + "W2JST4BL": { + "type": "pty", + "createdAt": 1756984158, + "expiresAt": 1757070558, + "cwd": "/home/lsamc/.local/src/Claude-Code-Remote", + "sessionId": "70221d98-958e-4084-91ca-971127620375", + "tmuxSession": "claude-session", + "description": "completed - Claude-Code-Remote" + }, + "7YGTUNQI": { + "type": "pty", + "createdAt": 1756984735, + "expiresAt": 1757071135, + "cwd": "/home/lsamc/.local/src/Claude-Code-Remote", + "sessionId": "b21eecfb-5566-4329-b7f6-e9ee5b8c5b87", + "tmuxSession": "claude-session", + "description": "completed - Claude-Code-Remote" + }, + "JN9R6ORI": { + "type": "pty", + "createdAt": 1756984808, + "expiresAt": 1757071208, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "0eb2f38b-b5f3-4cd2-a096-fdbb50f6b4a3", + "tmuxSession": "claude-session", + "description": "completed - ecllipse" + }, + "G15979CU": { + "type": "pty", + "createdAt": 1756984876, + "expiresAt": 1757071276, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "05abff6e-1f11-4662-bede-9cc40dba095b", + "tmuxSession": "claude-session", + "description": "completed - ecllipse" + }, + "XO7ZYYCD": { + "type": "pty", + "createdAt": 1756985082, + "expiresAt": 1757071482, + "cwd": "/home/lsamc/.local/src/Claude-Code-Remote", + "sessionId": "650de5dc-e5a5-406c-9ff0-e6b658b7639d", + "tmuxSession": "claude-session", + "description": "completed - Claude-Code-Remote" + }, + "297WCHFD": { + "type": "pty", + "createdAt": 1756985194, + "expiresAt": 1757071594, + "cwd": "/home/lsamc/.local/src/Claude-Code-Remote", + "sessionId": "e3cdc11d-2aef-4a0e-b8cc-0112889498a9", + "tmuxSession": "claude-session", + "description": "completed - Claude-Code-Remote" + }, + "TUBTGR8Z": { + "type": "pty", + "createdAt": 1756985273, + "expiresAt": 1757071673, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "e7ca8ded-58ed-4a39-b676-d8fedef37e74", + "tmuxSession": "claude-session", + "description": "completed - ecllipse" + }, + "5YCUAO3D": { + "type": "pty", + "createdAt": 1756985483, + "expiresAt": 1757071883, + "cwd": "/home/lsamc/.local/src/Claude-Code-Remote", + "sessionId": "9c7ab226-b2b3-4a52-b884-37ba050e71ac", + "tmuxSession": "claude-session", + "description": "completed - Claude-Code-Remote" + }, + "2VCH8RD0": { + "type": "pty", + "createdAt": 1756986019, + "expiresAt": 1757072419, + "cwd": "/home/lsamc/.local/src/Claude-Code-Remote", + "sessionId": "d5eebf40-762c-42f0-9a9e-6f38eb1e131f", + "tmuxSession": "claude-session", + "description": "completed - Claude-Code-Remote" + }, + "3WMICU56": { + "type": "pty", + "createdAt": 1756987089, + "expiresAt": 1757073489, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "2a135963-ca49-425f-aa41-433154c4f70d", + "tmuxSession": "claude-session", + "description": "completed - ecllipse" + }, + "05BC2ZC2": { + "type": "pty", + "createdAt": 1756987248, + "expiresAt": 1757073648, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "84037cac-6d82-454e-ae12-66b59baf9d8f", + "tmuxSession": "claude-session", + "description": "completed - ecllipse" + }, + "M9SZFQ16": { + "type": "pty", + "createdAt": 1756987334, + "expiresAt": 1757073734, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "562fcfeb-8b0d-4ae2-87c5-6a6fafe7c53f", + "tmuxSession": "claude-session", + "description": "completed - ecllipse" + }, + "6G3CXZ8Y": { + "type": "pty", + "createdAt": 1756987424, + "expiresAt": 1757073824, + "cwd": "/home/lsamc/.local/src/Claude-Code-Remote", + "sessionId": "3cf3c431-0aed-4097-a594-47144bf08a62", + "tmuxSession": "claude-session", + "description": "completed - Claude-Code-Remote" + }, + "I5LFQWV0": { + "type": "pty", + "createdAt": 1756987485, + "expiresAt": 1757073885, + "cwd": "/home/lsamc/.local/src/Claude-Code-Remote", + "sessionId": "ba716dd3-e2c2-4886-9e42-17c1b8d060ae", + "tmuxSession": "claude-session", + "description": "completed - Claude-Code-Remote" + }, + "JLROEO9E": { + "type": "pty", + "createdAt": 1756987634, + "expiresAt": 1757074034, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "3db165f7-e6ea-4d47-82d0-c11f8e32127e", + "tmuxSession": "claude-session", + "description": "completed - ecllipse" + }, + "K38PPZ6B": { + "type": "pty", + "createdAt": 1756988634, + "expiresAt": 1757075034, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "379f517e-b533-47b8-a9f4-134565e03e6a", + "tmuxSession": "claude-session", + "description": "completed - ecllipse" + }, + "JFRFCCUN": { + "type": "pty", + "createdAt": 1756990126, + "expiresAt": 1757076526, + "cwd": "/home/lsamc/.local/src/Claude-Code-Remote", + "sessionId": "868c8e44-ed03-40bd-bfa1-05c62b852e52", + "tmuxSession": "claude-session", + "description": "completed - Claude-Code-Remote" + }, + "TDO4OJHV": { + "type": "pty", + "createdAt": 1756990188, + "expiresAt": 1757076588, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "10dfce8a-7602-4f0d-8c4f-d7292ba769cf", + "tmuxSession": "claude-session", + "description": "completed - ecllipse" + }, + "L1WV5FAM": { + "type": "pty", + "createdAt": 1756990266, + "expiresAt": 1757076666, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "6f1193e8-da56-4dde-b898-e7e756a86b51", + "tmuxSession": "claude-session", + "description": "completed - ecllipse" + }, + "U9ERQKL6": { + "type": "pty", + "createdAt": 1756990314, + "expiresAt": 1757076714, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "7e3faaa7-73a4-4cfc-a9b6-34994c7f847f", + "tmuxSession": "claude-session", + "description": "completed - ecllipse" + }, + "O6D5M0TE": { + "type": "pty", + "createdAt": 1756990348, + "expiresAt": 1757076748, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "e31e9b64-a65b-4336-ad80-d465482842a6", + "tmuxSession": "claude-session", + "description": "completed - ecllipse" + }, + "A08Q192M": { + "type": "pty", + "createdAt": 1756990442, + "expiresAt": 1757076842, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "51d7c124-9978-4598-ab91-988fd489918f", + "tmuxSession": "claude-session", + "description": "completed - ecllipse" + }, + "WANYF73Z": { + "type": "pty", + "createdAt": 1756990505, + "expiresAt": 1757076905, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "281cf8ad-6e3b-4add-ba99-81d781b5da94", + "tmuxSession": "claude-session", + "description": "completed - ecllipse" + }, + "X6ILHKQN": { + "type": "pty", + "createdAt": 1756990584, + "expiresAt": 1757076984, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "0e4ac6fa-8808-4a68-9ebe-b97537c596a9", + "tmuxSession": "claude-session", + "description": "completed - ecllipse" + }, + "JSJBJIU3": { + "type": "pty", + "createdAt": 1756990621, + "expiresAt": 1757077021, + "cwd": "/home/lsamc/develop/ecllipse", + "sessionId": "dbd1f477-0550-463b-b147-fcdf78720177", + "tmuxSession": "claude-session", + "description": "completed - ecllipse" } } \ No newline at end of file diff --git a/src/utils/controller-injector.js b/src/utils/controller-injector.js index f49efd1..6a2d494 100644 --- a/src/utils/controller-injector.js +++ b/src/utils/controller-injector.js @@ -11,7 +11,7 @@ const Logger = require('../core/logger'); class ControllerInjector { constructor(config = {}) { this.logger = new Logger('ControllerInjector'); - this.mode = config.mode || process.env.INJECTION_MODE || 'pty'; + this.mode = config.mode || process.env.INJECTION_MODE || 'tmux'; this.defaultSession = config.defaultSession || process.env.TMUX_SESSION || 'claude-code'; } @@ -107,4 +107,4 @@ class ControllerInjector { } } -module.exports = ControllerInjector; \ No newline at end of file +module.exports = ControllerInjector; diff --git a/src/utils/tmux-monitor.js b/src/utils/tmux-monitor.js index 07f6f26..3b2056b 100644 --- a/src/utils/tmux-monitor.js +++ b/src/utils/tmux-monitor.js @@ -609,92 +609,102 @@ class TmuxMonitor extends EventEmitter { extractConversation(text, sessionName = null) { const lines = text.split('\n'); + console.log(`[DEBUG] extractConversation called for session: ${sessionName}`); + console.log(`[DEBUG] Total lines in buffer: ${lines.length}`); + console.log(`[DEBUG] Last 5 lines:`, lines.slice(-5)); + let userQuestion = ''; let claudeResponse = ''; let responseLines = []; - let inResponse = false; - - // Find the most recent user question and Claude response - let inUserInput = false; - let userQuestionLines = []; + let lastUserIndex = -1; - for (let i = 0; i < lines.length; i++) { + // First pass: Find the most recent user input + for (let i = lines.length - 1; i >= 0; i--) { const line = lines[i].trim(); - - // Detect user input (line starting with "> " followed by content) if (line.startsWith('> ') && line.length > 2) { - userQuestionLines = [line.substring(2).trim()]; - inUserInput = true; - inResponse = false; // Reset response capture - responseLines = []; // Clear previous response + lastUserIndex = i; + userQuestion = line.substring(2).trim(); + console.log(`[DEBUG] Found user question at line ${i}: ${userQuestion}`); + break; + } + } + + // If we found a user question, look for the response after it + if (lastUserIndex >= 0) { + let foundResponseStart = false; + + for (let i = lastUserIndex + 1; i < lines.length; i++) { + const line = lines[i].trim(); - // Record user input timestamp if session name provided - if (sessionName) { - this.traceCapture.recordUserInput(sessionName); + // Skip empty lines and system lines + if (!line || + line.includes('? for shortcuts') || + line.match(/^[╭╰│─]+$/) || + line.startsWith('$') || + line.startsWith('#') || + line.startsWith('[')) { + continue; } - continue; - } - - // Continue capturing multi-line user input - if (inUserInput && !line.startsWith('⏺') && line.length > 0) { - userQuestionLines.push(line); - continue; - } - - // End of user input - if (inUserInput && (line.startsWith('⏺') || line.length === 0)) { - inUserInput = false; - userQuestion = userQuestionLines.join(' '); - } - - // Detect Claude response (line starting with "⏺ " or other response indicators) - if (line.startsWith('⏺ ') || - (inResponse && line.length > 0 && - !line.startsWith('╭') && !line.startsWith('│') && !line.startsWith('╰') && - !line.startsWith('> ') && !line.includes('? for shortcuts'))) { + // Multiple patterns to detect Claude responses + const isClaudeResponse = + line.startsWith('⏺ ') || // Traditional marker + line.startsWith('I\'ll ') || // Common Claude opening + line.startsWith('I can ') || + line.startsWith('Let me ') || + line.startsWith('Here') || + line.startsWith('Sure') || + line.startsWith('Yes') || + line.startsWith('No') || + line.includes('```') || // Code blocks + /^[A-Z][a-z]/.test(line); // Sentences starting with capital letter - if (line.startsWith('⏺ ')) { - inResponse = true; - responseLines = [line.substring(2).trim()]; // Remove "⏺ " prefix - } else if (inResponse) { + if (isClaudeResponse && !foundResponseStart) { + foundResponseStart = true; + responseLines = [line.startsWith('⏺ ') ? line.substring(2).trim() : line]; + console.log(`[DEBUG] Found response start at line ${i}: ${line}`); + } else if (foundResponseStart) { + // Stop if we hit another user input or prompt + if (line.startsWith('> ') || line.includes('│ > │') || line.startsWith('╭')) { + console.log(`[DEBUG] Stopping response collection at line ${i}: ${line}`); + break; + } responseLines.push(line); } } + } + + // Fallback: Look for any Claude response pattern in the last 20 lines + if (responseLines.length === 0) { + console.log(`[DEBUG] No response found after user input, trying fallback method`); + const recentLines = lines.slice(-20); - // Stop capturing response when we hit another prompt or box boundary - if (inResponse && (line.startsWith('╭') || line.startsWith('│ > ') || line.includes('? for shortcuts'))) { - inResponse = false; + for (let i = 0; i < recentLines.length; i++) { + const line = recentLines[i].trim(); + + if (line.startsWith('⏺ ') || + (line.length > 10 && !line.startsWith('> ') && !line.includes('? for shortcuts'))) { + responseLines.push(line.startsWith('⏺ ') ? line.substring(2).trim() : line); + console.log(`[DEBUG] Fallback found response line: ${line}`); + } } } - + // Join response lines and clean up claudeResponse = responseLines.join('\n').trim(); // Remove box characters but preserve formatting claudeResponse = claudeResponse - .replace(/[╭╰│]/g, '') + .replace(/[╭╰]/g, '') .replace(/^\s*│\s*/gm, '') - // Don't collapse multiple spaces - preserve code formatting - // .replace(/\s+/g, ' ') + .replace(/│\s*$/gm, '') .trim(); - - // Don't limit response length - we want the full response - // if (claudeResponse.length > 500) { - // claudeResponse = claudeResponse.substring(0, 497) + '...'; - // } - - // If we didn't find a question in the standard format, look for any recent text input - if (!userQuestion) { - for (let i = lines.length - 1; i >= 0; i--) { - const line = lines[i].trim(); - if (line.startsWith('> ') && line.length > 2) { - userQuestion = line.substring(2).trim(); - break; - } - } - } - + + console.log(`[DEBUG] Final extraction result:`); + console.log(`[DEBUG] User Question: "${userQuestion}"`); + console.log(`[DEBUG] Claude Response: "${claudeResponse.substring(0, 100)}${claudeResponse.length > 100 ? '...' : ''}"`); + console.log(`[DEBUG] Response lines count: ${responseLines.length}`); + return { userQuestion: userQuestion || 'No user input', claudeResponse: claudeResponse || 'No Claude response' diff --git a/test-extraction-fix.js b/test-extraction-fix.js new file mode 100644 index 0000000..b881b93 --- /dev/null +++ b/test-extraction-fix.js @@ -0,0 +1,22 @@ +#!/usr/bin/env node + +/** + * Test script for extractConversation function fix + * Tests the improved response detection logic + */ + +const TmuxMonitor = require('./src/utils/tmux-monitor'); + +// Create test tmux buffer content that mimics actual Claude Code output +const testBuffer1 = ` +Welcome to Claude Code +? for shortcuts +─────────────────────────── + +> what does this project do? + +I'll help you understand what this project does. Let me analyze the codebase structure first. + + + +/path/to/file.js \ No newline at end of file diff --git a/test-injection.js b/test-injection.js index b54d135..10aa198 100755 --- a/test-injection.js +++ b/test-injection.js @@ -31,4 +31,4 @@ async function testInjection() { } } -testInjection().catch(console.error); < /dev/null \ No newline at end of file +testInjection().catch(console.error);