@saccolabs/tars 1.7.0 → 1.7.2
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/README.md +10 -7
- package/dist/channels/channel-manager.d.ts +35 -0
- package/dist/channels/channel-manager.js +94 -0
- package/dist/channels/channel-manager.js.map +1 -0
- package/dist/channels/discord/discord-channel.d.ts +41 -0
- package/dist/channels/discord/discord-channel.js +203 -0
- package/dist/channels/discord/discord-channel.js.map +1 -0
- package/dist/channels/discord/message-formatter.d.ts +95 -0
- package/dist/channels/discord/message-formatter.js +482 -0
- package/dist/channels/discord/message-formatter.js.map +1 -0
- package/dist/channels/types.d.ts +36 -0
- package/dist/channels/types.js +2 -0
- package/dist/channels/types.js.map +1 -0
- package/dist/cli/commands/setup.js +92 -136
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/start.d.ts +4 -1
- package/dist/cli/commands/start.js +47 -37
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/status.js +19 -0
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/config/config.d.ts +11 -2
- package/dist/config/config.js +34 -13
- package/dist/config/config.js.map +1 -1
- package/dist/scripts/debug-cli.js +1 -1
- package/dist/scripts/debug-cli.js.map +1 -1
- package/dist/supervisor/cron-service.d.ts +3 -3
- package/dist/supervisor/cron-service.js +4 -4
- package/dist/supervisor/cron-service.js.map +1 -1
- package/dist/supervisor/gemini-engine.d.ts +4 -4
- package/dist/supervisor/gemini-engine.js +9 -9
- package/dist/supervisor/gemini-engine.js.map +1 -1
- package/dist/supervisor/heartbeat-service.js +1 -1
- package/dist/supervisor/heartbeat-service.js.map +1 -1
- package/dist/supervisor/main.js +59 -60
- package/dist/supervisor/main.js.map +1 -1
- package/dist/tools/send-discord-message.d.ts +9 -6
- package/dist/tools/send-discord-message.js +14 -21
- package/dist/tools/send-discord-message.js.map +1 -1
- package/dist/tools/send-notification.d.ts +15 -0
- package/dist/tools/send-notification.js +51 -0
- package/dist/tools/send-notification.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/package.json +12 -2
- package/src/prompts/system.md +4 -0
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discord Message Formatter
|
|
3
|
+
*
|
|
4
|
+
* Transforms Gemini CLI output (GitHub Flavored Markdown)
|
|
5
|
+
* into Discord-compatible formatting.
|
|
6
|
+
*
|
|
7
|
+
* Discord supports:
|
|
8
|
+
* - Bold: **text**
|
|
9
|
+
* - Italic: *text* or _text_
|
|
10
|
+
* - Underline: __text__
|
|
11
|
+
* - Strikethrough: ~~text~~
|
|
12
|
+
* - Code inline: `text`
|
|
13
|
+
* - Code block: ```lang\ncode\n```
|
|
14
|
+
* - Blockquotes: > text
|
|
15
|
+
* - Headers: # (only #, ##, ###)
|
|
16
|
+
*
|
|
17
|
+
* Discord does NOT support:
|
|
18
|
+
* - Markdown tables (we instruct the LLM to avoid these)
|
|
19
|
+
* - #### or deeper headers
|
|
20
|
+
* - Small text (-#)
|
|
21
|
+
*/
|
|
22
|
+
export class MessageFormatter {
|
|
23
|
+
static MAX_MESSAGE_LENGTH = 1990;
|
|
24
|
+
/**
|
|
25
|
+
* Format text for Discord
|
|
26
|
+
*/
|
|
27
|
+
static format(text) {
|
|
28
|
+
if (!text)
|
|
29
|
+
return text;
|
|
30
|
+
let formatted = text;
|
|
31
|
+
// Step 1: Fix broken asterisks FIRST (creates patterns that need spacing)
|
|
32
|
+
formatted = this.fixAsterisks(formatted);
|
|
33
|
+
// Step 2: CRITICAL - Fix spacing issues (LLM often merges words)
|
|
34
|
+
formatted = this.fixSpacing(formatted);
|
|
35
|
+
// Step 3: Normalize bullets (* item -> • item)
|
|
36
|
+
formatted = this.normalizeBullets(formatted);
|
|
37
|
+
// Step 4: Normalize headers (#### -> ### or bold)
|
|
38
|
+
formatted = this.normalizeHeaders(formatted);
|
|
39
|
+
// Step 5: Fix blockquotes (ensure they render properly)
|
|
40
|
+
formatted = this.fixBlockquotes(formatted);
|
|
41
|
+
// Step 6: Format JSON blocks in code blocks
|
|
42
|
+
formatted = this.formatJsonBlocks(formatted);
|
|
43
|
+
// Step 7: Strip any remaining tables (fallback if LLM still generates them)
|
|
44
|
+
formatted = this.stripTables(formatted);
|
|
45
|
+
// Step 8: Fix small text markers (-#) that Discord doesn't support
|
|
46
|
+
formatted = this.fixSmallText(formatted);
|
|
47
|
+
// Step 9: Clean up excessive whitespace
|
|
48
|
+
formatted = formatted.replace(/\n{3,}/g, '\n\n');
|
|
49
|
+
return formatted.trim();
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Fix critical spacing issues from LLM output
|
|
53
|
+
* These are the most common formatting bugs that break Discord rendering
|
|
54
|
+
*/
|
|
55
|
+
static fixSpacing(text) {
|
|
56
|
+
let result = text;
|
|
57
|
+
// 1. Ensure space AFTER closing bold before next word
|
|
58
|
+
result = result.replace(/\*\*([^*]+)\*\*(?=[a-zA-Z0-9])/g, '**$1** ');
|
|
59
|
+
// 2. Ensure space BEFORE opening bold after a word
|
|
60
|
+
result = result.replace(/([a-zA-Z0-9])\*\*([^*]+)\*\*/g, '$1 **$2**');
|
|
61
|
+
// 3. Ensure space after colon before bold
|
|
62
|
+
result = result.replace(/([^*]):\*\*/g, '$1: **');
|
|
63
|
+
// 4. Ensure space around middle dots
|
|
64
|
+
result = result.replace(/([a-zA-Z0-9])·([a-zA-Z0-9])/g, '$1 · $2');
|
|
65
|
+
// 5. Ensure DOUBLE NEWLINE before section emojis
|
|
66
|
+
// This ensures headers like "📊 Signal Check" always start on a new paragraph
|
|
67
|
+
// REMOVED: ✅, ❌, ⚠️, 💡, 🛡️ (often used in lists/inline)
|
|
68
|
+
// KEPT: 🔍, 📊, 🧠, 📈, ⚖️, 🎯, 📋, 🔄, 📅 (Major section headers)
|
|
69
|
+
const sectionEmojis = '🔍|📊|🧠|📈|⚖️|🎯|📋|🔄|📅';
|
|
70
|
+
// Look for [not newline][spaces?][likely emoji] -> replace with [char]\n\n[emoji]
|
|
71
|
+
result = result.replace(new RegExp(`([^\\n])\\s*(${sectionEmojis})`, 'g'), '$1\n\n$2');
|
|
72
|
+
// 6. Ensure space after emojis before bold
|
|
73
|
+
result = result.replace(new RegExp(`(${sectionEmojis})\\*\\*`, 'g'), '$1 **');
|
|
74
|
+
// 7. Fix "set for**time**" pattern
|
|
75
|
+
result = result.replace(/for\*\*/g, 'for **');
|
|
76
|
+
// 8. Fix bullet points that run together
|
|
77
|
+
// "• Item1• Item2" -> "• Item1\n• Item2"
|
|
78
|
+
// Also ensure bullets appearing in middle of text get a newline
|
|
79
|
+
result = result.replace(/([^\n])\s*• /g, '$1\n• ');
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Fix broken asterisks patterns
|
|
84
|
+
* Only fixes obviously broken patterns, avoids aggressive matching
|
|
85
|
+
*/
|
|
86
|
+
static fixAsterisks(text) {
|
|
87
|
+
let result = text;
|
|
88
|
+
// Fix 4+ asterisks down to 2 (****text**** -> **text**)
|
|
89
|
+
result = result.replace(/\*{4,}(.+?)\*{4,}/g, '**$1**');
|
|
90
|
+
// Fix trailing-only ** at end of line (text** -> **text**)
|
|
91
|
+
// Only applies when line starts with a letter/number (no leading **)
|
|
92
|
+
// AND has exactly trailing ** (indicative of broken bold)
|
|
93
|
+
result = result.replace(/^([^*\n][^*]*)(\*\*)$/gm, (match, content, trail) => {
|
|
94
|
+
// Check if content already has opening ** - skip if so
|
|
95
|
+
if (content.includes('**'))
|
|
96
|
+
return match;
|
|
97
|
+
return `**${content.trim()}**`;
|
|
98
|
+
});
|
|
99
|
+
// Fix: Close unclosed bold tags at start of line (**Text -> **Text**)
|
|
100
|
+
result = result.replace(/^(\*\*[^*]+?)(?<!\*\*)(\s*[:.,!?-]?)$/gm, (match, content, punct) => {
|
|
101
|
+
// If already closed, don't touch
|
|
102
|
+
if (content.trim().endsWith('**'))
|
|
103
|
+
return match;
|
|
104
|
+
return `${content.trim()}${punct}**`;
|
|
105
|
+
});
|
|
106
|
+
// Also handle cases specifically ending with punctuation on the line
|
|
107
|
+
result = result.replace(/^(\*\*[^*]+)(?=\s*([:.,!?-]))/gm, (match, content, punct) => {
|
|
108
|
+
if (match.endsWith('**'))
|
|
109
|
+
return match;
|
|
110
|
+
// Regex lookahead logic is tricky here, simplifiying:
|
|
111
|
+
// The previous regex fixes the EOL case.
|
|
112
|
+
// This regex handles mid-line punctuation if we want to support it?
|
|
113
|
+
// Actually, the previous regex handles `punctuation at the end of the line OR content`.
|
|
114
|
+
// If we have `**Header: content`, the first regex won't catch it unless it matches newline?
|
|
115
|
+
// Let's rely on the first regex which is robust for EOL.
|
|
116
|
+
// For mid-line, if there's no closing `**`, it's hard to guess where it ends.
|
|
117
|
+
// So we'll skip this second aggressive block to avoid regressions.
|
|
118
|
+
return match;
|
|
119
|
+
});
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Normalize bullet points for Discord
|
|
124
|
+
*/
|
|
125
|
+
static normalizeBullets(text) {
|
|
126
|
+
return (text
|
|
127
|
+
// Convert "* item" to "• item" (but not inside code blocks)
|
|
128
|
+
.replace(/^(\s*)\* /gm, '$1• ')
|
|
129
|
+
// Convert "- item" that's not a separator line or subtext
|
|
130
|
+
.replace(/^(\s*)- (?![-#]+)/gm, '$1• '));
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Normalize markdown headers to Discord-friendly format
|
|
134
|
+
* Discord supports #, ##, ### natively now.
|
|
135
|
+
*/
|
|
136
|
+
static normalizeHeaders(text) {
|
|
137
|
+
return (text
|
|
138
|
+
// Ensure space after hashes
|
|
139
|
+
.replace(/^(#{1,3})(?=[^#\s])/gm, '$1 ')
|
|
140
|
+
// Convert #### and deeper to bold
|
|
141
|
+
.replace(/^#{4,}\s+(.+)$/gm, '**$1**'));
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Fix blockquote formatting
|
|
145
|
+
*/
|
|
146
|
+
static fixBlockquotes(text) {
|
|
147
|
+
const lines = text.split('\n');
|
|
148
|
+
const result = [];
|
|
149
|
+
let inBlockquote = false;
|
|
150
|
+
for (const line of lines) {
|
|
151
|
+
if (line.startsWith('> ')) {
|
|
152
|
+
inBlockquote = true;
|
|
153
|
+
result.push(line);
|
|
154
|
+
}
|
|
155
|
+
else if (line.startsWith('>') && line.length === 1) {
|
|
156
|
+
// Empty blockquote line - skip it
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
else if (inBlockquote && line.trim() === '') {
|
|
160
|
+
inBlockquote = false;
|
|
161
|
+
result.push(line);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
inBlockquote = false;
|
|
165
|
+
result.push(line);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return result.join('\n');
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Detect and wrap JSON-like content in code blocks
|
|
172
|
+
*/
|
|
173
|
+
static formatJsonBlocks(text) {
|
|
174
|
+
if (text.includes('```json') || text.includes('```\n{')) {
|
|
175
|
+
return text;
|
|
176
|
+
}
|
|
177
|
+
const jsonPattern = /(?:^|\n)([\[{][\s\S]*?[\]}])(?=\n|$)/g;
|
|
178
|
+
return text.replace(jsonPattern, (match, json) => {
|
|
179
|
+
try {
|
|
180
|
+
const trimmed = json.trim();
|
|
181
|
+
if ((trimmed.startsWith('{') || trimmed.startsWith('[')) && trimmed.length > 20) {
|
|
182
|
+
const parsed = JSON.parse(trimmed);
|
|
183
|
+
const pretty = JSON.stringify(parsed, null, 2);
|
|
184
|
+
return '\n```json\n' + pretty + '\n```';
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// Not valid JSON
|
|
189
|
+
}
|
|
190
|
+
return match;
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Strip markdown tables - they don't render well on mobile Discord
|
|
195
|
+
* This is a fallback; the LLM should be instructed not to generate tables
|
|
196
|
+
*/
|
|
197
|
+
static stripTables(text) {
|
|
198
|
+
// Detect table patterns and convert to simple list
|
|
199
|
+
const lines = text.split('\n');
|
|
200
|
+
const result = [];
|
|
201
|
+
let inTable = false;
|
|
202
|
+
let tableRows = [];
|
|
203
|
+
for (const line of lines) {
|
|
204
|
+
// Check if this is a table separator line (|---|---|)
|
|
205
|
+
if (line.match(/^\|?\s*[-:]+[-:\s|]*\|?\s*$/)) {
|
|
206
|
+
inTable = true;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
// Check if this is a table row
|
|
210
|
+
if (line.includes('|') && (line.startsWith('|') || line.match(/\w+\s*\|/))) {
|
|
211
|
+
inTable = true;
|
|
212
|
+
const cells = line
|
|
213
|
+
.split('|')
|
|
214
|
+
.map((c) => c.trim())
|
|
215
|
+
.filter((c) => c.length > 0);
|
|
216
|
+
if (cells.length > 0) {
|
|
217
|
+
tableRows.push(cells);
|
|
218
|
+
}
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
// End of table - convert to list
|
|
222
|
+
if (inTable && tableRows.length > 0) {
|
|
223
|
+
// First row is usually header
|
|
224
|
+
const header = tableRows[0];
|
|
225
|
+
const dataRows = tableRows.slice(1);
|
|
226
|
+
for (const row of dataRows) {
|
|
227
|
+
const parts = [];
|
|
228
|
+
for (let i = 0; i < row.length && i < header.length; i++) {
|
|
229
|
+
if (i === 0) {
|
|
230
|
+
parts.push(`**${row[i]}**`);
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
parts.push(row[i]);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
result.push(`• ${parts.join(' · ')}`);
|
|
237
|
+
}
|
|
238
|
+
tableRows = [];
|
|
239
|
+
inTable = false;
|
|
240
|
+
}
|
|
241
|
+
result.push(line);
|
|
242
|
+
}
|
|
243
|
+
// Handle any remaining table at end of text
|
|
244
|
+
if (tableRows.length > 0) {
|
|
245
|
+
const header = tableRows[0];
|
|
246
|
+
const dataRows = tableRows.slice(1);
|
|
247
|
+
for (const row of dataRows) {
|
|
248
|
+
const parts = [];
|
|
249
|
+
for (let i = 0; i < row.length && i < header.length; i++) {
|
|
250
|
+
if (i === 0) {
|
|
251
|
+
parts.push(`**${row[i]}**`);
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
parts.push(row[i]);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
result.push(`• ${parts.join(' · ')}`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return result.join('\n');
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Fix small text markers (-#) that Discord doesn't support
|
|
264
|
+
*/
|
|
265
|
+
static fixSmallText(text) {
|
|
266
|
+
// Convert -# prefix to regular text or remove it
|
|
267
|
+
return text.replace(/^-#\s*/gm, '');
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Split long messages into Discord-safe chunks intelligently
|
|
271
|
+
* Respects semantic boundaries: headers, code blocks, paragraphs
|
|
272
|
+
*/
|
|
273
|
+
static split(text, maxLength = this.MAX_MESSAGE_LENGTH) {
|
|
274
|
+
if (!text)
|
|
275
|
+
return [];
|
|
276
|
+
if (text.length <= maxLength)
|
|
277
|
+
return [text];
|
|
278
|
+
const chunks = [];
|
|
279
|
+
let remaining = text;
|
|
280
|
+
while (remaining.length > 0) {
|
|
281
|
+
if (remaining.length <= maxLength) {
|
|
282
|
+
chunks.push(remaining);
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
// Find best split point, leaving buffer for markdown closures
|
|
286
|
+
let splitIndex = this.findSemanticSplitPoint(remaining, maxLength - 20);
|
|
287
|
+
// If the semantic split failed to find a good spot (e.g., returned the max length)
|
|
288
|
+
// and we are trying to split a continuous block of text (like 3000 'a's),
|
|
289
|
+
// just hard cut it. Our findSemanticSplitPoint ensures it won't be > maxLength - 20.
|
|
290
|
+
let chunk = remaining.substring(0, splitIndex);
|
|
291
|
+
// Check if we are inside a code block by counting backticks
|
|
292
|
+
let inCodeBlock = false;
|
|
293
|
+
let currentLang = '';
|
|
294
|
+
const tickRegex = /```([a-zA-Z0-9]*)/g;
|
|
295
|
+
let match;
|
|
296
|
+
while ((match = tickRegex.exec(chunk)) !== null) {
|
|
297
|
+
if (!inCodeBlock) {
|
|
298
|
+
inCodeBlock = true;
|
|
299
|
+
currentLang = match[1] || '';
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
inCodeBlock = false;
|
|
303
|
+
currentLang = '';
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
if (inCodeBlock) {
|
|
307
|
+
chunks.push(chunk.trimEnd() + '\n```');
|
|
308
|
+
remaining =
|
|
309
|
+
'```' + currentLang + '\n' + remaining.substring(splitIndex).trimStart();
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
chunks.push(chunk.trimEnd());
|
|
313
|
+
remaining = remaining.substring(splitIndex).trimStart();
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return chunks;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Find the optimal split point respecting semantic boundaries
|
|
320
|
+
* Priority: Header > Code block boundary > Paragraph > Sentence > Hard cut
|
|
321
|
+
*/
|
|
322
|
+
static findSemanticSplitPoint(text, maxLength) {
|
|
323
|
+
// 1. Try to split BEFORE a markdown header (## or ###)
|
|
324
|
+
const headerPattern = /\n(##+ )/g;
|
|
325
|
+
let match;
|
|
326
|
+
let lastHeaderBefore = -1;
|
|
327
|
+
while ((match = headerPattern.exec(text)) !== null) {
|
|
328
|
+
const pos = match.index;
|
|
329
|
+
if (pos > maxLength)
|
|
330
|
+
break;
|
|
331
|
+
if (pos > maxLength / 2) {
|
|
332
|
+
lastHeaderBefore = pos;
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
if (lastHeaderBefore > maxLength / 2) {
|
|
337
|
+
return lastHeaderBefore;
|
|
338
|
+
}
|
|
339
|
+
// 2. Try to split AFTER a complete code block
|
|
340
|
+
const codeBlockEndPattern = /```\n/g;
|
|
341
|
+
let lastCodeEnd = -1;
|
|
342
|
+
while ((match = codeBlockEndPattern.exec(text)) !== null) {
|
|
343
|
+
const pos = match.index + match[0].length;
|
|
344
|
+
if (pos > maxLength)
|
|
345
|
+
break;
|
|
346
|
+
if (pos > maxLength / 2) {
|
|
347
|
+
lastCodeEnd = pos;
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if (lastCodeEnd > maxLength / 2) {
|
|
352
|
+
return lastCodeEnd;
|
|
353
|
+
}
|
|
354
|
+
// 3. Try to split at paragraph boundary (double newline)
|
|
355
|
+
let splitIndex = text.lastIndexOf('\n\n', maxLength);
|
|
356
|
+
if (splitIndex > maxLength / 2) {
|
|
357
|
+
return splitIndex + 2;
|
|
358
|
+
}
|
|
359
|
+
// 4. Try to split at single newline
|
|
360
|
+
splitIndex = text.lastIndexOf('\n', maxLength);
|
|
361
|
+
if (splitIndex > maxLength / 3) {
|
|
362
|
+
return splitIndex + 1;
|
|
363
|
+
}
|
|
364
|
+
// 5. Try to split at sentence boundary (. followed by space)
|
|
365
|
+
splitIndex = text.lastIndexOf('. ', maxLength);
|
|
366
|
+
if (splitIndex > maxLength / 3) {
|
|
367
|
+
return splitIndex + 2;
|
|
368
|
+
}
|
|
369
|
+
// 6. Try to split at space
|
|
370
|
+
splitIndex = text.lastIndexOf(' ', maxLength);
|
|
371
|
+
if (splitIndex > -1) {
|
|
372
|
+
// If a space was found at all, use it as a fallback
|
|
373
|
+
return splitIndex + 1;
|
|
374
|
+
}
|
|
375
|
+
// 7. Last resort: hard cut at maxLength
|
|
376
|
+
return Math.min(maxLength, text.length);
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Format and split in one operation
|
|
380
|
+
* Ensures summary line (first line with actionable emoji) stays at the top
|
|
381
|
+
*/
|
|
382
|
+
static formatAndSplit(text) {
|
|
383
|
+
const formatted = this.format(text);
|
|
384
|
+
// If text fits in one message, no special handling needed
|
|
385
|
+
if (formatted.length <= this.MAX_MESSAGE_LENGTH) {
|
|
386
|
+
return [formatted];
|
|
387
|
+
}
|
|
388
|
+
// Extract summary line (first line starting with key emoji)
|
|
389
|
+
const { summary, rest } = this.extractSummaryLine(formatted);
|
|
390
|
+
// Split the remaining content
|
|
391
|
+
const chunks = this.split(rest);
|
|
392
|
+
// If we found a summary, prepend it to the first chunk
|
|
393
|
+
if (summary && chunks.length > 0) {
|
|
394
|
+
// Check if adding summary would exceed limit
|
|
395
|
+
const firstChunkWithSummary = `${summary}\n\n${chunks[0]}`;
|
|
396
|
+
if (firstChunkWithSummary.length <= this.MAX_MESSAGE_LENGTH) {
|
|
397
|
+
chunks[0] = firstChunkWithSummary;
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
// Summary + first chunk too long, send summary as its own message
|
|
401
|
+
chunks.unshift(summary);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
return chunks;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Extract the summary line from the beginning of formatted text
|
|
408
|
+
* Summary lines start with key actionable emojis: 🎯 ⚖️ 📊 ⚠️ ✅ ❓
|
|
409
|
+
*/
|
|
410
|
+
static extractSummaryLine(text) {
|
|
411
|
+
const lines = text.split('\n');
|
|
412
|
+
const summaryEmojis = ['🎯', '⚖️', '📊', '⚠️', '✅', '❓', '❌'];
|
|
413
|
+
// Check first few lines for summary pattern
|
|
414
|
+
for (let i = 0; i < Math.min(3, lines.length); i++) {
|
|
415
|
+
const line = lines[i].trim();
|
|
416
|
+
// Check if line starts with a summary emoji
|
|
417
|
+
if (summaryEmojis.some((emoji) => line.startsWith(emoji))) {
|
|
418
|
+
// Found summary line - extract it and return rest
|
|
419
|
+
const summary = line;
|
|
420
|
+
const restLines = [...lines.slice(0, i), ...lines.slice(i + 1)];
|
|
421
|
+
const rest = restLines.join('\n').trim();
|
|
422
|
+
return { summary, rest };
|
|
423
|
+
}
|
|
424
|
+
// Also check for bold emoji pattern: **🎯 or similar
|
|
425
|
+
if (line.match(/^\*\*[🎯⚖️📊⚠️✅❓❌]/)) {
|
|
426
|
+
const summary = line;
|
|
427
|
+
const restLines = [...lines.slice(0, i), ...lines.slice(i + 1)];
|
|
428
|
+
const rest = restLines.join('\n').trim();
|
|
429
|
+
return { summary, rest };
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
return { summary: null, rest: text };
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Parse markdown into sections based on headers (##)
|
|
436
|
+
*/
|
|
437
|
+
static parseSections(text) {
|
|
438
|
+
const sections = [];
|
|
439
|
+
const lines = text.split('\n');
|
|
440
|
+
let currentTitle = 'Summary';
|
|
441
|
+
let currentContent = [];
|
|
442
|
+
for (const line of lines) {
|
|
443
|
+
const headerMatch = line.match(/^##\s+(.+)$/);
|
|
444
|
+
if (headerMatch) {
|
|
445
|
+
if (currentContent.length > 0 || currentTitle !== 'Summary') {
|
|
446
|
+
sections.push({
|
|
447
|
+
title: currentTitle,
|
|
448
|
+
content: currentContent.join('\n').trim()
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
currentTitle = headerMatch[1];
|
|
452
|
+
currentContent = [];
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
currentContent.push(line);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
if (currentContent.length > 0 || sections.length === 0) {
|
|
459
|
+
sections.push({
|
|
460
|
+
title: currentTitle,
|
|
461
|
+
content: currentContent.join('\n').trim()
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
return sections;
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Format a data object as a clean Discord-friendly list
|
|
468
|
+
*/
|
|
469
|
+
static formatDataAsEmbed(title, data) {
|
|
470
|
+
const lines = [`**${title}**`];
|
|
471
|
+
for (const [key, value] of Object.entries(data)) {
|
|
472
|
+
if (typeof value === 'object') {
|
|
473
|
+
lines.push(`• **${key}:** \`${JSON.stringify(value)}\``);
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
lines.push(`• **${key}:** ${value}`);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
return lines.join('\n');
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
//# sourceMappingURL=message-formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-formatter.js","sourceRoot":"","sources":["../../../src/channels/discord/message-formatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { AttachmentContext } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Common message structure across all channels
|
|
4
|
+
*/
|
|
5
|
+
export interface ChannelMessage {
|
|
6
|
+
content: string;
|
|
7
|
+
senderId: string;
|
|
8
|
+
senderName: string;
|
|
9
|
+
channelId: string;
|
|
10
|
+
attachments?: AttachmentContext[];
|
|
11
|
+
metadata?: Record<string, any>;
|
|
12
|
+
reply: (content: string, attachments?: string[]) => Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Interface for communication platforms (Discord, WhatsApp, etc.)
|
|
16
|
+
*/
|
|
17
|
+
export interface CommunicationChannel {
|
|
18
|
+
readonly id: string;
|
|
19
|
+
readonly isEnabled: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Initialize and connect to the platform
|
|
22
|
+
*/
|
|
23
|
+
start(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Disconnect from the platform
|
|
26
|
+
*/
|
|
27
|
+
stop(): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Send a proactive notification to the user
|
|
30
|
+
*/
|
|
31
|
+
notify(content: string, attachments?: string[]): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Register a callback for incoming messages
|
|
34
|
+
*/
|
|
35
|
+
onMessage(handler: (message: ChannelMessage) => Promise<void>): void;
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/channels/types.ts"],"names":[],"mappings":""}
|