dev3000 0.0.76 → 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.
Files changed (40) hide show
  1. package/README.md +107 -27
  2. package/dist/cdp-monitor.d.ts.map +1 -1
  3. package/dist/cdp-monitor.js +33 -10
  4. package/dist/cdp-monitor.js.map +1 -1
  5. package/dist/dev-environment.d.ts +1 -1
  6. package/dist/dev-environment.d.ts.map +1 -1
  7. package/dist/dev-environment.js +201 -268
  8. package/dist/dev-environment.js.map +1 -1
  9. package/dist/src/tui-interface-impl.tsx +110 -59
  10. package/dist/tui-interface-impl.d.ts +1 -0
  11. package/dist/tui-interface-impl.d.ts.map +1 -1
  12. package/dist/tui-interface-impl.js +63 -14
  13. package/dist/tui-interface-impl.js.map +1 -1
  14. package/dist/tui-interface.d.ts +2 -0
  15. package/dist/tui-interface.d.ts.map +1 -1
  16. package/dist/tui-interface.js +8 -1
  17. package/dist/tui-interface.js.map +1 -1
  18. package/mcp-server/.next/BUILD_ID +1 -1
  19. package/mcp-server/.next/build-manifest.json +2 -2
  20. package/mcp-server/.next/fallback-build-manifest.json +2 -2
  21. package/mcp-server/.next/prerender-manifest.json +3 -3
  22. package/mcp-server/.next/server/app/_global-error.html +2 -2
  23. package/mcp-server/.next/server/app/_global-error.rsc +1 -1
  24. package/mcp-server/.next/server/app/_not-found.html +1 -1
  25. package/mcp-server/.next/server/app/_not-found.rsc +1 -1
  26. package/mcp-server/.next/server/app/index.html +1 -1
  27. package/mcp-server/.next/server/app/index.rsc +1 -1
  28. package/mcp-server/.next/server/chunks/[root-of-the-server]__270b33b7._.js +13 -23
  29. package/mcp-server/.next/server/chunks/[root-of-the-server]__270b33b7._.js.map +1 -1
  30. package/mcp-server/.next/server/chunks/ssr/_62451611._.js.map +1 -1
  31. package/mcp-server/.next/server/chunks/ssr/_b15f05ee._.js.map +1 -1
  32. package/mcp-server/.next/server/server-reference-manifest.js +1 -1
  33. package/mcp-server/.next/server/server-reference-manifest.json +1 -1
  34. package/mcp-server/app/mcp/tools.ts +686 -151
  35. package/mcp-server/package.json +0 -6
  36. package/package.json +7 -1
  37. package/src/tui-interface-impl.tsx +110 -59
  38. /package/mcp-server/.next/static/{SDKkQ5XdHwJr8jB5PJj7F → GE4QeOWMVNF-ly63PtQFE}/_buildManifest.js +0 -0
  39. /package/mcp-server/.next/static/{SDKkQ5XdHwJr8jB5PJj7F → GE4QeOWMVNF-ly63PtQFE}/_clientMiddlewareManifest.json +0 -0
  40. /package/mcp-server/.next/static/{SDKkQ5XdHwJr8jB5PJj7F → GE4QeOWMVNF-ly63PtQFE}/_ssgManifest.js +0 -0
@@ -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
- * Detect which AI CLI tools are available on the system
175
+ * Ensure MCP server configurations are added to project's .mcp.json (Claude Code)
207
176
  */
208
- async function detectAvailableAiCliTools() {
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 dev3000Command = tool.addHttpMcpCommand(MCP_NAMES.DEV3000, `http://localhost:${mcpPort}/mcp`);
252
- await new Promise((resolve, reject) => {
253
- const configProcess = spawn(dev3000Command[0], dev3000Command.slice(1), {
254
- stdio: ["inherit", "pipe", "pipe"]
255
- });
256
- let errorOutput = "";
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
- catch (error) {
300
- console.log(`⚠️ Failed to configure chrome-devtools MCP for ${tool.name}:`, error);
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
- else if (enableChromeDevtools && !chromeDevtoolsSupported) {
304
- // Chrome version doesn't support chrome-devtools MCP
305
- results.chromeSkipped = "Chrome < 140.0.7339.214";
306
- }
307
- // Configure nextjs-dev MCP if enabled
308
- if (enableNextjsMcp) {
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
- catch (error) {
332
- console.log(`⚠️ Failed to configure nextjs-dev MCP for ${tool.name}:`, error);
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
- return results;
223
+ catch (_error) {
224
+ // Ignore errors - settings file manipulation is optional
225
+ }
336
226
  }
337
227
  /**
338
- * Clean up MCP configurations for a specific AI CLI tool
228
+ * Ensure MCP server configurations are added to project's .cursor/mcp.json
339
229
  */
340
- async function cleanupMcpsForCliTool(tool, enableChromeDevtools, enableNextjsMcp) {
341
- // Clean up dev3000 MCP (fire and forget)
230
+ async function ensureCursorMcpServers(mcpPort, appPort, enableChromeDevtools, enableNextjsMcp) {
342
231
  try {
343
- const dev3000Command = tool.removeMcpCommand(MCP_NAMES.DEV3000);
344
- spawn(dev3000Command[0], dev3000Command.slice(1), {
345
- stdio: "ignore",
346
- detached: true
347
- }).unref();
348
- }
349
- catch {
350
- // Ignore cleanup errors
351
- }
352
- // Clean up chrome-devtools MCP if it was enabled (fire and forget)
353
- if (enableChromeDevtools) {
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
- catch {
362
- // Ignore cleanup errors
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
- // Clean up nextjs-dev MCP if it was enabled (fire and forget)
366
- if (enableNextjsMcp) {
367
- try {
368
- const nextjsDevCommand = tool.removeMcpCommand(MCP_NAMES.NEXTJS_DEV);
369
- spawn(nextjsDevCommand[0], nextjsDevCommand.slice(1), {
370
- stdio: "ignore",
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
- catch {
375
- // Ignore cleanup errors
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
- * Configure MCPs for all detected AI CLI tools
286
+ * Clean up MCP server configurations from project's .cursor/mcp.json
381
287
  */
382
- async function configureAiCliIntegrations(mcpPort, appPort, enableChromeDevtools, silent = false) {
383
- if (!silent)
384
- console.log("🔍 Detecting available AI CLI tools...");
385
- const availableTools = await detectAvailableAiCliTools();
386
- if (availableTools.length === 0) {
387
- if (!silent)
388
- console.log("📝 No AI CLI tools detected - dev3000 will work when CLIs are installed later");
389
- return [];
390
- }
391
- // Check Chrome version if chrome-devtools MCP is requested
392
- let chromeDevtoolsSupported = false;
393
- if (enableChromeDevtools) {
394
- if (!silent)
395
- console.log("🔍 Checking Chrome version for chrome-devtools MCP compatibility...");
396
- chromeDevtoolsSupported = await isChromeDevtoolsMcpSupported();
397
- if (!chromeDevtoolsSupported && !silent) {
398
- console.log("⚠️ Chrome version < 140.0.7339.214 detected - chrome-devtools MCP will be skipped");
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
- // Check if NextJS MCP is enabled in project configuration
402
- const enableNextjsMcp = await isNextjsMcpEnabled();
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 for all detected AI CLI tools
328
+ * Clean up MCP server configurations from project's .mcp.json (Claude Code)
433
329
  */
434
- async function cleanupAiCliIntegrations(availableTools, enableChromeDevtools, enableNextjsMcp, silent = false) {
435
- if (availableTools.length === 0)
436
- return;
437
- if (!silent)
438
- console.log("🧹 Cleaning up AI CLI MCP configurations...");
439
- for (const tool of availableTools) {
440
- cleanupMcpsForCliTool(tool, enableChromeDevtools, enableNextjsMcp); // Fire and forget
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
- // Check ports BEFORE starting TUI to avoid console output conflicts
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, 200));
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
- this.configuredAiCliTools = await configureAiCliIntegrations(this.options.mcpPort || "3684", this.options.port, this.options.chromeDevtoolsMcp !== false, // Default to true unless explicitly disabled
822
- true // Silent mode when TUI is active
823
- );
824
- if (this.configuredAiCliTools.length > 0) {
825
- this.logD3K(`AI CLI Integration: Configured ${this.configuredAiCliTools.length} AI CLI tools for seamless dev3000 access`);
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
- this.configuredAiCliTools = await configureAiCliIntegrations(this.options.mcpPort || "3684", this.options.port, this.options.chromeDevtoolsMcp !== false, // Default to true unless explicitly disabled
879
- false // Show output in non-TUI mode
880
- );
881
- if (this.configuredAiCliTools.length > 0) {
882
- this.logD3K(`AI CLI Integration: Configured ${this.configuredAiCliTools.length} AI CLI tools for seamless dev3000 access`);
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 /tmp/d3k.log`));
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
- console.log(chalk.yellow("Check the logs at ~/.d3k/d3k.log for errors. Feeling like helping? Run dev3000 --debug and file an issue at https://github.com/vercel-labs/dev3000/issues"));
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 AI CLI MCP configurations
1982
- if (this.configuredAiCliTools.length > 0) {
1983
- await cleanupAiCliIntegrations(this.configuredAiCliTools, this.options.chromeDevtoolsMcp !== false, this.enableNextjsMcp, this.options.tui);
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 {