* Add configuration option to disable subagent notifications - Added 'enableSubagentNotifications' config option (default: false) - Modified notification handler to check config before sending subagent notifications - Created documentation explaining the feature - Updated README with note about subagent notifications This addresses the issue where frequent subagent notifications can be distracting. Users can now control whether they receive notifications when subagents stop/start. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Add subagent activity tracking in completion emails - Track subagent activities instead of sending individual notifications - Include subagent activity summary in completion emails - Update email templates to display subagent activities - Add SubagentTracker utility to manage activity tracking - Update documentation to explain the new behavior This provides a better user experience by: 1. Reducing notification noise from frequent subagent activities 2. Still providing full visibility into what subagents did 3. Consolidating all information in the completion email 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Improve subagent activity details and documentation - Enhanced activity capture to include up to 1000 characters (was 200) - Improved email display format with better visual separation - Added detection for initialization-only captures with helpful message - Added configuration option for activity detail level - Created comprehensive documentation explaining the timing limitation - Added visual indicators for processing status This addresses the issue where subagent outputs were truncated or only showed initialization messages. Users now get better visibility into what subagents are doing, with clear indication when full output is available in tmux. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * delete redundant files and modify README * Fix HTML escaping in email notifications - Add _escapeHtml function to properly escape HTML entities in emails - Escape user-generated content to prevent HTML tags from being hidden - Fix issue where <developer> and other HTML-like strings disappeared in emails - Apply escaping to both main email content and subagent activity summaries 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
parent
3d2a26286c
commit
5159e53eaa
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -116,6 +116,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);
|
||||
|
||||
if (result.success) {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
"waiting": "Hero"
|
||||
},
|
||||
"enabled": true,
|
||||
"enableSubagentNotifications": false,
|
||||
"subagentActivityDetail": "medium",
|
||||
"timeout": 5,
|
||||
"customMessages": {
|
||||
"completed": null,
|
||||
|
|
|
|||
|
|
@ -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 {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{subagentActivities}}
|
||||
|
||||
<!-- Continue Instructions -->
|
||||
<div style="margin: 30px 0 20px 0; border-top: 1px solid #333; padding-top: 20px;">
|
||||
<span style="color: #999;">$</span> <span style="color: #00ff00;">claude-code help --continue</span><br>
|
||||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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": "<eba8744e-8cc1-4fad-9dc8-69d558c51cca-1754021210179@claude-code-remote>",
|
||||
"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": "<a1ed6757-6782-4b22-a486-aab5a9d60a3c-1754021267945@claude-code-remote>",
|
||||
"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": "<e3392712-9a5b-4c96-a23c-5d97c226b415-1754022640364@claude-code-remote>",
|
||||
"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": "<ed814c4b-0b97-4e10-8ad1-dae1a7cb7ef9-1754022927776@claude-code-remote>",
|
||||
"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": "<cc5a1eba-7e04-44e6-919f-0395ddf2ee08-1754024054719@claude-code-remote>",
|
||||
"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": "<bfd8b8d0-bcc4-4336-a6eb-8ca3f8b6c96e-1754025557415@claude-code-remote>",
|
||||
"sessionId": "bfd8b8d0-bcc4-4336-a6eb-8ca3f8b6c96e",
|
||||
"token": "ATUBLIN1",
|
||||
"type": "notification",
|
||||
"sentAt": "2025-08-01T05:19:18.866Z"
|
||||
},
|
||||
{
|
||||
"messageId": "<cdbfc3f9-e27e-47d9-82b9-9058f0180fff-1754025634473@claude-code-remote>",
|
||||
"sessionId": "cdbfc3f9-e27e-47d9-82b9-9058f0180fff",
|
||||
"token": "2W24RZTM",
|
||||
"type": "notification",
|
||||
"sentAt": "2025-08-01T05:20:35.851Z"
|
||||
},
|
||||
{
|
||||
"messageId": "<cf18cb3b-bc72-46ea-985f-2b7f29f0993f-1754025855175@claude-code-remote>",
|
||||
"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": []
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
{}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
|
|
@ -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 -->
|
||||
<div style="margin: 20px 0; padding: 15px; background-color: #1f1f1f; border: 1px solid #444; border-radius: 4px;">
|
||||
<div style="color: #ff9800; margin-bottom: 10px; font-weight: bold;">📊 Subagent Activities Summary</div>
|
||||
<div style="color: #ccc; font-size: 13px; line-height: 1.6;">`;
|
||||
|
||||
for (const [type, items] of Object.entries(grouped)) {
|
||||
html += `<div style="margin-bottom: 10px;">`;
|
||||
html += `<div style="color: #00bcd4; font-weight: bold;">${type} (${items.length} activities)</div>`;
|
||||
html += `<ul style="margin: 5px 0 0 20px; padding: 0;">`;
|
||||
items.forEach((item, index) => {
|
||||
const time = new Date(item.timestamp).toLocaleTimeString();
|
||||
html += `<li style="color: #ccc; margin: 8px 0; list-style-type: none;">`;
|
||||
html += `<div style="background-color: #262626; padding: 10px; border-left: 3px solid #00bcd4; margin: 5px 0;">`;
|
||||
html += `<div><span style="color: #999;">[${time}]</span> <strong style="color: #fff;">${this._escapeHtml(item.description || 'Subagent task')}</strong></div>`;
|
||||
|
||||
if (item.details) {
|
||||
// Show the question if available
|
||||
if (item.details.userQuestion && item.details.userQuestion !== item.description) {
|
||||
html += `<div style="color: #00ff00; margin-top: 5px; font-size: 12px;">→ Question: ${this._escapeHtml(item.details.userQuestion)}</div>`;
|
||||
}
|
||||
|
||||
// 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 += `<div style="color: #ff9800; margin-top: 5px; font-size: 12px; font-style: italic;">⏳ Subagent was processing... (full output available in tmux session)</div>`;
|
||||
} else {
|
||||
html += `<div style="color: #ccc; margin-top: 5px; margin-left: 20px; font-size: 12px; white-space: pre-wrap; max-height: 200px; overflow-y: auto; background-color: #1a1a1a; padding: 8px; border-radius: 4px;">`;
|
||||
html += this._escapeHtml(response);
|
||||
html += `</div>`;
|
||||
}
|
||||
}
|
||||
}
|
||||
html += `</div>`;
|
||||
html += `</li>`;
|
||||
});
|
||||
html += `</ul>`;
|
||||
html += `</div>`;
|
||||
}
|
||||
|
||||
html += `
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
// 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;
|
||||
Loading…
Reference in New Issue