@zahidzorbaz/tudun 1.1.3 → 1.1.4
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.
- package/dist/domain/dto/dialog.d.ts +0 -3
- package/dist/infrastructure/terminal-injector/index.d.ts +16 -0
- package/dist/infrastructure/terminal-injector/index.js +53 -0
- package/dist/infrastructure/terminal-injector/index.js.map +1 -0
- package/dist/infrastructure/terminal-injector/windows-injector.d.ts +10 -0
- package/dist/infrastructure/terminal-injector/windows-injector.js +167 -0
- package/dist/infrastructure/terminal-injector/windows-injector.js.map +1 -0
- package/dist/infrastructure/whatsapp/dialog-listener.service.d.ts +37 -0
- package/dist/infrastructure/whatsapp/dialog-listener.service.js +191 -0
- package/dist/infrastructure/whatsapp/dialog-listener.service.js.map +1 -0
- package/dist/interface/mcp/server.js +3 -0
- package/dist/interface/mcp/server.js.map +1 -1
- package/dist/interface/mcp/tools/start-whatsapp-dialog.js +18 -20
- package/dist/interface/mcp/tools/start-whatsapp-dialog.js.map +1 -1
- package/dist/interface/mcp/tools/stop-whatsapp-dialog.js +5 -8
- package/dist/interface/mcp/tools/stop-whatsapp-dialog.js.map +1 -1
- package/dist/interface/mcp/types.d.ts +2 -0
- package/package.json +1 -1
|
@@ -5,8 +5,6 @@ export interface DialogStartInput {
|
|
|
5
5
|
}
|
|
6
6
|
export interface DialogStartResult {
|
|
7
7
|
dialogId: string;
|
|
8
|
-
filePath: string;
|
|
9
|
-
supervisorFilePath: string;
|
|
10
8
|
contactNumber: string;
|
|
11
9
|
contactName: string;
|
|
12
10
|
}
|
|
@@ -17,5 +15,4 @@ export interface DialogInfo {
|
|
|
17
15
|
topic: string;
|
|
18
16
|
status: 'active' | 'stopped';
|
|
19
17
|
createdAt: number;
|
|
20
|
-
messageCount: number;
|
|
21
18
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal Injector for WhatsApp Dialog Messages
|
|
3
|
+
* Injects WhatsApp messages directly into Claude Code's terminal
|
|
4
|
+
* so Claude can auto-reply without polling files.
|
|
5
|
+
*
|
|
6
|
+
* Adapted from claude-collab (@dolusoft/claude-collab)
|
|
7
|
+
*/
|
|
8
|
+
export interface WpMessage {
|
|
9
|
+
contactName: string;
|
|
10
|
+
contactNumber: string;
|
|
11
|
+
body: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function injectWhatsAppMessage(msg: WpMessage): Promise<void>;
|
|
14
|
+
export declare function injectWhatsAppBatch(contactName: string, contactNumber: string, messages: string[]): Promise<void>;
|
|
15
|
+
export declare function injectSupervisorMessage(message: string): Promise<void>;
|
|
16
|
+
export declare function injectRestoreText(): Promise<void>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal Injector for WhatsApp Dialog Messages
|
|
3
|
+
* Injects WhatsApp messages directly into Claude Code's terminal
|
|
4
|
+
* so Claude can auto-reply without polling files.
|
|
5
|
+
*
|
|
6
|
+
* Adapted from claude-collab (@dolusoft/claude-collab)
|
|
7
|
+
*/
|
|
8
|
+
import { windowsInject, windowsInjectCtrlY } from './windows-injector.js';
|
|
9
|
+
function formatSingleMessage(msg) {
|
|
10
|
+
const body = msg.body.trim() || '[medya mesaji]';
|
|
11
|
+
const clean = body.replace(/\s+/g, ' ').trim();
|
|
12
|
+
return `[WP] ${msg.contactName}: ${clean} — send_whatsapp_message ile ${msg.contactNumber}'e yanit ver, stil profiline uygun yaz.`;
|
|
13
|
+
}
|
|
14
|
+
function formatBatchMessages(contactName, contactNumber, messages) {
|
|
15
|
+
const parts = messages.map((m, i) => {
|
|
16
|
+
const body = m.trim() || '[medya]';
|
|
17
|
+
const clean = body.replace(/\s+/g, ' ').trim();
|
|
18
|
+
return `(${i + 1}) "${clean}"`;
|
|
19
|
+
});
|
|
20
|
+
return `[WP] ${contactName} (${messages.length} mesaj): ${parts.join(' ')} — send_whatsapp_message ile ${contactNumber}'e yanit ver, stil profiline uygun yaz.`;
|
|
21
|
+
}
|
|
22
|
+
function formatSupervisor(message) {
|
|
23
|
+
const clean = message.replace(/\s+/g, ' ').trim();
|
|
24
|
+
return `[WP SUPERVISOR]: ${clean} — Bu supervisor komutudur, aktif diyaloglara uygula.`;
|
|
25
|
+
}
|
|
26
|
+
export async function injectWhatsAppMessage(msg) {
|
|
27
|
+
if (process.platform !== 'win32')
|
|
28
|
+
return;
|
|
29
|
+
const text = formatSingleMessage(msg);
|
|
30
|
+
await windowsInject(text);
|
|
31
|
+
}
|
|
32
|
+
export async function injectWhatsAppBatch(contactName, contactNumber, messages) {
|
|
33
|
+
if (process.platform !== 'win32')
|
|
34
|
+
return;
|
|
35
|
+
if (messages.length === 1) {
|
|
36
|
+
await injectWhatsAppMessage({ contactName, contactNumber, body: messages[0] });
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const text = formatBatchMessages(contactName, contactNumber, messages);
|
|
40
|
+
await windowsInject(text);
|
|
41
|
+
}
|
|
42
|
+
export async function injectSupervisorMessage(message) {
|
|
43
|
+
if (process.platform !== 'win32')
|
|
44
|
+
return;
|
|
45
|
+
const text = formatSupervisor(message);
|
|
46
|
+
await windowsInject(text);
|
|
47
|
+
}
|
|
48
|
+
export async function injectRestoreText() {
|
|
49
|
+
if (process.platform !== 'win32')
|
|
50
|
+
return;
|
|
51
|
+
await windowsInjectCtrlY();
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infrastructure/terminal-injector/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAQ1E,SAAS,mBAAmB,CAAC,GAAc;IACzC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,gBAAgB,CAAC;IACjD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C,OAAO,QAAQ,GAAG,CAAC,WAAW,KAAK,KAAK,gCAAgC,GAAG,CAAC,aAAa,yCAAyC,CAAC;AACrI,CAAC;AAED,SAAS,mBAAmB,CAAC,WAAmB,EAAE,aAAqB,EAAE,QAAkB;IACzF,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAClC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/C,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC;IACjC,CAAC,CAAC,CAAC;IACH,OAAO,QAAQ,WAAW,KAAK,QAAQ,CAAC,MAAM,YAAY,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,gCAAgC,aAAa,yCAAyC,CAAC;AAClK,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAe;IACvC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,OAAO,oBAAoB,KAAK,uDAAuD,CAAC;AAC1F,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,GAAc;IACxD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO;IACzC,MAAM,IAAI,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,WAAmB,EAAE,aAAqB,EAAE,QAAkB;IACtG,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO;IAEzC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,qBAAqB,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/E,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,mBAAmB,CAAC,WAAW,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;IACvE,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,OAAe;IAC3D,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO;IACzC,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO;IACzC,MAAM,kBAAkB,EAAE,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Windows Terminal Injector
|
|
3
|
+
* AttachConsole(ppid) → CreateFile("CONIN$") → WriteConsoleInput
|
|
4
|
+
* All keystrokes (text, Ctrl+U, Enter, Ctrl+Y) go through WriteConsoleInput.
|
|
5
|
+
* No WScript.Shell / SendKeys / SetForegroundWindow — no focus dependency.
|
|
6
|
+
*
|
|
7
|
+
* Adapted from claude-collab (@dolusoft/claude-collab)
|
|
8
|
+
*/
|
|
9
|
+
export declare function windowsInject(text: string): Promise<void>;
|
|
10
|
+
export declare function windowsInjectCtrlY(): Promise<void>;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Windows Terminal Injector
|
|
3
|
+
* AttachConsole(ppid) → CreateFile("CONIN$") → WriteConsoleInput
|
|
4
|
+
* All keystrokes (text, Ctrl+U, Enter, Ctrl+Y) go through WriteConsoleInput.
|
|
5
|
+
* No WScript.Shell / SendKeys / SetForegroundWindow — no focus dependency.
|
|
6
|
+
*
|
|
7
|
+
* Adapted from claude-collab (@dolusoft/claude-collab)
|
|
8
|
+
*/
|
|
9
|
+
import { execFile } from 'node:child_process';
|
|
10
|
+
import { unlinkSync } from 'node:fs';
|
|
11
|
+
import { tmpdir } from 'node:os';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
const CS_CONINJECT = `
|
|
14
|
+
using System;
|
|
15
|
+
using System.Collections.Generic;
|
|
16
|
+
using System.Runtime.InteropServices;
|
|
17
|
+
|
|
18
|
+
public class ConInject {
|
|
19
|
+
[DllImport("kernel32.dll")] public static extern bool FreeConsole();
|
|
20
|
+
[DllImport("kernel32.dll")] public static extern bool AttachConsole(uint pid);
|
|
21
|
+
[DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
|
|
22
|
+
public static extern IntPtr CreateFile(
|
|
23
|
+
string lpFileName, uint dwDesiredAccess, uint dwShareMode,
|
|
24
|
+
IntPtr lpSecurityAttributes, uint dwCreationDisposition,
|
|
25
|
+
uint dwFlagsAndAttributes, IntPtr hTemplateFile);
|
|
26
|
+
[DllImport("kernel32.dll")] public static extern bool WriteConsoleInput(
|
|
27
|
+
IntPtr hIn, INPUT_RECORD[] buf, uint len, out uint written);
|
|
28
|
+
[DllImport("kernel32.dll")] public static extern bool CloseHandle(IntPtr h);
|
|
29
|
+
|
|
30
|
+
[StructLayout(LayoutKind.Explicit, Size=20)]
|
|
31
|
+
public struct INPUT_RECORD {
|
|
32
|
+
[FieldOffset(0)] public ushort EventType;
|
|
33
|
+
[FieldOffset(4)] public int bKeyDown;
|
|
34
|
+
[FieldOffset(8)] public ushort wRepeatCount;
|
|
35
|
+
[FieldOffset(10)] public ushort wVirtualKeyCode;
|
|
36
|
+
[FieldOffset(12)] public ushort wVirtualScanCode;
|
|
37
|
+
[FieldOffset(14)] public ushort UnicodeChar;
|
|
38
|
+
[FieldOffset(16)] public uint dwControlKeyState;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const uint LEFT_CTRL = 0x0008;
|
|
42
|
+
|
|
43
|
+
static IntPtr OpenConin(uint pid) {
|
|
44
|
+
FreeConsole();
|
|
45
|
+
if (!AttachConsole(pid)) return new IntPtr(-1);
|
|
46
|
+
return CreateFile("CONIN$", 0xC0000000, 3, IntPtr.Zero, 3, 0, IntPtr.Zero);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public static int InjectText(uint pid, string text) {
|
|
50
|
+
IntPtr hIn = OpenConin(pid);
|
|
51
|
+
if (hIn == new IntPtr(-1)) return -1;
|
|
52
|
+
|
|
53
|
+
var records = new List<INPUT_RECORD>();
|
|
54
|
+
foreach (char c in text) {
|
|
55
|
+
records.Add(new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, UnicodeChar=(ushort)c });
|
|
56
|
+
records.Add(new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, UnicodeChar=(ushort)c });
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
var arr = records.ToArray();
|
|
60
|
+
uint written;
|
|
61
|
+
bool ok = WriteConsoleInput(hIn, arr, (uint)arr.Length, out written);
|
|
62
|
+
CloseHandle(hIn);
|
|
63
|
+
return ok ? (int)written : -2;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public static int InjectEnter(uint pid) {
|
|
67
|
+
IntPtr hIn = OpenConin(pid);
|
|
68
|
+
if (hIn == new IntPtr(-1)) return -1;
|
|
69
|
+
|
|
70
|
+
var records = new INPUT_RECORD[] {
|
|
71
|
+
new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, wVirtualKeyCode=0x0D, UnicodeChar=0x0D },
|
|
72
|
+
new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, wVirtualKeyCode=0x0D, UnicodeChar=0x0D }
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
uint written;
|
|
76
|
+
bool ok = WriteConsoleInput(hIn, records, (uint)records.Length, out written);
|
|
77
|
+
CloseHandle(hIn);
|
|
78
|
+
return ok ? (int)written : -2;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public static int InjectCtrlU(uint pid) {
|
|
82
|
+
IntPtr hIn = OpenConin(pid);
|
|
83
|
+
if (hIn == new IntPtr(-1)) return -1;
|
|
84
|
+
|
|
85
|
+
var records = new INPUT_RECORD[] {
|
|
86
|
+
new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, wVirtualKeyCode=0xA2, dwControlKeyState=LEFT_CTRL },
|
|
87
|
+
new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, wVirtualKeyCode=0x55, UnicodeChar=0x15, dwControlKeyState=LEFT_CTRL },
|
|
88
|
+
new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, wVirtualKeyCode=0x55, UnicodeChar=0x15, dwControlKeyState=LEFT_CTRL },
|
|
89
|
+
new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, wVirtualKeyCode=0xA2, dwControlKeyState=0 }
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
uint written;
|
|
93
|
+
bool ok = WriteConsoleInput(hIn, records, (uint)records.Length, out written);
|
|
94
|
+
CloseHandle(hIn);
|
|
95
|
+
return ok ? (int)written : -2;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public static int InjectCtrlY(uint pid) {
|
|
99
|
+
IntPtr hIn = OpenConin(pid);
|
|
100
|
+
if (hIn == new IntPtr(-1)) return -1;
|
|
101
|
+
|
|
102
|
+
var records = new INPUT_RECORD[] {
|
|
103
|
+
new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, wVirtualKeyCode=0xA2, dwControlKeyState=LEFT_CTRL },
|
|
104
|
+
new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, wVirtualKeyCode=0x59, UnicodeChar=0x19, dwControlKeyState=LEFT_CTRL },
|
|
105
|
+
new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, wVirtualKeyCode=0x59, UnicodeChar=0x19, dwControlKeyState=LEFT_CTRL },
|
|
106
|
+
new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, wVirtualKeyCode=0xA2, dwControlKeyState=0 }
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
uint written;
|
|
110
|
+
bool ok = WriteConsoleInput(hIn, records, (uint)records.Length, out written);
|
|
111
|
+
CloseHandle(hIn);
|
|
112
|
+
return ok ? (int)written : -2;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
`;
|
|
116
|
+
function buildScript(claudePid, body) {
|
|
117
|
+
const logFile = join(tmpdir(), `tudun-inject-${Date.now()}.log`).replace(/\\/g, '/');
|
|
118
|
+
return `
|
|
119
|
+
$log = "${logFile}"
|
|
120
|
+
function Log($msg) { Add-Content -Path $log -Value $msg -Encoding UTF8 }
|
|
121
|
+
$claudePid = ${claudePid}
|
|
122
|
+
try { Add-Type @'${CS_CONINJECT}'@ } catch { }
|
|
123
|
+
${body}
|
|
124
|
+
`;
|
|
125
|
+
}
|
|
126
|
+
function run(script) {
|
|
127
|
+
return new Promise((resolve) => {
|
|
128
|
+
const encoded = Buffer.from(script, 'utf16le').toString('base64');
|
|
129
|
+
execFile('powershell', ['-NoProfile', '-WindowStyle', 'Hidden', '-EncodedCommand', encoded], { windowsHide: true }, () => {
|
|
130
|
+
const logFile = script.match(/\$log = "([^"]+)"/)?.[1];
|
|
131
|
+
if (logFile)
|
|
132
|
+
try {
|
|
133
|
+
unlinkSync(logFile);
|
|
134
|
+
}
|
|
135
|
+
catch { /* ok */ }
|
|
136
|
+
resolve();
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
export async function windowsInject(text) {
|
|
141
|
+
const claudePid = process.ppid;
|
|
142
|
+
const textB64 = Buffer.from(text, 'utf16le').toString('base64');
|
|
143
|
+
const script = buildScript(claudePid, `
|
|
144
|
+
$textBytes = [System.Convert]::FromBase64String('${textB64}')
|
|
145
|
+
$text = [System.Text.Encoding]::Unicode.GetString($textBytes)
|
|
146
|
+
|
|
147
|
+
# 1. Ctrl+U to save user's current text to kill ring
|
|
148
|
+
[ConInject]::InjectCtrlU([uint32]$claudePid) | Out-Null
|
|
149
|
+
Start-Sleep -Milliseconds 100
|
|
150
|
+
|
|
151
|
+
# 2. Write text into console input buffer
|
|
152
|
+
[ConInject]::InjectText([uint32]$claudePid, $text) | Out-Null
|
|
153
|
+
Start-Sleep -Milliseconds 50
|
|
154
|
+
|
|
155
|
+
# 3. Send Enter
|
|
156
|
+
[ConInject]::InjectEnter([uint32]$claudePid) | Out-Null
|
|
157
|
+
`);
|
|
158
|
+
await run(script);
|
|
159
|
+
}
|
|
160
|
+
export async function windowsInjectCtrlY() {
|
|
161
|
+
const claudePid = process.ppid;
|
|
162
|
+
const script = buildScript(claudePid, `
|
|
163
|
+
[ConInject]::InjectCtrlY([uint32]$claudePid) | Out-Null
|
|
164
|
+
`);
|
|
165
|
+
await run(script);
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=windows-injector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"windows-injector.js","sourceRoot":"","sources":["../../../src/infrastructure/terminal-injector/windows-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsGpB,CAAC;AAEF,SAAS,WAAW,CAAC,SAAiB,EAAE,IAAY;IAClD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,gBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACrF,OAAO;UACC,OAAO;;eAEF,SAAS;mBACL,YAAY;EAC7B,IAAI;CACL,CAAC;AACF,CAAC;AAED,SAAS,GAAG,CAAC,MAAc;IACzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAClE,QAAQ,CACN,YAAY,EACZ,CAAC,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,iBAAiB,EAAE,OAAO,CAAC,EACpE,EAAE,WAAW,EAAE,IAAI,EAAE,EACrB,GAAG,EAAE;YACH,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACvD,IAAI,OAAO;gBAAE,IAAI,CAAC;oBAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC5D,OAAO,EAAE,CAAC;QACZ,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC9C,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEhE,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,EAAE;mDACW,OAAO;;;;;;;;;;;;;CAazD,CAAC,CAAC;IAED,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAE/B,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,EAAE;;CAEvC,CAAC,CAAC;IAED,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dialog Listener Service
|
|
3
|
+
* Connects to WPBridge WebSocket and listens for WhatsApp messages.
|
|
4
|
+
* Injects relevant messages into Claude Code's terminal via terminal injection.
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Single WebSocket connection for all active dialogs
|
|
8
|
+
* - 3s debounce for message bursts (batches rapid messages)
|
|
9
|
+
* - Supervisor detection (self-messages → [WP SUPERVISOR])
|
|
10
|
+
* - Echo prevention (skips Claude's own outgoing messages)
|
|
11
|
+
* - Exponential backoff reconnect on disconnect
|
|
12
|
+
* - History replay filtering (ignores events before dialog start)
|
|
13
|
+
*/
|
|
14
|
+
export declare class DialogListenerService {
|
|
15
|
+
private readonly wpBridgeUrl;
|
|
16
|
+
private ws;
|
|
17
|
+
private activeDialogs;
|
|
18
|
+
private ownerNumber;
|
|
19
|
+
private debounceTimers;
|
|
20
|
+
private reconnectAttempt;
|
|
21
|
+
private reconnectTimer;
|
|
22
|
+
private intentionallyClosed;
|
|
23
|
+
private wsUrl;
|
|
24
|
+
constructor(wpBridgeUrl: string);
|
|
25
|
+
startListening(dialogId: string, contactNumber: string, contactName: string, ownerNumber: string): void;
|
|
26
|
+
stopListening(dialogId: string): void;
|
|
27
|
+
stopAll(): void;
|
|
28
|
+
hasActiveDialogs(): boolean;
|
|
29
|
+
private connect;
|
|
30
|
+
private disconnect;
|
|
31
|
+
private scheduleReconnect;
|
|
32
|
+
private handleEvent;
|
|
33
|
+
private handleIncoming;
|
|
34
|
+
private handleOutgoing;
|
|
35
|
+
private addToDebounce;
|
|
36
|
+
private flushDebounce;
|
|
37
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dialog Listener Service
|
|
3
|
+
* Connects to WPBridge WebSocket and listens for WhatsApp messages.
|
|
4
|
+
* Injects relevant messages into Claude Code's terminal via terminal injection.
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Single WebSocket connection for all active dialogs
|
|
8
|
+
* - 3s debounce for message bursts (batches rapid messages)
|
|
9
|
+
* - Supervisor detection (self-messages → [WP SUPERVISOR])
|
|
10
|
+
* - Echo prevention (skips Claude's own outgoing messages)
|
|
11
|
+
* - Exponential backoff reconnect on disconnect
|
|
12
|
+
* - History replay filtering (ignores events before dialog start)
|
|
13
|
+
*/
|
|
14
|
+
import { injectWhatsAppBatch, injectSupervisorMessage, injectRestoreText } from '../terminal-injector/index.js';
|
|
15
|
+
const DEBOUNCE_MS = 3000;
|
|
16
|
+
const MAX_RECONNECT_DELAY_MS = 30_000;
|
|
17
|
+
export class DialogListenerService {
|
|
18
|
+
wpBridgeUrl;
|
|
19
|
+
ws = null;
|
|
20
|
+
activeDialogs = new Map();
|
|
21
|
+
ownerNumber = '';
|
|
22
|
+
debounceTimers = new Map();
|
|
23
|
+
reconnectAttempt = 0;
|
|
24
|
+
reconnectTimer = null;
|
|
25
|
+
intentionallyClosed = false;
|
|
26
|
+
wsUrl;
|
|
27
|
+
constructor(wpBridgeUrl) {
|
|
28
|
+
this.wpBridgeUrl = wpBridgeUrl;
|
|
29
|
+
this.wsUrl = wpBridgeUrl.replace(/^http/, 'ws') + '/ws';
|
|
30
|
+
}
|
|
31
|
+
startListening(dialogId, contactNumber, contactName, ownerNumber) {
|
|
32
|
+
this.ownerNumber = ownerNumber;
|
|
33
|
+
this.activeDialogs.set(contactNumber, {
|
|
34
|
+
dialogId,
|
|
35
|
+
contactName,
|
|
36
|
+
contactNumber,
|
|
37
|
+
startedAt: Date.now(),
|
|
38
|
+
});
|
|
39
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
40
|
+
this.connect();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
stopListening(dialogId) {
|
|
44
|
+
for (const [number, meta] of this.activeDialogs) {
|
|
45
|
+
if (meta.dialogId === dialogId) {
|
|
46
|
+
this.activeDialogs.delete(number);
|
|
47
|
+
// Clear debounce timer for this contact
|
|
48
|
+
const debounce = this.debounceTimers.get(number);
|
|
49
|
+
if (debounce) {
|
|
50
|
+
clearTimeout(debounce.timer);
|
|
51
|
+
this.debounceTimers.delete(number);
|
|
52
|
+
}
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (this.activeDialogs.size === 0) {
|
|
57
|
+
this.disconnect();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
stopAll() {
|
|
61
|
+
for (const debounce of this.debounceTimers.values()) {
|
|
62
|
+
clearTimeout(debounce.timer);
|
|
63
|
+
}
|
|
64
|
+
this.debounceTimers.clear();
|
|
65
|
+
this.activeDialogs.clear();
|
|
66
|
+
this.disconnect();
|
|
67
|
+
}
|
|
68
|
+
hasActiveDialogs() {
|
|
69
|
+
return this.activeDialogs.size > 0;
|
|
70
|
+
}
|
|
71
|
+
connect() {
|
|
72
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN)
|
|
73
|
+
return;
|
|
74
|
+
this.intentionallyClosed = false;
|
|
75
|
+
try {
|
|
76
|
+
this.ws = new WebSocket(this.wsUrl);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
this.scheduleReconnect();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
this.ws.onopen = () => {
|
|
83
|
+
this.reconnectAttempt = 0;
|
|
84
|
+
};
|
|
85
|
+
this.ws.onmessage = (event) => {
|
|
86
|
+
try {
|
|
87
|
+
const wsEvent = JSON.parse(String(event.data));
|
|
88
|
+
this.handleEvent(wsEvent);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// ignore malformed events
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
this.ws.onclose = () => {
|
|
95
|
+
this.ws = null;
|
|
96
|
+
if (!this.intentionallyClosed && this.activeDialogs.size > 0) {
|
|
97
|
+
this.scheduleReconnect();
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
this.ws.onerror = () => {
|
|
101
|
+
// onclose will fire after this
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
disconnect() {
|
|
105
|
+
this.intentionallyClosed = true;
|
|
106
|
+
if (this.reconnectTimer) {
|
|
107
|
+
clearTimeout(this.reconnectTimer);
|
|
108
|
+
this.reconnectTimer = null;
|
|
109
|
+
}
|
|
110
|
+
if (this.ws) {
|
|
111
|
+
this.ws.onclose = null;
|
|
112
|
+
this.ws.onerror = null;
|
|
113
|
+
this.ws.onmessage = null;
|
|
114
|
+
this.ws.close();
|
|
115
|
+
this.ws = null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
scheduleReconnect() {
|
|
119
|
+
if (this.intentionallyClosed)
|
|
120
|
+
return;
|
|
121
|
+
const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempt), MAX_RECONNECT_DELAY_MS);
|
|
122
|
+
this.reconnectAttempt++;
|
|
123
|
+
this.reconnectTimer = setTimeout(() => {
|
|
124
|
+
this.reconnectTimer = null;
|
|
125
|
+
if (this.activeDialogs.size > 0) {
|
|
126
|
+
this.connect();
|
|
127
|
+
}
|
|
128
|
+
}, delay);
|
|
129
|
+
}
|
|
130
|
+
handleEvent(event) {
|
|
131
|
+
if (event.type === 'message') {
|
|
132
|
+
this.handleIncoming(event.data);
|
|
133
|
+
}
|
|
134
|
+
else if (event.type === 'message_create') {
|
|
135
|
+
this.handleOutgoing(event.data);
|
|
136
|
+
}
|
|
137
|
+
// Ignore other event types (qr, ready, status, log, etc.)
|
|
138
|
+
}
|
|
139
|
+
handleIncoming(msg) {
|
|
140
|
+
const contactNumber = msg.from.replace(/@.*$/, '');
|
|
141
|
+
// Only process messages from active dialog contacts
|
|
142
|
+
const dialog = this.activeDialogs.get(contactNumber);
|
|
143
|
+
if (!dialog)
|
|
144
|
+
return;
|
|
145
|
+
// Skip history replay (messages before dialog started)
|
|
146
|
+
if (msg.timestamp * 1000 < dialog.startedAt)
|
|
147
|
+
return;
|
|
148
|
+
// Skip group messages
|
|
149
|
+
if (msg.from.includes('@g.us'))
|
|
150
|
+
return;
|
|
151
|
+
// Add to debounce queue
|
|
152
|
+
this.addToDebounce(contactNumber, dialog.contactName, msg.body);
|
|
153
|
+
}
|
|
154
|
+
handleOutgoing(msg) {
|
|
155
|
+
const toNumber = msg.to.replace(/@.*$/, '');
|
|
156
|
+
// Self-message = supervisor command
|
|
157
|
+
if (this.ownerNumber && toNumber === this.ownerNumber) {
|
|
158
|
+
// Skip if before any dialog started
|
|
159
|
+
const earliestStart = Math.min(...[...this.activeDialogs.values()].map(d => d.startedAt));
|
|
160
|
+
if (msg.timestamp * 1000 < earliestStart)
|
|
161
|
+
return;
|
|
162
|
+
void injectSupervisorMessage(msg.body);
|
|
163
|
+
void injectRestoreText();
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
// All other outgoing messages are echoes from Claude → SKIP
|
|
167
|
+
}
|
|
168
|
+
addToDebounce(contactNumber, contactName, body) {
|
|
169
|
+
const existing = this.debounceTimers.get(contactNumber);
|
|
170
|
+
if (existing) {
|
|
171
|
+
existing.messages.push(body);
|
|
172
|
+
clearTimeout(existing.timer);
|
|
173
|
+
existing.timer = setTimeout(() => this.flushDebounce(contactNumber, contactName), DEBOUNCE_MS);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
this.debounceTimers.set(contactNumber, {
|
|
177
|
+
messages: [body],
|
|
178
|
+
timer: setTimeout(() => this.flushDebounce(contactNumber, contactName), DEBOUNCE_MS),
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
flushDebounce(contactNumber, contactName) {
|
|
183
|
+
const entry = this.debounceTimers.get(contactNumber);
|
|
184
|
+
if (!entry)
|
|
185
|
+
return;
|
|
186
|
+
this.debounceTimers.delete(contactNumber);
|
|
187
|
+
void injectWhatsAppBatch(contactName, contactNumber, entry.messages)
|
|
188
|
+
.then(() => injectRestoreText());
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=dialog-listener.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialog-listener.service.js","sourceRoot":"","sources":["../../../src/infrastructure/whatsapp/dialog-listener.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,7 @@ import { GoogleContactsService } from '../../infrastructure/google/contacts.serv
|
|
|
7
7
|
import { GoogleGmailService } from '../../infrastructure/google/gmail.service.js';
|
|
8
8
|
import { WpBridgeService } from '../../infrastructure/whatsapp/wpbridge.service.js';
|
|
9
9
|
import { StyleAnalyzerService } from '../../infrastructure/analysis/index.js';
|
|
10
|
+
import { DialogListenerService } from '../../infrastructure/whatsapp/dialog-listener.service.js';
|
|
10
11
|
// System
|
|
11
12
|
import { registerAuthorizeGoogleTool } from './tools/authorize-google.js';
|
|
12
13
|
import { registerGetStatusTool } from './tools/get-status.js';
|
|
@@ -59,6 +60,7 @@ export async function createServer() {
|
|
|
59
60
|
const gmailService = new GoogleGmailService(authService);
|
|
60
61
|
const whatsappService = new WpBridgeService(config.wpBridgeUrl);
|
|
61
62
|
const styleAnalyzer = new StyleAnalyzerService();
|
|
63
|
+
const dialogListener = new DialogListenerService(config.wpBridgeUrl);
|
|
62
64
|
const deps = {
|
|
63
65
|
authService,
|
|
64
66
|
calendarService,
|
|
@@ -67,6 +69,7 @@ export async function createServer() {
|
|
|
67
69
|
gmailService,
|
|
68
70
|
whatsappService,
|
|
69
71
|
styleAnalyzer,
|
|
72
|
+
dialogListener,
|
|
70
73
|
};
|
|
71
74
|
const server = new McpServer({
|
|
72
75
|
name: 'tudun',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/interface/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,2CAA2C,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AAChF,OAAO,EAAE,qBAAqB,EAAE,MAAM,iDAAiD,CAAC;AACxF,OAAO,EAAE,kBAAkB,EAAE,MAAM,8CAA8C,CAAC;AAClF,OAAO,EAAE,qBAAqB,EAAE,MAAM,iDAAiD,CAAC;AACxF,OAAO,EAAE,kBAAkB,EAAE,MAAM,8CAA8C,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAC;AACpF,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/interface/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { z } from 'zod/v4';
|
|
2
2
|
export function registerStartWhatsappDialogTool(server, deps) {
|
|
3
|
-
server.tool('start_whatsapp_dialog', 'Belirli bir kisiyle WhatsApp diyalogu baslatir.
|
|
3
|
+
server.tool('start_whatsapp_dialog', 'Belirli bir kisiyle WhatsApp diyalogu baslatir. Gelen mesajlar otomatik olarak terminaline enjekte edilir. Baslatmadan once analyze_conversation_style ile stil analizi yapin.', {
|
|
4
4
|
contact_number: z.string().describe('Telefon numarasi (orn: 905551234567)'),
|
|
5
|
-
contact_name: z.string().describe('Kisi adi
|
|
6
|
-
topic: z.string().describe('Diyalog konusu
|
|
5
|
+
contact_name: z.string().describe('Kisi adi'),
|
|
6
|
+
topic: z.string().describe('Diyalog konusu'),
|
|
7
7
|
}, async ({ contact_number, contact_name, topic }) => {
|
|
8
8
|
try {
|
|
9
9
|
const result = await deps.whatsappService.startDialog({
|
|
@@ -11,28 +11,26 @@ export function registerStartWhatsappDialogTool(server, deps) {
|
|
|
11
11
|
contactName: contact_name,
|
|
12
12
|
topic,
|
|
13
13
|
});
|
|
14
|
+
// Get owner number for supervisor detection
|
|
15
|
+
let ownerNumber = '';
|
|
16
|
+
try {
|
|
17
|
+
const status = await deps.whatsappService.getStatus();
|
|
18
|
+
ownerNumber = status.phone ?? '';
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// continue without supervisor support
|
|
22
|
+
}
|
|
23
|
+
// Start WebSocket listener + terminal injection
|
|
24
|
+
deps.dialogListener.startListening(result.dialogId, result.contactNumber, result.contactName, ownerNumber);
|
|
14
25
|
const instructions = [
|
|
15
26
|
'DIYALOG BASLATILDI',
|
|
16
27
|
`Dialog ID: ${result.dialogId}`,
|
|
17
28
|
`Kisi: ${result.contactName} (${result.contactNumber})`,
|
|
18
|
-
`Mesaj dosyasi: ${result.filePath}`,
|
|
19
|
-
`Supervisor dosyasi: ${result.supervisorFilePath}`,
|
|
20
29
|
'',
|
|
21
|
-
'
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
'
|
|
25
|
-
'4. Yanit gondermek icin send_whatsapp_message tool\'unu kullan',
|
|
26
|
-
'5. Hassas konularda kullaniciya WhatsApp\'tan sor (kendi numarasina mesaj at)',
|
|
27
|
-
'6. Bitirdiginde stop_whatsapp_dialog tool\'unu cagir',
|
|
28
|
-
'',
|
|
29
|
-
'MESAJ FORMATI (her satir bir JSON):',
|
|
30
|
-
'{"from":"kisi","to":"me","message":"...","timestamp":...,"type":"incoming","id":"..."}',
|
|
31
|
-
'{"from":"me","to":"kisi","message":"...","timestamp":...,"type":"outgoing","auto":true,"id":"..."}',
|
|
32
|
-
'',
|
|
33
|
-
'SUPERVISOR MESAJLARI:',
|
|
34
|
-
'Kullanicinin kendi numarasindan gonderdigi mesajlar _supervisor.jsonl\'e yazilir.',
|
|
35
|
-
'Bu mesajlar kullanicinin sana verdigi komutlardir (ornegin: "ahmet\'e fiyat 20k de").',
|
|
30
|
+
'Mesajlar otomatik olarak terminaline enjekte edilecek [WP] formatiyla.',
|
|
31
|
+
'Yanit vermek icin: send_whatsapp_message tool\'unu kullan, stil profilini uygula.',
|
|
32
|
+
'Supervisor: WhatsApp\'tan kendine mesaj at, komut [WP SUPERVISOR] olarak terminaline gelecek.',
|
|
33
|
+
'Bitirmek icin: stop_whatsapp_dialog tool\'unu kullan.',
|
|
36
34
|
].join('\n');
|
|
37
35
|
return { content: [{ type: 'text', text: instructions }] };
|
|
38
36
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-whatsapp-dialog.js","sourceRoot":"","sources":["../../../../src/interface/mcp/tools/start-whatsapp-dialog.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAG3B,MAAM,UAAU,+BAA+B,CAAC,MAAiB,EAAE,IAAkB;IACnF,MAAM,CAAC,IAAI,CACT,uBAAuB,EACvB,
|
|
1
|
+
{"version":3,"file":"start-whatsapp-dialog.js","sourceRoot":"","sources":["../../../../src/interface/mcp/tools/start-whatsapp-dialog.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAG3B,MAAM,UAAU,+BAA+B,CAAC,MAAiB,EAAE,IAAkB;IACnF,MAAM,CAAC,IAAI,CACT,uBAAuB,EACvB,gLAAgL,EAChL;QACE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;QAC3E,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC7C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;KAC7C,EACD,KAAK,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,EAAE;QAChD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC;gBACpD,aAAa,EAAE,cAAc;gBAC7B,WAAW,EAAE,YAAY;gBACzB,KAAK;aACN,CAAC,CAAC;YAEH,4CAA4C;YAC5C,IAAI,WAAW,GAAG,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,CAAC;gBACtD,WAAW,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;YACnC,CAAC;YAAC,MAAM,CAAC;gBACP,sCAAsC;YACxC,CAAC;YAED,gDAAgD;YAChD,IAAI,CAAC,cAAc,CAAC,cAAc,CAChC,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,aAAa,EACpB,MAAM,CAAC,WAAW,EAClB,WAAW,CACZ,CAAC;YAEF,MAAM,YAAY,GAAG;gBACnB,oBAAoB;gBACpB,cAAc,MAAM,CAAC,QAAQ,EAAE;gBAC/B,SAAS,MAAM,CAAC,WAAW,KAAK,MAAM,CAAC,aAAa,GAAG;gBACvD,EAAE;gBACF,wEAAwE;gBACxE,mFAAmF;gBACnF,+FAA+F;gBAC/F,uDAAuD;aACxD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEb,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;QACtE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,0BAA2B,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC;gBAChG,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
import { z } from 'zod/v4';
|
|
2
2
|
export function registerStopWhatsappDialogTool(server, deps) {
|
|
3
|
-
server.tool('stop_whatsapp_dialog', 'Aktif bir WhatsApp diyalogunu durdurur
|
|
3
|
+
server.tool('stop_whatsapp_dialog', 'Aktif bir WhatsApp diyalogunu durdurur. Terminal injection ve WebSocket dinleme kapatilir.', {
|
|
4
4
|
dialog_id: z.string().describe('Diyalog ID (start_whatsapp_dialog ciktisindaki Dialog ID)'),
|
|
5
5
|
}, async ({ dialog_id }) => {
|
|
6
6
|
try {
|
|
7
|
+
// Stop WebSocket listener first
|
|
8
|
+
deps.dialogListener.stopListening(dialog_id);
|
|
9
|
+
// Then stop dialog on WPBridge
|
|
7
10
|
await deps.whatsappService.stopDialog(dialog_id);
|
|
8
11
|
return {
|
|
9
12
|
content: [{
|
|
10
13
|
type: 'text',
|
|
11
|
-
text:
|
|
12
|
-
`Diyalog durduruldu ve arsivlendi: ${dialog_id}`,
|
|
13
|
-
'',
|
|
14
|
-
'Yapilacaklar:',
|
|
15
|
-
'1. tail -f islemlerini durdur (background task\'lari kapat)',
|
|
16
|
-
'2. Diyalog ozeti kullaniciya bildirildi',
|
|
17
|
-
].join('\n'),
|
|
14
|
+
text: `Diyalog durduruldu: ${dialog_id}\nTerminal injection kapatildi.`,
|
|
18
15
|
}],
|
|
19
16
|
};
|
|
20
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stop-whatsapp-dialog.js","sourceRoot":"","sources":["../../../../src/interface/mcp/tools/stop-whatsapp-dialog.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAG3B,MAAM,UAAU,8BAA8B,CAAC,MAAiB,EAAE,IAAkB;IAClF,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,
|
|
1
|
+
{"version":3,"file":"stop-whatsapp-dialog.js","sourceRoot":"","sources":["../../../../src/interface/mcp/tools/stop-whatsapp-dialog.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAG3B,MAAM,UAAU,8BAA8B,CAAC,MAAiB,EAAE,IAAkB;IAClF,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,4FAA4F,EAC5F;QACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2DAA2D,CAAC;KAC5F,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QACtB,IAAI,CAAC;YACH,gCAAgC;YAChC,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;YAE7C,+BAA+B;YAC/B,MAAM,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YAEjD,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,uBAAuB,SAAS,iCAAiC;qBACxE,CAAC;aACH,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,0BAA2B,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC;gBAChG,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -5,6 +5,7 @@ import type { IContactsService } from '../../domain/ports/contacts-service.js';
|
|
|
5
5
|
import type { IGmailService } from '../../domain/ports/gmail-service.js';
|
|
6
6
|
import type { IWhatsAppService } from '../../domain/ports/whatsapp-service.js';
|
|
7
7
|
import type { IStyleAnalyzer } from '../../domain/ports/style-analyzer.js';
|
|
8
|
+
import type { DialogListenerService } from '../../infrastructure/whatsapp/dialog-listener.service.js';
|
|
8
9
|
export interface Dependencies {
|
|
9
10
|
authService: IAuthService;
|
|
10
11
|
calendarService: ICalendarService;
|
|
@@ -13,4 +14,5 @@ export interface Dependencies {
|
|
|
13
14
|
gmailService: IGmailService;
|
|
14
15
|
whatsappService: IWhatsAppService;
|
|
15
16
|
styleAnalyzer: IStyleAnalyzer;
|
|
17
|
+
dialogListener: DialogListenerService;
|
|
16
18
|
}
|
package/package.json
CHANGED