dev3000 0.0.156 → 0.0.159
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 +3 -1
- package/dist/cdp-monitor.d.ts +2 -3
- package/dist/cdp-monitor.d.ts.map +1 -1
- package/dist/cdp-monitor.js +5 -11
- package/dist/cdp-monitor.js.map +1 -1
- package/dist/cli.js +182 -161
- package/dist/cli.js.map +1 -1
- package/dist/commands/cloud-check-pr.js +2 -1
- package/dist/commands/cloud-check-pr.js.map +1 -1
- package/dist/commands/cloud-fix.d.ts +1 -2
- package/dist/commands/cloud-fix.d.ts.map +1 -1
- package/dist/commands/cloud-fix.js +49 -685
- package/dist/commands/cloud-fix.js.map +1 -1
- package/dist/components/PackageSelector.d.ts +3 -2
- package/dist/components/PackageSelector.d.ts.map +1 -1
- package/dist/components/PackageSelector.js +9 -4
- package/dist/components/PackageSelector.js.map +1 -1
- package/dist/dev-environment.d.ts +9 -40
- package/dist/dev-environment.d.ts.map +1 -1
- package/dist/dev-environment.js +245 -542
- package/dist/dev-environment.js.map +1 -1
- package/dist/skills/d3k/SKILL.md +35 -2
- package/dist/src/tui-interface-impl.tsx +2 -12
- package/dist/tui-interface-impl.d.ts +0 -1
- package/dist/tui-interface-impl.d.ts.map +1 -1
- package/dist/tui-interface-impl.js +3 -7
- package/dist/tui-interface-impl.js.map +1 -1
- package/dist/tui-interface-opentui.d.ts +0 -1
- package/dist/tui-interface-opentui.d.ts.map +1 -1
- package/dist/tui-interface-opentui.js +26 -10
- package/dist/tui-interface-opentui.js.map +1 -1
- package/dist/tui-interface.d.ts +0 -1
- package/dist/tui-interface.d.ts.map +1 -1
- package/dist/tui-interface.js.map +1 -1
- package/dist/utils/agent-browser.d.ts.map +1 -1
- package/dist/utils/agent-browser.js +18 -13
- package/dist/utils/agent-browser.js.map +1 -1
- package/dist/utils/agent-selection.d.ts +1 -0
- package/dist/utils/agent-selection.d.ts.map +1 -1
- package/dist/utils/agent-selection.js +26 -1
- package/dist/utils/agent-selection.js.map +1 -1
- package/dist/utils/d3k-dir.d.ts +3 -0
- package/dist/utils/d3k-dir.d.ts.map +1 -0
- package/dist/utils/d3k-dir.js +12 -0
- package/dist/utils/d3k-dir.js.map +1 -0
- package/dist/utils/skill-installer.d.ts +7 -7
- package/dist/utils/skill-installer.d.ts.map +1 -1
- package/dist/utils/skill-installer.js +131 -18
- package/dist/utils/skill-installer.js.map +1 -1
- package/dist/utils/user-config.d.ts +0 -1
- package/dist/utils/user-config.d.ts.map +1 -1
- package/dist/utils/user-config.js +0 -13
- package/dist/utils/user-config.js.map +1 -1
- package/package.json +9 -29
- package/src/tui-interface-impl.tsx +2 -12
- package/dist/commands/cloud-fix-workflow.d.ts +0 -16
- package/dist/commands/cloud-fix-workflow.d.ts.map +0 -1
- package/dist/commands/cloud-fix-workflow.js +0 -153
- package/dist/commands/cloud-fix-workflow.js.map +0 -1
- package/dist/commands/restart.d.ts +0 -8
- package/dist/commands/restart.d.ts.map +0 -1
- package/dist/commands/restart.js +0 -92
- package/dist/commands/restart.js.map +0 -1
- package/dist/utils/mcp-configs.d.ts +0 -6
- package/dist/utils/mcp-configs.d.ts.map +0 -1
- package/dist/utils/mcp-configs.js +0 -54
- package/dist/utils/mcp-configs.js.map +0 -1
- package/mcp-server/.next/BUILD_ID +0 -1
- package/mcp-server/.next/app-path-routes-manifest.json +0 -22
- package/mcp-server/.next/build/chunks/[root-of-the-server]__25374c4f._.js +0 -500
- package/mcp-server/.next/build/chunks/[root-of-the-server]__25374c4f._.js.map +0 -11
- package/mcp-server/.next/build/chunks/[root-of-the-server]__6e020478._.js +0 -441
- package/mcp-server/.next/build/chunks/[root-of-the-server]__6e020478._.js.map +0 -7
- package/mcp-server/.next/build/chunks/[root-of-the-server]__c438ef56._.js +0 -205
- package/mcp-server/.next/build/chunks/[root-of-the-server]__c438ef56._.js.map +0 -8
- package/mcp-server/.next/build/chunks/[root-of-the-server]__c7ae8543._.js +0 -500
- package/mcp-server/.next/build/chunks/[root-of-the-server]__c7ae8543._.js.map +0 -11
- package/mcp-server/.next/build/chunks/[turbopack-node]_transforms_postcss_ts_7988927e._.js +0 -13
- package/mcp-server/.next/build/chunks/[turbopack-node]_transforms_postcss_ts_7988927e._.js.map +0 -5
- package/mcp-server/.next/build/chunks/[turbopack-node]_transforms_webpack-loaders_ts_1efa112f._.js +0 -12
- package/mcp-server/.next/build/chunks/[turbopack-node]_transforms_webpack-loaders_ts_1efa112f._.js.map +0 -5
- package/mcp-server/.next/build/chunks/[turbopack]_runtime.js +0 -795
- package/mcp-server/.next/build/chunks/[turbopack]_runtime.js.map +0 -10
- package/mcp-server/.next/build/chunks/node_modules__bun_19755e4f._.js +0 -6758
- package/mcp-server/.next/build/chunks/node_modules__bun_19755e4f._.js.map +0 -47
- package/mcp-server/.next/build/package.json +0 -1
- package/mcp-server/.next/build/postcss.js +0 -6
- package/mcp-server/.next/build/postcss.js.map +0 -5
- package/mcp-server/.next/build/webpack-loaders.js +0 -6
- package/mcp-server/.next/build/webpack-loaders.js.map +0 -5
- package/mcp-server/.next/build-manifest.json +0 -20
- package/mcp-server/.next/export-marker.json +0 -6
- package/mcp-server/.next/fallback-build-manifest.json +0 -12
- package/mcp-server/.next/images-manifest.json +0 -66
- package/mcp-server/.next/next-minimal-server.js.nft.json +0 -1
- package/mcp-server/.next/next-server.js.nft.json +0 -1
- package/mcp-server/.next/package.json +0 -1
- package/mcp-server/.next/prerender-manifest.json +0 -85
- package/mcp-server/.next/required-server-files.js +0 -164
- package/mcp-server/.next/required-server-files.json +0 -164
- package/mcp-server/.next/routes-manifest.json +0 -171
- package/mcp-server/.next/server/app/_global-error/page/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/_global-error/page/build-manifest.json +0 -17
- package/mcp-server/.next/server/app/_global-error/page/next-font-manifest.json +0 -6
- package/mcp-server/.next/server/app/_global-error/page/react-loadable-manifest.json +0 -1
- package/mcp-server/.next/server/app/_global-error/page/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/_global-error/page.js +0 -10
- package/mcp-server/.next/server/app/_global-error/page.js.map +0 -5
- package/mcp-server/.next/server/app/_global-error/page.js.nft.json +0 -1
- package/mcp-server/.next/server/app/_global-error/page_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/_global-error.html +0 -2
- package/mcp-server/.next/server/app/_global-error.meta +0 -15
- package/mcp-server/.next/server/app/_global-error.rsc +0 -12
- package/mcp-server/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +0 -5
- package/mcp-server/.next/server/app/_global-error.segments/_full.segment.rsc +0 -12
- package/mcp-server/.next/server/app/_global-error.segments/_head.segment.rsc +0 -5
- package/mcp-server/.next/server/app/_global-error.segments/_index.segment.rsc +0 -4
- package/mcp-server/.next/server/app/_global-error.segments/_tree.segment.rsc +0 -1
- package/mcp-server/.next/server/app/_not-found/page/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/_not-found/page/build-manifest.json +0 -17
- package/mcp-server/.next/server/app/_not-found/page/next-font-manifest.json +0 -6
- package/mcp-server/.next/server/app/_not-found/page/react-loadable-manifest.json +0 -1
- package/mcp-server/.next/server/app/_not-found/page/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/_not-found/page.js +0 -13
- package/mcp-server/.next/server/app/_not-found/page.js.map +0 -5
- package/mcp-server/.next/server/app/_not-found/page.js.nft.json +0 -1
- package/mcp-server/.next/server/app/_not-found/page_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/_not-found.html +0 -1
- package/mcp-server/.next/server/app/_not-found.meta +0 -16
- package/mcp-server/.next/server/app/_not-found.rsc +0 -14
- package/mcp-server/.next/server/app/_not-found.segments/_full.segment.rsc +0 -14
- package/mcp-server/.next/server/app/_not-found.segments/_head.segment.rsc +0 -5
- package/mcp-server/.next/server/app/_not-found.segments/_index.segment.rsc +0 -6
- package/mcp-server/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +0 -5
- package/mcp-server/.next/server/app/_not-found.segments/_not-found.segment.rsc +0 -4
- package/mcp-server/.next/server/app/_not-found.segments/_tree.segment.rsc +0 -2
- package/mcp-server/.next/server/app/api/jank/[session]/route/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/api/jank/[session]/route/build-manifest.json +0 -11
- package/mcp-server/.next/server/app/api/jank/[session]/route/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/api/jank/[session]/route.js +0 -10
- package/mcp-server/.next/server/app/api/jank/[session]/route.js.map +0 -5
- package/mcp-server/.next/server/app/api/jank/[session]/route.js.nft.json +0 -1
- package/mcp-server/.next/server/app/api/jank/[session]/route_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/api/logs/append/route/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/api/logs/append/route/build-manifest.json +0 -11
- package/mcp-server/.next/server/app/api/logs/append/route/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/api/logs/append/route.js +0 -6
- package/mcp-server/.next/server/app/api/logs/append/route.js.map +0 -5
- package/mcp-server/.next/server/app/api/logs/append/route.js.nft.json +0 -1
- package/mcp-server/.next/server/app/api/logs/append/route_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/api/logs/head/route/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/api/logs/head/route/build-manifest.json +0 -11
- package/mcp-server/.next/server/app/api/logs/head/route/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/api/logs/head/route.js +0 -6
- package/mcp-server/.next/server/app/api/logs/head/route.js.map +0 -5
- package/mcp-server/.next/server/app/api/logs/head/route.js.nft.json +0 -1
- package/mcp-server/.next/server/app/api/logs/head/route_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/api/logs/list/route/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/api/logs/list/route/build-manifest.json +0 -11
- package/mcp-server/.next/server/app/api/logs/list/route/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/api/logs/list/route.js +0 -6
- package/mcp-server/.next/server/app/api/logs/list/route.js.map +0 -5
- package/mcp-server/.next/server/app/api/logs/list/route.js.nft.json +0 -1
- package/mcp-server/.next/server/app/api/logs/list/route_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/api/logs/rotate/route/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/api/logs/rotate/route/build-manifest.json +0 -11
- package/mcp-server/.next/server/app/api/logs/rotate/route/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/api/logs/rotate/route.js +0 -8
- package/mcp-server/.next/server/app/api/logs/rotate/route.js.map +0 -5
- package/mcp-server/.next/server/app/api/logs/rotate/route.js.nft.json +0 -1
- package/mcp-server/.next/server/app/api/logs/rotate/route_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/api/logs/stream/route/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/api/logs/stream/route/build-manifest.json +0 -11
- package/mcp-server/.next/server/app/api/logs/stream/route/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/api/logs/stream/route.js +0 -6
- package/mcp-server/.next/server/app/api/logs/stream/route.js.map +0 -5
- package/mcp-server/.next/server/app/api/logs/stream/route.js.nft.json +0 -1
- package/mcp-server/.next/server/app/api/logs/stream/route_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/api/logs/tail/route/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/api/logs/tail/route/build-manifest.json +0 -11
- package/mcp-server/.next/server/app/api/logs/tail/route/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/api/logs/tail/route.js +0 -6
- package/mcp-server/.next/server/app/api/logs/tail/route.js.map +0 -5
- package/mcp-server/.next/server/app/api/logs/tail/route.js.nft.json +0 -1
- package/mcp-server/.next/server/app/api/logs/tail/route_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/api/orchestrator/route/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/api/orchestrator/route/build-manifest.json +0 -11
- package/mcp-server/.next/server/app/api/orchestrator/route/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/api/orchestrator/route.js +0 -9
- package/mcp-server/.next/server/app/api/orchestrator/route.js.map +0 -5
- package/mcp-server/.next/server/app/api/orchestrator/route.js.nft.json +0 -1
- package/mcp-server/.next/server/app/api/orchestrator/route_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/api/screenshots/[filename]/route/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/api/screenshots/[filename]/route/build-manifest.json +0 -11
- package/mcp-server/.next/server/app/api/screenshots/[filename]/route/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/api/screenshots/[filename]/route.js +0 -8
- package/mcp-server/.next/server/app/api/screenshots/[filename]/route.js.map +0 -5
- package/mcp-server/.next/server/app/api/screenshots/[filename]/route.js.nft.json +0 -1
- package/mcp-server/.next/server/app/api/screenshots/[filename]/route_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/api/screenshots/capture/route/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/api/screenshots/capture/route/build-manifest.json +0 -11
- package/mcp-server/.next/server/app/api/screenshots/capture/route/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/api/screenshots/capture/route.js +0 -9
- package/mcp-server/.next/server/app/api/screenshots/capture/route.js.map +0 -5
- package/mcp-server/.next/server/app/api/screenshots/capture/route.js.nft.json +0 -1
- package/mcp-server/.next/server/app/api/screenshots/capture/route_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/api/screenshots/clear/route/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/api/screenshots/clear/route/build-manifest.json +0 -11
- package/mcp-server/.next/server/app/api/screenshots/clear/route/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/api/screenshots/clear/route.js +0 -8
- package/mcp-server/.next/server/app/api/screenshots/clear/route.js.map +0 -5
- package/mcp-server/.next/server/app/api/screenshots/clear/route.js.nft.json +0 -1
- package/mcp-server/.next/server/app/api/screenshots/clear/route_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/api/screenshots/list/route/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/api/screenshots/list/route/build-manifest.json +0 -11
- package/mcp-server/.next/server/app/api/screenshots/list/route/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/api/screenshots/list/route.js +0 -8
- package/mcp-server/.next/server/app/api/screenshots/list/route.js.map +0 -5
- package/mcp-server/.next/server/app/api/screenshots/list/route.js.nft.json +0 -1
- package/mcp-server/.next/server/app/api/screenshots/list/route_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/api/teams/route/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/api/teams/route/build-manifest.json +0 -11
- package/mcp-server/.next/server/app/api/teams/route/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/api/teams/route.js +0 -8
- package/mcp-server/.next/server/app/api/teams/route.js.map +0 -5
- package/mcp-server/.next/server/app/api/teams/route.js.nft.json +0 -1
- package/mcp-server/.next/server/app/api/teams/route_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/api/tools/route/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/api/tools/route/build-manifest.json +0 -11
- package/mcp-server/.next/server/app/api/tools/route/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/api/tools/route.js +0 -8
- package/mcp-server/.next/server/app/api/tools/route.js.map +0 -5
- package/mcp-server/.next/server/app/api/tools/route.js.nft.json +0 -1
- package/mcp-server/.next/server/app/api/tools/route_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/index.html +0 -1
- package/mcp-server/.next/server/app/index.meta +0 -14
- package/mcp-server/.next/server/app/index.rsc +0 -18
- package/mcp-server/.next/server/app/index.segments/__PAGE__.segment.rsc +0 -9
- package/mcp-server/.next/server/app/index.segments/_full.segment.rsc +0 -18
- package/mcp-server/.next/server/app/index.segments/_head.segment.rsc +0 -5
- package/mcp-server/.next/server/app/index.segments/_index.segment.rsc +0 -6
- package/mcp-server/.next/server/app/index.segments/_tree.segment.rsc +0 -2
- package/mcp-server/.next/server/app/logs/page/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/logs/page/build-manifest.json +0 -17
- package/mcp-server/.next/server/app/logs/page/next-font-manifest.json +0 -6
- package/mcp-server/.next/server/app/logs/page/react-loadable-manifest.json +0 -1
- package/mcp-server/.next/server/app/logs/page/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/logs/page.js +0 -16
- package/mcp-server/.next/server/app/logs/page.js.map +0 -5
- package/mcp-server/.next/server/app/logs/page.js.nft.json +0 -1
- package/mcp-server/.next/server/app/logs/page_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/mcp/route/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/mcp/route/build-manifest.json +0 -11
- package/mcp-server/.next/server/app/mcp/route/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/mcp/route.js +0 -11
- package/mcp-server/.next/server/app/mcp/route.js.map +0 -5
- package/mcp-server/.next/server/app/mcp/route.js.nft.json +0 -1
- package/mcp-server/.next/server/app/mcp/route_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/page/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/page/build-manifest.json +0 -17
- package/mcp-server/.next/server/app/page/next-font-manifest.json +0 -6
- package/mcp-server/.next/server/app/page/react-loadable-manifest.json +0 -1
- package/mcp-server/.next/server/app/page/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/page.js +0 -15
- package/mcp-server/.next/server/app/page.js.map +0 -5
- package/mcp-server/.next/server/app/page.js.nft.json +0 -1
- package/mcp-server/.next/server/app/page_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app/video/[session]/page/app-paths-manifest.json +0 -3
- package/mcp-server/.next/server/app/video/[session]/page/build-manifest.json +0 -17
- package/mcp-server/.next/server/app/video/[session]/page/next-font-manifest.json +0 -6
- package/mcp-server/.next/server/app/video/[session]/page/react-loadable-manifest.json +0 -1
- package/mcp-server/.next/server/app/video/[session]/page/server-reference-manifest.json +0 -4
- package/mcp-server/.next/server/app/video/[session]/page.js +0 -15
- package/mcp-server/.next/server/app/video/[session]/page.js.map +0 -5
- package/mcp-server/.next/server/app/video/[session]/page.js.nft.json +0 -1
- package/mcp-server/.next/server/app/video/[session]/page_client-reference-manifest.js +0 -2
- package/mcp-server/.next/server/app-paths-manifest.json +0 -22
- package/mcp-server/.next/server/chunks/250ae__next-internal_server_app_api_screenshots_[filename]_route_actions_4f8d6e37.js +0 -3
- package/mcp-server/.next/server/chunks/250ae__next-internal_server_app_api_screenshots_[filename]_route_actions_4f8d6e37.js.map +0 -1
- package/mcp-server/.next/server/chunks/250ae__next-internal_server_app_api_screenshots_capture_route_actions_4034f26c.js +0 -3
- package/mcp-server/.next/server/chunks/250ae__next-internal_server_app_api_screenshots_capture_route_actions_4034f26c.js.map +0 -1
- package/mcp-server/.next/server/chunks/250ae__next-internal_server_app_api_screenshots_clear_route_actions_e26206f4.js +0 -3
- package/mcp-server/.next/server/chunks/250ae__next-internal_server_app_api_screenshots_clear_route_actions_e26206f4.js.map +0 -1
- package/mcp-server/.next/server/chunks/[externals]__0e1fd2ca._.js +0 -3
- package/mcp-server/.next/server/chunks/[externals]__0e1fd2ca._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[externals]_next_dist_2a398dc7._.js +0 -3
- package/mcp-server/.next/server/chunks/[externals]_next_dist_2a398dc7._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[externals]_node:crypto_c20cce38._.js +0 -3
- package/mcp-server/.next/server/chunks/[externals]_node:crypto_c20cce38._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__1dca9894._.js +0 -3
- package/mcp-server/.next/server/chunks/[root-of-the-server]__1dca9894._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__21541e6b._.js +0 -11
- package/mcp-server/.next/server/chunks/[root-of-the-server]__21541e6b._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__2f95edf0._.js +0 -17
- package/mcp-server/.next/server/chunks/[root-of-the-server]__2f95edf0._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__377f76d7._.js +0 -7
- package/mcp-server/.next/server/chunks/[root-of-the-server]__377f76d7._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__454b0d3c._.js +0 -7
- package/mcp-server/.next/server/chunks/[root-of-the-server]__454b0d3c._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__69e6dfb7._.js +0 -3
- package/mcp-server/.next/server/chunks/[root-of-the-server]__69e6dfb7._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__6baff21e._.js +0 -4
- package/mcp-server/.next/server/chunks/[root-of-the-server]__6baff21e._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__6f790e1f._.js +0 -3
- package/mcp-server/.next/server/chunks/[root-of-the-server]__6f790e1f._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__7049acd5._.js +0 -3
- package/mcp-server/.next/server/chunks/[root-of-the-server]__7049acd5._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__73c9cc46._.js +0 -3
- package/mcp-server/.next/server/chunks/[root-of-the-server]__73c9cc46._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__78991125._.js +0 -3
- package/mcp-server/.next/server/chunks/[root-of-the-server]__78991125._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__7ae828c6._.js +0 -3
- package/mcp-server/.next/server/chunks/[root-of-the-server]__7ae828c6._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__94946101._.js +0 -3
- package/mcp-server/.next/server/chunks/[root-of-the-server]__94946101._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__99274dd8._.js +0 -4
- package/mcp-server/.next/server/chunks/[root-of-the-server]__99274dd8._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__9c4c7095._.js +0 -3
- package/mcp-server/.next/server/chunks/[root-of-the-server]__9c4c7095._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__b56464d6._.js +0 -7
- package/mcp-server/.next/server/chunks/[root-of-the-server]__b56464d6._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__b698502d._.js +0 -3
- package/mcp-server/.next/server/chunks/[root-of-the-server]__b698502d._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__b86e20b6._.js +0 -3
- package/mcp-server/.next/server/chunks/[root-of-the-server]__b86e20b6._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__c8cf5b23._.js +0 -3
- package/mcp-server/.next/server/chunks/[root-of-the-server]__c8cf5b23._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__e6a83e60._.js +0 -4
- package/mcp-server/.next/server/chunks/[root-of-the-server]__e6a83e60._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__ee139f8a._.js +0 -3
- package/mcp-server/.next/server/chunks/[root-of-the-server]__ee139f8a._.js.map +0 -1
- package/mcp-server/.next/server/chunks/[turbopack]_runtime.js +0 -795
- package/mcp-server/.next/server/chunks/[turbopack]_runtime.js.map +0 -10
- package/mcp-server/.next/server/chunks/edd96_next_80752ad3._.js +0 -3
- package/mcp-server/.next/server/chunks/edd96_next_80752ad3._.js.map +0 -1
- package/mcp-server/.next/server/chunks/edd96_next_dist_esm_build_templates_app-route_f51c5640.js +0 -3
- package/mcp-server/.next/server/chunks/edd96_next_dist_esm_build_templates_app-route_f51c5640.js.map +0 -1
- package/mcp-server/.next/server/chunks/edd96_next_dist_fa47e982._.js +0 -6
- package/mcp-server/.next/server/chunks/edd96_next_dist_fa47e982._.js.map +0 -1
- package/mcp-server/.next/server/chunks/edd96_next_ef93dda6._.js +0 -14
- package/mcp-server/.next/server/chunks/edd96_next_ef93dda6._.js.map +0 -1
- package/mcp-server/.next/server/chunks/mcp-server_70405c2f._.js +0 -3
- package/mcp-server/.next/server/chunks/mcp-server_70405c2f._.js.map +0 -1
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_jank_[session]_route_actions_3b2b275b.js +0 -3
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_jank_[session]_route_actions_3b2b275b.js.map +0 -1
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_append_route_actions_bc66060f.js +0 -3
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_append_route_actions_bc66060f.js.map +0 -1
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_head_route_actions_1152480c.js +0 -3
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_head_route_actions_1152480c.js.map +0 -1
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_list_route_actions_b9e24400.js +0 -3
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_list_route_actions_b9e24400.js.map +0 -1
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_rotate_route_actions_76075d08.js +0 -3
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_rotate_route_actions_76075d08.js.map +0 -1
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_stream_route_actions_16e5c553.js +0 -3
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_stream_route_actions_16e5c553.js.map +0 -1
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_tail_route_actions_55440150.js +0 -3
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_tail_route_actions_55440150.js.map +0 -1
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_orchestrator_route_actions_c6fba9ec.js +0 -3
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_orchestrator_route_actions_c6fba9ec.js.map +0 -1
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_screenshots_list_route_actions_acfa57bd.js +0 -3
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_screenshots_list_route_actions_acfa57bd.js.map +0 -1
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_teams_route_actions_aaa1c876.js +0 -3
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_teams_route_actions_aaa1c876.js.map +0 -1
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_tools_route_actions_007f3c7c.js +0 -3
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_tools_route_actions_007f3c7c.js.map +0 -1
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_mcp_route_actions_7f7b5be4.js +0 -3
- package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_mcp_route_actions_7f7b5be4.js.map +0 -1
- package/mcp-server/.next/server/chunks/mcp-server_app_mcp_tools_ts_faf6d7df._.js +0 -185
- package/mcp-server/.next/server/chunks/mcp-server_app_mcp_tools_ts_faf6d7df._.js.map +0 -1
- package/mcp-server/.next/server/chunks/mcp-server_instrumentation_node_ts_32271e34._.js +0 -3
- package/mcp-server/.next/server/chunks/mcp-server_instrumentation_node_ts_32271e34._.js.map +0 -1
- package/mcp-server/.next/server/chunks/src_utils_agent-browser_ts_cc00e0d8._.js +0 -3
- package/mcp-server/.next/server/chunks/src_utils_agent-browser_ts_cc00e0d8._.js.map +0 -1
- package/mcp-server/.next/server/chunks/src_utils_project-name_ts_1fab1dd5._.js +0 -3
- package/mcp-server/.next/server/chunks/src_utils_project-name_ts_1fab1dd5._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__250a4cf3._.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__250a4cf3._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__41e244ae._.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__41e244ae._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__4a45fb1f._.js +0 -4
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__4a45fb1f._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__4feaccaf._.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__4feaccaf._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__6d9fa861._.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__6d9fa861._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__9913ce94._.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__9913ce94._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__9923da5e._.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__9923da5e._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__a8fcf205._.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__a8fcf205._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__b17d4048._.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__b17d4048._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__dcf84f77._.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__dcf84f77._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__df4ed844._.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__df4ed844._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/[turbopack]_runtime.js +0 -795
- package/mcp-server/.next/server/chunks/ssr/[turbopack]_runtime.js.map +0 -10
- package/mcp-server/.next/server/chunks/ssr/_213c874b._.js +0 -4
- package/mcp-server/.next/server/chunks/ssr/_213c874b._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/_69be9abe._.js +0 -4
- package/mcp-server/.next/server/chunks/ssr/_69be9abe._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/_b38781f1._.js +0 -4
- package/mcp-server/.next/server/chunks/ssr/_b38781f1._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/_edba94b0._.js +0 -8
- package/mcp-server/.next/server/chunks/ssr/_edba94b0._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/_f478416d._.js +0 -8
- package/mcp-server/.next/server/chunks/ssr/_f478416d._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_22d4e869._.js +0 -4
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_22d4e869._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_329c4a9b._.js +0 -10
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_329c4a9b._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_6cceb2cd._.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_6cceb2cd._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_861297ac._.js +0 -6
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_861297ac._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_client_components_85c7e922._.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_client_components_85c7e922._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_client_components_builtin_forbidden_0eb1cacd.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_client_components_builtin_forbidden_0eb1cacd.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_client_components_builtin_global-error_e64e654b.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_client_components_builtin_global-error_e64e654b.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_client_components_builtin_unauthorized_06e7b5f5.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_client_components_builtin_unauthorized_06e7b5f5.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_esm_build_templates_app-page_f82c7ca4.js +0 -4
- package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_esm_build_templates_app-page_f82c7ca4.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app__global-error_page_actions_404453e7.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app__global-error_page_actions_404453e7.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app__not-found_page_actions_c1864427.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app__not-found_page_actions_c1864427.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app_logs_page_actions_71542ba9.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app_logs_page_actions_71542ba9.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app_page_actions_a5ee4758.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app_page_actions_a5ee4758.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app_video_[session]_page_actions_a6aab323.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app_video_[session]_page_actions_a6aab323.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/mcp-server_app_layout_tsx_afa41767._.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/mcp-server_app_layout_tsx_afa41767._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/mcp-server_app_page_tsx_9fc46577._.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/mcp-server_app_page_tsx_9fc46577._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/mcp-server_components_dark-mode-toggle_tsx_f31dd15d._.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/mcp-server_components_dark-mode-toggle_tsx_f31dd15d._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/node_modules__bun_39d5fbaf._.js +0 -3
- package/mcp-server/.next/server/chunks/ssr/node_modules__bun_39d5fbaf._.js.map +0 -1
- package/mcp-server/.next/server/chunks/ssr/node_modules__bun_d6d37386._.js +0 -5
- package/mcp-server/.next/server/chunks/ssr/node_modules__bun_d6d37386._.js.map +0 -1
- package/mcp-server/.next/server/functions-config-manifest.json +0 -4
- package/mcp-server/.next/server/instrumentation.js +0 -4
- package/mcp-server/.next/server/instrumentation.js.nft.json +0 -1
- package/mcp-server/.next/server/interception-route-rewrite-manifest.js +0 -1
- package/mcp-server/.next/server/middleware-build-manifest.js +0 -21
- package/mcp-server/.next/server/middleware-manifest.json +0 -6
- package/mcp-server/.next/server/next-font-manifest.js +0 -1
- package/mcp-server/.next/server/next-font-manifest.json +0 -6
- package/mcp-server/.next/server/pages/404.html +0 -1
- package/mcp-server/.next/server/pages/500.html +0 -2
- package/mcp-server/.next/server/pages-manifest.json +0 -4
- package/mcp-server/.next/server/server-reference-manifest.js +0 -1
- package/mcp-server/.next/server/server-reference-manifest.json +0 -5
- package/mcp-server/.next/static/HxwUjR9e01QAp7lf9kRjn/_buildManifest.js +0 -11
- package/mcp-server/.next/static/HxwUjR9e01QAp7lf9kRjn/_clientMiddlewareManifest.json +0 -1
- package/mcp-server/.next/static/HxwUjR9e01QAp7lf9kRjn/_ssgManifest.js +0 -1
- package/mcp-server/.next/static/chunks/10099c90a1ca89ea.js +0 -4
- package/mcp-server/.next/static/chunks/10c04cb580a9beec.js +0 -1
- package/mcp-server/.next/static/chunks/13606014ef33124c.js +0 -2
- package/mcp-server/.next/static/chunks/39e9bdcc541cc428.js +0 -1
- package/mcp-server/.next/static/chunks/3f3f8e7d16ba3bf4.js +0 -1
- package/mcp-server/.next/static/chunks/4785978304fb9e19.js +0 -1
- package/mcp-server/.next/static/chunks/59cdeaf92a780e96.css +0 -1
- package/mcp-server/.next/static/chunks/5df77c9395248155.js +0 -1
- package/mcp-server/.next/static/chunks/807aef58565dccb1.js +0 -1
- package/mcp-server/.next/static/chunks/a6dad97d9634a72d.js +0 -1
- package/mcp-server/.next/static/chunks/a6dad97d9634a72d.js.map +0 -1
- package/mcp-server/.next/static/chunks/b8eb42a9560f7980.js +0 -3
- package/mcp-server/.next/static/chunks/ea7b53054294e7bb.js +0 -3
- package/mcp-server/.next/static/chunks/ec58e1c556f5d0fa.js +0 -3
- package/mcp-server/.next/static/chunks/turbopack-b64e111cadf03885.js +0 -4
- package/mcp-server/app/api/jank/[session]/route.ts +0 -344
- package/mcp-server/app/api/logs/append/route.ts +0 -82
- package/mcp-server/app/api/logs/head/route.ts +0 -32
- package/mcp-server/app/api/logs/list/route.ts +0 -71
- package/mcp-server/app/api/logs/rotate/route.ts +0 -48
- package/mcp-server/app/api/logs/stream/route.ts +0 -61
- package/mcp-server/app/api/logs/tail/route.ts +0 -32
- package/mcp-server/app/api/orchestrator/route.ts +0 -73
- package/mcp-server/app/api/screenshots/[filename]/route.ts +0 -61
- package/mcp-server/app/api/screenshots/capture/route.ts +0 -137
- package/mcp-server/app/api/screenshots/clear/route.ts +0 -44
- package/mcp-server/app/api/screenshots/list/route.ts +0 -22
- package/mcp-server/app/api/teams/route.ts +0 -86
- package/mcp-server/app/api/tools/route.ts +0 -92
- package/mcp-server/app/globals.css +0 -124
- package/mcp-server/app/layout.tsx +0 -23
- package/mcp-server/app/logs/LogsClient.infinite-loop.test.tsx +0 -127
- package/mcp-server/app/logs/LogsClient.test.ts +0 -416
- package/mcp-server/app/logs/LogsClient.tsx +0 -1967
- package/mcp-server/app/logs/page.tsx +0 -150
- package/mcp-server/app/logs/utils.ts +0 -151
- package/mcp-server/app/mcp/client-manager.ts +0 -346
- package/mcp-server/app/mcp/route.ts +0 -765
- package/mcp-server/app/mcp/tools.ts +0 -4158
- package/mcp-server/app/page.tsx +0 -399
- package/mcp-server/app/video/[session]/page.tsx +0 -239
- package/mcp-server/next-env.d.ts +0 -6
- package/mcp-server/package.json +0 -48
- package/mcp-server/postcss.config.mjs +0 -5
- package/mcp-server/public/favicon-16.svg +0 -4
- package/mcp-server/public/favicon-180.png +0 -0
- package/mcp-server/public/favicon-64.svg +0 -4
- package/mcp-server/public/favicon-preview.html +0 -67
- package/mcp-server/public/favicon.ico +0 -0
- package/mcp-server/public/favicon.svg +0 -4
- package/mcp-server/public/screenshots/test.txt +0 -1
- package/mcp-server/start-production.mjs +0 -101
- package/mcp-server/tsconfig.json +0 -28
package/dist/dev-environment.js
CHANGED
|
@@ -4,40 +4,20 @@ import { appendFileSync, copyFileSync, existsSync, mkdirSync, readdirSync, readF
|
|
|
4
4
|
import https from "https";
|
|
5
5
|
import ora from "ora";
|
|
6
6
|
import { homedir, tmpdir } from "os";
|
|
7
|
-
import { dirname, join } from "path";
|
|
7
|
+
import { dirname, join, resolve, sep } from "path";
|
|
8
8
|
import { fileURLToPath } from "url";
|
|
9
9
|
import { CDPMonitor } from "./cdp-monitor.js";
|
|
10
10
|
import { ScreencastManager } from "./screencast-manager.js";
|
|
11
11
|
import { NextJsErrorDetector, OutputProcessor, StandardLogParser } from "./services/parsers/index.js";
|
|
12
12
|
import { getBundledSkillsPath } from "./skills/index.js";
|
|
13
13
|
import { DevTUI } from "./tui-interface.js";
|
|
14
|
-
import { formatMcpConfigTargets, MCP_CONFIG_TARGETS } from "./utils/mcp-configs.js";
|
|
15
14
|
import { getProjectDir, getProjectDisplayName, getProjectName } from "./utils/project-name.js";
|
|
15
|
+
import { getSkillsPathForLocation } from "./utils/skill-installer.js";
|
|
16
16
|
import { formatTimestamp } from "./utils/timestamp.js";
|
|
17
17
|
import { checkForUpdates, initTelemetrySession, performUpgradeAsync, sendSessionEndTelemetry } from "./utils/version-check.js";
|
|
18
|
-
//
|
|
19
|
-
const MCP_NAMES = {
|
|
20
|
-
DEV3000: "dev3000",
|
|
21
|
-
CHROME_DEVTOOLS: "dev3000-chrome-devtools",
|
|
22
|
-
NEXTJS_DEV: "dev3000-nextjs-dev",
|
|
23
|
-
VERCEL: "vercel"
|
|
24
|
-
};
|
|
25
|
-
// Vercel MCP URL (public OAuth-based MCP) - kept for potential future use
|
|
18
|
+
// Vercel tools URL (legacy, kept for potential future use)
|
|
26
19
|
// @ts-expect-error Unused but kept for reference
|
|
27
|
-
const
|
|
28
|
-
/**
|
|
29
|
-
* Patterns for identifying orphaned MCP-related processes to clean up on startup.
|
|
30
|
-
*
|
|
31
|
-
* IMPORTANT: This list must NOT include ".d3k/chrome-profiles" or any pattern
|
|
32
|
-
* that would match Chrome instances from OTHER running d3k instances.
|
|
33
|
-
* Each d3k instance handles its own profile cleanup via killExistingChromeWithProfile().
|
|
34
|
-
*
|
|
35
|
-
* @see cleanupOrphanedPlaywrightProcesses
|
|
36
|
-
*/
|
|
37
|
-
export const ORPHANED_PROCESS_CLEANUP_PATTERNS = [
|
|
38
|
-
"ms-playwright/mcp-chrome", // Playwright MCP Chrome user data dir
|
|
39
|
-
"mcp-server-playwright" // Playwright MCP server node process
|
|
40
|
-
];
|
|
20
|
+
const _VERCEL_TOOLS_URL = "https://mcp.vercel.com";
|
|
41
21
|
/**
|
|
42
22
|
* Check if the current project has a .vercel directory (indicating a Vercel project)
|
|
43
23
|
* Kept for potential future use
|
|
@@ -147,11 +127,7 @@ function isInSandbox() {
|
|
|
147
127
|
* Returns the count of running d3k processes (excluding the current one if specified).
|
|
148
128
|
*
|
|
149
129
|
* CRITICAL FOR PROCESS CLEANUP:
|
|
150
|
-
* This function
|
|
151
|
-
* Only the LAST d3k instance should kill the MCP server.
|
|
152
|
-
*
|
|
153
|
-
* @see handleShutdown - Uses this to decide MCP cleanup
|
|
154
|
-
* @see SIGHUP handler - Uses this for synchronous MCP cleanup on tmux close
|
|
130
|
+
* This function is used to reason about multi-instance shutdown behavior.
|
|
155
131
|
*/
|
|
156
132
|
export function countActiveD3kInstances(excludeCurrentPid = false) {
|
|
157
133
|
try {
|
|
@@ -184,87 +160,6 @@ export function countActiveD3kInstances(excludeCurrentPid = false) {
|
|
|
184
160
|
return excludeCurrentPid ? 0 : 1;
|
|
185
161
|
}
|
|
186
162
|
}
|
|
187
|
-
/**
|
|
188
|
-
* Clean up orphaned Playwright/MCP Chrome processes from previous d3k sessions.
|
|
189
|
-
* These processes can become orphaned when d3k crashes or is force-killed,
|
|
190
|
-
* leaving Chrome instances that prevent new sessions from starting properly.
|
|
191
|
-
*
|
|
192
|
-
* This function identifies and kills:
|
|
193
|
-
* - Chrome processes spawned by ms-playwright for MCP servers
|
|
194
|
-
* - mcp-server-playwright node processes
|
|
195
|
-
* - Chrome using d3k-specific profile directories
|
|
196
|
-
*/
|
|
197
|
-
async function cleanupOrphanedPlaywrightProcesses(debugLog) {
|
|
198
|
-
// Skip in sandbox environments where ps/grep may not work
|
|
199
|
-
if (isInSandbox()) {
|
|
200
|
-
debugLog("Skipping orphaned process cleanup in sandbox environment");
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
try {
|
|
204
|
-
const { execSync } = await import("child_process");
|
|
205
|
-
for (const pattern of ORPHANED_PROCESS_CLEANUP_PATTERNS) {
|
|
206
|
-
try {
|
|
207
|
-
// Find PIDs matching the pattern
|
|
208
|
-
const result = execSync(`ps aux | grep -i "${pattern}" | grep -v grep | awk '{print $2}'`, {
|
|
209
|
-
encoding: "utf-8",
|
|
210
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
211
|
-
}).trim();
|
|
212
|
-
if (result) {
|
|
213
|
-
const pids = result.split("\n").filter(Boolean);
|
|
214
|
-
debugLog(`Found ${pids.length} orphaned process(es) matching "${pattern}": [${pids.join(", ")}]`);
|
|
215
|
-
for (const pid of pids) {
|
|
216
|
-
try {
|
|
217
|
-
const pidNum = parseInt(pid, 10);
|
|
218
|
-
// First try SIGTERM for graceful shutdown
|
|
219
|
-
process.kill(pidNum, "SIGTERM");
|
|
220
|
-
debugLog(`Sent SIGTERM to orphaned process ${pid}`);
|
|
221
|
-
// Give it a moment to terminate
|
|
222
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
223
|
-
// Check if still alive and force kill if needed
|
|
224
|
-
try {
|
|
225
|
-
process.kill(pidNum, 0); // Check if process exists
|
|
226
|
-
process.kill(pidNum, "SIGKILL");
|
|
227
|
-
debugLog(`Sent SIGKILL to stubborn process ${pid}`);
|
|
228
|
-
}
|
|
229
|
-
catch {
|
|
230
|
-
// Process already dead, good
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
catch (error) {
|
|
234
|
-
// Process may have already exited or we don't have permission
|
|
235
|
-
debugLog(`Could not kill process ${pid}: ${error}`);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
catch {
|
|
241
|
-
// grep returns exit code 1 when no matches found, which is fine
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
// Also clean up any stale Chrome lock files that might prevent new instances
|
|
245
|
-
const lockFilePaths = [
|
|
246
|
-
join(homedir(), "Library/Caches/ms-playwright/mcp-chrome/SingletonLock"),
|
|
247
|
-
join(homedir(), "Library/Caches/ms-playwright/mcp-chrome/SingletonSocket"),
|
|
248
|
-
join(homedir(), "Library/Caches/ms-playwright/mcp-chrome/SingletonCookie")
|
|
249
|
-
];
|
|
250
|
-
for (const lockFile of lockFilePaths) {
|
|
251
|
-
try {
|
|
252
|
-
if (existsSync(lockFile)) {
|
|
253
|
-
unlinkSync(lockFile);
|
|
254
|
-
debugLog(`Removed stale lock file: ${lockFile}`);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
catch {
|
|
258
|
-
// Ignore errors - file might be locked by running process
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
debugLog("Orphaned process cleanup completed");
|
|
262
|
-
}
|
|
263
|
-
catch (error) {
|
|
264
|
-
debugLog(`Error during orphaned process cleanup: ${error}`);
|
|
265
|
-
// Non-fatal - continue with startup
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
163
|
/**
|
|
269
164
|
* Check if a port is available for binding (no process is listening on it).
|
|
270
165
|
* Used for finding available ports before starting servers.
|
|
@@ -390,170 +285,12 @@ export async function findAvailablePort(startPort) {
|
|
|
390
285
|
throw new Error(`No available ports found starting from ${startPort}`);
|
|
391
286
|
}
|
|
392
287
|
// REMOVED: isNextjsMcpEnabled check - now using framework detection from cli.ts
|
|
393
|
-
// Framework detection happens in cli.ts and is stored in session files for
|
|
394
|
-
/**
|
|
395
|
-
* Check if Chrome version supports chrome-devtools MCP (>= 140.0.7339.214)
|
|
396
|
-
*/
|
|
397
|
-
async function isChromeDevtoolsMcpSupported() {
|
|
398
|
-
try {
|
|
399
|
-
// Try different Chrome binary paths
|
|
400
|
-
const chromePaths = [
|
|
401
|
-
"/tmp/chromium", // Vercel Sandbox (@sparticuz/chromium)
|
|
402
|
-
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", // macOS
|
|
403
|
-
"/opt/google/chrome/chrome", // Linux
|
|
404
|
-
"chrome", // PATH
|
|
405
|
-
"google-chrome", // Linux PATH
|
|
406
|
-
"google-chrome-stable" // Linux PATH
|
|
407
|
-
];
|
|
408
|
-
for (const chromePath of chromePaths) {
|
|
409
|
-
try {
|
|
410
|
-
const versionOutput = await new Promise((resolve, reject) => {
|
|
411
|
-
const chromeProcess = spawn(chromePath, ["--version"], {
|
|
412
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
413
|
-
});
|
|
414
|
-
let output = "";
|
|
415
|
-
chromeProcess.stdout?.on("data", (data) => {
|
|
416
|
-
output += data.toString();
|
|
417
|
-
});
|
|
418
|
-
chromeProcess.on("close", (code) => {
|
|
419
|
-
if (code === 0) {
|
|
420
|
-
resolve(output.trim());
|
|
421
|
-
}
|
|
422
|
-
else {
|
|
423
|
-
reject(new Error(`Chrome version check failed with code ${code}`));
|
|
424
|
-
}
|
|
425
|
-
});
|
|
426
|
-
chromeProcess.on("error", reject);
|
|
427
|
-
// Timeout after 3 seconds
|
|
428
|
-
setTimeout(() => {
|
|
429
|
-
chromeProcess.kill();
|
|
430
|
-
reject(new Error("Chrome version check timeout"));
|
|
431
|
-
}, 3000);
|
|
432
|
-
});
|
|
433
|
-
// Parse version from output like "Google Chrome 140.0.7339.214"
|
|
434
|
-
const versionMatch = versionOutput.match(/(\d+)\.(\d+)\.(\d+)\.(\d+)/);
|
|
435
|
-
if (versionMatch) {
|
|
436
|
-
const [, major, minor, build, patch] = versionMatch.map(Number);
|
|
437
|
-
const currentVersion = [major, minor, build, patch];
|
|
438
|
-
const requiredVersion = [140, 0, 7339, 214];
|
|
439
|
-
// Compare version numbers
|
|
440
|
-
for (let i = 0; i < 4; i++) {
|
|
441
|
-
if (currentVersion[i] > requiredVersion[i])
|
|
442
|
-
return true;
|
|
443
|
-
if (currentVersion[i] < requiredVersion[i])
|
|
444
|
-
return false;
|
|
445
|
-
}
|
|
446
|
-
return true; // Versions are equal
|
|
447
|
-
}
|
|
448
|
-
break; // Found Chrome but couldn't parse version - continue with other paths
|
|
449
|
-
}
|
|
450
|
-
catch {
|
|
451
|
-
// Try next Chrome path
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
return false; // Chrome not found or version not supported
|
|
455
|
-
}
|
|
456
|
-
catch {
|
|
457
|
-
return false; // Any error means not supported
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
/**
|
|
461
|
-
* Clean up old dev3000 MCP entries from project's .mcp.json (Claude Code)
|
|
462
|
-
* MCP server has been removed - we now use CLI commands instead
|
|
463
|
-
*/
|
|
464
|
-
async function ensureMcpServers(_mcpPort, _appPort, _enableChromeDevtools) {
|
|
465
|
-
try {
|
|
466
|
-
const settingsPath = join(process.cwd(), ".mcp.json");
|
|
467
|
-
if (!existsSync(settingsPath)) {
|
|
468
|
-
return; // Nothing to clean up
|
|
469
|
-
}
|
|
470
|
-
const settingsContent = readFileSync(settingsPath, "utf-8");
|
|
471
|
-
const settings = JSON.parse(settingsContent);
|
|
472
|
-
if (!settings.mcpServers) {
|
|
473
|
-
return; // Nothing to clean up
|
|
474
|
-
}
|
|
475
|
-
let removed = false;
|
|
476
|
-
// Remove dev3000 MCP entry if it exists (MCP server removed)
|
|
477
|
-
if (settings.mcpServers[MCP_NAMES.DEV3000]) {
|
|
478
|
-
delete settings.mcpServers[MCP_NAMES.DEV3000];
|
|
479
|
-
removed = true;
|
|
480
|
-
}
|
|
481
|
-
// Write if we removed anything
|
|
482
|
-
if (removed) {
|
|
483
|
-
writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
catch (_error) {
|
|
487
|
-
// Ignore errors - settings file manipulation is optional
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
/**
|
|
491
|
-
* Clean up old dev3000 MCP entries from project's .cursor/mcp.json
|
|
492
|
-
* MCP server has been removed - we now use CLI commands instead
|
|
493
|
-
*/
|
|
494
|
-
async function ensureCursorMcpServers(_mcpPort, _appPort, _enableChromeDevtools) {
|
|
495
|
-
try {
|
|
496
|
-
const cursorDir = join(process.cwd(), ".cursor");
|
|
497
|
-
const settingsPath = join(cursorDir, "mcp.json");
|
|
498
|
-
if (!existsSync(settingsPath)) {
|
|
499
|
-
return; // Nothing to clean up
|
|
500
|
-
}
|
|
501
|
-
const settingsContent = readFileSync(settingsPath, "utf-8");
|
|
502
|
-
const settings = JSON.parse(settingsContent);
|
|
503
|
-
if (!settings.mcpServers) {
|
|
504
|
-
return; // Nothing to clean up
|
|
505
|
-
}
|
|
506
|
-
let removed = false;
|
|
507
|
-
// Remove dev3000 MCP entry if it exists (MCP server removed)
|
|
508
|
-
if (settings.mcpServers[MCP_NAMES.DEV3000]) {
|
|
509
|
-
delete settings.mcpServers[MCP_NAMES.DEV3000];
|
|
510
|
-
removed = true;
|
|
511
|
-
}
|
|
512
|
-
// Write if we removed anything
|
|
513
|
-
if (removed) {
|
|
514
|
-
writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
catch (_error) {
|
|
518
|
-
// Ignore errors - settings file manipulation is optional
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
/**
|
|
522
|
-
* Clean up old dev3000 MCP entries from project's opencode.json
|
|
523
|
-
* OpenCode uses "mcp" instead of "mcpServers"
|
|
524
|
-
* MCP server has been removed - we now use CLI commands instead
|
|
525
|
-
*/
|
|
526
|
-
async function ensureOpenCodeMcpServers(_mcpPort, _appPort, _enableChromeDevtools) {
|
|
527
|
-
try {
|
|
528
|
-
const settingsPath = join(process.cwd(), "opencode.json");
|
|
529
|
-
if (!existsSync(settingsPath)) {
|
|
530
|
-
return; // Nothing to clean up
|
|
531
|
-
}
|
|
532
|
-
const settingsContent = readFileSync(settingsPath, "utf-8");
|
|
533
|
-
const settings = JSON.parse(settingsContent);
|
|
534
|
-
if (!settings.mcp) {
|
|
535
|
-
return; // Nothing to clean up
|
|
536
|
-
}
|
|
537
|
-
let removed = false;
|
|
538
|
-
// Remove dev3000 MCP entry if it exists (MCP server removed)
|
|
539
|
-
if (settings.mcp[MCP_NAMES.DEV3000]) {
|
|
540
|
-
delete settings.mcp[MCP_NAMES.DEV3000];
|
|
541
|
-
removed = true;
|
|
542
|
-
}
|
|
543
|
-
// Write if we removed anything
|
|
544
|
-
if (removed) {
|
|
545
|
-
writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
catch (_error) {
|
|
549
|
-
// Ignore errors - settings file manipulation is optional
|
|
550
|
-
}
|
|
551
|
-
}
|
|
288
|
+
// Framework detection happens in cli.ts and is stored in session files for CLI integration
|
|
552
289
|
/**
|
|
553
290
|
* Ensure d3k skill is installed in project's .claude/skills/d3k/
|
|
554
291
|
* Claude Code reads from .claude/skills/ (must be real files, not symlinks)
|
|
555
292
|
*/
|
|
556
|
-
async function ensureD3kSkill() {
|
|
293
|
+
async function ensureD3kSkill(skillsAgentId) {
|
|
557
294
|
try {
|
|
558
295
|
const bundledSkillsDir = getBundledSkillsPath();
|
|
559
296
|
if (!bundledSkillsDir)
|
|
@@ -561,8 +298,13 @@ async function ensureD3kSkill() {
|
|
|
561
298
|
const bundledSkillPath = join(bundledSkillsDir, "d3k", "SKILL.md");
|
|
562
299
|
if (!existsSync(bundledSkillPath))
|
|
563
300
|
return;
|
|
564
|
-
|
|
565
|
-
|
|
301
|
+
const targetSkillsDir = skillsAgentId ? getSkillsPathForLocation(skillsAgentId, "project")?.path : null;
|
|
302
|
+
// Install directly to the agent-specific skills dir (fallback to .agents)
|
|
303
|
+
let skillsRoot = join(process.cwd(), ".agents", "skills");
|
|
304
|
+
if (targetSkillsDir) {
|
|
305
|
+
skillsRoot = targetSkillsDir;
|
|
306
|
+
}
|
|
307
|
+
const skillDir = join(skillsRoot, "d3k");
|
|
566
308
|
const skillPath = join(skillDir, "SKILL.md");
|
|
567
309
|
// Check if already up to date
|
|
568
310
|
const bundledContent = readFileSync(bundledSkillPath, "utf-8");
|
|
@@ -583,7 +325,7 @@ async function ensureD3kSkill() {
|
|
|
583
325
|
}
|
|
584
326
|
}
|
|
585
327
|
// REMOVED: cleanup functions are no longer needed
|
|
586
|
-
//
|
|
328
|
+
// CLI integration config files are now kept persistent across dev3000 restarts
|
|
587
329
|
export function createPersistentLogFile() {
|
|
588
330
|
// Get unique project name
|
|
589
331
|
const projectName = getProjectName();
|
|
@@ -605,7 +347,7 @@ export function createPersistentLogFile() {
|
|
|
605
347
|
}
|
|
606
348
|
}
|
|
607
349
|
/**
|
|
608
|
-
* Write session info for
|
|
350
|
+
* Write session info for external tooling to discover.
|
|
609
351
|
*
|
|
610
352
|
* CRITICAL FOR PROCESS CLEANUP:
|
|
611
353
|
* This writes the session.json file that contains chromePids and serverPid.
|
|
@@ -615,7 +357,7 @@ export function createPersistentLogFile() {
|
|
|
615
357
|
* processes belong to THIS d3k instance so we don't accidentally kill
|
|
616
358
|
* Chrome instances from other d3k sessions.
|
|
617
359
|
*/
|
|
618
|
-
export function writeSessionInfo(projectName, logFilePath, appPort,
|
|
360
|
+
export function writeSessionInfo(projectName, logFilePath, appPort, cdpUrl, chromePids, serverCommand, framework, serverPid) {
|
|
619
361
|
const projectDir = getProjectDir();
|
|
620
362
|
try {
|
|
621
363
|
// Create project directory if it doesn't exist
|
|
@@ -627,7 +369,6 @@ export function writeSessionInfo(projectName, logFilePath, appPort, mcpPort, cdp
|
|
|
627
369
|
projectName,
|
|
628
370
|
logFilePath,
|
|
629
371
|
appPort,
|
|
630
|
-
mcpPort: mcpPort || null,
|
|
631
372
|
cdpUrl: cdpUrl || null,
|
|
632
373
|
startTime: new Date().toISOString(),
|
|
633
374
|
pid: process.pid,
|
|
@@ -646,39 +387,16 @@ export function writeSessionInfo(projectName, logFilePath, appPort, mcpPort, cdp
|
|
|
646
387
|
console.warn(chalk.yellow(`⚠️ Could not write session info: ${error}`));
|
|
647
388
|
}
|
|
648
389
|
}
|
|
649
|
-
|
|
650
|
-
* Get Chrome PIDs for a d3k session from the session.json file.
|
|
651
|
-
*
|
|
652
|
-
* CRITICAL FOR PROCESS CLEANUP:
|
|
653
|
-
* Chrome PIDs are stored in session.json and used during shutdown to kill
|
|
654
|
-
* the specific Chrome instances spawned by THIS d3k instance.
|
|
655
|
-
*
|
|
656
|
-
* The SIGHUP handler uses this to synchronously kill Chrome on tmux close
|
|
657
|
-
* before the process terminates.
|
|
658
|
-
*
|
|
659
|
-
* @param projectName - The project name (used to locate session.json)
|
|
660
|
-
* @returns Array of Chrome PIDs, or empty array if none found
|
|
661
|
-
*/
|
|
662
|
-
export function getSessionChromePids(projectName) {
|
|
663
|
-
const sessionFile = join(homedir(), ".d3k", projectName, "session.json");
|
|
664
|
-
try {
|
|
665
|
-
if (existsSync(sessionFile)) {
|
|
666
|
-
const sessionInfo = JSON.parse(readFileSync(sessionFile, "utf8"));
|
|
667
|
-
return sessionInfo.chromePids || [];
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
catch (_error) {
|
|
671
|
-
// Non-fatal - return empty array
|
|
672
|
-
}
|
|
673
|
-
return [];
|
|
674
|
-
}
|
|
675
|
-
// Get server PID for this instance
|
|
676
|
-
function getSessionServerPid(projectName) {
|
|
390
|
+
function getSessionInfo(projectName) {
|
|
677
391
|
const sessionFile = join(homedir(), ".d3k", projectName, "session.json");
|
|
678
392
|
try {
|
|
679
393
|
if (existsSync(sessionFile)) {
|
|
680
394
|
const sessionInfo = JSON.parse(readFileSync(sessionFile, "utf8"));
|
|
681
|
-
return
|
|
395
|
+
return {
|
|
396
|
+
serverPid: sessionInfo.serverPid ?? null,
|
|
397
|
+
chromePids: sessionInfo.chromePids ?? [],
|
|
398
|
+
cwd: sessionInfo.cwd ?? null
|
|
399
|
+
};
|
|
682
400
|
}
|
|
683
401
|
}
|
|
684
402
|
catch (_error) {
|
|
@@ -686,6 +404,9 @@ function getSessionServerPid(projectName) {
|
|
|
686
404
|
}
|
|
687
405
|
return null;
|
|
688
406
|
}
|
|
407
|
+
export function getSessionChromePids(projectName) {
|
|
408
|
+
return getSessionInfo(projectName)?.chromePids ?? [];
|
|
409
|
+
}
|
|
689
410
|
function createLogFileInDir(baseDir, _projectName) {
|
|
690
411
|
// Create short timestamp: MMDD-HHmmss (e.g., 0106-171301)
|
|
691
412
|
const now = new Date();
|
|
@@ -751,22 +472,14 @@ export class DevEnvironment {
|
|
|
751
472
|
healthCheckTimer = null;
|
|
752
473
|
tui = null;
|
|
753
474
|
portChangeMessage = null;
|
|
754
|
-
chromeDevtoolsSupported = false;
|
|
755
475
|
portDetected = false;
|
|
756
476
|
serverUsesHttps = false;
|
|
757
|
-
disabledMcpConfigSet;
|
|
758
477
|
/** Returns "https" or "http" based on detected server protocol */
|
|
759
478
|
get serverProtocol() {
|
|
760
479
|
return this.serverUsesHttps ? "https" : "http";
|
|
761
480
|
}
|
|
762
481
|
constructor(options) {
|
|
763
|
-
|
|
764
|
-
this.options = {
|
|
765
|
-
...options,
|
|
766
|
-
mcpPort: options.portMcp || options.mcpPort || "3684",
|
|
767
|
-
disabledMcpConfigs: options.disabledMcpConfigs || []
|
|
768
|
-
};
|
|
769
|
-
this.disabledMcpConfigSet = new Set(this.options.disabledMcpConfigs);
|
|
482
|
+
this.options = { ...options };
|
|
770
483
|
this.logger = new Logger(options.logFile, options.tail || false, options.dateTimeFormat || "local");
|
|
771
484
|
this.outputProcessor = new OutputProcessor(new StandardLogParser(), new NextJsErrorDetector());
|
|
772
485
|
// Detect if running from compiled binary
|
|
@@ -789,6 +502,10 @@ export class DevEnvironment {
|
|
|
789
502
|
// Use project-specific PID and lock files to allow multiple projects to run simultaneously
|
|
790
503
|
this.pidFile = join(tmpdir(), `dev3000-${projectName}.pid`);
|
|
791
504
|
this.lockFile = join(tmpdir(), `dev3000-${projectName}.lock`);
|
|
505
|
+
// Allow CLI-level crash handlers to trigger emergency cleanup.
|
|
506
|
+
globalThis.__d3kEmergencyShutdown = (reason, error) => {
|
|
507
|
+
this.emergencyShutdown(1, reason, error);
|
|
508
|
+
};
|
|
792
509
|
// Read version - for compiled binaries, use injected version; otherwise read from package.json
|
|
793
510
|
this.version = "0.0.0";
|
|
794
511
|
// Check for compile-time injected version first
|
|
@@ -823,7 +540,7 @@ export class DevEnvironment {
|
|
|
823
540
|
this.spinner = ora({
|
|
824
541
|
text: "Initializing...",
|
|
825
542
|
spinner: "dots",
|
|
826
|
-
isEnabled: !options.tui // Disable spinner in TUI mode
|
|
543
|
+
isEnabled: !options.tui && !options.tail // Disable spinner in TUI mode
|
|
827
544
|
});
|
|
828
545
|
// Ensure screenshot directory exists
|
|
829
546
|
try {
|
|
@@ -842,14 +559,7 @@ export class DevEnvironment {
|
|
|
842
559
|
this.initializeD3KLog();
|
|
843
560
|
}
|
|
844
561
|
async checkPortsAvailable(silent = false) {
|
|
845
|
-
//
|
|
846
|
-
// This prevents "kill EPERM" errors when MCP tries to spawn new browsers
|
|
847
|
-
await cleanupOrphanedPlaywrightProcesses((msg) => this.debugLog(msg));
|
|
848
|
-
// MCP server removed - no longer need to kill
|
|
849
|
-
// if (this.options.mcpPort) {
|
|
850
|
-
// this.debugLog(`Ensuring port ${this.options.mcpPort} is free (always kill)`)
|
|
851
|
-
// await this.killMcpServer()
|
|
852
|
-
// }
|
|
562
|
+
// No legacy server to clean up; continue with port checks.
|
|
853
563
|
// Check if user explicitly set ports via CLI flags
|
|
854
564
|
const userSetAppPort = this.options.userSetPort || false;
|
|
855
565
|
// If user didn't set ports, find available ones first (before checking)
|
|
@@ -881,7 +591,7 @@ export class DevEnvironment {
|
|
|
881
591
|
throw new Error(`Port ${this.options.port} is already in use. Please free the port and try again.`);
|
|
882
592
|
}
|
|
883
593
|
}
|
|
884
|
-
//
|
|
594
|
+
// Legacy server removed - only check app port availability
|
|
885
595
|
}
|
|
886
596
|
async checkProcessHealth() {
|
|
887
597
|
if (this.isShuttingDown)
|
|
@@ -893,7 +603,7 @@ export class DevEnvironment {
|
|
|
893
603
|
return true;
|
|
894
604
|
}
|
|
895
605
|
try {
|
|
896
|
-
// Only check app port -
|
|
606
|
+
// Only check app port - legacy server has been removed
|
|
897
607
|
const ports = [this.options.port];
|
|
898
608
|
for (const port of ports) {
|
|
899
609
|
const result = await new Promise((resolve, reject) => {
|
|
@@ -938,32 +648,51 @@ export class DevEnvironment {
|
|
|
938
648
|
this.debugLog("Health check timer stopped");
|
|
939
649
|
}
|
|
940
650
|
}
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
if (enabledTargets.length === 0) {
|
|
944
|
-
this.logD3K("AI CLI Integration: MCP config generation disabled via --disable-mcp-configs/DEV3000_DISABLE_MCP_CONFIGS");
|
|
651
|
+
emergencyShutdown(exitCode, reason, error) {
|
|
652
|
+
if (this.isShuttingDown)
|
|
945
653
|
return;
|
|
654
|
+
this.isShuttingDown = true;
|
|
655
|
+
this.debugLog(`Emergency shutdown requested (${reason})`);
|
|
656
|
+
if (error) {
|
|
657
|
+
const errorText = error instanceof Error ? error.stack || error.message : String(error);
|
|
658
|
+
this.debugLog(`Emergency shutdown error: ${errorText}`);
|
|
946
659
|
}
|
|
947
|
-
|
|
948
|
-
if (
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
}
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
660
|
+
// Stop CDP reconnection attempts before killing the app server.
|
|
661
|
+
if (this.cdpMonitor) {
|
|
662
|
+
this.cdpMonitor.prepareShutdown();
|
|
663
|
+
}
|
|
664
|
+
// Best-effort synchronous cleanup (mirrors SIGHUP handler).
|
|
665
|
+
const { spawnSync } = require("child_process");
|
|
666
|
+
const port = this.options.port;
|
|
667
|
+
this.debugLog(`Synchronous kill for port ${port}`);
|
|
668
|
+
spawnSync("sh", ["-c", `lsof -ti:${port} | xargs kill -9 2>/dev/null`], {
|
|
669
|
+
stdio: "pipe",
|
|
670
|
+
timeout: 5000
|
|
671
|
+
});
|
|
672
|
+
const projectName = getProjectName();
|
|
673
|
+
const sessionInfo = getSessionInfo(projectName);
|
|
674
|
+
const chromePids = sessionInfo?.chromePids ?? [];
|
|
675
|
+
if (chromePids.length > 0) {
|
|
676
|
+
this.debugLog(`Synchronously killing Chrome PIDs: [${chromePids.join(", ")}]`);
|
|
677
|
+
for (const pid of chromePids) {
|
|
678
|
+
try {
|
|
679
|
+
process.kill(pid, "SIGTERM");
|
|
680
|
+
}
|
|
681
|
+
catch {
|
|
682
|
+
// Ignore - process may already be dead
|
|
683
|
+
}
|
|
684
|
+
}
|
|
963
685
|
}
|
|
964
|
-
|
|
965
|
-
this.
|
|
686
|
+
if (sessionInfo?.serverPid) {
|
|
687
|
+
this.killServerPidIfOwned(sessionInfo.serverPid, sessionInfo.cwd, `emergency:${reason}`);
|
|
966
688
|
}
|
|
689
|
+
this.handleShutdown()
|
|
690
|
+
.then(() => {
|
|
691
|
+
process.exit(exitCode);
|
|
692
|
+
})
|
|
693
|
+
.catch(() => {
|
|
694
|
+
process.exit(exitCode);
|
|
695
|
+
});
|
|
967
696
|
}
|
|
968
697
|
async start() {
|
|
969
698
|
// Check if another instance is already running for this project
|
|
@@ -974,6 +703,8 @@ export class DevEnvironment {
|
|
|
974
703
|
}
|
|
975
704
|
// Initialize telemetry session (used by version check)
|
|
976
705
|
initTelemetrySession(this.options.framework);
|
|
706
|
+
// Kill any orphaned server process from a previous run of this project
|
|
707
|
+
this.cleanupOrphanedServer();
|
|
977
708
|
// Check if TUI mode is enabled (default) and stdin supports it
|
|
978
709
|
const canUseTUI = this.options.tui && process.stdin.isTTY;
|
|
979
710
|
if (!canUseTUI && this.options.tui) {
|
|
@@ -988,7 +719,6 @@ export class DevEnvironment {
|
|
|
988
719
|
// Start TUI interface with initial status and updated port
|
|
989
720
|
this.tui = new DevTUI({
|
|
990
721
|
appPort: this.options.port, // This may have been updated by checkPortsAvailable
|
|
991
|
-
mcpPort: this.options.mcpPort || "3684",
|
|
992
722
|
logFile: this.options.logFile,
|
|
993
723
|
commandName: this.options.commandName,
|
|
994
724
|
serversOnly: this.options.serversOnly,
|
|
@@ -1014,6 +744,21 @@ export class DevEnvironment {
|
|
|
1014
744
|
stdio: "pipe",
|
|
1015
745
|
timeout: 5000
|
|
1016
746
|
});
|
|
747
|
+
const projectName = getProjectName();
|
|
748
|
+
const chromePids = getSessionChromePids(projectName);
|
|
749
|
+
if (chromePids.length > 0) {
|
|
750
|
+
this.debugLog(`Synchronous kill for Chrome PIDs: [${chromePids.join(", ")}]`);
|
|
751
|
+
for (const pid of chromePids) {
|
|
752
|
+
try {
|
|
753
|
+
process.kill(pid, "SIGTERM");
|
|
754
|
+
process.kill(pid, 0);
|
|
755
|
+
process.kill(pid, "SIGKILL");
|
|
756
|
+
}
|
|
757
|
+
catch {
|
|
758
|
+
// Ignore - process may already be dead
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
1017
762
|
// Now do the rest of cleanup async
|
|
1018
763
|
this.tui?.updateStatus("Shutting down...");
|
|
1019
764
|
this.handleShutdown()
|
|
@@ -1049,6 +794,9 @@ export class DevEnvironment {
|
|
|
1049
794
|
});
|
|
1050
795
|
// Show initial status message
|
|
1051
796
|
await this.tui.updateStatus("d3k is checking for skill updates...");
|
|
797
|
+
// Install d3k skill early so it's available when Claude Code starts
|
|
798
|
+
// This is important for --with-agent where both start simultaneously
|
|
799
|
+
await ensureD3kSkill(this.options.skillsAgentId);
|
|
1052
800
|
// Check ports in background after TUI is visible
|
|
1053
801
|
await this.checkPortsAvailable(true); // silent mode for TUI
|
|
1054
802
|
// Update the app port in TUI (may have changed during port check)
|
|
@@ -1073,7 +821,7 @@ export class DevEnvironment {
|
|
|
1073
821
|
// Start user's dev server
|
|
1074
822
|
await this.tui.updateStatus("Starting your dev server...");
|
|
1075
823
|
await this.startServer();
|
|
1076
|
-
//
|
|
824
|
+
// Legacy tools server removed - using CLI commands instead
|
|
1077
825
|
// await this.startMcpServer()
|
|
1078
826
|
// Wait for servers to be ready
|
|
1079
827
|
await this.tui.updateStatus("Waiting for app...");
|
|
@@ -1087,21 +835,8 @@ export class DevEnvironment {
|
|
|
1087
835
|
}
|
|
1088
836
|
// Update TUI with confirmed port (may have changed during server startup)
|
|
1089
837
|
this.tui.updateAppPort(this.options.port);
|
|
1090
|
-
//
|
|
838
|
+
// Legacy tools server removed - using CLI commands instead
|
|
1091
839
|
// await this.waitForMcpServer()
|
|
1092
|
-
// Configure AI CLI integrations (both dev3000 and chrome-devtools MCPs)
|
|
1093
|
-
if (!this.options.serversOnly) {
|
|
1094
|
-
await this.tui.updateStatus("Configuring AI CLI integrations...");
|
|
1095
|
-
// Check if Chrome version supports chrome-devtools MCP
|
|
1096
|
-
if (this.options.chromeDevtoolsMcp !== false) {
|
|
1097
|
-
this.chromeDevtoolsSupported = await isChromeDevtoolsMcpSupported();
|
|
1098
|
-
if (!this.chromeDevtoolsSupported) {
|
|
1099
|
-
this.logD3K("Chrome version < 140.0.7339.214 detected - chrome-devtools MCP will be skipped");
|
|
1100
|
-
}
|
|
1101
|
-
}
|
|
1102
|
-
// Ensure MCP server configurations in project settings files (instant, local)
|
|
1103
|
-
await this.configureMcpConfigs();
|
|
1104
|
-
}
|
|
1105
840
|
// Start CDP monitoring only if server started successfully and not in servers-only mode
|
|
1106
841
|
if (!this.options.serversOnly && serverStarted) {
|
|
1107
842
|
await this.tui.updateStatus(`Starting ${this.options.commandName} browser...`);
|
|
@@ -1113,16 +848,19 @@ export class DevEnvironment {
|
|
|
1113
848
|
else {
|
|
1114
849
|
this.debugLog("Browser monitoring disabled via --servers-only flag");
|
|
1115
850
|
}
|
|
1116
|
-
// Write session info for
|
|
851
|
+
// Write session info for tooling discovery (include CDP URL if browser monitoring was started)
|
|
1117
852
|
const cdpUrl = this.cdpMonitor?.getCdpUrl() || null;
|
|
1118
853
|
const chromePids = this.cdpMonitor?.getChromePids() || [];
|
|
1119
|
-
writeSessionInfo(projectName, this.options.logFile, this.options.port,
|
|
854
|
+
writeSessionInfo(projectName, this.options.logFile, this.options.port, cdpUrl, chromePids, this.options.serverCommand, this.options.framework, this.serverProcess?.pid);
|
|
1120
855
|
// Clear status - ready!
|
|
1121
856
|
await this.tui.updateStatus(null);
|
|
1122
857
|
}
|
|
1123
858
|
else {
|
|
1124
859
|
// Non-TUI mode - original flow
|
|
1125
860
|
console.log(chalk.hex("#A18CE5")(`Starting ${this.options.commandName} (v${this.version})`));
|
|
861
|
+
// Install d3k skill early so it's available when Claude Code starts
|
|
862
|
+
// This is important for --with-agent where both start simultaneously
|
|
863
|
+
await ensureD3kSkill(this.options.skillsAgentId);
|
|
1126
864
|
// Start spinner
|
|
1127
865
|
this.spinner.start("Checking ports...");
|
|
1128
866
|
// Check if ports are available first
|
|
@@ -1135,7 +873,7 @@ export class DevEnvironment {
|
|
|
1135
873
|
// Start user's dev server
|
|
1136
874
|
this.spinner.text = "Starting your dev server...";
|
|
1137
875
|
await this.startServer();
|
|
1138
|
-
//
|
|
876
|
+
// Legacy server removed - using CLI commands instead
|
|
1139
877
|
// await this.startMcpServer()
|
|
1140
878
|
// Wait for servers to be ready
|
|
1141
879
|
this.spinner.text = "Waiting for app...";
|
|
@@ -1147,21 +885,8 @@ export class DevEnvironment {
|
|
|
1147
885
|
console.error(chalk.yellow("Exiting without launching browser."));
|
|
1148
886
|
process.exit(1);
|
|
1149
887
|
}
|
|
1150
|
-
//
|
|
888
|
+
// Legacy server removed - using CLI commands instead
|
|
1151
889
|
// await this.waitForMcpServer()
|
|
1152
|
-
// Configure AI CLI integrations (both dev3000 and chrome-devtools MCPs)
|
|
1153
|
-
if (!this.options.serversOnly) {
|
|
1154
|
-
this.spinner.text = "Configuring AI CLI integrations...";
|
|
1155
|
-
// Check if Chrome version supports chrome-devtools MCP
|
|
1156
|
-
if (this.options.chromeDevtoolsMcp !== false) {
|
|
1157
|
-
this.chromeDevtoolsSupported = await isChromeDevtoolsMcpSupported();
|
|
1158
|
-
if (!this.chromeDevtoolsSupported) {
|
|
1159
|
-
this.logD3K("Chrome version < 140.0.7339.214 detected - chrome-devtools MCP will be skipped");
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
// Ensure MCP server configurations in project settings files (instant, local)
|
|
1163
|
-
await this.configureMcpConfigs();
|
|
1164
|
-
}
|
|
1165
890
|
// Start CDP monitoring only if server started successfully and not in servers-only mode
|
|
1166
891
|
if (!this.options.serversOnly && serverStarted) {
|
|
1167
892
|
this.spinner.text = `Starting ${this.options.commandName} browser...`;
|
|
@@ -1178,7 +903,7 @@ export class DevEnvironment {
|
|
|
1178
903
|
// Include CDP URL if browser monitoring was started
|
|
1179
904
|
const cdpUrl = this.cdpMonitor?.getCdpUrl() || null;
|
|
1180
905
|
const chromePids = this.cdpMonitor?.getChromePids() || [];
|
|
1181
|
-
writeSessionInfo(projectName, this.options.logFile, this.options.port,
|
|
906
|
+
writeSessionInfo(projectName, this.options.logFile, this.options.port, cdpUrl, chromePids, this.options.serverCommand, this.options.framework, this.serverProcess?.pid);
|
|
1182
907
|
// Complete startup with success message only in non-TUI mode
|
|
1183
908
|
this.spinner.succeed("Development environment ready!");
|
|
1184
909
|
// Regular console output (when TUI is disabled with --no-tui)
|
|
@@ -1187,7 +912,7 @@ export class DevEnvironment {
|
|
|
1187
912
|
console.log(chalk.cyan(`🌐 Your App: ${this.serverProtocol}://localhost:${this.options.port}`));
|
|
1188
913
|
console.log(chalk.cyan(`🔧 CLI Tools: d3k fix, d3k crawl, d3k find-component`));
|
|
1189
914
|
if (this.options.serversOnly) {
|
|
1190
|
-
console.log(chalk.cyan("🖥️ Servers-only mode -
|
|
915
|
+
console.log(chalk.cyan("🖥️ Servers-only mode - browser monitoring disabled"));
|
|
1191
916
|
}
|
|
1192
917
|
console.log(chalk.cyan("\nUse Ctrl-C to stop.\n"));
|
|
1193
918
|
// Auto-upgrade in non-TUI mode (non-blocking)
|
|
@@ -1322,6 +1047,83 @@ export class DevEnvironment {
|
|
|
1322
1047
|
}
|
|
1323
1048
|
});
|
|
1324
1049
|
}
|
|
1050
|
+
isSessionCwdOwned(sessionCwd) {
|
|
1051
|
+
if (!sessionCwd)
|
|
1052
|
+
return false;
|
|
1053
|
+
try {
|
|
1054
|
+
const current = resolve(process.cwd());
|
|
1055
|
+
const session = resolve(sessionCwd);
|
|
1056
|
+
return session === current || current.startsWith(session + sep) || session.startsWith(current + sep);
|
|
1057
|
+
}
|
|
1058
|
+
catch {
|
|
1059
|
+
return false;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
isPidRunning(pid) {
|
|
1063
|
+
try {
|
|
1064
|
+
process.kill(pid, 0);
|
|
1065
|
+
return true;
|
|
1066
|
+
}
|
|
1067
|
+
catch {
|
|
1068
|
+
return false;
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
killServerPidIfOwned(pid, sessionCwd, reason) {
|
|
1072
|
+
if (!this.isSessionCwdOwned(sessionCwd)) {
|
|
1073
|
+
this.debugLog(`Skipping server PID ${pid} kill (${reason}): session cwd mismatch`);
|
|
1074
|
+
return;
|
|
1075
|
+
}
|
|
1076
|
+
if (!this.isPidRunning(pid)) {
|
|
1077
|
+
this.debugLog(`Skipping server PID ${pid} kill (${reason}): not running`);
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
1080
|
+
this.debugLog(`Killing server PID ${pid} (${reason})`);
|
|
1081
|
+
try {
|
|
1082
|
+
process.kill(pid, "SIGTERM");
|
|
1083
|
+
}
|
|
1084
|
+
catch {
|
|
1085
|
+
// Ignore - process may already be dead
|
|
1086
|
+
}
|
|
1087
|
+
if (process.platform !== "win32") {
|
|
1088
|
+
try {
|
|
1089
|
+
process.kill(-pid, "SIGTERM");
|
|
1090
|
+
}
|
|
1091
|
+
catch {
|
|
1092
|
+
// Ignore - process group may not exist
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
try {
|
|
1096
|
+
process.kill(pid, 0);
|
|
1097
|
+
process.kill(pid, "SIGKILL");
|
|
1098
|
+
}
|
|
1099
|
+
catch {
|
|
1100
|
+
// Ignore - process may already be dead
|
|
1101
|
+
}
|
|
1102
|
+
if (process.platform !== "win32") {
|
|
1103
|
+
try {
|
|
1104
|
+
process.kill(-pid, "SIGKILL");
|
|
1105
|
+
}
|
|
1106
|
+
catch {
|
|
1107
|
+
// Ignore - process group may not exist
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
if (!isInSandbox()) {
|
|
1111
|
+
try {
|
|
1112
|
+
const { spawnSync } = require("child_process");
|
|
1113
|
+
spawnSync("pkill", ["-P", pid.toString()], { stdio: "ignore" });
|
|
1114
|
+
}
|
|
1115
|
+
catch {
|
|
1116
|
+
// Ignore pkill errors
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
cleanupOrphanedServer() {
|
|
1121
|
+
const projectName = getProjectName();
|
|
1122
|
+
const sessionInfo = getSessionInfo(projectName);
|
|
1123
|
+
if (!sessionInfo?.serverPid)
|
|
1124
|
+
return;
|
|
1125
|
+
this.killServerPidIfOwned(sessionInfo.serverPid, sessionInfo.cwd, "startup orphan cleanup");
|
|
1126
|
+
}
|
|
1325
1127
|
acquireLock() {
|
|
1326
1128
|
try {
|
|
1327
1129
|
// Check if lock file exists
|
|
@@ -1378,7 +1180,7 @@ export class DevEnvironment {
|
|
|
1378
1180
|
const cdpUrl = this.cdpMonitor?.getCdpUrl();
|
|
1379
1181
|
const chromePids = this.cdpMonitor?.getChromePids() || [];
|
|
1380
1182
|
if (cdpUrl || chromePids.length > 0) {
|
|
1381
|
-
writeSessionInfo(projectName, this.options.logFile, this.options.port,
|
|
1183
|
+
writeSessionInfo(projectName, this.options.logFile, this.options.port, cdpUrl || undefined, chromePids, this.options.serverCommand, this.options.framework, this.serverProcess?.pid);
|
|
1382
1184
|
this.debugLog(`Updated session info with new port: ${this.options.port}`);
|
|
1383
1185
|
}
|
|
1384
1186
|
// Update TUI header with new port
|
|
@@ -1557,23 +1359,6 @@ export class DevEnvironment {
|
|
|
1557
1359
|
// Ignore D3K log initialization errors - non-critical
|
|
1558
1360
|
}
|
|
1559
1361
|
}
|
|
1560
|
-
logD3K(message) {
|
|
1561
|
-
// Write [D3K] logs to project-specific dev3000 debug log, NOT to main project log
|
|
1562
|
-
// This prevents Claude from thinking dev3000's orchestration logic needs to be "fixed"
|
|
1563
|
-
const timestamp = formatTimestamp(new Date(), this.options.dateTimeFormat || "local");
|
|
1564
|
-
const logEntry = `[${timestamp}] [D3K] ${message}\n`;
|
|
1565
|
-
try {
|
|
1566
|
-
const projectDir = getProjectDir();
|
|
1567
|
-
if (!existsSync(projectDir)) {
|
|
1568
|
-
mkdirSync(projectDir, { recursive: true });
|
|
1569
|
-
}
|
|
1570
|
-
const d3kLogFile = join(projectDir, "d3k.log");
|
|
1571
|
-
appendFileSync(d3kLogFile, logEntry);
|
|
1572
|
-
}
|
|
1573
|
-
catch {
|
|
1574
|
-
// Ignore D3K log write errors - non-critical
|
|
1575
|
-
}
|
|
1576
|
-
}
|
|
1577
1362
|
async startCDPMonitoringSync() {
|
|
1578
1363
|
// Skip if in servers-only mode
|
|
1579
1364
|
if (this.options.serversOnly) {
|
|
@@ -1603,7 +1388,6 @@ export class DevEnvironment {
|
|
|
1603
1388
|
this.cdpMonitor = new CDPMonitor(this.options.profileDir, this.screenshotDir, (_source, message) => {
|
|
1604
1389
|
this.logger.log("browser", message);
|
|
1605
1390
|
}, this.options.debug, this.options.browser, this.options.pluginReactScan, this.options.port, // App server port to monitor
|
|
1606
|
-
this.options.mcpPort, // MCP server port to ignore
|
|
1607
1391
|
this.options.debugPort, // Chrome debug port
|
|
1608
1392
|
this.options.headless // Headless mode for serverless/CI environments
|
|
1609
1393
|
);
|
|
@@ -1633,7 +1417,7 @@ export class DevEnvironment {
|
|
|
1633
1417
|
}
|
|
1634
1418
|
// Always write session info after CDP monitoring starts - this is critical for
|
|
1635
1419
|
// sandbox environments where external tools poll for the cdpUrl in the session file
|
|
1636
|
-
writeSessionInfo(projectName, this.options.logFile, this.options.port,
|
|
1420
|
+
writeSessionInfo(projectName, this.options.logFile, this.options.port, cdpUrl || undefined, chromePids, this.options.serverCommand, this.options.framework, this.serverProcess?.pid);
|
|
1637
1421
|
this.debugLog(`Updated session info with CDP URL: ${cdpUrl}, Chrome PIDs: [${chromePids.join(", ")}]`);
|
|
1638
1422
|
this.logger.log("browser", `[CDP] Session info written with cdpUrl: ${cdpUrl ? "available" : "null"}`);
|
|
1639
1423
|
// Navigate to the app
|
|
@@ -1657,9 +1441,9 @@ export class DevEnvironment {
|
|
|
1657
1441
|
await this.screencastManager.stop();
|
|
1658
1442
|
this.screencastManager = null;
|
|
1659
1443
|
}
|
|
1660
|
-
// Read
|
|
1444
|
+
// Read session info BEFORE deleting it (needed for cleanup)
|
|
1661
1445
|
const projectName = getProjectName();
|
|
1662
|
-
const
|
|
1446
|
+
const sessionInfo = getSessionInfo(projectName);
|
|
1663
1447
|
// Clean up session file
|
|
1664
1448
|
try {
|
|
1665
1449
|
const sessionFile = join(homedir(), ".d3k", projectName, "session.json");
|
|
@@ -1670,7 +1454,7 @@ export class DevEnvironment {
|
|
|
1670
1454
|
catch (_error) {
|
|
1671
1455
|
// Non-fatal - ignore cleanup errors
|
|
1672
1456
|
}
|
|
1673
|
-
// Check PID file ownership BEFORE deleting (needed for
|
|
1457
|
+
// Check PID file ownership BEFORE deleting (needed for cleanup decisions)
|
|
1674
1458
|
let weOwnPidFile = false;
|
|
1675
1459
|
try {
|
|
1676
1460
|
if (existsSync(this.pidFile)) {
|
|
@@ -1720,26 +1504,12 @@ export class DevEnvironment {
|
|
|
1720
1504
|
console.log(chalk.gray(`⚠️ Could not kill ${name} on port ${port}`));
|
|
1721
1505
|
}
|
|
1722
1506
|
};
|
|
1723
|
-
// Kill app server only
|
|
1507
|
+
// Kill app server only
|
|
1724
1508
|
console.log(chalk.cyan("🔄 Killing app server..."));
|
|
1725
1509
|
await killPortProcess(this.options.port, "your app server");
|
|
1726
1510
|
// Kill server process and its children using the saved PID (from before session file was deleted)
|
|
1727
|
-
if (
|
|
1728
|
-
|
|
1729
|
-
const { spawnSync } = await import("child_process");
|
|
1730
|
-
// Kill all child processes of the server
|
|
1731
|
-
spawnSync("pkill", ["-P", savedServerPid.toString()], { stdio: "ignore" });
|
|
1732
|
-
// Kill the server process itself
|
|
1733
|
-
try {
|
|
1734
|
-
process.kill(savedServerPid, "SIGKILL");
|
|
1735
|
-
}
|
|
1736
|
-
catch {
|
|
1737
|
-
// Process may already be dead
|
|
1738
|
-
}
|
|
1739
|
-
}
|
|
1740
|
-
catch {
|
|
1741
|
-
// Ignore pkill errors
|
|
1742
|
-
}
|
|
1511
|
+
if (sessionInfo?.serverPid) {
|
|
1512
|
+
this.killServerPidIfOwned(sessionInfo.serverPid, sessionInfo.cwd, "graceful shutdown");
|
|
1743
1513
|
}
|
|
1744
1514
|
// Shutdown CDP monitor if it was started
|
|
1745
1515
|
if (this.cdpMonitor) {
|
|
@@ -1752,26 +1522,6 @@ export class DevEnvironment {
|
|
|
1752
1522
|
console.log(chalk.gray("⚠️ CDP monitor shutdown failed"));
|
|
1753
1523
|
}
|
|
1754
1524
|
}
|
|
1755
|
-
// Kill MCP server only if this is the last d3k instance AND we own the PID file
|
|
1756
|
-
const otherInstances = countActiveD3kInstances(true); // exclude current process
|
|
1757
|
-
this.debugLog(`Other active d3k instances: ${otherInstances}, weOwnPidFile: ${weOwnPidFile}`);
|
|
1758
|
-
if (otherInstances === 0 && this.options.mcpPort && !isInSandbox() && weOwnPidFile) {
|
|
1759
|
-
console.log(chalk.yellow("🔄 Killing MCP server (last d3k instance)..."));
|
|
1760
|
-
try {
|
|
1761
|
-
const { spawnSync } = await import("child_process");
|
|
1762
|
-
spawnSync("sh", ["-c", `lsof -ti:${this.options.mcpPort} -sTCP:LISTEN | xargs kill -9 2>/dev/null`], {
|
|
1763
|
-
stdio: "pipe",
|
|
1764
|
-
timeout: 5000
|
|
1765
|
-
});
|
|
1766
|
-
console.log(chalk.green("✅ MCP server stopped"));
|
|
1767
|
-
}
|
|
1768
|
-
catch {
|
|
1769
|
-
// Ignore errors
|
|
1770
|
-
}
|
|
1771
|
-
}
|
|
1772
|
-
else if (!weOwnPidFile) {
|
|
1773
|
-
this.debugLog("Skipping MCP cleanup - we don't own the PID file (subprocess will handle it)");
|
|
1774
|
-
}
|
|
1775
1525
|
console.log(chalk.red(`❌ ${this.options.commandName} exited due to server failure`));
|
|
1776
1526
|
// Show recent log entries to help diagnose the issue
|
|
1777
1527
|
this.showRecentLogs();
|
|
@@ -1817,6 +1567,25 @@ export class DevEnvironment {
|
|
|
1817
1567
|
stdio: "pipe",
|
|
1818
1568
|
timeout: 5000
|
|
1819
1569
|
});
|
|
1570
|
+
const projectName = getProjectName();
|
|
1571
|
+
const sessionInfo = getSessionInfo(projectName);
|
|
1572
|
+
const chromePids = sessionInfo?.chromePids ?? [];
|
|
1573
|
+
if (chromePids.length > 0) {
|
|
1574
|
+
this.debugLog(`Synchronous kill for Chrome PIDs: [${chromePids.join(", ")}]`);
|
|
1575
|
+
for (const pid of chromePids) {
|
|
1576
|
+
try {
|
|
1577
|
+
process.kill(pid, "SIGTERM");
|
|
1578
|
+
process.kill(pid, 0);
|
|
1579
|
+
process.kill(pid, "SIGKILL");
|
|
1580
|
+
}
|
|
1581
|
+
catch {
|
|
1582
|
+
// Ignore - process may already be dead
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
if (sessionInfo?.serverPid) {
|
|
1587
|
+
this.killServerPidIfOwned(sessionInfo.serverPid, sessionInfo.cwd, "SIGINT");
|
|
1588
|
+
}
|
|
1820
1589
|
if (this.options.tui && this.tui) {
|
|
1821
1590
|
// In TUI mode, show shutting down message
|
|
1822
1591
|
this.debugLog("Updating TUI status with shutdown message");
|
|
@@ -1858,6 +1627,25 @@ export class DevEnvironment {
|
|
|
1858
1627
|
stdio: "pipe",
|
|
1859
1628
|
timeout: 5000
|
|
1860
1629
|
});
|
|
1630
|
+
const projectName = getProjectName();
|
|
1631
|
+
const sessionInfo = getSessionInfo(projectName);
|
|
1632
|
+
const chromePids = sessionInfo?.chromePids ?? [];
|
|
1633
|
+
if (chromePids.length > 0) {
|
|
1634
|
+
this.debugLog(`Synchronous kill for Chrome PIDs: [${chromePids.join(", ")}]`);
|
|
1635
|
+
for (const pid of chromePids) {
|
|
1636
|
+
try {
|
|
1637
|
+
process.kill(pid, "SIGTERM");
|
|
1638
|
+
process.kill(pid, 0);
|
|
1639
|
+
process.kill(pid, "SIGKILL");
|
|
1640
|
+
}
|
|
1641
|
+
catch {
|
|
1642
|
+
// Ignore - process may already be dead
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
if (sessionInfo?.serverPid) {
|
|
1647
|
+
this.killServerPidIfOwned(sessionInfo.serverPid, sessionInfo.cwd, "SIGTERM");
|
|
1648
|
+
}
|
|
1861
1649
|
this.handleShutdown()
|
|
1862
1650
|
.then(() => {
|
|
1863
1651
|
process.exit(0);
|
|
@@ -1877,66 +1665,18 @@ export class DevEnvironment {
|
|
|
1877
1665
|
* 1. Signal CDP monitor to stop reconnection attempts
|
|
1878
1666
|
* 2. Kill dev server processes on app port (synchronous via lsof)
|
|
1879
1667
|
* 3. Kill Chrome PIDs from session.json (synchronous)
|
|
1880
|
-
* 4.
|
|
1881
|
-
* 5. Call handleShutdown() for async cleanup
|
|
1668
|
+
* 4. Call handleShutdown() for async cleanup
|
|
1882
1669
|
*
|
|
1883
1670
|
* INVARIANTS (enforced by tests in dev-environment.test.ts):
|
|
1884
1671
|
* - Chrome PIDs are stored per-session in session.json
|
|
1885
1672
|
* - We only kill Chrome instances WE spawned (via chromePids array)
|
|
1886
|
-
* - MCP server is only killed when countActiveD3kInstances() returns 0
|
|
1887
1673
|
* - All cleanup happens BEFORE process.exit()
|
|
1888
1674
|
*
|
|
1889
1675
|
* @see dev-environment.test.ts - "SIGHUP handler cleanup" test suite
|
|
1890
1676
|
*/
|
|
1891
1677
|
process.on("SIGHUP", () => {
|
|
1892
1678
|
this.debugLog("SIGHUP received (tmux session closing)");
|
|
1893
|
-
|
|
1894
|
-
return;
|
|
1895
|
-
this.isShuttingDown = true;
|
|
1896
|
-
// 1. Signal CDP monitor to stop reconnection attempts
|
|
1897
|
-
if (this.cdpMonitor) {
|
|
1898
|
-
this.cdpMonitor.prepareShutdown();
|
|
1899
|
-
}
|
|
1900
|
-
// 2. CRITICAL: Kill dev server processes SYNCHRONOUSLY
|
|
1901
|
-
// tmux might kill us quickly, so we can't rely on async cleanup
|
|
1902
|
-
const { spawnSync } = require("child_process");
|
|
1903
|
-
const port = this.options.port;
|
|
1904
|
-
this.debugLog(`Synchronous kill for port ${port}`);
|
|
1905
|
-
spawnSync("sh", ["-c", `lsof -ti:${port} | xargs kill -9 2>/dev/null`], {
|
|
1906
|
-
stdio: "pipe",
|
|
1907
|
-
timeout: 5000
|
|
1908
|
-
});
|
|
1909
|
-
// 3. CRITICAL: Kill Chrome PIDs synchronously
|
|
1910
|
-
// Get Chrome PIDs from session file before it gets deleted
|
|
1911
|
-
const projectName = getProjectName();
|
|
1912
|
-
const chromePids = getSessionChromePids(projectName);
|
|
1913
|
-
if (chromePids.length > 0) {
|
|
1914
|
-
this.debugLog(`Synchronously killing Chrome PIDs: [${chromePids.join(", ")}]`);
|
|
1915
|
-
for (const pid of chromePids) {
|
|
1916
|
-
try {
|
|
1917
|
-
process.kill(pid, "SIGTERM");
|
|
1918
|
-
}
|
|
1919
|
-
catch {
|
|
1920
|
-
// Ignore - process may already be dead
|
|
1921
|
-
}
|
|
1922
|
-
}
|
|
1923
|
-
}
|
|
1924
|
-
// 4. CRITICAL: Kill MCP server only if we're the LAST instance
|
|
1925
|
-
const otherInstances = countActiveD3kInstances(true);
|
|
1926
|
-
if (otherInstances === 0 && this.options.mcpPort) {
|
|
1927
|
-
this.debugLog(`Synchronously killing MCP server on port ${this.options.mcpPort}`);
|
|
1928
|
-
spawnSync("sh", ["-c", `lsof -ti:${this.options.mcpPort} -sTCP:LISTEN | xargs kill -9 2>/dev/null`], {
|
|
1929
|
-
stdio: "pipe",
|
|
1930
|
-
timeout: 5000
|
|
1931
|
-
});
|
|
1932
|
-
}
|
|
1933
|
-
this.handleShutdown()
|
|
1934
|
-
.then(() => {
|
|
1935
|
-
process.exit(0);
|
|
1936
|
-
})
|
|
1937
|
-
.catch(() => {
|
|
1938
|
-
process.exit(1);
|
|
1939
|
-
});
|
|
1679
|
+
this.emergencyShutdown(0, "SIGHUP");
|
|
1940
1680
|
});
|
|
1941
1681
|
}
|
|
1942
1682
|
async handleShutdown() {
|
|
@@ -1946,9 +1686,9 @@ export class DevEnvironment {
|
|
|
1946
1686
|
sendSessionEndTelemetry().catch(() => { });
|
|
1947
1687
|
// Release the lock file
|
|
1948
1688
|
this.releaseLock();
|
|
1949
|
-
// Read
|
|
1689
|
+
// Read session info BEFORE deleting it (needed for cleanup)
|
|
1950
1690
|
const projectName = getProjectName();
|
|
1951
|
-
const
|
|
1691
|
+
const sessionInfo = getSessionInfo(projectName);
|
|
1952
1692
|
// Clean up session file
|
|
1953
1693
|
try {
|
|
1954
1694
|
const sessionFile = join(homedir(), ".d3k", projectName, "session.json");
|
|
@@ -1959,8 +1699,7 @@ export class DevEnvironment {
|
|
|
1959
1699
|
catch (_error) {
|
|
1960
1700
|
// Non-fatal - ignore cleanup errors
|
|
1961
1701
|
}
|
|
1962
|
-
// Check PID file ownership BEFORE deleting (needed for
|
|
1963
|
-
// Only the process that owns the PID file should clean up the MCP server
|
|
1702
|
+
// Check PID file ownership BEFORE deleting (needed for cleanup decisions)
|
|
1964
1703
|
let weOwnPidFile = false;
|
|
1965
1704
|
try {
|
|
1966
1705
|
if (existsSync(this.pidFile)) {
|
|
@@ -2013,7 +1752,8 @@ export class DevEnvironment {
|
|
|
2013
1752
|
// Fallback: force kill any remaining Chrome processes for THIS instance only
|
|
2014
1753
|
try {
|
|
2015
1754
|
const projectName = getProjectName();
|
|
2016
|
-
const
|
|
1755
|
+
const sessionInfo = getSessionInfo(projectName);
|
|
1756
|
+
const chromePids = sessionInfo?.chromePids ?? [];
|
|
2017
1757
|
if (chromePids.length > 0) {
|
|
2018
1758
|
this.debugLog(`Fallback cleanup: killing Chrome PIDs for this instance: [${chromePids.join(", ")}]`);
|
|
2019
1759
|
const { spawn } = await import("child_process");
|
|
@@ -2029,16 +1769,18 @@ export class DevEnvironment {
|
|
|
2029
1769
|
else {
|
|
2030
1770
|
this.debugLog("Fallback cleanup: no Chrome PIDs found for this instance");
|
|
2031
1771
|
}
|
|
1772
|
+
if (sessionInfo?.serverPid) {
|
|
1773
|
+
this.killServerPidIfOwned(sessionInfo.serverPid, sessionInfo.cwd, "TUI shutdown");
|
|
1774
|
+
}
|
|
2032
1775
|
}
|
|
2033
1776
|
catch {
|
|
2034
1777
|
// Ignore errors in fallback cleanup
|
|
2035
1778
|
}
|
|
2036
1779
|
}
|
|
2037
1780
|
}
|
|
2038
|
-
// REMOVED: No longer clean up
|
|
1781
|
+
// REMOVED: No longer clean up CLI config files on shutdown
|
|
2039
1782
|
// This was causing Claude Code instances to crash when dev3000 was killed
|
|
2040
|
-
//
|
|
2041
|
-
// for the next dev3000 run, providing a better developer experience
|
|
1783
|
+
// Config file cleanup removed; keep user config files untouched on shutdown
|
|
2042
1784
|
// Kill processes on both ports (skip in sandbox - lsof doesn't exist)
|
|
2043
1785
|
const killPortProcess = async (port, name) => {
|
|
2044
1786
|
// Skip lsof-based kill in sandbox environments
|
|
@@ -2093,7 +1835,7 @@ export class DevEnvironment {
|
|
|
2093
1835
|
}
|
|
2094
1836
|
}
|
|
2095
1837
|
};
|
|
2096
|
-
// Kill app server
|
|
1838
|
+
// Kill app server
|
|
2097
1839
|
if (!this.options.tui) {
|
|
2098
1840
|
console.log(chalk.yellow("🔄 Killing app server..."));
|
|
2099
1841
|
}
|
|
@@ -2148,18 +1890,8 @@ export class DevEnvironment {
|
|
|
2148
1890
|
spawnSync("sh", ["-c", `pkill -f "next-server.*${cwd}"`], { stdio: "ignore" });
|
|
2149
1891
|
this.debugLog(`Sent pkill signal for next processes in ${cwd}`);
|
|
2150
1892
|
// Kill server process and its children using the saved PID (from before session file was deleted)
|
|
2151
|
-
if (
|
|
2152
|
-
|
|
2153
|
-
spawnSync("pkill", ["-P", savedServerPid.toString()], { stdio: "ignore" });
|
|
2154
|
-
this.debugLog(`Killed children of server PID ${savedServerPid}`);
|
|
2155
|
-
// Kill the server process itself
|
|
2156
|
-
try {
|
|
2157
|
-
process.kill(savedServerPid, "SIGKILL");
|
|
2158
|
-
this.debugLog(`Killed server PID ${savedServerPid}`);
|
|
2159
|
-
}
|
|
2160
|
-
catch {
|
|
2161
|
-
// Process may already be dead
|
|
2162
|
-
}
|
|
1893
|
+
if (sessionInfo?.serverPid) {
|
|
1894
|
+
this.killServerPidIfOwned(sessionInfo.serverPid, sessionInfo.cwd, "handleShutdown");
|
|
2163
1895
|
}
|
|
2164
1896
|
// Final synchronous lsof kill - most reliable method
|
|
2165
1897
|
const result = spawnSync("sh", ["-c", `lsof -ti:${this.options.port} | xargs kill -9 2>/dev/null`], {
|
|
@@ -2170,35 +1902,6 @@ export class DevEnvironment {
|
|
|
2170
1902
|
catch {
|
|
2171
1903
|
// Ignore pkill errors
|
|
2172
1904
|
}
|
|
2173
|
-
// Kill MCP server only if this is the last d3k instance AND we own the PID file
|
|
2174
|
-
// (other d3k instances in other projects might still need it)
|
|
2175
|
-
// The TUI parent shouldn't do MCP cleanup - the subprocess (which owns the PID file) will handle it
|
|
2176
|
-
// Note: weOwnPidFile was already determined at the top of handleShutdown()
|
|
2177
|
-
const otherInstances = countActiveD3kInstances(true); // exclude current process
|
|
2178
|
-
this.debugLog(`Other active d3k instances: ${otherInstances}, weOwnPidFile: ${weOwnPidFile}`);
|
|
2179
|
-
if (otherInstances === 0 && this.options.mcpPort && weOwnPidFile) {
|
|
2180
|
-
if (!this.options.tui) {
|
|
2181
|
-
console.log(chalk.yellow("🔄 Killing MCP server (last d3k instance)..."));
|
|
2182
|
-
}
|
|
2183
|
-
this.debugLog(`Killing MCP server on port ${this.options.mcpPort} (no other d3k instances)`);
|
|
2184
|
-
try {
|
|
2185
|
-
const { spawnSync } = await import("child_process");
|
|
2186
|
-
const mcpResult = spawnSync("sh", ["-c", `lsof -ti:${this.options.mcpPort} -sTCP:LISTEN | xargs kill -9 2>/dev/null`], { stdio: "pipe", timeout: 5000 });
|
|
2187
|
-
this.debugLog(`MCP server kill exit code: ${mcpResult.status}`);
|
|
2188
|
-
if (!this.options.tui) {
|
|
2189
|
-
console.log(chalk.green("✅ MCP server stopped"));
|
|
2190
|
-
}
|
|
2191
|
-
}
|
|
2192
|
-
catch (error) {
|
|
2193
|
-
this.debugLog(`Error killing MCP server: ${error}`);
|
|
2194
|
-
}
|
|
2195
|
-
}
|
|
2196
|
-
else if (otherInstances > 0) {
|
|
2197
|
-
this.debugLog(`Keeping MCP server running for ${otherInstances} other d3k instance(s)`);
|
|
2198
|
-
}
|
|
2199
|
-
else if (!weOwnPidFile) {
|
|
2200
|
-
this.debugLog("Skipping MCP cleanup - we don't own the PID file (subprocess will handle it)");
|
|
2201
|
-
}
|
|
2202
1905
|
if (!this.options.tui) {
|
|
2203
1906
|
console.log(chalk.green("✅ Cleanup complete"));
|
|
2204
1907
|
}
|