dev3000 0.0.157 → 0.0.160
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 +257 -557
- 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 +32 -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/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/.next/static/gTFARHqj7X4ZmcJWlUVID/_buildManifest.js +0 -11
- package/mcp-server/.next/static/gTFARHqj7X4ZmcJWlUVID/_clientMiddlewareManifest.json +0 -1
- package/mcp-server/.next/static/gTFARHqj7X4ZmcJWlUVID/_ssgManifest.js +0 -1
- 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
|
|
288
|
+
// Framework detection happens in cli.ts and is stored in session files for CLI integration
|
|
394
289
|
/**
|
|
395
|
-
*
|
|
290
|
+
* Ensure d3k skill is installed in project's skills directory.
|
|
291
|
+
* Claude Code reads from .claude/skills/ (must be real files, not symlinks).
|
|
396
292
|
*/
|
|
397
|
-
async function
|
|
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
|
-
}
|
|
552
|
-
/**
|
|
553
|
-
* Ensure d3k skill is installed in project's .claude/skills/d3k/
|
|
554
|
-
* Claude Code reads from .claude/skills/ (must be real files, not symlinks)
|
|
555
|
-
*/
|
|
556
|
-
async function ensureD3kSkill() {
|
|
293
|
+
async function ensureD3kSkill(skillsAgentId) {
|
|
557
294
|
try {
|
|
558
295
|
const bundledSkillsDir = getBundledSkillsPath();
|
|
559
296
|
if (!bundledSkillsDir)
|
|
@@ -561,29 +298,37 @@ async function ensureD3kSkill() {
|
|
|
561
298
|
const bundledSkillPath = join(bundledSkillsDir, "d3k", "SKILL.md");
|
|
562
299
|
if (!existsSync(bundledSkillPath))
|
|
563
300
|
return;
|
|
564
|
-
|
|
565
|
-
const
|
|
566
|
-
|
|
567
|
-
|
|
301
|
+
const targetSkillsDir = skillsAgentId ? getSkillsPathForLocation(skillsAgentId, "project")?.path : null;
|
|
302
|
+
const skillRoots = new Set();
|
|
303
|
+
// Install directly to the agent-specific skills dir (fallback to .agents)
|
|
304
|
+
const defaultSkillsRoot = join(process.cwd(), ".agents", "skills");
|
|
305
|
+
skillRoots.add(targetSkillsDir || defaultSkillsRoot);
|
|
306
|
+
// Ensure Claude Code can load the skill from .claude/skills when applicable
|
|
307
|
+
if (skillsAgentId === "claude-code") {
|
|
308
|
+
skillRoots.add(join(process.cwd(), ".claude", "skills"));
|
|
309
|
+
}
|
|
568
310
|
const bundledContent = readFileSync(bundledSkillPath, "utf-8");
|
|
569
|
-
|
|
570
|
-
const
|
|
571
|
-
|
|
572
|
-
|
|
311
|
+
for (const skillsRoot of skillRoots) {
|
|
312
|
+
const skillDir = join(skillsRoot, "d3k");
|
|
313
|
+
const skillPath = join(skillDir, "SKILL.md");
|
|
314
|
+
if (existsSync(skillPath)) {
|
|
315
|
+
const existingContent = readFileSync(skillPath, "utf-8");
|
|
316
|
+
if (existingContent === bundledContent) {
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
573
319
|
}
|
|
320
|
+
if (!existsSync(skillDir)) {
|
|
321
|
+
mkdirSync(skillDir, { recursive: true });
|
|
322
|
+
}
|
|
323
|
+
copyFileSync(bundledSkillPath, skillPath);
|
|
574
324
|
}
|
|
575
|
-
// Copy skill to .claude/skills/d3k/
|
|
576
|
-
if (!existsSync(skillDir)) {
|
|
577
|
-
mkdirSync(skillDir, { recursive: true });
|
|
578
|
-
}
|
|
579
|
-
copyFileSync(bundledSkillPath, skillPath);
|
|
580
325
|
}
|
|
581
326
|
catch (_error) {
|
|
582
327
|
// Ignore errors - skill installation is optional
|
|
583
328
|
}
|
|
584
329
|
}
|
|
585
330
|
// REMOVED: cleanup functions are no longer needed
|
|
586
|
-
//
|
|
331
|
+
// CLI integration config files are now kept persistent across dev3000 restarts
|
|
587
332
|
export function createPersistentLogFile() {
|
|
588
333
|
// Get unique project name
|
|
589
334
|
const projectName = getProjectName();
|
|
@@ -605,7 +350,7 @@ export function createPersistentLogFile() {
|
|
|
605
350
|
}
|
|
606
351
|
}
|
|
607
352
|
/**
|
|
608
|
-
* Write session info for
|
|
353
|
+
* Write session info for external tooling to discover.
|
|
609
354
|
*
|
|
610
355
|
* CRITICAL FOR PROCESS CLEANUP:
|
|
611
356
|
* This writes the session.json file that contains chromePids and serverPid.
|
|
@@ -615,7 +360,7 @@ export function createPersistentLogFile() {
|
|
|
615
360
|
* processes belong to THIS d3k instance so we don't accidentally kill
|
|
616
361
|
* Chrome instances from other d3k sessions.
|
|
617
362
|
*/
|
|
618
|
-
export function writeSessionInfo(projectName, logFilePath, appPort,
|
|
363
|
+
export function writeSessionInfo(projectName, logFilePath, appPort, cdpUrl, chromePids, serverCommand, framework, serverPid) {
|
|
619
364
|
const projectDir = getProjectDir();
|
|
620
365
|
try {
|
|
621
366
|
// Create project directory if it doesn't exist
|
|
@@ -627,7 +372,6 @@ export function writeSessionInfo(projectName, logFilePath, appPort, mcpPort, cdp
|
|
|
627
372
|
projectName,
|
|
628
373
|
logFilePath,
|
|
629
374
|
appPort,
|
|
630
|
-
mcpPort: mcpPort || null,
|
|
631
375
|
cdpUrl: cdpUrl || null,
|
|
632
376
|
startTime: new Date().toISOString(),
|
|
633
377
|
pid: process.pid,
|
|
@@ -646,39 +390,16 @@ export function writeSessionInfo(projectName, logFilePath, appPort, mcpPort, cdp
|
|
|
646
390
|
console.warn(chalk.yellow(`⚠️ Could not write session info: ${error}`));
|
|
647
391
|
}
|
|
648
392
|
}
|
|
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) {
|
|
393
|
+
function getSessionInfo(projectName) {
|
|
677
394
|
const sessionFile = join(homedir(), ".d3k", projectName, "session.json");
|
|
678
395
|
try {
|
|
679
396
|
if (existsSync(sessionFile)) {
|
|
680
397
|
const sessionInfo = JSON.parse(readFileSync(sessionFile, "utf8"));
|
|
681
|
-
return
|
|
398
|
+
return {
|
|
399
|
+
serverPid: sessionInfo.serverPid ?? null,
|
|
400
|
+
chromePids: sessionInfo.chromePids ?? [],
|
|
401
|
+
cwd: sessionInfo.cwd ?? null
|
|
402
|
+
};
|
|
682
403
|
}
|
|
683
404
|
}
|
|
684
405
|
catch (_error) {
|
|
@@ -686,6 +407,9 @@ function getSessionServerPid(projectName) {
|
|
|
686
407
|
}
|
|
687
408
|
return null;
|
|
688
409
|
}
|
|
410
|
+
export function getSessionChromePids(projectName) {
|
|
411
|
+
return getSessionInfo(projectName)?.chromePids ?? [];
|
|
412
|
+
}
|
|
689
413
|
function createLogFileInDir(baseDir, _projectName) {
|
|
690
414
|
// Create short timestamp: MMDD-HHmmss (e.g., 0106-171301)
|
|
691
415
|
const now = new Date();
|
|
@@ -751,22 +475,14 @@ export class DevEnvironment {
|
|
|
751
475
|
healthCheckTimer = null;
|
|
752
476
|
tui = null;
|
|
753
477
|
portChangeMessage = null;
|
|
754
|
-
chromeDevtoolsSupported = false;
|
|
755
478
|
portDetected = false;
|
|
756
479
|
serverUsesHttps = false;
|
|
757
|
-
disabledMcpConfigSet;
|
|
758
480
|
/** Returns "https" or "http" based on detected server protocol */
|
|
759
481
|
get serverProtocol() {
|
|
760
482
|
return this.serverUsesHttps ? "https" : "http";
|
|
761
483
|
}
|
|
762
484
|
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);
|
|
485
|
+
this.options = { ...options };
|
|
770
486
|
this.logger = new Logger(options.logFile, options.tail || false, options.dateTimeFormat || "local");
|
|
771
487
|
this.outputProcessor = new OutputProcessor(new StandardLogParser(), new NextJsErrorDetector());
|
|
772
488
|
// Detect if running from compiled binary
|
|
@@ -789,6 +505,10 @@ export class DevEnvironment {
|
|
|
789
505
|
// Use project-specific PID and lock files to allow multiple projects to run simultaneously
|
|
790
506
|
this.pidFile = join(tmpdir(), `dev3000-${projectName}.pid`);
|
|
791
507
|
this.lockFile = join(tmpdir(), `dev3000-${projectName}.lock`);
|
|
508
|
+
// Allow CLI-level crash handlers to trigger emergency cleanup.
|
|
509
|
+
globalThis.__d3kEmergencyShutdown = (reason, error) => {
|
|
510
|
+
this.emergencyShutdown(1, reason, error);
|
|
511
|
+
};
|
|
792
512
|
// Read version - for compiled binaries, use injected version; otherwise read from package.json
|
|
793
513
|
this.version = "0.0.0";
|
|
794
514
|
// Check for compile-time injected version first
|
|
@@ -823,7 +543,7 @@ export class DevEnvironment {
|
|
|
823
543
|
this.spinner = ora({
|
|
824
544
|
text: "Initializing...",
|
|
825
545
|
spinner: "dots",
|
|
826
|
-
isEnabled: !options.tui // Disable spinner in TUI mode
|
|
546
|
+
isEnabled: !options.tui && !options.tail // Disable spinner in TUI mode
|
|
827
547
|
});
|
|
828
548
|
// Ensure screenshot directory exists
|
|
829
549
|
try {
|
|
@@ -842,14 +562,7 @@ export class DevEnvironment {
|
|
|
842
562
|
this.initializeD3KLog();
|
|
843
563
|
}
|
|
844
564
|
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
|
-
// }
|
|
565
|
+
// No legacy server to clean up; continue with port checks.
|
|
853
566
|
// Check if user explicitly set ports via CLI flags
|
|
854
567
|
const userSetAppPort = this.options.userSetPort || false;
|
|
855
568
|
// If user didn't set ports, find available ones first (before checking)
|
|
@@ -881,7 +594,7 @@ export class DevEnvironment {
|
|
|
881
594
|
throw new Error(`Port ${this.options.port} is already in use. Please free the port and try again.`);
|
|
882
595
|
}
|
|
883
596
|
}
|
|
884
|
-
//
|
|
597
|
+
// Legacy server removed - only check app port availability
|
|
885
598
|
}
|
|
886
599
|
async checkProcessHealth() {
|
|
887
600
|
if (this.isShuttingDown)
|
|
@@ -893,7 +606,7 @@ export class DevEnvironment {
|
|
|
893
606
|
return true;
|
|
894
607
|
}
|
|
895
608
|
try {
|
|
896
|
-
// Only check app port -
|
|
609
|
+
// Only check app port - legacy server has been removed
|
|
897
610
|
const ports = [this.options.port];
|
|
898
611
|
for (const port of ports) {
|
|
899
612
|
const result = await new Promise((resolve, reject) => {
|
|
@@ -938,32 +651,51 @@ export class DevEnvironment {
|
|
|
938
651
|
this.debugLog("Health check timer stopped");
|
|
939
652
|
}
|
|
940
653
|
}
|
|
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");
|
|
654
|
+
emergencyShutdown(exitCode, reason, error) {
|
|
655
|
+
if (this.isShuttingDown)
|
|
945
656
|
return;
|
|
657
|
+
this.isShuttingDown = true;
|
|
658
|
+
this.debugLog(`Emergency shutdown requested (${reason})`);
|
|
659
|
+
if (error) {
|
|
660
|
+
const errorText = error instanceof Error ? error.stack || error.message : String(error);
|
|
661
|
+
this.debugLog(`Emergency shutdown error: ${errorText}`);
|
|
946
662
|
}
|
|
947
|
-
|
|
948
|
-
if (
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
}
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
663
|
+
// Stop CDP reconnection attempts before killing the app server.
|
|
664
|
+
if (this.cdpMonitor) {
|
|
665
|
+
this.cdpMonitor.prepareShutdown();
|
|
666
|
+
}
|
|
667
|
+
// Best-effort synchronous cleanup (mirrors SIGHUP handler).
|
|
668
|
+
const { spawnSync } = require("child_process");
|
|
669
|
+
const port = this.options.port;
|
|
670
|
+
this.debugLog(`Synchronous kill for port ${port}`);
|
|
671
|
+
spawnSync("sh", ["-c", `lsof -ti:${port} | xargs kill -9 2>/dev/null`], {
|
|
672
|
+
stdio: "pipe",
|
|
673
|
+
timeout: 5000
|
|
674
|
+
});
|
|
675
|
+
const projectName = getProjectName();
|
|
676
|
+
const sessionInfo = getSessionInfo(projectName);
|
|
677
|
+
const chromePids = sessionInfo?.chromePids ?? [];
|
|
678
|
+
if (chromePids.length > 0) {
|
|
679
|
+
this.debugLog(`Synchronously killing Chrome PIDs: [${chromePids.join(", ")}]`);
|
|
680
|
+
for (const pid of chromePids) {
|
|
681
|
+
try {
|
|
682
|
+
process.kill(pid, "SIGTERM");
|
|
683
|
+
}
|
|
684
|
+
catch {
|
|
685
|
+
// Ignore - process may already be dead
|
|
686
|
+
}
|
|
687
|
+
}
|
|
963
688
|
}
|
|
964
|
-
|
|
965
|
-
this.
|
|
689
|
+
if (sessionInfo?.serverPid) {
|
|
690
|
+
this.killServerPidIfOwned(sessionInfo.serverPid, sessionInfo.cwd, `emergency:${reason}`);
|
|
966
691
|
}
|
|
692
|
+
this.handleShutdown()
|
|
693
|
+
.then(() => {
|
|
694
|
+
process.exit(exitCode);
|
|
695
|
+
})
|
|
696
|
+
.catch(() => {
|
|
697
|
+
process.exit(exitCode);
|
|
698
|
+
});
|
|
967
699
|
}
|
|
968
700
|
async start() {
|
|
969
701
|
// Check if another instance is already running for this project
|
|
@@ -974,6 +706,8 @@ export class DevEnvironment {
|
|
|
974
706
|
}
|
|
975
707
|
// Initialize telemetry session (used by version check)
|
|
976
708
|
initTelemetrySession(this.options.framework);
|
|
709
|
+
// Kill any orphaned server process from a previous run of this project
|
|
710
|
+
this.cleanupOrphanedServer();
|
|
977
711
|
// Check if TUI mode is enabled (default) and stdin supports it
|
|
978
712
|
const canUseTUI = this.options.tui && process.stdin.isTTY;
|
|
979
713
|
if (!canUseTUI && this.options.tui) {
|
|
@@ -988,7 +722,6 @@ export class DevEnvironment {
|
|
|
988
722
|
// Start TUI interface with initial status and updated port
|
|
989
723
|
this.tui = new DevTUI({
|
|
990
724
|
appPort: this.options.port, // This may have been updated by checkPortsAvailable
|
|
991
|
-
mcpPort: this.options.mcpPort || "3684",
|
|
992
725
|
logFile: this.options.logFile,
|
|
993
726
|
commandName: this.options.commandName,
|
|
994
727
|
serversOnly: this.options.serversOnly,
|
|
@@ -1014,6 +747,21 @@ export class DevEnvironment {
|
|
|
1014
747
|
stdio: "pipe",
|
|
1015
748
|
timeout: 5000
|
|
1016
749
|
});
|
|
750
|
+
const projectName = getProjectName();
|
|
751
|
+
const chromePids = getSessionChromePids(projectName);
|
|
752
|
+
if (chromePids.length > 0) {
|
|
753
|
+
this.debugLog(`Synchronous kill for Chrome PIDs: [${chromePids.join(", ")}]`);
|
|
754
|
+
for (const pid of chromePids) {
|
|
755
|
+
try {
|
|
756
|
+
process.kill(pid, "SIGTERM");
|
|
757
|
+
process.kill(pid, 0);
|
|
758
|
+
process.kill(pid, "SIGKILL");
|
|
759
|
+
}
|
|
760
|
+
catch {
|
|
761
|
+
// Ignore - process may already be dead
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
}
|
|
1017
765
|
// Now do the rest of cleanup async
|
|
1018
766
|
this.tui?.updateStatus("Shutting down...");
|
|
1019
767
|
this.handleShutdown()
|
|
@@ -1051,7 +799,7 @@ export class DevEnvironment {
|
|
|
1051
799
|
await this.tui.updateStatus("d3k is checking for skill updates...");
|
|
1052
800
|
// Install d3k skill early so it's available when Claude Code starts
|
|
1053
801
|
// This is important for --with-agent where both start simultaneously
|
|
1054
|
-
await ensureD3kSkill();
|
|
802
|
+
await ensureD3kSkill(this.options.skillsAgentId);
|
|
1055
803
|
// Check ports in background after TUI is visible
|
|
1056
804
|
await this.checkPortsAvailable(true); // silent mode for TUI
|
|
1057
805
|
// Update the app port in TUI (may have changed during port check)
|
|
@@ -1076,7 +824,7 @@ export class DevEnvironment {
|
|
|
1076
824
|
// Start user's dev server
|
|
1077
825
|
await this.tui.updateStatus("Starting your dev server...");
|
|
1078
826
|
await this.startServer();
|
|
1079
|
-
//
|
|
827
|
+
// Legacy tools server removed - using CLI commands instead
|
|
1080
828
|
// await this.startMcpServer()
|
|
1081
829
|
// Wait for servers to be ready
|
|
1082
830
|
await this.tui.updateStatus("Waiting for app...");
|
|
@@ -1090,21 +838,8 @@ export class DevEnvironment {
|
|
|
1090
838
|
}
|
|
1091
839
|
// Update TUI with confirmed port (may have changed during server startup)
|
|
1092
840
|
this.tui.updateAppPort(this.options.port);
|
|
1093
|
-
//
|
|
841
|
+
// Legacy tools server removed - using CLI commands instead
|
|
1094
842
|
// await this.waitForMcpServer()
|
|
1095
|
-
// Configure AI CLI integrations (both dev3000 and chrome-devtools MCPs)
|
|
1096
|
-
if (!this.options.serversOnly) {
|
|
1097
|
-
await this.tui.updateStatus("Configuring AI CLI integrations...");
|
|
1098
|
-
// Check if Chrome version supports chrome-devtools MCP
|
|
1099
|
-
if (this.options.chromeDevtoolsMcp !== false) {
|
|
1100
|
-
this.chromeDevtoolsSupported = await isChromeDevtoolsMcpSupported();
|
|
1101
|
-
if (!this.chromeDevtoolsSupported) {
|
|
1102
|
-
this.logD3K("Chrome version < 140.0.7339.214 detected - chrome-devtools MCP will be skipped");
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
// Ensure MCP server configurations in project settings files (instant, local)
|
|
1106
|
-
await this.configureMcpConfigs();
|
|
1107
|
-
}
|
|
1108
843
|
// Start CDP monitoring only if server started successfully and not in servers-only mode
|
|
1109
844
|
if (!this.options.serversOnly && serverStarted) {
|
|
1110
845
|
await this.tui.updateStatus(`Starting ${this.options.commandName} browser...`);
|
|
@@ -1116,10 +851,10 @@ export class DevEnvironment {
|
|
|
1116
851
|
else {
|
|
1117
852
|
this.debugLog("Browser monitoring disabled via --servers-only flag");
|
|
1118
853
|
}
|
|
1119
|
-
// Write session info for
|
|
854
|
+
// Write session info for tooling discovery (include CDP URL if browser monitoring was started)
|
|
1120
855
|
const cdpUrl = this.cdpMonitor?.getCdpUrl() || null;
|
|
1121
856
|
const chromePids = this.cdpMonitor?.getChromePids() || [];
|
|
1122
|
-
writeSessionInfo(projectName, this.options.logFile, this.options.port,
|
|
857
|
+
writeSessionInfo(projectName, this.options.logFile, this.options.port, cdpUrl, chromePids, this.options.serverCommand, this.options.framework, this.serverProcess?.pid);
|
|
1123
858
|
// Clear status - ready!
|
|
1124
859
|
await this.tui.updateStatus(null);
|
|
1125
860
|
}
|
|
@@ -1128,7 +863,7 @@ export class DevEnvironment {
|
|
|
1128
863
|
console.log(chalk.hex("#A18CE5")(`Starting ${this.options.commandName} (v${this.version})`));
|
|
1129
864
|
// Install d3k skill early so it's available when Claude Code starts
|
|
1130
865
|
// This is important for --with-agent where both start simultaneously
|
|
1131
|
-
await ensureD3kSkill();
|
|
866
|
+
await ensureD3kSkill(this.options.skillsAgentId);
|
|
1132
867
|
// Start spinner
|
|
1133
868
|
this.spinner.start("Checking ports...");
|
|
1134
869
|
// Check if ports are available first
|
|
@@ -1141,7 +876,7 @@ export class DevEnvironment {
|
|
|
1141
876
|
// Start user's dev server
|
|
1142
877
|
this.spinner.text = "Starting your dev server...";
|
|
1143
878
|
await this.startServer();
|
|
1144
|
-
//
|
|
879
|
+
// Legacy server removed - using CLI commands instead
|
|
1145
880
|
// await this.startMcpServer()
|
|
1146
881
|
// Wait for servers to be ready
|
|
1147
882
|
this.spinner.text = "Waiting for app...";
|
|
@@ -1153,21 +888,8 @@ export class DevEnvironment {
|
|
|
1153
888
|
console.error(chalk.yellow("Exiting without launching browser."));
|
|
1154
889
|
process.exit(1);
|
|
1155
890
|
}
|
|
1156
|
-
//
|
|
891
|
+
// Legacy server removed - using CLI commands instead
|
|
1157
892
|
// await this.waitForMcpServer()
|
|
1158
|
-
// Configure AI CLI integrations (both dev3000 and chrome-devtools MCPs)
|
|
1159
|
-
if (!this.options.serversOnly) {
|
|
1160
|
-
this.spinner.text = "Configuring AI CLI integrations...";
|
|
1161
|
-
// Check if Chrome version supports chrome-devtools MCP
|
|
1162
|
-
if (this.options.chromeDevtoolsMcp !== false) {
|
|
1163
|
-
this.chromeDevtoolsSupported = await isChromeDevtoolsMcpSupported();
|
|
1164
|
-
if (!this.chromeDevtoolsSupported) {
|
|
1165
|
-
this.logD3K("Chrome version < 140.0.7339.214 detected - chrome-devtools MCP will be skipped");
|
|
1166
|
-
}
|
|
1167
|
-
}
|
|
1168
|
-
// Ensure MCP server configurations in project settings files (instant, local)
|
|
1169
|
-
await this.configureMcpConfigs();
|
|
1170
|
-
}
|
|
1171
893
|
// Start CDP monitoring only if server started successfully and not in servers-only mode
|
|
1172
894
|
if (!this.options.serversOnly && serverStarted) {
|
|
1173
895
|
this.spinner.text = `Starting ${this.options.commandName} browser...`;
|
|
@@ -1184,7 +906,7 @@ export class DevEnvironment {
|
|
|
1184
906
|
// Include CDP URL if browser monitoring was started
|
|
1185
907
|
const cdpUrl = this.cdpMonitor?.getCdpUrl() || null;
|
|
1186
908
|
const chromePids = this.cdpMonitor?.getChromePids() || [];
|
|
1187
|
-
writeSessionInfo(projectName, this.options.logFile, this.options.port,
|
|
909
|
+
writeSessionInfo(projectName, this.options.logFile, this.options.port, cdpUrl, chromePids, this.options.serverCommand, this.options.framework, this.serverProcess?.pid);
|
|
1188
910
|
// Complete startup with success message only in non-TUI mode
|
|
1189
911
|
this.spinner.succeed("Development environment ready!");
|
|
1190
912
|
// Regular console output (when TUI is disabled with --no-tui)
|
|
@@ -1193,7 +915,7 @@ export class DevEnvironment {
|
|
|
1193
915
|
console.log(chalk.cyan(`🌐 Your App: ${this.serverProtocol}://localhost:${this.options.port}`));
|
|
1194
916
|
console.log(chalk.cyan(`🔧 CLI Tools: d3k fix, d3k crawl, d3k find-component`));
|
|
1195
917
|
if (this.options.serversOnly) {
|
|
1196
|
-
console.log(chalk.cyan("🖥️ Servers-only mode -
|
|
918
|
+
console.log(chalk.cyan("🖥️ Servers-only mode - browser monitoring disabled"));
|
|
1197
919
|
}
|
|
1198
920
|
console.log(chalk.cyan("\nUse Ctrl-C to stop.\n"));
|
|
1199
921
|
// Auto-upgrade in non-TUI mode (non-blocking)
|
|
@@ -1328,6 +1050,83 @@ export class DevEnvironment {
|
|
|
1328
1050
|
}
|
|
1329
1051
|
});
|
|
1330
1052
|
}
|
|
1053
|
+
isSessionCwdOwned(sessionCwd) {
|
|
1054
|
+
if (!sessionCwd)
|
|
1055
|
+
return false;
|
|
1056
|
+
try {
|
|
1057
|
+
const current = resolve(process.cwd());
|
|
1058
|
+
const session = resolve(sessionCwd);
|
|
1059
|
+
return session === current || current.startsWith(session + sep) || session.startsWith(current + sep);
|
|
1060
|
+
}
|
|
1061
|
+
catch {
|
|
1062
|
+
return false;
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
isPidRunning(pid) {
|
|
1066
|
+
try {
|
|
1067
|
+
process.kill(pid, 0);
|
|
1068
|
+
return true;
|
|
1069
|
+
}
|
|
1070
|
+
catch {
|
|
1071
|
+
return false;
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
killServerPidIfOwned(pid, sessionCwd, reason) {
|
|
1075
|
+
if (!this.isSessionCwdOwned(sessionCwd)) {
|
|
1076
|
+
this.debugLog(`Skipping server PID ${pid} kill (${reason}): session cwd mismatch`);
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
if (!this.isPidRunning(pid)) {
|
|
1080
|
+
this.debugLog(`Skipping server PID ${pid} kill (${reason}): not running`);
|
|
1081
|
+
return;
|
|
1082
|
+
}
|
|
1083
|
+
this.debugLog(`Killing server PID ${pid} (${reason})`);
|
|
1084
|
+
try {
|
|
1085
|
+
process.kill(pid, "SIGTERM");
|
|
1086
|
+
}
|
|
1087
|
+
catch {
|
|
1088
|
+
// Ignore - process may already be dead
|
|
1089
|
+
}
|
|
1090
|
+
if (process.platform !== "win32") {
|
|
1091
|
+
try {
|
|
1092
|
+
process.kill(-pid, "SIGTERM");
|
|
1093
|
+
}
|
|
1094
|
+
catch {
|
|
1095
|
+
// Ignore - process group may not exist
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
try {
|
|
1099
|
+
process.kill(pid, 0);
|
|
1100
|
+
process.kill(pid, "SIGKILL");
|
|
1101
|
+
}
|
|
1102
|
+
catch {
|
|
1103
|
+
// Ignore - process may already be dead
|
|
1104
|
+
}
|
|
1105
|
+
if (process.platform !== "win32") {
|
|
1106
|
+
try {
|
|
1107
|
+
process.kill(-pid, "SIGKILL");
|
|
1108
|
+
}
|
|
1109
|
+
catch {
|
|
1110
|
+
// Ignore - process group may not exist
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
if (!isInSandbox()) {
|
|
1114
|
+
try {
|
|
1115
|
+
const { spawnSync } = require("child_process");
|
|
1116
|
+
spawnSync("pkill", ["-P", pid.toString()], { stdio: "ignore" });
|
|
1117
|
+
}
|
|
1118
|
+
catch {
|
|
1119
|
+
// Ignore pkill errors
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
cleanupOrphanedServer() {
|
|
1124
|
+
const projectName = getProjectName();
|
|
1125
|
+
const sessionInfo = getSessionInfo(projectName);
|
|
1126
|
+
if (!sessionInfo?.serverPid)
|
|
1127
|
+
return;
|
|
1128
|
+
this.killServerPidIfOwned(sessionInfo.serverPid, sessionInfo.cwd, "startup orphan cleanup");
|
|
1129
|
+
}
|
|
1331
1130
|
acquireLock() {
|
|
1332
1131
|
try {
|
|
1333
1132
|
// Check if lock file exists
|
|
@@ -1384,7 +1183,7 @@ export class DevEnvironment {
|
|
|
1384
1183
|
const cdpUrl = this.cdpMonitor?.getCdpUrl();
|
|
1385
1184
|
const chromePids = this.cdpMonitor?.getChromePids() || [];
|
|
1386
1185
|
if (cdpUrl || chromePids.length > 0) {
|
|
1387
|
-
writeSessionInfo(projectName, this.options.logFile, this.options.port,
|
|
1186
|
+
writeSessionInfo(projectName, this.options.logFile, this.options.port, cdpUrl || undefined, chromePids, this.options.serverCommand, this.options.framework, this.serverProcess?.pid);
|
|
1388
1187
|
this.debugLog(`Updated session info with new port: ${this.options.port}`);
|
|
1389
1188
|
}
|
|
1390
1189
|
// Update TUI header with new port
|
|
@@ -1563,23 +1362,6 @@ export class DevEnvironment {
|
|
|
1563
1362
|
// Ignore D3K log initialization errors - non-critical
|
|
1564
1363
|
}
|
|
1565
1364
|
}
|
|
1566
|
-
logD3K(message) {
|
|
1567
|
-
// Write [D3K] logs to project-specific dev3000 debug log, NOT to main project log
|
|
1568
|
-
// This prevents Claude from thinking dev3000's orchestration logic needs to be "fixed"
|
|
1569
|
-
const timestamp = formatTimestamp(new Date(), this.options.dateTimeFormat || "local");
|
|
1570
|
-
const logEntry = `[${timestamp}] [D3K] ${message}\n`;
|
|
1571
|
-
try {
|
|
1572
|
-
const projectDir = getProjectDir();
|
|
1573
|
-
if (!existsSync(projectDir)) {
|
|
1574
|
-
mkdirSync(projectDir, { recursive: true });
|
|
1575
|
-
}
|
|
1576
|
-
const d3kLogFile = join(projectDir, "d3k.log");
|
|
1577
|
-
appendFileSync(d3kLogFile, logEntry);
|
|
1578
|
-
}
|
|
1579
|
-
catch {
|
|
1580
|
-
// Ignore D3K log write errors - non-critical
|
|
1581
|
-
}
|
|
1582
|
-
}
|
|
1583
1365
|
async startCDPMonitoringSync() {
|
|
1584
1366
|
// Skip if in servers-only mode
|
|
1585
1367
|
if (this.options.serversOnly) {
|
|
@@ -1609,7 +1391,6 @@ export class DevEnvironment {
|
|
|
1609
1391
|
this.cdpMonitor = new CDPMonitor(this.options.profileDir, this.screenshotDir, (_source, message) => {
|
|
1610
1392
|
this.logger.log("browser", message);
|
|
1611
1393
|
}, this.options.debug, this.options.browser, this.options.pluginReactScan, this.options.port, // App server port to monitor
|
|
1612
|
-
this.options.mcpPort, // MCP server port to ignore
|
|
1613
1394
|
this.options.debugPort, // Chrome debug port
|
|
1614
1395
|
this.options.headless // Headless mode for serverless/CI environments
|
|
1615
1396
|
);
|
|
@@ -1639,7 +1420,7 @@ export class DevEnvironment {
|
|
|
1639
1420
|
}
|
|
1640
1421
|
// Always write session info after CDP monitoring starts - this is critical for
|
|
1641
1422
|
// sandbox environments where external tools poll for the cdpUrl in the session file
|
|
1642
|
-
writeSessionInfo(projectName, this.options.logFile, this.options.port,
|
|
1423
|
+
writeSessionInfo(projectName, this.options.logFile, this.options.port, cdpUrl || undefined, chromePids, this.options.serverCommand, this.options.framework, this.serverProcess?.pid);
|
|
1643
1424
|
this.debugLog(`Updated session info with CDP URL: ${cdpUrl}, Chrome PIDs: [${chromePids.join(", ")}]`);
|
|
1644
1425
|
this.logger.log("browser", `[CDP] Session info written with cdpUrl: ${cdpUrl ? "available" : "null"}`);
|
|
1645
1426
|
// Navigate to the app
|
|
@@ -1663,9 +1444,9 @@ export class DevEnvironment {
|
|
|
1663
1444
|
await this.screencastManager.stop();
|
|
1664
1445
|
this.screencastManager = null;
|
|
1665
1446
|
}
|
|
1666
|
-
// Read
|
|
1447
|
+
// Read session info BEFORE deleting it (needed for cleanup)
|
|
1667
1448
|
const projectName = getProjectName();
|
|
1668
|
-
const
|
|
1449
|
+
const sessionInfo = getSessionInfo(projectName);
|
|
1669
1450
|
// Clean up session file
|
|
1670
1451
|
try {
|
|
1671
1452
|
const sessionFile = join(homedir(), ".d3k", projectName, "session.json");
|
|
@@ -1676,7 +1457,7 @@ export class DevEnvironment {
|
|
|
1676
1457
|
catch (_error) {
|
|
1677
1458
|
// Non-fatal - ignore cleanup errors
|
|
1678
1459
|
}
|
|
1679
|
-
// Check PID file ownership BEFORE deleting (needed for
|
|
1460
|
+
// Check PID file ownership BEFORE deleting (needed for cleanup decisions)
|
|
1680
1461
|
let weOwnPidFile = false;
|
|
1681
1462
|
try {
|
|
1682
1463
|
if (existsSync(this.pidFile)) {
|
|
@@ -1726,26 +1507,12 @@ export class DevEnvironment {
|
|
|
1726
1507
|
console.log(chalk.gray(`⚠️ Could not kill ${name} on port ${port}`));
|
|
1727
1508
|
}
|
|
1728
1509
|
};
|
|
1729
|
-
// Kill app server only
|
|
1510
|
+
// Kill app server only
|
|
1730
1511
|
console.log(chalk.cyan("🔄 Killing app server..."));
|
|
1731
1512
|
await killPortProcess(this.options.port, "your app server");
|
|
1732
1513
|
// Kill server process and its children using the saved PID (from before session file was deleted)
|
|
1733
|
-
if (
|
|
1734
|
-
|
|
1735
|
-
const { spawnSync } = await import("child_process");
|
|
1736
|
-
// Kill all child processes of the server
|
|
1737
|
-
spawnSync("pkill", ["-P", savedServerPid.toString()], { stdio: "ignore" });
|
|
1738
|
-
// Kill the server process itself
|
|
1739
|
-
try {
|
|
1740
|
-
process.kill(savedServerPid, "SIGKILL");
|
|
1741
|
-
}
|
|
1742
|
-
catch {
|
|
1743
|
-
// Process may already be dead
|
|
1744
|
-
}
|
|
1745
|
-
}
|
|
1746
|
-
catch {
|
|
1747
|
-
// Ignore pkill errors
|
|
1748
|
-
}
|
|
1514
|
+
if (sessionInfo?.serverPid) {
|
|
1515
|
+
this.killServerPidIfOwned(sessionInfo.serverPid, sessionInfo.cwd, "graceful shutdown");
|
|
1749
1516
|
}
|
|
1750
1517
|
// Shutdown CDP monitor if it was started
|
|
1751
1518
|
if (this.cdpMonitor) {
|
|
@@ -1758,26 +1525,6 @@ export class DevEnvironment {
|
|
|
1758
1525
|
console.log(chalk.gray("⚠️ CDP monitor shutdown failed"));
|
|
1759
1526
|
}
|
|
1760
1527
|
}
|
|
1761
|
-
// Kill MCP server only if this is the last d3k instance AND we own the PID file
|
|
1762
|
-
const otherInstances = countActiveD3kInstances(true); // exclude current process
|
|
1763
|
-
this.debugLog(`Other active d3k instances: ${otherInstances}, weOwnPidFile: ${weOwnPidFile}`);
|
|
1764
|
-
if (otherInstances === 0 && this.options.mcpPort && !isInSandbox() && weOwnPidFile) {
|
|
1765
|
-
console.log(chalk.yellow("🔄 Killing MCP server (last d3k instance)..."));
|
|
1766
|
-
try {
|
|
1767
|
-
const { spawnSync } = await import("child_process");
|
|
1768
|
-
spawnSync("sh", ["-c", `lsof -ti:${this.options.mcpPort} -sTCP:LISTEN | xargs kill -9 2>/dev/null`], {
|
|
1769
|
-
stdio: "pipe",
|
|
1770
|
-
timeout: 5000
|
|
1771
|
-
});
|
|
1772
|
-
console.log(chalk.green("✅ MCP server stopped"));
|
|
1773
|
-
}
|
|
1774
|
-
catch {
|
|
1775
|
-
// Ignore errors
|
|
1776
|
-
}
|
|
1777
|
-
}
|
|
1778
|
-
else if (!weOwnPidFile) {
|
|
1779
|
-
this.debugLog("Skipping MCP cleanup - we don't own the PID file (subprocess will handle it)");
|
|
1780
|
-
}
|
|
1781
1528
|
console.log(chalk.red(`❌ ${this.options.commandName} exited due to server failure`));
|
|
1782
1529
|
// Show recent log entries to help diagnose the issue
|
|
1783
1530
|
this.showRecentLogs();
|
|
@@ -1823,6 +1570,25 @@ export class DevEnvironment {
|
|
|
1823
1570
|
stdio: "pipe",
|
|
1824
1571
|
timeout: 5000
|
|
1825
1572
|
});
|
|
1573
|
+
const projectName = getProjectName();
|
|
1574
|
+
const sessionInfo = getSessionInfo(projectName);
|
|
1575
|
+
const chromePids = sessionInfo?.chromePids ?? [];
|
|
1576
|
+
if (chromePids.length > 0) {
|
|
1577
|
+
this.debugLog(`Synchronous kill for Chrome PIDs: [${chromePids.join(", ")}]`);
|
|
1578
|
+
for (const pid of chromePids) {
|
|
1579
|
+
try {
|
|
1580
|
+
process.kill(pid, "SIGTERM");
|
|
1581
|
+
process.kill(pid, 0);
|
|
1582
|
+
process.kill(pid, "SIGKILL");
|
|
1583
|
+
}
|
|
1584
|
+
catch {
|
|
1585
|
+
// Ignore - process may already be dead
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
if (sessionInfo?.serverPid) {
|
|
1590
|
+
this.killServerPidIfOwned(sessionInfo.serverPid, sessionInfo.cwd, "SIGINT");
|
|
1591
|
+
}
|
|
1826
1592
|
if (this.options.tui && this.tui) {
|
|
1827
1593
|
// In TUI mode, show shutting down message
|
|
1828
1594
|
this.debugLog("Updating TUI status with shutdown message");
|
|
@@ -1864,6 +1630,25 @@ export class DevEnvironment {
|
|
|
1864
1630
|
stdio: "pipe",
|
|
1865
1631
|
timeout: 5000
|
|
1866
1632
|
});
|
|
1633
|
+
const projectName = getProjectName();
|
|
1634
|
+
const sessionInfo = getSessionInfo(projectName);
|
|
1635
|
+
const chromePids = sessionInfo?.chromePids ?? [];
|
|
1636
|
+
if (chromePids.length > 0) {
|
|
1637
|
+
this.debugLog(`Synchronous kill for Chrome PIDs: [${chromePids.join(", ")}]`);
|
|
1638
|
+
for (const pid of chromePids) {
|
|
1639
|
+
try {
|
|
1640
|
+
process.kill(pid, "SIGTERM");
|
|
1641
|
+
process.kill(pid, 0);
|
|
1642
|
+
process.kill(pid, "SIGKILL");
|
|
1643
|
+
}
|
|
1644
|
+
catch {
|
|
1645
|
+
// Ignore - process may already be dead
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
}
|
|
1649
|
+
if (sessionInfo?.serverPid) {
|
|
1650
|
+
this.killServerPidIfOwned(sessionInfo.serverPid, sessionInfo.cwd, "SIGTERM");
|
|
1651
|
+
}
|
|
1867
1652
|
this.handleShutdown()
|
|
1868
1653
|
.then(() => {
|
|
1869
1654
|
process.exit(0);
|
|
@@ -1883,66 +1668,18 @@ export class DevEnvironment {
|
|
|
1883
1668
|
* 1. Signal CDP monitor to stop reconnection attempts
|
|
1884
1669
|
* 2. Kill dev server processes on app port (synchronous via lsof)
|
|
1885
1670
|
* 3. Kill Chrome PIDs from session.json (synchronous)
|
|
1886
|
-
* 4.
|
|
1887
|
-
* 5. Call handleShutdown() for async cleanup
|
|
1671
|
+
* 4. Call handleShutdown() for async cleanup
|
|
1888
1672
|
*
|
|
1889
1673
|
* INVARIANTS (enforced by tests in dev-environment.test.ts):
|
|
1890
1674
|
* - Chrome PIDs are stored per-session in session.json
|
|
1891
1675
|
* - We only kill Chrome instances WE spawned (via chromePids array)
|
|
1892
|
-
* - MCP server is only killed when countActiveD3kInstances() returns 0
|
|
1893
1676
|
* - All cleanup happens BEFORE process.exit()
|
|
1894
1677
|
*
|
|
1895
1678
|
* @see dev-environment.test.ts - "SIGHUP handler cleanup" test suite
|
|
1896
1679
|
*/
|
|
1897
1680
|
process.on("SIGHUP", () => {
|
|
1898
1681
|
this.debugLog("SIGHUP received (tmux session closing)");
|
|
1899
|
-
|
|
1900
|
-
return;
|
|
1901
|
-
this.isShuttingDown = true;
|
|
1902
|
-
// 1. Signal CDP monitor to stop reconnection attempts
|
|
1903
|
-
if (this.cdpMonitor) {
|
|
1904
|
-
this.cdpMonitor.prepareShutdown();
|
|
1905
|
-
}
|
|
1906
|
-
// 2. CRITICAL: Kill dev server processes SYNCHRONOUSLY
|
|
1907
|
-
// tmux might kill us quickly, so we can't rely on async cleanup
|
|
1908
|
-
const { spawnSync } = require("child_process");
|
|
1909
|
-
const port = this.options.port;
|
|
1910
|
-
this.debugLog(`Synchronous kill for port ${port}`);
|
|
1911
|
-
spawnSync("sh", ["-c", `lsof -ti:${port} | xargs kill -9 2>/dev/null`], {
|
|
1912
|
-
stdio: "pipe",
|
|
1913
|
-
timeout: 5000
|
|
1914
|
-
});
|
|
1915
|
-
// 3. CRITICAL: Kill Chrome PIDs synchronously
|
|
1916
|
-
// Get Chrome PIDs from session file before it gets deleted
|
|
1917
|
-
const projectName = getProjectName();
|
|
1918
|
-
const chromePids = getSessionChromePids(projectName);
|
|
1919
|
-
if (chromePids.length > 0) {
|
|
1920
|
-
this.debugLog(`Synchronously killing Chrome PIDs: [${chromePids.join(", ")}]`);
|
|
1921
|
-
for (const pid of chromePids) {
|
|
1922
|
-
try {
|
|
1923
|
-
process.kill(pid, "SIGTERM");
|
|
1924
|
-
}
|
|
1925
|
-
catch {
|
|
1926
|
-
// Ignore - process may already be dead
|
|
1927
|
-
}
|
|
1928
|
-
}
|
|
1929
|
-
}
|
|
1930
|
-
// 4. CRITICAL: Kill MCP server only if we're the LAST instance
|
|
1931
|
-
const otherInstances = countActiveD3kInstances(true);
|
|
1932
|
-
if (otherInstances === 0 && this.options.mcpPort) {
|
|
1933
|
-
this.debugLog(`Synchronously killing MCP server on port ${this.options.mcpPort}`);
|
|
1934
|
-
spawnSync("sh", ["-c", `lsof -ti:${this.options.mcpPort} -sTCP:LISTEN | xargs kill -9 2>/dev/null`], {
|
|
1935
|
-
stdio: "pipe",
|
|
1936
|
-
timeout: 5000
|
|
1937
|
-
});
|
|
1938
|
-
}
|
|
1939
|
-
this.handleShutdown()
|
|
1940
|
-
.then(() => {
|
|
1941
|
-
process.exit(0);
|
|
1942
|
-
})
|
|
1943
|
-
.catch(() => {
|
|
1944
|
-
process.exit(1);
|
|
1945
|
-
});
|
|
1682
|
+
this.emergencyShutdown(0, "SIGHUP");
|
|
1946
1683
|
});
|
|
1947
1684
|
}
|
|
1948
1685
|
async handleShutdown() {
|
|
@@ -1952,9 +1689,9 @@ export class DevEnvironment {
|
|
|
1952
1689
|
sendSessionEndTelemetry().catch(() => { });
|
|
1953
1690
|
// Release the lock file
|
|
1954
1691
|
this.releaseLock();
|
|
1955
|
-
// Read
|
|
1692
|
+
// Read session info BEFORE deleting it (needed for cleanup)
|
|
1956
1693
|
const projectName = getProjectName();
|
|
1957
|
-
const
|
|
1694
|
+
const sessionInfo = getSessionInfo(projectName);
|
|
1958
1695
|
// Clean up session file
|
|
1959
1696
|
try {
|
|
1960
1697
|
const sessionFile = join(homedir(), ".d3k", projectName, "session.json");
|
|
@@ -1965,8 +1702,7 @@ export class DevEnvironment {
|
|
|
1965
1702
|
catch (_error) {
|
|
1966
1703
|
// Non-fatal - ignore cleanup errors
|
|
1967
1704
|
}
|
|
1968
|
-
// Check PID file ownership BEFORE deleting (needed for
|
|
1969
|
-
// Only the process that owns the PID file should clean up the MCP server
|
|
1705
|
+
// Check PID file ownership BEFORE deleting (needed for cleanup decisions)
|
|
1970
1706
|
let weOwnPidFile = false;
|
|
1971
1707
|
try {
|
|
1972
1708
|
if (existsSync(this.pidFile)) {
|
|
@@ -2019,7 +1755,8 @@ export class DevEnvironment {
|
|
|
2019
1755
|
// Fallback: force kill any remaining Chrome processes for THIS instance only
|
|
2020
1756
|
try {
|
|
2021
1757
|
const projectName = getProjectName();
|
|
2022
|
-
const
|
|
1758
|
+
const sessionInfo = getSessionInfo(projectName);
|
|
1759
|
+
const chromePids = sessionInfo?.chromePids ?? [];
|
|
2023
1760
|
if (chromePids.length > 0) {
|
|
2024
1761
|
this.debugLog(`Fallback cleanup: killing Chrome PIDs for this instance: [${chromePids.join(", ")}]`);
|
|
2025
1762
|
const { spawn } = await import("child_process");
|
|
@@ -2035,16 +1772,18 @@ export class DevEnvironment {
|
|
|
2035
1772
|
else {
|
|
2036
1773
|
this.debugLog("Fallback cleanup: no Chrome PIDs found for this instance");
|
|
2037
1774
|
}
|
|
1775
|
+
if (sessionInfo?.serverPid) {
|
|
1776
|
+
this.killServerPidIfOwned(sessionInfo.serverPid, sessionInfo.cwd, "TUI shutdown");
|
|
1777
|
+
}
|
|
2038
1778
|
}
|
|
2039
1779
|
catch {
|
|
2040
1780
|
// Ignore errors in fallback cleanup
|
|
2041
1781
|
}
|
|
2042
1782
|
}
|
|
2043
1783
|
}
|
|
2044
|
-
// REMOVED: No longer clean up
|
|
1784
|
+
// REMOVED: No longer clean up CLI config files on shutdown
|
|
2045
1785
|
// This was causing Claude Code instances to crash when dev3000 was killed
|
|
2046
|
-
//
|
|
2047
|
-
// for the next dev3000 run, providing a better developer experience
|
|
1786
|
+
// Config file cleanup removed; keep user config files untouched on shutdown
|
|
2048
1787
|
// Kill processes on both ports (skip in sandbox - lsof doesn't exist)
|
|
2049
1788
|
const killPortProcess = async (port, name) => {
|
|
2050
1789
|
// Skip lsof-based kill in sandbox environments
|
|
@@ -2099,7 +1838,7 @@ export class DevEnvironment {
|
|
|
2099
1838
|
}
|
|
2100
1839
|
}
|
|
2101
1840
|
};
|
|
2102
|
-
// Kill app server
|
|
1841
|
+
// Kill app server
|
|
2103
1842
|
if (!this.options.tui) {
|
|
2104
1843
|
console.log(chalk.yellow("🔄 Killing app server..."));
|
|
2105
1844
|
}
|
|
@@ -2154,18 +1893,8 @@ export class DevEnvironment {
|
|
|
2154
1893
|
spawnSync("sh", ["-c", `pkill -f "next-server.*${cwd}"`], { stdio: "ignore" });
|
|
2155
1894
|
this.debugLog(`Sent pkill signal for next processes in ${cwd}`);
|
|
2156
1895
|
// Kill server process and its children using the saved PID (from before session file was deleted)
|
|
2157
|
-
if (
|
|
2158
|
-
|
|
2159
|
-
spawnSync("pkill", ["-P", savedServerPid.toString()], { stdio: "ignore" });
|
|
2160
|
-
this.debugLog(`Killed children of server PID ${savedServerPid}`);
|
|
2161
|
-
// Kill the server process itself
|
|
2162
|
-
try {
|
|
2163
|
-
process.kill(savedServerPid, "SIGKILL");
|
|
2164
|
-
this.debugLog(`Killed server PID ${savedServerPid}`);
|
|
2165
|
-
}
|
|
2166
|
-
catch {
|
|
2167
|
-
// Process may already be dead
|
|
2168
|
-
}
|
|
1896
|
+
if (sessionInfo?.serverPid) {
|
|
1897
|
+
this.killServerPidIfOwned(sessionInfo.serverPid, sessionInfo.cwd, "handleShutdown");
|
|
2169
1898
|
}
|
|
2170
1899
|
// Final synchronous lsof kill - most reliable method
|
|
2171
1900
|
const result = spawnSync("sh", ["-c", `lsof -ti:${this.options.port} | xargs kill -9 2>/dev/null`], {
|
|
@@ -2176,35 +1905,6 @@ export class DevEnvironment {
|
|
|
2176
1905
|
catch {
|
|
2177
1906
|
// Ignore pkill errors
|
|
2178
1907
|
}
|
|
2179
|
-
// Kill MCP server only if this is the last d3k instance AND we own the PID file
|
|
2180
|
-
// (other d3k instances in other projects might still need it)
|
|
2181
|
-
// The TUI parent shouldn't do MCP cleanup - the subprocess (which owns the PID file) will handle it
|
|
2182
|
-
// Note: weOwnPidFile was already determined at the top of handleShutdown()
|
|
2183
|
-
const otherInstances = countActiveD3kInstances(true); // exclude current process
|
|
2184
|
-
this.debugLog(`Other active d3k instances: ${otherInstances}, weOwnPidFile: ${weOwnPidFile}`);
|
|
2185
|
-
if (otherInstances === 0 && this.options.mcpPort && weOwnPidFile) {
|
|
2186
|
-
if (!this.options.tui) {
|
|
2187
|
-
console.log(chalk.yellow("🔄 Killing MCP server (last d3k instance)..."));
|
|
2188
|
-
}
|
|
2189
|
-
this.debugLog(`Killing MCP server on port ${this.options.mcpPort} (no other d3k instances)`);
|
|
2190
|
-
try {
|
|
2191
|
-
const { spawnSync } = await import("child_process");
|
|
2192
|
-
const mcpResult = spawnSync("sh", ["-c", `lsof -ti:${this.options.mcpPort} -sTCP:LISTEN | xargs kill -9 2>/dev/null`], { stdio: "pipe", timeout: 5000 });
|
|
2193
|
-
this.debugLog(`MCP server kill exit code: ${mcpResult.status}`);
|
|
2194
|
-
if (!this.options.tui) {
|
|
2195
|
-
console.log(chalk.green("✅ MCP server stopped"));
|
|
2196
|
-
}
|
|
2197
|
-
}
|
|
2198
|
-
catch (error) {
|
|
2199
|
-
this.debugLog(`Error killing MCP server: ${error}`);
|
|
2200
|
-
}
|
|
2201
|
-
}
|
|
2202
|
-
else if (otherInstances > 0) {
|
|
2203
|
-
this.debugLog(`Keeping MCP server running for ${otherInstances} other d3k instance(s)`);
|
|
2204
|
-
}
|
|
2205
|
-
else if (!weOwnPidFile) {
|
|
2206
|
-
this.debugLog("Skipping MCP cleanup - we don't own the PID file (subprocess will handle it)");
|
|
2207
|
-
}
|
|
2208
1908
|
if (!this.options.tui) {
|
|
2209
1909
|
console.log(chalk.green("✅ Cleanup complete"));
|
|
2210
1910
|
}
|