viewgate-wrapper 1.10.28 → 1.10.29
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/cli.js +17 -36
- package/package.json +3 -7
- package/mcp-server/dist/index.js +0 -222
- package/mcp-server/package.json +0 -20
package/dist/cli.js
CHANGED
|
@@ -14,31 +14,10 @@ async function setup() {
|
|
|
14
14
|
console.error(`❌ Could not find mcp_config.json at ${configPath}`);
|
|
15
15
|
process.exit(1);
|
|
16
16
|
}
|
|
17
|
-
// 2. Determine the path
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
// Check if we are running from node_modules or local dev
|
|
22
|
-
const isLocalDev = __dirname.includes('view-gate-wrapper' + path.sep + 'src') || __dirname.includes('view-gate-wrapper' + path.sep + 'dist');
|
|
23
|
-
if (isLocalDev) {
|
|
24
|
-
// Find the root of the project
|
|
25
|
-
let root = __dirname;
|
|
26
|
-
while (root !== path.parse(root).root && !fs.existsSync(path.join(root, 'package.json'))) {
|
|
27
|
-
root = path.dirname(root);
|
|
28
|
-
}
|
|
29
|
-
mcpServerPath = path.join(root, 'mcp-server', 'dist', 'index.js');
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
// In node_modules, we expect to be in something like node_modules/viewgate-wrapper/dist
|
|
33
|
-
mcpServerPath = path.join(__dirname, '..', 'mcp-server', 'dist', 'index.js');
|
|
34
|
-
}
|
|
35
|
-
// Normalize to forward slashes for the JSON config (cleaner on Windows)
|
|
36
|
-
const normalizedMcpPath = mcpServerPath.replace(/\\/g, '/');
|
|
37
|
-
if (!fs.existsSync(mcpServerPath)) {
|
|
38
|
-
console.error(`❌ MCP Server not found at: ${mcpServerPath}`);
|
|
39
|
-
console.log('Please ensure you have built the project: npm run build');
|
|
40
|
-
process.exit(1);
|
|
41
|
-
}
|
|
17
|
+
// 2. Determine the path or URL
|
|
18
|
+
// Since we now have a standalone server, we can point to its URL or local path.
|
|
19
|
+
// The user wants it to be scalable, so we'll prioritize a server URL.
|
|
20
|
+
const mcpServerUrl = process.env.MCP_SERVER_URL || 'https://view-gate.vercel.app/sse';
|
|
42
21
|
// 3. Read and update mcp_config.json
|
|
43
22
|
try {
|
|
44
23
|
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
@@ -48,22 +27,24 @@ async function setup() {
|
|
|
48
27
|
const currentServer = config.mcpServers.viewgate || {};
|
|
49
28
|
const env = currentServer.env || {};
|
|
50
29
|
// Default values if not present
|
|
51
|
-
const backendUrl = env.BACKEND_URL || '
|
|
52
|
-
const apiKey = env.API_KEY || '
|
|
30
|
+
const backendUrl = env.BACKEND_URL || 'http://localhost:5000';
|
|
31
|
+
const apiKey = env.API_KEY || '';
|
|
53
32
|
config.mcpServers.viewgate = {
|
|
54
|
-
command:
|
|
55
|
-
args: [
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
33
|
+
command: "npx",
|
|
34
|
+
args: [
|
|
35
|
+
"-y",
|
|
36
|
+
"mcp-remote",
|
|
37
|
+
`${mcpServerUrl}${mcpServerUrl.includes('?') ? '&' : '?'}apiKey=${apiKey}`
|
|
38
|
+
],
|
|
39
|
+
env: {}
|
|
60
40
|
};
|
|
61
41
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
62
42
|
console.log(`✅ Updated mcp_config.json successfully!`);
|
|
63
|
-
console.log(`📍 MCP
|
|
64
|
-
if (apiKey
|
|
65
|
-
console.log('\n⚠️
|
|
43
|
+
console.log(`📍 MCP Server URL: ${mcpServerUrl}`);
|
|
44
|
+
if (!apiKey) {
|
|
45
|
+
console.log('\n⚠️ Recuerda configurar tu API_KEY en:');
|
|
66
46
|
console.log(` ${configPath}`);
|
|
47
|
+
console.log(' Puedes encontrar tu API_KEY en el Dashboard de ViewGate.');
|
|
67
48
|
}
|
|
68
49
|
}
|
|
69
50
|
catch (error) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "viewgate-wrapper",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.29",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/viewgate-wrapper.umd.cjs",
|
|
6
6
|
"module": "./dist/viewgate-wrapper.js",
|
|
@@ -17,13 +17,11 @@
|
|
|
17
17
|
"./dist/*": "./dist/*"
|
|
18
18
|
},
|
|
19
19
|
"files": [
|
|
20
|
-
"dist"
|
|
21
|
-
"mcp-server/dist",
|
|
22
|
-
"mcp-server/package.json"
|
|
20
|
+
"dist"
|
|
23
21
|
],
|
|
24
22
|
"scripts": {
|
|
25
23
|
"dev": "vite",
|
|
26
|
-
"build": "vite build && tsc --emitDeclarationOnly && npx tsc src/cli.ts --outDir dist --module nodenext --target esnext --moduleResolution nodenext --esModuleInterop --skipLibCheck --rootDir src && npx tsc src/plugin/transform-logic.ts src/plugin/vite-plugin-viewgate.ts src/plugin/next-loader.ts --outDir dist/plugin --module nodenext --target esnext --moduleResolution nodenext --esModuleInterop --skipLibCheck --rootDir src/plugin
|
|
24
|
+
"build": "vite build && tsc --emitDeclarationOnly && npx tsc src/cli.ts --outDir dist --module nodenext --target esnext --moduleResolution nodenext --esModuleInterop --skipLibCheck --rootDir src && npx tsc src/plugin/transform-logic.ts src/plugin/vite-plugin-viewgate.ts src/plugin/next-loader.ts --outDir dist/plugin --module nodenext --target esnext --moduleResolution nodenext --esModuleInterop --skipLibCheck --rootDir src/plugin",
|
|
27
25
|
"preview": "vite preview"
|
|
28
26
|
},
|
|
29
27
|
"keywords": [],
|
|
@@ -35,11 +33,9 @@
|
|
|
35
33
|
"react-dom": "^19.0.0"
|
|
36
34
|
},
|
|
37
35
|
"dependencies": {
|
|
38
|
-
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
39
36
|
"html-to-image": "^1.11.13",
|
|
40
37
|
"html2canvas-pro": "^2.0.2",
|
|
41
38
|
"lucide-react": "^0.577.0",
|
|
42
|
-
"node-fetch": "^2.7.0",
|
|
43
39
|
"swr": "^2.4.1"
|
|
44
40
|
},
|
|
45
41
|
"devDependencies": {
|
package/mcp-server/dist/index.js
DELETED
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
-
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
4
|
-
import fetch from "node-fetch";
|
|
5
|
-
import fs from "fs";
|
|
6
|
-
import path from "path";
|
|
7
|
-
const BACKEND_URL = process.env.BACKEND_URL || "https://view-gate.vercel.app";
|
|
8
|
-
const server = new Server({
|
|
9
|
-
name: "viewgate-mcp",
|
|
10
|
-
version: "1.0.0",
|
|
11
|
-
}, {
|
|
12
|
-
capabilities: {
|
|
13
|
-
tools: {},
|
|
14
|
-
},
|
|
15
|
-
});
|
|
16
|
-
/**
|
|
17
|
-
* List available tools.
|
|
18
|
-
* Exposes a tool to read annotations from the backend.
|
|
19
|
-
*/
|
|
20
|
-
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
21
|
-
return {
|
|
22
|
-
tools: [
|
|
23
|
-
{
|
|
24
|
-
name: "get_annotations",
|
|
25
|
-
description: "Retrieves all feedback annotations. For each annotation, follow the '_ia_fix_instruction' to perform a FAST, SURGICAL fix. Use 'outerHtml' and 'source' (file:line) to locate the exact code block without manual searching.",
|
|
26
|
-
inputSchema: {
|
|
27
|
-
type: "object",
|
|
28
|
-
properties: {},
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
name: "mark_annotation_ready",
|
|
33
|
-
description: "Mark an annotation as ready for review after applying changes, and generate a local Markdown log.",
|
|
34
|
-
inputSchema: {
|
|
35
|
-
type: "object",
|
|
36
|
-
properties: {
|
|
37
|
-
id: {
|
|
38
|
-
type: "string",
|
|
39
|
-
description: "The ID of the annotation to mark as ready"
|
|
40
|
-
},
|
|
41
|
-
originalMessage: {
|
|
42
|
-
type: "string",
|
|
43
|
-
description: "The original feedback message for the changelog"
|
|
44
|
-
},
|
|
45
|
-
appliedChanges: {
|
|
46
|
-
type: "string",
|
|
47
|
-
description: "Brief summary of what was changed in the code"
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
required: ["id", "originalMessage", "appliedChanges"]
|
|
51
|
-
},
|
|
52
|
-
}
|
|
53
|
-
],
|
|
54
|
-
};
|
|
55
|
-
});
|
|
56
|
-
/**
|
|
57
|
-
* Handle tool calls.
|
|
58
|
-
*/
|
|
59
|
-
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
60
|
-
switch (request.params.name) {
|
|
61
|
-
case "get_annotations": {
|
|
62
|
-
try {
|
|
63
|
-
const statuses = 'pending,bug_fixing';
|
|
64
|
-
const response = await fetch(`${BACKEND_URL}/api/annotations?full=true&status=${statuses}`, {
|
|
65
|
-
headers: {
|
|
66
|
-
'x-api-key': process.env.API_KEY || ''
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
if (!response.ok) {
|
|
70
|
-
throw new Error(`Backend responded with ${response.status}`);
|
|
71
|
-
}
|
|
72
|
-
const data = await response.json();
|
|
73
|
-
const rawAnnotations = Array.isArray(data) ? data : (data?.data || []);
|
|
74
|
-
if (!Array.isArray(rawAnnotations)) {
|
|
75
|
-
return {
|
|
76
|
-
content: [{ type: "text", text: "Error: Invalid format" }],
|
|
77
|
-
isError: true
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
const priorityMap = {
|
|
81
|
-
'urgent': 4,
|
|
82
|
-
'urgente': 4,
|
|
83
|
-
'high': 3,
|
|
84
|
-
'alta': 3,
|
|
85
|
-
'medium': 2,
|
|
86
|
-
'media': 2,
|
|
87
|
-
'low': 1,
|
|
88
|
-
'baja': 1
|
|
89
|
-
};
|
|
90
|
-
const sortedAnnotations = rawAnnotations.sort((a, b) => {
|
|
91
|
-
// 1. Primary Sort: Status (Pending > Bug Fixing)
|
|
92
|
-
const statusOrder = {
|
|
93
|
-
'pending': 2,
|
|
94
|
-
'bug_fixing': 1
|
|
95
|
-
};
|
|
96
|
-
const statusA = (a.status || 'pending').toLowerCase();
|
|
97
|
-
const statusB = (b.status || 'pending').toLowerCase();
|
|
98
|
-
if (statusOrder[statusA] !== statusOrder[statusB]) {
|
|
99
|
-
// Higher number = Higher priority
|
|
100
|
-
return (statusOrder[statusB] || 0) - (statusOrder[statusA] || 0);
|
|
101
|
-
}
|
|
102
|
-
// 2. Secondary Sort: Priority (Urgent > Alta > Media > Baja)
|
|
103
|
-
const prioA = priorityMap[(a.priority || 'medium').toLowerCase()] || 0;
|
|
104
|
-
const prioB = priorityMap[(b.priority || 'medium').toLowerCase()] || 0;
|
|
105
|
-
return prioB - prioA;
|
|
106
|
-
});
|
|
107
|
-
const annotationsWithTips = sortedAnnotations.map((ann) => {
|
|
108
|
-
const source = ann.reference?.source;
|
|
109
|
-
const hasSource = source && source !== 'unknown:0';
|
|
110
|
-
const [file, line] = hasSource ? source.split(':') : [null, null];
|
|
111
|
-
let hint = "";
|
|
112
|
-
if (hasSource) {
|
|
113
|
-
hint = `SURGICAL FIX: Open \`${file}\` at line ${line}. The element is \`${ann.reference.tag}\`.`;
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
hint = `MANUAL FIND: Search for the element using selector \`${ann.reference?.selector}\`. Reference HTML: \`${ann.reference?.outerHtml?.slice(0, 100)}...\``;
|
|
117
|
-
}
|
|
118
|
-
return {
|
|
119
|
-
...ann,
|
|
120
|
-
_ia_fix_instruction: hint
|
|
121
|
-
};
|
|
122
|
-
});
|
|
123
|
-
return {
|
|
124
|
-
content: [
|
|
125
|
-
{
|
|
126
|
-
type: "text",
|
|
127
|
-
text: JSON.stringify(annotationsWithTips, null, 2),
|
|
128
|
-
},
|
|
129
|
-
],
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
catch (error) {
|
|
133
|
-
return {
|
|
134
|
-
content: [
|
|
135
|
-
{
|
|
136
|
-
type: "text",
|
|
137
|
-
text: `Error fetching annotations: ${error.message}`,
|
|
138
|
-
},
|
|
139
|
-
],
|
|
140
|
-
isError: true,
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
case "mark_annotation_ready": {
|
|
145
|
-
try {
|
|
146
|
-
const { id, originalMessage, appliedChanges } = request.params.arguments;
|
|
147
|
-
// 1. Update backend status
|
|
148
|
-
const response = await fetch(`${BACKEND_URL}/api/annotations/${id}`, {
|
|
149
|
-
method: 'PATCH',
|
|
150
|
-
headers: {
|
|
151
|
-
'Content-Type': 'application/json',
|
|
152
|
-
'x-api-key': process.env.API_KEY || ''
|
|
153
|
-
},
|
|
154
|
-
body: JSON.stringify({ status: 'ready_for_review' })
|
|
155
|
-
});
|
|
156
|
-
if (!response.ok) {
|
|
157
|
-
throw new Error(`Backend responded with ${response.status} when updating annotation`);
|
|
158
|
-
}
|
|
159
|
-
const updatedAnnotation = await response.json();
|
|
160
|
-
// 2. Generate local Markdown file
|
|
161
|
-
// We write this to the user's project root (where the MCP server was executed from)
|
|
162
|
-
const projectRoot = process.cwd();
|
|
163
|
-
const viewgateDir = path.join(projectRoot, 'viewgate');
|
|
164
|
-
if (!fs.existsSync(viewgateDir)) {
|
|
165
|
-
fs.mkdirSync(viewgateDir, { recursive: true });
|
|
166
|
-
}
|
|
167
|
-
const date = new Date();
|
|
168
|
-
const formattedDate = date.toISOString().replace(/[:.]/g, '-');
|
|
169
|
-
const fileName = `cambios-${formattedDate}.md`;
|
|
170
|
-
const filePath = path.join(viewgateDir, fileName);
|
|
171
|
-
const markdownContent = `# Change Log: ${date.toLocaleString()}
|
|
172
|
-
|
|
173
|
-
## Original Feedback
|
|
174
|
-
> ${originalMessage}
|
|
175
|
-
|
|
176
|
-
## Applied Changes
|
|
177
|
-
${appliedChanges}
|
|
178
|
-
|
|
179
|
-
## Annotation Details
|
|
180
|
-
- **ID:** ${id}
|
|
181
|
-
- **Component:** ${updatedAnnotation.componentName || 'Unknown'}
|
|
182
|
-
- **File:** ${updatedAnnotation.filePath || 'Unknown'}
|
|
183
|
-
- **Status updated to:** Ready for review
|
|
184
|
-
`;
|
|
185
|
-
fs.writeFileSync(filePath, markdownContent, 'utf8');
|
|
186
|
-
return {
|
|
187
|
-
content: [
|
|
188
|
-
{
|
|
189
|
-
type: "text",
|
|
190
|
-
text: `Successfully marked annotation ${id} as ready_for_review.\nGenerated local changelog at: ${filePath}`,
|
|
191
|
-
},
|
|
192
|
-
],
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
catch (error) {
|
|
196
|
-
return {
|
|
197
|
-
content: [
|
|
198
|
-
{
|
|
199
|
-
type: "text",
|
|
200
|
-
text: `Error marking annotation ready: ${error.message}`,
|
|
201
|
-
},
|
|
202
|
-
],
|
|
203
|
-
isError: true,
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
default:
|
|
208
|
-
throw new Error("Unknown tool");
|
|
209
|
-
}
|
|
210
|
-
});
|
|
211
|
-
/**
|
|
212
|
-
* Start the server using stdio transport.
|
|
213
|
-
*/
|
|
214
|
-
async function main() {
|
|
215
|
-
const transport = new StdioServerTransport();
|
|
216
|
-
await server.connect(transport);
|
|
217
|
-
console.error("ViewGate MCP server running on stdio");
|
|
218
|
-
}
|
|
219
|
-
main().catch((error) => {
|
|
220
|
-
console.error("Server error:", error);
|
|
221
|
-
process.exit(1);
|
|
222
|
-
});
|
package/mcp-server/package.json
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "mcp-server",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"type": "module",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"build": "tsc",
|
|
8
|
-
"start": "node dist/index.js",
|
|
9
|
-
"dev": "tsc -w"
|
|
10
|
-
},
|
|
11
|
-
"keywords": [],
|
|
12
|
-
"author": "",
|
|
13
|
-
"license": "ISC",
|
|
14
|
-
"description": "",
|
|
15
|
-
"dependencies": {},
|
|
16
|
-
"devDependencies": {
|
|
17
|
-
"@types/node-fetch": "^2.6.13",
|
|
18
|
-
"typescript": "^5.9.3"
|
|
19
|
-
}
|
|
20
|
-
}
|