viewgate-mcp 1.0.60 → 1.0.62

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 +30 -21
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -148,10 +148,8 @@ function createMcpServer(apiKey, personalKey) {
148
148
  }
149
149
  else if (toolName === "generate_ui_components") {
150
150
  guard.step = 2;
151
- }
152
- else if (toolName === "mark_ui_component_generated") {
153
- // Allow finishing if it was started in this flow
154
- resetGuard();
151
+ // Step 3 is now terminal, but we reset after success in the handler
152
+ guard.step = 3;
155
153
  }
156
154
  else {
157
155
  throw new Error("TOOL_CALL_BLOCKED: tool not allowed in active flow");
@@ -165,8 +163,8 @@ function createMcpServer(apiKey, personalKey) {
165
163
  else if (toolName === "mark_annotations_as_live") {
166
164
  if (guard.step !== 1)
167
165
  throw new Error("TOOL_CALL_BLOCKED: unexpected step");
168
- // Stop here and reset flow as per USER_REQUEST (MCP only reaches 'applied')
169
- resetGuard();
166
+ // Reset moved to success handler
167
+ guard.step = 2;
170
168
  }
171
169
  else {
172
170
  throw new Error("TOOL_CALL_BLOCKED: tool not allowed in active flow");
@@ -179,7 +177,7 @@ function createMcpServer(apiKey, personalKey) {
179
177
  else if (toolName === "mark_annotations_as_live") {
180
178
  if (guard.step !== 1)
181
179
  throw new Error("TOOL_CALL_BLOCKED: unexpected step");
182
- resetGuard();
180
+ guard.step = 2;
183
181
  }
184
182
  else {
185
183
  throw new Error("TOOL_CALL_BLOCKED: tool not allowed in active flow");
@@ -198,7 +196,8 @@ function createMcpServer(apiKey, personalKey) {
198
196
  else {
199
197
  if (guard.step !== 1)
200
198
  throw new Error("TOOL_CALL_BLOCKED: unexpected step");
201
- resetGuard();
199
+ // Reset moved to success handler
200
+ guard.step = 2;
202
201
  }
203
202
  }
204
203
  else if (guard.flow === "sync") {
@@ -398,6 +397,7 @@ function createMcpServer(apiKey, personalKey) {
398
397
  const errorBody = await response.text();
399
398
  throw new Error(`Backend responded with ${response.status}: ${errorBody}`);
400
399
  }
400
+ resetGuard();
401
401
  const data = (await response.json());
402
402
  const styleHandler = data?.settings?.styleHandler || 'unknown';
403
403
  const language = data?.settings?.language || 'en';
@@ -442,7 +442,7 @@ function createMcpServer(apiKey, personalKey) {
442
442
  'css': `Use CSS custom properties for all colors. Read theme values like: const primary = theme?.primary || 'var(--vg-primary)'. Apply them inline or inject a <style> block using these variables. Never hardcode colors.`,
443
443
  'sass': `Use CSS custom properties as values. Resolve theme at runtime: const primary = theme?.primary || 'var(--vg-primary)'. Apply via inline style or injected <style>.`,
444
444
  'css-modules': `CSS Modules can use CSS vars. In JS: const primary = theme?.primary || 'var(--vg-primary)'. Pass primary as CSS var via style={{ '--component-primary': primary }} on the root element and reference it inside the .module.css.`,
445
- 'tailwind': `Use Tailwind's arbitrary value syntax for theme colors: className={\`bg-[\${theme?.primary || 'var(--vg-primary)'}]\`}. For text and borders follow the same pattern. Never use fixed Tailwind color classes like text-blue-500.`,
445
+ 'tailwind': `Use Tailwind's standard 'primary' color class which is dynamically injected by the preview engine. Example: className="bg-primary hover:bg-primary-hover text-primary-foreground". If manually overriding, use: style={{ backgroundColor: theme?.primary || 'var(--vg-primary)' }}. NEVER use fixed classes like text-blue-500.`,
446
446
  'css-in-js': `In styled-components template literals, read the theme prop: color: \${({ theme: t }) => t?.primary || 'var(--vg-primary)'}. Accept the full theme object via props and propagate it through styled-components ThemeProvider if needed.`,
447
447
  'bootstrap': `Override Bootstrap CSS vars on the root element: style={{ '--bs-primary': theme?.primary || 'var(--vg-primary)' }}. Use btn-primary, text-primary etc. classes which will inherit the overridden variable.`,
448
448
  'mui': `Use createTheme({ palette: { primary: { main: theme?.primary || 'var(--vg-primary)' } } }) inside the component and wrap with ThemeProvider. Accept the theme prop and recreate the MUI theme from it.`,
@@ -469,25 +469,27 @@ function createMcpServer(apiKey, personalKey) {
469
469
  instruction: `You MUST use ${styleLabel} for ALL styling. Do not mix or use any other styling approach. The component must be fully styled using this technology and be production-ready.`
470
470
  },
471
471
  themingTokens: {
472
- description: 'The component MUST accept an optional `theme` prop for color customization. This is the primary mechanism for users to apply their own brand colors via a JSON file in their project.',
472
+ description: 'CRITICAL: The component MUST accept an optional `theme` prop. This is non-negotiable for production-ready components.',
473
473
  propInterface: {
474
- primary: 'string — main brand/accent color (buttons, links, active states)',
475
- primaryHover: 'string — hover state of primary, slightly darker',
476
- primaryLight: 'string — light tint of primary for backgrounds (10% opacity)',
474
+ primary: 'string — main brand/accent color (buttons, active states)',
475
+ primaryHover: 'string — hover state of primary',
476
+ primaryLight: 'string — light tint of primary for backgrounds',
477
+ primaryForeground: 'string — contrasting text color for primary backgrounds (white/black)',
477
478
  surface: 'string — card/panel background color',
478
- surfaceAlt: 'string — alternative surface for inputs/hover states',
479
+ surfaceAlt: 'string — alternative surface for inputs',
479
480
  border: 'string — border and divider color',
480
481
  text: 'string — primary text color',
481
482
  textMuted: 'string — secondary/muted text color',
482
- radius: 'string — base border radius (e.g. "8px", "12px")',
483
+ radius: 'string — base border radius (e.g. "12px")',
483
484
  },
484
- fallbackMechanism: 'When theme prop is not provided, fall back to CSS custom properties: var(--vg-primary), var(--vg-surface), etc. This allows the ViewGate dashboard preview (which injects CSS vars) and custom ThemeProviders to work without explicit props.',
485
+ fallbackMechanism: 'When theme prop is not provided, you MUST fall back to CSS custom properties: var(--vg-primary), var(--vg-surface), etc. This ensures the component is self-theming via global dashboard injection.',
485
486
  handlerSpecificInstruction: themingInstruction,
486
487
  criticalRules: [
487
- 'NEVER hardcode any color value (no #hex, no rgb(), no named colors like blue/red)',
488
- 'ALWAYS prefer theme prop values first, then var(--vg-*) CSS vars as fallback',
489
- 'The theme prop must be optional component must work without it using CSS var fallbacks',
490
- 'Expose the theme prop explicitly in the component TypeScript/PropTypes interface',
488
+ 'NEVER hardcode hex, rgb, or named colors. Use theme props or var(--vg-*) fallbacks.',
489
+ 'MUST use Tailwind standard "primary" class (e.g. bg-primary, text-primary-foreground) as these are dynamically injected in the dashboard.',
490
+ 'The theme prop MUST be optional and typed in the component interface.',
491
+ 'Micro-animations MUST be implemented with Framer Motion (use whileHover, whileTap, etc.)',
492
+ 'AESTHETIC PERFECTION: The generated component MUST be an EXACT visual match of the source design. Pay extreme attention to spacing, shadows, and subtle gradients.',
491
493
  ]
492
494
  },
493
495
  constraints: {
@@ -500,7 +502,9 @@ function createMcpServer(apiKey, personalKey) {
500
502
  mustBeProductionReady: true,
501
503
  mustUseFramerMotionForAnimations: true,
502
504
  themingIsMandatory: true,
503
- stylingHandlerIsStrict: true
505
+ stylingHandlerIsStrict: true,
506
+ mustBeAestheticallyIdentical: true,
507
+ visualFidelityInstruction: "You MUST ensure 100% visual parity. The output component must be PREMIUM and indistinguishable from the provided Figma design in terms of layout, spacing, and styling tokens."
504
508
  }
505
509
  };
506
510
  results.push({
@@ -527,6 +531,7 @@ function createMcpServer(apiKey, personalKey) {
527
531
  2) REGISTRAR LA PREVIEW usando 'mark_ui_component_generated'.
528
532
 
529
533
  REQUISITO TECNOLÓGICO OBLIGATORIO: Usar ${styleLabel} para TODOS los estilos.
534
+ REQUISITO DE FIDELIDAD ESTÉTICA: El componente debe ser VISUALMENTE IDÉNTICO al original. Respeta cada píxel de espaciado, sombras y pesos de fuente.
530
535
  REQUISITO DE THEMING: DEBES respetar las themingTokens. NUNCA hardcodees colores (#hex, etc). Usa SIEMPRE la prop 'theme' o el fallback 'var(--vg-*)'.
531
536
  NOTA: Si styleHandler es '${styleHandler}', NO utilices otra tecnología distinta aunque los archivos originales (Figma HTML/CSS) digan lo contrario.`,
532
537
  results
@@ -709,6 +714,7 @@ Lang: ${rawData.preferredLanguage === 'es' ? 'ES' : 'EN'}
709
714
  });
710
715
  if (!response.ok)
711
716
  throw new Error(`Backend responded with ${response.status}`);
717
+ resetGuard();
712
718
  const data = (await response.json());
713
719
  return {
714
720
  content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
@@ -729,6 +735,9 @@ Lang: ${rawData.preferredLanguage === 'es' ? 'ES' : 'EN'}
729
735
  });
730
736
  if (!response.ok)
731
737
  throw new Error(`Backend responded with ${response.status}`);
738
+ if (args.results) {
739
+ resetGuard();
740
+ }
732
741
  const data = (await response.json());
733
742
  // Point: Version Storing
734
743
  if (data.backlogVersion)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "viewgate-mcp",
3
- "version": "1.0.60",
3
+ "version": "1.0.62",
4
4
  "main": "dist/index.js",
5
5
  "bin": {
6
6
  "viewgate-mcp": "./dist/index.js"