dev3000 0.0.90 → 0.0.91

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 (25) hide show
  1. package/dist/dev-environment.d.ts.map +1 -1
  2. package/dist/dev-environment.js +8 -7
  3. package/dist/dev-environment.js.map +1 -1
  4. package/mcp-server/.next/BUILD_ID +1 -1
  5. package/mcp-server/.next/build-manifest.json +2 -2
  6. package/mcp-server/.next/fallback-build-manifest.json +2 -2
  7. package/mcp-server/.next/prerender-manifest.json +3 -3
  8. package/mcp-server/.next/server/app/_global-error.html +2 -2
  9. package/mcp-server/.next/server/app/_global-error.rsc +1 -1
  10. package/mcp-server/.next/server/app/_not-found.html +1 -1
  11. package/mcp-server/.next/server/app/_not-found.rsc +1 -1
  12. package/mcp-server/.next/server/app/index.html +1 -1
  13. package/mcp-server/.next/server/app/index.rsc +1 -1
  14. package/mcp-server/.next/server/chunks/[root-of-the-server]__ae49815f._.js +50 -12
  15. package/mcp-server/.next/server/chunks/[root-of-the-server]__ae49815f._.js.map +1 -1
  16. package/mcp-server/.next/server/chunks/[root-of-the-server]__dc0b0022._.js +1 -1
  17. package/mcp-server/.next/server/chunks/[root-of-the-server]__dc0b0022._.js.map +1 -1
  18. package/mcp-server/.next/server/server-reference-manifest.js +1 -1
  19. package/mcp-server/.next/server/server-reference-manifest.json +1 -1
  20. package/mcp-server/app/mcp/route.ts +13 -1
  21. package/mcp-server/app/mcp/tools.ts +215 -2
  22. package/package.json +1 -1
  23. /package/mcp-server/.next/static/{XC8IdMzOP-R6sszO2tUlu → eVL_05d0pOH_qw2twMoct}/_buildManifest.js +0 -0
  24. /package/mcp-server/.next/static/{XC8IdMzOP-R6sszO2tUlu → eVL_05d0pOH_qw2twMoct}/_clientMiddlewareManifest.json +0 -0
  25. /package/mcp-server/.next/static/{XC8IdMzOP-R6sszO2tUlu → eVL_05d0pOH_qw2twMoct}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- self.__RSC_SERVER_MANIFEST="{\n \"node\": {},\n \"edge\": {},\n \"encryptionKey\": \"coTPdU0svpRNodp0Rw8CHLLSd/s45e/rD4kkbrVURd0=\"\n}"
1
+ self.__RSC_SERVER_MANIFEST="{\n \"node\": {},\n \"edge\": {},\n \"encryptionKey\": \"mkpbqeA8hbQBwumcGof8mtazY/m9j2lVb+4otV6eSo0=\"\n}"
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "node": {},
3
3
  "edge": {},
4
- "encryptionKey": "coTPdU0svpRNodp0Rw8CHLLSd/s45e/rD4kkbrVURd0="
4
+ "encryptionKey": "mkpbqeA8hbQBwumcGof8mtazY/m9j2lVb+4otV6eSo0="
5
5
  }
@@ -4,7 +4,7 @@ import { join } from "node:path"
4
4
  import { createMcpHandler } from "mcp-handler"
5
5
  import { z } from "zod"
6
6
  import { getMCPClientManager } from "./client-manager"
7
- import { executeBrowserAction, findComponentSource, fixMyApp, TOOL_DESCRIPTIONS } from "./tools"
7
+ import { executeBrowserAction, findComponentSource, fixMyApp, restartDevServer, TOOL_DESCRIPTIONS } from "./tools"
8
8
 
9
9
  // Detect available package runner (npx, pnpm dlx, or fail)
10
10
  const getPackageRunner = (): { command: string; args: string[] } | null => {
@@ -285,6 +285,18 @@ const handler = createMcpHandler(
285
285
  }
286
286
  )
287
287
 
288
+ // Dev server restart tool
289
+ server.tool(
290
+ "restart_dev_server",
291
+ TOOL_DESCRIPTIONS.restart_dev_server,
292
+ {
293
+ projectName: z.string().optional().describe("Project name (if multiple dev3000 instances are running)")
294
+ },
295
+ async (params) => {
296
+ return restartDevServer(params)
297
+ }
298
+ )
299
+
288
300
  // Tool that returns monitoring code for Claude to execute
289
301
  // TODO: Commenting out for now - need to figure out the right approach for proactive monitoring
290
302
  /*
@@ -1,4 +1,4 @@
1
- import { exec } from "child_process"
1
+ import { exec, spawn } from "child_process"
2
2
  import { appendFileSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync } from "fs"
3
3
  import { homedir, tmpdir } from "os"
4
4
  import { join } from "path"
@@ -21,7 +21,10 @@ export const TOOL_DESCRIPTIONS = {
21
21
  "🔍 **VISUAL DIFF ANALYZER** - Analyzes two screenshots to identify and describe visual differences. Returns detailed instructions for Claude to load and compare the images, focusing on what changed that could cause layout shifts.\n\n🎯 **WHAT IT PROVIDES:**\n• Direct instructions to load both images via Read tool\n• Context about what to look for\n• Guidance on identifying layout shift causes\n• Structured format for easy analysis\n\n💡 **PERFECT FOR:** Understanding what visual changes occurred between before/after frames in CLS detection, identifying elements that appeared/moved/resized.",
22
22
 
23
23
  find_component_source:
24
- "🔍 **COMPONENT SOURCE FINDER** - Maps DOM elements to their source code by extracting the React component function and finding unique patterns to search for.\n\n🎯 **HOW IT WORKS:**\n• Inspects the element via Chrome DevTools Protocol\n• Extracts the React component function source using .toString()\n• Identifies unique code patterns (specific JSX, classNames, imports)\n• Returns targeted grep patterns to find the exact source file\n\n💡 **PERFECT FOR:** Finding which file contains the code for a specific element, especially useful for CLS debugging when you need to fix layout shifts in specific components."
24
+ "🔍 **COMPONENT SOURCE FINDER** - Maps DOM elements to their source code by extracting the React component function and finding unique patterns to search for.\n\n🎯 **HOW IT WORKS:**\n• Inspects the element via Chrome DevTools Protocol\n• Extracts the React component function source using .toString()\n• Identifies unique code patterns (specific JSX, classNames, imports)\n• Returns targeted grep patterns to find the exact source file\n\n💡 **PERFECT FOR:** Finding which file contains the code for a specific element, especially useful for CLS debugging when you need to fix layout shifts in specific components.",
25
+
26
+ restart_dev_server:
27
+ "🔄 **DEV SERVER RESTART** - Safely restarts the development server while preserving dev3000's monitoring, logs, and browser connection.\n\n🎯 **SMART RESTART LOGIC:**\n• First tries nextjs-dev MCP restart (if available and user has Next.js canary)\n• Falls back to dev3000's own restart mechanism:\n - Kills the old server process on the app port\n - Waits for clean shutdown\n - Spawns a new server with the same command that was originally used\n - Keeps dev3000's MCP server, browser monitoring, and screenshot capture running\n• All logging continues seamlessly - no data loss\n• Browser monitoring stays connected - no need to relaunch Chrome\n\n⚡ **WHEN TO USE:**\n• After modifying next.config.js, middleware, or environment variables\n• When you need a clean restart to clear server state\n• After significant code changes that Next.js HMR can't handle\n• When debugging persistent state or memory issues\n\n⚠️ **CRITICAL - DO NOT:**\n• ❌ NEVER manually run kill commands on the dev server like `pkill -f \"next dev\"` or `lsof -ti :3000 | xargs kill`\n• ❌ NEVER manually start the dev server with `npm run dev`, `pnpm dev`, `next dev`, etc.\n• ✅ ALWAYS use this tool for dev server restarts - it preserves all dev3000 infrastructure\n\n⚠️ **IMPORTANT:**\n• AVOID using this unnecessarily - Next.js HMR handles most changes automatically\n• Only restart when truly needed for config changes or state issues\n• The server will be offline for a few seconds during restart\n• Browser may show connection error briefly while server restarts\n\n💡 **PERFECT FOR:** 'restart the dev server', 'clean restart', 'reload the server' - but only when actually needed, not for regular code changes."
25
28
  }
26
29
 
27
30
  // Types
@@ -3266,3 +3269,213 @@ export async function findComponentSource(params: {
3266
3269
  }
3267
3270
  }
3268
3271
  }
3272
+
3273
+ /**
3274
+ * Restart the development server while preserving logs and monitoring
3275
+ */
3276
+ export async function restartDevServer(params: {
3277
+ projectName?: string
3278
+ }): Promise<{ content: Array<{ type: "text"; text: string }> }> {
3279
+ const { projectName } = params
3280
+
3281
+ try {
3282
+ // Find active session
3283
+ const sessions = findActiveSessions()
3284
+ if (sessions.length === 0) {
3285
+ return {
3286
+ content: [
3287
+ {
3288
+ type: "text",
3289
+ text: "❌ **NO ACTIVE SESSIONS**\n\nNo active dev3000 sessions found. Make sure your app is running with dev3000."
3290
+ }
3291
+ ]
3292
+ }
3293
+ }
3294
+
3295
+ // Use specified project or first available session
3296
+ let targetSession = sessions[0]
3297
+ if (projectName) {
3298
+ const found = sessions.find((s) => s.projectName === projectName)
3299
+ if (found) {
3300
+ targetSession = found
3301
+ }
3302
+ }
3303
+
3304
+ const sessionData = JSON.parse(readFileSync(targetSession.sessionFile, "utf-8"))
3305
+ const appPort = sessionData.appPort
3306
+ const serverCommand = sessionData.serverCommand
3307
+ const cwd = sessionData.cwd
3308
+
3309
+ if (!appPort) {
3310
+ return {
3311
+ content: [
3312
+ {
3313
+ type: "text",
3314
+ text: "❌ **NO APP PORT FOUND**\n\nSession file doesn't contain app port information."
3315
+ }
3316
+ ]
3317
+ }
3318
+ }
3319
+
3320
+ if (!serverCommand) {
3321
+ return {
3322
+ content: [
3323
+ {
3324
+ type: "text",
3325
+ text: "❌ **NO SERVER COMMAND FOUND**\n\nSession file doesn't contain the original server command. This session may have been created with an older version of dev3000."
3326
+ }
3327
+ ]
3328
+ }
3329
+ }
3330
+
3331
+ logToDevFile(
3332
+ `Restart Dev Server: Starting restart for project [${targetSession.projectName}] on port ${appPort} with command [${serverCommand}]`
3333
+ )
3334
+
3335
+ // Check if nextjs-dev MCP is available
3336
+ const availableMcps = await discoverAvailableMcps(targetSession.projectName)
3337
+ const hasNextjsDev = availableMcps.includes("nextjs-dev")
3338
+
3339
+ logToDevFile(`Restart Dev Server: Has nextjs-dev MCP: ${hasNextjsDev}`)
3340
+
3341
+ // Try nextjs-dev MCP first if available
3342
+ if (hasNextjsDev) {
3343
+ try {
3344
+ logToDevFile("Restart Dev Server: Attempting to use nextjs-dev MCP restart")
3345
+
3346
+ // Check if nextjs-dev has restart capability
3347
+ const capabilities = await getMcpCapabilities({ mcpName: "nextjs-dev" })
3348
+ const capabilitiesText =
3349
+ capabilities.content[0] && "text" in capabilities.content[0] ? capabilities.content[0].text : ""
3350
+
3351
+ if (capabilitiesText.includes("restart") || capabilitiesText.includes("reload")) {
3352
+ logToDevFile("Restart Dev Server: nextjs-dev MCP has restart capability, delegating")
3353
+
3354
+ return {
3355
+ content: [
3356
+ {
3357
+ type: "text",
3358
+ text: "✅ **DELEGATING TO NEXTJS-DEV MCP**\n\nThe nextjs-dev MCP has restart capabilities. Please use the nextjs-dev MCP restart tool directly for better integration with Next.js."
3359
+ }
3360
+ ]
3361
+ }
3362
+ }
3363
+
3364
+ logToDevFile("Restart Dev Server: nextjs-dev MCP doesn't have restart capability, falling back")
3365
+ } catch (error) {
3366
+ logToDevFile(`Restart Dev Server: Failed to check nextjs-dev capabilities - ${error}`)
3367
+ }
3368
+ }
3369
+
3370
+ // Fallback: Use dev3000's own restart mechanism
3371
+ logToDevFile("Restart Dev Server: Using dev3000 restart mechanism")
3372
+
3373
+ // Kill processes on the app port
3374
+ const killCommand = `lsof -ti :${appPort} | xargs kill 2>/dev/null || true`
3375
+ logToDevFile(`Restart Dev Server: Executing kill command: ${killCommand}`)
3376
+
3377
+ try {
3378
+ await execAsync(killCommand)
3379
+ logToDevFile("Restart Dev Server: Kill command executed successfully")
3380
+ } catch (error) {
3381
+ logToDevFile(`Restart Dev Server: Kill command failed (may be ok) - ${error}`)
3382
+ }
3383
+
3384
+ // Wait for clean shutdown
3385
+ await new Promise((resolve) => setTimeout(resolve, 2000))
3386
+
3387
+ // Check if port is now free
3388
+ const checkCommand = `lsof -ti :${appPort}`
3389
+ let portFree = false
3390
+ try {
3391
+ const { stdout } = await execAsync(checkCommand)
3392
+ portFree = stdout.trim() === ""
3393
+ logToDevFile(`Restart Dev Server: Port check result - free: ${portFree}`)
3394
+ } catch {
3395
+ // Command failed means no process on port (port is free)
3396
+ portFree = true
3397
+ logToDevFile("Restart Dev Server: Port is free (lsof returned no results)")
3398
+ }
3399
+
3400
+ if (!portFree) {
3401
+ return {
3402
+ content: [
3403
+ {
3404
+ type: "text",
3405
+ text: `⚠️ **PORT STILL IN USE**\n\nFailed to free port ${appPort}. There may be a process that couldn't be killed.\n\nTry manually killing the process:\n\`\`\`bash\nlsof -ti :${appPort} | xargs kill -9\n\`\`\``
3406
+ }
3407
+ ]
3408
+ }
3409
+ }
3410
+
3411
+ logToDevFile("Restart Dev Server: Port is now free, spawning new server process")
3412
+
3413
+ // Spawn new server process
3414
+ try {
3415
+ const serverProcess = spawn(serverCommand, {
3416
+ stdio: "inherit", // Inherit stdio so output goes to dev3000's logs
3417
+ shell: true,
3418
+ detached: true, // Run independently
3419
+ cwd: cwd || process.cwd() // Use original working directory
3420
+ })
3421
+
3422
+ // Unref so this process doesn't keep MCP server alive
3423
+ serverProcess.unref()
3424
+
3425
+ logToDevFile(`Restart Dev Server: Spawned new server process with PID ${serverProcess.pid}`)
3426
+
3427
+ // Wait a moment for server to start
3428
+ await new Promise((resolve) => setTimeout(resolve, 1000))
3429
+
3430
+ // Check if server is actually running on the port
3431
+ try {
3432
+ const { stdout: checkResult } = await execAsync(`lsof -ti :${appPort}`)
3433
+ const isRunning = checkResult.trim() !== ""
3434
+
3435
+ if (isRunning) {
3436
+ logToDevFile("Restart Dev Server: Server successfully restarted and running on port")
3437
+ return {
3438
+ content: [
3439
+ {
3440
+ type: "text",
3441
+ text: `✅ **DEV SERVER RESTARTED**\n\nSuccessfully restarted the development server on port ${appPort}.\n\n🎯 **STATUS:**\n• Old server process: Killed\n• New server process: Running (PID ${serverProcess.pid})\n• Port ${appPort}: Active\n• Browser monitoring: Unchanged\n• Logs: Still being captured\n\n💡 The server has been restarted while keeping dev3000's monitoring, screenshots, and logging intact.`
3442
+ }
3443
+ ]
3444
+ }
3445
+ }
3446
+ logToDevFile("Restart Dev Server: Server process spawned but not yet listening on port (may still be starting)")
3447
+ } catch {
3448
+ logToDevFile("Restart Dev Server: Server process spawned but not yet listening on port (may still be starting)")
3449
+ }
3450
+
3451
+ return {
3452
+ content: [
3453
+ {
3454
+ type: "text",
3455
+ text: `🔄 **DEV SERVER RESTARTING**\n\nStarted a new server process (PID ${serverProcess.pid}).\n\n⏳ **STATUS:**\n• Old server: Killed\n• New server: Starting (may take a few moments)\n• Command: \`${serverCommand}\`\n• Port: ${appPort}\n\nThe server is restarting. Check the dev3000 logs to see when it's ready.`
3456
+ }
3457
+ ]
3458
+ }
3459
+ } catch (spawnError) {
3460
+ logToDevFile(`Restart Dev Server: Failed to spawn new server process - ${spawnError}`)
3461
+ return {
3462
+ content: [
3463
+ {
3464
+ type: "text",
3465
+ text: `❌ **RESTART FAILED**\n\nFailed to start new server process.\n\n**Error:** ${spawnError instanceof Error ? spawnError.message : String(spawnError)}\n\n**Command:** \`${serverCommand}\`\n\nThe old server was killed but the new one failed to start. You may need to manually restart dev3000.`
3466
+ }
3467
+ ]
3468
+ }
3469
+ }
3470
+ } catch (error) {
3471
+ logToDevFile(`Restart Dev Server: Error - ${error}`)
3472
+ return {
3473
+ content: [
3474
+ {
3475
+ type: "text",
3476
+ text: `❌ **ERROR**\n\n${error instanceof Error ? error.message : String(error)}`
3477
+ }
3478
+ ]
3479
+ }
3480
+ }
3481
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dev3000",
3
- "version": "0.0.90",
3
+ "version": "0.0.91",
4
4
  "description": "AI-powered development tools with browser monitoring and MCP server integration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",