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.
Files changed (2) hide show
  1. package/dist/index.js +49 -57
  2. 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("TOOL_CALL_BLOCKED: tool not allowed in idle");
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
- throw new Error("TOOL_CALL_BLOCKED: tool not allowed in active flow");
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 === "mark_annotation_ready") {
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 === "mark_annotation_ready") {
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: "mark_annotation_ready",
294
- description: "Mark as ready/applied. Use internal IDs. IMPORTANT: appliedChanges must be in the project's preferredLanguage (e.g. SPANISH).",
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 "mark_annotation_ready": {
607
+ case "mark_annotations_as_live": {
622
608
  const args = argsAny;
623
609
  const results = args.results;
624
- console.error(`[mark_annotation_ready] Submitting results for ${results?.length} items`);
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 data = (await response.json());
705
- const langHint = data.preferredLanguage === 'es'
706
- ? "\n*** [INSTRUCTION: Project is in SPANISH. Provide all CSS/Visual changes in SPANISH comments if requested.] ***\n\n\n\n"
707
- : "";
708
- return { content: [{ type: "text", text: langHint + JSON.stringify(data, null, 2) }] };
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "viewgate-mcp",
3
- "version": "1.0.47",
3
+ "version": "1.0.48",
4
4
  "main": "dist/index.js",
5
5
  "bin": {
6
6
  "viewgate-mcp": "./dist/index.js"