@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,36 @@
1
+ /**
2
+ * LINE Notification Channel
3
+ * Sends notifications via LINE Messaging API with command support
4
+ */
5
+ import NotificationChannel from '../base/channel';
6
+ import TmuxMonitor from '../../utils/tmux-monitor';
7
+ import type { Notification } from '../../types';
8
+ interface LINEConfig {
9
+ enabled?: boolean;
10
+ channelAccessToken?: string;
11
+ userId?: string;
12
+ groupId?: string;
13
+ [key: string]: unknown;
14
+ }
15
+ interface LINEMessage {
16
+ type: string;
17
+ text: string;
18
+ }
19
+ declare class LINEChannel extends NotificationChannel {
20
+ sessionsDir: string;
21
+ tmuxMonitor: TmuxMonitor;
22
+ lineApiUrl: string;
23
+ constructor(config?: LINEConfig);
24
+ _ensureDirectories(): void;
25
+ _validateConfig(): boolean;
26
+ _generateToken(): string;
27
+ _getCurrentTmuxSession(): string | null;
28
+ _sendImpl(notification: Notification): Promise<boolean>;
29
+ _generateLINEMessage(notification: Notification, sessionId: string, token: string): LINEMessage[];
30
+ _createSession(sessionId: string, notification: Notification, token: string): Promise<void>;
31
+ _removeSession(sessionId: string): Promise<void>;
32
+ supportsRelay(): boolean;
33
+ validateConfig(): boolean;
34
+ }
35
+ export = LINEChannel;
36
+ //# sourceMappingURL=line.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"line.d.ts","sourceRoot":"","sources":["../../../../src/channels/line/line.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,mBAAmB,MAAM,iBAAiB,CAAC;AAMlD,OAAO,WAAW,MAAM,0BAA0B,CAAC;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,UAAU,UAAU;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAeD,UAAU,WAAW;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,cAAM,WAAY,SAAQ,mBAAmB;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;gBAEP,MAAM,GAAE,UAA6B;IAUjD,kBAAkB,IAAI,IAAI;IAM1B,eAAe,IAAI,OAAO;IAa1B,cAAc,IAAI,MAAM;IAUxB,sBAAsB,IAAI,MAAM,GAAG,IAAI;IAejC,SAAS,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IA2D7D,oBAAoB,CAAC,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE;IAuC3F,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB3F,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtD,aAAa,IAAI,OAAO;IAIxB,cAAc,IAAI,OAAO;CAG5B;AAED,SAAS,WAAW,CAAC"}
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ /**
3
+ * LINE Notification Channel
4
+ * Sends notifications via LINE Messaging API with command 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 http_request_1 = __importDefault(require("../../utils/http-request"));
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 LINEChannel extends channel_1.default {
18
+ sessionsDir;
19
+ tmuxMonitor;
20
+ lineApiUrl;
21
+ constructor(config = {}) {
22
+ super('line', config);
23
+ this.sessionsDir = path_1.default.join(__dirname, '../../data/sessions');
24
+ this.tmuxMonitor = new tmux_monitor_1.default();
25
+ this.lineApiUrl = 'https://api.line.me/v2/bot/message';
26
+ this._ensureDirectories();
27
+ this._validateConfig();
28
+ }
29
+ _ensureDirectories() {
30
+ if (!fs_1.default.existsSync(this.sessionsDir)) {
31
+ fs_1.default.mkdirSync(this.sessionsDir, { recursive: true });
32
+ }
33
+ }
34
+ _validateConfig() {
35
+ const config = this.config;
36
+ if (!config.channelAccessToken) {
37
+ this.logger.warn('LINE Channel Access Token not found');
38
+ return false;
39
+ }
40
+ if (!config.userId && !config.groupId) {
41
+ this.logger.warn('LINE User ID or Group ID must be configured');
42
+ return false;
43
+ }
44
+ return true;
45
+ }
46
+ _generateToken() {
47
+ // Generate short Token (uppercase letters + numbers, 8 digits)
48
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
49
+ let token = '';
50
+ for (let i = 0; i < 8; i++) {
51
+ token += chars.charAt(Math.floor(Math.random() * chars.length));
52
+ }
53
+ return token;
54
+ }
55
+ _getCurrentTmuxSession() {
56
+ try {
57
+ // Try to get current tmux session
58
+ const tmuxSession = (0, child_process_1.execSync)('tmux display-message -p "#S"', {
59
+ encoding: 'utf8',
60
+ stdio: ['ignore', 'pipe', 'ignore']
61
+ }).trim();
62
+ return tmuxSession || null;
63
+ }
64
+ catch (error) {
65
+ // Not in a tmux session or tmux not available
66
+ return null;
67
+ }
68
+ }
69
+ async _sendImpl(notification) {
70
+ if (!this._validateConfig()) {
71
+ throw new Error('LINE channel not properly configured');
72
+ }
73
+ const config = this.config;
74
+ // Generate session ID and Token
75
+ const sessionId = uuidv4();
76
+ const token = this._generateToken();
77
+ // Get current tmux session and conversation content
78
+ const tmuxSession = this._getCurrentTmuxSession();
79
+ if (tmuxSession && !notification.metadata) {
80
+ const conversation = this.tmuxMonitor.getRecentConversation(tmuxSession);
81
+ notification.metadata = {
82
+ userQuestion: conversation.userQuestion || notification.message,
83
+ claudeResponse: conversation.claudeResponse || notification.message,
84
+ tmuxSession: tmuxSession,
85
+ timestamp: new Date().toISOString(),
86
+ language: 'en'
87
+ };
88
+ }
89
+ // Create session record
90
+ await this._createSession(sessionId, notification, token);
91
+ // Generate LINE message
92
+ const messages = this._generateLINEMessage(notification, sessionId, token);
93
+ // Determine recipient (user or group)
94
+ const to = config.groupId || config.userId;
95
+ const requestData = {
96
+ to: to,
97
+ messages: messages
98
+ };
99
+ try {
100
+ await http_request_1.default.post(`${this.lineApiUrl}/push`, requestData, {
101
+ headers: {
102
+ 'Authorization': `Bearer ${config.channelAccessToken}`
103
+ }
104
+ });
105
+ this.logger.info(`LINE message sent successfully, Session: ${sessionId}`);
106
+ return true;
107
+ }
108
+ catch (error) {
109
+ this.logger.error('Failed to send LINE message:', error.message);
110
+ // Clean up failed session
111
+ await this._removeSession(sessionId);
112
+ return false;
113
+ }
114
+ }
115
+ _generateLINEMessage(notification, sessionId, token) {
116
+ const type = notification.type;
117
+ const emoji = type === 'completed' ? 'āœ…' : 'ā³';
118
+ const status = type === 'completed' ? 'Completed' : 'Waiting for Input';
119
+ let messageText = `${emoji} Claude Task ${status}\n`;
120
+ messageText += `Project: ${notification.project}\n`;
121
+ messageText += `Session Token: ${token}\n\n`;
122
+ if (notification.metadata) {
123
+ if (notification.metadata.userQuestion) {
124
+ const userQuestion = notification.metadata.userQuestion;
125
+ messageText += `šŸ“ Your question:\n${userQuestion.substring(0, 200)}`;
126
+ if (userQuestion.length > 200) {
127
+ messageText += '...';
128
+ }
129
+ messageText += '\n\n';
130
+ }
131
+ if (notification.metadata.claudeResponse) {
132
+ const claudeResponse = notification.metadata.claudeResponse;
133
+ messageText += `šŸ¤– Claude response:\n${claudeResponse.substring(0, 300)}`;
134
+ if (claudeResponse.length > 300) {
135
+ messageText += '...';
136
+ }
137
+ messageText += '\n\n';
138
+ }
139
+ }
140
+ messageText += `šŸ’¬ Reply to this message with:\n`;
141
+ messageText += `Token ${token} <your command>\n`;
142
+ messageText += `to send a new command to Claude`;
143
+ return [{
144
+ type: 'text',
145
+ text: messageText
146
+ }];
147
+ }
148
+ async _createSession(sessionId, notification, token) {
149
+ const session = {
150
+ id: sessionId,
151
+ token: token,
152
+ type: 'line',
153
+ created: new Date().toISOString(),
154
+ expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), // Expires after 24 hours
155
+ createdAt: Math.floor(Date.now() / 1000),
156
+ expiresAt: Math.floor((Date.now() + 24 * 60 * 60 * 1000) / 1000),
157
+ tmuxSession: notification.metadata?.tmuxSession || 'default',
158
+ project: notification.project,
159
+ notification: notification
160
+ };
161
+ const sessionFile = path_1.default.join(this.sessionsDir, `${sessionId}.json`);
162
+ fs_1.default.writeFileSync(sessionFile, JSON.stringify(session, null, 2));
163
+ this.logger.debug(`Session created: ${sessionId}`);
164
+ }
165
+ async _removeSession(sessionId) {
166
+ const sessionFile = path_1.default.join(this.sessionsDir, `${sessionId}.json`);
167
+ if (fs_1.default.existsSync(sessionFile)) {
168
+ fs_1.default.unlinkSync(sessionFile);
169
+ this.logger.debug(`Session removed: ${sessionId}`);
170
+ }
171
+ }
172
+ supportsRelay() {
173
+ return true;
174
+ }
175
+ validateConfig() {
176
+ return this._validateConfig();
177
+ }
178
+ }
179
+ module.exports = LINEChannel;
180
+ //# sourceMappingURL=line.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"line.js","sourceRoot":"","sources":["../../../../src/channels/line/line.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;AAEH,8DAAkD;AAClD,mEAAuD;AACvD,4EAAgD;AAChD,MAAM,MAAM,GAAG,IAAA,0BAAO,GAAE,CAAC;AACzB,gDAAwB;AACxB,4CAAoB;AACpB,4EAAmD;AACnD,iDAAyC;AA6BzC,MAAM,WAAY,SAAQ,iBAAmB;IACzC,WAAW,CAAS;IACpB,WAAW,CAAc;IACzB,UAAU,CAAS;IAEnB,YAAY,SAAqB,EAAgB;QAC7C,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACtB,IAAI,CAAC,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC;QAC/D,IAAI,CAAC,WAAW,GAAG,IAAI,sBAAW,EAAE,CAAC;QACrC,IAAI,CAAC,UAAU,GAAG,oCAAoC,CAAC;QAEvD,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,eAAe,EAAE,CAAC;IAC3B,CAAC;IAED,kBAAkB;QACd,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YACnC,YAAE,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,CAAC;IACL,CAAC;IAED,eAAe;QACX,MAAM,MAAM,GAAG,IAAI,CAAC,MAAoB,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;YACxD,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;YAChE,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,cAAc;QACV,+DAA+D;QAC/D,MAAM,KAAK,GAAG,sCAAsC,CAAC;QACrD,IAAI,KAAK,GAAG,EAAE,CAAC;QACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACzB,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QACpE,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,sBAAsB;QAClB,IAAI,CAAC;YACD,kCAAkC;YAClC,MAAM,WAAW,GAAG,IAAA,wBAAQ,EAAC,8BAA8B,EAAE;gBACzD,QAAQ,EAAE,MAAM;gBAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;aACtC,CAAC,CAAC,IAAI,EAAE,CAAC;YAEV,OAAO,WAAW,IAAI,IAAI,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACtB,8CAA8C;YAC9C,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,YAA0B;QACtC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC5D,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAoB,CAAC;QAEzC,gCAAgC;QAChC,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAEpC,oDAAoD;QACpD,MAAM,WAAW,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAClD,IAAI,WAAW,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;YACxC,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC;YACzE,YAAY,CAAC,QAAQ,GAAG;gBACpB,YAAY,EAAE,YAAY,CAAC,YAAY,IAAI,YAAY,CAAC,OAAO;gBAC/D,cAAc,EAAE,YAAY,CAAC,cAAc,IAAI,YAAY,CAAC,OAAO;gBACnE,WAAW,EAAE,WAAW;gBACxB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,QAAQ,EAAE,IAAI;aACjB,CAAC;QACN,CAAC;QAED,wBAAwB;QACxB,MAAM,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;QAE1D,wBAAwB;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QAE3E,sCAAsC;QACtC,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC;QAE3C,MAAM,WAAW,GAAG;YAChB,EAAE,EAAE,EAAE;YACN,QAAQ,EAAE,QAAQ;SACrB,CAAC;QAEF,IAAI,CAAC;YACD,MAAM,sBAAQ,CAAC,IAAI,CACf,GAAG,IAAI,CAAC,UAAU,OAAO,EACzB,WAAW,EACX;gBACI,OAAO,EAAE;oBACL,eAAe,EAAE,UAAU,MAAM,CAAC,kBAAkB,EAAE;iBACzD;aACJ,CACJ,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4CAA4C,SAAS,EAAE,CAAC,CAAC;YAC1E,OAAO,IAAI,CAAC;QAChB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACtB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAG,KAAe,CAAC,OAAO,CAAC,CAAC;YAC5E,0BAA0B;YAC1B,MAAM,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;YACrC,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED,oBAAoB,CAAC,YAA0B,EAAE,SAAiB,EAAE,KAAa;QAC7E,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,mBAAmB,CAAC;QAExE,IAAI,WAAW,GAAG,GAAG,KAAK,gBAAgB,MAAM,IAAI,CAAC;QACrD,WAAW,IAAI,YAAY,YAAY,CAAC,OAAO,IAAI,CAAC;QACpD,WAAW,IAAI,kBAAkB,KAAK,MAAM,CAAC;QAE7C,IAAI,YAAY,CAAC,QAAQ,EAAE,CAAC;YACxB,IAAI,YAAY,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;gBACrC,MAAM,YAAY,GAAG,YAAY,CAAC,QAAQ,CAAC,YAAsB,CAAC;gBAClE,WAAW,IAAI,sBAAsB,YAAY,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;gBACtE,IAAI,YAAY,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;oBAC5B,WAAW,IAAI,KAAK,CAAC;gBACzB,CAAC;gBACD,WAAW,IAAI,MAAM,CAAC;YAC1B,CAAC;YAED,IAAI,YAAY,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;gBACvC,MAAM,cAAc,GAAG,YAAY,CAAC,QAAQ,CAAC,cAAwB,CAAC;gBACtE,WAAW,IAAI,wBAAwB,cAAc,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;gBAC1E,IAAI,cAAc,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;oBAC9B,WAAW,IAAI,KAAK,CAAC;gBACzB,CAAC;gBACD,WAAW,IAAI,MAAM,CAAC;YAC1B,CAAC;QACL,CAAC;QAED,WAAW,IAAI,kCAAkC,CAAC;QAClD,WAAW,IAAI,SAAS,KAAK,mBAAmB,CAAC;QACjD,WAAW,IAAI,iCAAiC,CAAC;QAEjD,OAAO,CAAC;gBACJ,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,WAAW;aACpB,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,SAAiB,EAAE,YAA0B,EAAE,KAAa;QAC7E,MAAM,OAAO,GAAkB;YAC3B,EAAE,EAAE,SAAS;YACb,KAAK,EAAE,KAAK;YACZ,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACjC,OAAO,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,yBAAyB;YAC5F,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;YACxC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;YAChE,WAAW,EAAG,YAAY,CAAC,QAAQ,EAAE,WAAsB,IAAI,SAAS;YACxE,OAAO,EAAE,YAAY,CAAC,OAAO;YAC7B,YAAY,EAAE,YAAY;SAC7B,CAAC;QAEF,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,SAAS,OAAO,CAAC,CAAC;QACrE,YAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAEhE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,SAAS,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,SAAiB;QAClC,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,SAAS,OAAO,CAAC,CAAC;QACrE,IAAI,YAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC7B,YAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;YAC3B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,SAAS,EAAE,CAAC,CAAC;QACvD,CAAC;IACL,CAAC;IAED,aAAa;QACT,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,cAAc;QACV,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC;IAClC,CAAC;CACJ;AAED,iBAAS,WAAW,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * LINE Webhook Handler
3
+ * Handles incoming LINE messages and commands
4
+ */
5
+ import Logger from '../../core/logger';
6
+ import ControllerInjector from '../../utils/controller-injector';
7
+ interface LINEWebhookConfig {
8
+ channelSecret?: string;
9
+ channelAccessToken?: string;
10
+ userId?: string;
11
+ groupId?: string;
12
+ whitelist?: string[];
13
+ [key: string]: unknown;
14
+ }
15
+ interface LINEEvent {
16
+ type: string;
17
+ source: {
18
+ userId?: string;
19
+ groupId?: string;
20
+ type: string;
21
+ };
22
+ message: {
23
+ type: string;
24
+ text: string;
25
+ };
26
+ replyToken: string;
27
+ }
28
+ interface SessionData {
29
+ id: string;
30
+ token: string;
31
+ type: string;
32
+ tmuxSession?: string;
33
+ expiresAt: number;
34
+ [key: string]: unknown;
35
+ }
36
+ declare class LINEWebhookHandler {
37
+ config: LINEWebhookConfig;
38
+ logger: Logger;
39
+ sessionsDir: string;
40
+ injector: ControllerInjector;
41
+ app: any;
42
+ constructor(config?: LINEWebhookConfig);
43
+ _setupMiddleware(): void;
44
+ _setupRoutes(): void;
45
+ _validateSignature(body: Buffer, signature: string): boolean;
46
+ _handleWebhook(req: any, res: any): Promise<void>;
47
+ _handleTextMessage(event: LINEEvent): Promise<void>;
48
+ _isAuthorized(userId: string | undefined, groupId: string | undefined): boolean;
49
+ _findSessionByToken(token: string): Promise<SessionData | null>;
50
+ _removeSession(sessionId: string): Promise<void>;
51
+ _replyMessage(replyToken: string, text: string): Promise<void>;
52
+ start(port?: number): void;
53
+ }
54
+ export = LINEWebhookHandler;
55
+ //# sourceMappingURL=webhook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../../../src/channels/line/webhook.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,MAAM,MAAM,mBAAmB,CAAC;AACvC,OAAO,kBAAkB,MAAM,iCAAiC,CAAC;AAEjE,UAAU,iBAAiB;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,UAAU,SAAS;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QACJ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,OAAO,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,WAAW;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,cAAM,kBAAkB;IACpB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,GAAG,EAAE,GAAG,CAAC;gBAEG,MAAM,GAAE,iBAAsB;IAc1C,gBAAgB,IAAI,IAAI;IAQxB,YAAY,IAAI,IAAI;IAUpB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IActD,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BjD,kBAAkB,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IA2DzD,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO;IAyBzE,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAoB/D,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQhD,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBpE,KAAK,CAAC,IAAI,GAAE,MAAa,GAAG,IAAI;CAKnC;AAED,SAAS,kBAAkB,CAAC"}
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ /**
3
+ * LINE Webhook Handler
4
+ * Handles incoming LINE messages and commands
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ const optional_require_1 = require("../../utils/optional-require");
10
+ const express = (0, optional_require_1.optionalRequire)('express', 'LINE webhook server');
11
+ const crypto_1 = __importDefault(require("crypto"));
12
+ const http_request_1 = __importDefault(require("../../utils/http-request"));
13
+ const path_1 = __importDefault(require("path"));
14
+ const fs_1 = __importDefault(require("fs"));
15
+ const logger_1 = __importDefault(require("../../core/logger"));
16
+ const controller_injector_1 = __importDefault(require("../../utils/controller-injector"));
17
+ class LINEWebhookHandler {
18
+ config;
19
+ logger;
20
+ sessionsDir;
21
+ injector;
22
+ app;
23
+ constructor(config = {}) {
24
+ if (!express) {
25
+ throw new Error('express is required for the LINE webhook server. Install with: npm install express');
26
+ }
27
+ this.config = config;
28
+ this.logger = new logger_1.default('LINEWebhook');
29
+ this.sessionsDir = path_1.default.join(__dirname, '../../data/sessions');
30
+ this.injector = new controller_injector_1.default();
31
+ this.app = express();
32
+ this._setupMiddleware();
33
+ this._setupRoutes();
34
+ }
35
+ _setupMiddleware() {
36
+ // Parse raw body for signature verification
37
+ this.app.use('/webhook', express.raw({ type: 'application/json' }));
38
+ // Parse JSON for other routes
39
+ this.app.use(express.json());
40
+ }
41
+ _setupRoutes() {
42
+ // LINE webhook endpoint
43
+ this.app.post('/webhook', this._handleWebhook.bind(this));
44
+ // Health check endpoint
45
+ this.app.get('/health', (req, res) => {
46
+ res.json({ status: 'ok', service: 'line-webhook' });
47
+ });
48
+ }
49
+ _validateSignature(body, signature) {
50
+ if (!this.config.channelSecret) {
51
+ this.logger.error('Channel Secret not configured');
52
+ return false;
53
+ }
54
+ const hash = crypto_1.default
55
+ .createHmac('SHA256', this.config.channelSecret)
56
+ .update(body)
57
+ .digest('base64');
58
+ return hash === signature;
59
+ }
60
+ async _handleWebhook(req, res) {
61
+ const signature = req.headers['x-line-signature'];
62
+ // Validate signature
63
+ if (!this._validateSignature(req.body, signature)) {
64
+ this.logger.warn('Invalid signature');
65
+ res.status(401).send('Unauthorized');
66
+ return;
67
+ }
68
+ try {
69
+ const events = JSON.parse(req.body.toString()).events;
70
+ for (const event of events) {
71
+ if (event.type === 'message' && event.message.type === 'text') {
72
+ await this._handleTextMessage(event);
73
+ }
74
+ }
75
+ res.status(200).send('OK');
76
+ }
77
+ catch (error) {
78
+ this.logger.error('Webhook handling error:', error.message);
79
+ res.status(500).send('Internal Server Error');
80
+ }
81
+ }
82
+ async _handleTextMessage(event) {
83
+ const userId = event.source.userId;
84
+ const groupId = event.source.groupId;
85
+ const messageText = event.message.text.trim();
86
+ const replyToken = event.replyToken;
87
+ // Check if user is authorized
88
+ if (!this._isAuthorized(userId, groupId)) {
89
+ this.logger.warn(`Unauthorized user/group: ${userId || groupId}`);
90
+ await this._replyMessage(replyToken, 'āš ļø You are not authorized to use this feature');
91
+ return;
92
+ }
93
+ // Parse command
94
+ const commandMatch = messageText.match(/^Token\s+([A-Z0-9]{8})\s+(.+)$/i);
95
+ if (!commandMatch) {
96
+ await this._replyMessage(replyToken, 'āŒ Invalid format. Usage:\nToken <8-char Token> <your command>\n\nExample:\nToken ABC12345 Please analyze this code');
97
+ return;
98
+ }
99
+ const token = commandMatch[1].toUpperCase();
100
+ const command = commandMatch[2];
101
+ // Find session by token
102
+ const session = await this._findSessionByToken(token);
103
+ if (!session) {
104
+ await this._replyMessage(replyToken, 'āŒ Invalid or expired token. Please wait for a new task notification.');
105
+ return;
106
+ }
107
+ // Check if session is expired
108
+ if (session.expiresAt < Math.floor(Date.now() / 1000)) {
109
+ await this._replyMessage(replyToken, 'āŒ Token has expired. Please wait for a new task notification.');
110
+ await this._removeSession(session.id);
111
+ return;
112
+ }
113
+ try {
114
+ // Inject command into tmux session
115
+ const tmuxSession = session.tmuxSession || 'default';
116
+ await this.injector.injectCommand(command, tmuxSession);
117
+ // Send confirmation
118
+ await this._replyMessage(replyToken, `āœ… Command sent\n\nšŸ“ Command: ${command}\nšŸ–„ļø Session: ${tmuxSession}\n\nPlease wait, Claude is processing your request...`);
119
+ // Log command execution
120
+ this.logger.info(`Command injected - User: ${userId}, Token: ${token}, Command: ${command}`);
121
+ }
122
+ catch (error) {
123
+ this.logger.error('Command injection failed:', error.message);
124
+ await this._replyMessage(replyToken, `āŒ Command execution failed: ${error.message}`);
125
+ }
126
+ }
127
+ _isAuthorized(userId, groupId) {
128
+ // Check whitelist
129
+ const whitelist = this.config.whitelist || [];
130
+ if (groupId && whitelist.includes(groupId)) {
131
+ return true;
132
+ }
133
+ if (userId && whitelist.includes(userId)) {
134
+ return true;
135
+ }
136
+ // If no whitelist configured, allow configured user/group
137
+ if (whitelist.length === 0) {
138
+ if (groupId && groupId === this.config.groupId) {
139
+ return true;
140
+ }
141
+ if (userId && userId === this.config.userId) {
142
+ return true;
143
+ }
144
+ }
145
+ return false;
146
+ }
147
+ async _findSessionByToken(token) {
148
+ const files = fs_1.default.readdirSync(this.sessionsDir);
149
+ for (const file of files) {
150
+ if (!file.endsWith('.json'))
151
+ continue;
152
+ const sessionPath = path_1.default.join(this.sessionsDir, file);
153
+ try {
154
+ const session = JSON.parse(fs_1.default.readFileSync(sessionPath, 'utf8'));
155
+ if (session.token === token) {
156
+ return session;
157
+ }
158
+ }
159
+ catch (error) {
160
+ this.logger.error(`Failed to read session file ${file}:`, error.message);
161
+ }
162
+ }
163
+ return null;
164
+ }
165
+ async _removeSession(sessionId) {
166
+ const sessionFile = path_1.default.join(this.sessionsDir, `${sessionId}.json`);
167
+ if (fs_1.default.existsSync(sessionFile)) {
168
+ fs_1.default.unlinkSync(sessionFile);
169
+ this.logger.debug(`Session removed: ${sessionId}`);
170
+ }
171
+ }
172
+ async _replyMessage(replyToken, text) {
173
+ try {
174
+ await http_request_1.default.post('https://api.line.me/v2/bot/message/reply', { replyToken, messages: [{ type: 'text', text }] }, {
175
+ headers: {
176
+ 'Authorization': `Bearer ${this.config.channelAccessToken}`
177
+ }
178
+ });
179
+ }
180
+ catch (error) {
181
+ this.logger.error('Failed to reply message:', error.message);
182
+ }
183
+ }
184
+ start(port = 3000) {
185
+ this.app.listen(port, () => {
186
+ this.logger.info(`LINE webhook server started on port ${port}`);
187
+ });
188
+ }
189
+ }
190
+ module.exports = LINEWebhookHandler;
191
+ //# sourceMappingURL=webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../../../src/channels/line/webhook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Desktop Notification Channel
3
+ * Sends notifications to the local desktop
4
+ */
5
+ import NotificationChannel from '../base/channel';
6
+ import type { Notification } from '../../types';
7
+ interface DesktopConfig {
8
+ enabled?: boolean;
9
+ completedSound?: string;
10
+ waitingSound?: string;
11
+ [key: string]: unknown;
12
+ }
13
+ interface SoundCategories {
14
+ [category: string]: string[];
15
+ }
16
+ declare class DesktopChannel extends NotificationChannel {
17
+ platform: string;
18
+ soundsDir: string;
19
+ constructor(config?: DesktopConfig);
20
+ _sendImpl(notification: Notification): Promise<boolean>;
21
+ _getSoundForType(type: string): string;
22
+ _sendMacOS(title: string, message: string, sound: string): boolean;
23
+ _sendLinux(title: string, message: string, sound: string): boolean;
24
+ _sendWindows(title: string, message: string, sound: string): boolean;
25
+ _playSound(soundName: string): void;
26
+ validateConfig(): boolean;
27
+ getAvailableSounds(): SoundCategories;
28
+ }
29
+ export = DesktopChannel;
30
+ //# sourceMappingURL=desktop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"desktop.d.ts","sourceRoot":"","sources":["../../../../src/channels/local/desktop.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,mBAAmB,MAAM,iBAAiB,CAAC;AAIlD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,UAAU,aAAa;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,UAAU,eAAe;IACrB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAChC;AAED,cAAM,cAAe,SAAQ,mBAAmB;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;gBAEN,MAAM,GAAE,aAAmC;IAMjD,SAAS,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAiB7D,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAStC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAsBlE,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAalE,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAqBpE,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IA8BnC,cAAc,IAAI,OAAO;IAKzB,kBAAkB,IAAI,eAAe;CA0BxC;AAED,SAAS,cAAc,CAAC"}