@verygoodplugins/mcp-freescout 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/implement-freescout-ticket.md +422 -0
- package/.claude/mcp-freescout.code-workspace +7 -0
- package/.claude/settings.json +60 -0
- package/.gitattributes +2 -0
- package/LICENSE +674 -0
- package/README.md +477 -0
- package/dist/freescout-api.d.ts +18 -0
- package/dist/freescout-api.d.ts.map +1 -0
- package/dist/freescout-api.js +79 -0
- package/dist/freescout-api.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +604 -0
- package/dist/index.js.map +1 -0
- package/dist/ticket-analyzer.d.ts +15 -0
- package/dist/ticket-analyzer.d.ts.map +1 -0
- package/dist/ticket-analyzer.js +257 -0
- package/dist/ticket-analyzer.js.map +1 -0
- package/dist/types.d.ts +77 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
export class TicketAnalyzer {
|
|
2
|
+
analyzeConversation(conversation) {
|
|
3
|
+
const threads = conversation._embedded?.threads || [];
|
|
4
|
+
const customer = conversation._embedded?.customer;
|
|
5
|
+
const customerMessages = threads.filter(t => t.type === 'customer');
|
|
6
|
+
const teamNotes = threads.filter(t => t.type === 'note');
|
|
7
|
+
// Extract issue description from customer messages
|
|
8
|
+
const issueDescription = this.extractIssueDescription(customerMessages);
|
|
9
|
+
// Extract code snippets and error messages
|
|
10
|
+
const codeSnippets = this.extractCodeSnippets(threads);
|
|
11
|
+
const errorMessages = this.extractErrorMessages(threads);
|
|
12
|
+
// Check if tested by team
|
|
13
|
+
const testedByTeam = this.checkTestedByTeam(teamNotes);
|
|
14
|
+
// Extract attachments
|
|
15
|
+
const attachments = this.extractAttachments(threads);
|
|
16
|
+
// Analyze if it's a bug or third-party issue
|
|
17
|
+
const analysis = this.analyzeIssueType(issueDescription, threads);
|
|
18
|
+
return {
|
|
19
|
+
ticketId: conversation.id.toString(),
|
|
20
|
+
customerName: customer ? `${customer.first_name || ''} ${customer.last_name || ''}`.trim() : 'Unknown',
|
|
21
|
+
customerEmail: customer?.email || 'unknown@example.com',
|
|
22
|
+
issueDescription,
|
|
23
|
+
hasAttachments: attachments.length > 0,
|
|
24
|
+
attachments,
|
|
25
|
+
codeSnippets,
|
|
26
|
+
errorMessages,
|
|
27
|
+
isReproducible: testedByTeam || this.checkReproducible(threads),
|
|
28
|
+
testedByTeam,
|
|
29
|
+
isBug: analysis.isBug,
|
|
30
|
+
isThirdPartyIssue: analysis.isThirdParty,
|
|
31
|
+
rootCause: analysis.rootCause,
|
|
32
|
+
suggestedSolution: analysis.suggestedSolution,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
extractIssueDescription(customerMessages) {
|
|
36
|
+
if (customerMessages.length === 0) {
|
|
37
|
+
return 'No customer messages found';
|
|
38
|
+
}
|
|
39
|
+
// Get the first customer message as the primary description
|
|
40
|
+
const firstMessage = customerMessages[0];
|
|
41
|
+
const description = this.stripHtml(firstMessage.body);
|
|
42
|
+
// Add any additional context from follow-up messages
|
|
43
|
+
const additionalContext = customerMessages
|
|
44
|
+
.slice(1)
|
|
45
|
+
.map(m => this.stripHtml(m.body))
|
|
46
|
+
.filter(text => text.length > 50) // Only include substantial messages
|
|
47
|
+
.join('\n\nAdditional context:\n');
|
|
48
|
+
return additionalContext ? `${description}\n\n${additionalContext}` : description;
|
|
49
|
+
}
|
|
50
|
+
extractCodeSnippets(threads) {
|
|
51
|
+
const snippets = [];
|
|
52
|
+
for (const thread of threads) {
|
|
53
|
+
const body = thread.body;
|
|
54
|
+
// Look for code blocks
|
|
55
|
+
const codeBlockMatches = body.matchAll(/<pre[^>]*>.*?<\/pre>/gs);
|
|
56
|
+
for (const match of codeBlockMatches) {
|
|
57
|
+
snippets.push(this.stripHtml(match[0]));
|
|
58
|
+
}
|
|
59
|
+
// Look for inline code
|
|
60
|
+
const inlineCodeMatches = body.matchAll(/<code[^>]*>.*?<\/code>/gs);
|
|
61
|
+
for (const match of inlineCodeMatches) {
|
|
62
|
+
const code = this.stripHtml(match[0]);
|
|
63
|
+
if (code.length > 20) { // Only include substantial code snippets
|
|
64
|
+
snippets.push(code);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Look for common code patterns in plain text
|
|
68
|
+
const lines = this.stripHtml(body).split('\n');
|
|
69
|
+
for (const line of lines) {
|
|
70
|
+
if (this.looksLikeCode(line)) {
|
|
71
|
+
snippets.push(line.trim());
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return [...new Set(snippets)]; // Remove duplicates
|
|
76
|
+
}
|
|
77
|
+
extractErrorMessages(threads) {
|
|
78
|
+
const errors = [];
|
|
79
|
+
const errorPatterns = [
|
|
80
|
+
/error[:\s]+(.+)/gi,
|
|
81
|
+
/exception[:\s]+(.+)/gi,
|
|
82
|
+
/warning[:\s]+(.+)/gi,
|
|
83
|
+
/fatal[:\s]+(.+)/gi,
|
|
84
|
+
/failed[:\s]+(.+)/gi,
|
|
85
|
+
/cannot\s+(.+)/gi,
|
|
86
|
+
/unable\s+to\s+(.+)/gi,
|
|
87
|
+
/undefined\s+(.+)/gi,
|
|
88
|
+
/null\s+(.+)/gi,
|
|
89
|
+
];
|
|
90
|
+
for (const thread of threads) {
|
|
91
|
+
const text = this.stripHtml(thread.body);
|
|
92
|
+
for (const pattern of errorPatterns) {
|
|
93
|
+
const matches = text.matchAll(pattern);
|
|
94
|
+
for (const match of matches) {
|
|
95
|
+
const error = match[0].trim();
|
|
96
|
+
if (error.length > 10 && error.length < 500) {
|
|
97
|
+
errors.push(error);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return [...new Set(errors)];
|
|
103
|
+
}
|
|
104
|
+
checkTestedByTeam(teamNotes) {
|
|
105
|
+
const testKeywords = [
|
|
106
|
+
'tested',
|
|
107
|
+
'reproduced',
|
|
108
|
+
'confirmed',
|
|
109
|
+
'verified',
|
|
110
|
+
'replicated',
|
|
111
|
+
'able to reproduce',
|
|
112
|
+
'can reproduce',
|
|
113
|
+
'seeing the same',
|
|
114
|
+
];
|
|
115
|
+
for (const note of teamNotes) {
|
|
116
|
+
const text = this.stripHtml(note.body).toLowerCase();
|
|
117
|
+
if (testKeywords.some(keyword => text.includes(keyword))) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
checkReproducible(threads) {
|
|
124
|
+
const reproducibleKeywords = [
|
|
125
|
+
'steps to reproduce',
|
|
126
|
+
'how to reproduce',
|
|
127
|
+
'reproduction steps',
|
|
128
|
+
'always happens',
|
|
129
|
+
'consistently',
|
|
130
|
+
'every time',
|
|
131
|
+
];
|
|
132
|
+
for (const thread of threads) {
|
|
133
|
+
const text = this.stripHtml(thread.body).toLowerCase();
|
|
134
|
+
if (reproducibleKeywords.some(keyword => text.includes(keyword))) {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
extractAttachments(threads) {
|
|
141
|
+
const attachments = [];
|
|
142
|
+
for (const thread of threads) {
|
|
143
|
+
if (thread.attachments && thread.attachments.length > 0) {
|
|
144
|
+
for (const attachment of thread.attachments) {
|
|
145
|
+
attachments.push(`${attachment.file_name} (${attachment.mime_type})`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return attachments;
|
|
150
|
+
}
|
|
151
|
+
analyzeIssueType(description, threads) {
|
|
152
|
+
const fullText = threads.map(t => this.stripHtml(t.body)).join('\n').toLowerCase();
|
|
153
|
+
// Check for third-party issues
|
|
154
|
+
const thirdPartyIndicators = [
|
|
155
|
+
'elementor',
|
|
156
|
+
'third-party plugin',
|
|
157
|
+
'another plugin',
|
|
158
|
+
'theme conflict',
|
|
159
|
+
'hosting limitation',
|
|
160
|
+
'server configuration',
|
|
161
|
+
'php version',
|
|
162
|
+
'wordpress core',
|
|
163
|
+
];
|
|
164
|
+
const isThirdParty = thirdPartyIndicators.some(indicator => fullText.includes(indicator));
|
|
165
|
+
// Check if it's a feature request vs bug
|
|
166
|
+
const featureKeywords = [
|
|
167
|
+
'would be nice',
|
|
168
|
+
'feature request',
|
|
169
|
+
'enhancement',
|
|
170
|
+
'could you add',
|
|
171
|
+
'is it possible to',
|
|
172
|
+
'would like to',
|
|
173
|
+
];
|
|
174
|
+
const isFeatureRequest = featureKeywords.some(keyword => fullText.includes(keyword));
|
|
175
|
+
// Check for configuration issues
|
|
176
|
+
const configKeywords = [
|
|
177
|
+
'settings',
|
|
178
|
+
'configuration',
|
|
179
|
+
'not configured',
|
|
180
|
+
'setup',
|
|
181
|
+
'installation',
|
|
182
|
+
];
|
|
183
|
+
const isConfigIssue = configKeywords.some(keyword => fullText.includes(keyword));
|
|
184
|
+
return {
|
|
185
|
+
isBug: !isFeatureRequest && !isConfigIssue && !isThirdParty,
|
|
186
|
+
isThirdParty,
|
|
187
|
+
rootCause: isThirdParty ? 'Third-party plugin or system limitation' :
|
|
188
|
+
isConfigIssue ? 'Configuration or setup issue' :
|
|
189
|
+
isFeatureRequest ? 'Feature request, not a bug' : undefined,
|
|
190
|
+
suggestedSolution: undefined,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
stripHtml(html) {
|
|
194
|
+
return html
|
|
195
|
+
.replace(/<[^>]*>/g, ' ') // Remove HTML tags
|
|
196
|
+
.replace(/ /g, ' ') // Replace
|
|
197
|
+
.replace(/</g, '<') // Replace <
|
|
198
|
+
.replace(/>/g, '>') // Replace >
|
|
199
|
+
.replace(/&/g, '&') // Replace &
|
|
200
|
+
.replace(/"/g, '"') // Replace "
|
|
201
|
+
.replace(/'/g, "'") // Replace '
|
|
202
|
+
.replace(/\s+/g, ' ') // Normalize whitespace
|
|
203
|
+
.trim();
|
|
204
|
+
}
|
|
205
|
+
looksLikeCode(line) {
|
|
206
|
+
const codeIndicators = [
|
|
207
|
+
/^\s*\/\//, // Comments
|
|
208
|
+
/^\s*#/, // Comments or directives
|
|
209
|
+
/^\s*\*/, // Comments
|
|
210
|
+
/function\s+\w+/, // Function declarations
|
|
211
|
+
/class\s+\w+/, // Class declarations
|
|
212
|
+
/\$\w+/, // PHP variables
|
|
213
|
+
/\w+\s*\(\s*\)/, // Function calls
|
|
214
|
+
/\w+\s*=\s*.+/, // Assignments
|
|
215
|
+
/if\s*\(/, // Control structures
|
|
216
|
+
/for\s*\(/,
|
|
217
|
+
/while\s*\(/,
|
|
218
|
+
/return\s+/,
|
|
219
|
+
/import\s+/,
|
|
220
|
+
/require\s*\(/,
|
|
221
|
+
/include\s*\(/,
|
|
222
|
+
];
|
|
223
|
+
return codeIndicators.some(pattern => pattern.test(line));
|
|
224
|
+
}
|
|
225
|
+
generateCustomerReply(analysis, fixDescription, isExplanatory = false) {
|
|
226
|
+
const customerFirstName = analysis.customerName.split(' ')[0] || 'there';
|
|
227
|
+
if (isExplanatory) {
|
|
228
|
+
return `Hi ${customerFirstName},
|
|
229
|
+
|
|
230
|
+
Thanks for reporting this. After investigating, I've found that ${analysis.rootCause || 'this is expected behavior'}.
|
|
231
|
+
|
|
232
|
+
${fixDescription || 'This is working as designed based on the current system architecture.'}
|
|
233
|
+
|
|
234
|
+
Please let me know if you have any questions or if there's anything else I can help clarify!`;
|
|
235
|
+
}
|
|
236
|
+
if (!analysis.isBug) {
|
|
237
|
+
return `Hi ${customerFirstName},
|
|
238
|
+
|
|
239
|
+
Thanks for reaching out. ${analysis.rootCause || 'After reviewing your request, this appears to be a configuration or feature request rather than a bug.'}
|
|
240
|
+
|
|
241
|
+
${fixDescription || 'I can help you with the configuration, or we can consider this as a feature request for a future update.'}
|
|
242
|
+
|
|
243
|
+
Please let me know how you'd like to proceed!`;
|
|
244
|
+
}
|
|
245
|
+
return `Hi ${customerFirstName},
|
|
246
|
+
|
|
247
|
+
Thanks for reporting this. We were able to reproduce it on our end. We've implemented a fix that ${fixDescription || 'addresses the issue you reported'}.
|
|
248
|
+
|
|
249
|
+
The fix has been submitted for review and will be included in the next plugin update. You'll receive the update through WordPress's automatic update system.
|
|
250
|
+
|
|
251
|
+
Here's what was changed:
|
|
252
|
+
- ${fixDescription || 'Fixed the reported issue'}
|
|
253
|
+
|
|
254
|
+
Please let me know if you have any questions!`;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=ticket-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ticket-analyzer.js","sourceRoot":"","sources":["../src/ticket-analyzer.ts"],"names":[],"mappings":"AAMA,MAAM,OAAO,cAAc;IACzB,mBAAmB,CAAC,YAAmC;QACrD,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,IAAI,EAAE,CAAC;QACtD,MAAM,QAAQ,GAAG,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC;QAElD,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QACpE,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;QAEzD,mDAAmD;QACnD,MAAM,gBAAgB,GAAG,IAAI,CAAC,uBAAuB,CAAC,gBAAgB,CAAC,CAAC;QAExE,2CAA2C;QAC3C,MAAM,YAAY,GAAG,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;QACvD,MAAM,aAAa,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAEzD,0BAA0B;QAC1B,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAEvD,sBAAsB;QACtB,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAErD,6CAA6C;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAElE,OAAO;YACL,QAAQ,EAAE,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE;YACpC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,UAAU,IAAI,EAAE,IAAI,QAAQ,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS;YACtG,aAAa,EAAE,QAAQ,EAAE,KAAK,IAAI,qBAAqB;YACvD,gBAAgB;YAChB,cAAc,EAAE,WAAW,CAAC,MAAM,GAAG,CAAC;YACtC,WAAW;YACX,YAAY;YACZ,aAAa;YACb,cAAc,EAAE,YAAY,IAAI,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;YAC/D,YAAY;YACZ,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,iBAAiB,EAAE,QAAQ,CAAC,YAAY;YACxC,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;SAC9C,CAAC;IACJ,CAAC;IAEO,uBAAuB,CAAC,gBAAmC;QACjE,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,OAAO,4BAA4B,CAAC;QACtC,CAAC;QAED,4DAA4D;QAC5D,MAAM,YAAY,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAEtD,qDAAqD;QACrD,MAAM,iBAAiB,GAAG,gBAAgB;aACvC,KAAK,CAAC,CAAC,CAAC;aACR,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;aAChC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,oCAAoC;aACrE,IAAI,CAAC,2BAA2B,CAAC,CAAC;QAErC,OAAO,iBAAiB,CAAC,CAAC,CAAC,GAAG,WAAW,OAAO,iBAAiB,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;IACpF,CAAC;IAEO,mBAAmB,CAAC,OAA0B;QACpD,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YAEzB,uBAAuB;YACvB,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC;YACjE,KAAK,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;gBACrC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1C,CAAC;YAED,uBAAuB;YACvB,MAAM,iBAAiB,GAAG,IAAI,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC;YACpE,KAAK,MAAM,KAAK,IAAI,iBAAiB,EAAE,CAAC;gBACtC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtC,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC,CAAC,yCAAyC;oBAC/D,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtB,CAAC;YACH,CAAC;YAED,8CAA8C;YAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC7B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC7B,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,oBAAoB;IACrD,CAAC;IAEO,oBAAoB,CAAC,OAA0B;QACrD,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,aAAa,GAAG;YACpB,mBAAmB;YACnB,uBAAuB;YACvB,qBAAqB;YACrB,mBAAmB;YACnB,oBAAoB;YACpB,iBAAiB;YACjB,sBAAsB;YACtB,oBAAoB;YACpB,eAAe;SAChB,CAAC;QAEF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAEzC,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;gBACpC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBACvC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;oBAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;oBAC9B,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;wBAC5C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACrB,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9B,CAAC;IAEO,iBAAiB,CAAC,SAA4B;QACpD,MAAM,YAAY,GAAG;YACnB,QAAQ;YACR,YAAY;YACZ,WAAW;YACX,UAAU;YACV,YAAY;YACZ,mBAAmB;YACnB,eAAe;YACf,iBAAiB;SAClB,CAAC;QAEF,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YACrD,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;gBACzD,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,iBAAiB,CAAC,OAA0B;QAClD,MAAM,oBAAoB,GAAG;YAC3B,oBAAoB;YACpB,kBAAkB;YAClB,oBAAoB;YACpB,gBAAgB;YAChB,cAAc;YACd,YAAY;SACb,CAAC;QAEF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YACvD,IAAI,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;gBACjE,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,kBAAkB,CAAC,OAA0B;QACnD,MAAM,WAAW,GAAa,EAAE,CAAC;QAEjC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxD,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;oBAC5C,WAAW,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,SAAS,KAAK,UAAU,CAAC,SAAS,GAAG,CAAC,CAAC;gBACxE,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAEO,gBAAgB,CAAC,WAAmB,EAAE,OAA0B;QAMtE,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QAEnF,+BAA+B;QAC/B,MAAM,oBAAoB,GAAG;YAC3B,WAAW;YACX,oBAAoB;YACpB,gBAAgB;YAChB,gBAAgB;YAChB,oBAAoB;YACpB,sBAAsB;YACtB,aAAa;YACb,gBAAgB;SACjB,CAAC;QAEF,MAAM,YAAY,GAAG,oBAAoB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CACzD,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAC7B,CAAC;QAEF,yCAAyC;QACzC,MAAM,eAAe,GAAG;YACtB,eAAe;YACf,iBAAiB;YACjB,aAAa;YACb,eAAe;YACf,mBAAmB;YACnB,eAAe;SAChB,CAAC;QAEF,MAAM,gBAAgB,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CACtD,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAC3B,CAAC;QAEF,iCAAiC;QACjC,MAAM,cAAc,GAAG;YACrB,UAAU;YACV,eAAe;YACf,gBAAgB;YAChB,OAAO;YACP,cAAc;SACf,CAAC;QAEF,MAAM,aAAa,GAAG,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAClD,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAC3B,CAAC;QAEF,OAAO;YACL,KAAK,EAAE,CAAC,gBAAgB,IAAI,CAAC,aAAa,IAAI,CAAC,YAAY;YAC3D,YAAY;YACZ,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC,yCAAyC,CAAC,CAAC;gBAC1D,aAAa,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC;oBAChD,gBAAgB,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,SAAS;YACtE,iBAAiB,EAAE,SAAS;SAC7B,CAAC;IACJ,CAAC;IAEO,SAAS,CAAC,IAAY;QAC5B,OAAO,IAAI;aACR,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,mBAAmB;aAC5C,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAG,iBAAiB;aAC3C,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAK,eAAe;aACzC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAK,eAAe;aACzC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAI,gBAAgB;aAC1C,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAG,iBAAiB;aAC3C,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAI,gBAAgB;aAC1C,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAM,uBAAuB;aACjD,IAAI,EAAE,CAAC;IACZ,CAAC;IAEO,aAAa,CAAC,IAAY;QAChC,MAAM,cAAc,GAAG;YACrB,UAAU,EAAY,WAAW;YACjC,OAAO,EAAe,yBAAyB;YAC/C,QAAQ,EAAc,WAAW;YACjC,gBAAgB,EAAM,wBAAwB;YAC9C,aAAa,EAAS,qBAAqB;YAC3C,OAAO,EAAe,gBAAgB;YACtC,eAAe,EAAO,iBAAiB;YACvC,cAAc,EAAQ,cAAc;YACpC,SAAS,EAAa,qBAAqB;YAC3C,UAAU;YACV,YAAY;YACZ,WAAW;YACX,WAAW;YACX,cAAc;YACd,cAAc;SACf,CAAC;QAEF,OAAO,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,qBAAqB,CACnB,QAAwB,EACxB,cAAuB,EACvB,gBAAyB,KAAK;QAE9B,MAAM,iBAAiB,GAAG,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC;QAEzE,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO,MAAM,iBAAiB;;kEAE8B,QAAQ,CAAC,SAAS,IAAI,2BAA2B;;EAEjH,cAAc,IAAI,uEAAuE;;6FAEE,CAAC;QAC1F,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACpB,OAAO,MAAM,iBAAiB;;2BAET,QAAQ,CAAC,SAAS,IAAI,wGAAwG;;EAEvJ,cAAc,IAAI,0GAA0G;;8CAEhF,CAAC;QAC3C,CAAC;QAED,OAAO,MAAM,iBAAiB;;mGAEiE,cAAc,IAAI,kCAAkC;;;;;IAKnJ,cAAc,IAAI,0BAA0B;;8CAEF,CAAC;IAC7C,CAAC;CACF"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
export interface FreeScoutThread {
|
|
2
|
+
id: number;
|
|
3
|
+
type: 'customer' | 'message' | 'note';
|
|
4
|
+
body: string;
|
|
5
|
+
created_by_customer: boolean;
|
|
6
|
+
created_at: string;
|
|
7
|
+
attachments?: Array<{
|
|
8
|
+
id: number;
|
|
9
|
+
file_name: string;
|
|
10
|
+
mime_type: string;
|
|
11
|
+
size: number;
|
|
12
|
+
url?: string;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
15
|
+
export interface FreeScoutCustomer {
|
|
16
|
+
id: number;
|
|
17
|
+
email: string;
|
|
18
|
+
first_name?: string;
|
|
19
|
+
last_name?: string;
|
|
20
|
+
company?: string;
|
|
21
|
+
phone?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface FreeScoutConversation {
|
|
24
|
+
id: number;
|
|
25
|
+
number: number;
|
|
26
|
+
subject: string;
|
|
27
|
+
status: 'active' | 'pending' | 'closed' | 'spam';
|
|
28
|
+
user_id: number | null;
|
|
29
|
+
customer_id: number;
|
|
30
|
+
mailbox_id: number;
|
|
31
|
+
created_at: string;
|
|
32
|
+
updated_at: string;
|
|
33
|
+
_embedded?: {
|
|
34
|
+
threads?: FreeScoutThread[];
|
|
35
|
+
customer?: FreeScoutCustomer;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export interface FreeScoutApiResponse<T> {
|
|
39
|
+
_embedded?: {
|
|
40
|
+
conversations?: T[];
|
|
41
|
+
threads?: FreeScoutThread[];
|
|
42
|
+
customer?: FreeScoutCustomer;
|
|
43
|
+
};
|
|
44
|
+
data?: T;
|
|
45
|
+
page?: {
|
|
46
|
+
size: number;
|
|
47
|
+
total_elements: number;
|
|
48
|
+
total_pages: number;
|
|
49
|
+
number: number;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export interface TicketAnalysis {
|
|
53
|
+
ticketId: string;
|
|
54
|
+
customerName: string;
|
|
55
|
+
customerEmail: string;
|
|
56
|
+
issueDescription: string;
|
|
57
|
+
hasAttachments: boolean;
|
|
58
|
+
attachments: string[];
|
|
59
|
+
codeSnippets: string[];
|
|
60
|
+
errorMessages: string[];
|
|
61
|
+
isReproducible: boolean;
|
|
62
|
+
testedByTeam: boolean;
|
|
63
|
+
suggestedSolution?: string;
|
|
64
|
+
isBug: boolean;
|
|
65
|
+
isThirdPartyIssue: boolean;
|
|
66
|
+
rootCause?: string;
|
|
67
|
+
}
|
|
68
|
+
export interface ImplementationPlan {
|
|
69
|
+
issue: string;
|
|
70
|
+
rootCause: string;
|
|
71
|
+
solution: string;
|
|
72
|
+
filesToModify: string[];
|
|
73
|
+
alternativeApproaches: string[];
|
|
74
|
+
hasBreakingChanges: boolean;
|
|
75
|
+
requiresDocumentationUpdate: boolean;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB,EAAE,OAAO,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,KAAK,CAAC;QAClB,EAAE,EAAE,MAAM,CAAC;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;IACjD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE;QACV,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;QAC5B,QAAQ,CAAC,EAAE,iBAAiB,CAAC;KAC9B,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE;QACV,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC;QACpB,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;QAC5B,QAAQ,CAAC,EAAE,iBAAiB,CAAC;KAC9B,CAAC;IACF,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,IAAI,CAAC,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,2BAA2B,EAAE,OAAO,CAAC;CACtC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@verygoodplugins/mcp-freescout",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for FreeScout ticket management and workflow automation",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"mcp-freescout": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsx watch src/index.ts",
|
|
13
|
+
"start": "node dist/index.js",
|
|
14
|
+
"test": "jest",
|
|
15
|
+
"lint": "eslint src/**/*.ts",
|
|
16
|
+
"format": "prettier --write src/**/*.ts",
|
|
17
|
+
"prepublishOnly": "npm run build"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mcp",
|
|
21
|
+
"mcp-server",
|
|
22
|
+
"modelcontextprotocol",
|
|
23
|
+
"freescout",
|
|
24
|
+
"helpdesk",
|
|
25
|
+
"ticket-management",
|
|
26
|
+
"workflow-automation"
|
|
27
|
+
],
|
|
28
|
+
"author": "Very Good Plugins",
|
|
29
|
+
"license": "GPL-3.0",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/verygoodplugins/mcp-freescout.git"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/verygoodplugins/mcp-freescout#readme",
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/verygoodplugins/mcp-freescout/issues"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@modelcontextprotocol/sdk": "^0.5.0",
|
|
40
|
+
"node-fetch": "^3.3.2",
|
|
41
|
+
"zod": "^3.22.4",
|
|
42
|
+
"dotenv": "^16.3.1"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^20.10.0",
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "^6.13.0",
|
|
47
|
+
"@typescript-eslint/parser": "^6.13.0",
|
|
48
|
+
"eslint": "^8.54.0",
|
|
49
|
+
"jest": "^29.7.0",
|
|
50
|
+
"prettier": "^3.1.0",
|
|
51
|
+
"tsx": "^4.6.0",
|
|
52
|
+
"typescript": "^5.3.0"
|
|
53
|
+
}
|
|
54
|
+
}
|