dev3000 0.0.77 ā 0.0.79
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 +2 -1
- package/dist/dev-environment.d.ts.map +1 -1
- package/dist/dev-environment.js +230 -271
- package/dist/dev-environment.js.map +1 -1
- package/dist/screencast-manager.d.ts +76 -0
- package/dist/screencast-manager.d.ts.map +1 -0
- package/dist/screencast-manager.js +410 -0
- package/dist/screencast-manager.js.map +1 -0
- package/dist/src/tui-interface-impl.tsx +45 -14
- 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 +24 -7
- 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/app-path-routes-manifest.json +4 -1
- package/mcp-server/.next/build-manifest.json +5 -5
- package/mcp-server/.next/fallback-build-manifest.json +2 -2
- package/mcp-server/.next/prerender-manifest.json +3 -3
- package/mcp-server/.next/routes-manifest.json +16 -0
- package/mcp-server/.next/server/app/_global-error/page/build-manifest.json +3 -3
- package/mcp-server/.next/server/app/_global-error/page.js +1 -1
- package/mcp-server/.next/server/app/_global-error/page.js.nft.json +1 -1
- 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/page/build-manifest.json +3 -3
- package/mcp-server/.next/server/app/_not-found/page.js +1 -1
- package/mcp-server/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/mcp-server/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/mcp-server/.next/server/app/_not-found.html +1 -1
- package/mcp-server/.next/server/app/_not-found.rsc +2 -2
- package/mcp-server/.next/server/app/api/jank/[session]/route/app-paths-manifest.json +3 -0
- package/mcp-server/.next/server/app/api/jank/[session]/route/build-manifest.json +11 -0
- package/mcp-server/.next/server/app/api/jank/[session]/route/server-reference-manifest.json +4 -0
- package/mcp-server/.next/server/app/api/jank/[session]/route.js +9 -0
- package/mcp-server/.next/server/app/api/jank/[session]/route.js.map +5 -0
- package/mcp-server/.next/server/app/api/jank/[session]/route.js.nft.json +1 -0
- package/mcp-server/.next/server/app/api/jank/[session]/route_client-reference-manifest.js +2 -0
- package/mcp-server/.next/server/app/api/logs/head/route.js.nft.json +1 -1
- package/mcp-server/.next/server/app/api/logs/list/route.js.nft.json +1 -1
- package/mcp-server/.next/server/app/api/logs/rotate/route.js +1 -1
- package/mcp-server/.next/server/app/api/logs/rotate/route.js.nft.json +1 -1
- package/mcp-server/.next/server/app/api/logs/stream/route.js.nft.json +1 -1
- package/mcp-server/.next/server/app/api/logs/tail/route.js.nft.json +1 -1
- package/mcp-server/.next/server/app/api/screenshots/[filename]/route.js +1 -1
- package/mcp-server/.next/server/app/api/screenshots/[filename]/route.js.nft.json +1 -1
- package/mcp-server/.next/server/app/api/screenshots/list/route/app-paths-manifest.json +3 -0
- package/mcp-server/.next/server/app/api/screenshots/list/route/build-manifest.json +11 -0
- package/mcp-server/.next/server/app/api/screenshots/list/route/server-reference-manifest.json +4 -0
- package/mcp-server/.next/server/app/api/screenshots/list/route.js +7 -0
- package/mcp-server/.next/server/app/api/screenshots/list/route.js.map +5 -0
- package/mcp-server/.next/server/app/api/screenshots/list/route.js.nft.json +1 -0
- package/mcp-server/.next/server/app/api/screenshots/list/route_client-reference-manifest.js +2 -0
- package/mcp-server/.next/server/app/api/tools/route.js +1 -1
- package/mcp-server/.next/server/app/api/tools/route.js.nft.json +1 -1
- package/mcp-server/.next/server/app/index.html +1 -1
- package/mcp-server/.next/server/app/index.rsc +3 -3
- package/mcp-server/.next/server/app/logs/page/build-manifest.json +3 -3
- package/mcp-server/.next/server/app/logs/page.js +1 -1
- package/mcp-server/.next/server/app/logs/page.js.nft.json +1 -1
- package/mcp-server/.next/server/app/logs/page_client-reference-manifest.js +1 -1
- package/mcp-server/.next/server/app/mcp/route.js +3 -2
- package/mcp-server/.next/server/app/mcp/route.js.nft.json +1 -1
- package/mcp-server/.next/server/app/page/build-manifest.json +3 -3
- package/mcp-server/.next/server/app/page.js +1 -1
- package/mcp-server/.next/server/app/page.js.nft.json +1 -1
- package/mcp-server/.next/server/app/page_client-reference-manifest.js +1 -1
- package/mcp-server/.next/server/app/video/[session]/page/app-paths-manifest.json +3 -0
- package/mcp-server/.next/server/app/video/[session]/page/build-manifest.json +18 -0
- package/mcp-server/.next/server/app/video/[session]/page/next-font-manifest.json +6 -0
- package/mcp-server/.next/server/app/video/[session]/page/react-loadable-manifest.json +1 -0
- package/mcp-server/.next/server/app/video/[session]/page/server-reference-manifest.json +4 -0
- package/mcp-server/.next/server/app/video/[session]/page.js +15 -0
- package/mcp-server/.next/server/app/video/[session]/page.js.map +5 -0
- package/mcp-server/.next/server/app/video/[session]/page.js.nft.json +1 -0
- package/mcp-server/.next/server/app/video/[session]/page_client-reference-manifest.js +2 -0
- package/mcp-server/.next/server/app-paths-manifest.json +4 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__00592d3f._.js +34 -0
- package/mcp-server/.next/server/chunks/[root-of-the-server]__00592d3f._.js.map +1 -0
- package/mcp-server/.next/server/chunks/{[root-of-the-server]__5580d2ea._.js ā [root-of-the-server]__177c72c6._.js} +3 -3
- package/mcp-server/.next/server/chunks/[root-of-the-server]__177c72c6._.js.map +1 -0
- package/mcp-server/.next/server/chunks/{[root-of-the-server]__ffb73672._.js ā [root-of-the-server]__2056c8b5._.js} +2 -2
- package/mcp-server/.next/server/chunks/{[root-of-the-server]__d1f9e389._.js ā [root-of-the-server]__55c04517._.js} +2 -2
- package/mcp-server/.next/server/chunks/[root-of-the-server]__6ee9a99f._.js +3 -0
- package/mcp-server/.next/server/chunks/[root-of-the-server]__6ee9a99f._.js.map +1 -0
- package/mcp-server/.next/server/chunks/[root-of-the-server]__9a45c8f9._.js +3 -0
- package/mcp-server/.next/server/chunks/[root-of-the-server]__9a45c8f9._.js.map +1 -0
- package/mcp-server/.next/server/chunks/{[root-of-the-server]__e2089993._.js ā [root-of-the-server]__bc773251._.js} +2 -2
- package/mcp-server/.next/server/chunks/[root-of-the-server]__e1a64519._.js +3 -0
- package/mcp-server/.next/server/chunks/[root-of-the-server]__e1a64519._.js.map +1 -0
- package/mcp-server/.next/server/chunks/[root-of-the-server]__e6dcd8bf._.js +3 -0
- package/mcp-server/.next/server/chunks/[root-of-the-server]__e6dcd8bf._.js.map +1 -0
- package/mcp-server/.next/server/chunks/d1d76_next_dist_esm_build_templates_app-route_820fc951.js +3 -0
- package/mcp-server/.next/server/chunks/d1d76_next_dist_esm_build_templates_app-route_820fc951.js.map +1 -0
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_jank_[session]_route_actions_3b2b275b.js +3 -0
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_jank_[session]_route_actions_3b2b275b.js.map +1 -0
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_screenshots_list_route_actions_acfa57bd.js +3 -0
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_screenshots_list_route_actions_acfa57bd.js.map +1 -0
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__bf771f7e._.js +3 -0
- package/mcp-server/.next/server/chunks/ssr/{[root-of-the-server]__8db775f9._.js.map ā [root-of-the-server]__bf771f7e._.js.map} +1 -1
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__c4e78a20._.js +3 -0
- package/mcp-server/.next/server/chunks/ssr/{[root-of-the-server]__e5dec879._.js.map ā [root-of-the-server]__c4e78a20._.js.map} +1 -1
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__e1bc1b8a._.js +3 -0
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__e1bc1b8a._.js.map +1 -0
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__fc10c8f1._.js +3 -0
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__fc10c8f1._.js.map +1 -0
- package/mcp-server/.next/server/chunks/ssr/_0b8335fc._.js +1 -1
- package/mcp-server/.next/server/chunks/ssr/_0b8335fc._.js.map +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/chunks/ssr/_bacf0748._.js +2 -2
- package/mcp-server/.next/server/chunks/ssr/_bacf0748._.js.map +1 -1
- package/mcp-server/.next/server/chunks/ssr/_e4aa8f16._.js +4 -0
- package/mcp-server/.next/server/chunks/ssr/_e4aa8f16._.js.map +1 -0
- package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app_video_[session]_page_actions_a6aab323.js +3 -0
- package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app_video_[session]_page_actions_a6aab323.js.map +1 -0
- package/mcp-server/.next/server/middleware-build-manifest.js +3 -3
- 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/.next/static/chunks/274a8d03fad7f819.js +1 -0
- package/mcp-server/.next/static/chunks/3d37ed424c6aaf63.css +1 -0
- package/mcp-server/.next/static/chunks/543e14c771a22442.js +1 -0
- package/mcp-server/.next/static/chunks/58fdd5192b305065.js +1 -0
- package/mcp-server/.next/static/chunks/6bd684c2018a357c.js +1 -0
- package/mcp-server/.next/static/chunks/6d59e588420330ca.js +1 -0
- package/mcp-server/.next/static/chunks/9625e4da85a132f3.js +1 -0
- package/mcp-server/.next/static/chunks/c36bc797d535a4dc.js +1 -0
- package/mcp-server/.next/static/chunks/{turbopack-7cd5a898ed038e26.js ā turbopack-9656e7304584cab2.js} +2 -2
- package/mcp-server/app/api/jank/[session]/route.ts +344 -0
- package/mcp-server/app/api/screenshots/list/route.ts +22 -0
- package/mcp-server/app/logs/LogsClient.tsx +33 -0
- package/mcp-server/app/logs/utils.ts +2 -0
- package/mcp-server/app/mcp/route.ts +20 -0
- package/mcp-server/app/mcp/tools.ts +288 -9
- package/mcp-server/app/video/[session]/page.tsx +237 -0
- package/mcp-server/package.json +4 -6
- package/package.json +7 -1
- package/src/tui-interface-impl.tsx +45 -14
- package/mcp-server/.next/server/chunks/[root-of-the-server]__270b33b7._.js +0 -34
- package/mcp-server/.next/server/chunks/[root-of-the-server]__270b33b7._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__5580d2ea._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__8db775f9._.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__e5dec879._.js +0 -3
- package/mcp-server/.next/static/chunks/11ac0d0e69696c72.js +0 -1
- package/mcp-server/.next/static/chunks/172f6179d608c15f.js +0 -1
- package/mcp-server/.next/static/chunks/65b18bf1ede9811a.css +0 -1
- package/mcp-server/.next/static/chunks/bb8a4e5f381a85ec.js +0 -1
- package/mcp-server/.next/static/chunks/e09be78bba2194fd.js +0 -1
- package/mcp-server/.next/static/chunks/fec3a6ddaef02b8b.js +0 -1
- /package/mcp-server/.next/server/chunks/{[root-of-the-server]__ffb73672._.js.map ā [root-of-the-server]__2056c8b5._.js.map} +0 -0
- /package/mcp-server/.next/server/chunks/{[root-of-the-server]__d1f9e389._.js.map ā [root-of-the-server]__55c04517._.js.map} +0 -0
- /package/mcp-server/.next/server/chunks/{[root-of-the-server]__e2089993._.js.map ā [root-of-the-server]__bc773251._.js.map} +0 -0
- /package/mcp-server/.next/static/{NWQx_KX68gOo5fDkdXq6G ā T9qI0it_H-9Z-TE5_ROut}/_buildManifest.js +0 -0
- /package/mcp-server/.next/static/{NWQx_KX68gOo5fDkdXq6G ā T9qI0it_H-9Z-TE5_ROut}/_clientMiddlewareManifest.json +0 -0
- /package/mcp-server/.next/static/{NWQx_KX68gOo5fDkdXq6G ā T9qI0it_H-9Z-TE5_ROut}/_ssgManifest.js +0 -0
package/dist/dev-environment.js
CHANGED
|
@@ -6,6 +6,7 @@ import { homedir, tmpdir } from "os";
|
|
|
6
6
|
import { dirname, join } from "path";
|
|
7
7
|
import { fileURLToPath } from "url";
|
|
8
8
|
import { CDPMonitor } from "./cdp-monitor.js";
|
|
9
|
+
import { ScreencastManager } from "./screencast-manager.js";
|
|
9
10
|
import { NextJsErrorDetector, OutputProcessor, StandardLogParser } from "./services/parsers/index.js";
|
|
10
11
|
import { DevTUI } from "./tui-interface.js";
|
|
11
12
|
import { getProjectDisplayName, getProjectName } from "./utils/project-name.js";
|
|
@@ -77,37 +78,6 @@ async function findAvailablePort(startPort) {
|
|
|
77
78
|
}
|
|
78
79
|
throw new Error(`No available ports found starting from ${startPort}`);
|
|
79
80
|
}
|
|
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
81
|
/**
|
|
112
82
|
* Check if Next.js MCP server is enabled in the project configuration
|
|
113
83
|
*/
|
|
@@ -203,241 +173,198 @@ async function isChromeDevtoolsMcpSupported() {
|
|
|
203
173
|
}
|
|
204
174
|
}
|
|
205
175
|
/**
|
|
206
|
-
*
|
|
207
|
-
*/
|
|
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
|
|
176
|
+
* Ensure MCP server configurations are added to project's .mcp.json (Claude Code)
|
|
242
177
|
*/
|
|
243
|
-
async function
|
|
244
|
-
const results = {
|
|
245
|
-
dev3000: false,
|
|
246
|
-
chromeDevtools: false,
|
|
247
|
-
nextjsDev: false
|
|
248
|
-
};
|
|
249
|
-
// Configure main dev3000 MCP
|
|
178
|
+
async function ensureMcpServers(mcpPort, appPort, enableChromeDevtools, enableNextjsMcp) {
|
|
250
179
|
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
|
-
});
|
|
180
|
+
const settingsPath = join(process.cwd(), ".mcp.json");
|
|
181
|
+
// Read or create settings
|
|
182
|
+
let settings;
|
|
183
|
+
if (existsSync(settingsPath)) {
|
|
184
|
+
const settingsContent = readFileSync(settingsPath, "utf-8");
|
|
185
|
+
settings = JSON.parse(settingsContent);
|
|
298
186
|
}
|
|
299
|
-
|
|
300
|
-
|
|
187
|
+
else {
|
|
188
|
+
settings = {};
|
|
189
|
+
}
|
|
190
|
+
// Ensure mcpServers structure exists
|
|
191
|
+
if (!settings.mcpServers) {
|
|
192
|
+
settings.mcpServers = {};
|
|
193
|
+
}
|
|
194
|
+
let added = false;
|
|
195
|
+
// Add dev3000 MCP server (HTTP type)
|
|
196
|
+
if (!settings.mcpServers[MCP_NAMES.DEV3000]) {
|
|
197
|
+
settings.mcpServers[MCP_NAMES.DEV3000] = {
|
|
198
|
+
type: "http",
|
|
199
|
+
url: `http://localhost:${mcpPort}/mcp`
|
|
200
|
+
};
|
|
201
|
+
added = true;
|
|
301
202
|
}
|
|
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
|
-
});
|
|
203
|
+
// Add chrome-devtools MCP server if enabled (stdio - no type needed)
|
|
204
|
+
if (enableChromeDevtools && !settings.mcpServers[MCP_NAMES.CHROME_DEVTOOLS]) {
|
|
205
|
+
settings.mcpServers[MCP_NAMES.CHROME_DEVTOOLS] = {
|
|
206
|
+
command: "npx",
|
|
207
|
+
args: ["chrome-devtools-mcp@latest", "--browserUrl", "http://127.0.0.1:9222"]
|
|
208
|
+
};
|
|
209
|
+
added = true;
|
|
330
210
|
}
|
|
331
|
-
|
|
332
|
-
|
|
211
|
+
// Add nextjs-dev MCP server if enabled (HTTP type - connects to Next.js dev server)
|
|
212
|
+
if (enableNextjsMcp && !settings.mcpServers[MCP_NAMES.NEXTJS_DEV]) {
|
|
213
|
+
settings.mcpServers[MCP_NAMES.NEXTJS_DEV] = {
|
|
214
|
+
type: "http",
|
|
215
|
+
url: `http://localhost:${appPort}/_next/mcp`
|
|
216
|
+
};
|
|
217
|
+
added = true;
|
|
218
|
+
}
|
|
219
|
+
// Write if we added anything
|
|
220
|
+
if (added) {
|
|
221
|
+
writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
|
|
333
222
|
}
|
|
334
223
|
}
|
|
335
|
-
|
|
224
|
+
catch (_error) {
|
|
225
|
+
// Ignore errors - settings file manipulation is optional
|
|
226
|
+
}
|
|
336
227
|
}
|
|
337
228
|
/**
|
|
338
|
-
*
|
|
229
|
+
* Ensure MCP server configurations are added to project's .cursor/mcp.json
|
|
339
230
|
*/
|
|
340
|
-
async function
|
|
341
|
-
// Clean up dev3000 MCP (fire and forget)
|
|
231
|
+
async function ensureCursorMcpServers(mcpPort, appPort, enableChromeDevtools, enableNextjsMcp) {
|
|
342
232
|
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();
|
|
233
|
+
const cursorDir = join(process.cwd(), ".cursor");
|
|
234
|
+
const settingsPath = join(cursorDir, "mcp.json");
|
|
235
|
+
// Ensure .cursor directory exists
|
|
236
|
+
if (!existsSync(cursorDir)) {
|
|
237
|
+
mkdirSync(cursorDir, { recursive: true });
|
|
238
|
+
}
|
|
239
|
+
// Read or create settings
|
|
240
|
+
let settings;
|
|
241
|
+
if (existsSync(settingsPath)) {
|
|
242
|
+
const settingsContent = readFileSync(settingsPath, "utf-8");
|
|
243
|
+
settings = JSON.parse(settingsContent);
|
|
360
244
|
}
|
|
361
|
-
|
|
362
|
-
|
|
245
|
+
else {
|
|
246
|
+
settings = {};
|
|
247
|
+
}
|
|
248
|
+
// Ensure mcpServers structure exists
|
|
249
|
+
if (!settings.mcpServers) {
|
|
250
|
+
settings.mcpServers = {};
|
|
251
|
+
}
|
|
252
|
+
let added = false;
|
|
253
|
+
// Add dev3000 MCP server
|
|
254
|
+
if (!settings.mcpServers[MCP_NAMES.DEV3000]) {
|
|
255
|
+
settings.mcpServers[MCP_NAMES.DEV3000] = {
|
|
256
|
+
type: "http",
|
|
257
|
+
url: `http://localhost:${mcpPort}/mcp`
|
|
258
|
+
};
|
|
259
|
+
added = true;
|
|
363
260
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
detached: true
|
|
372
|
-
}).unref();
|
|
261
|
+
// Add chrome-devtools MCP server if enabled
|
|
262
|
+
if (enableChromeDevtools && !settings.mcpServers[MCP_NAMES.CHROME_DEVTOOLS]) {
|
|
263
|
+
settings.mcpServers[MCP_NAMES.CHROME_DEVTOOLS] = {
|
|
264
|
+
command: "npx",
|
|
265
|
+
args: ["chrome-devtools-mcp@latest", "--browserUrl", "http://127.0.0.1:9222"]
|
|
266
|
+
};
|
|
267
|
+
added = true;
|
|
373
268
|
}
|
|
374
|
-
|
|
375
|
-
|
|
269
|
+
// Add nextjs-dev MCP server if enabled (HTTP type - connects to Next.js dev server)
|
|
270
|
+
if (enableNextjsMcp && !settings.mcpServers[MCP_NAMES.NEXTJS_DEV]) {
|
|
271
|
+
settings.mcpServers[MCP_NAMES.NEXTJS_DEV] = {
|
|
272
|
+
type: "http",
|
|
273
|
+
url: `http://localhost:${appPort}/_next/mcp`
|
|
274
|
+
};
|
|
275
|
+
added = true;
|
|
276
|
+
}
|
|
277
|
+
// Write if we added anything
|
|
278
|
+
if (added) {
|
|
279
|
+
writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
|
|
376
280
|
}
|
|
377
281
|
}
|
|
282
|
+
catch (_error) {
|
|
283
|
+
// Ignore errors - settings file manipulation is optional
|
|
284
|
+
}
|
|
378
285
|
}
|
|
379
286
|
/**
|
|
380
|
-
*
|
|
287
|
+
* Clean up MCP server configurations from project's .cursor/mcp.json
|
|
381
288
|
*/
|
|
382
|
-
async function
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
289
|
+
async function cleanupCursorMcpServers(enableChromeDevtools, enableNextjsMcp) {
|
|
290
|
+
try {
|
|
291
|
+
const settingsPath = join(process.cwd(), ".cursor", "mcp.json");
|
|
292
|
+
// Check if file exists
|
|
293
|
+
if (!existsSync(settingsPath)) {
|
|
294
|
+
return; // No settings file to clean up
|
|
295
|
+
}
|
|
296
|
+
// Read current settings
|
|
297
|
+
const settingsContent = readFileSync(settingsPath, "utf-8");
|
|
298
|
+
const settings = JSON.parse(settingsContent);
|
|
299
|
+
// Ensure mcpServers structure exists
|
|
300
|
+
if (!settings.mcpServers) {
|
|
301
|
+
return; // No MCP servers to clean up
|
|
302
|
+
}
|
|
303
|
+
let removed = false;
|
|
304
|
+
// Remove dev3000 MCP server
|
|
305
|
+
if (settings.mcpServers[MCP_NAMES.DEV3000]) {
|
|
306
|
+
delete settings.mcpServers[MCP_NAMES.DEV3000];
|
|
307
|
+
removed = true;
|
|
308
|
+
}
|
|
309
|
+
// Remove chrome-devtools MCP server if it was enabled
|
|
310
|
+
if (enableChromeDevtools && settings.mcpServers[MCP_NAMES.CHROME_DEVTOOLS]) {
|
|
311
|
+
delete settings.mcpServers[MCP_NAMES.CHROME_DEVTOOLS];
|
|
312
|
+
removed = true;
|
|
313
|
+
}
|
|
314
|
+
// Remove nextjs-dev MCP server if it was enabled
|
|
315
|
+
if (enableNextjsMcp && settings.mcpServers[MCP_NAMES.NEXTJS_DEV]) {
|
|
316
|
+
delete settings.mcpServers[MCP_NAMES.NEXTJS_DEV];
|
|
317
|
+
removed = true;
|
|
318
|
+
}
|
|
319
|
+
// Only write if we actually removed something
|
|
320
|
+
if (removed) {
|
|
321
|
+
writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
|
|
399
322
|
}
|
|
400
323
|
}
|
|
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}`);
|
|
324
|
+
catch (_error) {
|
|
325
|
+
// Ignore cleanup errors
|
|
428
326
|
}
|
|
429
|
-
return availableTools;
|
|
430
327
|
}
|
|
431
328
|
/**
|
|
432
|
-
* Clean up MCP configurations
|
|
329
|
+
* Clean up MCP server configurations from project's .mcp.json (Claude Code)
|
|
433
330
|
*/
|
|
434
|
-
async function
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
331
|
+
async function cleanupMcpServers(enableChromeDevtools, enableNextjsMcp) {
|
|
332
|
+
try {
|
|
333
|
+
const settingsPath = join(process.cwd(), ".mcp.json");
|
|
334
|
+
// Check if file exists
|
|
335
|
+
if (!existsSync(settingsPath)) {
|
|
336
|
+
return; // No settings file to clean up
|
|
337
|
+
}
|
|
338
|
+
// Read current settings
|
|
339
|
+
const settingsContent = readFileSync(settingsPath, "utf-8");
|
|
340
|
+
const settings = JSON.parse(settingsContent);
|
|
341
|
+
// Ensure mcpServers structure exists
|
|
342
|
+
if (!settings.mcpServers) {
|
|
343
|
+
return; // No MCP servers to clean up
|
|
344
|
+
}
|
|
345
|
+
let removed = false;
|
|
346
|
+
// Remove dev3000 MCP server
|
|
347
|
+
if (settings.mcpServers[MCP_NAMES.DEV3000]) {
|
|
348
|
+
delete settings.mcpServers[MCP_NAMES.DEV3000];
|
|
349
|
+
removed = true;
|
|
350
|
+
}
|
|
351
|
+
// Remove chrome-devtools MCP server if it was enabled
|
|
352
|
+
if (enableChromeDevtools && settings.mcpServers[MCP_NAMES.CHROME_DEVTOOLS]) {
|
|
353
|
+
delete settings.mcpServers[MCP_NAMES.CHROME_DEVTOOLS];
|
|
354
|
+
removed = true;
|
|
355
|
+
}
|
|
356
|
+
// Remove nextjs-dev MCP server if it was enabled
|
|
357
|
+
if (enableNextjsMcp && settings.mcpServers[MCP_NAMES.NEXTJS_DEV]) {
|
|
358
|
+
delete settings.mcpServers[MCP_NAMES.NEXTJS_DEV];
|
|
359
|
+
removed = true;
|
|
360
|
+
}
|
|
361
|
+
// Only write if we actually removed something
|
|
362
|
+
if (removed) {
|
|
363
|
+
writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
catch (_error) {
|
|
367
|
+
// Ignore cleanup errors
|
|
441
368
|
}
|
|
442
369
|
}
|
|
443
370
|
export function createPersistentLogFile() {
|
|
@@ -548,6 +475,7 @@ export class DevEnvironment {
|
|
|
548
475
|
serverProcess = null;
|
|
549
476
|
mcpServerProcess = null;
|
|
550
477
|
cdpMonitor = null;
|
|
478
|
+
screencastManager = null;
|
|
551
479
|
logger;
|
|
552
480
|
outputProcessor;
|
|
553
481
|
options;
|
|
@@ -562,8 +490,8 @@ export class DevEnvironment {
|
|
|
562
490
|
tui = null;
|
|
563
491
|
portChangeMessage = null;
|
|
564
492
|
firstSigintTime = null;
|
|
565
|
-
configuredAiCliTools = [];
|
|
566
493
|
enableNextjsMcp = false;
|
|
494
|
+
chromeDevtoolsSupported = false;
|
|
567
495
|
constructor(options) {
|
|
568
496
|
// Handle portMcp vs mcpPort naming
|
|
569
497
|
this.options = {
|
|
@@ -762,9 +690,7 @@ export class DevEnvironment {
|
|
|
762
690
|
async start() {
|
|
763
691
|
// Check if TUI mode is enabled (default)
|
|
764
692
|
if (this.options.tui) {
|
|
765
|
-
//
|
|
766
|
-
await this.checkPortsAvailable(true); // silent mode for TUI
|
|
767
|
-
// Clear console and start TUI
|
|
693
|
+
// Clear console and start TUI immediately for fast render
|
|
768
694
|
console.clear();
|
|
769
695
|
// Get unique project name
|
|
770
696
|
const projectName = getProjectName();
|
|
@@ -781,7 +707,12 @@ export class DevEnvironment {
|
|
|
781
707
|
});
|
|
782
708
|
await this.tui.start();
|
|
783
709
|
// Give TUI a moment to fully initialize
|
|
784
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
710
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
711
|
+
// Check ports in background after TUI is visible
|
|
712
|
+
await this.tui.updateStatus("Checking ports...");
|
|
713
|
+
await this.checkPortsAvailable(true); // silent mode for TUI
|
|
714
|
+
// Update the app port in TUI (may have changed during port check)
|
|
715
|
+
this.tui.updateAppPort(this.options.port);
|
|
785
716
|
// Show port change message if needed
|
|
786
717
|
if (this.portChangeMessage) {
|
|
787
718
|
await this.tui.updateStatus(this.portChangeMessage);
|
|
@@ -818,15 +749,17 @@ export class DevEnvironment {
|
|
|
818
749
|
await this.tui.updateStatus("Configuring AI CLI integrations...");
|
|
819
750
|
// Check if NextJS MCP is enabled and store the result
|
|
820
751
|
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");
|
|
752
|
+
// Check if Chrome version supports chrome-devtools MCP
|
|
753
|
+
if (this.options.chromeDevtoolsMcp !== false) {
|
|
754
|
+
this.chromeDevtoolsSupported = await isChromeDevtoolsMcpSupported();
|
|
755
|
+
if (!this.chromeDevtoolsSupported) {
|
|
756
|
+
this.logD3K("Chrome version < 140.0.7339.214 detected - chrome-devtools MCP will be skipped");
|
|
757
|
+
}
|
|
829
758
|
}
|
|
759
|
+
// Ensure MCP server configurations in project settings files (instant, local)
|
|
760
|
+
await ensureMcpServers(this.options.mcpPort || "3684", this.options.port, this.chromeDevtoolsSupported, this.enableNextjsMcp);
|
|
761
|
+
await ensureCursorMcpServers(this.options.mcpPort || "3684", this.options.port, this.chromeDevtoolsSupported, this.enableNextjsMcp);
|
|
762
|
+
this.logD3K(`AI CLI Integration: Configured MCP servers in .mcp.json and .cursor/mcp.json`);
|
|
830
763
|
}
|
|
831
764
|
// Start CDP monitoring if not in servers-only mode
|
|
832
765
|
if (!this.options.serversOnly) {
|
|
@@ -839,8 +772,10 @@ export class DevEnvironment {
|
|
|
839
772
|
else {
|
|
840
773
|
this.debugLog("Browser monitoring disabled via --servers-only flag");
|
|
841
774
|
}
|
|
842
|
-
// Write session info for MCP server discovery
|
|
843
|
-
|
|
775
|
+
// Write session info for MCP server discovery (include CDP URL if browser monitoring was started)
|
|
776
|
+
const cdpUrl = this.cdpMonitor?.getCdpUrl() || null;
|
|
777
|
+
const chromePids = this.cdpMonitor?.getChromePids() || [];
|
|
778
|
+
writeSessionInfo(projectName, this.options.logFile, this.options.port, this.options.mcpPort, cdpUrl, chromePids);
|
|
844
779
|
// Clear status - ready!
|
|
845
780
|
await this.tui.updateStatus(null);
|
|
846
781
|
}
|
|
@@ -875,15 +810,17 @@ export class DevEnvironment {
|
|
|
875
810
|
this.spinner.text = "Configuring AI CLI integrations...";
|
|
876
811
|
// Check if NextJS MCP is enabled and store the result
|
|
877
812
|
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");
|
|
813
|
+
// Check if Chrome version supports chrome-devtools MCP
|
|
814
|
+
if (this.options.chromeDevtoolsMcp !== false) {
|
|
815
|
+
this.chromeDevtoolsSupported = await isChromeDevtoolsMcpSupported();
|
|
816
|
+
if (!this.chromeDevtoolsSupported) {
|
|
817
|
+
this.logD3K("Chrome version < 140.0.7339.214 detected - chrome-devtools MCP will be skipped");
|
|
818
|
+
}
|
|
886
819
|
}
|
|
820
|
+
// Ensure MCP server configurations in project settings files (instant, local)
|
|
821
|
+
await ensureMcpServers(this.options.mcpPort || "3684", this.options.port, this.chromeDevtoolsSupported, this.enableNextjsMcp);
|
|
822
|
+
await ensureCursorMcpServers(this.options.mcpPort || "3684", this.options.port, this.chromeDevtoolsSupported, this.enableNextjsMcp);
|
|
823
|
+
this.logD3K(`AI CLI Integration: Configured MCP servers in .mcp.json and .cursor/mcp.json`);
|
|
887
824
|
}
|
|
888
825
|
// Start CDP monitoring if not in servers-only mode
|
|
889
826
|
if (!this.options.serversOnly) {
|
|
@@ -898,7 +835,10 @@ export class DevEnvironment {
|
|
|
898
835
|
}
|
|
899
836
|
// Get project name for session info and Visual Timeline URL
|
|
900
837
|
const projectName = getProjectName();
|
|
901
|
-
|
|
838
|
+
// Include CDP URL if browser monitoring was started
|
|
839
|
+
const cdpUrl = this.cdpMonitor?.getCdpUrl() || null;
|
|
840
|
+
const chromePids = this.cdpMonitor?.getChromePids() || [];
|
|
841
|
+
writeSessionInfo(projectName, this.options.logFile, this.options.port, this.options.mcpPort, cdpUrl, chromePids);
|
|
902
842
|
// Complete startup with success message only in non-TUI mode
|
|
903
843
|
this.spinner.succeed("Development environment ready!");
|
|
904
844
|
// Regular console output (when TUI is disabled with --no-tui)
|
|
@@ -1055,7 +995,7 @@ export class DevEnvironment {
|
|
|
1055
995
|
}
|
|
1056
996
|
}
|
|
1057
997
|
console.log(chalk.cyan(`\nš Full logs: ${this.options.logFile}`));
|
|
1058
|
-
console.log(chalk.cyan(` Quick access: tail -f
|
|
998
|
+
console.log(chalk.cyan(` Quick access: tail -f ${this.options.logFile}`));
|
|
1059
999
|
}
|
|
1060
1000
|
catch (_error) {
|
|
1061
1001
|
// Fallback if we can't read the log file
|
|
@@ -1762,6 +1702,20 @@ export class DevEnvironment {
|
|
|
1762
1702
|
const projectName = getProjectName();
|
|
1763
1703
|
const cdpUrl = this.cdpMonitor.getCdpUrl();
|
|
1764
1704
|
const chromePids = this.cdpMonitor.getChromePids();
|
|
1705
|
+
// Start screencast manager for automatic jank detection
|
|
1706
|
+
if (cdpUrl) {
|
|
1707
|
+
this.screencastManager = new ScreencastManager(cdpUrl, (msg) => {
|
|
1708
|
+
// Pass through [SCREENCAST] messages directly so they can be linkified in logs UI
|
|
1709
|
+
if (msg.includes("[SCREENCAST]")) {
|
|
1710
|
+
this.logger.log("browser", msg);
|
|
1711
|
+
}
|
|
1712
|
+
else {
|
|
1713
|
+
this.logger.log("browser", `[Screencast] ${msg}`);
|
|
1714
|
+
}
|
|
1715
|
+
}, this.options.port.toString());
|
|
1716
|
+
await this.screencastManager.start();
|
|
1717
|
+
this.logger.log("browser", "[Screencast] Auto-capture enabled for navigation events");
|
|
1718
|
+
}
|
|
1765
1719
|
if (cdpUrl || chromePids.length > 0) {
|
|
1766
1720
|
writeSessionInfo(projectName, this.options.logFile, this.options.port, this.options.mcpPort, cdpUrl || undefined, chromePids);
|
|
1767
1721
|
this.debugLog(`Updated session info with CDP URL: ${cdpUrl}, Chrome PIDs: [${chromePids.join(", ")}]`);
|
|
@@ -1782,6 +1736,11 @@ export class DevEnvironment {
|
|
|
1782
1736
|
this.isShuttingDown = true;
|
|
1783
1737
|
// Stop health monitoring
|
|
1784
1738
|
this.stopHealthCheck();
|
|
1739
|
+
// Stop screencast manager
|
|
1740
|
+
if (this.screencastManager) {
|
|
1741
|
+
await this.screencastManager.stop();
|
|
1742
|
+
this.screencastManager = null;
|
|
1743
|
+
}
|
|
1785
1744
|
// Clean up session file
|
|
1786
1745
|
try {
|
|
1787
1746
|
const projectName = getProjectName();
|
|
@@ -1839,7 +1798,8 @@ export class DevEnvironment {
|
|
|
1839
1798
|
}
|
|
1840
1799
|
}
|
|
1841
1800
|
console.log(chalk.red(`ā ${this.options.commandName} exited due to server failure`));
|
|
1842
|
-
|
|
1801
|
+
const projectName = getProjectName();
|
|
1802
|
+
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
1803
|
process.exit(1);
|
|
1844
1804
|
}
|
|
1845
1805
|
setupCleanupHandlers() {
|
|
@@ -1978,10 +1938,9 @@ export class DevEnvironment {
|
|
|
1978
1938
|
}
|
|
1979
1939
|
}
|
|
1980
1940
|
}
|
|
1981
|
-
// Clean up
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
}
|
|
1941
|
+
// Clean up MCP server configurations from project settings files (instant)
|
|
1942
|
+
await cleanupMcpServers(this.chromeDevtoolsSupported, this.enableNextjsMcp);
|
|
1943
|
+
await cleanupCursorMcpServers(this.chromeDevtoolsSupported, this.enableNextjsMcp);
|
|
1985
1944
|
// Kill processes on both ports
|
|
1986
1945
|
const killPortProcess = async (port, name) => {
|
|
1987
1946
|
try {
|