@redplanethq/corebrain 2.8.13 → 2.8.14
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/commands/coding/list.js +1 -1
- package/dist/commands/coding/list.js.map +1 -1
- package/dist/commands/coding/setup.d.ts +2 -1
- package/dist/commands/coding/setup.d.ts.map +1 -1
- package/dist/commands/coding/setup.js +1 -24
- package/dist/commands/coding/setup.js.map +1 -1
- package/dist/commands/folder/add.d.ts +13 -0
- package/dist/commands/folder/add.d.ts.map +1 -0
- package/dist/commands/folder/add.js +71 -0
- package/dist/commands/folder/add.js.map +1 -0
- package/dist/commands/folder/index.d.ts +3 -0
- package/dist/commands/folder/index.d.ts.map +1 -0
- package/dist/commands/folder/index.js +5 -0
- package/dist/commands/folder/index.js.map +1 -0
- package/dist/commands/folder/list.d.ts +8 -0
- package/dist/commands/folder/list.d.ts.map +1 -0
- package/dist/commands/folder/list.js +39 -0
- package/dist/commands/folder/list.js.map +1 -0
- package/dist/commands/folder/remove.d.ts +10 -0
- package/dist/commands/folder/remove.d.ts.map +1 -0
- package/dist/commands/folder/remove.js +29 -0
- package/dist/commands/folder/remove.js.map +1 -0
- package/dist/commands/folder/scope.d.ts +13 -0
- package/dist/commands/folder/scope.d.ts.map +1 -0
- package/dist/commands/folder/scope.js +61 -0
- package/dist/commands/folder/scope.js.map +1 -0
- package/dist/commands/gateway/config.d.ts +1 -1
- package/dist/commands/gateway/config.d.ts.map +1 -1
- package/dist/commands/gateway/config.js +122 -116
- package/dist/commands/gateway/config.js.map +1 -1
- package/dist/commands/gateway/register.d.ts +37 -0
- package/dist/commands/gateway/register.d.ts.map +1 -0
- package/dist/commands/gateway/register.js +132 -0
- package/dist/commands/gateway/register.js.map +1 -0
- package/dist/commands/gateway/start.d.ts +2 -1
- package/dist/commands/gateway/start.d.ts.map +1 -1
- package/dist/commands/gateway/start.js +73 -6
- package/dist/commands/gateway/start.js.map +1 -1
- package/dist/commands/gateway/status.d.ts.map +1 -1
- package/dist/commands/gateway/status.js +10 -1
- package/dist/commands/gateway/status.js.map +1 -1
- package/dist/commands/gateway/stop.d.ts.map +1 -1
- package/dist/commands/gateway/stop.js +11 -0
- package/dist/commands/gateway/stop.js.map +1 -1
- package/dist/config/folders.d.ts +20 -0
- package/dist/config/folders.d.ts.map +1 -0
- package/dist/config/folders.js +114 -0
- package/dist/config/folders.js.map +1 -0
- package/dist/server/api/auth.d.ts +17 -0
- package/dist/server/api/auth.d.ts.map +1 -0
- package/dist/server/api/auth.js +45 -0
- package/dist/server/api/auth.js.map +1 -0
- package/dist/server/api/browser/cdp.d.ts +18 -0
- package/dist/server/api/browser/cdp.d.ts.map +1 -0
- package/dist/server/api/browser/cdp.js +137 -0
- package/dist/server/api/browser/cdp.js.map +1 -0
- package/dist/server/api/browser/index.d.ts +3 -0
- package/dist/server/api/browser/index.d.ts.map +1 -0
- package/dist/server/api/browser/index.js +10 -0
- package/dist/server/api/browser/index.js.map +1 -0
- package/dist/server/api/browser/launch.d.ts +17 -0
- package/dist/server/api/browser/launch.d.ts.map +1 -0
- package/dist/server/api/browser/launch.js +41 -0
- package/dist/server/api/browser/launch.js.map +1 -0
- package/dist/server/api/coding/coding_spawn.d.ts +22 -0
- package/dist/server/api/coding/coding_spawn.d.ts.map +1 -0
- package/dist/server/api/coding/coding_spawn.js +121 -0
- package/dist/server/api/coding/coding_spawn.js.map +1 -0
- package/dist/server/api/coding/coding_xterm_session.d.ts +3 -0
- package/dist/server/api/coding/coding_xterm_session.d.ts.map +1 -0
- package/dist/server/api/coding/coding_xterm_session.js +163 -0
- package/dist/server/api/coding/coding_xterm_session.js.map +1 -0
- package/dist/server/api/coding/index.d.ts +10 -0
- package/dist/server/api/coding/index.d.ts.map +1 -0
- package/dist/server/api/coding/index.js +17 -0
- package/dist/server/api/coding/index.js.map +1 -0
- package/dist/server/api/exec/index.d.ts +3 -0
- package/dist/server/api/exec/index.d.ts.map +1 -0
- package/dist/server/api/exec/index.js +6 -0
- package/dist/server/api/exec/index.js.map +1 -0
- package/dist/server/api/files/index.d.ts +3 -0
- package/dist/server/api/files/index.d.ts.map +1 -0
- package/dist/server/api/files/index.js +6 -0
- package/dist/server/api/files/index.js.map +1 -0
- package/dist/server/api/folders/index.d.ts +14 -0
- package/dist/server/api/folders/index.d.ts.map +1 -0
- package/dist/server/api/folders/index.js +161 -0
- package/dist/server/api/folders/index.js.map +1 -0
- package/dist/server/api/manifest-builder.d.ts +13 -0
- package/dist/server/api/manifest-builder.d.ts.map +1 -0
- package/dist/server/api/manifest-builder.js +155 -0
- package/dist/server/api/manifest-builder.js.map +1 -0
- package/dist/server/api/ops.d.ts +3 -0
- package/dist/server/api/ops.d.ts.map +1 -0
- package/dist/server/api/ops.js +32 -0
- package/dist/server/api/ops.js.map +1 -0
- package/dist/server/api/server.d.ts +9 -0
- package/dist/server/api/server.d.ts.map +1 -0
- package/dist/server/api/server.js +66 -0
- package/dist/server/api/server.js.map +1 -0
- package/dist/server/api/shell/index.d.ts +17 -0
- package/dist/server/api/shell/index.d.ts.map +1 -0
- package/dist/server/api/shell/index.js +61 -0
- package/dist/server/api/shell/index.js.map +1 -0
- package/dist/server/api/tool-group.d.ts +21 -0
- package/dist/server/api/tool-group.d.ts.map +1 -0
- package/dist/server/api/tool-group.js +23 -0
- package/dist/server/api/tool-group.js.map +1 -0
- package/dist/server/api/tunnels/ngrok.d.ts +10 -0
- package/dist/server/api/tunnels/ngrok.d.ts.map +1 -0
- package/dist/server/api/tunnels/ngrok.js +33 -0
- package/dist/server/api/tunnels/ngrok.js.map +1 -0
- package/dist/server/api/tunnels/tailscale.d.ts +12 -0
- package/dist/server/api/tunnels/tailscale.d.ts.map +1 -0
- package/dist/server/api/tunnels/tailscale.js +49 -0
- package/dist/server/api/tunnels/tailscale.js.map +1 -0
- package/dist/server/api/utils/index.d.ts +3 -0
- package/dist/server/api/utils/index.d.ts.map +1 -0
- package/dist/server/api/utils/index.js +6 -0
- package/dist/server/api/utils/index.js.map +1 -0
- package/dist/server/gateway-entry.d.ts +2 -2
- package/dist/server/gateway-entry.js +43 -106
- package/dist/server/gateway-entry.js.map +1 -1
- package/dist/server/gateway-log.d.ts +10 -0
- package/dist/server/gateway-log.d.ts.map +1 -0
- package/dist/server/gateway-log.js +33 -0
- package/dist/server/gateway-log.js.map +1 -0
- package/dist/server/pty/manager.d.ts +75 -0
- package/dist/server/pty/manager.d.ts.map +1 -0
- package/dist/server/pty/manager.js +280 -0
- package/dist/server/pty/manager.js.map +1 -0
- package/dist/server/tools/coding-tools.d.ts.map +1 -1
- package/dist/server/tools/coding-tools.js +56 -17
- package/dist/server/tools/coding-tools.js.map +1 -1
- package/dist/server/tools/exec-tools.d.ts.map +1 -1
- package/dist/server/tools/exec-tools.js +30 -3
- package/dist/server/tools/exec-tools.js.map +1 -1
- package/dist/server/tools/files-tools.d.ts +8 -0
- package/dist/server/tools/files-tools.d.ts.map +1 -0
- package/dist/server/tools/files-tools.js +523 -0
- package/dist/server/tools/files-tools.js.map +1 -0
- package/dist/server/tools/scope-error.d.ts +8 -0
- package/dist/server/tools/scope-error.d.ts.map +1 -0
- package/dist/server/tools/scope-error.js +11 -0
- package/dist/server/tools/scope-error.js.map +1 -0
- package/dist/types/config.d.ts +15 -3
- package/dist/types/config.d.ts.map +1 -1
- package/dist/utils/agent-templates.d.ts +18 -0
- package/dist/utils/agent-templates.d.ts.map +1 -0
- package/dist/utils/agent-templates.js +59 -0
- package/dist/utils/agent-templates.js.map +1 -0
- package/dist/utils/browser-manager.d.ts +20 -0
- package/dist/utils/browser-manager.d.ts.map +1 -1
- package/dist/utils/browser-manager.js +76 -0
- package/dist/utils/browser-manager.js.map +1 -1
- package/dist/utils/coding-agents/codex.d.ts +5 -8
- package/dist/utils/coding-agents/codex.d.ts.map +1 -1
- package/dist/utils/coding-agents/codex.js +6 -26
- package/dist/utils/coding-agents/codex.js.map +1 -1
- package/dist/utils/coding-runner.d.ts +13 -9
- package/dist/utils/coding-runner.d.ts.map +1 -1
- package/dist/utils/coding-runner.js +45 -78
- package/dist/utils/coding-runner.js.map +1 -1
- package/dist/utils/env-bootstrap.d.ts +29 -0
- package/dist/utils/env-bootstrap.d.ts.map +1 -0
- package/dist/utils/env-bootstrap.js +204 -0
- package/dist/utils/env-bootstrap.js.map +1 -0
- package/package.json +8 -1
- package/dist/commands/coding/close.d.ts +0 -11
- package/dist/commands/coding/close.d.ts.map +0 -1
- package/dist/commands/coding/close.js +0 -76
- package/dist/commands/coding/close.js.map +0 -1
- package/dist/commands/coding/resume.d.ts +0 -12
- package/dist/commands/coding/resume.d.ts.map +0 -1
- package/dist/commands/coding/resume.js +0 -86
- package/dist/commands/coding/resume.js.map +0 -1
- package/dist/commands/coding/start.d.ts +0 -17
- package/dist/commands/coding/start.d.ts.map +0 -1
- package/dist/commands/coding/start.js +0 -135
- package/dist/commands/coding/start.js.map +0 -1
- package/dist/server/gateway-client.d.ts +0 -84
- package/dist/server/gateway-client.d.ts.map +0 -1
- package/dist/server/gateway-client.js +0 -340
- package/dist/server/gateway-client.js.map +0 -1
- package/dist/server/tools/imessage-tools.d.ts +0 -34
- package/dist/server/tools/imessage-tools.d.ts.map +0 -1
- package/dist/server/tools/imessage-tools.js +0 -262
- package/dist/server/tools/imessage-tools.js.map +0 -1
- package/dist/utils/app-bundle.d.ts +0 -25
- package/dist/utils/app-bundle.d.ts.map +0 -1
- package/dist/utils/app-bundle.js +0 -117
- package/dist/utils/app-bundle.js.map +0 -1
|
@@ -1,340 +0,0 @@
|
|
|
1
|
-
import WebSocket from 'ws';
|
|
2
|
-
import { hostname } from 'node:os';
|
|
3
|
-
import { browserTools, executeBrowserTool } from '../server/tools/browser-tools.js';
|
|
4
|
-
import { codingTools, executeCodingTool } from '../server/tools/coding-tools.js';
|
|
5
|
-
import { execTools, executeExecTool } from '../server/tools/exec-tools.js';
|
|
6
|
-
import { utilsTools, executeUtilsTool } from '../server/tools/utils-tools.js';
|
|
7
|
-
import { imessageTools, executeIMessageTool } from '../server/tools/imessage-tools.js';
|
|
8
|
-
import { closeAllSessions } from '../utils/browser-manager.js';
|
|
9
|
-
import { getPreferences } from '../config/preferences.js';
|
|
10
|
-
export class GatewayClient {
|
|
11
|
-
ws = null;
|
|
12
|
-
config;
|
|
13
|
-
state = 'disconnected';
|
|
14
|
-
gatewayId = null;
|
|
15
|
-
reconnectAttempts = 0;
|
|
16
|
-
maxReconnectAttempts = 10;
|
|
17
|
-
reconnectTimer = null;
|
|
18
|
-
shouldReconnect = true;
|
|
19
|
-
pingInterval = null;
|
|
20
|
-
constructor(config) {
|
|
21
|
-
this.config = config;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Log a message using the provided logger or console
|
|
25
|
-
*/
|
|
26
|
-
log(message) {
|
|
27
|
-
if (this.config.logger) {
|
|
28
|
-
this.config.logger(message);
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
console.log(message);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Get enabled tools based on gateway slots config
|
|
36
|
-
*/
|
|
37
|
-
getEnabledTools() {
|
|
38
|
-
const prefs = getPreferences();
|
|
39
|
-
const slots = prefs.gateway?.slots;
|
|
40
|
-
const tools = [];
|
|
41
|
-
// Utils tools (sleep, etc.) are always available
|
|
42
|
-
tools.push(...utilsTools);
|
|
43
|
-
if (slots?.browser?.enabled) {
|
|
44
|
-
tools.push(...browserTools);
|
|
45
|
-
}
|
|
46
|
-
if (slots?.coding?.enabled) {
|
|
47
|
-
tools.push(...codingTools);
|
|
48
|
-
}
|
|
49
|
-
if (slots?.exec?.enabled) {
|
|
50
|
-
tools.push(...execTools);
|
|
51
|
-
}
|
|
52
|
-
if (slots?.imessage?.enabled) {
|
|
53
|
-
tools.push(...imessageTools);
|
|
54
|
-
}
|
|
55
|
-
return tools;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Build the WebSocket URL from config
|
|
59
|
-
*/
|
|
60
|
-
buildWsUrl() {
|
|
61
|
-
let baseUrl = this.config.url;
|
|
62
|
-
// Convert http(s) to ws(s)
|
|
63
|
-
if (baseUrl.startsWith('https://')) {
|
|
64
|
-
baseUrl = 'wss://' + baseUrl.slice(8);
|
|
65
|
-
}
|
|
66
|
-
else if (baseUrl.startsWith('http://')) {
|
|
67
|
-
baseUrl = 'ws://' + baseUrl.slice(7);
|
|
68
|
-
}
|
|
69
|
-
// Remove trailing slash
|
|
70
|
-
if (baseUrl.endsWith('/')) {
|
|
71
|
-
baseUrl = baseUrl.slice(0, -1);
|
|
72
|
-
}
|
|
73
|
-
return `${baseUrl}/gateway/ws?token=${encodeURIComponent(this.config.apiKey)}`;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Connect to the gateway WebSocket server
|
|
77
|
-
*/
|
|
78
|
-
connect() {
|
|
79
|
-
if (this.state !== 'disconnected') {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
this.shouldReconnect = true;
|
|
83
|
-
this.state = 'connecting';
|
|
84
|
-
const wsUrl = this.buildWsUrl();
|
|
85
|
-
this.log(`Connecting to gateway: ${this.config.url}`);
|
|
86
|
-
this.ws = new WebSocket(wsUrl);
|
|
87
|
-
this.ws.on('open', () => {
|
|
88
|
-
this.state = 'connected';
|
|
89
|
-
this.reconnectAttempts = 0;
|
|
90
|
-
this.log('Gateway WebSocket connected');
|
|
91
|
-
this.config.onConnect?.();
|
|
92
|
-
// Send init message
|
|
93
|
-
this.send({
|
|
94
|
-
type: 'init',
|
|
95
|
-
gatewayId: this.config.gatewayId,
|
|
96
|
-
name: this.config.name,
|
|
97
|
-
description: this.config.description,
|
|
98
|
-
platform: process.platform,
|
|
99
|
-
hostname: hostname(),
|
|
100
|
-
clientVersion: '1.0.0',
|
|
101
|
-
});
|
|
102
|
-
// Start ping interval to keep connection alive
|
|
103
|
-
this.startPingInterval();
|
|
104
|
-
});
|
|
105
|
-
this.ws.on('message', async (data) => {
|
|
106
|
-
try {
|
|
107
|
-
const message = JSON.parse(data.toString());
|
|
108
|
-
await this.handleMessage(message);
|
|
109
|
-
}
|
|
110
|
-
catch (parseErr) {
|
|
111
|
-
this.log(`ERROR: Failed to parse message: ${parseErr}`);
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
this.ws.on('close', () => {
|
|
115
|
-
this.handleDisconnect();
|
|
116
|
-
});
|
|
117
|
-
this.ws.on('error', (wsErr) => {
|
|
118
|
-
this.log(`ERROR: Gateway WebSocket error: ${wsErr.message}`);
|
|
119
|
-
this.config.onError?.(wsErr);
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Handle incoming messages from server
|
|
124
|
-
*/
|
|
125
|
-
async handleMessage(message) {
|
|
126
|
-
switch (message.type) {
|
|
127
|
-
case 'get_supported_tools': {
|
|
128
|
-
const enabledTools = this.getEnabledTools();
|
|
129
|
-
this.log(`Sending ${enabledTools.length} enabled tools`);
|
|
130
|
-
this.send({
|
|
131
|
-
type: 'supported_tools',
|
|
132
|
-
tools: enabledTools,
|
|
133
|
-
});
|
|
134
|
-
break;
|
|
135
|
-
}
|
|
136
|
-
case 'ready': {
|
|
137
|
-
this.state = 'ready';
|
|
138
|
-
const readyMsg = message;
|
|
139
|
-
this.gatewayId = readyMsg.gatewayId;
|
|
140
|
-
this.log(`Gateway ready: ${this.gatewayId}`);
|
|
141
|
-
this.config.onReady?.(this.gatewayId);
|
|
142
|
-
break;
|
|
143
|
-
}
|
|
144
|
-
case 'tool_call': {
|
|
145
|
-
const toolCall = message;
|
|
146
|
-
this.log(`TOOL_CALL: ${toolCall.tool} (id: ${toolCall.id})`);
|
|
147
|
-
this.log(`TOOL_PARAMS: ${JSON.stringify(toolCall.params)}`);
|
|
148
|
-
try {
|
|
149
|
-
let result;
|
|
150
|
-
const prefs = getPreferences();
|
|
151
|
-
const slots = prefs.gateway?.slots;
|
|
152
|
-
// Route to appropriate executor based on tool prefix (with slot check)
|
|
153
|
-
if (toolCall.tool === 'sleep') {
|
|
154
|
-
result = await executeUtilsTool(toolCall.tool, toolCall.params);
|
|
155
|
-
}
|
|
156
|
-
else if (toolCall.tool.startsWith('browser_')) {
|
|
157
|
-
if (!slots?.browser?.enabled) {
|
|
158
|
-
result = { success: false, error: 'Browser slot is not enabled' };
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
result = await executeBrowserTool(toolCall.tool, toolCall.params);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
else if (toolCall.tool.startsWith('coding_')) {
|
|
165
|
-
if (!slots?.coding?.enabled) {
|
|
166
|
-
result = { success: false, error: 'Coding slot is not enabled' };
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
result = await executeCodingTool(toolCall.tool, toolCall.params, msg => this.log(msg));
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
else if (toolCall.tool.startsWith('exec_')) {
|
|
173
|
-
if (!slots?.exec?.enabled) {
|
|
174
|
-
result = { success: false, error: 'Exec slot is not enabled' };
|
|
175
|
-
}
|
|
176
|
-
else {
|
|
177
|
-
result = await executeExecTool(toolCall.tool, toolCall.params);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
else if (toolCall.tool.startsWith('imessage_')) {
|
|
181
|
-
if (!slots?.imessage?.enabled) {
|
|
182
|
-
result = { success: false, error: 'iMessage slot is not enabled' };
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
result = await executeIMessageTool(toolCall.tool, toolCall.params);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
result = { success: false, error: `Unknown tool: ${toolCall.tool}` };
|
|
190
|
-
}
|
|
191
|
-
if (result.success) {
|
|
192
|
-
this.log(`TOOL_RESULT: ${toolCall.tool} (id: ${toolCall.id}) - success - ${JSON.stringify(result.result)}`);
|
|
193
|
-
this.send({
|
|
194
|
-
type: 'tool_result',
|
|
195
|
-
id: toolCall.id,
|
|
196
|
-
result: result.result,
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
else {
|
|
200
|
-
this.log(`TOOL_ERROR: ${toolCall.tool} (id: ${toolCall.id}) - ${result.error}`);
|
|
201
|
-
this.send({
|
|
202
|
-
type: 'tool_result',
|
|
203
|
-
id: toolCall.id,
|
|
204
|
-
error: result.error,
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
catch (err) {
|
|
209
|
-
const errorMessage = err instanceof Error ? err.message : 'Unknown error';
|
|
210
|
-
this.log(`TOOL_EXCEPTION: ${toolCall.tool} (id: ${toolCall.id}) - ${errorMessage}`);
|
|
211
|
-
this.send({
|
|
212
|
-
type: 'tool_result',
|
|
213
|
-
id: toolCall.id,
|
|
214
|
-
error: errorMessage,
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
break;
|
|
218
|
-
}
|
|
219
|
-
case 'ping': {
|
|
220
|
-
this.send({ type: 'pong' });
|
|
221
|
-
break;
|
|
222
|
-
}
|
|
223
|
-
case 'error': {
|
|
224
|
-
const errorMsg = message;
|
|
225
|
-
this.log(`ERROR: Gateway error: ${errorMsg.message} (${errorMsg.code})`);
|
|
226
|
-
break;
|
|
227
|
-
}
|
|
228
|
-
default:
|
|
229
|
-
this.log(`Unknown message type: ${message.type}`);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* Handle disconnect and attempt reconnection
|
|
234
|
-
*/
|
|
235
|
-
async handleDisconnect() {
|
|
236
|
-
const wasReady = this.state === 'ready';
|
|
237
|
-
this.state = 'disconnected';
|
|
238
|
-
this.gatewayId = null;
|
|
239
|
-
this.ws = null;
|
|
240
|
-
this.stopPingInterval();
|
|
241
|
-
this.log('Gateway WebSocket disconnected');
|
|
242
|
-
this.config.onDisconnect?.();
|
|
243
|
-
// Auto-close all browser sessions on disconnect
|
|
244
|
-
if (wasReady) {
|
|
245
|
-
this.log('Closing all browser sessions...');
|
|
246
|
-
try {
|
|
247
|
-
await closeAllSessions();
|
|
248
|
-
}
|
|
249
|
-
catch {
|
|
250
|
-
// Ignore errors when closing browser
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
// Attempt reconnection with exponential backoff
|
|
254
|
-
if (this.shouldReconnect &&
|
|
255
|
-
this.reconnectAttempts < this.maxReconnectAttempts) {
|
|
256
|
-
const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);
|
|
257
|
-
this.reconnectAttempts++;
|
|
258
|
-
this.log(`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);
|
|
259
|
-
this.reconnectTimer = setTimeout(() => {
|
|
260
|
-
this.connect();
|
|
261
|
-
}, delay);
|
|
262
|
-
}
|
|
263
|
-
else if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
264
|
-
this.log('Max reconnection attempts reached. Shutting down gateway.');
|
|
265
|
-
this.config.onMaxReconnectReached?.();
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
/**
|
|
269
|
-
* Send a message to the server
|
|
270
|
-
*/
|
|
271
|
-
send(message) {
|
|
272
|
-
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
273
|
-
this.ws.send(JSON.stringify(message));
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Start ping interval to keep connection alive
|
|
278
|
-
*/
|
|
279
|
-
startPingInterval() {
|
|
280
|
-
this.stopPingInterval();
|
|
281
|
-
this.pingInterval = setInterval(() => {
|
|
282
|
-
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
283
|
-
this.ws.ping();
|
|
284
|
-
}
|
|
285
|
-
}, 30000);
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Stop ping interval
|
|
289
|
-
*/
|
|
290
|
-
stopPingInterval() {
|
|
291
|
-
if (this.pingInterval) {
|
|
292
|
-
clearInterval(this.pingInterval);
|
|
293
|
-
this.pingInterval = null;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
/**
|
|
297
|
-
* Disconnect from the gateway
|
|
298
|
-
*/
|
|
299
|
-
disconnect() {
|
|
300
|
-
this.shouldReconnect = false;
|
|
301
|
-
if (this.reconnectTimer) {
|
|
302
|
-
clearTimeout(this.reconnectTimer);
|
|
303
|
-
this.reconnectTimer = null;
|
|
304
|
-
}
|
|
305
|
-
this.stopPingInterval();
|
|
306
|
-
if (this.ws) {
|
|
307
|
-
this.ws.close();
|
|
308
|
-
this.ws = null;
|
|
309
|
-
}
|
|
310
|
-
this.state = 'disconnected';
|
|
311
|
-
this.gatewayId = null;
|
|
312
|
-
}
|
|
313
|
-
/**
|
|
314
|
-
* Get the current state
|
|
315
|
-
*/
|
|
316
|
-
getState() {
|
|
317
|
-
return this.state;
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* Get the gateway ID (if ready)
|
|
321
|
-
*/
|
|
322
|
-
getGatewayId() {
|
|
323
|
-
return this.gatewayId;
|
|
324
|
-
}
|
|
325
|
-
/**
|
|
326
|
-
* Check if connected and ready
|
|
327
|
-
*/
|
|
328
|
-
isReady() {
|
|
329
|
-
return this.state === 'ready';
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* Create and connect a gateway client
|
|
334
|
-
*/
|
|
335
|
-
export function createGatewayClient(config) {
|
|
336
|
-
const client = new GatewayClient(config);
|
|
337
|
-
client.connect();
|
|
338
|
-
return client;
|
|
339
|
-
}
|
|
340
|
-
//# sourceMappingURL=gateway-client.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gateway-client.js","sourceRoot":"","sources":["../../src/server/gateway-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import zod from 'zod';
|
|
2
|
-
import type { GatewayTool } from '../../server/tools/browser-tools.js';
|
|
3
|
-
export declare const IMessageGetThreadsSchema: zod.ZodObject<{
|
|
4
|
-
limit: zod.ZodDefault<zod.ZodOptional<zod.ZodNumber>>;
|
|
5
|
-
sender: zod.ZodOptional<zod.ZodString>;
|
|
6
|
-
after: zod.ZodOptional<zod.ZodString>;
|
|
7
|
-
before: zod.ZodOptional<zod.ZodString>;
|
|
8
|
-
}, zod.core.$strip>;
|
|
9
|
-
export declare const IMessageGetMessagesSchema: zod.ZodObject<{
|
|
10
|
-
threadId: zod.ZodString;
|
|
11
|
-
limit: zod.ZodDefault<zod.ZodOptional<zod.ZodNumber>>;
|
|
12
|
-
after: zod.ZodOptional<zod.ZodString>;
|
|
13
|
-
before: zod.ZodOptional<zod.ZodString>;
|
|
14
|
-
fromMe: zod.ZodOptional<zod.ZodBoolean>;
|
|
15
|
-
}, zod.core.$strip>;
|
|
16
|
-
export declare const IMessageSearchSchema: zod.ZodObject<{
|
|
17
|
-
query: zod.ZodString;
|
|
18
|
-
limit: zod.ZodDefault<zod.ZodOptional<zod.ZodNumber>>;
|
|
19
|
-
after: zod.ZodOptional<zod.ZodString>;
|
|
20
|
-
before: zod.ZodOptional<zod.ZodString>;
|
|
21
|
-
sender: zod.ZodOptional<zod.ZodString>;
|
|
22
|
-
fromMe: zod.ZodOptional<zod.ZodBoolean>;
|
|
23
|
-
}, zod.core.$strip>;
|
|
24
|
-
export declare const IMessageSendSchema: zod.ZodObject<{
|
|
25
|
-
to: zod.ZodString;
|
|
26
|
-
message: zod.ZodString;
|
|
27
|
-
}, zod.core.$strip>;
|
|
28
|
-
export declare const imessageTools: GatewayTool[];
|
|
29
|
-
export declare function executeIMessageTool(toolName: string, params: Record<string, unknown>): Promise<{
|
|
30
|
-
success: boolean;
|
|
31
|
-
result?: unknown;
|
|
32
|
-
error?: string;
|
|
33
|
-
}>;
|
|
34
|
-
//# sourceMappingURL=imessage-tools.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"imessage-tools.d.ts","sourceRoot":"","sources":["../../../src/server/tools/imessage-tools.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAC;AAItB,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAQ9D,eAAO,MAAM,wBAAwB;;;;;mBAKnC,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;mBAMpC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;mBAO/B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;mBAG7B,CAAC;AAkDH,eAAO,MAAM,aAAa,EAAE,WAAW,EAqBtC,CAAC;AA0CF,wBAAsB,mBAAmB,CACxC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC,CA+I/D"}
|
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
import zod from 'zod';
|
|
2
|
-
import { execSync } from 'node:child_process';
|
|
3
|
-
import { homedir } from 'node:os';
|
|
4
|
-
import { join } from 'node:path';
|
|
5
|
-
// ============ Constants ============
|
|
6
|
-
const DB_PATH = join(homedir(), 'Library/Messages/chat.db');
|
|
7
|
-
// ============ Zod Schemas ============
|
|
8
|
-
export const IMessageGetThreadsSchema = zod.object({
|
|
9
|
-
limit: zod.number().optional().default(10).describe('Number of threads to return (default: 10)'),
|
|
10
|
-
sender: zod.string().optional().describe('Filter by phone number or sender ID (partial match)'),
|
|
11
|
-
after: zod.string().optional().describe('Filter threads active after this date (ISO 8601 or YYYY-MM-DD)'),
|
|
12
|
-
before: zod.string().optional().describe('Filter threads active before this date (ISO 8601 or YYYY-MM-DD)'),
|
|
13
|
-
});
|
|
14
|
-
export const IMessageGetMessagesSchema = zod.object({
|
|
15
|
-
threadId: zod.string().describe('Chat identifier (phone number, email, or sender ID)'),
|
|
16
|
-
limit: zod.number().optional().default(20).describe('Number of messages to return (default: 20)'),
|
|
17
|
-
after: zod.string().optional().describe('Filter messages after this date (ISO 8601 or YYYY-MM-DD)'),
|
|
18
|
-
before: zod.string().optional().describe('Filter messages before this date (ISO 8601 or YYYY-MM-DD)'),
|
|
19
|
-
fromMe: zod.boolean().optional().describe('true = only sent, false = only received'),
|
|
20
|
-
});
|
|
21
|
-
export const IMessageSearchSchema = zod.object({
|
|
22
|
-
query: zod.string().describe('Text to search for in messages'),
|
|
23
|
-
limit: zod.number().optional().default(20).describe('Number of results to return (default: 20)'),
|
|
24
|
-
after: zod.string().optional().describe('Search messages after this date — recommended to limit scope (ISO 8601 or YYYY-MM-DD)'),
|
|
25
|
-
before: zod.string().optional().describe('Search messages before this date — recommended to limit scope (ISO 8601 or YYYY-MM-DD)'),
|
|
26
|
-
sender: zod.string().optional().describe('Limit search to a specific sender (partial match)'),
|
|
27
|
-
fromMe: zod.boolean().optional().describe('true = only sent messages, false = only received'),
|
|
28
|
-
});
|
|
29
|
-
export const IMessageSendSchema = zod.object({
|
|
30
|
-
to: zod.string().describe('Phone number or email to send to'),
|
|
31
|
-
message: zod.string().describe('Message text to send'),
|
|
32
|
-
});
|
|
33
|
-
// ============ JSON Schemas ============
|
|
34
|
-
const jsonSchemas = {
|
|
35
|
-
imessage_get_threads: {
|
|
36
|
-
type: 'object',
|
|
37
|
-
properties: {
|
|
38
|
-
limit: { type: 'number', description: 'Number of threads to return (default: 10)' },
|
|
39
|
-
sender: { type: 'string', description: 'Filter by phone number or sender ID (partial match)' },
|
|
40
|
-
after: { type: 'string', description: 'Filter threads active after this date (ISO 8601 or YYYY-MM-DD)' },
|
|
41
|
-
before: { type: 'string', description: 'Filter threads active before this date (ISO 8601 or YYYY-MM-DD)' },
|
|
42
|
-
},
|
|
43
|
-
required: [],
|
|
44
|
-
},
|
|
45
|
-
imessage_get_messages: {
|
|
46
|
-
type: 'object',
|
|
47
|
-
properties: {
|
|
48
|
-
threadId: { type: 'string', description: 'Chat identifier (phone number, email, or sender ID)' },
|
|
49
|
-
limit: { type: 'number', description: 'Number of messages to return (default: 20)' },
|
|
50
|
-
after: { type: 'string', description: 'Filter messages after this date (ISO 8601 or YYYY-MM-DD)' },
|
|
51
|
-
before: { type: 'string', description: 'Filter messages before this date (ISO 8601 or YYYY-MM-DD)' },
|
|
52
|
-
fromMe: { type: 'boolean', description: 'true = only sent, false = only received' },
|
|
53
|
-
},
|
|
54
|
-
required: ['threadId'],
|
|
55
|
-
},
|
|
56
|
-
imessage_search: {
|
|
57
|
-
type: 'object',
|
|
58
|
-
properties: {
|
|
59
|
-
query: { type: 'string', description: 'Text to search for in messages' },
|
|
60
|
-
limit: { type: 'number', description: 'Number of results to return (default: 20)' },
|
|
61
|
-
after: { type: 'string', description: 'Search messages after this date — recommended to limit scope (ISO 8601 or YYYY-MM-DD)' },
|
|
62
|
-
before: { type: 'string', description: 'Search messages before this date — recommended to limit scope (ISO 8601 or YYYY-MM-DD)' },
|
|
63
|
-
sender: { type: 'string', description: 'Limit search to a specific sender (partial match)' },
|
|
64
|
-
fromMe: { type: 'boolean', description: 'true = only sent messages, false = only received' },
|
|
65
|
-
},
|
|
66
|
-
required: ['query'],
|
|
67
|
-
},
|
|
68
|
-
imessage_send: {
|
|
69
|
-
type: 'object',
|
|
70
|
-
properties: {
|
|
71
|
-
to: { type: 'string', description: 'Phone number or email to send to' },
|
|
72
|
-
message: { type: 'string', description: 'Message text to send' },
|
|
73
|
-
},
|
|
74
|
-
required: ['to', 'message'],
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
// ============ Tool Definitions ============
|
|
78
|
-
export const imessageTools = [
|
|
79
|
-
{
|
|
80
|
-
name: 'imessage_get_threads',
|
|
81
|
-
description: 'Get recent iMessage/SMS conversation threads. Can filter by sender and date range.',
|
|
82
|
-
inputSchema: jsonSchemas.imessage_get_threads,
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
name: 'imessage_get_messages',
|
|
86
|
-
description: 'Get messages from a specific thread by sender ID, phone number, or email. Can filter by date range and sent/received.',
|
|
87
|
-
inputSchema: jsonSchemas.imessage_get_messages,
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
name: 'imessage_search',
|
|
91
|
-
description: 'Search iMessage/SMS history by text. Use after/before to limit scope. Works for SMS too.',
|
|
92
|
-
inputSchema: jsonSchemas.imessage_search,
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
name: 'imessage_send',
|
|
96
|
-
description: 'Send an iMessage to a phone number or email address.',
|
|
97
|
-
inputSchema: jsonSchemas.imessage_send,
|
|
98
|
-
},
|
|
99
|
-
];
|
|
100
|
-
// ============ Query Runner ============
|
|
101
|
-
// Uses osascript "do shell script" to run sqlite3 under the user's login session.
|
|
102
|
-
// This only requires Automation permission (one-time popup) — no Full Disk Access needed.
|
|
103
|
-
function runSQL(sql) {
|
|
104
|
-
// Base64-encode SQL to avoid all shell quoting/escaping issues.
|
|
105
|
-
// The gateway runs via CoreBrainGateway.app which has Full Disk Access —
|
|
106
|
-
// so we pipe directly to sqlite3 without any osascript wrapper.
|
|
107
|
-
const b64 = Buffer.from(sql).toString('base64');
|
|
108
|
-
let output;
|
|
109
|
-
try {
|
|
110
|
-
output = execSync(`echo "${b64}" | base64 -d | sqlite3 -json "${DB_PATH}"`, { encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024 }).trim();
|
|
111
|
-
}
|
|
112
|
-
catch (err) {
|
|
113
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
114
|
-
if (msg.includes('authorization denied') || msg.includes('unable to open')) {
|
|
115
|
-
throw new Error('Full Disk Access required for iMessage tools. Run: corebrain gateway config and re-enable iMessage to complete setup.');
|
|
116
|
-
}
|
|
117
|
-
throw new Error(`iMessage query failed: ${msg}`);
|
|
118
|
-
}
|
|
119
|
-
return output ? JSON.parse(output) : [];
|
|
120
|
-
}
|
|
121
|
-
function escapeSQL(str) {
|
|
122
|
-
return str.replace(/'/g, "''");
|
|
123
|
-
}
|
|
124
|
-
// Convert ISO/YYYY-MM-DD date to Apple CoreData nanosecond timestamp
|
|
125
|
-
function toAppleTs(dateStr) {
|
|
126
|
-
const secs = Math.floor(new Date(dateStr).getTime() / 1000);
|
|
127
|
-
return (secs - 978307200) * 1_000_000_000;
|
|
128
|
-
}
|
|
129
|
-
// ============ Tool Execution ============
|
|
130
|
-
export async function executeIMessageTool(toolName, params) {
|
|
131
|
-
try {
|
|
132
|
-
switch (toolName) {
|
|
133
|
-
case 'imessage_get_threads': {
|
|
134
|
-
const p = IMessageGetThreadsSchema.parse(params);
|
|
135
|
-
const conditions = [];
|
|
136
|
-
if (p.sender) {
|
|
137
|
-
conditions.push(`c.chat_identifier LIKE '%${escapeSQL(p.sender)}%'`);
|
|
138
|
-
}
|
|
139
|
-
if (p.after) {
|
|
140
|
-
conditions.push(`m.date >= ${toAppleTs(p.after)}`);
|
|
141
|
-
}
|
|
142
|
-
if (p.before) {
|
|
143
|
-
conditions.push(`m.date <= ${toAppleTs(p.before)}`);
|
|
144
|
-
}
|
|
145
|
-
const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
146
|
-
const sql = `
|
|
147
|
-
SELECT
|
|
148
|
-
c.chat_identifier,
|
|
149
|
-
c.display_name,
|
|
150
|
-
datetime(MAX(m.date)/1000000000 + 978307200, 'unixepoch', 'localtime') AS last_message_date,
|
|
151
|
-
COUNT(m.ROWID) AS message_count
|
|
152
|
-
FROM chat c
|
|
153
|
-
LEFT JOIN chat_message_join cmj ON c.ROWID = cmj.chat_id
|
|
154
|
-
LEFT JOIN message m ON cmj.message_id = m.ROWID
|
|
155
|
-
${where}
|
|
156
|
-
GROUP BY c.ROWID
|
|
157
|
-
ORDER BY MAX(m.date) DESC
|
|
158
|
-
LIMIT ${p.limit}
|
|
159
|
-
`;
|
|
160
|
-
const threads = runSQL(sql);
|
|
161
|
-
return { success: true, result: { threads, count: threads.length } };
|
|
162
|
-
}
|
|
163
|
-
case 'imessage_get_messages': {
|
|
164
|
-
const p = IMessageGetMessagesSchema.parse(params);
|
|
165
|
-
const conditions = [
|
|
166
|
-
`c.chat_identifier LIKE '%${escapeSQL(p.threadId)}%'`,
|
|
167
|
-
];
|
|
168
|
-
if (p.after)
|
|
169
|
-
conditions.push(`m.date >= ${toAppleTs(p.after)}`);
|
|
170
|
-
if (p.before)
|
|
171
|
-
conditions.push(`m.date <= ${toAppleTs(p.before)}`);
|
|
172
|
-
if (p.fromMe !== undefined)
|
|
173
|
-
conditions.push(`m.is_from_me = ${p.fromMe ? 1 : 0}`);
|
|
174
|
-
const sql = `
|
|
175
|
-
SELECT
|
|
176
|
-
COALESCE(h.id, 'me') AS sender,
|
|
177
|
-
m.text,
|
|
178
|
-
m.is_from_me,
|
|
179
|
-
datetime(m.date/1000000000 + 978307200, 'unixepoch', 'localtime') AS date,
|
|
180
|
-
m.is_read
|
|
181
|
-
FROM message m
|
|
182
|
-
JOIN chat_message_join cmj ON m.ROWID = cmj.message_id
|
|
183
|
-
JOIN chat c ON cmj.chat_id = c.ROWID
|
|
184
|
-
LEFT JOIN handle h ON m.handle_id = h.ROWID
|
|
185
|
-
WHERE ${conditions.join(' AND ')}
|
|
186
|
-
ORDER BY m.date DESC
|
|
187
|
-
LIMIT ${p.limit}
|
|
188
|
-
`;
|
|
189
|
-
const messages = runSQL(sql);
|
|
190
|
-
return {
|
|
191
|
-
success: true,
|
|
192
|
-
result: {
|
|
193
|
-
threadId: p.threadId,
|
|
194
|
-
messages: messages.reverse(),
|
|
195
|
-
count: messages.length,
|
|
196
|
-
},
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
case 'imessage_search': {
|
|
200
|
-
const p = IMessageSearchSchema.parse(params);
|
|
201
|
-
const conditions = [
|
|
202
|
-
`m.text LIKE '%${escapeSQL(p.query)}%'`,
|
|
203
|
-
];
|
|
204
|
-
if (p.sender) {
|
|
205
|
-
conditions.push(`(c.chat_identifier LIKE '%${escapeSQL(p.sender)}%' OR h.id LIKE '%${escapeSQL(p.sender)}%')`);
|
|
206
|
-
}
|
|
207
|
-
if (p.after)
|
|
208
|
-
conditions.push(`m.date >= ${toAppleTs(p.after)}`);
|
|
209
|
-
if (p.before)
|
|
210
|
-
conditions.push(`m.date <= ${toAppleTs(p.before)}`);
|
|
211
|
-
if (p.fromMe !== undefined)
|
|
212
|
-
conditions.push(`m.is_from_me = ${p.fromMe ? 1 : 0}`);
|
|
213
|
-
const sql = `
|
|
214
|
-
SELECT
|
|
215
|
-
c.chat_identifier,
|
|
216
|
-
COALESCE(h.id, 'me') AS sender,
|
|
217
|
-
m.text,
|
|
218
|
-
m.is_from_me,
|
|
219
|
-
datetime(m.date/1000000000 + 978307200, 'unixepoch', 'localtime') AS date
|
|
220
|
-
FROM message m
|
|
221
|
-
JOIN chat_message_join cmj ON m.ROWID = cmj.message_id
|
|
222
|
-
JOIN chat c ON cmj.chat_id = c.ROWID
|
|
223
|
-
LEFT JOIN handle h ON m.handle_id = h.ROWID
|
|
224
|
-
WHERE ${conditions.join(' AND ')}
|
|
225
|
-
ORDER BY m.date DESC
|
|
226
|
-
LIMIT ${p.limit}
|
|
227
|
-
`;
|
|
228
|
-
const messages = runSQL(sql);
|
|
229
|
-
return { success: true, result: { query: p.query, messages, count: messages.length } };
|
|
230
|
-
}
|
|
231
|
-
case 'imessage_send': {
|
|
232
|
-
const p = IMessageSendSchema.parse(params);
|
|
233
|
-
const to = p.to.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
234
|
-
const msg = p.message.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
235
|
-
const script = [
|
|
236
|
-
'tell application "Messages"',
|
|
237
|
-
'set targetService to 1st account whose service type = iMessage',
|
|
238
|
-
`set targetBuddy to participant "${to}" of targetService`,
|
|
239
|
-
`send "${msg}" to targetBuddy`,
|
|
240
|
-
'end tell',
|
|
241
|
-
].join('\n');
|
|
242
|
-
execSync(`osascript -e '${script.replace(/'/g, "'\\''")}'`, { encoding: 'utf-8' });
|
|
243
|
-
return {
|
|
244
|
-
success: true,
|
|
245
|
-
result: { message: `Message sent to ${p.to}`, to: p.to, text: p.message },
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
default:
|
|
249
|
-
return { success: false, error: `Unknown tool: ${toolName}` };
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
catch (err) {
|
|
253
|
-
if (err instanceof zod.ZodError) {
|
|
254
|
-
return { success: false, error: `Invalid parameters: ${err.message}` };
|
|
255
|
-
}
|
|
256
|
-
return {
|
|
257
|
-
success: false,
|
|
258
|
-
error: err instanceof Error ? err.message : 'Unknown error',
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
//# sourceMappingURL=imessage-tools.js.map
|