+
+
+
+
+
+ |
+ |
+ |
+ claude-code-remote@{{project}} - Waiting for Input |
+
+
+
-
-
- Project: {{projectDir}}
- Time: {{timestamp}}
- Status: {{type}}
-
-
-
-
-
⏳ Waiting for Processing
-
{{message}}
-
-
-
-
💬 Please Provide Guidance
-
- Claude needs your further guidance. Please reply to this email to tell Claude what to do next.
-
-
-
-
-
Session ID: {{sessionId}}
-
🔒 Security note: Please do not forward this email, session will automatically expire after 24 hours
-
📧 This is an automated email from Claude-Code-Remote
+
+
+
+
+
$ claude-code status
+
+ PROJECT: {{projectDir}}
+ SESSION: #{{token}}
+ STATUS: ⏳ Waiting for input
+ TIME: {{timestamp}}
+
+
+
+
+
+
$ claude-code wait
+
+ [WAITING] Claude needs your input to continue...
+
+
+ {{message}}
+
+
+
+
+
+
$ claude-code help --respond
+
+
→ ACTION REQUIRED:
+
+ Claude is waiting for your guidance.
+ Reply to this email with your instructions to continue.
+
+
+
+
+
+
+
$ echo $SESSION_INFO
+
+ SESSION_ID={{sessionId}}
+ EXPIRES_IN=24h
+ SECURITY=Do not forward this email
+ POWERED_BY=Claude-Code-Remote
+
+
diff --git a/src/data/processed-messages.json b/src/data/processed-messages.json
index 1eccd07..02ff827 100644
--- a/src/data/processed-messages.json
+++ b/src/data/processed-messages.json
@@ -1,38 +1,42 @@
[
{
"id": 1312,
- "timestamp": 1753632056082
+ "timestamp": 1754021490457
},
{
"id": 1315,
- "timestamp": 1753632056082
+ "timestamp": 1754021490457
},
{
"id": 1310,
- "timestamp": 1753632056082
+ "timestamp": 1754021490457
},
{
"id": 1323,
- "timestamp": 1753632056082
+ "timestamp": 1754021490457
},
{
"id": 1331,
- "timestamp": 1753632056082
+ "timestamp": 1754021490457
},
{
"id": 1334,
- "timestamp": 1753632056082
+ "timestamp": 1754021490457
},
{
"id": 1342,
- "timestamp": 1753632056082
+ "timestamp": 1754021490457
},
{
"id": 1346,
- "timestamp": 1753632056082
+ "timestamp": 1754021490457
},
{
"id": 1348,
- "timestamp": 1753632056082
+ "timestamp": 1754021490457
+ },
+ {
+ "id": 180,
+ "timestamp": 1754021490457
}
]
\ No newline at end of file
diff --git a/src/data/sent-messages.json b/src/data/sent-messages.json
new file mode 100644
index 0000000..5099b92
--- /dev/null
+++ b/src/data/sent-messages.json
@@ -0,0 +1,46 @@
+{
+ "messages": [
+ {
+ "messageId": "<52d15aa1-d5a4-4d7d-8f01-4752d7d5fc6f-1754021037319@claude-code-remote>",
+ "sessionId": "52d15aa1-d5a4-4d7d-8f01-4752d7d5fc6f",
+ "token": "49WUF9NS",
+ "type": "notification",
+ "sentAt": "2025-08-01T04:03:59.850Z"
+ },
+ {
+ "messageId": "
",
+ "sessionId": "eba8744e-8cc1-4fad-9dc8-69d558c51cca",
+ "token": "N9PHUN4Q",
+ "type": "notification",
+ "sentAt": "2025-08-01T04:06:52.776Z"
+ },
+ {
+ "messageId": "<859daa99-1ea9-4c40-aa68-c3967a0d7e4e-1754021233658@claude-code-remote>",
+ "sessionId": "859daa99-1ea9-4c40-aa68-c3967a0d7e4e",
+ "token": "GXWFSL3S",
+ "type": "notification",
+ "sentAt": "2025-08-01T04:07:15.556Z"
+ },
+ {
+ "messageId": "",
+ "sessionId": "a1ed6757-6782-4b22-a486-aab5a9d60a3c",
+ "token": "6EZXA6IN",
+ "type": "notification",
+ "sentAt": "2025-08-01T04:07:49.959Z"
+ },
+ {
+ "messageId": "<2122d57c-8434-44f0-b4e6-7eafb40ed49d-1754021285815@claude-code-remote>",
+ "sessionId": "2122d57c-8434-44f0-b4e6-7eafb40ed49d",
+ "token": "ZQY1UOIJ",
+ "type": "notification",
+ "sentAt": "2025-08-01T04:08:07.833Z"
+ },
+ {
+ "messageId": "<2b30b1f7-b9c3-4cb4-b889-11c58009bd07-1754021533703@claude-code-remote>",
+ "sessionId": "2b30b1f7-b9c3-4cb4-b889-11c58009bd07",
+ "token": "L4KQ8DVJ",
+ "type": "notification",
+ "sentAt": "2025-08-01T04:12:15.795Z"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/data/session-map.json b/src/data/session-map.json
index f1ee324..2b79bdb 100644
--- a/src/data/session-map.json
+++ b/src/data/session-map.json
@@ -529,5 +529,86 @@
"sessionId": "4e67ac76-5c0a-4229-b3cd-c4ff865c9df3",
"tmuxSession": "video",
"description": "completed - Claude-Code-Remote"
+ },
+ "3E0T4KHA": {
+ "type": "pty",
+ "createdAt": 1754020190,
+ "expiresAt": 1754106590,
+ "cwd": "/Users/vaclis./Documents/project/Claude-Code-Remote",
+ "sessionId": "1ce6c5e0-4151-4d51-9472-f481ed23f023",
+ "tmuxSession": "WavJaby",
+ "description": "completed - Claude-Code-Remote"
+ },
+ "8BIFRACK": {
+ "type": "pty",
+ "createdAt": 1754020301,
+ "expiresAt": 1754106701,
+ "cwd": "/Users/vaclis./Documents/project/ReThreads",
+ "sessionId": "0fd97a36-da77-4c9b-917f-6963c0373458",
+ "tmuxSession": "my-project",
+ "description": "completed - ReThreads"
+ },
+ "OG1SS2R9": {
+ "type": "pty",
+ "createdAt": 1754020306,
+ "expiresAt": 1754106706,
+ "cwd": "/Users/vaclis./Documents/project/Claude-Code-Remote",
+ "sessionId": "43b979a7-9039-4d0f-8c09-b86365ef0e61",
+ "tmuxSession": "WavJaby",
+ "description": "completed - Claude-Code-Remote"
+ },
+ "49WUF9NS": {
+ "type": "pty",
+ "createdAt": 1754021037,
+ "expiresAt": 1754107437,
+ "cwd": "/Users/vaclis./Documents/project/Claude-Code-Remote",
+ "sessionId": "52d15aa1-d5a4-4d7d-8f01-4752d7d5fc6f",
+ "tmuxSession": "WavJaby",
+ "description": "completed - Claude-Code-Remote"
+ },
+ "N9PHUN4Q": {
+ "type": "pty",
+ "createdAt": 1754021210,
+ "expiresAt": 1754107610,
+ "cwd": "/Users/vaclis./Documents/project/Claude-Code-Remote",
+ "sessionId": "eba8744e-8cc1-4fad-9dc8-69d558c51cca",
+ "tmuxSession": "test-session",
+ "description": "completed - Claude-Code-Remote-Test"
+ },
+ "GXWFSL3S": {
+ "type": "pty",
+ "createdAt": 1754021233,
+ "expiresAt": 1754107633,
+ "cwd": "/Users/vaclis./Documents/project/Claude-Code-Remote",
+ "sessionId": "859daa99-1ea9-4c40-aa68-c3967a0d7e4e",
+ "tmuxSession": "WavJaby",
+ "description": "completed - Claude-Code-Remote"
+ },
+ "6EZXA6IN": {
+ "type": "pty",
+ "createdAt": 1754021267,
+ "expiresAt": 1754107667,
+ "cwd": "/Users/vaclis./Documents/project/Claude-Code-Remote",
+ "sessionId": "a1ed6757-6782-4b22-a486-aab5a9d60a3c",
+ "tmuxSession": "test-session",
+ "description": "completed - Claude-Code-Remote-Test"
+ },
+ "ZQY1UOIJ": {
+ "type": "pty",
+ "createdAt": 1754021285,
+ "expiresAt": 1754107685,
+ "cwd": "/Users/vaclis./Documents/project/Claude-Code-Remote",
+ "sessionId": "2122d57c-8434-44f0-b4e6-7eafb40ed49d",
+ "tmuxSession": "WavJaby",
+ "description": "completed - Claude-Code-Remote"
+ },
+ "L4KQ8DVJ": {
+ "type": "pty",
+ "createdAt": 1754021533,
+ "expiresAt": 1754107933,
+ "cwd": "/Users/vaclis./Documents/project/Claude-Code-Remote",
+ "sessionId": "2b30b1f7-b9c3-4cb4-b889-11c58009bd07",
+ "tmuxSession": "test-session",
+ "description": "completed - Claude-Code-Remote-Test"
}
}
\ No newline at end of file
diff --git a/src/utils/tmux-monitor.js b/src/utils/tmux-monitor.js
index dc0de39..73ba423 100644
--- a/src/utils/tmux-monitor.js
+++ b/src/utils/tmux-monitor.js
@@ -61,7 +61,7 @@ class TmuxMonitor {
* @param {number} lines - Number of lines to retrieve
* @returns {Object} - { userQuestion, claudeResponse }
*/
- getRecentConversation(sessionName, lines = 50) {
+ getRecentConversation(sessionName, lines = 200) {
try {
const captureFile = path.join(this.captureDir, `${sessionName}.log`);
@@ -87,7 +87,7 @@ class TmuxMonitor {
* @param {string} sessionName - The tmux session name
* @param {number} lines - Number of lines to retrieve
*/
- getFromTmuxBuffer(sessionName, lines = 50) {
+ getFromTmuxBuffer(sessionName, lines = 200) {
try {
// Capture the pane contents
const buffer = execSync(`tmux capture-pane -t ${sessionName} -p -S -${lines}`, {
@@ -150,17 +150,18 @@ class TmuxMonitor {
// Join response lines and clean up
claudeResponse = responseLines.join('\n').trim();
- // Remove box characters and clean up formatting
+ // Remove box characters but preserve formatting
claudeResponse = claudeResponse
.replace(/[╭╰│]/g, '')
.replace(/^\s*│\s*/gm, '')
- .replace(/\s+/g, ' ')
+ // Don't collapse multiple spaces - preserve code formatting
+ // .replace(/\s+/g, ' ')
.trim();
- // Limit response length
- if (claudeResponse.length > 500) {
- claudeResponse = claudeResponse.substring(0, 497) + '...';
- }
+ // 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) {
diff --git a/test-long-email.js b/test-long-email.js
new file mode 100755
index 0000000..1c85d64
--- /dev/null
+++ b/test-long-email.js
@@ -0,0 +1,142 @@
+#!/usr/bin/env node
+
+/**
+ * Test script for long email content
+ * Tests the new terminal-style email template with long Claude responses
+ */
+
+const path = require('path');
+require('dotenv').config({ path: path.join(__dirname, '.env') });
+
+const EmailChannel = require('./src/channels/email/smtp');
+const ConfigManager = require('./src/core/config');
+
+async function testLongEmail() {
+ console.log('Testing long email content...\n');
+
+ // Load config
+ const configManager = new ConfigManager();
+ configManager.load();
+ const emailConfig = configManager.getChannel('email');
+
+ if (!emailConfig || !emailConfig.enabled) {
+ console.error('❌ Email channel not configured or disabled');
+ console.log('Please configure email in config/channels.json first');
+ process.exit(1);
+ }
+
+ // Create email channel
+ const email = new EmailChannel(emailConfig.config);
+
+ // Create a test notification with very long content
+ const longCodeExample = `
+function processData(inputArray) {
+ // This is a sample function with detailed implementation
+ const results = [];
+
+ for (let i = 0; i < inputArray.length; i++) {
+ const item = inputArray[i];
+
+ // Validate input
+ if (!item || typeof item !== 'object') {
+ console.warn(\`Invalid item at index \${i}\`);
+ continue;
+ }
+
+ // Process each item
+ const processed = {
+ id: item.id || generateId(),
+ name: item.name?.trim() || 'Unknown',
+ timestamp: new Date().toISOString(),
+ data: {
+ original: item,
+ processed: true,
+ metadata: {
+ source: 'test-system',
+ version: '1.0.0',
+ processingTime: Date.now()
+ }
+ }
+ };
+
+ // Apply transformations
+ if (item.transform) {
+ processed.data.transformed = applyTransform(item.transform, item);
+ }
+
+ results.push(processed);
+ }
+
+ return results;
+}
+
+// Helper functions
+function generateId() {
+ return 'id_' + Math.random().toString(36).substr(2, 9);
+}
+
+function applyTransform(transformType, data) {
+ switch (transformType) {
+ case 'uppercase':
+ return JSON.stringify(data).toUpperCase();
+ case 'reverse':
+ return JSON.stringify(data).split('').reverse().join('');
+ default:
+ return data;
+ }
+}
+`;
+
+ const testNotification = {
+ type: 'completed',
+ title: 'Test Long Content',
+ message: 'Testing terminal-style email with long Claude response',
+ project: 'Claude-Code-Remote-Test',
+ metadata: {
+ userQuestion: 'Please help me implement a data processing function with error handling, validation, and transformation features',
+ claudeResponse: `I'll help you implement a comprehensive data processing function. Here's a complete implementation with all the features you requested:
+
+${longCodeExample}
+
+This implementation includes:
+
+1. **Input Validation**: The function checks each item to ensure it's a valid object before processing.
+
+2. **Error Handling**: Uses try-catch blocks and console warnings for invalid items.
+
+3. **Data Transformation**: Supports different transformation types through the \`applyTransform\` function.
+
+4. **Metadata Tracking**: Each processed item includes metadata about when and how it was processed.
+
+5. **ID Generation**: Automatically generates unique IDs for items that don't have one.
+
+Additional features you might want to consider:
+
+- **Async Processing**: For handling large datasets or async transformations
+- **Batch Processing**: Process items in chunks to avoid memory issues
+- **Progress Tracking**: Add callbacks or events to track processing progress
+- **Custom Validators**: Allow custom validation functions to be passed in
+- **Error Recovery**: Implement retry logic for failed items
+
+The function is designed to be extensible and maintainable. You can easily add new transformation types or modify the processing logic as needed.`,
+ tmuxSession: 'test-session'
+ }
+ };
+
+ try {
+ console.log('Sending test email with long content...');
+ const result = await email._sendImpl(testNotification);
+
+ if (result) {
+ console.log('✅ Email sent successfully!');
+ console.log('Check your inbox for the terminal-style email');
+ } else {
+ console.log('❌ Failed to send email');
+ }
+ } catch (error) {
+ console.error('❌ Error:', error.message);
+ }
+}
+
+// Run test
+testLongEmail();
\ No newline at end of file