dev3000 0.0.77 → 0.0.78
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/README.md +18 -0
- package/dist/cdp-monitor.d.ts.map +1 -1
- package/dist/cdp-monitor.js +33 -10
- package/dist/cdp-monitor.js.map +1 -1
- package/dist/dev-environment.d.ts +1 -1
- package/dist/dev-environment.d.ts.map +1 -1
- package/dist/dev-environment.js +201 -268
- package/dist/dev-environment.js.map +1 -1
- package/dist/src/tui-interface-impl.tsx +30 -7
- package/dist/tui-interface-impl.d.ts +1 -0
- package/dist/tui-interface-impl.d.ts.map +1 -1
- package/dist/tui-interface-impl.js +17 -2
- package/dist/tui-interface-impl.js.map +1 -1
- package/dist/tui-interface.d.ts +2 -0
- package/dist/tui-interface.d.ts.map +1 -1
- package/dist/tui-interface.js +8 -1
- package/dist/tui-interface.js.map +1 -1
- package/mcp-server/.next/BUILD_ID +1 -1
- package/mcp-server/.next/build-manifest.json +2 -2
- package/mcp-server/.next/fallback-build-manifest.json +2 -2
- package/mcp-server/.next/prerender-manifest.json +3 -3
- package/mcp-server/.next/server/app/_global-error.html +2 -2
- package/mcp-server/.next/server/app/_global-error.rsc +1 -1
- package/mcp-server/.next/server/app/_not-found.html +1 -1
- package/mcp-server/.next/server/app/_not-found.rsc +1 -1
- package/mcp-server/.next/server/app/index.html +1 -1
- package/mcp-server/.next/server/app/index.rsc +1 -1
- package/mcp-server/.next/server/chunks/ssr/_62451611._.js.map +1 -1
- package/mcp-server/.next/server/chunks/ssr/_b15f05ee._.js.map +1 -1
- package/mcp-server/.next/server/server-reference-manifest.js +1 -1
- package/mcp-server/.next/server/server-reference-manifest.json +1 -1
- package/mcp-server/package.json +0 -6
- package/package.json +7 -1
- package/src/tui-interface-impl.tsx +30 -7
- /package/mcp-server/.next/static/{NWQx_KX68gOo5fDkdXq6G → GE4QeOWMVNF-ly63PtQFE}/_buildManifest.js +0 -0
- /package/mcp-server/.next/static/{NWQx_KX68gOo5fDkdXq6G → GE4QeOWMVNF-ly63PtQFE}/_clientMiddlewareManifest.json +0 -0
- /package/mcp-server/.next/static/{NWQx_KX68gOo5fDkdXq6G → GE4QeOWMVNF-ly63PtQFE}/_ssgManifest.js +0 -0
package/dist/dev-environment.js
CHANGED
|
@@ -77,37 +77,6 @@ async function findAvailablePort(startPort) {
|
|
|
77
77
|
}
|
|
78
78
|
throw new Error(`No available ports found starting from ${startPort}`);
|
|
79
79
|
}
|
|
80
|
-
const AI_CLI_TOOLS = [
|
|
81
|
-
{
|
|
82
|
-
binary: "claude",
|
|
83
|
-
name: "Claude Code",
|
|
84
|
-
addMcpCommand: (name, command, ...args) => ["claude", "mcp", "add", name, command, ...args],
|
|
85
|
-
addHttpMcpCommand: (name, url) => ["claude", "mcp", "add", "-t", "http", name, url],
|
|
86
|
-
removeMcpCommand: (name) => ["claude", "mcp", "remove", name]
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
binary: "gemini",
|
|
90
|
-
name: "Gemini CLI",
|
|
91
|
-
addMcpCommand: (name, command, ...args) => ["gemini", "mcp", "add", name, command, ...args],
|
|
92
|
-
addHttpMcpCommand: (name, url) => ["gemini", "mcp", "add", "-t", "http", name, url],
|
|
93
|
-
removeMcpCommand: (name) => ["gemini", "mcp", "remove", name]
|
|
94
|
-
}
|
|
95
|
-
// TODO: Research and add other AI CLI tools once we verify their MCP capabilities
|
|
96
|
-
// {
|
|
97
|
-
// binary: "cursor-agent",
|
|
98
|
-
// name: "Cursor Agent",
|
|
99
|
-
// addMcpCommand: (name, command, ...args) => ["cursor-agent", "mcp", "add", name, command, ...args],
|
|
100
|
-
// addHttpMcpCommand: (name, url) => ["cursor-agent", "mcp", "add", "-t", "http", name, url],
|
|
101
|
-
// removeMcpCommand: (name) => ["cursor-agent", "mcp", "remove", name]
|
|
102
|
-
// },
|
|
103
|
-
// {
|
|
104
|
-
// binary: "codex",
|
|
105
|
-
// name: "Codex CLI",
|
|
106
|
-
// addMcpCommand: (name, command, ...args) => ["codex", "mcp", "add", name, command, ...args],
|
|
107
|
-
// addHttpMcpCommand: (name, url) => ["codex", "mcp", "add", "-t", "http", name, url],
|
|
108
|
-
// removeMcpCommand: (name) => ["codex", "mcp", "remove", name]
|
|
109
|
-
// }
|
|
110
|
-
];
|
|
111
80
|
/**
|
|
112
81
|
* Check if Next.js MCP server is enabled in the project configuration
|
|
113
82
|
*/
|
|
@@ -203,241 +172,198 @@ async function isChromeDevtoolsMcpSupported() {
|
|
|
203
172
|
}
|
|
204
173
|
}
|
|
205
174
|
/**
|
|
206
|
-
*
|
|
175
|
+
* Ensure MCP server configurations are added to project's .mcp.json (Claude Code)
|
|
207
176
|
*/
|
|
208
|
-
async function
|
|
209
|
-
const availableTools = [];
|
|
210
|
-
for (const tool of AI_CLI_TOOLS) {
|
|
211
|
-
try {
|
|
212
|
-
// Try to run the binary with --version to check if it exists
|
|
213
|
-
await new Promise((resolve, reject) => {
|
|
214
|
-
const testProcess = spawn(tool.binary, ["--version"], {
|
|
215
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
216
|
-
});
|
|
217
|
-
testProcess.on("close", (_code) => {
|
|
218
|
-
// Most CLIs return 0 for --version, but some might return other codes
|
|
219
|
-
// We just check if the binary exists and runs
|
|
220
|
-
resolve();
|
|
221
|
-
});
|
|
222
|
-
testProcess.on("error", (error) => {
|
|
223
|
-
// Binary not found or not executable
|
|
224
|
-
reject(error);
|
|
225
|
-
});
|
|
226
|
-
// Timeout after 2 seconds
|
|
227
|
-
setTimeout(() => {
|
|
228
|
-
testProcess.kill();
|
|
229
|
-
reject(new Error("Timeout"));
|
|
230
|
-
}, 2000);
|
|
231
|
-
});
|
|
232
|
-
availableTools.push(tool);
|
|
233
|
-
}
|
|
234
|
-
catch {
|
|
235
|
-
// Tool not available - continue checking others
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
return availableTools;
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Configure MCPs for a specific AI CLI tool
|
|
242
|
-
*/
|
|
243
|
-
async function configureMcpsForCliTool(tool, mcpPort, appPort, enableChromeDevtools, chromeDevtoolsSupported, enableNextjsMcp) {
|
|
244
|
-
const results = {
|
|
245
|
-
dev3000: false,
|
|
246
|
-
chromeDevtools: false,
|
|
247
|
-
nextjsDev: false
|
|
248
|
-
};
|
|
249
|
-
// Configure main dev3000 MCP
|
|
177
|
+
async function ensureMcpServers(mcpPort, appPort, enableChromeDevtools, enableNextjsMcp) {
|
|
250
178
|
try {
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
configProcess.stderr?.on("data", (data) => {
|
|
258
|
-
errorOutput += data.toString();
|
|
259
|
-
});
|
|
260
|
-
configProcess.on("close", (code) => {
|
|
261
|
-
if (code === 0 || errorOutput.includes("already exists")) {
|
|
262
|
-
results.dev3000 = true;
|
|
263
|
-
resolve();
|
|
264
|
-
}
|
|
265
|
-
else {
|
|
266
|
-
reject(new Error(`Failed to configure dev3000 MCP: ${errorOutput}`));
|
|
267
|
-
}
|
|
268
|
-
});
|
|
269
|
-
configProcess.on("error", reject);
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
catch (error) {
|
|
273
|
-
console.log(`⚠️ Failed to configure dev3000 MCP for ${tool.name}:`, error);
|
|
274
|
-
}
|
|
275
|
-
// Configure chrome-devtools MCP if enabled and Chrome version is supported
|
|
276
|
-
if (enableChromeDevtools && chromeDevtoolsSupported) {
|
|
277
|
-
try {
|
|
278
|
-
const chromeDevtoolsCommand = tool.addMcpCommand(MCP_NAMES.CHROME_DEVTOOLS, "npx", "chrome-devtools-mcp@latest", "--", "--browserUrl", "http://127.0.0.1:9222");
|
|
279
|
-
await new Promise((resolve, reject) => {
|
|
280
|
-
const configProcess = spawn(chromeDevtoolsCommand[0], chromeDevtoolsCommand.slice(1), {
|
|
281
|
-
stdio: ["inherit", "pipe", "pipe"]
|
|
282
|
-
});
|
|
283
|
-
let errorOutput = "";
|
|
284
|
-
configProcess.stderr?.on("data", (data) => {
|
|
285
|
-
errorOutput += data.toString();
|
|
286
|
-
});
|
|
287
|
-
configProcess.on("close", (code) => {
|
|
288
|
-
if (code === 0 || errorOutput.includes("already exists")) {
|
|
289
|
-
results.chromeDevtools = true;
|
|
290
|
-
resolve();
|
|
291
|
-
}
|
|
292
|
-
else {
|
|
293
|
-
reject(new Error(`Failed to configure chrome-devtools MCP: ${errorOutput}`));
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
|
-
configProcess.on("error", reject);
|
|
297
|
-
});
|
|
179
|
+
const settingsPath = join(process.cwd(), ".mcp.json");
|
|
180
|
+
// Read or create settings
|
|
181
|
+
let settings;
|
|
182
|
+
if (existsSync(settingsPath)) {
|
|
183
|
+
const settingsContent = readFileSync(settingsPath, "utf-8");
|
|
184
|
+
settings = JSON.parse(settingsContent);
|
|
298
185
|
}
|
|
299
|
-
|
|
300
|
-
|
|
186
|
+
else {
|
|
187
|
+
settings = {};
|
|
188
|
+
}
|
|
189
|
+
// Ensure mcpServers structure exists
|
|
190
|
+
if (!settings.mcpServers) {
|
|
191
|
+
settings.mcpServers = {};
|
|
192
|
+
}
|
|
193
|
+
let added = false;
|
|
194
|
+
// Add dev3000 MCP server (HTTP type)
|
|
195
|
+
if (!settings.mcpServers[MCP_NAMES.DEV3000]) {
|
|
196
|
+
settings.mcpServers[MCP_NAMES.DEV3000] = {
|
|
197
|
+
type: "http",
|
|
198
|
+
url: `http://localhost:${mcpPort}/mcp`
|
|
199
|
+
};
|
|
200
|
+
added = true;
|
|
301
201
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
try {
|
|
310
|
-
const nextjsDevCommand = tool.addHttpMcpCommand(MCP_NAMES.NEXTJS_DEV, `http://localhost:${appPort}/_next/mcp`);
|
|
311
|
-
await new Promise((resolve, reject) => {
|
|
312
|
-
const configProcess = spawn(nextjsDevCommand[0], nextjsDevCommand.slice(1), {
|
|
313
|
-
stdio: ["inherit", "pipe", "pipe"]
|
|
314
|
-
});
|
|
315
|
-
let errorOutput = "";
|
|
316
|
-
configProcess.stderr?.on("data", (data) => {
|
|
317
|
-
errorOutput += data.toString();
|
|
318
|
-
});
|
|
319
|
-
configProcess.on("close", (code) => {
|
|
320
|
-
if (code === 0 || errorOutput.includes("already exists")) {
|
|
321
|
-
results.nextjsDev = true;
|
|
322
|
-
resolve();
|
|
323
|
-
}
|
|
324
|
-
else {
|
|
325
|
-
reject(new Error(`Failed to configure nextjs-dev MCP: ${errorOutput}`));
|
|
326
|
-
}
|
|
327
|
-
});
|
|
328
|
-
configProcess.on("error", reject);
|
|
329
|
-
});
|
|
202
|
+
// Add chrome-devtools MCP server if enabled (stdio - no type needed)
|
|
203
|
+
if (enableChromeDevtools && !settings.mcpServers[MCP_NAMES.CHROME_DEVTOOLS]) {
|
|
204
|
+
settings.mcpServers[MCP_NAMES.CHROME_DEVTOOLS] = {
|
|
205
|
+
command: "npx",
|
|
206
|
+
args: ["chrome-devtools-mcp@latest", "--browserUrl", "http://127.0.0.1:9222"]
|
|
207
|
+
};
|
|
208
|
+
added = true;
|
|
330
209
|
}
|
|
331
|
-
|
|
332
|
-
|
|
210
|
+
// Add nextjs-dev MCP server if enabled (HTTP type - connects to Next.js dev server)
|
|
211
|
+
if (enableNextjsMcp && !settings.mcpServers[MCP_NAMES.NEXTJS_DEV]) {
|
|
212
|
+
settings.mcpServers[MCP_NAMES.NEXTJS_DEV] = {
|
|
213
|
+
type: "http",
|
|
214
|
+
url: `http://localhost:${appPort}/_next/mcp`
|
|
215
|
+
};
|
|
216
|
+
added = true;
|
|
217
|
+
}
|
|
218
|
+
// Write if we added anything
|
|
219
|
+
if (added) {
|
|
220
|
+
writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
|
|
333
221
|
}
|
|
334
222
|
}
|
|
335
|
-
|
|
223
|
+
catch (_error) {
|
|
224
|
+
// Ignore errors - settings file manipulation is optional
|
|
225
|
+
}
|
|
336
226
|
}
|
|
337
227
|
/**
|
|
338
|
-
*
|
|
228
|
+
* Ensure MCP server configurations are added to project's .cursor/mcp.json
|
|
339
229
|
*/
|
|
340
|
-
async function
|
|
341
|
-
// Clean up dev3000 MCP (fire and forget)
|
|
230
|
+
async function ensureCursorMcpServers(mcpPort, appPort, enableChromeDevtools, enableNextjsMcp) {
|
|
342
231
|
try {
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
try {
|
|
355
|
-
const chromeDevtoolsCommand = tool.removeMcpCommand(MCP_NAMES.CHROME_DEVTOOLS);
|
|
356
|
-
spawn(chromeDevtoolsCommand[0], chromeDevtoolsCommand.slice(1), {
|
|
357
|
-
stdio: "ignore",
|
|
358
|
-
detached: true
|
|
359
|
-
}).unref();
|
|
232
|
+
const cursorDir = join(process.cwd(), ".cursor");
|
|
233
|
+
const settingsPath = join(cursorDir, "mcp.json");
|
|
234
|
+
// Ensure .cursor directory exists
|
|
235
|
+
if (!existsSync(cursorDir)) {
|
|
236
|
+
mkdirSync(cursorDir, { recursive: true });
|
|
237
|
+
}
|
|
238
|
+
// Read or create settings
|
|
239
|
+
let settings;
|
|
240
|
+
if (existsSync(settingsPath)) {
|
|
241
|
+
const settingsContent = readFileSync(settingsPath, "utf-8");
|
|
242
|
+
settings = JSON.parse(settingsContent);
|
|
360
243
|
}
|
|
361
|
-
|
|
362
|
-
|
|
244
|
+
else {
|
|
245
|
+
settings = {};
|
|
246
|
+
}
|
|
247
|
+
// Ensure mcpServers structure exists
|
|
248
|
+
if (!settings.mcpServers) {
|
|
249
|
+
settings.mcpServers = {};
|
|
250
|
+
}
|
|
251
|
+
let added = false;
|
|
252
|
+
// Add dev3000 MCP server
|
|
253
|
+
if (!settings.mcpServers[MCP_NAMES.DEV3000]) {
|
|
254
|
+
settings.mcpServers[MCP_NAMES.DEV3000] = {
|
|
255
|
+
type: "http",
|
|
256
|
+
url: `http://localhost:${mcpPort}/mcp`
|
|
257
|
+
};
|
|
258
|
+
added = true;
|
|
363
259
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
detached: true
|
|
372
|
-
}).unref();
|
|
260
|
+
// Add chrome-devtools MCP server if enabled
|
|
261
|
+
if (enableChromeDevtools && !settings.mcpServers[MCP_NAMES.CHROME_DEVTOOLS]) {
|
|
262
|
+
settings.mcpServers[MCP_NAMES.CHROME_DEVTOOLS] = {
|
|
263
|
+
command: "npx",
|
|
264
|
+
args: ["chrome-devtools-mcp@latest", "--browserUrl", "http://127.0.0.1:9222"]
|
|
265
|
+
};
|
|
266
|
+
added = true;
|
|
373
267
|
}
|
|
374
|
-
|
|
375
|
-
|
|
268
|
+
// Add nextjs-dev MCP server if enabled (HTTP type - connects to Next.js dev server)
|
|
269
|
+
if (enableNextjsMcp && !settings.mcpServers[MCP_NAMES.NEXTJS_DEV]) {
|
|
270
|
+
settings.mcpServers[MCP_NAMES.NEXTJS_DEV] = {
|
|
271
|
+
type: "http",
|
|
272
|
+
url: `http://localhost:${appPort}/_next/mcp`
|
|
273
|
+
};
|
|
274
|
+
added = true;
|
|
376
275
|
}
|
|
276
|
+
// Write if we added anything
|
|
277
|
+
if (added) {
|
|
278
|
+
writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
catch (_error) {
|
|
282
|
+
// Ignore errors - settings file manipulation is optional
|
|
377
283
|
}
|
|
378
284
|
}
|
|
379
285
|
/**
|
|
380
|
-
*
|
|
286
|
+
* Clean up MCP server configurations from project's .cursor/mcp.json
|
|
381
287
|
*/
|
|
382
|
-
async function
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
288
|
+
async function cleanupCursorMcpServers(enableChromeDevtools, enableNextjsMcp) {
|
|
289
|
+
try {
|
|
290
|
+
const settingsPath = join(process.cwd(), ".cursor", "mcp.json");
|
|
291
|
+
// Check if file exists
|
|
292
|
+
if (!existsSync(settingsPath)) {
|
|
293
|
+
return; // No settings file to clean up
|
|
294
|
+
}
|
|
295
|
+
// Read current settings
|
|
296
|
+
const settingsContent = readFileSync(settingsPath, "utf-8");
|
|
297
|
+
const settings = JSON.parse(settingsContent);
|
|
298
|
+
// Ensure mcpServers structure exists
|
|
299
|
+
if (!settings.mcpServers) {
|
|
300
|
+
return; // No MCP servers to clean up
|
|
301
|
+
}
|
|
302
|
+
let removed = false;
|
|
303
|
+
// Remove dev3000 MCP server
|
|
304
|
+
if (settings.mcpServers[MCP_NAMES.DEV3000]) {
|
|
305
|
+
delete settings.mcpServers[MCP_NAMES.DEV3000];
|
|
306
|
+
removed = true;
|
|
307
|
+
}
|
|
308
|
+
// Remove chrome-devtools MCP server if it was enabled
|
|
309
|
+
if (enableChromeDevtools && settings.mcpServers[MCP_NAMES.CHROME_DEVTOOLS]) {
|
|
310
|
+
delete settings.mcpServers[MCP_NAMES.CHROME_DEVTOOLS];
|
|
311
|
+
removed = true;
|
|
312
|
+
}
|
|
313
|
+
// Remove nextjs-dev MCP server if it was enabled
|
|
314
|
+
if (enableNextjsMcp && settings.mcpServers[MCP_NAMES.NEXTJS_DEV]) {
|
|
315
|
+
delete settings.mcpServers[MCP_NAMES.NEXTJS_DEV];
|
|
316
|
+
removed = true;
|
|
317
|
+
}
|
|
318
|
+
// Only write if we actually removed something
|
|
319
|
+
if (removed) {
|
|
320
|
+
writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
|
|
399
321
|
}
|
|
400
322
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
if (enableNextjsMcp && !silent) {
|
|
404
|
-
console.log("🔍 Next.js MCP server detected in project configuration");
|
|
405
|
-
}
|
|
406
|
-
if (!silent)
|
|
407
|
-
console.log(`🔧 Configuring MCPs for ${availableTools.length} detected AI CLI tools...`);
|
|
408
|
-
for (const tool of availableTools) {
|
|
409
|
-
if (!silent)
|
|
410
|
-
console.log(` Configuring ${tool.name}...`);
|
|
411
|
-
const results = await configureMcpsForCliTool(tool, mcpPort, appPort, enableChromeDevtools, chromeDevtoolsSupported, enableNextjsMcp);
|
|
412
|
-
let status = "";
|
|
413
|
-
if (results.dev3000)
|
|
414
|
-
status += "✅ dev3000";
|
|
415
|
-
if (results.chromeDevtools)
|
|
416
|
-
status += results.dev3000 ? " + chrome-devtools" : "✅ chrome-devtools";
|
|
417
|
-
if (results.nextjsDev)
|
|
418
|
-
status += results.dev3000 || results.chromeDevtools ? " + nextjs-dev" : "✅ nextjs-dev";
|
|
419
|
-
if (results.chromeSkipped)
|
|
420
|
-
status +=
|
|
421
|
-
results.dev3000 || results.nextjsDev
|
|
422
|
-
? ` (chrome-devtools skipped: ${results.chromeSkipped})`
|
|
423
|
-
: `⚠️ chrome-devtools skipped: ${results.chromeSkipped}`;
|
|
424
|
-
if (!results.dev3000 && !results.chromeDevtools && !results.nextjsDev && !results.chromeSkipped)
|
|
425
|
-
status = "❌ failed";
|
|
426
|
-
if (!silent)
|
|
427
|
-
console.log(` ${tool.name}: ${status}`);
|
|
323
|
+
catch (_error) {
|
|
324
|
+
// Ignore cleanup errors
|
|
428
325
|
}
|
|
429
|
-
return availableTools;
|
|
430
326
|
}
|
|
431
327
|
/**
|
|
432
|
-
* Clean up MCP configurations
|
|
328
|
+
* Clean up MCP server configurations from project's .mcp.json (Claude Code)
|
|
433
329
|
*/
|
|
434
|
-
async function
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
330
|
+
async function cleanupMcpServers(enableChromeDevtools, enableNextjsMcp) {
|
|
331
|
+
try {
|
|
332
|
+
const settingsPath = join(process.cwd(), ".mcp.json");
|
|
333
|
+
// Check if file exists
|
|
334
|
+
if (!existsSync(settingsPath)) {
|
|
335
|
+
return; // No settings file to clean up
|
|
336
|
+
}
|
|
337
|
+
// Read current settings
|
|
338
|
+
const settingsContent = readFileSync(settingsPath, "utf-8");
|
|
339
|
+
const settings = JSON.parse(settingsContent);
|
|
340
|
+
// Ensure mcpServers structure exists
|
|
341
|
+
if (!settings.mcpServers) {
|
|
342
|
+
return; // No MCP servers to clean up
|
|
343
|
+
}
|
|
344
|
+
let removed = false;
|
|
345
|
+
// Remove dev3000 MCP server
|
|
346
|
+
if (settings.mcpServers[MCP_NAMES.DEV3000]) {
|
|
347
|
+
delete settings.mcpServers[MCP_NAMES.DEV3000];
|
|
348
|
+
removed = true;
|
|
349
|
+
}
|
|
350
|
+
// Remove chrome-devtools MCP server if it was enabled
|
|
351
|
+
if (enableChromeDevtools && settings.mcpServers[MCP_NAMES.CHROME_DEVTOOLS]) {
|
|
352
|
+
delete settings.mcpServers[MCP_NAMES.CHROME_DEVTOOLS];
|
|
353
|
+
removed = true;
|
|
354
|
+
}
|
|
355
|
+
// Remove nextjs-dev MCP server if it was enabled
|
|
356
|
+
if (enableNextjsMcp && settings.mcpServers[MCP_NAMES.NEXTJS_DEV]) {
|
|
357
|
+
delete settings.mcpServers[MCP_NAMES.NEXTJS_DEV];
|
|
358
|
+
removed = true;
|
|
359
|
+
}
|
|
360
|
+
// Only write if we actually removed something
|
|
361
|
+
if (removed) {
|
|
362
|
+
writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
catch (_error) {
|
|
366
|
+
// Ignore cleanup errors
|
|
441
367
|
}
|
|
442
368
|
}
|
|
443
369
|
export function createPersistentLogFile() {
|
|
@@ -562,8 +488,8 @@ export class DevEnvironment {
|
|
|
562
488
|
tui = null;
|
|
563
489
|
portChangeMessage = null;
|
|
564
490
|
firstSigintTime = null;
|
|
565
|
-
configuredAiCliTools = [];
|
|
566
491
|
enableNextjsMcp = false;
|
|
492
|
+
chromeDevtoolsSupported = false;
|
|
567
493
|
constructor(options) {
|
|
568
494
|
// Handle portMcp vs mcpPort naming
|
|
569
495
|
this.options = {
|
|
@@ -762,9 +688,7 @@ export class DevEnvironment {
|
|
|
762
688
|
async start() {
|
|
763
689
|
// Check if TUI mode is enabled (default)
|
|
764
690
|
if (this.options.tui) {
|
|
765
|
-
//
|
|
766
|
-
await this.checkPortsAvailable(true); // silent mode for TUI
|
|
767
|
-
// Clear console and start TUI
|
|
691
|
+
// Clear console and start TUI immediately for fast render
|
|
768
692
|
console.clear();
|
|
769
693
|
// Get unique project name
|
|
770
694
|
const projectName = getProjectName();
|
|
@@ -781,7 +705,12 @@ export class DevEnvironment {
|
|
|
781
705
|
});
|
|
782
706
|
await this.tui.start();
|
|
783
707
|
// Give TUI a moment to fully initialize
|
|
784
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
708
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
709
|
+
// Check ports in background after TUI is visible
|
|
710
|
+
await this.tui.updateStatus("Checking ports...");
|
|
711
|
+
await this.checkPortsAvailable(true); // silent mode for TUI
|
|
712
|
+
// Update the app port in TUI (may have changed during port check)
|
|
713
|
+
this.tui.updateAppPort(this.options.port);
|
|
785
714
|
// Show port change message if needed
|
|
786
715
|
if (this.portChangeMessage) {
|
|
787
716
|
await this.tui.updateStatus(this.portChangeMessage);
|
|
@@ -818,15 +747,17 @@ export class DevEnvironment {
|
|
|
818
747
|
await this.tui.updateStatus("Configuring AI CLI integrations...");
|
|
819
748
|
// Check if NextJS MCP is enabled and store the result
|
|
820
749
|
this.enableNextjsMcp = await isNextjsMcpEnabled();
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
else {
|
|
828
|
-
this.logD3K("AI CLI Integration: No AI CLIs detected, manual configuration will be needed");
|
|
750
|
+
// Check if Chrome version supports chrome-devtools MCP
|
|
751
|
+
if (this.options.chromeDevtoolsMcp !== false) {
|
|
752
|
+
this.chromeDevtoolsSupported = await isChromeDevtoolsMcpSupported();
|
|
753
|
+
if (!this.chromeDevtoolsSupported) {
|
|
754
|
+
this.logD3K("Chrome version < 140.0.7339.214 detected - chrome-devtools MCP will be skipped");
|
|
755
|
+
}
|
|
829
756
|
}
|
|
757
|
+
// Ensure MCP server configurations in project settings files (instant, local)
|
|
758
|
+
await ensureMcpServers(this.options.mcpPort || "3684", this.options.port, this.chromeDevtoolsSupported, this.enableNextjsMcp);
|
|
759
|
+
await ensureCursorMcpServers(this.options.mcpPort || "3684", this.options.port, this.chromeDevtoolsSupported, this.enableNextjsMcp);
|
|
760
|
+
this.logD3K(`AI CLI Integration: Configured MCP servers in .mcp.json and .cursor/mcp.json`);
|
|
830
761
|
}
|
|
831
762
|
// Start CDP monitoring if not in servers-only mode
|
|
832
763
|
if (!this.options.serversOnly) {
|
|
@@ -875,15 +806,17 @@ export class DevEnvironment {
|
|
|
875
806
|
this.spinner.text = "Configuring AI CLI integrations...";
|
|
876
807
|
// Check if NextJS MCP is enabled and store the result
|
|
877
808
|
this.enableNextjsMcp = await isNextjsMcpEnabled();
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
else {
|
|
885
|
-
this.logD3K("AI CLI Integration: No AI CLIs detected, manual configuration will be needed");
|
|
809
|
+
// Check if Chrome version supports chrome-devtools MCP
|
|
810
|
+
if (this.options.chromeDevtoolsMcp !== false) {
|
|
811
|
+
this.chromeDevtoolsSupported = await isChromeDevtoolsMcpSupported();
|
|
812
|
+
if (!this.chromeDevtoolsSupported) {
|
|
813
|
+
this.logD3K("Chrome version < 140.0.7339.214 detected - chrome-devtools MCP will be skipped");
|
|
814
|
+
}
|
|
886
815
|
}
|
|
816
|
+
// Ensure MCP server configurations in project settings files (instant, local)
|
|
817
|
+
await ensureMcpServers(this.options.mcpPort || "3684", this.options.port, this.chromeDevtoolsSupported, this.enableNextjsMcp);
|
|
818
|
+
await ensureCursorMcpServers(this.options.mcpPort || "3684", this.options.port, this.chromeDevtoolsSupported, this.enableNextjsMcp);
|
|
819
|
+
this.logD3K(`AI CLI Integration: Configured MCP servers in .mcp.json and .cursor/mcp.json`);
|
|
887
820
|
}
|
|
888
821
|
// Start CDP monitoring if not in servers-only mode
|
|
889
822
|
if (!this.options.serversOnly) {
|
|
@@ -1055,7 +988,7 @@ export class DevEnvironment {
|
|
|
1055
988
|
}
|
|
1056
989
|
}
|
|
1057
990
|
console.log(chalk.cyan(`\n📄 Full logs: ${this.options.logFile}`));
|
|
1058
|
-
console.log(chalk.cyan(` Quick access: tail -f
|
|
991
|
+
console.log(chalk.cyan(` Quick access: tail -f ${this.options.logFile}`));
|
|
1059
992
|
}
|
|
1060
993
|
catch (_error) {
|
|
1061
994
|
// Fallback if we can't read the log file
|
|
@@ -1839,7 +1772,8 @@ export class DevEnvironment {
|
|
|
1839
1772
|
}
|
|
1840
1773
|
}
|
|
1841
1774
|
console.log(chalk.red(`❌ ${this.options.commandName} exited due to server failure`));
|
|
1842
|
-
|
|
1775
|
+
const projectName = getProjectName();
|
|
1776
|
+
console.log(chalk.yellow(`Check the logs at ~/.d3k/logs/dev3000-${projectName}-d3k.log for errors. Feeling like helping? Run dev3000 --debug and file an issue at https://github.com/vercel-labs/dev3000/issues`));
|
|
1843
1777
|
process.exit(1);
|
|
1844
1778
|
}
|
|
1845
1779
|
setupCleanupHandlers() {
|
|
@@ -1978,10 +1912,9 @@ export class DevEnvironment {
|
|
|
1978
1912
|
}
|
|
1979
1913
|
}
|
|
1980
1914
|
}
|
|
1981
|
-
// Clean up
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
}
|
|
1915
|
+
// Clean up MCP server configurations from project settings files (instant)
|
|
1916
|
+
await cleanupMcpServers(this.chromeDevtoolsSupported, this.enableNextjsMcp);
|
|
1917
|
+
await cleanupCursorMcpServers(this.chromeDevtoolsSupported, this.enableNextjsMcp);
|
|
1985
1918
|
// Kill processes on both ports
|
|
1986
1919
|
const killPortProcess = async (port, name) => {
|
|
1987
1920
|
try {
|