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.
Files changed (516) hide show
  1. package/README.md +3 -1
  2. package/dist/cdp-monitor.d.ts +2 -3
  3. package/dist/cdp-monitor.d.ts.map +1 -1
  4. package/dist/cdp-monitor.js +5 -11
  5. package/dist/cdp-monitor.js.map +1 -1
  6. package/dist/cli.js +182 -161
  7. package/dist/cli.js.map +1 -1
  8. package/dist/commands/cloud-check-pr.js +2 -1
  9. package/dist/commands/cloud-check-pr.js.map +1 -1
  10. package/dist/commands/cloud-fix.d.ts +1 -2
  11. package/dist/commands/cloud-fix.d.ts.map +1 -1
  12. package/dist/commands/cloud-fix.js +49 -685
  13. package/dist/commands/cloud-fix.js.map +1 -1
  14. package/dist/components/PackageSelector.d.ts +3 -2
  15. package/dist/components/PackageSelector.d.ts.map +1 -1
  16. package/dist/components/PackageSelector.js +9 -4
  17. package/dist/components/PackageSelector.js.map +1 -1
  18. package/dist/dev-environment.d.ts +9 -40
  19. package/dist/dev-environment.d.ts.map +1 -1
  20. package/dist/dev-environment.js +257 -557
  21. package/dist/dev-environment.js.map +1 -1
  22. package/dist/skills/d3k/SKILL.md +35 -2
  23. package/dist/src/tui-interface-impl.tsx +2 -12
  24. package/dist/tui-interface-impl.d.ts +0 -1
  25. package/dist/tui-interface-impl.d.ts.map +1 -1
  26. package/dist/tui-interface-impl.js +3 -7
  27. package/dist/tui-interface-impl.js.map +1 -1
  28. package/dist/tui-interface-opentui.d.ts +0 -1
  29. package/dist/tui-interface-opentui.d.ts.map +1 -1
  30. package/dist/tui-interface-opentui.js +26 -10
  31. package/dist/tui-interface-opentui.js.map +1 -1
  32. package/dist/tui-interface.d.ts +0 -1
  33. package/dist/tui-interface.d.ts.map +1 -1
  34. package/dist/tui-interface.js.map +1 -1
  35. package/dist/utils/agent-browser.d.ts.map +1 -1
  36. package/dist/utils/agent-browser.js +18 -13
  37. package/dist/utils/agent-browser.js.map +1 -1
  38. package/dist/utils/agent-selection.d.ts +1 -0
  39. package/dist/utils/agent-selection.d.ts.map +1 -1
  40. package/dist/utils/agent-selection.js +32 -1
  41. package/dist/utils/agent-selection.js.map +1 -1
  42. package/dist/utils/d3k-dir.d.ts +3 -0
  43. package/dist/utils/d3k-dir.d.ts.map +1 -0
  44. package/dist/utils/d3k-dir.js +12 -0
  45. package/dist/utils/d3k-dir.js.map +1 -0
  46. package/dist/utils/skill-installer.d.ts +7 -7
  47. package/dist/utils/skill-installer.d.ts.map +1 -1
  48. package/dist/utils/skill-installer.js +131 -18
  49. package/dist/utils/skill-installer.js.map +1 -1
  50. package/dist/utils/user-config.d.ts +0 -1
  51. package/dist/utils/user-config.d.ts.map +1 -1
  52. package/dist/utils/user-config.js +0 -13
  53. package/dist/utils/user-config.js.map +1 -1
  54. package/package.json +9 -29
  55. package/src/tui-interface-impl.tsx +2 -12
  56. package/dist/commands/cloud-fix-workflow.d.ts +0 -16
  57. package/dist/commands/cloud-fix-workflow.d.ts.map +0 -1
  58. package/dist/commands/cloud-fix-workflow.js +0 -153
  59. package/dist/commands/cloud-fix-workflow.js.map +0 -1
  60. package/dist/commands/restart.d.ts +0 -8
  61. package/dist/commands/restart.d.ts.map +0 -1
  62. package/dist/commands/restart.js +0 -92
  63. package/dist/commands/restart.js.map +0 -1
  64. package/dist/utils/mcp-configs.d.ts +0 -6
  65. package/dist/utils/mcp-configs.d.ts.map +0 -1
  66. package/dist/utils/mcp-configs.js +0 -54
  67. package/dist/utils/mcp-configs.js.map +0 -1
  68. package/mcp-server/.next/BUILD_ID +0 -1
  69. package/mcp-server/.next/app-path-routes-manifest.json +0 -22
  70. package/mcp-server/.next/build/chunks/[root-of-the-server]__25374c4f._.js +0 -500
  71. package/mcp-server/.next/build/chunks/[root-of-the-server]__25374c4f._.js.map +0 -11
  72. package/mcp-server/.next/build/chunks/[root-of-the-server]__6e020478._.js +0 -441
  73. package/mcp-server/.next/build/chunks/[root-of-the-server]__6e020478._.js.map +0 -7
  74. package/mcp-server/.next/build/chunks/[root-of-the-server]__c438ef56._.js +0 -205
  75. package/mcp-server/.next/build/chunks/[root-of-the-server]__c438ef56._.js.map +0 -8
  76. package/mcp-server/.next/build/chunks/[root-of-the-server]__c7ae8543._.js +0 -500
  77. package/mcp-server/.next/build/chunks/[root-of-the-server]__c7ae8543._.js.map +0 -11
  78. package/mcp-server/.next/build/chunks/[turbopack-node]_transforms_postcss_ts_7988927e._.js +0 -13
  79. package/mcp-server/.next/build/chunks/[turbopack-node]_transforms_postcss_ts_7988927e._.js.map +0 -5
  80. package/mcp-server/.next/build/chunks/[turbopack-node]_transforms_webpack-loaders_ts_1efa112f._.js +0 -12
  81. package/mcp-server/.next/build/chunks/[turbopack-node]_transforms_webpack-loaders_ts_1efa112f._.js.map +0 -5
  82. package/mcp-server/.next/build/chunks/[turbopack]_runtime.js +0 -795
  83. package/mcp-server/.next/build/chunks/[turbopack]_runtime.js.map +0 -10
  84. package/mcp-server/.next/build/chunks/node_modules__bun_19755e4f._.js +0 -6758
  85. package/mcp-server/.next/build/chunks/node_modules__bun_19755e4f._.js.map +0 -47
  86. package/mcp-server/.next/build/package.json +0 -1
  87. package/mcp-server/.next/build/postcss.js +0 -6
  88. package/mcp-server/.next/build/postcss.js.map +0 -5
  89. package/mcp-server/.next/build/webpack-loaders.js +0 -6
  90. package/mcp-server/.next/build/webpack-loaders.js.map +0 -5
  91. package/mcp-server/.next/build-manifest.json +0 -20
  92. package/mcp-server/.next/export-marker.json +0 -6
  93. package/mcp-server/.next/fallback-build-manifest.json +0 -12
  94. package/mcp-server/.next/images-manifest.json +0 -66
  95. package/mcp-server/.next/next-minimal-server.js.nft.json +0 -1
  96. package/mcp-server/.next/next-server.js.nft.json +0 -1
  97. package/mcp-server/.next/package.json +0 -1
  98. package/mcp-server/.next/prerender-manifest.json +0 -85
  99. package/mcp-server/.next/required-server-files.js +0 -164
  100. package/mcp-server/.next/required-server-files.json +0 -164
  101. package/mcp-server/.next/routes-manifest.json +0 -171
  102. package/mcp-server/.next/server/app/_global-error/page/app-paths-manifest.json +0 -3
  103. package/mcp-server/.next/server/app/_global-error/page/build-manifest.json +0 -17
  104. package/mcp-server/.next/server/app/_global-error/page/next-font-manifest.json +0 -6
  105. package/mcp-server/.next/server/app/_global-error/page/react-loadable-manifest.json +0 -1
  106. package/mcp-server/.next/server/app/_global-error/page/server-reference-manifest.json +0 -4
  107. package/mcp-server/.next/server/app/_global-error/page.js +0 -10
  108. package/mcp-server/.next/server/app/_global-error/page.js.map +0 -5
  109. package/mcp-server/.next/server/app/_global-error/page.js.nft.json +0 -1
  110. package/mcp-server/.next/server/app/_global-error/page_client-reference-manifest.js +0 -2
  111. package/mcp-server/.next/server/app/_global-error.html +0 -2
  112. package/mcp-server/.next/server/app/_global-error.meta +0 -15
  113. package/mcp-server/.next/server/app/_global-error.rsc +0 -12
  114. package/mcp-server/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +0 -5
  115. package/mcp-server/.next/server/app/_global-error.segments/_full.segment.rsc +0 -12
  116. package/mcp-server/.next/server/app/_global-error.segments/_head.segment.rsc +0 -5
  117. package/mcp-server/.next/server/app/_global-error.segments/_index.segment.rsc +0 -4
  118. package/mcp-server/.next/server/app/_global-error.segments/_tree.segment.rsc +0 -1
  119. package/mcp-server/.next/server/app/_not-found/page/app-paths-manifest.json +0 -3
  120. package/mcp-server/.next/server/app/_not-found/page/build-manifest.json +0 -17
  121. package/mcp-server/.next/server/app/_not-found/page/next-font-manifest.json +0 -6
  122. package/mcp-server/.next/server/app/_not-found/page/react-loadable-manifest.json +0 -1
  123. package/mcp-server/.next/server/app/_not-found/page/server-reference-manifest.json +0 -4
  124. package/mcp-server/.next/server/app/_not-found/page.js +0 -13
  125. package/mcp-server/.next/server/app/_not-found/page.js.map +0 -5
  126. package/mcp-server/.next/server/app/_not-found/page.js.nft.json +0 -1
  127. package/mcp-server/.next/server/app/_not-found/page_client-reference-manifest.js +0 -2
  128. package/mcp-server/.next/server/app/_not-found.html +0 -1
  129. package/mcp-server/.next/server/app/_not-found.meta +0 -16
  130. package/mcp-server/.next/server/app/_not-found.rsc +0 -14
  131. package/mcp-server/.next/server/app/_not-found.segments/_full.segment.rsc +0 -14
  132. package/mcp-server/.next/server/app/_not-found.segments/_head.segment.rsc +0 -5
  133. package/mcp-server/.next/server/app/_not-found.segments/_index.segment.rsc +0 -6
  134. package/mcp-server/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +0 -5
  135. package/mcp-server/.next/server/app/_not-found.segments/_not-found.segment.rsc +0 -4
  136. package/mcp-server/.next/server/app/_not-found.segments/_tree.segment.rsc +0 -2
  137. package/mcp-server/.next/server/app/api/jank/[session]/route/app-paths-manifest.json +0 -3
  138. package/mcp-server/.next/server/app/api/jank/[session]/route/build-manifest.json +0 -11
  139. package/mcp-server/.next/server/app/api/jank/[session]/route/server-reference-manifest.json +0 -4
  140. package/mcp-server/.next/server/app/api/jank/[session]/route.js +0 -10
  141. package/mcp-server/.next/server/app/api/jank/[session]/route.js.map +0 -5
  142. package/mcp-server/.next/server/app/api/jank/[session]/route.js.nft.json +0 -1
  143. package/mcp-server/.next/server/app/api/jank/[session]/route_client-reference-manifest.js +0 -2
  144. package/mcp-server/.next/server/app/api/logs/append/route/app-paths-manifest.json +0 -3
  145. package/mcp-server/.next/server/app/api/logs/append/route/build-manifest.json +0 -11
  146. package/mcp-server/.next/server/app/api/logs/append/route/server-reference-manifest.json +0 -4
  147. package/mcp-server/.next/server/app/api/logs/append/route.js +0 -6
  148. package/mcp-server/.next/server/app/api/logs/append/route.js.map +0 -5
  149. package/mcp-server/.next/server/app/api/logs/append/route.js.nft.json +0 -1
  150. package/mcp-server/.next/server/app/api/logs/append/route_client-reference-manifest.js +0 -2
  151. package/mcp-server/.next/server/app/api/logs/head/route/app-paths-manifest.json +0 -3
  152. package/mcp-server/.next/server/app/api/logs/head/route/build-manifest.json +0 -11
  153. package/mcp-server/.next/server/app/api/logs/head/route/server-reference-manifest.json +0 -4
  154. package/mcp-server/.next/server/app/api/logs/head/route.js +0 -6
  155. package/mcp-server/.next/server/app/api/logs/head/route.js.map +0 -5
  156. package/mcp-server/.next/server/app/api/logs/head/route.js.nft.json +0 -1
  157. package/mcp-server/.next/server/app/api/logs/head/route_client-reference-manifest.js +0 -2
  158. package/mcp-server/.next/server/app/api/logs/list/route/app-paths-manifest.json +0 -3
  159. package/mcp-server/.next/server/app/api/logs/list/route/build-manifest.json +0 -11
  160. package/mcp-server/.next/server/app/api/logs/list/route/server-reference-manifest.json +0 -4
  161. package/mcp-server/.next/server/app/api/logs/list/route.js +0 -6
  162. package/mcp-server/.next/server/app/api/logs/list/route.js.map +0 -5
  163. package/mcp-server/.next/server/app/api/logs/list/route.js.nft.json +0 -1
  164. package/mcp-server/.next/server/app/api/logs/list/route_client-reference-manifest.js +0 -2
  165. package/mcp-server/.next/server/app/api/logs/rotate/route/app-paths-manifest.json +0 -3
  166. package/mcp-server/.next/server/app/api/logs/rotate/route/build-manifest.json +0 -11
  167. package/mcp-server/.next/server/app/api/logs/rotate/route/server-reference-manifest.json +0 -4
  168. package/mcp-server/.next/server/app/api/logs/rotate/route.js +0 -8
  169. package/mcp-server/.next/server/app/api/logs/rotate/route.js.map +0 -5
  170. package/mcp-server/.next/server/app/api/logs/rotate/route.js.nft.json +0 -1
  171. package/mcp-server/.next/server/app/api/logs/rotate/route_client-reference-manifest.js +0 -2
  172. package/mcp-server/.next/server/app/api/logs/stream/route/app-paths-manifest.json +0 -3
  173. package/mcp-server/.next/server/app/api/logs/stream/route/build-manifest.json +0 -11
  174. package/mcp-server/.next/server/app/api/logs/stream/route/server-reference-manifest.json +0 -4
  175. package/mcp-server/.next/server/app/api/logs/stream/route.js +0 -6
  176. package/mcp-server/.next/server/app/api/logs/stream/route.js.map +0 -5
  177. package/mcp-server/.next/server/app/api/logs/stream/route.js.nft.json +0 -1
  178. package/mcp-server/.next/server/app/api/logs/stream/route_client-reference-manifest.js +0 -2
  179. package/mcp-server/.next/server/app/api/logs/tail/route/app-paths-manifest.json +0 -3
  180. package/mcp-server/.next/server/app/api/logs/tail/route/build-manifest.json +0 -11
  181. package/mcp-server/.next/server/app/api/logs/tail/route/server-reference-manifest.json +0 -4
  182. package/mcp-server/.next/server/app/api/logs/tail/route.js +0 -6
  183. package/mcp-server/.next/server/app/api/logs/tail/route.js.map +0 -5
  184. package/mcp-server/.next/server/app/api/logs/tail/route.js.nft.json +0 -1
  185. package/mcp-server/.next/server/app/api/logs/tail/route_client-reference-manifest.js +0 -2
  186. package/mcp-server/.next/server/app/api/orchestrator/route/app-paths-manifest.json +0 -3
  187. package/mcp-server/.next/server/app/api/orchestrator/route/build-manifest.json +0 -11
  188. package/mcp-server/.next/server/app/api/orchestrator/route/server-reference-manifest.json +0 -4
  189. package/mcp-server/.next/server/app/api/orchestrator/route.js +0 -9
  190. package/mcp-server/.next/server/app/api/orchestrator/route.js.map +0 -5
  191. package/mcp-server/.next/server/app/api/orchestrator/route.js.nft.json +0 -1
  192. package/mcp-server/.next/server/app/api/orchestrator/route_client-reference-manifest.js +0 -2
  193. package/mcp-server/.next/server/app/api/screenshots/[filename]/route/app-paths-manifest.json +0 -3
  194. package/mcp-server/.next/server/app/api/screenshots/[filename]/route/build-manifest.json +0 -11
  195. package/mcp-server/.next/server/app/api/screenshots/[filename]/route/server-reference-manifest.json +0 -4
  196. package/mcp-server/.next/server/app/api/screenshots/[filename]/route.js +0 -8
  197. package/mcp-server/.next/server/app/api/screenshots/[filename]/route.js.map +0 -5
  198. package/mcp-server/.next/server/app/api/screenshots/[filename]/route.js.nft.json +0 -1
  199. package/mcp-server/.next/server/app/api/screenshots/[filename]/route_client-reference-manifest.js +0 -2
  200. package/mcp-server/.next/server/app/api/screenshots/capture/route/app-paths-manifest.json +0 -3
  201. package/mcp-server/.next/server/app/api/screenshots/capture/route/build-manifest.json +0 -11
  202. package/mcp-server/.next/server/app/api/screenshots/capture/route/server-reference-manifest.json +0 -4
  203. package/mcp-server/.next/server/app/api/screenshots/capture/route.js +0 -9
  204. package/mcp-server/.next/server/app/api/screenshots/capture/route.js.map +0 -5
  205. package/mcp-server/.next/server/app/api/screenshots/capture/route.js.nft.json +0 -1
  206. package/mcp-server/.next/server/app/api/screenshots/capture/route_client-reference-manifest.js +0 -2
  207. package/mcp-server/.next/server/app/api/screenshots/clear/route/app-paths-manifest.json +0 -3
  208. package/mcp-server/.next/server/app/api/screenshots/clear/route/build-manifest.json +0 -11
  209. package/mcp-server/.next/server/app/api/screenshots/clear/route/server-reference-manifest.json +0 -4
  210. package/mcp-server/.next/server/app/api/screenshots/clear/route.js +0 -8
  211. package/mcp-server/.next/server/app/api/screenshots/clear/route.js.map +0 -5
  212. package/mcp-server/.next/server/app/api/screenshots/clear/route.js.nft.json +0 -1
  213. package/mcp-server/.next/server/app/api/screenshots/clear/route_client-reference-manifest.js +0 -2
  214. package/mcp-server/.next/server/app/api/screenshots/list/route/app-paths-manifest.json +0 -3
  215. package/mcp-server/.next/server/app/api/screenshots/list/route/build-manifest.json +0 -11
  216. package/mcp-server/.next/server/app/api/screenshots/list/route/server-reference-manifest.json +0 -4
  217. package/mcp-server/.next/server/app/api/screenshots/list/route.js +0 -8
  218. package/mcp-server/.next/server/app/api/screenshots/list/route.js.map +0 -5
  219. package/mcp-server/.next/server/app/api/screenshots/list/route.js.nft.json +0 -1
  220. package/mcp-server/.next/server/app/api/screenshots/list/route_client-reference-manifest.js +0 -2
  221. package/mcp-server/.next/server/app/api/teams/route/app-paths-manifest.json +0 -3
  222. package/mcp-server/.next/server/app/api/teams/route/build-manifest.json +0 -11
  223. package/mcp-server/.next/server/app/api/teams/route/server-reference-manifest.json +0 -4
  224. package/mcp-server/.next/server/app/api/teams/route.js +0 -8
  225. package/mcp-server/.next/server/app/api/teams/route.js.map +0 -5
  226. package/mcp-server/.next/server/app/api/teams/route.js.nft.json +0 -1
  227. package/mcp-server/.next/server/app/api/teams/route_client-reference-manifest.js +0 -2
  228. package/mcp-server/.next/server/app/api/tools/route/app-paths-manifest.json +0 -3
  229. package/mcp-server/.next/server/app/api/tools/route/build-manifest.json +0 -11
  230. package/mcp-server/.next/server/app/api/tools/route/server-reference-manifest.json +0 -4
  231. package/mcp-server/.next/server/app/api/tools/route.js +0 -8
  232. package/mcp-server/.next/server/app/api/tools/route.js.map +0 -5
  233. package/mcp-server/.next/server/app/api/tools/route.js.nft.json +0 -1
  234. package/mcp-server/.next/server/app/api/tools/route_client-reference-manifest.js +0 -2
  235. package/mcp-server/.next/server/app/index.html +0 -1
  236. package/mcp-server/.next/server/app/index.meta +0 -14
  237. package/mcp-server/.next/server/app/index.rsc +0 -18
  238. package/mcp-server/.next/server/app/index.segments/__PAGE__.segment.rsc +0 -9
  239. package/mcp-server/.next/server/app/index.segments/_full.segment.rsc +0 -18
  240. package/mcp-server/.next/server/app/index.segments/_head.segment.rsc +0 -5
  241. package/mcp-server/.next/server/app/index.segments/_index.segment.rsc +0 -6
  242. package/mcp-server/.next/server/app/index.segments/_tree.segment.rsc +0 -2
  243. package/mcp-server/.next/server/app/logs/page/app-paths-manifest.json +0 -3
  244. package/mcp-server/.next/server/app/logs/page/build-manifest.json +0 -17
  245. package/mcp-server/.next/server/app/logs/page/next-font-manifest.json +0 -6
  246. package/mcp-server/.next/server/app/logs/page/react-loadable-manifest.json +0 -1
  247. package/mcp-server/.next/server/app/logs/page/server-reference-manifest.json +0 -4
  248. package/mcp-server/.next/server/app/logs/page.js +0 -16
  249. package/mcp-server/.next/server/app/logs/page.js.map +0 -5
  250. package/mcp-server/.next/server/app/logs/page.js.nft.json +0 -1
  251. package/mcp-server/.next/server/app/logs/page_client-reference-manifest.js +0 -2
  252. package/mcp-server/.next/server/app/mcp/route/app-paths-manifest.json +0 -3
  253. package/mcp-server/.next/server/app/mcp/route/build-manifest.json +0 -11
  254. package/mcp-server/.next/server/app/mcp/route/server-reference-manifest.json +0 -4
  255. package/mcp-server/.next/server/app/mcp/route.js +0 -11
  256. package/mcp-server/.next/server/app/mcp/route.js.map +0 -5
  257. package/mcp-server/.next/server/app/mcp/route.js.nft.json +0 -1
  258. package/mcp-server/.next/server/app/mcp/route_client-reference-manifest.js +0 -2
  259. package/mcp-server/.next/server/app/page/app-paths-manifest.json +0 -3
  260. package/mcp-server/.next/server/app/page/build-manifest.json +0 -17
  261. package/mcp-server/.next/server/app/page/next-font-manifest.json +0 -6
  262. package/mcp-server/.next/server/app/page/react-loadable-manifest.json +0 -1
  263. package/mcp-server/.next/server/app/page/server-reference-manifest.json +0 -4
  264. package/mcp-server/.next/server/app/page.js +0 -15
  265. package/mcp-server/.next/server/app/page.js.map +0 -5
  266. package/mcp-server/.next/server/app/page.js.nft.json +0 -1
  267. package/mcp-server/.next/server/app/page_client-reference-manifest.js +0 -2
  268. package/mcp-server/.next/server/app/video/[session]/page/app-paths-manifest.json +0 -3
  269. package/mcp-server/.next/server/app/video/[session]/page/build-manifest.json +0 -17
  270. package/mcp-server/.next/server/app/video/[session]/page/next-font-manifest.json +0 -6
  271. package/mcp-server/.next/server/app/video/[session]/page/react-loadable-manifest.json +0 -1
  272. package/mcp-server/.next/server/app/video/[session]/page/server-reference-manifest.json +0 -4
  273. package/mcp-server/.next/server/app/video/[session]/page.js +0 -15
  274. package/mcp-server/.next/server/app/video/[session]/page.js.map +0 -5
  275. package/mcp-server/.next/server/app/video/[session]/page.js.nft.json +0 -1
  276. package/mcp-server/.next/server/app/video/[session]/page_client-reference-manifest.js +0 -2
  277. package/mcp-server/.next/server/app-paths-manifest.json +0 -22
  278. package/mcp-server/.next/server/chunks/250ae__next-internal_server_app_api_screenshots_[filename]_route_actions_4f8d6e37.js +0 -3
  279. package/mcp-server/.next/server/chunks/250ae__next-internal_server_app_api_screenshots_[filename]_route_actions_4f8d6e37.js.map +0 -1
  280. package/mcp-server/.next/server/chunks/250ae__next-internal_server_app_api_screenshots_capture_route_actions_4034f26c.js +0 -3
  281. package/mcp-server/.next/server/chunks/250ae__next-internal_server_app_api_screenshots_capture_route_actions_4034f26c.js.map +0 -1
  282. package/mcp-server/.next/server/chunks/250ae__next-internal_server_app_api_screenshots_clear_route_actions_e26206f4.js +0 -3
  283. package/mcp-server/.next/server/chunks/250ae__next-internal_server_app_api_screenshots_clear_route_actions_e26206f4.js.map +0 -1
  284. package/mcp-server/.next/server/chunks/[externals]__0e1fd2ca._.js +0 -3
  285. package/mcp-server/.next/server/chunks/[externals]__0e1fd2ca._.js.map +0 -1
  286. package/mcp-server/.next/server/chunks/[externals]_next_dist_2a398dc7._.js +0 -3
  287. package/mcp-server/.next/server/chunks/[externals]_next_dist_2a398dc7._.js.map +0 -1
  288. package/mcp-server/.next/server/chunks/[externals]_node:crypto_c20cce38._.js +0 -3
  289. package/mcp-server/.next/server/chunks/[externals]_node:crypto_c20cce38._.js.map +0 -1
  290. package/mcp-server/.next/server/chunks/[root-of-the-server]__1dca9894._.js +0 -3
  291. package/mcp-server/.next/server/chunks/[root-of-the-server]__1dca9894._.js.map +0 -1
  292. package/mcp-server/.next/server/chunks/[root-of-the-server]__21541e6b._.js +0 -11
  293. package/mcp-server/.next/server/chunks/[root-of-the-server]__21541e6b._.js.map +0 -1
  294. package/mcp-server/.next/server/chunks/[root-of-the-server]__2f95edf0._.js +0 -17
  295. package/mcp-server/.next/server/chunks/[root-of-the-server]__2f95edf0._.js.map +0 -1
  296. package/mcp-server/.next/server/chunks/[root-of-the-server]__377f76d7._.js +0 -7
  297. package/mcp-server/.next/server/chunks/[root-of-the-server]__377f76d7._.js.map +0 -1
  298. package/mcp-server/.next/server/chunks/[root-of-the-server]__454b0d3c._.js +0 -7
  299. package/mcp-server/.next/server/chunks/[root-of-the-server]__454b0d3c._.js.map +0 -1
  300. package/mcp-server/.next/server/chunks/[root-of-the-server]__69e6dfb7._.js +0 -3
  301. package/mcp-server/.next/server/chunks/[root-of-the-server]__69e6dfb7._.js.map +0 -1
  302. package/mcp-server/.next/server/chunks/[root-of-the-server]__6baff21e._.js +0 -4
  303. package/mcp-server/.next/server/chunks/[root-of-the-server]__6baff21e._.js.map +0 -1
  304. package/mcp-server/.next/server/chunks/[root-of-the-server]__6f790e1f._.js +0 -3
  305. package/mcp-server/.next/server/chunks/[root-of-the-server]__6f790e1f._.js.map +0 -1
  306. package/mcp-server/.next/server/chunks/[root-of-the-server]__7049acd5._.js +0 -3
  307. package/mcp-server/.next/server/chunks/[root-of-the-server]__7049acd5._.js.map +0 -1
  308. package/mcp-server/.next/server/chunks/[root-of-the-server]__73c9cc46._.js +0 -3
  309. package/mcp-server/.next/server/chunks/[root-of-the-server]__73c9cc46._.js.map +0 -1
  310. package/mcp-server/.next/server/chunks/[root-of-the-server]__78991125._.js +0 -3
  311. package/mcp-server/.next/server/chunks/[root-of-the-server]__78991125._.js.map +0 -1
  312. package/mcp-server/.next/server/chunks/[root-of-the-server]__7ae828c6._.js +0 -3
  313. package/mcp-server/.next/server/chunks/[root-of-the-server]__7ae828c6._.js.map +0 -1
  314. package/mcp-server/.next/server/chunks/[root-of-the-server]__94946101._.js +0 -3
  315. package/mcp-server/.next/server/chunks/[root-of-the-server]__94946101._.js.map +0 -1
  316. package/mcp-server/.next/server/chunks/[root-of-the-server]__99274dd8._.js +0 -4
  317. package/mcp-server/.next/server/chunks/[root-of-the-server]__99274dd8._.js.map +0 -1
  318. package/mcp-server/.next/server/chunks/[root-of-the-server]__9c4c7095._.js +0 -3
  319. package/mcp-server/.next/server/chunks/[root-of-the-server]__9c4c7095._.js.map +0 -1
  320. package/mcp-server/.next/server/chunks/[root-of-the-server]__b56464d6._.js +0 -7
  321. package/mcp-server/.next/server/chunks/[root-of-the-server]__b56464d6._.js.map +0 -1
  322. package/mcp-server/.next/server/chunks/[root-of-the-server]__b698502d._.js +0 -3
  323. package/mcp-server/.next/server/chunks/[root-of-the-server]__b698502d._.js.map +0 -1
  324. package/mcp-server/.next/server/chunks/[root-of-the-server]__b86e20b6._.js +0 -3
  325. package/mcp-server/.next/server/chunks/[root-of-the-server]__b86e20b6._.js.map +0 -1
  326. package/mcp-server/.next/server/chunks/[root-of-the-server]__c8cf5b23._.js +0 -3
  327. package/mcp-server/.next/server/chunks/[root-of-the-server]__c8cf5b23._.js.map +0 -1
  328. package/mcp-server/.next/server/chunks/[root-of-the-server]__e6a83e60._.js +0 -4
  329. package/mcp-server/.next/server/chunks/[root-of-the-server]__e6a83e60._.js.map +0 -1
  330. package/mcp-server/.next/server/chunks/[root-of-the-server]__ee139f8a._.js +0 -3
  331. package/mcp-server/.next/server/chunks/[root-of-the-server]__ee139f8a._.js.map +0 -1
  332. package/mcp-server/.next/server/chunks/[turbopack]_runtime.js +0 -795
  333. package/mcp-server/.next/server/chunks/[turbopack]_runtime.js.map +0 -10
  334. package/mcp-server/.next/server/chunks/edd96_next_80752ad3._.js +0 -3
  335. package/mcp-server/.next/server/chunks/edd96_next_80752ad3._.js.map +0 -1
  336. package/mcp-server/.next/server/chunks/edd96_next_dist_esm_build_templates_app-route_f51c5640.js +0 -3
  337. package/mcp-server/.next/server/chunks/edd96_next_dist_esm_build_templates_app-route_f51c5640.js.map +0 -1
  338. package/mcp-server/.next/server/chunks/edd96_next_dist_fa47e982._.js +0 -6
  339. package/mcp-server/.next/server/chunks/edd96_next_dist_fa47e982._.js.map +0 -1
  340. package/mcp-server/.next/server/chunks/edd96_next_ef93dda6._.js +0 -14
  341. package/mcp-server/.next/server/chunks/edd96_next_ef93dda6._.js.map +0 -1
  342. package/mcp-server/.next/server/chunks/mcp-server_70405c2f._.js +0 -3
  343. package/mcp-server/.next/server/chunks/mcp-server_70405c2f._.js.map +0 -1
  344. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_jank_[session]_route_actions_3b2b275b.js +0 -3
  345. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_jank_[session]_route_actions_3b2b275b.js.map +0 -1
  346. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_append_route_actions_bc66060f.js +0 -3
  347. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_append_route_actions_bc66060f.js.map +0 -1
  348. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_head_route_actions_1152480c.js +0 -3
  349. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_head_route_actions_1152480c.js.map +0 -1
  350. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_list_route_actions_b9e24400.js +0 -3
  351. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_list_route_actions_b9e24400.js.map +0 -1
  352. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_rotate_route_actions_76075d08.js +0 -3
  353. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_rotate_route_actions_76075d08.js.map +0 -1
  354. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_stream_route_actions_16e5c553.js +0 -3
  355. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_stream_route_actions_16e5c553.js.map +0 -1
  356. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_tail_route_actions_55440150.js +0 -3
  357. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_logs_tail_route_actions_55440150.js.map +0 -1
  358. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_orchestrator_route_actions_c6fba9ec.js +0 -3
  359. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_orchestrator_route_actions_c6fba9ec.js.map +0 -1
  360. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_screenshots_list_route_actions_acfa57bd.js +0 -3
  361. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_screenshots_list_route_actions_acfa57bd.js.map +0 -1
  362. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_teams_route_actions_aaa1c876.js +0 -3
  363. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_teams_route_actions_aaa1c876.js.map +0 -1
  364. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_tools_route_actions_007f3c7c.js +0 -3
  365. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_api_tools_route_actions_007f3c7c.js.map +0 -1
  366. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_mcp_route_actions_7f7b5be4.js +0 -3
  367. package/mcp-server/.next/server/chunks/mcp-server__next-internal_server_app_mcp_route_actions_7f7b5be4.js.map +0 -1
  368. package/mcp-server/.next/server/chunks/mcp-server_app_mcp_tools_ts_faf6d7df._.js +0 -185
  369. package/mcp-server/.next/server/chunks/mcp-server_app_mcp_tools_ts_faf6d7df._.js.map +0 -1
  370. package/mcp-server/.next/server/chunks/mcp-server_instrumentation_node_ts_32271e34._.js +0 -3
  371. package/mcp-server/.next/server/chunks/mcp-server_instrumentation_node_ts_32271e34._.js.map +0 -1
  372. package/mcp-server/.next/server/chunks/src_utils_agent-browser_ts_cc00e0d8._.js +0 -3
  373. package/mcp-server/.next/server/chunks/src_utils_agent-browser_ts_cc00e0d8._.js.map +0 -1
  374. package/mcp-server/.next/server/chunks/src_utils_project-name_ts_1fab1dd5._.js +0 -3
  375. package/mcp-server/.next/server/chunks/src_utils_project-name_ts_1fab1dd5._.js.map +0 -1
  376. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__250a4cf3._.js +0 -3
  377. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__250a4cf3._.js.map +0 -1
  378. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__41e244ae._.js +0 -3
  379. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__41e244ae._.js.map +0 -1
  380. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__4a45fb1f._.js +0 -4
  381. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__4a45fb1f._.js.map +0 -1
  382. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__4feaccaf._.js +0 -3
  383. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__4feaccaf._.js.map +0 -1
  384. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__6d9fa861._.js +0 -3
  385. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__6d9fa861._.js.map +0 -1
  386. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__9913ce94._.js +0 -3
  387. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__9913ce94._.js.map +0 -1
  388. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__9923da5e._.js +0 -3
  389. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__9923da5e._.js.map +0 -1
  390. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__a8fcf205._.js +0 -3
  391. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__a8fcf205._.js.map +0 -1
  392. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__b17d4048._.js +0 -3
  393. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__b17d4048._.js.map +0 -1
  394. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__dcf84f77._.js +0 -3
  395. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__dcf84f77._.js.map +0 -1
  396. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__df4ed844._.js +0 -3
  397. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__df4ed844._.js.map +0 -1
  398. package/mcp-server/.next/server/chunks/ssr/[turbopack]_runtime.js +0 -795
  399. package/mcp-server/.next/server/chunks/ssr/[turbopack]_runtime.js.map +0 -10
  400. package/mcp-server/.next/server/chunks/ssr/_213c874b._.js +0 -4
  401. package/mcp-server/.next/server/chunks/ssr/_213c874b._.js.map +0 -1
  402. package/mcp-server/.next/server/chunks/ssr/_69be9abe._.js +0 -4
  403. package/mcp-server/.next/server/chunks/ssr/_69be9abe._.js.map +0 -1
  404. package/mcp-server/.next/server/chunks/ssr/_b38781f1._.js +0 -4
  405. package/mcp-server/.next/server/chunks/ssr/_b38781f1._.js.map +0 -1
  406. package/mcp-server/.next/server/chunks/ssr/_edba94b0._.js +0 -8
  407. package/mcp-server/.next/server/chunks/ssr/_edba94b0._.js.map +0 -1
  408. package/mcp-server/.next/server/chunks/ssr/_f478416d._.js +0 -8
  409. package/mcp-server/.next/server/chunks/ssr/_f478416d._.js.map +0 -1
  410. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_22d4e869._.js +0 -4
  411. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_22d4e869._.js.map +0 -1
  412. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_329c4a9b._.js +0 -10
  413. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_329c4a9b._.js.map +0 -1
  414. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_6cceb2cd._.js +0 -3
  415. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_6cceb2cd._.js.map +0 -1
  416. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_861297ac._.js +0 -6
  417. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_861297ac._.js.map +0 -1
  418. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_client_components_85c7e922._.js +0 -3
  419. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_client_components_85c7e922._.js.map +0 -1
  420. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_client_components_builtin_forbidden_0eb1cacd.js +0 -3
  421. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_client_components_builtin_forbidden_0eb1cacd.js.map +0 -1
  422. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_client_components_builtin_global-error_e64e654b.js +0 -3
  423. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_client_components_builtin_global-error_e64e654b.js.map +0 -1
  424. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_client_components_builtin_unauthorized_06e7b5f5.js +0 -3
  425. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_client_components_builtin_unauthorized_06e7b5f5.js.map +0 -1
  426. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_esm_build_templates_app-page_f82c7ca4.js +0 -4
  427. package/mcp-server/.next/server/chunks/ssr/edd96_next_dist_esm_build_templates_app-page_f82c7ca4.js.map +0 -1
  428. package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app__global-error_page_actions_404453e7.js +0 -3
  429. package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app__global-error_page_actions_404453e7.js.map +0 -1
  430. package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app__not-found_page_actions_c1864427.js +0 -3
  431. package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app__not-found_page_actions_c1864427.js.map +0 -1
  432. package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app_logs_page_actions_71542ba9.js +0 -3
  433. package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app_logs_page_actions_71542ba9.js.map +0 -1
  434. package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app_page_actions_a5ee4758.js +0 -3
  435. package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app_page_actions_a5ee4758.js.map +0 -1
  436. package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app_video_[session]_page_actions_a6aab323.js +0 -3
  437. package/mcp-server/.next/server/chunks/ssr/mcp-server__next-internal_server_app_video_[session]_page_actions_a6aab323.js.map +0 -1
  438. package/mcp-server/.next/server/chunks/ssr/mcp-server_app_layout_tsx_afa41767._.js +0 -3
  439. package/mcp-server/.next/server/chunks/ssr/mcp-server_app_layout_tsx_afa41767._.js.map +0 -1
  440. package/mcp-server/.next/server/chunks/ssr/mcp-server_app_page_tsx_9fc46577._.js +0 -3
  441. package/mcp-server/.next/server/chunks/ssr/mcp-server_app_page_tsx_9fc46577._.js.map +0 -1
  442. package/mcp-server/.next/server/chunks/ssr/mcp-server_components_dark-mode-toggle_tsx_f31dd15d._.js +0 -3
  443. package/mcp-server/.next/server/chunks/ssr/mcp-server_components_dark-mode-toggle_tsx_f31dd15d._.js.map +0 -1
  444. package/mcp-server/.next/server/chunks/ssr/node_modules__bun_39d5fbaf._.js +0 -3
  445. package/mcp-server/.next/server/chunks/ssr/node_modules__bun_39d5fbaf._.js.map +0 -1
  446. package/mcp-server/.next/server/chunks/ssr/node_modules__bun_d6d37386._.js +0 -5
  447. package/mcp-server/.next/server/chunks/ssr/node_modules__bun_d6d37386._.js.map +0 -1
  448. package/mcp-server/.next/server/functions-config-manifest.json +0 -4
  449. package/mcp-server/.next/server/instrumentation.js +0 -4
  450. package/mcp-server/.next/server/instrumentation.js.nft.json +0 -1
  451. package/mcp-server/.next/server/interception-route-rewrite-manifest.js +0 -1
  452. package/mcp-server/.next/server/middleware-build-manifest.js +0 -21
  453. package/mcp-server/.next/server/middleware-manifest.json +0 -6
  454. package/mcp-server/.next/server/next-font-manifest.js +0 -1
  455. package/mcp-server/.next/server/next-font-manifest.json +0 -6
  456. package/mcp-server/.next/server/pages/404.html +0 -1
  457. package/mcp-server/.next/server/pages/500.html +0 -2
  458. package/mcp-server/.next/server/pages-manifest.json +0 -4
  459. package/mcp-server/.next/server/server-reference-manifest.js +0 -1
  460. package/mcp-server/.next/server/server-reference-manifest.json +0 -5
  461. package/mcp-server/.next/static/chunks/10099c90a1ca89ea.js +0 -4
  462. package/mcp-server/.next/static/chunks/10c04cb580a9beec.js +0 -1
  463. package/mcp-server/.next/static/chunks/13606014ef33124c.js +0 -2
  464. package/mcp-server/.next/static/chunks/39e9bdcc541cc428.js +0 -1
  465. package/mcp-server/.next/static/chunks/3f3f8e7d16ba3bf4.js +0 -1
  466. package/mcp-server/.next/static/chunks/4785978304fb9e19.js +0 -1
  467. package/mcp-server/.next/static/chunks/59cdeaf92a780e96.css +0 -1
  468. package/mcp-server/.next/static/chunks/5df77c9395248155.js +0 -1
  469. package/mcp-server/.next/static/chunks/807aef58565dccb1.js +0 -1
  470. package/mcp-server/.next/static/chunks/a6dad97d9634a72d.js +0 -1
  471. package/mcp-server/.next/static/chunks/a6dad97d9634a72d.js.map +0 -1
  472. package/mcp-server/.next/static/chunks/b8eb42a9560f7980.js +0 -3
  473. package/mcp-server/.next/static/chunks/ea7b53054294e7bb.js +0 -3
  474. package/mcp-server/.next/static/chunks/ec58e1c556f5d0fa.js +0 -3
  475. package/mcp-server/.next/static/chunks/turbopack-b64e111cadf03885.js +0 -4
  476. package/mcp-server/.next/static/gTFARHqj7X4ZmcJWlUVID/_buildManifest.js +0 -11
  477. package/mcp-server/.next/static/gTFARHqj7X4ZmcJWlUVID/_clientMiddlewareManifest.json +0 -1
  478. package/mcp-server/.next/static/gTFARHqj7X4ZmcJWlUVID/_ssgManifest.js +0 -1
  479. package/mcp-server/app/api/jank/[session]/route.ts +0 -344
  480. package/mcp-server/app/api/logs/append/route.ts +0 -82
  481. package/mcp-server/app/api/logs/head/route.ts +0 -32
  482. package/mcp-server/app/api/logs/list/route.ts +0 -71
  483. package/mcp-server/app/api/logs/rotate/route.ts +0 -48
  484. package/mcp-server/app/api/logs/stream/route.ts +0 -61
  485. package/mcp-server/app/api/logs/tail/route.ts +0 -32
  486. package/mcp-server/app/api/orchestrator/route.ts +0 -73
  487. package/mcp-server/app/api/screenshots/[filename]/route.ts +0 -61
  488. package/mcp-server/app/api/screenshots/capture/route.ts +0 -137
  489. package/mcp-server/app/api/screenshots/clear/route.ts +0 -44
  490. package/mcp-server/app/api/screenshots/list/route.ts +0 -22
  491. package/mcp-server/app/api/teams/route.ts +0 -86
  492. package/mcp-server/app/api/tools/route.ts +0 -92
  493. package/mcp-server/app/globals.css +0 -124
  494. package/mcp-server/app/layout.tsx +0 -23
  495. package/mcp-server/app/logs/LogsClient.infinite-loop.test.tsx +0 -127
  496. package/mcp-server/app/logs/LogsClient.test.ts +0 -416
  497. package/mcp-server/app/logs/LogsClient.tsx +0 -1967
  498. package/mcp-server/app/logs/page.tsx +0 -150
  499. package/mcp-server/app/logs/utils.ts +0 -151
  500. package/mcp-server/app/mcp/client-manager.ts +0 -346
  501. package/mcp-server/app/mcp/route.ts +0 -765
  502. package/mcp-server/app/mcp/tools.ts +0 -4158
  503. package/mcp-server/app/page.tsx +0 -399
  504. package/mcp-server/app/video/[session]/page.tsx +0 -239
  505. package/mcp-server/next-env.d.ts +0 -6
  506. package/mcp-server/package.json +0 -48
  507. package/mcp-server/postcss.config.mjs +0 -5
  508. package/mcp-server/public/favicon-16.svg +0 -4
  509. package/mcp-server/public/favicon-180.png +0 -0
  510. package/mcp-server/public/favicon-64.svg +0 -4
  511. package/mcp-server/public/favicon-preview.html +0 -67
  512. package/mcp-server/public/favicon.ico +0 -0
  513. package/mcp-server/public/favicon.svg +0 -4
  514. package/mcp-server/public/screenshots/test.txt +0 -1
  515. package/mcp-server/start-production.mjs +0 -101
  516. package/mcp-server/tsconfig.json +0 -28
@@ -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
- // MCP names
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 _VERCEL_MCP_URL = "https://mcp.vercel.com";
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 determines whether MCP server should be killed on shutdown.
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 MCP orchestrator
288
+ // Framework detection happens in cli.ts and is stored in session files for CLI integration
394
289
  /**
395
- * Check if Chrome version supports chrome-devtools MCP (>= 140.0.7339.214)
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 isChromeDevtoolsMcpSupported() {
398
- try {
399
- // Try different Chrome binary paths
400
- const chromePaths = [
401
- "/tmp/chromium", // Vercel Sandbox (@sparticuz/chromium)
402
- "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", // macOS
403
- "/opt/google/chrome/chrome", // Linux
404
- "chrome", // PATH
405
- "google-chrome", // Linux PATH
406
- "google-chrome-stable" // Linux PATH
407
- ];
408
- for (const chromePath of chromePaths) {
409
- try {
410
- const versionOutput = await new Promise((resolve, reject) => {
411
- const chromeProcess = spawn(chromePath, ["--version"], {
412
- stdio: ["ignore", "pipe", "ignore"]
413
- });
414
- let output = "";
415
- chromeProcess.stdout?.on("data", (data) => {
416
- output += data.toString();
417
- });
418
- chromeProcess.on("close", (code) => {
419
- if (code === 0) {
420
- resolve(output.trim());
421
- }
422
- else {
423
- reject(new Error(`Chrome version check failed with code ${code}`));
424
- }
425
- });
426
- chromeProcess.on("error", reject);
427
- // Timeout after 3 seconds
428
- setTimeout(() => {
429
- chromeProcess.kill();
430
- reject(new Error("Chrome version check timeout"));
431
- }, 3000);
432
- });
433
- // Parse version from output like "Google Chrome 140.0.7339.214"
434
- const versionMatch = versionOutput.match(/(\d+)\.(\d+)\.(\d+)\.(\d+)/);
435
- if (versionMatch) {
436
- const [, major, minor, build, patch] = versionMatch.map(Number);
437
- const currentVersion = [major, minor, build, patch];
438
- const requiredVersion = [140, 0, 7339, 214];
439
- // Compare version numbers
440
- for (let i = 0; i < 4; i++) {
441
- if (currentVersion[i] > requiredVersion[i])
442
- return true;
443
- if (currentVersion[i] < requiredVersion[i])
444
- return false;
445
- }
446
- return true; // Versions are equal
447
- }
448
- break; // Found Chrome but couldn't parse version - continue with other paths
449
- }
450
- catch {
451
- // Try next Chrome path
452
- }
453
- }
454
- return false; // Chrome not found or version not supported
455
- }
456
- catch {
457
- return false; // Any error means not supported
458
- }
459
- }
460
- /**
461
- * Clean up old dev3000 MCP entries from project's .mcp.json (Claude Code)
462
- * MCP server has been removed - we now use CLI commands instead
463
- */
464
- async function ensureMcpServers(_mcpPort, _appPort, _enableChromeDevtools) {
465
- try {
466
- const settingsPath = join(process.cwd(), ".mcp.json");
467
- if (!existsSync(settingsPath)) {
468
- return; // Nothing to clean up
469
- }
470
- const settingsContent = readFileSync(settingsPath, "utf-8");
471
- const settings = JSON.parse(settingsContent);
472
- if (!settings.mcpServers) {
473
- return; // Nothing to clean up
474
- }
475
- let removed = false;
476
- // Remove dev3000 MCP entry if it exists (MCP server removed)
477
- if (settings.mcpServers[MCP_NAMES.DEV3000]) {
478
- delete settings.mcpServers[MCP_NAMES.DEV3000];
479
- removed = true;
480
- }
481
- // Write if we removed anything
482
- if (removed) {
483
- writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
484
- }
485
- }
486
- catch (_error) {
487
- // Ignore errors - settings file manipulation is optional
488
- }
489
- }
490
- /**
491
- * Clean up old dev3000 MCP entries from project's .cursor/mcp.json
492
- * MCP server has been removed - we now use CLI commands instead
493
- */
494
- async function ensureCursorMcpServers(_mcpPort, _appPort, _enableChromeDevtools) {
495
- try {
496
- const cursorDir = join(process.cwd(), ".cursor");
497
- const settingsPath = join(cursorDir, "mcp.json");
498
- if (!existsSync(settingsPath)) {
499
- return; // Nothing to clean up
500
- }
501
- const settingsContent = readFileSync(settingsPath, "utf-8");
502
- const settings = JSON.parse(settingsContent);
503
- if (!settings.mcpServers) {
504
- return; // Nothing to clean up
505
- }
506
- let removed = false;
507
- // Remove dev3000 MCP entry if it exists (MCP server removed)
508
- if (settings.mcpServers[MCP_NAMES.DEV3000]) {
509
- delete settings.mcpServers[MCP_NAMES.DEV3000];
510
- removed = true;
511
- }
512
- // Write if we removed anything
513
- if (removed) {
514
- writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
515
- }
516
- }
517
- catch (_error) {
518
- // Ignore errors - settings file manipulation is optional
519
- }
520
- }
521
- /**
522
- * Clean up old dev3000 MCP entries from project's opencode.json
523
- * OpenCode uses "mcp" instead of "mcpServers"
524
- * MCP server has been removed - we now use CLI commands instead
525
- */
526
- async function ensureOpenCodeMcpServers(_mcpPort, _appPort, _enableChromeDevtools) {
527
- try {
528
- const settingsPath = join(process.cwd(), "opencode.json");
529
- if (!existsSync(settingsPath)) {
530
- return; // Nothing to clean up
531
- }
532
- const settingsContent = readFileSync(settingsPath, "utf-8");
533
- const settings = JSON.parse(settingsContent);
534
- if (!settings.mcp) {
535
- return; // Nothing to clean up
536
- }
537
- let removed = false;
538
- // Remove dev3000 MCP entry if it exists (MCP server removed)
539
- if (settings.mcp[MCP_NAMES.DEV3000]) {
540
- delete settings.mcp[MCP_NAMES.DEV3000];
541
- removed = true;
542
- }
543
- // Write if we removed anything
544
- if (removed) {
545
- writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
546
- }
547
- }
548
- catch (_error) {
549
- // Ignore errors - settings file manipulation is optional
550
- }
551
- }
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
- // Install directly to .claude/skills/d3k/ (where Claude Code looks)
565
- const skillDir = join(process.cwd(), ".claude", "skills", "d3k");
566
- const skillPath = join(skillDir, "SKILL.md");
567
- // Check if already up to date
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
- if (existsSync(skillPath)) {
570
- const existingContent = readFileSync(skillPath, "utf-8");
571
- if (existingContent === bundledContent) {
572
- return; // Already up to date
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
- // MCP config files are now kept persistent across dev3000 restarts
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 MCP server to discover.
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, mcpPort, cdpUrl, chromePids, serverCommand, framework, serverPid) {
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 sessionInfo.serverPid || null;
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
- // Handle portMcp vs mcpPort naming
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
- // Clean up orphaned Playwright/Chrome processes from previous crashed sessions
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
- // MCP server removed - no longer need to check mcpPort availability
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 - MCP server has been removed
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
- async configureMcpConfigs() {
942
- const enabledTargets = MCP_CONFIG_TARGETS.filter((target) => !this.disabledMcpConfigSet.has(target));
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
- const configuredTargets = [];
948
- if (enabledTargets.includes("claude")) {
949
- await ensureMcpServers(this.options.mcpPort || "3684", this.options.port, this.chromeDevtoolsSupported);
950
- await ensureD3kSkill(); // Install d3k skill for Claude Code
951
- configuredTargets.push("claude");
952
- }
953
- if (enabledTargets.includes("cursor")) {
954
- await ensureCursorMcpServers(this.options.mcpPort || "3684", this.options.port, this.chromeDevtoolsSupported);
955
- configuredTargets.push("cursor");
956
- }
957
- if (enabledTargets.includes("opencode")) {
958
- await ensureOpenCodeMcpServers(this.options.mcpPort || "3684", this.options.port, this.chromeDevtoolsSupported);
959
- configuredTargets.push("opencode");
960
- }
961
- if (configuredTargets.length > 0) {
962
- this.logD3K(`AI CLI Integration: Configured MCP servers in ${formatMcpConfigTargets(configuredTargets)}`);
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
- else {
965
- this.logD3K("AI CLI Integration: MCP configs already up to date");
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
- // MCP server removed - using CLI commands instead
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
- // MCP server removed - using CLI commands instead
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 MCP server discovery (include CDP URL if browser monitoring was started)
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, this.options.mcpPort, cdpUrl, chromePids, this.options.serverCommand, this.options.framework, this.serverProcess?.pid);
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
- // MCP server removed - using CLI commands instead
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
- // MCP server removed - using CLI commands instead
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, this.options.mcpPort, cdpUrl, chromePids, this.options.serverCommand, this.options.framework, this.serverProcess?.pid);
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 - use Chrome extension for browser monitoring"));
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, this.options.mcpPort, cdpUrl || undefined, chromePids, this.options.serverCommand, this.options.framework, this.serverProcess?.pid);
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, this.options.mcpPort, cdpUrl || undefined, chromePids, this.options.serverCommand, this.options.framework, this.serverProcess?.pid);
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 server PID from session file BEFORE deleting it (needed for cleanup)
1447
+ // Read session info BEFORE deleting it (needed for cleanup)
1667
1448
  const projectName = getProjectName();
1668
- const savedServerPid = getSessionServerPid(projectName);
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 MCP cleanup decision)
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 (MCP server remains as singleton)
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 (!isInSandbox() && savedServerPid) {
1734
- try {
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. Kill MCP server IF we're the last d3k instance (synchronous)
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
- if (this.isShuttingDown)
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 server PID from session file BEFORE deleting it (needed for cleanup)
1692
+ // Read session info BEFORE deleting it (needed for cleanup)
1956
1693
  const projectName = getProjectName();
1957
- const savedServerPid = getSessionServerPid(projectName);
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 MCP cleanup decision)
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 chromePids = getSessionChromePids(projectName);
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 MCP config files on shutdown
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
- // Now we keep .mcp.json, .cursor/mcp.json, and opencode.json configured
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 (MCP server remains as singleton)
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 (savedServerPid) {
2158
- // Kill all child processes of the server
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
  }