diff --git a/README.md b/README.md
index 4be36b3..7a99187 100644
--- a/README.md
+++ b/README.md
@@ -28,9 +28,9 @@ Control [Claude Code](https://claude.ai/code) remotely via email. Start tasks lo
## š
Changelog
### January 2025
-- **2025-01-15**: Implement terminal-style UI for email notifications ([#8](https://github.com/JessyTsui/Claude-Code-Remote/pull/8) by [@vaclisinc](https://github.com/vaclisinc))
-- **2025-01-15**: Fix working directory issue - enable claude-remote to run from any directory ([#7](https://github.com/JessyTsui/Claude-Code-Remote/pull/7) by [@vaclisinc](https://github.com/vaclisinc))
-- **2025-01-14**: Fix self-reply loop issue when using same email for send/receive ([#4](https://github.com/JessyTsui/Claude-Code-Remote/pull/4) by [@vaclisinc](https://github.com/vaclisinc))
+- **2025-08-01**: Implement terminal-style UI for email notifications ([#8](https://github.com/JessyTsui/Claude-Code-Remote/pull/8) by [@vaclisinc](https://github.com/vaclisinc))
+- **2025-08-01**: Fix working directory issue - enable claude-remote to run from any directory ([#7](https://github.com/JessyTsui/Claude-Code-Remote/pull/7) by [@vaclisinc](https://github.com/vaclisinc))
+- **2025-07-31**: Fix self-reply loop issue when using same email for send/receive ([#4](https://github.com/JessyTsui/Claude-Code-Remote/pull/4) by [@vaclisinc](https://github.com/vaclisinc))
### July 2025
- **2025-07-28**: Remove hardcoded values and implement environment-based configuration ([#2](https://github.com/JessyTsui/Claude-Code-Remote/pull/2) by [@kevinsslin](https://github.com/kevinsslin))
@@ -99,6 +99,7 @@ SESSION_MAP_PATH=/your/absolute/path/to/Claude-Code-Remote/src/data/session-map.
```
š **Gmail users**: Create an [App Password](https://myaccount.google.com/security) instead of using your regular password.
+> Note: You may need to enable two-step verification in your google account first before create app password.
### Step 3: Set Up Claude Code Hooks
@@ -137,6 +138,8 @@ Add this configuration (replace `/your/absolute/path/` with your actual path):
}
```
+> **Note**: Subagent notifications are disabled by default. To enable them, set `enableSubagentNotifications: true` in your config. See [Subagent Notifications Guide](./docs/SUBAGENT_NOTIFICATIONS.md) for details.
+
### Step 4: Test Your Setup
```bash
diff --git a/claude-remote.js b/claude-remote.js
index c5bce63..8741f14 100755
--- a/claude-remote.js
+++ b/claude-remote.js
@@ -115,6 +115,62 @@ class ClaudeCodeRemoteCLI {
// Automatically capture current tmux session conversation content
const metadata = await this.captureCurrentConversation();
+
+ // Handle subagent notifications
+ if (type === 'waiting') {
+ const Config = require('./src/core/config');
+ const config = new Config();
+ config.load();
+ const enableSubagentNotifications = config.get('enableSubagentNotifications', false);
+
+ if (!enableSubagentNotifications) {
+ // Instead of skipping, track the subagent activity
+ const SubagentTracker = require('./src/utils/subagent-tracker');
+ const tracker = new SubagentTracker();
+
+ // Use tmux session as the tracking key
+ const trackingKey = metadata.tmuxSession || 'default';
+
+ // Capture more detailed information about the subagent activity
+ const activityDetails = {
+ userQuestion: metadata.userQuestion || 'No question captured',
+ claudeResponse: metadata.claudeResponse || 'No response captured',
+ timestamp: new Date().toISOString(),
+ tmuxSession: metadata.tmuxSession
+ };
+
+ // Don't truncate the response too aggressively
+ if (activityDetails.claudeResponse && activityDetails.claudeResponse.length > 1000) {
+ activityDetails.claudeResponse = activityDetails.claudeResponse.substring(0, 1000) + '...[see full output in tmux]';
+ }
+
+ tracker.addActivity(trackingKey, {
+ type: 'SubagentStop',
+ description: metadata.userQuestion || 'Subagent task',
+ details: activityDetails
+ });
+
+ this.logger.info(`Subagent activity tracked for tmux session: ${trackingKey}`);
+ process.exit(0);
+ }
+ }
+
+ // For completed notifications, include subagent activities
+ if (type === 'completed') {
+ const SubagentTracker = require('./src/utils/subagent-tracker');
+ const tracker = new SubagentTracker();
+ const trackingKey = metadata.tmuxSession || 'default';
+
+ // Get and format subagent activities
+ const subagentSummary = tracker.formatActivitiesForEmail(trackingKey);
+ if (subagentSummary) {
+ metadata.subagentActivities = subagentSummary;
+ this.logger.info('Including subagent activities in completion email');
+
+ // Clear activities after including them
+ tracker.clearActivities(trackingKey);
+ }
+ }
const result = await this.notifier.notify(type, metadata);
diff --git a/config/defaults/config.json b/config/defaults/config.json
index f967e43..91f4e6a 100644
--- a/config/defaults/config.json
+++ b/config/defaults/config.json
@@ -5,6 +5,8 @@
"waiting": "Hero"
},
"enabled": true,
+ "enableSubagentNotifications": false,
+ "subagentActivityDetail": "medium",
"timeout": 5,
"customMessages": {
"completed": null,
diff --git a/src/channels/email/smtp.js b/src/channels/email/smtp.js
index 5d0f1e6..f821b38 100644
--- a/src/channels/email/smtp.js
+++ b/src/channels/email/smtp.js
@@ -24,6 +24,18 @@ class EmailChannel extends NotificationChannel {
this._initializeTransporter();
}
+ _escapeHtml(text) {
+ if (!text) return '';
+ const htmlEntities = {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ "'": '''
+ };
+ return text.replace(/[&<>"']/g, char => htmlEntities[char]);
+ }
+
_ensureDirectories() {
if (!fs.existsSync(this.sessionsDir)) {
fs.mkdirSync(this.sessionsDir, { recursive: true });
@@ -286,7 +298,8 @@ class EmailChannel extends NotificationChannel {
userQuestion: userQuestion || 'No specified task',
claudeResponse: claudeResponse || notification.message,
projectDir: projectDir,
- shortQuestion: shortQuestion || 'No specific question'
+ shortQuestion: shortQuestion || 'No specific question',
+ subagentActivities: notification.metadata?.subagentActivities || ''
};
let subject = enhancedSubject;
@@ -297,7 +310,9 @@ class EmailChannel extends NotificationChannel {
Object.keys(variables).forEach(key => {
const placeholder = new RegExp(`{{${key}}}`, 'g');
subject = subject.replace(placeholder, variables[key]);
- html = html.replace(placeholder, variables[key]);
+ // Escape HTML entities for HTML content
+ html = html.replace(placeholder, this._escapeHtml(variables[key]));
+ // No escaping needed for plain text
text = text.replace(placeholder, variables[key]);
});
@@ -356,6 +371,8 @@ class EmailChannel extends NotificationChannel {
+ {{subagentActivities}}
+
$ claude-code help --continue
@@ -398,6 +415,8 @@ Status: {{type}}
š¤ Claude's Response:
{{claudeResponse}}
+{{subagentActivities}}
+
How to Continue Conversation:
To continue conversation with Claude Code, please reply to this email directly and enter your instructions in the email body.
diff --git a/src/data/sent-messages.json b/src/data/sent-messages.json
index 077538b..b379c13 100644
--- a/src/data/sent-messages.json
+++ b/src/data/sent-messages.json
@@ -1,137 +1,3 @@
{
- "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"
- },
- {
- "messageId": "",
- "sessionId": "e3392712-9a5b-4c96-a23c-5d97c226b415",
- "token": "7ZFMSK5P",
- "type": "notification",
- "sentAt": "2025-08-01T04:30:41.978Z"
- },
- {
- "messageId": "<5d19da23-5c9d-4855-824e-fbd09a0d986c-1754022731688@claude-code-remote>",
- "sessionId": "5d19da23-5c9d-4855-824e-fbd09a0d986c",
- "token": "PJOE746Q",
- "type": "notification",
- "sentAt": "2025-08-01T04:32:13.100Z"
- },
- {
- "messageId": "",
- "sessionId": "ed814c4b-0b97-4e10-8ad1-dae1a7cb7ef9",
- "token": "C9I24JHD",
- "type": "notification",
- "sentAt": "2025-08-01T04:35:28.987Z"
- },
- {
- "messageId": "<46ae2185-2f70-4355-a3b8-9fc04fa01181-1754023256348@claude-code-remote>",
- "sessionId": "46ae2185-2f70-4355-a3b8-9fc04fa01181",
- "token": "GGBKJ2DV",
- "type": "notification",
- "sentAt": "2025-08-01T04:40:58.066Z"
- },
- {
- "messageId": "<49c51c77-8ecc-4a04-a7a8-5955f89411b1-1754023825872@claude-code-remote>",
- "sessionId": "49c51c77-8ecc-4a04-a7a8-5955f89411b1",
- "token": "DQH198YY",
- "type": "notification",
- "sentAt": "2025-08-01T04:50:27.443Z"
- },
- {
- "messageId": "",
- "sessionId": "cc5a1eba-7e04-44e6-919f-0395ddf2ee08",
- "token": "GQE6LLIF",
- "type": "notification",
- "sentAt": "2025-08-01T04:54:16.491Z"
- },
- {
- "messageId": "<63198b90-3b9d-4448-a932-7c39c771554a-1754024273245@claude-code-remote>",
- "sessionId": "63198b90-3b9d-4448-a932-7c39c771554a",
- "token": "WYKEGTXV",
- "type": "notification",
- "sentAt": "2025-08-01T04:57:54.938Z"
- },
- {
- "messageId": "",
- "sessionId": "bfd8b8d0-bcc4-4336-a6eb-8ca3f8b6c96e",
- "token": "ATUBLIN1",
- "type": "notification",
- "sentAt": "2025-08-01T05:19:18.866Z"
- },
- {
- "messageId": "",
- "sessionId": "cdbfc3f9-e27e-47d9-82b9-9058f0180fff",
- "token": "2W24RZTM",
- "type": "notification",
- "sentAt": "2025-08-01T05:20:35.851Z"
- },
- {
- "messageId": "",
- "sessionId": "cf18cb3b-bc72-46ea-985f-2b7f29f0993f",
- "token": "PHAVU604",
- "type": "notification",
- "sentAt": "2025-08-01T05:24:16.539Z"
- },
- {
- "messageId": "<6da5d6f6-7e68-47eb-8676-175d77f0ddbc-1754026029245@claude-code-remote>",
- "sessionId": "6da5d6f6-7e68-47eb-8676-175d77f0ddbc",
- "token": "C2APCY3V",
- "type": "notification",
- "sentAt": "2025-08-01T05:27:10.601Z"
- },
- {
- "messageId": "<9143d717-be05-4869-b40a-2c775addcfc4-1754026119754@claude-code-remote>",
- "sessionId": "9143d717-be05-4869-b40a-2c775addcfc4",
- "token": "N5P4GUG3",
- "type": "notification",
- "sentAt": "2025-08-01T05:28:41.439Z"
- },
- {
- "messageId": "<6fb2932d-d4ac-427b-8b7d-54af44fee1f2-1754026220881@claude-code-remote>",
- "sessionId": "6fb2932d-d4ac-427b-8b7d-54af44fee1f2",
- "token": "CZIKHCFO",
- "type": "notification",
- "sentAt": "2025-08-01T05:30:22.303Z"
- }
- ]
+ "messages": []
}
\ No newline at end of file
diff --git a/src/data/session-map.json b/src/data/session-map.json
index bfe17e4..9e26dfe 100644
--- a/src/data/session-map.json
+++ b/src/data/session-map.json
@@ -1,731 +1 @@
-{
- "7HUMGXOT": {
- "type": "pty",
- "createdAt": 1753601264,
- "expiresAt": 1753687664,
- "cwd": "/Users/jessytsui/dev/TaskPing",
- "sessionId": "3248adc2-eb7b-4eb2-a57c-b9ce320cb4ec",
- "tmuxSession": "hailuo",
- "description": "completed - TaskPing"
- },
- "5CLDW6NQ": {
- "type": "pty",
- "createdAt": 1753602124,
- "expiresAt": 1753688524,
- "cwd": "/Users/jessytsui/dev/TaskPing",
- "sessionId": "c7b6750f-6246-4ed3-bca5-81201ab980ee",
- "tmuxSession": "hailuo",
- "description": "completed - TaskPing"
- },
- "ONY66DAE": {
- "type": "pty",
- "createdAt": 1753604311,
- "expiresAt": 1753690711,
- "cwd": "/Users/jessytsui/dev/TaskPing",
- "sessionId": "2a8622dd-a0e9-4f4d-9cc8-a3bb432e9621",
- "tmuxSession": "hailuo",
- "description": "waiting - TaskPing"
- },
- "QHFI9FIJ": {
- "type": "pty",
- "createdAt": 1753607753,
- "expiresAt": 1753694153,
- "cwd": "/Users/jessytsui/dev/TaskPing",
- "sessionId": "a966681d-5cfd-47b9-bb1b-c7ee9655b97b",
- "tmuxSession": "a-0",
- "description": "waiting - TaskPing"
- },
- "G3QE3STQ": {
- "type": "pty",
- "createdAt": 1753622403,
- "expiresAt": 1753708803,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "7f6e11b3-0ac9-44b1-a75f-d3a15a8ec46e",
- "tmuxSession": "claude-taskping",
- "description": "completed - TaskPing-Test"
- },
- "Z0Q98XCC": {
- "type": "pty",
- "createdAt": 1753624374,
- "expiresAt": 1753710774,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "b2408839-8a64-4a07-8ceb-4a7a82ea5b25",
- "tmuxSession": "claude-taskping",
- "description": "completed - TaskPing-Test"
- },
- "65S5UGHZ": {
- "type": "pty",
- "createdAt": 1753624496,
- "expiresAt": 1753710896,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "117a1097-dd97-41ab-a276-e4820adc8da8",
- "tmuxSession": "claude-taskping",
- "description": "completed - Claude-Code-Remote"
- },
- "N9PPKGTO": {
- "type": "pty",
- "createdAt": 1753624605,
- "expiresAt": 1753711005,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "0caed3af-35ae-4b42-9081-b1a959735bde",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "TEST12345": {
- "type": "pty",
- "createdAt": 1753628000,
- "expiresAt": 1753714400,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "test-session-id",
- "tmuxSession": "test-claude",
- "description": "testing - Test Session"
- },
- "YTGT6F6F": {
- "type": "pty",
- "createdAt": 1753625040,
- "expiresAt": 1753711440,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "e6e973b6-20dd-497f-a988-02482af63336",
- "tmuxSession": "claude-taskping",
- "description": "completed - Claude-Code-Remote"
- },
- "2XQP1N0P": {
- "type": "pty",
- "createdAt": 1753625361,
- "expiresAt": 1753711761,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "0f694f4c-f8a4-476a-946a-3dc057c3bc46",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "GKPSGCBS": {
- "type": "pty",
- "createdAt": 1753625618,
- "expiresAt": 1753712018,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "e844d2ae-9098-4528-9e05-e77904a35be3",
- "tmuxSession": "claude-taskping",
- "description": "completed - Claude-Code-Remote"
- },
- "187JDGZ0": {
- "type": "pty",
- "createdAt": 1753625623,
- "expiresAt": 1753712023,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "633a2687-81e7-456e-9995-3321ce3f3b2b",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "NSYKTAWC": {
- "type": "pty",
- "createdAt": 1753625650,
- "expiresAt": 1753712050,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "b8dac307-8b4b-4286-aa73-324b9b659e60",
- "tmuxSession": "claude-taskping",
- "description": "completed - Claude-Code-Remote"
- },
- "1NTEJPH7": {
- "type": "pty",
- "createdAt": 1753625743,
- "expiresAt": 1753712143,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "09466a43-c495-4a30-ac08-eb425748a28c",
- "tmuxSession": "claude-taskping",
- "description": "completed - Claude-Code-Remote"
- },
- "5XO64F9Z": {
- "type": "pty",
- "createdAt": 1753625846,
- "expiresAt": 1753712246,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "99132172-7a97-46f7-b282-b22054d6e599",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "D8561S3A": {
- "type": "pty",
- "createdAt": 1753625904,
- "expiresAt": 1753712304,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "772628f1-414b-4242-bc8f-660ad53b6c23",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "GR0GED2E": {
- "type": "pty",
- "createdAt": 1753626215,
- "expiresAt": 1753712615,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "da40ba76-7047-41e0-95f2-081db87c1b3b",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "TTRQKVM9": {
- "type": "pty",
- "createdAt": 1753626245,
- "expiresAt": 1753712645,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "c7c5c95d-4541-47f6-b27a-35c0fd563413",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "P9UBHY8L": {
- "type": "pty",
- "createdAt": 1753626325,
- "expiresAt": 1753712725,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "a3f2b4f9-811e-4721-914f-f025919c2530",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "JQAOXCYJ": {
- "type": "pty",
- "createdAt": 1753626390,
- "expiresAt": 1753712790,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "f0d0635b-59f2-45eb-acfc-d649b12fd2d6",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "B7R9OR3K": {
- "type": "pty",
- "createdAt": 1753626445,
- "expiresAt": 1753712845,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "d33e49aa-a58f-46b0-8829-dfef7f474600",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "0KGM60XO": {
- "type": "pty",
- "createdAt": 1753626569,
- "expiresAt": 1753712969,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "02bd4449-bdcf-464e-916e-61bc62a18dd2",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "5NXM173C": {
- "type": "pty",
- "createdAt": 1753626834,
- "expiresAt": 1753713234,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "f8f915ee-ab64-471c-b3d2-71cb84d2b5fe",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "FU0A5E79": {
- "type": "pty",
- "createdAt": 1753627838,
- "expiresAt": 1753714238,
- "cwd": "/Users/jessytsui/dev/coverr_video",
- "sessionId": "1df42826-eb8e-47ee-bc5a-5886a1234d84",
- "tmuxSession": "video",
- "description": "completed - coverr_video"
- },
- "W3Y4UNV2": {
- "type": "pty",
- "createdAt": 1753627955,
- "expiresAt": 1753714355,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "23f16dc9-4668-4f34-b650-7919d325efd9",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "69PWGS1L": {
- "type": "pty",
- "createdAt": 1753628092,
- "expiresAt": 1753714492,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "8e847e83-677c-4b6a-9be8-184615731c9a",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "BP5WJBYZ": {
- "type": "pty",
- "createdAt": 1753631837,
- "expiresAt": 1753718237,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "0c7ba308-f6da-44bc-a622-8bdb4c7613a5",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "IS18V1WH": {
- "type": "pty",
- "createdAt": 1753631949,
- "expiresAt": 1753718349,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "563a4b27-f459-40fa-aa7b-df9c46643bab",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "QGLEAJLO": {
- "type": "pty",
- "createdAt": 1753632059,
- "expiresAt": 1753718459,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "e81186b8-c990-42a7-a1ec-16009e671f32",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "66VKI9JR": {
- "type": "pty",
- "createdAt": 1753633791,
- "expiresAt": 1753720191,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "29afd212-bfbb-443e-8e9f-7c4a08a9f178",
- "tmuxSession": "claude-taskping",
- "description": "completed - Claude-Code-Remote"
- },
- "MROLF6JQ": {
- "type": "pty",
- "createdAt": 1753633885,
- "expiresAt": 1753720285,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "6856d493-a825-45e9-ad87-d3dab6ebd3ed",
- "tmuxSession": "claude-taskping",
- "description": "completed - Claude-Code-Remote"
- },
- "JH6IROYI": {
- "type": "pty",
- "createdAt": 1753635239,
- "expiresAt": 1753721639,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "40829580-9b42-45c2-af54-994343101a4b",
- "tmuxSession": "claude-taskping",
- "description": "completed - Claude-Code-Remote"
- },
- "18E1GX7G": {
- "type": "pty",
- "createdAt": 1753635293,
- "expiresAt": 1753721693,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "d9524fbe-8915-4175-89e0-9358ccd86921",
- "tmuxSession": "claude-taskping",
- "description": "completed - Claude-Code-Remote"
- },
- "8CZC4SWF": {
- "type": "pty",
- "createdAt": 1753635381,
- "expiresAt": 1753721781,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "5d7673c5-5541-4c71-8f33-8270cde90376",
- "tmuxSession": "claude-taskping",
- "description": "completed - Claude-Code-Remote"
- },
- "L40V7BIU": {
- "type": "pty",
- "createdAt": 1753636194,
- "expiresAt": 1753722594,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "b4112f01-a8f5-44fe-8bb6-85b1f16d5cd9",
- "tmuxSession": "claude-taskping",
- "description": "completed - Claude-Code-Remote"
- },
- "X0PKR9KZ": {
- "type": "pty",
- "createdAt": 1753636706,
- "expiresAt": 1753723106,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "77747aee-ec17-4356-86be-ca20245eaa4c",
- "tmuxSession": "claude-taskping",
- "description": "completed - Claude-Code-Remote"
- },
- "K3G8GEM4": {
- "type": "pty",
- "createdAt": 1753636765,
- "expiresAt": 1753723165,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "5b70bf42-ed29-4004-afad-a337be665c74",
- "tmuxSession": "claude-taskping",
- "description": "completed - Claude-Code-Remote"
- },
- "1U1074XQ": {
- "type": "pty",
- "createdAt": 1753636941,
- "expiresAt": 1753723341,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "212bd122-ff8e-4299-88cc-93fed221ad2b",
- "tmuxSession": "claude-taskping",
- "description": "completed - Claude-Code-Remote"
- },
- "04Z5FEHE": {
- "type": "pty",
- "createdAt": 1753637049,
- "expiresAt": 1753723449,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "da16cada-9121-47c7-b7b8-4b47cbc46c7c",
- "tmuxSession": "claude-taskping",
- "description": "completed - Claude-Code-Remote"
- },
- "MSRLCGLS": {
- "type": "pty",
- "createdAt": 1753638288,
- "expiresAt": 1753724688,
- "cwd": "/Users/jessytsui",
- "sessionId": "d245e06c-9595-48f9-8ef1-c3f826352d75",
- "tmuxSession": "claude-taskping",
- "description": "completed - jessytsui"
- },
- "7O21O9ZR": {
- "type": "pty",
- "createdAt": 1753638308,
- "expiresAt": 1753724708,
- "cwd": "/Users/jessytsui",
- "sessionId": "6ec8789d-5eb0-4138-9180-f32559336906",
- "tmuxSession": "claude-taskping",
- "description": "completed - jessytsui"
- },
- "4S5KSCI3": {
- "type": "pty",
- "createdAt": 1753639559,
- "expiresAt": 1753725959,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "302103bd-522f-4349-8041-979a62c606d8",
- "tmuxSession": "claude-code-remote",
- "description": "completed - Claude-Code-Remote"
- },
- "VR3AB0NO": {
- "type": "pty",
- "createdAt": 1753640175,
- "expiresAt": 1753726575,
- "cwd": "/Users/jessytsui/dev/coverr_video",
- "sessionId": "6808bb5d-4268-4f46-aad7-0f01677f781e",
- "tmuxSession": "claude-code-remote",
- "description": "completed - coverr_video"
- },
- "RACVYH67": {
- "type": "pty",
- "createdAt": 1753640283,
- "expiresAt": 1753726683,
- "cwd": "/Users/jessytsui/dev/coverr_video",
- "sessionId": "4d23ece0-6931-4d6d-bb89-b2ba2709bba6",
- "tmuxSession": "claude-code-remote",
- "description": "completed - coverr_video"
- },
- "XBUMC8TX": {
- "type": "pty",
- "createdAt": 1753640359,
- "expiresAt": 1753726759,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "50436697-1576-4f70-9ea7-39ae61261192",
- "tmuxSession": "claude-code-remote",
- "description": "completed - Claude-Code-Remote"
- },
- "6L3BS2G9": {
- "type": "pty",
- "createdAt": 1753640370,
- "expiresAt": 1753726770,
- "cwd": "/Users/jessytsui/dev/coverr_video",
- "sessionId": "5ec3baf8-8dcd-44b6-9583-4fac336c92e2",
- "tmuxSession": "claude-code-remote",
- "description": "completed - coverr_video"
- },
- "ODFO312K": {
- "type": "pty",
- "createdAt": 1753640410,
- "expiresAt": 1753726810,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "616f15e8-0ae6-4a3b-ac02-373bca701630",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "6XWPQCEF": {
- "type": "pty",
- "createdAt": 1753640528,
- "expiresAt": 1753726928,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "b6d2d75b-c4b7-46cb-b922-d4f935e5424d",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "ZGXY36O1": {
- "type": "pty",
- "createdAt": 1753640690,
- "expiresAt": 1753727090,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "3ce40b4d-3273-4662-a6cf-ead30c91f950",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "MUE5LCUY": {
- "type": "pty",
- "createdAt": 1753684860,
- "expiresAt": 1753771260,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "698b6d2e-32f0-4eaa-8aa4-5bbf408b9640",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "KZVOG2PO": {
- "type": "pty",
- "createdAt": 1753684912,
- "expiresAt": 1753771312,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "0f63ad7f-2312-427f-b1e6-d186a6be3667",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "5HDFXY41": {
- "type": "pty",
- "createdAt": 1753684929,
- "expiresAt": 1753771329,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "22481ebb-0f9f-4f52-9668-347ed0fb0f98",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "NHXQJN3L": {
- "type": "pty",
- "createdAt": 1753685042,
- "expiresAt": 1753771442,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "a1b56007-ef57-48bb-8aa7-449bc5f9b1f7",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "84LX5NLI": {
- "type": "pty",
- "createdAt": 1753685161,
- "expiresAt": 1753771561,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "3535a857-c5da-4764-9367-9816955bfc30",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "3WYHK10U": {
- "type": "pty",
- "createdAt": 1753685478,
- "expiresAt": 1753771878,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "68eca4f9-79f4-4047-ab98-636cd742deee",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "INZLQTW0": {
- "type": "pty",
- "createdAt": 1753685542,
- "expiresAt": 1753771942,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "4bc09041-a751-43c0-93e1-f3b5a69d6aa1",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "TPV9W6VE": {
- "type": "pty",
- "createdAt": 1753685640,
- "expiresAt": 1753772040,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "023bb55f-acc0-4d8a-a2f4-79be0bd9a863",
- "tmuxSession": "video",
- "description": "completed - Claude-Code-Remote"
- },
- "IUNWWLOT": {
- "type": "pty",
- "createdAt": 1753685816,
- "expiresAt": 1753772216,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "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"
- },
- "7ZFMSK5P": {
- "type": "pty",
- "createdAt": 1754022640,
- "expiresAt": 1754109040,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "e3392712-9a5b-4c96-a23c-5d97c226b415",
- "tmuxSession": "a",
- "description": "completed - Claude-Code-Remote"
- },
- "PJOE746Q": {
- "type": "pty",
- "createdAt": 1754022731,
- "expiresAt": 1754109131,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "5d19da23-5c9d-4855-824e-fbd09a0d986c",
- "tmuxSession": "a",
- "description": "completed - Claude-Code-Remote"
- },
- "C9I24JHD": {
- "type": "pty",
- "createdAt": 1754022927,
- "expiresAt": 1754109327,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "ed814c4b-0b97-4e10-8ad1-dae1a7cb7ef9",
- "tmuxSession": "a",
- "description": "completed - Claude-Code-Remote"
- },
- "GGBKJ2DV": {
- "type": "pty",
- "createdAt": 1754023256,
- "expiresAt": 1754109656,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "46ae2185-2f70-4355-a3b8-9fc04fa01181",
- "tmuxSession": "a",
- "description": "completed - Claude-Code-Remote"
- },
- "DQH198YY": {
- "type": "pty",
- "createdAt": 1754023825,
- "expiresAt": 1754110225,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "49c51c77-8ecc-4a04-a7a8-5955f89411b1",
- "tmuxSession": "a",
- "description": "completed - Claude-Code-Remote"
- },
- "GQE6LLIF": {
- "type": "pty",
- "createdAt": 1754024054,
- "expiresAt": 1754110454,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "cc5a1eba-7e04-44e6-919f-0395ddf2ee08",
- "tmuxSession": "a",
- "description": "completed - Claude-Code-Remote"
- },
- "WYKEGTXV": {
- "type": "pty",
- "createdAt": 1754024273,
- "expiresAt": 1754110673,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "63198b90-3b9d-4448-a932-7c39c771554a",
- "tmuxSession": "a",
- "description": "completed - Claude-Code-Remote"
- },
- "ATUBLIN1": {
- "type": "pty",
- "createdAt": 1754025557,
- "expiresAt": 1754111957,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "bfd8b8d0-bcc4-4336-a6eb-8ca3f8b6c96e",
- "tmuxSession": "a",
- "description": "completed - Claude-Code-Remote"
- },
- "2W24RZTM": {
- "type": "pty",
- "createdAt": 1754025634,
- "expiresAt": 1754112034,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "cdbfc3f9-e27e-47d9-82b9-9058f0180fff",
- "tmuxSession": "a",
- "description": "completed - Claude-Code-Remote"
- },
- "PHAVU604": {
- "type": "pty",
- "createdAt": 1754025855,
- "expiresAt": 1754112255,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "cf18cb3b-bc72-46ea-985f-2b7f29f0993f",
- "tmuxSession": "a",
- "description": "completed - Claude-Code-Remote"
- },
- "C2APCY3V": {
- "type": "pty",
- "createdAt": 1754026029,
- "expiresAt": 1754112429,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "6da5d6f6-7e68-47eb-8676-175d77f0ddbc",
- "tmuxSession": "a",
- "description": "completed - Claude-Code-Remote"
- },
- "N5P4GUG3": {
- "type": "pty",
- "createdAt": 1754026119,
- "expiresAt": 1754112519,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "9143d717-be05-4869-b40a-2c775addcfc4",
- "tmuxSession": "a",
- "description": "completed - Claude-Code-Remote"
- },
- "CZIKHCFO": {
- "type": "pty",
- "createdAt": 1754026220,
- "expiresAt": 1754112620,
- "cwd": "/Users/jessytsui/dev/Claude-Code-Remote",
- "sessionId": "6fb2932d-d4ac-427b-8b7d-54af44fee1f2",
- "tmuxSession": "a",
- "description": "completed - Claude-Code-Remote"
- }
-}
\ No newline at end of file
+{}
\ No newline at end of file
diff --git a/src/data/subagent-activities.json b/src/data/subagent-activities.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/src/data/subagent-activities.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/src/utils/subagent-tracker.js b/src/utils/subagent-tracker.js
new file mode 100644
index 0000000..1f51940
--- /dev/null
+++ b/src/utils/subagent-tracker.js
@@ -0,0 +1,206 @@
+/**
+ * Subagent Activity Tracker
+ * Tracks subagent activities for including in completion emails
+ */
+
+const fs = require('fs');
+const path = require('path');
+
+class SubagentTracker {
+ constructor() {
+ this.dataDir = path.join(__dirname, '../data');
+ this.trackingFile = path.join(this.dataDir, 'subagent-activities.json');
+ this._ensureDataDir();
+ }
+
+ _escapeHtml(text) {
+ if (!text) return '';
+ const htmlEntities = {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ "'": '''
+ };
+ return String(text).replace(/[&<>"']/g, char => htmlEntities[char]);
+ }
+
+ _ensureDataDir() {
+ if (!fs.existsSync(this.dataDir)) {
+ fs.mkdirSync(this.dataDir, { recursive: true });
+ }
+ }
+
+ /**
+ * Load existing activities
+ */
+ _loadActivities() {
+ if (!fs.existsSync(this.trackingFile)) {
+ return {};
+ }
+ try {
+ return JSON.parse(fs.readFileSync(this.trackingFile, 'utf8'));
+ } catch (error) {
+ console.error('Failed to load subagent activities:', error);
+ return {};
+ }
+ }
+
+ /**
+ * Save activities to file
+ */
+ _saveActivities(activities) {
+ try {
+ fs.writeFileSync(this.trackingFile, JSON.stringify(activities, null, 2));
+ } catch (error) {
+ console.error('Failed to save subagent activities:', error);
+ }
+ }
+
+ /**
+ * Add a subagent activity
+ */
+ addActivity(sessionId, activity) {
+ const activities = this._loadActivities();
+
+ if (!activities[sessionId]) {
+ activities[sessionId] = {
+ startTime: new Date().toISOString(),
+ activities: []
+ };
+ }
+
+ activities[sessionId].activities.push({
+ timestamp: new Date().toISOString(),
+ type: activity.type || 'subagent',
+ description: activity.description || 'Subagent activity',
+ details: activity.details || {}
+ });
+
+ this._saveActivities(activities);
+ }
+
+ /**
+ * Get activities for a session
+ */
+ getActivities(sessionId) {
+ const activities = this._loadActivities();
+ return activities[sessionId] || null;
+ }
+
+ /**
+ * Clear activities for a session
+ */
+ clearActivities(sessionId) {
+ const activities = this._loadActivities();
+ delete activities[sessionId];
+ this._saveActivities(activities);
+ }
+
+ /**
+ * Clean up old activities (older than 24 hours)
+ */
+ cleanupOldActivities() {
+ const activities = this._loadActivities();
+ const now = new Date();
+ const oneDayAgo = new Date(now - 24 * 60 * 60 * 1000);
+
+ for (const sessionId in activities) {
+ const startTime = new Date(activities[sessionId].startTime);
+ if (startTime < oneDayAgo) {
+ delete activities[sessionId];
+ }
+ }
+
+ this._saveActivities(activities);
+ }
+
+ /**
+ * Format activities for email
+ */
+ formatActivitiesForEmail(sessionId) {
+ const sessionData = this.getActivities(sessionId);
+ if (!sessionData || sessionData.activities.length === 0) {
+ return '';
+ }
+
+ const activities = sessionData.activities;
+ const grouped = {};
+
+ // Group activities by type
+ activities.forEach(activity => {
+ const type = activity.type;
+ if (!grouped[type]) {
+ grouped[type] = [];
+ }
+ grouped[type].push(activity);
+ });
+
+ // Format as HTML
+ let html = `
+
+
+
š Subagent Activities Summary
+
`;
+
+ for (const [type, items] of Object.entries(grouped)) {
+ html += `
`;
+ html += `
${type} (${items.length} activities)
`;
+ html += `
`;
+ items.forEach((item, index) => {
+ const time = new Date(item.timestamp).toLocaleTimeString();
+ html += `- `;
+ html += `
`;
+ html += `
[${time}] ${this._escapeHtml(item.description || 'Subagent task')}
`;
+
+ if (item.details) {
+ // Show the question if available
+ if (item.details.userQuestion && item.details.userQuestion !== item.description) {
+ html += `
ā Question: ${this._escapeHtml(item.details.userQuestion)}
`;
+ }
+
+ // Show the response
+ if (item.details.claudeResponse) {
+ const response = item.details.claudeResponse;
+ // Check if this is just initialization text
+ if (response.includes('Initializing...') || response.includes('Concocting...')) {
+ html += `
ā³ Subagent was processing... (full output available in tmux session)
`;
+ } else {
+ html += `
`;
+ html += this._escapeHtml(response);
+ html += `
`;
+ }
+ }
+ }
+ html += `
`;
+ html += ` `;
+ });
+ html += `
`;
+ html += `
`;
+ }
+
+ html += `
+
+
`;
+
+ // Also format as plain text for text email
+ let text = '\nš Subagent Activities Summary\n\n';
+
+ for (const [type, items] of Object.entries(grouped)) {
+ text += `${type} (${items.length} activities)\n`;
+ items.forEach((item, index) => {
+ const time = new Date(item.timestamp).toLocaleTimeString();
+ text += ` ${index + 1}. [${time}] ${item.description}\n`;
+ if (item.details && item.details.claudeResponse) {
+ text += ` ${item.details.claudeResponse}\n`;
+ }
+ });
+ text += '\n';
+ }
+
+ // Return HTML for email (the email sender will use it appropriately)
+ return html;
+ }
+}
+
+module.exports = SubagentTracker;
\ No newline at end of file