viewgate-mcp 1.0.47 → 1.0.48
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/index.js +49 -57
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -68,7 +68,6 @@ function createMcpServer(apiKey, personalKey) {
|
|
|
68
68
|
case "mark_ui_component_generated":
|
|
69
69
|
return "ui_components";
|
|
70
70
|
case "get_annotations":
|
|
71
|
-
case "mark_annotation_ready":
|
|
72
71
|
case "mark_annotations_as_live":
|
|
73
72
|
return "annotations";
|
|
74
73
|
case "get_ui_improvements":
|
|
@@ -124,10 +123,13 @@ function createMcpServer(apiKey, personalKey) {
|
|
|
124
123
|
break;
|
|
125
124
|
default:
|
|
126
125
|
if (guard.flow === "idle") {
|
|
127
|
-
throw new Error(
|
|
126
|
+
throw new Error(`TOOL_CALL_BLOCKED: tool '${toolName}' not allowed in idle. Please start a workflow with 'get_annotations', 'get_ui_components', or 'get_ui_improvements'.`);
|
|
128
127
|
}
|
|
129
128
|
else {
|
|
130
|
-
|
|
129
|
+
const nextTool = guard.flow === "annotations" ? "mark_annotations_as_live" :
|
|
130
|
+
guard.flow === "ui_components" ? "mark_ui_component_generated" :
|
|
131
|
+
guard.flow === "ui_improvements" ? "mark_annotations_as_live" : "the next workflow step";
|
|
132
|
+
throw new Error(`TOOL_CALL_BLOCKED: tool '${toolName}' not allowed while in '${guard.flow}' workflow. You must call '${nextTool}' to complete the current task before starting another.`);
|
|
131
133
|
}
|
|
132
134
|
}
|
|
133
135
|
guard.startedAt = now;
|
|
@@ -160,16 +162,12 @@ function createMcpServer(apiKey, personalKey) {
|
|
|
160
162
|
// Allow re-fetching at any time during the flow
|
|
161
163
|
guard.step = 1;
|
|
162
164
|
}
|
|
163
|
-
else if (toolName === "
|
|
165
|
+
else if (toolName === "mark_annotations_as_live") {
|
|
164
166
|
if (guard.step !== 1)
|
|
165
167
|
throw new Error("TOOL_CALL_BLOCKED: unexpected step");
|
|
166
168
|
// Stop here and reset flow as per USER_REQUEST (MCP only reaches 'applied')
|
|
167
169
|
resetGuard();
|
|
168
170
|
}
|
|
169
|
-
else if (toolName === "mark_annotations_as_live") {
|
|
170
|
-
// Optional step if the model decides to use it, but no longer part of the required chain
|
|
171
|
-
resetGuard();
|
|
172
|
-
}
|
|
173
171
|
else {
|
|
174
172
|
throw new Error("TOOL_CALL_BLOCKED: tool not allowed in active flow");
|
|
175
173
|
}
|
|
@@ -178,14 +176,11 @@ function createMcpServer(apiKey, personalKey) {
|
|
|
178
176
|
if (toolName === "get_ui_improvements") {
|
|
179
177
|
guard.step = 1;
|
|
180
178
|
}
|
|
181
|
-
else if (toolName === "
|
|
179
|
+
else if (toolName === "mark_annotations_as_live") {
|
|
182
180
|
if (guard.step !== 1)
|
|
183
181
|
throw new Error("TOOL_CALL_BLOCKED: unexpected step");
|
|
184
182
|
resetGuard();
|
|
185
183
|
}
|
|
186
|
-
else if (toolName === "mark_annotations_as_live") {
|
|
187
|
-
resetGuard();
|
|
188
|
-
}
|
|
189
184
|
else {
|
|
190
185
|
throw new Error("TOOL_CALL_BLOCKED: tool not allowed in active flow");
|
|
191
186
|
}
|
|
@@ -290,8 +285,8 @@ function createMcpServer(apiKey, personalKey) {
|
|
|
290
285
|
},
|
|
291
286
|
},
|
|
292
287
|
{
|
|
293
|
-
name: "
|
|
294
|
-
description: "Mark as
|
|
288
|
+
name: "mark_annotations_as_live",
|
|
289
|
+
description: "Mark tickets (functional or UI/UX) as applied. Use this tool after fixing the code to submit your changes. IMPORTANT: appliedChanges must be in the project's preferredLanguage (e.g. SPANISH).",
|
|
295
290
|
inputSchema: {
|
|
296
291
|
type: "object",
|
|
297
292
|
properties: {
|
|
@@ -310,21 +305,6 @@ function createMcpServer(apiKey, personalKey) {
|
|
|
310
305
|
required: ["results"]
|
|
311
306
|
},
|
|
312
307
|
},
|
|
313
|
-
{
|
|
314
|
-
name: "mark_annotations_as_live",
|
|
315
|
-
description: "Mark as live (ready_for_review). IDs required.",
|
|
316
|
-
inputSchema: {
|
|
317
|
-
type: "object",
|
|
318
|
-
properties: {
|
|
319
|
-
ids: {
|
|
320
|
-
type: "array",
|
|
321
|
-
items: { type: "string" },
|
|
322
|
-
description: "Internal IDs."
|
|
323
|
-
}
|
|
324
|
-
},
|
|
325
|
-
required: ["ids"]
|
|
326
|
-
},
|
|
327
|
-
},
|
|
328
308
|
{
|
|
329
309
|
name: "planning",
|
|
330
310
|
description: "Planning tool for backlog tickets. Fetch tickets or submit analysis. IMPORTANT: aiAnalysis must be in the project's preferredLanguage (e.g. SPANISH).",
|
|
@@ -608,6 +588,12 @@ Endpoints: ${ann.backendEndpoints?.length ? ann.backendEndpoints.join(', ') : 'N
|
|
|
608
588
|
Feedback previo: ${ann.corrections && Array.isArray(ann.corrections) && ann.corrections.length > 0 ? ann.corrections[ann.corrections.length - 1].text : 'Ninguno'}
|
|
609
589
|
Tarea: ${ann.message}
|
|
610
590
|
Lang: ${rawData.preferredLanguage === 'es' ? 'ES' : 'EN'}
|
|
591
|
+
|
|
592
|
+
### FLUJO DE TRABAJO OBLIGATORIO ###
|
|
593
|
+
1. Analiza el código y el problema.
|
|
594
|
+
2. Aplica la solución técnica necesaria.
|
|
595
|
+
3. AL TERMINAR, DEBES LLAMAR A 'mark_annotations_as_live' con el id '${ann._id}' y un resumen de tus cambios en 'appliedChanges' (en ESPAÑOL).
|
|
596
|
+
4. El estado final del ticket será 'applied'. NO intentes usar otros estados o herramientas hasta completar este paso.
|
|
611
597
|
(RECUERDA: Toda tu respuesta, comentarios y análisis DEBEN estar en ESPAÑOL)`
|
|
612
598
|
};
|
|
613
599
|
});
|
|
@@ -618,10 +604,10 @@ Lang: ${rawData.preferredLanguage === 'es' ? 'ES' : 'EN'}
|
|
|
618
604
|
content: [{ type: "text", text: langHint + JSON.stringify({ preferredLanguage: rawData.preferredLanguage || 'en', annotations: annotationsWithTips }, null, 2) }],
|
|
619
605
|
};
|
|
620
606
|
}
|
|
621
|
-
case "
|
|
607
|
+
case "mark_annotations_as_live": {
|
|
622
608
|
const args = argsAny;
|
|
623
609
|
const results = args.results;
|
|
624
|
-
console.error(`[
|
|
610
|
+
console.error(`[mark_annotations_as_live] Submitting results for ${results?.length} items as applied`);
|
|
625
611
|
const response = await fetch(`${BACKEND_URL}/api/mcp/annotations/batch-ready`, {
|
|
626
612
|
method: 'PATCH',
|
|
627
613
|
headers: {
|
|
@@ -641,27 +627,6 @@ Lang: ${rawData.preferredLanguage === 'es' ? 'ES' : 'EN'}
|
|
|
641
627
|
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
642
628
|
};
|
|
643
629
|
}
|
|
644
|
-
case "mark_annotations_as_live": {
|
|
645
|
-
const args = argsAny;
|
|
646
|
-
const ids = args.ids;
|
|
647
|
-
console.error(`[mark_annotations_as_live] Marking ${ids?.length} items as live`);
|
|
648
|
-
const response = await fetch(`${BACKEND_URL}/api/mcp/annotations/mark-as-live`, {
|
|
649
|
-
method: 'POST',
|
|
650
|
-
headers: {
|
|
651
|
-
'Content-Type': 'application/json',
|
|
652
|
-
'x-api-key': apiKey,
|
|
653
|
-
'x-mcp-tool-name': toolName,
|
|
654
|
-
'x-personal-key': personalKey || ''
|
|
655
|
-
},
|
|
656
|
-
body: JSON.stringify({ ids })
|
|
657
|
-
});
|
|
658
|
-
if (!response.ok)
|
|
659
|
-
throw new Error(`Backend responded with ${response.status}`);
|
|
660
|
-
const data = (await response.json());
|
|
661
|
-
return {
|
|
662
|
-
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
663
|
-
};
|
|
664
|
-
}
|
|
665
630
|
case "planning": {
|
|
666
631
|
const args = argsAny;
|
|
667
632
|
const url = args.results ? `${BACKEND_URL}/api/mcp/annotations/batch-planning` : `${BACKEND_URL}/api/mcp/backlog`;
|
|
@@ -681,6 +646,7 @@ Lang: ${rawData.preferredLanguage === 'es' ? 'ES' : 'EN'}
|
|
|
681
646
|
}
|
|
682
647
|
case "get_ui_improvements": {
|
|
683
648
|
const args = argsAny;
|
|
649
|
+
const agentId = personalKey || 'mcp-agent-ui-' + (apiKey?.slice(-6) || 'generic');
|
|
684
650
|
const fetchUrl = new URL(`${BACKEND_URL}/api/mcp/ui-improvements`);
|
|
685
651
|
if (args.limit)
|
|
686
652
|
fetchUrl.searchParams.append("limit", args.limit.toString());
|
|
@@ -690,6 +656,10 @@ Lang: ${rawData.preferredLanguage === 'es' ? 'ES' : 'EN'}
|
|
|
690
656
|
fetchUrl.searchParams.append("key", args.key);
|
|
691
657
|
if (args.ids)
|
|
692
658
|
fetchUrl.searchParams.append("ids", args.ids);
|
|
659
|
+
// Add lock and agentId parameters to enable blocking flow
|
|
660
|
+
fetchUrl.searchParams.append("lock", "true");
|
|
661
|
+
fetchUrl.searchParams.append("agentId", agentId);
|
|
662
|
+
console.error(`[get_ui_improvements] Fetching with lock: ${fetchUrl.toString()}`);
|
|
693
663
|
const response = await fetch(fetchUrl, {
|
|
694
664
|
headers: {
|
|
695
665
|
'x-api-key': apiKey,
|
|
@@ -701,11 +671,33 @@ Lang: ${rawData.preferredLanguage === 'es' ? 'ES' : 'EN'}
|
|
|
701
671
|
const errorBody = await response.text();
|
|
702
672
|
throw new Error(`Backend responded with ${response.status}: ${errorBody}`);
|
|
703
673
|
}
|
|
704
|
-
const
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
: "";
|
|
708
|
-
|
|
674
|
+
const rawData = (await response.json());
|
|
675
|
+
let rawImprovements = Array.isArray(rawData) ? rawData : (rawData?.data || rawData?.improvements || []);
|
|
676
|
+
if (!Array.isArray(rawImprovements)) {
|
|
677
|
+
return { content: [{ type: "text", text: "Error: Invalid format from backend" }], isError: true };
|
|
678
|
+
}
|
|
679
|
+
const improvementsWithTips = rawImprovements.map((ann) => {
|
|
680
|
+
return {
|
|
681
|
+
...ann,
|
|
682
|
+
_ia_fix_instruction: `### INSTRUCCIONES PARA LA IA (MEJORA UI - IMPORTANTE) ###
|
|
683
|
+
A continuación se presenta un ticket de MEJORA VISUAL/UX que requiere tu atención.
|
|
684
|
+
DEBES RESPONDER EN ESPAÑOL.
|
|
685
|
+
Proyecto: ${rawData.name || 'ViewGate'}
|
|
686
|
+
Tarea: ${ann.message}
|
|
687
|
+
Lang: ${rawData.preferredLanguage === 'es' ? 'ES' : 'EN'}
|
|
688
|
+
|
|
689
|
+
### FLUJO DE TRABAJO OBLIGATORIO ###
|
|
690
|
+
1. Analiza el diseño y los estilos CSS actuales.
|
|
691
|
+
2. Aplica los cambios visuales solicitados (STRICTLY LIMITED TO VISUAL/CSS CHANGES).
|
|
692
|
+
3. AL TERMINAR, DEBES LLAMAR A 'mark_annotations_as_live' con el id '${ann._id}' y un resumen de tus cambios en 'appliedChanges' (en ESPAÑOL).
|
|
693
|
+
4. El estado final del ticket será 'applied'. NO intentes usar otros estados o herramientas hasta completar este paso.
|
|
694
|
+
(RECUERDA: Toda tu respuesta, comentarios y análisis DEBEN estar en ESPAÑOL)`
|
|
695
|
+
};
|
|
696
|
+
});
|
|
697
|
+
const langHint = rawData.preferredLanguage === 'es'
|
|
698
|
+
? "\n*** [INSTRUCTION: Project is in SPANISH. Provide all comments and changes in SPANISH ONLY.] ***\n\n"
|
|
699
|
+
: (rawData.preferredLanguage === 'en' ? "\n*** [INSTRUCTION: Provide all comments and analysis in English.] ***\n\n" : "");
|
|
700
|
+
return { content: [{ type: "text", text: langHint + JSON.stringify({ preferredLanguage: rawData.preferredLanguage || 'en', improvements: improvementsWithTips }, null, 2) }] };
|
|
709
701
|
}
|
|
710
702
|
case "sync_endpoints": {
|
|
711
703
|
const args = argsAny;
|