@jsayubi/ccgram 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/.env.example +19 -0
  2. package/LICENSE +21 -0
  3. package/README.md +338 -0
  4. package/ccgram.service +24 -0
  5. package/config/channels.json +58 -0
  6. package/config/default.json +27 -0
  7. package/config/defaults/config.json +16 -0
  8. package/config/defaults/i18n.json +32 -0
  9. package/config/email-template.json +31 -0
  10. package/config/test-with-subagent.json +16 -0
  11. package/config/user.json +27 -0
  12. package/dist/claude-hook-notify.d.ts +7 -0
  13. package/dist/claude-hook-notify.d.ts.map +1 -0
  14. package/dist/claude-hook-notify.js +154 -0
  15. package/dist/claude-hook-notify.js.map +1 -0
  16. package/dist/claude-remote.d.ts +50 -0
  17. package/dist/claude-remote.d.ts.map +1 -0
  18. package/dist/claude-remote.js +927 -0
  19. package/dist/claude-remote.js.map +1 -0
  20. package/dist/cli.d.ts +3 -0
  21. package/dist/cli.d.ts.map +1 -0
  22. package/dist/cli.js +110 -0
  23. package/dist/cli.js.map +1 -0
  24. package/dist/enhanced-hook-notify.d.ts +16 -0
  25. package/dist/enhanced-hook-notify.d.ts.map +1 -0
  26. package/dist/enhanced-hook-notify.js +288 -0
  27. package/dist/enhanced-hook-notify.js.map +1 -0
  28. package/dist/permission-hook.d.ts +15 -0
  29. package/dist/permission-hook.d.ts.map +1 -0
  30. package/dist/permission-hook.js +357 -0
  31. package/dist/permission-hook.js.map +1 -0
  32. package/dist/prompt-bridge.d.ts +50 -0
  33. package/dist/prompt-bridge.d.ts.map +1 -0
  34. package/dist/prompt-bridge.js +173 -0
  35. package/dist/prompt-bridge.js.map +1 -0
  36. package/dist/question-notify.d.ts +16 -0
  37. package/dist/question-notify.d.ts.map +1 -0
  38. package/dist/question-notify.js +272 -0
  39. package/dist/question-notify.js.map +1 -0
  40. package/dist/setup.d.ts +10 -0
  41. package/dist/setup.d.ts.map +1 -0
  42. package/dist/setup.js +649 -0
  43. package/dist/setup.js.map +1 -0
  44. package/dist/smart-monitor.d.ts +7 -0
  45. package/dist/smart-monitor.d.ts.map +1 -0
  46. package/dist/smart-monitor.js +256 -0
  47. package/dist/smart-monitor.js.map +1 -0
  48. package/dist/src/automation/claude-automation.d.ts +45 -0
  49. package/dist/src/automation/claude-automation.d.ts.map +1 -0
  50. package/dist/src/automation/claude-automation.js +367 -0
  51. package/dist/src/automation/claude-automation.js.map +1 -0
  52. package/dist/src/automation/clipboard-automation.d.ts +35 -0
  53. package/dist/src/automation/clipboard-automation.d.ts.map +1 -0
  54. package/dist/src/automation/clipboard-automation.js +242 -0
  55. package/dist/src/automation/clipboard-automation.js.map +1 -0
  56. package/dist/src/automation/simple-automation.d.ts +56 -0
  57. package/dist/src/automation/simple-automation.d.ts.map +1 -0
  58. package/dist/src/automation/simple-automation.js +283 -0
  59. package/dist/src/automation/simple-automation.js.map +1 -0
  60. package/dist/src/channels/base/channel.d.ts +60 -0
  61. package/dist/src/channels/base/channel.d.ts.map +1 -0
  62. package/dist/src/channels/base/channel.js +96 -0
  63. package/dist/src/channels/base/channel.js.map +1 -0
  64. package/dist/src/channels/email/smtp.d.ts +74 -0
  65. package/dist/src/channels/email/smtp.d.ts.map +1 -0
  66. package/dist/src/channels/email/smtp.js +605 -0
  67. package/dist/src/channels/email/smtp.js.map +1 -0
  68. package/dist/src/channels/line/line.d.ts +36 -0
  69. package/dist/src/channels/line/line.d.ts.map +1 -0
  70. package/dist/src/channels/line/line.js +180 -0
  71. package/dist/src/channels/line/line.js.map +1 -0
  72. package/dist/src/channels/line/webhook.d.ts +55 -0
  73. package/dist/src/channels/line/webhook.d.ts.map +1 -0
  74. package/dist/src/channels/line/webhook.js +191 -0
  75. package/dist/src/channels/line/webhook.js.map +1 -0
  76. package/dist/src/channels/local/desktop.d.ts +30 -0
  77. package/dist/src/channels/local/desktop.d.ts.map +1 -0
  78. package/dist/src/channels/local/desktop.js +161 -0
  79. package/dist/src/channels/local/desktop.js.map +1 -0
  80. package/dist/src/channels/telegram/telegram.d.ts +43 -0
  81. package/dist/src/channels/telegram/telegram.d.ts.map +1 -0
  82. package/dist/src/channels/telegram/telegram.js +223 -0
  83. package/dist/src/channels/telegram/telegram.js.map +1 -0
  84. package/dist/src/channels/telegram/webhook.d.ts +75 -0
  85. package/dist/src/channels/telegram/webhook.d.ts.map +1 -0
  86. package/dist/src/channels/telegram/webhook.js +278 -0
  87. package/dist/src/channels/telegram/webhook.js.map +1 -0
  88. package/dist/src/config-manager.d.ts +16 -0
  89. package/dist/src/config-manager.d.ts.map +1 -0
  90. package/dist/src/config-manager.js +152 -0
  91. package/dist/src/config-manager.js.map +1 -0
  92. package/dist/src/core/config.d.ts +28 -0
  93. package/dist/src/core/config.d.ts.map +1 -0
  94. package/dist/src/core/config.js +248 -0
  95. package/dist/src/core/config.js.map +1 -0
  96. package/dist/src/core/logger.d.ts +19 -0
  97. package/dist/src/core/logger.d.ts.map +1 -0
  98. package/dist/src/core/logger.js +47 -0
  99. package/dist/src/core/logger.js.map +1 -0
  100. package/dist/src/core/notifier.d.ts +45 -0
  101. package/dist/src/core/notifier.d.ts.map +1 -0
  102. package/dist/src/core/notifier.js +189 -0
  103. package/dist/src/core/notifier.js.map +1 -0
  104. package/dist/src/daemon/taskping-daemon.d.ts +38 -0
  105. package/dist/src/daemon/taskping-daemon.d.ts.map +1 -0
  106. package/dist/src/daemon/taskping-daemon.js +306 -0
  107. package/dist/src/daemon/taskping-daemon.js.map +1 -0
  108. package/dist/src/relay/claude-command-bridge.d.ts +57 -0
  109. package/dist/src/relay/claude-command-bridge.d.ts.map +1 -0
  110. package/dist/src/relay/claude-command-bridge.js +188 -0
  111. package/dist/src/relay/claude-command-bridge.js.map +1 -0
  112. package/dist/src/relay/command-relay.d.ts +94 -0
  113. package/dist/src/relay/command-relay.d.ts.map +1 -0
  114. package/dist/src/relay/command-relay.js +463 -0
  115. package/dist/src/relay/command-relay.js.map +1 -0
  116. package/dist/src/relay/email-listener.d.ts +65 -0
  117. package/dist/src/relay/email-listener.d.ts.map +1 -0
  118. package/dist/src/relay/email-listener.js +460 -0
  119. package/dist/src/relay/email-listener.js.map +1 -0
  120. package/dist/src/relay/relay-pty.d.ts +21 -0
  121. package/dist/src/relay/relay-pty.d.ts.map +1 -0
  122. package/dist/src/relay/relay-pty.js +696 -0
  123. package/dist/src/relay/relay-pty.js.map +1 -0
  124. package/dist/src/relay/smart-injector.d.ts +30 -0
  125. package/dist/src/relay/smart-injector.d.ts.map +1 -0
  126. package/dist/src/relay/smart-injector.js +233 -0
  127. package/dist/src/relay/smart-injector.js.map +1 -0
  128. package/dist/src/relay/tmux-injector.d.ts +46 -0
  129. package/dist/src/relay/tmux-injector.d.ts.map +1 -0
  130. package/dist/src/relay/tmux-injector.js +413 -0
  131. package/dist/src/relay/tmux-injector.js.map +1 -0
  132. package/dist/src/tools/config-manager.d.ts +33 -0
  133. package/dist/src/tools/config-manager.d.ts.map +1 -0
  134. package/dist/src/tools/config-manager.js +448 -0
  135. package/dist/src/tools/config-manager.js.map +1 -0
  136. package/dist/src/tools/installer.d.ts +38 -0
  137. package/dist/src/tools/installer.d.ts.map +1 -0
  138. package/dist/src/tools/installer.js +222 -0
  139. package/dist/src/tools/installer.js.map +1 -0
  140. package/dist/src/types/callbacks.d.ts +29 -0
  141. package/dist/src/types/callbacks.d.ts.map +1 -0
  142. package/dist/src/types/callbacks.js +7 -0
  143. package/dist/src/types/callbacks.js.map +1 -0
  144. package/dist/src/types/config.d.ts +56 -0
  145. package/dist/src/types/config.d.ts.map +1 -0
  146. package/dist/src/types/config.js +6 -0
  147. package/dist/src/types/config.js.map +1 -0
  148. package/dist/src/types/hooks.d.ts +47 -0
  149. package/dist/src/types/hooks.d.ts.map +1 -0
  150. package/dist/src/types/hooks.js +6 -0
  151. package/dist/src/types/hooks.js.map +1 -0
  152. package/dist/src/types/index.d.ts +7 -0
  153. package/dist/src/types/index.d.ts.map +1 -0
  154. package/dist/src/types/index.js +23 -0
  155. package/dist/src/types/index.js.map +1 -0
  156. package/dist/src/types/ipc.d.ts +43 -0
  157. package/dist/src/types/ipc.d.ts.map +1 -0
  158. package/dist/src/types/ipc.js +7 -0
  159. package/dist/src/types/ipc.js.map +1 -0
  160. package/dist/src/types/session.d.ts +70 -0
  161. package/dist/src/types/session.d.ts.map +1 -0
  162. package/dist/src/types/session.js +9 -0
  163. package/dist/src/types/session.js.map +1 -0
  164. package/dist/src/types/telegram.d.ts +58 -0
  165. package/dist/src/types/telegram.d.ts.map +1 -0
  166. package/dist/src/types/telegram.js +6 -0
  167. package/dist/src/types/telegram.js.map +1 -0
  168. package/dist/src/utils/active-check.d.ts +19 -0
  169. package/dist/src/utils/active-check.d.ts.map +1 -0
  170. package/dist/src/utils/active-check.js +41 -0
  171. package/dist/src/utils/active-check.js.map +1 -0
  172. package/dist/src/utils/callback-parser.d.ts +21 -0
  173. package/dist/src/utils/callback-parser.d.ts.map +1 -0
  174. package/dist/src/utils/callback-parser.js +58 -0
  175. package/dist/src/utils/callback-parser.js.map +1 -0
  176. package/dist/src/utils/controller-injector.d.ts +21 -0
  177. package/dist/src/utils/controller-injector.d.ts.map +1 -0
  178. package/dist/src/utils/controller-injector.js +108 -0
  179. package/dist/src/utils/controller-injector.js.map +1 -0
  180. package/dist/src/utils/conversation-tracker.d.ts +32 -0
  181. package/dist/src/utils/conversation-tracker.d.ts.map +1 -0
  182. package/dist/src/utils/conversation-tracker.js +119 -0
  183. package/dist/src/utils/conversation-tracker.js.map +1 -0
  184. package/dist/src/utils/http-request.d.ts +25 -0
  185. package/dist/src/utils/http-request.d.ts.map +1 -0
  186. package/dist/src/utils/http-request.js +66 -0
  187. package/dist/src/utils/http-request.js.map +1 -0
  188. package/dist/src/utils/optional-require.d.ts +13 -0
  189. package/dist/src/utils/optional-require.d.ts.map +1 -0
  190. package/dist/src/utils/optional-require.js +37 -0
  191. package/dist/src/utils/optional-require.js.map +1 -0
  192. package/dist/src/utils/paths.d.ts +11 -0
  193. package/dist/src/utils/paths.d.ts.map +1 -0
  194. package/dist/src/utils/paths.js +28 -0
  195. package/dist/src/utils/paths.js.map +1 -0
  196. package/dist/src/utils/pty-session-manager.d.ts +42 -0
  197. package/dist/src/utils/pty-session-manager.d.ts.map +1 -0
  198. package/dist/src/utils/pty-session-manager.js +182 -0
  199. package/dist/src/utils/pty-session-manager.js.map +1 -0
  200. package/dist/src/utils/subagent-tracker.d.ts +64 -0
  201. package/dist/src/utils/subagent-tracker.d.ts.map +1 -0
  202. package/dist/src/utils/subagent-tracker.js +191 -0
  203. package/dist/src/utils/subagent-tracker.js.map +1 -0
  204. package/dist/src/utils/tmux-monitor.d.ts +102 -0
  205. package/dist/src/utils/tmux-monitor.d.ts.map +1 -0
  206. package/dist/src/utils/tmux-monitor.js +642 -0
  207. package/dist/src/utils/tmux-monitor.js.map +1 -0
  208. package/dist/src/utils/trace-capture.d.ts +42 -0
  209. package/dist/src/utils/trace-capture.d.ts.map +1 -0
  210. package/dist/src/utils/trace-capture.js +102 -0
  211. package/dist/src/utils/trace-capture.js.map +1 -0
  212. package/dist/start-all-webhooks.d.ts +7 -0
  213. package/dist/start-all-webhooks.d.ts.map +1 -0
  214. package/dist/start-all-webhooks.js +98 -0
  215. package/dist/start-all-webhooks.js.map +1 -0
  216. package/dist/start-line-webhook.d.ts +7 -0
  217. package/dist/start-line-webhook.d.ts.map +1 -0
  218. package/dist/start-line-webhook.js +59 -0
  219. package/dist/start-line-webhook.js.map +1 -0
  220. package/dist/start-relay-pty.d.ts +7 -0
  221. package/dist/start-relay-pty.d.ts.map +1 -0
  222. package/dist/start-relay-pty.js +173 -0
  223. package/dist/start-relay-pty.js.map +1 -0
  224. package/dist/start-telegram-webhook.d.ts +7 -0
  225. package/dist/start-telegram-webhook.d.ts.map +1 -0
  226. package/dist/start-telegram-webhook.js +80 -0
  227. package/dist/start-telegram-webhook.js.map +1 -0
  228. package/dist/user-prompt-hook.d.ts +13 -0
  229. package/dist/user-prompt-hook.d.ts.map +1 -0
  230. package/dist/user-prompt-hook.js +45 -0
  231. package/dist/user-prompt-hook.js.map +1 -0
  232. package/dist/workspace-router.d.ts +78 -0
  233. package/dist/workspace-router.d.ts.map +1 -0
  234. package/dist/workspace-router.js +408 -0
  235. package/dist/workspace-router.js.map +1 -0
  236. package/dist/workspace-telegram-bot.d.ts +3 -0
  237. package/dist/workspace-telegram-bot.d.ts.map +1 -0
  238. package/dist/workspace-telegram-bot.js +1172 -0
  239. package/dist/workspace-telegram-bot.js.map +1 -0
  240. package/package.json +80 -0
  241. package/src/types/callbacks.ts +39 -0
  242. package/src/types/config.ts +63 -0
  243. package/src/types/hooks.ts +50 -0
  244. package/src/types/index.ts +6 -0
  245. package/src/types/ipc.ts +55 -0
  246. package/src/types/session.ts +72 -0
  247. package/src/types/telegram.ts +66 -0
@@ -0,0 +1,605 @@
1
+ "use strict";
2
+ /**
3
+ * Email Notification Channel
4
+ * Sends notifications via email with reply support
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ const channel_1 = __importDefault(require("../base/channel"));
10
+ const optional_require_1 = require("../../utils/optional-require");
11
+ const nodemailer = (0, optional_require_1.optionalRequire)('nodemailer', 'email notifications');
12
+ const uuidv4 = (0, optional_require_1.getUUID)();
13
+ const path_1 = __importDefault(require("path"));
14
+ const fs_1 = __importDefault(require("fs"));
15
+ const tmux_monitor_1 = __importDefault(require("../../utils/tmux-monitor"));
16
+ const child_process_1 = require("child_process");
17
+ class EmailChannel extends channel_1.default {
18
+ transporter;
19
+ sessionsDir;
20
+ templatesDir;
21
+ sentMessagesPath;
22
+ tmuxMonitor;
23
+ constructor(config = {}) {
24
+ super('email', config);
25
+ this.transporter = null;
26
+ this.sessionsDir = path_1.default.join(__dirname, '../../data/sessions');
27
+ this.templatesDir = path_1.default.join(__dirname, '../../assets/email-templates');
28
+ this.sentMessagesPath = config.sentMessagesPath || path_1.default.join(__dirname, '../../data/sent-messages.json');
29
+ this.tmuxMonitor = new tmux_monitor_1.default();
30
+ this._ensureDirectories();
31
+ this._initializeTransporter();
32
+ }
33
+ _escapeHtml(text) {
34
+ if (!text)
35
+ return '';
36
+ const htmlEntities = {
37
+ '&': '&',
38
+ '<': '&lt;',
39
+ '>': '&gt;',
40
+ '"': '&quot;',
41
+ "'": '&#39;'
42
+ };
43
+ return text.replace(/[&<>"']/g, char => htmlEntities[char]);
44
+ }
45
+ _ensureDirectories() {
46
+ if (!fs_1.default.existsSync(this.sessionsDir)) {
47
+ fs_1.default.mkdirSync(this.sessionsDir, { recursive: true });
48
+ }
49
+ if (!fs_1.default.existsSync(this.templatesDir)) {
50
+ fs_1.default.mkdirSync(this.templatesDir, { recursive: true });
51
+ }
52
+ }
53
+ _generateToken() {
54
+ // Generate short Token (uppercase letters + numbers, 8 digits)
55
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
56
+ let token = '';
57
+ for (let i = 0; i < 8; i++) {
58
+ token += chars.charAt(Math.floor(Math.random() * chars.length));
59
+ }
60
+ return token;
61
+ }
62
+ _initializeTransporter() {
63
+ if (!nodemailer) {
64
+ this.logger.warn('nodemailer not installed. Email notifications unavailable. Install with: npm install nodemailer');
65
+ return;
66
+ }
67
+ const config = this.config;
68
+ if (!config.smtp) {
69
+ this.logger.warn('SMTP configuration not found');
70
+ return;
71
+ }
72
+ try {
73
+ this.transporter = nodemailer.createTransport({
74
+ host: config.smtp.host,
75
+ port: config.smtp.port,
76
+ secure: config.smtp.secure || false,
77
+ auth: {
78
+ user: config.smtp.auth.user,
79
+ pass: config.smtp.auth.pass
80
+ },
81
+ // Add timeout settings
82
+ connectionTimeout: parseInt(process.env.SMTP_TIMEOUT) || 10000,
83
+ greetingTimeout: parseInt(process.env.SMTP_TIMEOUT) || 10000,
84
+ socketTimeout: parseInt(process.env.SMTP_TIMEOUT) || 10000
85
+ });
86
+ this.logger.debug('Email transporter initialized');
87
+ }
88
+ catch (error) {
89
+ this.logger.error('Failed to initialize email transporter:', error.message);
90
+ }
91
+ }
92
+ _getCurrentTmuxSession() {
93
+ try {
94
+ // Try to get current tmux session
95
+ const tmuxSession = (0, child_process_1.execSync)('tmux display-message -p "#S"', {
96
+ encoding: 'utf8',
97
+ stdio: ['ignore', 'pipe', 'ignore']
98
+ }).trim();
99
+ return tmuxSession || null;
100
+ }
101
+ catch (error) {
102
+ // Not in a tmux session or tmux not available
103
+ return null;
104
+ }
105
+ }
106
+ async _sendImpl(notification) {
107
+ if (!this.transporter) {
108
+ throw new Error('Email transporter not initialized');
109
+ }
110
+ const config = this.config;
111
+ if (!config.to) {
112
+ throw new Error('Email recipient not configured');
113
+ }
114
+ // Generate session ID and Token
115
+ const sessionId = uuidv4();
116
+ const token = this._generateToken();
117
+ // Get current tmux session and conversation content
118
+ const tmuxSession = this._getCurrentTmuxSession();
119
+ if (tmuxSession && !notification.metadata) {
120
+ const conversation = this.tmuxMonitor.getRecentConversation(tmuxSession);
121
+ const fullTrace = this.tmuxMonitor.getFullExecutionTrace(tmuxSession);
122
+ notification.metadata = {
123
+ userQuestion: conversation.userQuestion || notification.message,
124
+ claudeResponse: conversation.claudeResponse || notification.message,
125
+ tmuxSession: tmuxSession,
126
+ fullExecutionTrace: fullTrace,
127
+ timestamp: new Date().toISOString(),
128
+ language: 'en'
129
+ };
130
+ }
131
+ // Create session record
132
+ await this._createSession(sessionId, notification, token);
133
+ // Generate email content
134
+ const emailContent = this._generateEmailContent(notification, sessionId, token);
135
+ // Generate unique Message-ID
136
+ const messageId = `<${sessionId}-${Date.now()}@ccgram>`;
137
+ const mailOptions = {
138
+ from: config.from || config.smtp.auth.user,
139
+ to: config.to,
140
+ subject: emailContent.subject,
141
+ html: emailContent.html,
142
+ text: emailContent.text,
143
+ messageId: messageId,
144
+ // Add custom headers for reply recognition
145
+ headers: {
146
+ 'X-CCGram-Session-ID': sessionId,
147
+ 'X-CCGram-Type': notification.type
148
+ }
149
+ };
150
+ try {
151
+ const result = await this.transporter.sendMail(mailOptions);
152
+ this.logger.info(`Email sent successfully to ${config.to}, Session: ${sessionId}`);
153
+ // Track sent message
154
+ await this._trackSentMessage(messageId, sessionId, token);
155
+ return true;
156
+ }
157
+ catch (error) {
158
+ this.logger.error('Failed to send email:', error.message);
159
+ // Clean up failed session
160
+ await this._removeSession(sessionId);
161
+ return false;
162
+ }
163
+ }
164
+ async _createSession(sessionId, notification, token) {
165
+ const session = {
166
+ id: sessionId,
167
+ token: token,
168
+ type: 'pty',
169
+ created: new Date().toISOString(),
170
+ expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), // Expires after 24 hours
171
+ createdAt: Math.floor(Date.now() / 1000),
172
+ expiresAt: Math.floor((Date.now() + 24 * 60 * 60 * 1000) / 1000),
173
+ cwd: process.cwd(),
174
+ notification: {
175
+ type: notification.type,
176
+ project: notification.project,
177
+ message: notification.message
178
+ },
179
+ status: 'waiting',
180
+ commandCount: 0,
181
+ maxCommands: 10
182
+ };
183
+ const sessionFile = path_1.default.join(this.sessionsDir, `${sessionId}.json`);
184
+ fs_1.default.writeFileSync(sessionFile, JSON.stringify(session, null, 2));
185
+ // Also save in PTY mapping format
186
+ const sessionMapPath = process.env.SESSION_MAP_PATH || path_1.default.join(__dirname, '../../data/session-map.json');
187
+ let sessionMap = {};
188
+ if (fs_1.default.existsSync(sessionMapPath)) {
189
+ try {
190
+ sessionMap = JSON.parse(fs_1.default.readFileSync(sessionMapPath, 'utf8'));
191
+ }
192
+ catch (e) {
193
+ sessionMap = {};
194
+ }
195
+ }
196
+ // Use passed tmux session name or detect current session
197
+ const tmuxSession = notification.metadata?.tmuxSession || this._getCurrentTmuxSession() || 'ccgram';
198
+ sessionMap[token] = {
199
+ type: 'pty',
200
+ createdAt: Math.floor(Date.now() / 1000),
201
+ expiresAt: Math.floor((Date.now() + 24 * 60 * 60 * 1000) / 1000),
202
+ cwd: process.cwd(),
203
+ sessionId: sessionId,
204
+ tmuxSession: tmuxSession,
205
+ description: `${notification.type} - ${notification.project}`
206
+ };
207
+ // Ensure directory exists
208
+ const mapDir = path_1.default.dirname(sessionMapPath);
209
+ if (!fs_1.default.existsSync(mapDir)) {
210
+ fs_1.default.mkdirSync(mapDir, { recursive: true });
211
+ }
212
+ fs_1.default.writeFileSync(sessionMapPath, JSON.stringify(sessionMap, null, 2));
213
+ this.logger.debug(`Session created: ${sessionId}, Token: ${token}`);
214
+ }
215
+ async _removeSession(sessionId) {
216
+ const sessionFile = path_1.default.join(this.sessionsDir, `${sessionId}.json`);
217
+ if (fs_1.default.existsSync(sessionFile)) {
218
+ fs_1.default.unlinkSync(sessionFile);
219
+ this.logger.debug(`Session removed: ${sessionId}`);
220
+ }
221
+ }
222
+ async _trackSentMessage(messageId, sessionId, token) {
223
+ let sentMessages = { messages: [] };
224
+ // Read existing data if file exists
225
+ if (fs_1.default.existsSync(this.sentMessagesPath)) {
226
+ try {
227
+ sentMessages = JSON.parse(fs_1.default.readFileSync(this.sentMessagesPath, 'utf8'));
228
+ }
229
+ catch (e) {
230
+ this.logger.warn('Failed to read sent-messages.json, creating new one');
231
+ }
232
+ }
233
+ // Add new message
234
+ sentMessages.messages.push({
235
+ messageId: messageId,
236
+ sessionId: sessionId,
237
+ token: token,
238
+ type: 'notification',
239
+ sentAt: new Date().toISOString()
240
+ });
241
+ // Ensure directory exists
242
+ const dir = path_1.default.dirname(this.sentMessagesPath);
243
+ if (!fs_1.default.existsSync(dir)) {
244
+ fs_1.default.mkdirSync(dir, { recursive: true });
245
+ }
246
+ // Write updated data
247
+ fs_1.default.writeFileSync(this.sentMessagesPath, JSON.stringify(sentMessages, null, 2));
248
+ this.logger.debug(`Tracked sent message: ${messageId}`);
249
+ }
250
+ _generateEmailContent(notification, sessionId, token) {
251
+ const template = this._getTemplate(notification.type);
252
+ const timestamp = new Date().toLocaleString('zh-CN');
253
+ // Get project directory name (last level directory)
254
+ const projectDir = path_1.default.basename(process.cwd());
255
+ // Extract user question (from notification.metadata if available)
256
+ let userQuestion = '';
257
+ let claudeResponse = '';
258
+ if (notification.metadata) {
259
+ userQuestion = notification.metadata.userQuestion || '';
260
+ claudeResponse = notification.metadata.claudeResponse || '';
261
+ }
262
+ // Limit user question length for title
263
+ const maxQuestionLength = 30;
264
+ const shortQuestion = userQuestion.length > maxQuestionLength ?
265
+ userQuestion.substring(0, maxQuestionLength) + '...' : userQuestion;
266
+ // Generate more distinctive title
267
+ let enhancedSubject = template.subject;
268
+ if (shortQuestion) {
269
+ enhancedSubject = enhancedSubject.replace('{{project}}', `${projectDir} | ${shortQuestion}`);
270
+ }
271
+ else {
272
+ enhancedSubject = enhancedSubject.replace('{{project}}', projectDir);
273
+ }
274
+ // Check if execution trace should be included
275
+ const config = this.config;
276
+ const includeExecutionTrace = config.includeExecutionTrace !== false; // Default to true
277
+ // Generate execution trace section HTML
278
+ let executionTraceSection = '';
279
+ let executionTraceText = '';
280
+ if (includeExecutionTrace) {
281
+ executionTraceSection = `
282
+ <!-- Full Execution Trace (Terminal Style) -->
283
+ <div style="margin-top: 40px; border-top: 1px solid #333; padding-top: 30px;">
284
+ <div style="color: #666; margin-bottom: 15px;">
285
+ <span style="color: #666;">$</span> <span style="color: #666;">tail -n 1000 execution.log</span>
286
+ </div>
287
+ <div style="margin-left: 20px;">
288
+ <div style="color: #666; font-size: 12px; margin-bottom: 10px;">
289
+ <span style="color: #999;">[</span><span style="color: #666;">Execution Trace - Scroll to view</span><span style="color: #999;">]</span>
290
+ </div>
291
+ <div style="background-color: #0d0d0d; border: 1px solid #222; padding: 15px; max-height: 300px; overflow-y: auto; overflow-x: auto; scrollbar-width: thin; scrollbar-color: #444 #0d0d0d;">
292
+ <pre style="margin: 0; color: #888; font-size: 11px; line-height: 1.4; white-space: pre-wrap; word-wrap: break-word; font-family: 'Consolas', 'Monaco', 'Courier New', monospace;">{{fullExecutionTrace}}</pre>
293
+ </div>
294
+ </div>
295
+ </div>`;
296
+ executionTraceText = `
297
+
298
+ ====== FULL EXECUTION TRACE ======
299
+ {{fullExecutionTrace}}
300
+ ==================================`;
301
+ }
302
+ // Template variable replacement
303
+ const variables = {
304
+ project: projectDir,
305
+ message: notification.message,
306
+ timestamp: timestamp,
307
+ sessionId: sessionId,
308
+ token: token,
309
+ type: notification.type === 'completed' ? 'Task completed' : 'Waiting for input',
310
+ userQuestion: userQuestion || 'No specified task',
311
+ claudeResponse: claudeResponse || notification.message,
312
+ projectDir: projectDir,
313
+ shortQuestion: shortQuestion || 'No specific question',
314
+ subagentActivities: notification.metadata?.subagentActivities || '',
315
+ executionTraceSection: executionTraceSection,
316
+ executionTraceText: executionTraceText,
317
+ fullExecutionTrace: notification.metadata?.fullExecutionTrace ||
318
+ 'No execution trace available. This may occur if the task completed very quickly or if tmux session logging is not enabled.'
319
+ };
320
+ let subject = enhancedSubject;
321
+ let html = template.html;
322
+ let text = template.text;
323
+ // Replace template variables
324
+ Object.keys(variables).forEach(key => {
325
+ const placeholder = new RegExp(`{{${key}}}`, 'g');
326
+ subject = subject.replace(placeholder, variables[key]);
327
+ // Special handling for HTML content - don't escape
328
+ if (key === 'subagentActivities' || key === 'executionTraceSection') {
329
+ html = html.replace(placeholder, variables[key]);
330
+ }
331
+ else {
332
+ // Escape HTML entities for other content
333
+ html = html.replace(placeholder, this._escapeHtml(variables[key]));
334
+ }
335
+ // No escaping needed for plain text
336
+ text = text.replace(placeholder, variables[key]);
337
+ });
338
+ return { subject, html, text };
339
+ }
340
+ _getTemplate(type) {
341
+ // Default templates
342
+ const templates = {
343
+ completed: {
344
+ subject: '[CCGram #{{token}}] Claude Code Task Completed - {{project}}',
345
+ html: `
346
+ <div style="font-family: 'Consolas', 'Monaco', 'Courier New', monospace; background-color: #f5f5f5; padding: 0; margin: 0;">
347
+ <div style="max-width: 900px; margin: 0 auto; background-color: #1e1e1e; border: 1px solid #333; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);">
348
+ <!-- Terminal Header -->
349
+ <div style="background-color: #2d2d2d; padding: 10px 15px; border-bottom: 1px solid #444;">
350
+ <table style="display: inline-table; vertical-align: middle;" cellpadding="0" cellspacing="0">
351
+ <tr>
352
+ <td style="padding: 0;"><div style="width: 12px; height: 12px; border-radius: 50%; background-color: #ff5f56;"></div></td>
353
+ <td style="padding: 0 0 0 5px;"><div style="width: 12px; height: 12px; border-radius: 50%; background-color: #ffbd2e;"></div></td>
354
+ <td style="padding: 0 0 0 5px;"><div style="width: 12px; height: 12px; border-radius: 50%; background-color: #27c93f;"></div></td>
355
+ <td style="padding: 0 0 0 12px; color: #999; font-size: 14px; white-space: nowrap;">ccgram@{{project}} - Task Completed</td>
356
+ </tr>
357
+ </table>
358
+ </div>
359
+
360
+ <!-- Terminal Content -->
361
+ <div style="padding: 20px; background-color: #1a1a1a; min-height: 400px;">
362
+ <!-- User Input (Terminal Style) -->
363
+ <div style="margin-bottom: 30px;">
364
+ <div style="color: #00ff00; margin-bottom: 10px;">
365
+ <span style="color: #999;">$</span> <span style="color: #00ff00;">cat user_request.txt</span>
366
+ </div>
367
+ <div style="background-color: #262626; border-left: 4px solid #ff9800; padding: 15px 20px; margin-left: 20px; color: #f0f0f0; font-size: 15px; line-height: 1.6; font-weight: 500;">{{userQuestion}}</div>
368
+ </div>
369
+
370
+ <!-- Claude Response (Terminal Style) -->
371
+ <div style="margin-bottom: 30px;">
372
+ <div style="color: #00ff00; margin-bottom: 10px;">
373
+ <span style="color: #999;">$</span> <span style="color: #00ff00;">claude-code execute</span>
374
+ </div>
375
+ <div style="margin-left: 20px;">
376
+ <div style="color: #999; margin-bottom: 10px; font-size: 13px;">
377
+ <span style="color: #00bcd4;">[INFO]</span> Processing request...<br>
378
+ <span style="color: #00bcd4;">[INFO]</span> Task execution started at {{timestamp}}
379
+ </div>
380
+ <div style="background-color: #1f1f1f; border-left: 4px solid #00ff00; padding: 15px 20px; color: #f0f0f0; font-size: 14px; line-height: 1.6; white-space: pre-wrap; word-wrap: break-word;">{{claudeResponse}}</div>
381
+ <div style="color: #00ff00; margin-top: 10px; font-size: 13px;">
382
+ <span style="color: #00bcd4;">[SUCCESS]</span> Task completed successfully ✓
383
+ </div>
384
+ </div>
385
+ </div>
386
+
387
+ {{subagentActivities}}
388
+
389
+ <!-- Continue Instructions (Terminal Style) -->
390
+ <div style="margin: 40px 0; padding-top: 30px; border-top: 1px solid #333;">
391
+ <div style="color: #ff9800; margin-bottom: 15px;">
392
+ <span style="color: #999;">$</span> <span style="color: #ff9800;">claude-code --help continue</span>
393
+ </div>
394
+ <div style="margin-left: 20px; background-color: #0d0d0d; padding: 15px; border: 1px solid #333;">
395
+ <div style="color: #00ff00; margin-bottom: 10px; font-weight: bold;">TO CONTINUE THIS SESSION:</div>
396
+ <div style="color: #ccc; font-size: 13px; line-height: 1.8;">
397
+ Reply to this email directly with your next instruction.<br><br>
398
+ <span style="color: #666;">Examples:</span><br>
399
+ <span style="color: #999;">•</span> <span style="color: #00ff00;">"Add error handling to the function"</span><br>
400
+ <span style="color: #999;">•</span> <span style="color: #00ff00;">"Write unit tests for this code"</span><br>
401
+ <span style="color: #999;">•</span> <span style="color: #00ff00;">"Optimize the performance"</span>
402
+ </div>
403
+ </div>
404
+ </div>
405
+
406
+ {{executionTraceSection}}
407
+ </div>
408
+ </div>
409
+ </div>
410
+ `,
411
+ text: `
412
+ [CCGram #{{token}}] Claude Code Task Completed - {{projectDir}} | {{shortQuestion}}
413
+
414
+ Project: {{projectDir}}
415
+ Time: {{timestamp}}
416
+ Status: {{type}}
417
+
418
+ 📝 Your Question:
419
+ {{userQuestion}}
420
+
421
+ 🤖 Claude's Response:
422
+ {{claudeResponse}}
423
+
424
+ {{subagentActivities}}{{executionTraceText}}
425
+
426
+ How to Continue Conversation:
427
+ To continue conversation with Claude Code, please reply to this email directly and enter your instructions in the email body.
428
+
429
+ Example Replies:
430
+ • "Please continue optimizing the code"
431
+ • "Generate unit tests"
432
+ • "Explain the purpose of this function"
433
+
434
+ Session ID: {{sessionId}}
435
+ Security Note: Please do not forward this email, session will automatically expire after 24 hours
436
+ `
437
+ },
438
+ waiting: {
439
+ subject: '[CCGram #{{token}}] Claude Code Waiting for Input - {{project}}',
440
+ html: `
441
+ <div style="font-family: 'Consolas', 'Monaco', 'Courier New', monospace; background-color: #f5f5f5; padding: 0; margin: 0;">
442
+ <div style="max-width: 900px; margin: 0 auto; background-color: #1e1e1e; border: 1px solid #333; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);">
443
+ <!-- Terminal Header -->
444
+ <div style="background-color: #2d2d2d; padding: 10px 15px; border-bottom: 1px solid #444;">
445
+ <table style="display: inline-table; vertical-align: middle;" cellpadding="0" cellspacing="0">
446
+ <tr>
447
+ <td style="padding: 0;"><div style="width: 12px; height: 12px; border-radius: 50%; background-color: #ff5f56;"></div></td>
448
+ <td style="padding: 0 0 0 5px;"><div style="width: 12px; height: 12px; border-radius: 50%; background-color: #ffbd2e;"></div></td>
449
+ <td style="padding: 0 0 0 5px;"><div style="width: 12px; height: 12px; border-radius: 50%; background-color: #27c93f;"></div></td>
450
+ <td style="padding: 0 0 0 12px; color: #999; font-size: 14px; white-space: nowrap;">ccgram@{{project}} - Waiting for Input</td>
451
+ </tr>
452
+ </table>
453
+ </div>
454
+
455
+ <!-- Terminal Content -->
456
+ <div style="padding: 20px; background-color: #1a1a1a; min-height: 400px;">
457
+ <!-- Session Info -->
458
+ <div style="color: #00ff00; margin-bottom: 20px;">
459
+ <span style="color: #999;">$</span> <span style="color: #00ff00;">claude-code status</span><br>
460
+ <div style="margin-left: 20px; margin-top: 5px; color: #ccc;">
461
+ <span style="color: #ff9800;">PROJECT:</span> {{projectDir}}<br>
462
+ <span style="color: #ff9800;">SESSION:</span> #{{token}}<br>
463
+ <span style="color: #ff9800;">STATUS:</span> <span style="color: #ffeb3b;">⏳ Waiting for input</span><br>
464
+ <span style="color: #ff9800;">TIME:</span> {{timestamp}}
465
+ </div>
466
+ </div>
467
+
468
+ <!-- Waiting Message -->
469
+ <div style="margin: 20px 0;">
470
+ <span style="color: #999;">$</span> <span style="color: #00ff00;">claude-code wait</span><br>
471
+ <div style="color: #ffeb3b; margin: 10px 0;">
472
+ <span style="color: #ff9800;">[WAITING]</span> Claude needs your input to continue...<br>
473
+ </div>
474
+ <div style="background-color: #262626; border-left: 3px solid #ffeb3b; padding: 15px; margin: 10px 0; color: #f0f0f0;">
475
+ {{message}}
476
+ </div>
477
+ </div>
478
+
479
+ <!-- Continue Instructions -->
480
+ <div style="margin: 30px 0 20px 0; border-top: 1px solid #333; padding-top: 20px;">
481
+ <span style="color: #999;">$</span> <span style="color: #00ff00;">claude-code help --respond</span><br>
482
+ <div style="color: #f0f0f0; margin: 10px 0;">
483
+ <div style="color: #ff9800; margin-bottom: 10px;">→ ACTION REQUIRED:</div>
484
+ <div style="background-color: #262626; padding: 15px; border: 1px solid #333; margin: 10px 0;">
485
+ <span style="color: #ffeb3b;">Claude is waiting for your guidance.</span><br><br>
486
+ Reply to this email with your instructions to continue.
487
+ </div>
488
+ </div>
489
+ </div>
490
+
491
+ <!-- Session Footer -->
492
+ <div style="color: #666; font-size: 12px; margin-top: 30px; padding-top: 20px; border-top: 1px solid #333;">
493
+ <span style="color: #999;">$</span> <span style="color: #666;">echo $SESSION_INFO</span><br>
494
+ <div style="margin-left: 20px; margin-top: 5px;">
495
+ SESSION_ID={{sessionId}}<br>
496
+ EXPIRES_IN=24h<br>
497
+ SECURITY=Do not forward this email<br>
498
+ POWERED_BY=CCGram
499
+ </div>
500
+ </div>
501
+ </div>
502
+ </div>
503
+ </div>
504
+ `,
505
+ text: `
506
+ [CCGram #{{token}}] Claude Code Waiting for Input - {{projectDir}}
507
+
508
+ Project: {{projectDir}}
509
+ Time: {{timestamp}}
510
+ Status: {{type}}
511
+
512
+ ⏳ Waiting for Processing: {{message}}
513
+
514
+ Claude needs your further guidance. Please reply to this email to tell Claude what to do next.
515
+
516
+ Session ID: {{sessionId}}
517
+ Security Note: Please do not forward this email, session will automatically expire after 24 hours
518
+ `
519
+ }
520
+ };
521
+ return templates[type] || templates.completed;
522
+ }
523
+ validateConfig() {
524
+ const config = this.config;
525
+ if (!config.smtp) {
526
+ return { valid: false, error: 'SMTP configuration required' };
527
+ }
528
+ if (!config.smtp.host) {
529
+ return { valid: false, error: 'SMTP host required' };
530
+ }
531
+ if (!config.smtp.auth || !config.smtp.auth.user || !config.smtp.auth.pass) {
532
+ return { valid: false, error: 'SMTP authentication required' };
533
+ }
534
+ if (!config.to) {
535
+ return { valid: false, error: 'Recipient email required' };
536
+ }
537
+ return { valid: true };
538
+ }
539
+ async test() {
540
+ try {
541
+ if (!this.transporter) {
542
+ throw new Error('Email transporter not initialized');
543
+ }
544
+ // Verify SMTP connection
545
+ await this.transporter.verify();
546
+ // Send test email
547
+ const testNotification = {
548
+ type: 'completed',
549
+ title: 'CCGram Test',
550
+ message: 'This is a test email to verify that the email notification function is working properly.',
551
+ project: 'CCGram-Test',
552
+ metadata: {
553
+ test: true,
554
+ timestamp: new Date().toISOString(),
555
+ language: 'en',
556
+ userQuestion: 'This is a test notification',
557
+ claudeResponse: 'Email notification system is working correctly.',
558
+ fullExecutionTrace: `> claude-remote test
559
+
560
+ 🧪 Testing email notification system...
561
+
562
+ [2025-08-01T06:29:28.893Z] [Config] [INFO] Configuration loaded successfully
563
+ [2025-08-01T06:29:28.918Z] [Notifier] [INFO] Initialized 2 channels
564
+ [2025-08-01T06:29:29.015Z] [Channel:desktop] [INFO] Notification sent successfully
565
+ [2025-08-01T06:29:32.880Z] [Channel:email] [INFO] Email sent successfully
566
+
567
+ ✅ Test completed successfully!
568
+
569
+ This is a test trace to demonstrate how the full execution trace will appear in actual usage.
570
+ When Claude Code completes a task, this section will contain the complete terminal output including:
571
+ - User commands
572
+ - Claude's responses
573
+ - Subagent activities
574
+ - Error messages
575
+ - Debug information
576
+
577
+ The trace provides complete transparency about what happened during task execution.`
578
+ }
579
+ };
580
+ const result = await this._sendImpl(testNotification);
581
+ return result;
582
+ }
583
+ catch (error) {
584
+ this.logger.error('Email test failed:', error.message);
585
+ return false;
586
+ }
587
+ }
588
+ getStatus() {
589
+ const baseStatus = super.getStatus();
590
+ const config = this.config;
591
+ return {
592
+ ...baseStatus,
593
+ configured: this.validateConfig().valid,
594
+ supportsRelay: true,
595
+ smtp: {
596
+ host: config.smtp?.host || 'not configured',
597
+ port: config.smtp?.port || 'not configured',
598
+ secure: config.smtp?.secure || false
599
+ },
600
+ recipient: config.to || 'not configured'
601
+ };
602
+ }
603
+ }
604
+ module.exports = EmailChannel;
605
+ //# sourceMappingURL=smtp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smtp.js","sourceRoot":"","sources":["../../../../src/channels/email/smtp.ts"],"names":[],"mappings":"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"}