2025-07-27 02:22:12 +08:00
|
|
|
|
#!/usr/bin/env node
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2025-07-28 02:21:38 +08:00
|
|
|
|
* Claude-Code-Remote - Claude Code Smart Notification System
|
2025-07-27 02:22:12 +08:00
|
|
|
|
* Main entry point for the CLI tool
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2025-08-01 12:28:39 +08:00
|
|
|
|
// Load environment variables from Claude-Code-Remote directory
|
|
|
|
|
|
const path = require('path');
|
|
|
|
|
|
const envPath = path.join(__dirname, '.env');
|
|
|
|
|
|
require('dotenv').config({ path: envPath });
|
2025-07-28 14:44:37 +08:00
|
|
|
|
|
2025-07-27 02:22:12 +08:00
|
|
|
|
const Logger = require('./src/core/logger');
|
|
|
|
|
|
const Notifier = require('./src/core/notifier');
|
|
|
|
|
|
const ConfigManager = require('./src/core/config');
|
|
|
|
|
|
|
2025-07-28 02:21:38 +08:00
|
|
|
|
class ClaudeCodeRemoteCLI {
|
2025-07-27 02:22:12 +08:00
|
|
|
|
constructor() {
|
|
|
|
|
|
this.logger = new Logger('CLI');
|
|
|
|
|
|
this.config = new ConfigManager();
|
|
|
|
|
|
this.notifier = new Notifier(this.config);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async init() {
|
|
|
|
|
|
// Load configuration
|
|
|
|
|
|
this.config.load();
|
|
|
|
|
|
|
|
|
|
|
|
// Initialize channels
|
|
|
|
|
|
await this.notifier.initializeChannels();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async run() {
|
|
|
|
|
|
const args = process.argv.slice(2);
|
|
|
|
|
|
const command = args[0];
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
await this.init();
|
|
|
|
|
|
|
|
|
|
|
|
switch (command) {
|
|
|
|
|
|
case 'notify':
|
|
|
|
|
|
await this.handleNotify(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'test':
|
|
|
|
|
|
await this.handleTest(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'status':
|
|
|
|
|
|
await this.handleStatus(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'config':
|
|
|
|
|
|
await this.handleConfig(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'install':
|
|
|
|
|
|
await this.handleInstall(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'relay':
|
|
|
|
|
|
await this.handleRelay(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'edit-config':
|
|
|
|
|
|
await this.handleEditConfig(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'setup-email':
|
|
|
|
|
|
await this.handleSetupEmail(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'daemon':
|
|
|
|
|
|
await this.handleDaemon(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'commands':
|
|
|
|
|
|
await this.handleCommands(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'test-paste':
|
|
|
|
|
|
await this.handleTestPaste(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'test-simple':
|
|
|
|
|
|
await this.handleTestSimple(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'test-claude':
|
|
|
|
|
|
await this.handleTestClaude(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'setup-permissions':
|
|
|
|
|
|
await this.handleSetupPermissions(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'diagnose':
|
|
|
|
|
|
await this.handleDiagnose(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case '--help':
|
|
|
|
|
|
case '-h':
|
|
|
|
|
|
case undefined:
|
|
|
|
|
|
this.showHelp();
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
console.error(`Unknown command: ${command}`);
|
|
|
|
|
|
this.showHelp();
|
|
|
|
|
|
process.exit(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
this.logger.error('CLI error:', error.message);
|
|
|
|
|
|
process.exit(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async handleNotify(args) {
|
|
|
|
|
|
const typeIndex = args.findIndex(arg => arg === '--type');
|
|
|
|
|
|
|
|
|
|
|
|
if (typeIndex === -1 || typeIndex + 1 >= args.length) {
|
2025-07-28 02:21:38 +08:00
|
|
|
|
console.error('Usage: claude-remote notify --type <completed|waiting>');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
process.exit(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const type = args[typeIndex + 1];
|
|
|
|
|
|
|
|
|
|
|
|
if (!['completed', 'waiting'].includes(type)) {
|
|
|
|
|
|
console.error('Invalid type. Use: completed or waiting');
|
|
|
|
|
|
process.exit(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Automatically capture current tmux session conversation content
|
2025-07-27 15:27:24 +08:00
|
|
|
|
const metadata = await this.captureCurrentConversation();
|
2025-08-01 14:49:48 +08:00
|
|
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
Add full execution trace in email notifications (#11) (#14)
* 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>
* Add full execution trace to email notifications
- Add getFullExecutionTrace method to capture complete terminal output
- Include execution trace in a scrollable section within emails
- Add CSS styling for visible scrollbars on desktop
- Clean trace output by removing command prompt boxes
- Add fallback message when trace is not available
This addresses issue #11 - providing transparency about task execution
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Redesign email notification UI with improved terminal aesthetics
- Reorganize content hierarchy: user request at top, response second, trace at bottom
- Preserve terminal-style commands ($ cat, $ claude-code execute, etc.)
- Remove redundant session info footer
- Implement smart execution trace capture from user input to completion
- Add TraceCapture utility to track user input timestamps
- Improve visual hierarchy while maintaining terminal aesthetics
- Use border colors (orange for user, green for success) for better distinction
- Make execution trace collapsible and de-emphasized
This improves readability while preserving the terminal charm of the project.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix execution trace filtering to show only recent activity
- Change filter logic to find LAST user input instead of first
- Search backwards through content to find most recent "> " prompt
- Only include content from that point forward
- Add fallback to show last 100 lines if no user input found
- This ensures trace shows only relevant recent execution, not entire history
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove duplicate content from execution trace
- Skip the first user input line (already shown in main content)
- Skip the last Claude response (already shown in main content)
- Only show intermediate execution steps and tool usage
- Clean up empty lines at beginning and end
- This avoids redundancy and focuses trace on execution details
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix execution trace to properly remove complete user input and output
- Track multi-line user input and skip all continuation lines
- Detect when user input ends (empty line or next command)
- Stop before the last Claude response to avoid truncation
- Only show intermediate execution steps between input and output
This ensures the trace shows the complete execution process without
duplicating content already displayed in the main sections.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix multi-line user input capture and trace filtering
- Capture complete multi-line user input (not just first line)
- Join continuation lines with spaces for proper display
- Preserve all execution details in trace (tool calls, outputs)
- Only skip user input and final response, keep everything in between
* Add configuration toggle for subagent activities in email
- Added 'showSubagentActivitiesInEmail' config option (default: false)
- Modified claude-remote.js to check config before including subagent activities
- Created documentation explaining the configuration
- Allows users to choose between concise emails (execution trace only) or detailed emails (both summaries)
This addresses the redundancy between execution trace and subagent activities summary,
giving users control over email content.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix Git merge conflict in email template and document subagent config
- Removed Git merge conflict markers from email text template
- Added documentation for showSubagentActivitiesInEmail config in README
- Explained that subagent activities are disabled by default for concise emails
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Update README changelog for PR #10 and issue #11
- Added entry for subagent notifications configuration (PR #10)
- Added entry for execution trace feature (issue #11)
- Maintained chronological order in changelog
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* delete redundant files
* fix #15: add local database into .gitignore
* Fix execution trace display in email notifications
- Remove collapsible details tag for better email client compatibility
- Add configuration option to toggle execution trace display
- Fix HTML escaping issue for executionTraceSection variable
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove data files from git tracking
These session-specific data files should not be tracked in version control
as they are machine-specific and cause issues when pulling on other machines.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix typo(?) in changelog (#13)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Naich <an.naich@gmail.com>
Co-authored-by: JessyTsui <51992423+JessyTsui@users.noreply.github.com>
2025-08-02 04:07:34 +08:00
|
|
|
|
// For completed notifications, include subagent activities and execution trace
|
2025-08-01 14:49:48 +08:00
|
|
|
|
if (type === 'completed') {
|
Add full execution trace in email notifications (#11) (#14)
* 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>
* Add full execution trace to email notifications
- Add getFullExecutionTrace method to capture complete terminal output
- Include execution trace in a scrollable section within emails
- Add CSS styling for visible scrollbars on desktop
- Clean trace output by removing command prompt boxes
- Add fallback message when trace is not available
This addresses issue #11 - providing transparency about task execution
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Redesign email notification UI with improved terminal aesthetics
- Reorganize content hierarchy: user request at top, response second, trace at bottom
- Preserve terminal-style commands ($ cat, $ claude-code execute, etc.)
- Remove redundant session info footer
- Implement smart execution trace capture from user input to completion
- Add TraceCapture utility to track user input timestamps
- Improve visual hierarchy while maintaining terminal aesthetics
- Use border colors (orange for user, green for success) for better distinction
- Make execution trace collapsible and de-emphasized
This improves readability while preserving the terminal charm of the project.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix execution trace filtering to show only recent activity
- Change filter logic to find LAST user input instead of first
- Search backwards through content to find most recent "> " prompt
- Only include content from that point forward
- Add fallback to show last 100 lines if no user input found
- This ensures trace shows only relevant recent execution, not entire history
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove duplicate content from execution trace
- Skip the first user input line (already shown in main content)
- Skip the last Claude response (already shown in main content)
- Only show intermediate execution steps and tool usage
- Clean up empty lines at beginning and end
- This avoids redundancy and focuses trace on execution details
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix execution trace to properly remove complete user input and output
- Track multi-line user input and skip all continuation lines
- Detect when user input ends (empty line or next command)
- Stop before the last Claude response to avoid truncation
- Only show intermediate execution steps between input and output
This ensures the trace shows the complete execution process without
duplicating content already displayed in the main sections.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix multi-line user input capture and trace filtering
- Capture complete multi-line user input (not just first line)
- Join continuation lines with spaces for proper display
- Preserve all execution details in trace (tool calls, outputs)
- Only skip user input and final response, keep everything in between
* Add configuration toggle for subagent activities in email
- Added 'showSubagentActivitiesInEmail' config option (default: false)
- Modified claude-remote.js to check config before including subagent activities
- Created documentation explaining the configuration
- Allows users to choose between concise emails (execution trace only) or detailed emails (both summaries)
This addresses the redundancy between execution trace and subagent activities summary,
giving users control over email content.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix Git merge conflict in email template and document subagent config
- Removed Git merge conflict markers from email text template
- Added documentation for showSubagentActivitiesInEmail config in README
- Explained that subagent activities are disabled by default for concise emails
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Update README changelog for PR #10 and issue #11
- Added entry for subagent notifications configuration (PR #10)
- Added entry for execution trace feature (issue #11)
- Maintained chronological order in changelog
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* delete redundant files
* fix #15: add local database into .gitignore
* Fix execution trace display in email notifications
- Remove collapsible details tag for better email client compatibility
- Add configuration option to toggle execution trace display
- Fix HTML escaping issue for executionTraceSection variable
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove data files from git tracking
These session-specific data files should not be tracked in version control
as they are machine-specific and cause issues when pulling on other machines.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix typo(?) in changelog (#13)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Naich <an.naich@gmail.com>
Co-authored-by: JessyTsui <51992423+JessyTsui@users.noreply.github.com>
2025-08-02 04:07:34 +08:00
|
|
|
|
const Config = require('./src/core/config');
|
|
|
|
|
|
const config = new Config();
|
|
|
|
|
|
config.load();
|
|
|
|
|
|
const showSubagentActivitiesInEmail = config.get('showSubagentActivitiesInEmail', false);
|
2025-08-01 14:49:48 +08:00
|
|
|
|
|
Add full execution trace in email notifications (#11) (#14)
* 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>
* Add full execution trace to email notifications
- Add getFullExecutionTrace method to capture complete terminal output
- Include execution trace in a scrollable section within emails
- Add CSS styling for visible scrollbars on desktop
- Clean trace output by removing command prompt boxes
- Add fallback message when trace is not available
This addresses issue #11 - providing transparency about task execution
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Redesign email notification UI with improved terminal aesthetics
- Reorganize content hierarchy: user request at top, response second, trace at bottom
- Preserve terminal-style commands ($ cat, $ claude-code execute, etc.)
- Remove redundant session info footer
- Implement smart execution trace capture from user input to completion
- Add TraceCapture utility to track user input timestamps
- Improve visual hierarchy while maintaining terminal aesthetics
- Use border colors (orange for user, green for success) for better distinction
- Make execution trace collapsible and de-emphasized
This improves readability while preserving the terminal charm of the project.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix execution trace filtering to show only recent activity
- Change filter logic to find LAST user input instead of first
- Search backwards through content to find most recent "> " prompt
- Only include content from that point forward
- Add fallback to show last 100 lines if no user input found
- This ensures trace shows only relevant recent execution, not entire history
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove duplicate content from execution trace
- Skip the first user input line (already shown in main content)
- Skip the last Claude response (already shown in main content)
- Only show intermediate execution steps and tool usage
- Clean up empty lines at beginning and end
- This avoids redundancy and focuses trace on execution details
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix execution trace to properly remove complete user input and output
- Track multi-line user input and skip all continuation lines
- Detect when user input ends (empty line or next command)
- Stop before the last Claude response to avoid truncation
- Only show intermediate execution steps between input and output
This ensures the trace shows the complete execution process without
duplicating content already displayed in the main sections.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix multi-line user input capture and trace filtering
- Capture complete multi-line user input (not just first line)
- Join continuation lines with spaces for proper display
- Preserve all execution details in trace (tool calls, outputs)
- Only skip user input and final response, keep everything in between
* Add configuration toggle for subagent activities in email
- Added 'showSubagentActivitiesInEmail' config option (default: false)
- Modified claude-remote.js to check config before including subagent activities
- Created documentation explaining the configuration
- Allows users to choose between concise emails (execution trace only) or detailed emails (both summaries)
This addresses the redundancy between execution trace and subagent activities summary,
giving users control over email content.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix Git merge conflict in email template and document subagent config
- Removed Git merge conflict markers from email text template
- Added documentation for showSubagentActivitiesInEmail config in README
- Explained that subagent activities are disabled by default for concise emails
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Update README changelog for PR #10 and issue #11
- Added entry for subagent notifications configuration (PR #10)
- Added entry for execution trace feature (issue #11)
- Maintained chronological order in changelog
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* delete redundant files
* fix #15: add local database into .gitignore
* Fix execution trace display in email notifications
- Remove collapsible details tag for better email client compatibility
- Add configuration option to toggle execution trace display
- Fix HTML escaping issue for executionTraceSection variable
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove data files from git tracking
These session-specific data files should not be tracked in version control
as they are machine-specific and cause issues when pulling on other machines.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix typo(?) in changelog (#13)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Naich <an.naich@gmail.com>
Co-authored-by: JessyTsui <51992423+JessyTsui@users.noreply.github.com>
2025-08-02 04:07:34 +08:00
|
|
|
|
if (showSubagentActivitiesInEmail) {
|
|
|
|
|
|
const SubagentTracker = require('./src/utils/subagent-tracker');
|
|
|
|
|
|
const tracker = new SubagentTracker();
|
|
|
|
|
|
const trackingKey = metadata.tmuxSession || 'default';
|
2025-08-01 14:49:48 +08:00
|
|
|
|
|
Add full execution trace in email notifications (#11) (#14)
* 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>
* Add full execution trace to email notifications
- Add getFullExecutionTrace method to capture complete terminal output
- Include execution trace in a scrollable section within emails
- Add CSS styling for visible scrollbars on desktop
- Clean trace output by removing command prompt boxes
- Add fallback message when trace is not available
This addresses issue #11 - providing transparency about task execution
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Redesign email notification UI with improved terminal aesthetics
- Reorganize content hierarchy: user request at top, response second, trace at bottom
- Preserve terminal-style commands ($ cat, $ claude-code execute, etc.)
- Remove redundant session info footer
- Implement smart execution trace capture from user input to completion
- Add TraceCapture utility to track user input timestamps
- Improve visual hierarchy while maintaining terminal aesthetics
- Use border colors (orange for user, green for success) for better distinction
- Make execution trace collapsible and de-emphasized
This improves readability while preserving the terminal charm of the project.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix execution trace filtering to show only recent activity
- Change filter logic to find LAST user input instead of first
- Search backwards through content to find most recent "> " prompt
- Only include content from that point forward
- Add fallback to show last 100 lines if no user input found
- This ensures trace shows only relevant recent execution, not entire history
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove duplicate content from execution trace
- Skip the first user input line (already shown in main content)
- Skip the last Claude response (already shown in main content)
- Only show intermediate execution steps and tool usage
- Clean up empty lines at beginning and end
- This avoids redundancy and focuses trace on execution details
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix execution trace to properly remove complete user input and output
- Track multi-line user input and skip all continuation lines
- Detect when user input ends (empty line or next command)
- Stop before the last Claude response to avoid truncation
- Only show intermediate execution steps between input and output
This ensures the trace shows the complete execution process without
duplicating content already displayed in the main sections.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix multi-line user input capture and trace filtering
- Capture complete multi-line user input (not just first line)
- Join continuation lines with spaces for proper display
- Preserve all execution details in trace (tool calls, outputs)
- Only skip user input and final response, keep everything in between
* Add configuration toggle for subagent activities in email
- Added 'showSubagentActivitiesInEmail' config option (default: false)
- Modified claude-remote.js to check config before including subagent activities
- Created documentation explaining the configuration
- Allows users to choose between concise emails (execution trace only) or detailed emails (both summaries)
This addresses the redundancy between execution trace and subagent activities summary,
giving users control over email content.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix Git merge conflict in email template and document subagent config
- Removed Git merge conflict markers from email text template
- Added documentation for showSubagentActivitiesInEmail config in README
- Explained that subagent activities are disabled by default for concise emails
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Update README changelog for PR #10 and issue #11
- Added entry for subagent notifications configuration (PR #10)
- Added entry for execution trace feature (issue #11)
- Maintained chronological order in changelog
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* delete redundant files
* fix #15: add local database into .gitignore
* Fix execution trace display in email notifications
- Remove collapsible details tag for better email client compatibility
- Add configuration option to toggle execution trace display
- Fix HTML escaping issue for executionTraceSection variable
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove data files from git tracking
These session-specific data files should not be tracked in version control
as they are machine-specific and cause issues when pulling on other machines.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix typo(?) in changelog (#13)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Naich <an.naich@gmail.com>
Co-authored-by: JessyTsui <51992423+JessyTsui@users.noreply.github.com>
2025-08-02 04:07:34 +08:00
|
|
|
|
// Get and format subagent activities
|
|
|
|
|
|
const subagentSummary = tracker.formatActivitiesForEmail(trackingKey);
|
|
|
|
|
|
if (subagentSummary) {
|
|
|
|
|
|
metadata.subagentActivities = subagentSummary;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Clear activities after including them in the notification
|
|
|
|
|
|
tracker.clearActivities(trackingKey);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// Always clear activities even if not showing them
|
|
|
|
|
|
const SubagentTracker = require('./src/utils/subagent-tracker');
|
|
|
|
|
|
const tracker = new SubagentTracker();
|
|
|
|
|
|
const trackingKey = metadata.tmuxSession || 'default';
|
2025-08-01 14:49:48 +08:00
|
|
|
|
tracker.clearActivities(trackingKey);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-07-27 15:27:24 +08:00
|
|
|
|
|
|
|
|
|
|
const result = await this.notifier.notify(type, metadata);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
if (result.success) {
|
|
|
|
|
|
this.logger.info(`${type} notification sent successfully`);
|
|
|
|
|
|
process.exit(0);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.logger.error(`Failed to send ${type} notification`);
|
|
|
|
|
|
process.exit(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-27 15:27:24 +08:00
|
|
|
|
async captureCurrentConversation() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const { execSync } = require('child_process');
|
|
|
|
|
|
const TmuxMonitor = require('./src/utils/tmux-monitor');
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Get current tmux session name
|
2025-07-27 15:27:24 +08:00
|
|
|
|
let currentSession = null;
|
|
|
|
|
|
try {
|
|
|
|
|
|
currentSession = execSync('tmux display-message -p "#S"', {
|
|
|
|
|
|
encoding: 'utf8',
|
|
|
|
|
|
stdio: ['ignore', 'pipe', 'ignore']
|
|
|
|
|
|
}).trim();
|
|
|
|
|
|
} catch (e) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Not running in tmux, return empty metadata
|
2025-07-27 15:27:24 +08:00
|
|
|
|
return {};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!currentSession) {
|
|
|
|
|
|
return {};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Use TmuxMonitor to capture conversation
|
2025-07-27 15:27:24 +08:00
|
|
|
|
const tmuxMonitor = new TmuxMonitor();
|
|
|
|
|
|
const conversation = tmuxMonitor.getRecentConversation(currentSession);
|
Add full execution trace in email notifications (#11) (#14)
* 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>
* Add full execution trace to email notifications
- Add getFullExecutionTrace method to capture complete terminal output
- Include execution trace in a scrollable section within emails
- Add CSS styling for visible scrollbars on desktop
- Clean trace output by removing command prompt boxes
- Add fallback message when trace is not available
This addresses issue #11 - providing transparency about task execution
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Redesign email notification UI with improved terminal aesthetics
- Reorganize content hierarchy: user request at top, response second, trace at bottom
- Preserve terminal-style commands ($ cat, $ claude-code execute, etc.)
- Remove redundant session info footer
- Implement smart execution trace capture from user input to completion
- Add TraceCapture utility to track user input timestamps
- Improve visual hierarchy while maintaining terminal aesthetics
- Use border colors (orange for user, green for success) for better distinction
- Make execution trace collapsible and de-emphasized
This improves readability while preserving the terminal charm of the project.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix execution trace filtering to show only recent activity
- Change filter logic to find LAST user input instead of first
- Search backwards through content to find most recent "> " prompt
- Only include content from that point forward
- Add fallback to show last 100 lines if no user input found
- This ensures trace shows only relevant recent execution, not entire history
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove duplicate content from execution trace
- Skip the first user input line (already shown in main content)
- Skip the last Claude response (already shown in main content)
- Only show intermediate execution steps and tool usage
- Clean up empty lines at beginning and end
- This avoids redundancy and focuses trace on execution details
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix execution trace to properly remove complete user input and output
- Track multi-line user input and skip all continuation lines
- Detect when user input ends (empty line or next command)
- Stop before the last Claude response to avoid truncation
- Only show intermediate execution steps between input and output
This ensures the trace shows the complete execution process without
duplicating content already displayed in the main sections.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix multi-line user input capture and trace filtering
- Capture complete multi-line user input (not just first line)
- Join continuation lines with spaces for proper display
- Preserve all execution details in trace (tool calls, outputs)
- Only skip user input and final response, keep everything in between
* Add configuration toggle for subagent activities in email
- Added 'showSubagentActivitiesInEmail' config option (default: false)
- Modified claude-remote.js to check config before including subagent activities
- Created documentation explaining the configuration
- Allows users to choose between concise emails (execution trace only) or detailed emails (both summaries)
This addresses the redundancy between execution trace and subagent activities summary,
giving users control over email content.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix Git merge conflict in email template and document subagent config
- Removed Git merge conflict markers from email text template
- Added documentation for showSubagentActivitiesInEmail config in README
- Explained that subagent activities are disabled by default for concise emails
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Update README changelog for PR #10 and issue #11
- Added entry for subagent notifications configuration (PR #10)
- Added entry for execution trace feature (issue #11)
- Maintained chronological order in changelog
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* delete redundant files
* fix #15: add local database into .gitignore
* Fix execution trace display in email notifications
- Remove collapsible details tag for better email client compatibility
- Add configuration option to toggle execution trace display
- Fix HTML escaping issue for executionTraceSection variable
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove data files from git tracking
These session-specific data files should not be tracked in version control
as they are machine-specific and cause issues when pulling on other machines.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix typo(?) in changelog (#13)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Naich <an.naich@gmail.com>
Co-authored-by: JessyTsui <51992423+JessyTsui@users.noreply.github.com>
2025-08-02 04:07:34 +08:00
|
|
|
|
const fullTrace = tmuxMonitor.getFullExecutionTrace(currentSession);
|
2025-07-27 15:27:24 +08:00
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
userQuestion: conversation.userQuestion,
|
|
|
|
|
|
claudeResponse: conversation.claudeResponse,
|
Add full execution trace in email notifications (#11) (#14)
* 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>
* Add full execution trace to email notifications
- Add getFullExecutionTrace method to capture complete terminal output
- Include execution trace in a scrollable section within emails
- Add CSS styling for visible scrollbars on desktop
- Clean trace output by removing command prompt boxes
- Add fallback message when trace is not available
This addresses issue #11 - providing transparency about task execution
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Redesign email notification UI with improved terminal aesthetics
- Reorganize content hierarchy: user request at top, response second, trace at bottom
- Preserve terminal-style commands ($ cat, $ claude-code execute, etc.)
- Remove redundant session info footer
- Implement smart execution trace capture from user input to completion
- Add TraceCapture utility to track user input timestamps
- Improve visual hierarchy while maintaining terminal aesthetics
- Use border colors (orange for user, green for success) for better distinction
- Make execution trace collapsible and de-emphasized
This improves readability while preserving the terminal charm of the project.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix execution trace filtering to show only recent activity
- Change filter logic to find LAST user input instead of first
- Search backwards through content to find most recent "> " prompt
- Only include content from that point forward
- Add fallback to show last 100 lines if no user input found
- This ensures trace shows only relevant recent execution, not entire history
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove duplicate content from execution trace
- Skip the first user input line (already shown in main content)
- Skip the last Claude response (already shown in main content)
- Only show intermediate execution steps and tool usage
- Clean up empty lines at beginning and end
- This avoids redundancy and focuses trace on execution details
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix execution trace to properly remove complete user input and output
- Track multi-line user input and skip all continuation lines
- Detect when user input ends (empty line or next command)
- Stop before the last Claude response to avoid truncation
- Only show intermediate execution steps between input and output
This ensures the trace shows the complete execution process without
duplicating content already displayed in the main sections.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix multi-line user input capture and trace filtering
- Capture complete multi-line user input (not just first line)
- Join continuation lines with spaces for proper display
- Preserve all execution details in trace (tool calls, outputs)
- Only skip user input and final response, keep everything in between
* Add configuration toggle for subagent activities in email
- Added 'showSubagentActivitiesInEmail' config option (default: false)
- Modified claude-remote.js to check config before including subagent activities
- Created documentation explaining the configuration
- Allows users to choose between concise emails (execution trace only) or detailed emails (both summaries)
This addresses the redundancy between execution trace and subagent activities summary,
giving users control over email content.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix Git merge conflict in email template and document subagent config
- Removed Git merge conflict markers from email text template
- Added documentation for showSubagentActivitiesInEmail config in README
- Explained that subagent activities are disabled by default for concise emails
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Update README changelog for PR #10 and issue #11
- Added entry for subagent notifications configuration (PR #10)
- Added entry for execution trace feature (issue #11)
- Maintained chronological order in changelog
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* delete redundant files
* fix #15: add local database into .gitignore
* Fix execution trace display in email notifications
- Remove collapsible details tag for better email client compatibility
- Add configuration option to toggle execution trace display
- Fix HTML escaping issue for executionTraceSection variable
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove data files from git tracking
These session-specific data files should not be tracked in version control
as they are machine-specific and cause issues when pulling on other machines.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix typo(?) in changelog (#13)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Naich <an.naich@gmail.com>
Co-authored-by: JessyTsui <51992423+JessyTsui@users.noreply.github.com>
2025-08-02 04:07:34 +08:00
|
|
|
|
tmuxSession: currentSession,
|
|
|
|
|
|
fullExecutionTrace: fullTrace
|
2025-07-27 15:27:24 +08:00
|
|
|
|
};
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
this.logger.debug('Failed to capture conversation:', error.message);
|
|
|
|
|
|
return {};
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-27 02:22:12 +08:00
|
|
|
|
async handleTest(args) {
|
|
|
|
|
|
console.log('Testing notification channels...\n');
|
|
|
|
|
|
|
|
|
|
|
|
const results = await this.notifier.test();
|
|
|
|
|
|
|
|
|
|
|
|
for (const [channel, result] of Object.entries(results)) {
|
|
|
|
|
|
const status = result.success ? '✅ PASS' : '❌ FAIL';
|
|
|
|
|
|
console.log(`${channel}: ${status}`);
|
|
|
|
|
|
if (result.error) {
|
|
|
|
|
|
console.log(` Error: ${result.error}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const passCount = Object.values(results).filter(r => r.success).length;
|
|
|
|
|
|
const totalCount = Object.keys(results).length;
|
|
|
|
|
|
|
|
|
|
|
|
console.log(`\nTest completed: ${passCount}/${totalCount} channels passed`);
|
|
|
|
|
|
|
|
|
|
|
|
if (passCount === 0) {
|
|
|
|
|
|
process.exit(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async handleStatus(args) {
|
|
|
|
|
|
const status = this.notifier.getStatus();
|
|
|
|
|
|
|
2025-07-28 02:21:38 +08:00
|
|
|
|
console.log('Claude-Code-Remote Status\n');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
console.log('Configuration:');
|
|
|
|
|
|
console.log(` Enabled: ${status.enabled ? 'Yes' : 'No'}`);
|
|
|
|
|
|
console.log(` Language: ${status.config.language}`);
|
|
|
|
|
|
console.log(` Sounds: ${status.config.sound.completed} / ${status.config.sound.waiting}`);
|
|
|
|
|
|
|
|
|
|
|
|
console.log('\nChannels:');
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Display all available channels, including disabled ones
|
2025-07-27 02:22:12 +08:00
|
|
|
|
const allChannels = this.config._channels || {};
|
|
|
|
|
|
const activeChannels = status.channels || {};
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Merge all channel information
|
2025-07-27 02:22:12 +08:00
|
|
|
|
const channelNames = new Set([
|
|
|
|
|
|
...Object.keys(allChannels),
|
|
|
|
|
|
...Object.keys(activeChannels)
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
for (const name of channelNames) {
|
|
|
|
|
|
const channelConfig = allChannels[name] || {};
|
|
|
|
|
|
const channelStatus = activeChannels[name];
|
|
|
|
|
|
|
|
|
|
|
|
let enabled, configured, relay;
|
|
|
|
|
|
|
|
|
|
|
|
if (channelStatus) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Active channel, use actual status
|
2025-07-27 02:22:12 +08:00
|
|
|
|
enabled = channelStatus.enabled ? '✅' : '❌';
|
|
|
|
|
|
configured = channelStatus.configured ? '✅' : '❌';
|
|
|
|
|
|
relay = channelStatus.supportsRelay ? '✅' : '❌';
|
|
|
|
|
|
} else {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Inactive channel, use configuration status
|
2025-07-27 02:22:12 +08:00
|
|
|
|
enabled = channelConfig.enabled ? '✅' : '❌';
|
|
|
|
|
|
configured = this._isChannelConfigured(name, channelConfig) ? '✅' : '❌';
|
|
|
|
|
|
relay = this._supportsRelay(name) ? '✅' : '❌';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log(` ${name}:`);
|
|
|
|
|
|
console.log(` Enabled: ${enabled}`);
|
|
|
|
|
|
console.log(` Configured: ${configured}`);
|
|
|
|
|
|
console.log(` Supports Relay: ${relay}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_isChannelConfigured(name, config) {
|
|
|
|
|
|
switch (name) {
|
|
|
|
|
|
case 'desktop':
|
2025-07-27 17:17:15 +08:00
|
|
|
|
return true; // Desktop notifications don't need special configuration
|
2025-07-27 02:22:12 +08:00
|
|
|
|
case 'email':
|
|
|
|
|
|
return config.config &&
|
|
|
|
|
|
config.config.smtp &&
|
|
|
|
|
|
config.config.smtp.host &&
|
|
|
|
|
|
config.config.smtp.auth &&
|
|
|
|
|
|
config.config.smtp.auth.user &&
|
|
|
|
|
|
config.config.to;
|
|
|
|
|
|
default:
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_supportsRelay(name) {
|
|
|
|
|
|
switch (name) {
|
|
|
|
|
|
case 'email':
|
|
|
|
|
|
return true;
|
|
|
|
|
|
case 'desktop':
|
|
|
|
|
|
default:
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async handleConfig(args) {
|
|
|
|
|
|
// Launch the configuration tool
|
|
|
|
|
|
const ConfigTool = require('./src/tools/config-manager');
|
|
|
|
|
|
const configTool = new ConfigTool(this.config);
|
|
|
|
|
|
await configTool.run(args);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async handleInstall(args) {
|
|
|
|
|
|
// Launch the installer
|
|
|
|
|
|
const Installer = require('./src/tools/installer');
|
|
|
|
|
|
const installer = new Installer(this.config);
|
|
|
|
|
|
await installer.run(args);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async handleRelay(args) {
|
|
|
|
|
|
const subcommand = args[0];
|
|
|
|
|
|
|
|
|
|
|
|
switch (subcommand) {
|
|
|
|
|
|
case 'start':
|
|
|
|
|
|
await this.startRelay(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'stop':
|
|
|
|
|
|
await this.stopRelay(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'status':
|
|
|
|
|
|
await this.relayStatus(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'cleanup':
|
|
|
|
|
|
await this.cleanupRelay(args.slice(1));
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
2025-07-28 02:21:38 +08:00
|
|
|
|
console.error('Usage: claude-remote relay <start|stop|status|cleanup>');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
console.log('');
|
|
|
|
|
|
console.log('Commands:');
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log(' start Start email command relay service');
|
|
|
|
|
|
console.log(' stop Stop email command relay service');
|
|
|
|
|
|
console.log(' status View relay service status');
|
|
|
|
|
|
console.log(' cleanup Clean up completed command history');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
process.exit(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async startRelay(args) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const CommandRelayService = require('./src/relay/command-relay');
|
|
|
|
|
|
const emailConfig = this.config.getChannel('email');
|
|
|
|
|
|
|
|
|
|
|
|
if (!emailConfig || !emailConfig.enabled) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.error('❌ Email channel not configured or disabled');
|
2025-07-28 02:21:38 +08:00
|
|
|
|
console.log('Please run first: claude-remote config');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
process.exit(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('🚀 Starting email command relay service...');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
const relayService = new CommandRelayService(emailConfig.config);
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Listen for events
|
2025-07-27 02:22:12 +08:00
|
|
|
|
relayService.on('started', () => {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('✅ Command relay service started');
|
|
|
|
|
|
console.log('📧 Listening for email replies...');
|
|
|
|
|
|
console.log('💡 You can now remotely execute Claude Code commands by replying to emails');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
console.log('');
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('Press Ctrl+C to stop the service');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
relayService.on('commandQueued', (command) => {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log(`📨 Received new command: ${command.command.substring(0, 50)}...`);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
relayService.on('commandExecuted', (command) => {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log(`✅ Command executed successfully: ${command.id}`);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
relayService.on('commandFailed', (command, error) => {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log(`❌ Command execution failed: ${command.id} - ${error.message}`);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Handle graceful shutdown
|
2025-07-27 02:22:12 +08:00
|
|
|
|
process.on('SIGINT', async () => {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('\n🛑 Stopping command relay service...');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
await relayService.stop();
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('✅ Service stopped');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
process.exit(0);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Start service
|
2025-07-27 02:22:12 +08:00
|
|
|
|
await relayService.start();
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Keep process running
|
2025-07-27 02:22:12 +08:00
|
|
|
|
process.stdin.resume();
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.error('❌ Failed to start relay service:', error.message);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
process.exit(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async stopRelay(args) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('💡 Command relay service usually stopped with Ctrl+C');
|
|
|
|
|
|
console.log('If the service is still running, please find the corresponding process and terminate it manually');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async relayStatus(args) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const fs = require('fs');
|
|
|
|
|
|
const path = require('path');
|
|
|
|
|
|
const stateFile = path.join(__dirname, 'src/data/relay-state.json');
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('📊 Command relay service status\n');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Check email configuration
|
2025-07-27 02:22:12 +08:00
|
|
|
|
const emailConfig = this.config.getChannel('email');
|
|
|
|
|
|
if (!emailConfig || !emailConfig.enabled) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('❌ Email channel not configured');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('✅ Email configuration enabled');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
console.log(`📧 SMTP: ${emailConfig.config.smtp.host}:${emailConfig.config.smtp.port}`);
|
|
|
|
|
|
console.log(`📥 IMAP: ${emailConfig.config.imap.host}:${emailConfig.config.imap.port}`);
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log(`📬 Recipient: ${emailConfig.config.to}`);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Check relay status
|
2025-07-27 02:22:12 +08:00
|
|
|
|
if (fs.existsSync(stateFile)) {
|
|
|
|
|
|
const state = JSON.parse(fs.readFileSync(stateFile, 'utf8'));
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log(`\n📋 Command queue: ${state.commandQueue?.length || 0} commands`);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
if (state.commandQueue && state.commandQueue.length > 0) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('\nRecent commands:');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
state.commandQueue.slice(-5).forEach(cmd => {
|
|
|
|
|
|
const status = cmd.status === 'completed' ? '✅' :
|
|
|
|
|
|
cmd.status === 'failed' ? '❌' :
|
|
|
|
|
|
cmd.status === 'executing' ? '⏳' : '⏸️';
|
|
|
|
|
|
console.log(` ${status} ${cmd.id}: ${cmd.command.substring(0, 50)}...`);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('\n📋 No command history found');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.error('❌ Failed to get status:', error.message);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async cleanupRelay(args) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const fs = require('fs');
|
|
|
|
|
|
const path = require('path');
|
|
|
|
|
|
const stateFile = path.join(__dirname, 'src/data/relay-state.json');
|
|
|
|
|
|
|
|
|
|
|
|
if (!fs.existsSync(stateFile)) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('📋 No cleanup needed, no command history found');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const state = JSON.parse(fs.readFileSync(stateFile, 'utf8'));
|
|
|
|
|
|
const beforeCount = state.commandQueue?.length || 0;
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Clean up completed commands (keep those within 24 hours)
|
2025-07-27 02:22:12 +08:00
|
|
|
|
const cutoff = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
|
|
|
|
|
state.commandQueue = (state.commandQueue || []).filter(cmd =>
|
|
|
|
|
|
cmd.status !== 'completed' ||
|
|
|
|
|
|
new Date(cmd.completedAt || cmd.queuedAt) > cutoff
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
const afterCount = state.commandQueue.length;
|
|
|
|
|
|
const removedCount = beforeCount - afterCount;
|
|
|
|
|
|
|
|
|
|
|
|
fs.writeFileSync(stateFile, JSON.stringify(state, null, 2));
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log(`🧹 Cleanup completed: removed ${removedCount} completed commands`);
|
|
|
|
|
|
console.log(`📋 ${afterCount} commands remaining in queue`);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.error('❌ Cleanup failed:', error.message);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async handleEditConfig(args) {
|
|
|
|
|
|
const { spawn } = require('child_process');
|
|
|
|
|
|
const path = require('path');
|
|
|
|
|
|
|
|
|
|
|
|
const configType = args[0];
|
|
|
|
|
|
|
|
|
|
|
|
if (!configType) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('Available configuration files:');
|
|
|
|
|
|
console.log(' user - User personal configuration (config/user.json)');
|
|
|
|
|
|
console.log(' channels - Notification channel configuration (config/channels.json)');
|
|
|
|
|
|
console.log(' default - Default configuration template (config/default.json)');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
console.log('');
|
2025-07-28 02:21:38 +08:00
|
|
|
|
console.log('Usage: claude-remote edit-config <configuration-type>');
|
|
|
|
|
|
console.log('Example: claude-remote edit-config channels');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const configFiles = {
|
|
|
|
|
|
'user': path.join(__dirname, 'config/user.json'),
|
|
|
|
|
|
'channels': path.join(__dirname, 'config/channels.json'),
|
|
|
|
|
|
'default': path.join(__dirname, 'config/default.json')
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const configFile = configFiles[configType];
|
|
|
|
|
|
if (!configFile) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.error('❌ Invalid configuration type:', configType);
|
|
|
|
|
|
console.log('Available types: user, channels, default');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Check if file exists
|
2025-07-27 02:22:12 +08:00
|
|
|
|
const fs = require('fs');
|
|
|
|
|
|
if (!fs.existsSync(configFile)) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.error('❌ Configuration file does not exist:', configFile);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log(`📝 Opening configuration file: ${configFile}`);
|
|
|
|
|
|
console.log('💡 Save and close the editor after editing to take effect');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
console.log('');
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Determine the editor to use
|
2025-07-27 02:22:12 +08:00
|
|
|
|
const editor = process.env.EDITOR || process.env.VISUAL || this._getDefaultEditor();
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const editorProcess = spawn(editor, [configFile], {
|
|
|
|
|
|
stdio: 'inherit'
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
editorProcess.on('close', (code) => {
|
|
|
|
|
|
if (code === 0) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('✅ Configuration file saved');
|
2025-07-28 02:21:38 +08:00
|
|
|
|
console.log('💡 Run "claude-remote status" to view updated configuration');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
} else {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('❌ Editor exited abnormally');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
editorProcess.on('error', (error) => {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.error('❌ Unable to start editor:', error.message);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
console.log('');
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('💡 You can manually edit the configuration file:');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
console.log(` ${configFile}`);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.error('❌ Failed to start editor:', error.message);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
console.log('');
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('💡 You can manually edit the configuration file:');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
console.log(` ${configFile}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_getDefaultEditor() {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Determine default editor based on platform
|
2025-07-27 02:22:12 +08:00
|
|
|
|
if (process.platform === 'win32') {
|
|
|
|
|
|
return 'notepad';
|
|
|
|
|
|
} else if (process.platform === 'darwin') {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
return 'nano'; // Use nano on macOS as most users have it
|
2025-07-27 02:22:12 +08:00
|
|
|
|
} else {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
return 'nano'; // Linux default to nano
|
2025-07-27 02:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async handleSetupEmail(args) {
|
|
|
|
|
|
const readline = require('readline');
|
|
|
|
|
|
const fs = require('fs');
|
|
|
|
|
|
const path = require('path');
|
|
|
|
|
|
|
|
|
|
|
|
const rl = readline.createInterface({
|
|
|
|
|
|
input: process.stdin,
|
|
|
|
|
|
output: process.stdout
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const question = (prompt) => {
|
|
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
|
|
rl.question(prompt, resolve);
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
2025-07-28 02:21:38 +08:00
|
|
|
|
console.log('🚀 Claude-Code-Remote Email Quick Setup Wizard\n');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Select email provider
|
|
|
|
|
|
console.log('Please select your email provider:');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
console.log('1. Gmail');
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('2. QQ Email');
|
|
|
|
|
|
console.log('3. 163 Email');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
console.log('4. Outlook/Hotmail');
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('5. Custom');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
const providerChoice = await question('\nPlease select (1-5): ');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
let smtpHost, smtpPort, imapHost, imapPort, secure;
|
|
|
|
|
|
|
|
|
|
|
|
switch (providerChoice) {
|
|
|
|
|
|
case '1':
|
|
|
|
|
|
smtpHost = 'smtp.gmail.com';
|
|
|
|
|
|
smtpPort = 587;
|
|
|
|
|
|
imapHost = 'imap.gmail.com';
|
|
|
|
|
|
imapPort = 993;
|
|
|
|
|
|
secure = false;
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('\n📧 Gmail Configuration');
|
|
|
|
|
|
console.log('💡 Need to enable two-factor authentication and generate app password first');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case '2':
|
|
|
|
|
|
smtpHost = 'smtp.qq.com';
|
|
|
|
|
|
smtpPort = 587;
|
|
|
|
|
|
imapHost = 'imap.qq.com';
|
|
|
|
|
|
imapPort = 993;
|
|
|
|
|
|
secure = false;
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('\n📧 QQ Email Configuration');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case '3':
|
|
|
|
|
|
smtpHost = 'smtp.163.com';
|
|
|
|
|
|
smtpPort = 587;
|
|
|
|
|
|
imapHost = 'imap.163.com';
|
|
|
|
|
|
imapPort = 993;
|
|
|
|
|
|
secure = false;
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('\n📧 163 Email Configuration');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case '4':
|
|
|
|
|
|
smtpHost = 'smtp.live.com';
|
|
|
|
|
|
smtpPort = 587;
|
|
|
|
|
|
imapHost = 'imap-mail.outlook.com';
|
|
|
|
|
|
imapPort = 993;
|
|
|
|
|
|
secure = false;
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('\n📧 Outlook Configuration');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case '5':
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('\n📧 Custom Configuration');
|
|
|
|
|
|
smtpHost = await question('SMTP Host: ');
|
|
|
|
|
|
smtpPort = parseInt(await question('SMTP Port (default 587): ') || '587');
|
|
|
|
|
|
imapHost = await question('IMAP Host: ');
|
|
|
|
|
|
imapPort = parseInt(await question('IMAP Port (default 993): ') || '993');
|
|
|
|
|
|
const secureInput = await question('Use SSL/TLS? (y/n): ');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
secure = secureInput.toLowerCase() === 'y';
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('❌ Invalid selection');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
rl.close();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Get email account information
|
|
|
|
|
|
console.log('\n📝 Please enter email account information:');
|
|
|
|
|
|
const email = await question('Email address: ');
|
|
|
|
|
|
const password = await question('Password/App password: ');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Build configuration
|
2025-07-27 02:22:12 +08:00
|
|
|
|
const emailConfig = {
|
|
|
|
|
|
type: "email",
|
|
|
|
|
|
enabled: true,
|
|
|
|
|
|
config: {
|
|
|
|
|
|
smtp: {
|
|
|
|
|
|
host: smtpHost,
|
|
|
|
|
|
port: smtpPort,
|
|
|
|
|
|
secure: secure,
|
|
|
|
|
|
auth: {
|
|
|
|
|
|
user: email,
|
|
|
|
|
|
pass: password
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
imap: {
|
|
|
|
|
|
host: imapHost,
|
|
|
|
|
|
port: imapPort,
|
|
|
|
|
|
secure: true,
|
|
|
|
|
|
auth: {
|
|
|
|
|
|
user: email,
|
|
|
|
|
|
pass: password
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2025-07-28 02:21:38 +08:00
|
|
|
|
from: `Claude-Code-Remote <${email}>`,
|
2025-07-27 02:22:12 +08:00
|
|
|
|
to: email,
|
|
|
|
|
|
template: {
|
|
|
|
|
|
checkInterval: 30
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Read existing configuration
|
2025-07-27 02:22:12 +08:00
|
|
|
|
const channelsFile = path.join(__dirname, 'config/channels.json');
|
|
|
|
|
|
let channels = {};
|
|
|
|
|
|
|
|
|
|
|
|
if (fs.existsSync(channelsFile)) {
|
|
|
|
|
|
channels = JSON.parse(fs.readFileSync(channelsFile, 'utf8'));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Update email configuration
|
2025-07-27 02:22:12 +08:00
|
|
|
|
channels.email = emailConfig;
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Save configuration
|
2025-07-27 02:22:12 +08:00
|
|
|
|
fs.writeFileSync(channelsFile, JSON.stringify(channels, null, 2));
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('\n✅ Email configuration saved!');
|
|
|
|
|
|
console.log('\n🧪 You can now test email functionality:');
|
2025-07-28 02:21:38 +08:00
|
|
|
|
console.log(' claude-remote test');
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('\n🚀 Start command relay service:');
|
2025-07-28 02:21:38 +08:00
|
|
|
|
console.log(' claude-remote relay start');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Ask if user wants to test immediately
|
|
|
|
|
|
const testNow = await question('\nTest email sending now? (y/n): ');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
if (testNow.toLowerCase() === 'y') {
|
|
|
|
|
|
rl.close();
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Reload configuration and test
|
2025-07-27 02:22:12 +08:00
|
|
|
|
await this.init();
|
|
|
|
|
|
await this.handleTest([]);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
rl.close();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.error('❌ Configuration failed:', error.message);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
rl.close();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async handleDaemon(args) {
|
2025-07-28 02:21:38 +08:00
|
|
|
|
const ClaudeCodeRemoteDaemon = require('./src/daemon/taskping-daemon');
|
|
|
|
|
|
const daemon = new ClaudeCodeRemoteDaemon();
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
const command = args[0];
|
|
|
|
|
|
|
|
|
|
|
|
switch (command) {
|
|
|
|
|
|
case 'start':
|
|
|
|
|
|
await daemon.start();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'stop':
|
|
|
|
|
|
await daemon.stop();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'restart':
|
|
|
|
|
|
await daemon.restart();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'status':
|
|
|
|
|
|
daemon.showStatus();
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
2025-07-28 02:21:38 +08:00
|
|
|
|
console.log('Usage: claude-remote daemon <start|stop|restart|status>');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
console.log('');
|
|
|
|
|
|
console.log('Commands:');
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log(' start Start background daemon process');
|
|
|
|
|
|
console.log(' stop Stop background daemon process');
|
|
|
|
|
|
console.log(' restart Restart background daemon process');
|
|
|
|
|
|
console.log(' status View daemon process status');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async handleCommands(args) {
|
|
|
|
|
|
const ClaudeCommandBridge = require('./src/relay/claude-command-bridge');
|
|
|
|
|
|
const bridge = new ClaudeCommandBridge();
|
|
|
|
|
|
|
|
|
|
|
|
const command = args[0];
|
|
|
|
|
|
|
|
|
|
|
|
switch (command) {
|
|
|
|
|
|
case 'list':
|
|
|
|
|
|
const pending = bridge.getPendingCommands();
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log(`📋 Pending commands: ${pending.length}\n`);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
if (pending.length > 0) {
|
|
|
|
|
|
pending.forEach((cmd, index) => {
|
|
|
|
|
|
console.log(`${index + 1}. ${cmd.id}`);
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log(` Command: ${cmd.command}`);
|
|
|
|
|
|
console.log(` Time: ${cmd.timestamp}`);
|
|
|
|
|
|
console.log(` Session: ${cmd.sessionId}`);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
console.log('');
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case 'status':
|
|
|
|
|
|
const status = bridge.getStatus();
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('📊 Command bridge status\n');
|
|
|
|
|
|
console.log(`Pending commands: ${status.pendingCommands}`);
|
|
|
|
|
|
console.log(`Processed commands: ${status.processedCommands}`);
|
|
|
|
|
|
console.log(`Commands directory: ${status.commandsDir}`);
|
|
|
|
|
|
console.log(`Response directory: ${status.responseDir}`);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
if (status.recentCommands.length > 0) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('\nRecent commands:');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
status.recentCommands.forEach(cmd => {
|
|
|
|
|
|
console.log(` • ${cmd.command} (${cmd.timestamp})`);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case 'cleanup':
|
|
|
|
|
|
bridge.cleanup();
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('🧹 Old command files cleaned up');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case 'clear':
|
|
|
|
|
|
const pending2 = bridge.getPendingCommands();
|
|
|
|
|
|
for (const cmd of pending2) {
|
|
|
|
|
|
bridge.markCommandProcessed(cmd.id, 'cancelled', 'Manually cancelled');
|
|
|
|
|
|
}
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log(`🗑️ Cleared ${pending2.length} pending commands`);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
2025-07-28 02:21:38 +08:00
|
|
|
|
console.log('Usage: claude-remote commands <list|status|cleanup|clear>');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
console.log('');
|
|
|
|
|
|
console.log('Commands:');
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log(' list Show pending email commands');
|
|
|
|
|
|
console.log(' status Show command bridge status');
|
|
|
|
|
|
console.log(' cleanup Clean up old command files');
|
|
|
|
|
|
console.log(' clear Clear all pending commands');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async handleTestPaste(args) {
|
|
|
|
|
|
const ClipboardAutomation = require('./src/automation/clipboard-automation');
|
|
|
|
|
|
const automation = new ClipboardAutomation();
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
const testCommand = args.join(' ') || 'echo "Testing email reply auto-paste functionality"';
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('🧪 Testing auto-paste functionality');
|
|
|
|
|
|
console.log(`📝 Test command: ${testCommand}`);
|
|
|
|
|
|
console.log('\n⚠️ Please ensure Claude Code or Terminal window is open and active');
|
|
|
|
|
|
console.log('⏳ Command will be sent automatically in 3 seconds...\n');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Countdown
|
2025-07-27 02:22:12 +08:00
|
|
|
|
for (let i = 3; i > 0; i--) {
|
|
|
|
|
|
process.stdout.write(`${i}... `);
|
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
|
|
|
|
}
|
|
|
|
|
|
console.log('\n');
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const success = await automation.sendCommand(testCommand);
|
|
|
|
|
|
if (success) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('✅ Command has been auto-pasted!');
|
|
|
|
|
|
console.log('💡 If you don\'t see the effect, please check app permissions and window status');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
} else {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('❌ Auto-paste failed');
|
|
|
|
|
|
console.log('💡 Please ensure automation permissions are granted and target app is open');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.error('❌ Test failed:', error.message);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async handleSetupPermissions(args) {
|
|
|
|
|
|
const PermissionSetup = require('./setup-permissions');
|
|
|
|
|
|
const setup = new PermissionSetup();
|
|
|
|
|
|
await setup.checkAndSetup();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async handleTestSimple(args) {
|
|
|
|
|
|
const SimpleAutomation = require('./src/automation/simple-automation');
|
|
|
|
|
|
const automation = new SimpleAutomation();
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
const testCommand = args.join(' ') || 'echo "Testing simple automation functionality"';
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('🧪 Testing simple automation functionality');
|
|
|
|
|
|
console.log(`📝 Test command: ${testCommand}`);
|
|
|
|
|
|
console.log('\nThis test will:');
|
|
|
|
|
|
console.log('1. 📋 Copy command to clipboard');
|
|
|
|
|
|
console.log('2. 📄 Save command to file');
|
|
|
|
|
|
console.log('3. 🔔 Send notification (including dialog box)');
|
|
|
|
|
|
console.log('4. 🤖 Attempt auto-paste (if permissions granted)');
|
|
|
|
|
|
console.log('\n⏳ Starting test...\n');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const success = await automation.sendCommand(testCommand, 'test-session');
|
|
|
|
|
|
if (success) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('✅ Test successful!');
|
|
|
|
|
|
console.log('\n📋 Next steps:');
|
|
|
|
|
|
console.log('1. Check if you received notification');
|
|
|
|
|
|
console.log('2. Check if command was copied to clipboard');
|
|
|
|
|
|
console.log('3. If you see dialog box, you can choose to open command file');
|
|
|
|
|
|
console.log('4. Manually paste to Claude Code (if auto-paste didn\'t work)');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
const status = automation.getStatus();
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log(`\n📄 Command file: ${status.commandFile}`);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
if (status.commandFileExists) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('💡 You can run "open -t ' + status.commandFile + '" to view command file');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
} else {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('❌ Test failed');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.error('❌ Error occurred during test:', error.message);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async handleTestClaude(args) {
|
|
|
|
|
|
const ClaudeAutomation = require('./src/automation/claude-automation');
|
|
|
|
|
|
const automation = new ClaudeAutomation();
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
const testCommand = args.join(' ') || 'echo "This is an automated test command from email reply"';
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('🤖 Testing Claude Code specialized automation');
|
|
|
|
|
|
console.log(`📝 Test command: ${testCommand}`);
|
|
|
|
|
|
console.log('\n⚠️ Please ensure:');
|
|
|
|
|
|
console.log(' 1. Claude Code application is open');
|
|
|
|
|
|
console.log(' 2. Or Terminal/iTerm2 etc. terminal applications are open');
|
|
|
|
|
|
console.log(' 3. Necessary accessibility permissions have been granted');
|
|
|
|
|
|
console.log('\n⏳ Full automation test will start in 5 seconds...\n');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Countdown
|
2025-07-27 02:22:12 +08:00
|
|
|
|
for (let i = 5; i > 0; i--) {
|
|
|
|
|
|
process.stdout.write(`${i}... `);
|
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
|
|
|
|
}
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('\n🚀 Starting automation...\n');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
try {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Check permissions
|
2025-07-27 02:22:12 +08:00
|
|
|
|
const hasPermission = await automation.requestPermissions();
|
|
|
|
|
|
if (!hasPermission) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('⚠️ Permission check failed, but will still attempt execution...');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-27 17:17:15 +08:00
|
|
|
|
// Execute full automation
|
2025-07-27 02:22:12 +08:00
|
|
|
|
const success = await automation.sendCommand(testCommand, 'test-session');
|
|
|
|
|
|
|
|
|
|
|
|
if (success) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('✅ Full automation test successful!');
|
|
|
|
|
|
console.log('💡 Command should have been automatically input to Claude Code and started execution');
|
|
|
|
|
|
console.log('🔍 Please check Claude Code window to see if command was received');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
} else {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log('❌ Automation test failed');
|
|
|
|
|
|
console.log('💡 Possible reasons:');
|
|
|
|
|
|
console.log(' • Claude Code or terminal application not found');
|
|
|
|
|
|
console.log(' • Insufficient permissions');
|
|
|
|
|
|
console.log(' • Application not responding');
|
|
|
|
|
|
console.log('\n🔧 Suggestions:');
|
2025-07-28 02:21:38 +08:00
|
|
|
|
console.log(' 1. Run "claude-remote setup-permissions" to check permissions');
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.log(' 2. Ensure Claude Code is running in foreground');
|
|
|
|
|
|
console.log(' 3. Try manually clicking input box in Claude Code first');
|
2025-07-27 02:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
2025-07-27 17:17:15 +08:00
|
|
|
|
console.error('❌ Error occurred during test:', error.message);
|
2025-07-27 02:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async handleDiagnose(args) {
|
|
|
|
|
|
const AutomationDiagnostic = require('./diagnose-automation');
|
|
|
|
|
|
const diagnostic = new AutomationDiagnostic();
|
|
|
|
|
|
await diagnostic.runDiagnostic();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
showHelp() {
|
|
|
|
|
|
console.log(`
|
2025-07-28 02:21:38 +08:00
|
|
|
|
Claude-Code-Remote - Claude Code Smart Notification System
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
2025-07-28 02:21:38 +08:00
|
|
|
|
Usage: claude-remote <command> [options]
|
2025-07-27 02:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
Commands:
|
|
|
|
|
|
notify --type <type> Send a notification (completed|waiting)
|
|
|
|
|
|
test Test all notification channels
|
|
|
|
|
|
status Show system status
|
|
|
|
|
|
config Launch configuration manager
|
|
|
|
|
|
setup-email Quick email setup wizard
|
|
|
|
|
|
edit-config <type> Edit configuration files directly
|
|
|
|
|
|
install Install and configure Claude Code hooks
|
|
|
|
|
|
relay <subcommand> Manage email command relay service
|
|
|
|
|
|
daemon <subcommand> Manage background daemon service
|
|
|
|
|
|
commands <subcommand> Manage email commands and bridge
|
|
|
|
|
|
test-paste [command] Test automatic paste functionality
|
|
|
|
|
|
test-simple [command] Test simple automation (recommended)
|
|
|
|
|
|
test-claude [command] Test Claude Code full automation
|
|
|
|
|
|
setup-permissions Setup macOS permissions for automation
|
|
|
|
|
|
diagnose Diagnose automation issues
|
|
|
|
|
|
|
|
|
|
|
|
Options:
|
|
|
|
|
|
-h, --help Show this help message
|
|
|
|
|
|
|
|
|
|
|
|
Relay Subcommands:
|
|
|
|
|
|
relay start Start email command relay service
|
|
|
|
|
|
relay stop Stop email command relay service
|
|
|
|
|
|
relay status Show relay service status
|
|
|
|
|
|
relay cleanup Clean up completed command history
|
|
|
|
|
|
|
|
|
|
|
|
Daemon Subcommands:
|
|
|
|
|
|
daemon start Start background daemon service
|
|
|
|
|
|
daemon stop Stop background daemon service
|
|
|
|
|
|
daemon restart Restart background daemon service
|
|
|
|
|
|
daemon status Show daemon service status
|
|
|
|
|
|
|
|
|
|
|
|
Commands Subcommands:
|
|
|
|
|
|
commands list Show pending email commands
|
|
|
|
|
|
commands status Show command bridge status
|
|
|
|
|
|
commands cleanup Clean up old command files
|
|
|
|
|
|
commands clear Clear all pending commands
|
|
|
|
|
|
|
|
|
|
|
|
Examples:
|
2025-07-28 02:21:38 +08:00
|
|
|
|
claude-remote notify --type completed
|
|
|
|
|
|
claude-remote test
|
|
|
|
|
|
claude-remote setup-email # Quick email setup (recommended)
|
|
|
|
|
|
claude-remote edit-config channels # Edit configuration files directly
|
|
|
|
|
|
claude-remote config # Interactive configuration
|
|
|
|
|
|
claude-remote install
|
|
|
|
|
|
claude-remote daemon start # Start background service (recommended)
|
|
|
|
|
|
claude-remote daemon status # View service status
|
|
|
|
|
|
claude-remote test-claude # Test full automation (recommended)
|
|
|
|
|
|
claude-remote commands list # View pending email commands
|
|
|
|
|
|
claude-remote relay start # Run in foreground (need to keep window open)
|
|
|
|
|
|
|
|
|
|
|
|
For more information, visit: https://github.com/Claude-Code-Remote/Claude-Code-Remote
|
2025-07-27 02:22:12 +08:00
|
|
|
|
`);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Run CLI if this file is executed directly
|
|
|
|
|
|
if (require.main === module) {
|
2025-07-28 02:21:38 +08:00
|
|
|
|
const cli = new ClaudeCodeRemoteCLI();
|
2025-07-27 02:22:12 +08:00
|
|
|
|
cli.run().catch(error => {
|
|
|
|
|
|
console.error('Fatal error:', error.message);
|
|
|
|
|
|
process.exit(1);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-28 02:21:38 +08:00
|
|
|
|
module.exports = ClaudeCodeRemoteCLI;
|