claude-chrome-parallel 1.0.0

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 (395) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +501 -0
  3. package/assets/demo.svg +278 -0
  4. package/dist/cdp/client.d.ts +218 -0
  5. package/dist/cdp/client.d.ts.map +1 -0
  6. package/dist/cdp/client.js +797 -0
  7. package/dist/cdp/client.js.map +1 -0
  8. package/dist/cdp/connection-pool.d.ts +125 -0
  9. package/dist/cdp/connection-pool.d.ts.map +1 -0
  10. package/dist/cdp/connection-pool.js +443 -0
  11. package/dist/cdp/connection-pool.js.map +1 -0
  12. package/dist/cdp/screenshot-scheduler.d.ts +54 -0
  13. package/dist/cdp/screenshot-scheduler.d.ts.map +1 -0
  14. package/dist/cdp/screenshot-scheduler.js +87 -0
  15. package/dist/cdp/screenshot-scheduler.js.map +1 -0
  16. package/dist/chrome/launcher.d.ts +55 -0
  17. package/dist/chrome/launcher.d.ts.map +1 -0
  18. package/dist/chrome/launcher.js +383 -0
  19. package/dist/chrome/launcher.js.map +1 -0
  20. package/dist/chrome/pool.d.ts +54 -0
  21. package/dist/chrome/pool.d.ts.map +1 -0
  22. package/dist/chrome/pool.js +301 -0
  23. package/dist/chrome/pool.js.map +1 -0
  24. package/dist/chrome/profile-detector.d.ts +52 -0
  25. package/dist/chrome/profile-detector.d.ts.map +1 -0
  26. package/dist/chrome/profile-detector.js +246 -0
  27. package/dist/chrome/profile-detector.js.map +1 -0
  28. package/dist/cli/claude-session.d.ts +11 -0
  29. package/dist/cli/claude-session.js +349 -0
  30. package/dist/cli/claude-session.js.map +1 -0
  31. package/dist/cli/index.d.ts +14 -0
  32. package/dist/cli/index.js +858 -0
  33. package/dist/cli/index.js.map +1 -0
  34. package/dist/cli/install.d.ts +16 -0
  35. package/dist/cli/install.js +185 -0
  36. package/dist/cli/install.js.map +1 -0
  37. package/dist/cli/uninstall.d.ts +7 -0
  38. package/dist/cli/uninstall.js +126 -0
  39. package/dist/cli/uninstall.js.map +1 -0
  40. package/dist/cli/update-check.d.ts +9 -0
  41. package/dist/cli/update-check.js +141 -0
  42. package/dist/cli/update-check.js.map +1 -0
  43. package/dist/config/config-recovery.d.ts +69 -0
  44. package/dist/config/config-recovery.d.ts.map +1 -0
  45. package/dist/config/config-recovery.js +302 -0
  46. package/dist/config/config-recovery.js.map +1 -0
  47. package/dist/config/global.d.ts +49 -0
  48. package/dist/config/global.d.ts.map +1 -0
  49. package/dist/config/global.js +24 -0
  50. package/dist/config/global.js.map +1 -0
  51. package/dist/config/index.d.ts +7 -0
  52. package/dist/config/index.d.ts.map +1 -0
  53. package/dist/config/index.js +23 -0
  54. package/dist/config/index.js.map +1 -0
  55. package/dist/config/session-isolator.d.ts +76 -0
  56. package/dist/config/session-isolator.d.ts.map +1 -0
  57. package/dist/config/session-isolator.js +268 -0
  58. package/dist/config/session-isolator.js.map +1 -0
  59. package/dist/dashboard/activity-tracker.d.ts +76 -0
  60. package/dist/dashboard/activity-tracker.d.ts.map +1 -0
  61. package/dist/dashboard/activity-tracker.js +219 -0
  62. package/dist/dashboard/activity-tracker.js.map +1 -0
  63. package/dist/dashboard/ansi.d.ts +117 -0
  64. package/dist/dashboard/ansi.d.ts.map +1 -0
  65. package/dist/dashboard/ansi.js +199 -0
  66. package/dist/dashboard/ansi.js.map +1 -0
  67. package/dist/dashboard/index.d.ts +110 -0
  68. package/dist/dashboard/index.d.ts.map +1 -0
  69. package/dist/dashboard/index.js +412 -0
  70. package/dist/dashboard/index.js.map +1 -0
  71. package/dist/dashboard/keyboard-handler.d.ts +43 -0
  72. package/dist/dashboard/keyboard-handler.d.ts.map +1 -0
  73. package/dist/dashboard/keyboard-handler.js +215 -0
  74. package/dist/dashboard/keyboard-handler.js.map +1 -0
  75. package/dist/dashboard/operation-controller.d.ts +76 -0
  76. package/dist/dashboard/operation-controller.d.ts.map +1 -0
  77. package/dist/dashboard/operation-controller.js +167 -0
  78. package/dist/dashboard/operation-controller.js.map +1 -0
  79. package/dist/dashboard/renderer.d.ts +76 -0
  80. package/dist/dashboard/renderer.d.ts.map +1 -0
  81. package/dist/dashboard/renderer.js +193 -0
  82. package/dist/dashboard/renderer.js.map +1 -0
  83. package/dist/dashboard/types.d.ts +56 -0
  84. package/dist/dashboard/types.d.ts.map +1 -0
  85. package/dist/dashboard/types.js +12 -0
  86. package/dist/dashboard/types.js.map +1 -0
  87. package/dist/dashboard/views/main-view.d.ts +23 -0
  88. package/dist/dashboard/views/main-view.d.ts.map +1 -0
  89. package/dist/dashboard/views/main-view.js +143 -0
  90. package/dist/dashboard/views/main-view.js.map +1 -0
  91. package/dist/dashboard/views/sessions-view.d.ts +22 -0
  92. package/dist/dashboard/views/sessions-view.d.ts.map +1 -0
  93. package/dist/dashboard/views/sessions-view.js +104 -0
  94. package/dist/dashboard/views/sessions-view.js.map +1 -0
  95. package/dist/dashboard/views/tabs-view.d.ts +21 -0
  96. package/dist/dashboard/views/tabs-view.d.ts.map +1 -0
  97. package/dist/dashboard/views/tabs-view.js +92 -0
  98. package/dist/dashboard/views/tabs-view.js.map +1 -0
  99. package/dist/hints/hint-engine.d.ts +77 -0
  100. package/dist/hints/hint-engine.d.ts.map +1 -0
  101. package/dist/hints/hint-engine.js +191 -0
  102. package/dist/hints/hint-engine.js.map +1 -0
  103. package/dist/hints/index.d.ts +8 -0
  104. package/dist/hints/index.d.ts.map +1 -0
  105. package/dist/hints/index.js +11 -0
  106. package/dist/hints/index.js.map +1 -0
  107. package/dist/hints/pattern-learner.d.ts +76 -0
  108. package/dist/hints/pattern-learner.d.ts.map +1 -0
  109. package/dist/hints/pattern-learner.js +254 -0
  110. package/dist/hints/pattern-learner.js.map +1 -0
  111. package/dist/hints/rules/composite-suggestions.d.ts +6 -0
  112. package/dist/hints/rules/composite-suggestions.d.ts.map +1 -0
  113. package/dist/hints/rules/composite-suggestions.js +66 -0
  114. package/dist/hints/rules/composite-suggestions.js.map +1 -0
  115. package/dist/hints/rules/error-recovery.d.ts +7 -0
  116. package/dist/hints/rules/error-recovery.d.ts.map +1 -0
  117. package/dist/hints/rules/error-recovery.js +55 -0
  118. package/dist/hints/rules/error-recovery.js.map +1 -0
  119. package/dist/hints/rules/learned-rules.d.ts +13 -0
  120. package/dist/hints/rules/learned-rules.d.ts.map +1 -0
  121. package/dist/hints/rules/learned-rules.js +27 -0
  122. package/dist/hints/rules/learned-rules.js.map +1 -0
  123. package/dist/hints/rules/repetition-detection.d.ts +7 -0
  124. package/dist/hints/rules/repetition-detection.d.ts.map +1 -0
  125. package/dist/hints/rules/repetition-detection.js +82 -0
  126. package/dist/hints/rules/repetition-detection.js.map +1 -0
  127. package/dist/hints/rules/sequence-detection.d.ts +6 -0
  128. package/dist/hints/rules/sequence-detection.d.ts.map +1 -0
  129. package/dist/hints/rules/sequence-detection.js +89 -0
  130. package/dist/hints/rules/sequence-detection.js.map +1 -0
  131. package/dist/hints/rules/success-hints.d.ts +6 -0
  132. package/dist/hints/rules/success-hints.d.ts.map +1 -0
  133. package/dist/hints/rules/success-hints.js +62 -0
  134. package/dist/hints/rules/success-hints.js.map +1 -0
  135. package/dist/index.d.ts +10 -0
  136. package/dist/index.d.ts.map +1 -0
  137. package/dist/index.js +272 -0
  138. package/dist/index.js.map +1 -0
  139. package/dist/lightpanda/launcher.d.ts +58 -0
  140. package/dist/lightpanda/launcher.d.ts.map +1 -0
  141. package/dist/lightpanda/launcher.js +199 -0
  142. package/dist/lightpanda/launcher.js.map +1 -0
  143. package/dist/mcp-server.d.ts +129 -0
  144. package/dist/mcp-server.d.ts.map +1 -0
  145. package/dist/mcp-server.js +641 -0
  146. package/dist/mcp-server.js.map +1 -0
  147. package/dist/memory/domain-memory.d.ts +68 -0
  148. package/dist/memory/domain-memory.d.ts.map +1 -0
  149. package/dist/memory/domain-memory.js +227 -0
  150. package/dist/memory/domain-memory.js.map +1 -0
  151. package/dist/orchestration/plan-executor.d.ts +19 -0
  152. package/dist/orchestration/plan-executor.d.ts.map +1 -0
  153. package/dist/orchestration/plan-executor.js +284 -0
  154. package/dist/orchestration/plan-executor.js.map +1 -0
  155. package/dist/orchestration/plan-registry.d.ts +55 -0
  156. package/dist/orchestration/plan-registry.d.ts.map +1 -0
  157. package/dist/orchestration/plan-registry.js +255 -0
  158. package/dist/orchestration/plan-registry.js.map +1 -0
  159. package/dist/orchestration/state-manager.d.ts +127 -0
  160. package/dist/orchestration/state-manager.d.ts.map +1 -0
  161. package/dist/orchestration/state-manager.js +438 -0
  162. package/dist/orchestration/state-manager.js.map +1 -0
  163. package/dist/orchestration/workflow-engine.d.ts +162 -0
  164. package/dist/orchestration/workflow-engine.d.ts.map +1 -0
  165. package/dist/orchestration/workflow-engine.js +731 -0
  166. package/dist/orchestration/workflow-engine.js.map +1 -0
  167. package/dist/resources/usage-guide.d.ts +13 -0
  168. package/dist/resources/usage-guide.d.ts.map +1 -0
  169. package/dist/resources/usage-guide.js +101 -0
  170. package/dist/resources/usage-guide.js.map +1 -0
  171. package/dist/router/browser-router.d.ts +51 -0
  172. package/dist/router/browser-router.d.ts.map +1 -0
  173. package/dist/router/browser-router.js +178 -0
  174. package/dist/router/browser-router.js.map +1 -0
  175. package/dist/router/cookie-sync.d.ts +48 -0
  176. package/dist/router/cookie-sync.d.ts.map +1 -0
  177. package/dist/router/cookie-sync.js +106 -0
  178. package/dist/router/cookie-sync.js.map +1 -0
  179. package/dist/router/index.d.ts +5 -0
  180. package/dist/router/index.d.ts.map +1 -0
  181. package/dist/router/index.js +10 -0
  182. package/dist/router/index.js.map +1 -0
  183. package/dist/router/tool-routing-registry.d.ts +21 -0
  184. package/dist/router/tool-routing-registry.d.ts.map +1 -0
  185. package/dist/router/tool-routing-registry.js +90 -0
  186. package/dist/router/tool-routing-registry.js.map +1 -0
  187. package/dist/session-manager.d.ts +251 -0
  188. package/dist/session-manager.d.ts.map +1 -0
  189. package/dist/session-manager.js +912 -0
  190. package/dist/session-manager.js.map +1 -0
  191. package/dist/tools/batch-execute.d.ts +11 -0
  192. package/dist/tools/batch-execute.d.ts.map +1 -0
  193. package/dist/tools/batch-execute.js +226 -0
  194. package/dist/tools/batch-execute.js.map +1 -0
  195. package/dist/tools/click-element.d.ts +8 -0
  196. package/dist/tools/click-element.d.ts.map +1 -0
  197. package/dist/tools/click-element.js +455 -0
  198. package/dist/tools/click-element.js.map +1 -0
  199. package/dist/tools/computer.d.ts +6 -0
  200. package/dist/tools/computer.d.ts.map +1 -0
  201. package/dist/tools/computer.js +638 -0
  202. package/dist/tools/computer.js.map +1 -0
  203. package/dist/tools/console-capture.d.ts +6 -0
  204. package/dist/tools/console-capture.d.ts.map +1 -0
  205. package/dist/tools/console-capture.js +320 -0
  206. package/dist/tools/console-capture.js.map +1 -0
  207. package/dist/tools/cookies.d.ts +6 -0
  208. package/dist/tools/cookies.d.ts.map +1 -0
  209. package/dist/tools/cookies.js +263 -0
  210. package/dist/tools/cookies.js.map +1 -0
  211. package/dist/tools/drag-drop.d.ts +6 -0
  212. package/dist/tools/drag-drop.d.ts.map +1 -0
  213. package/dist/tools/drag-drop.js +252 -0
  214. package/dist/tools/drag-drop.js.map +1 -0
  215. package/dist/tools/emulate-device.d.ts +6 -0
  216. package/dist/tools/emulate-device.d.ts.map +1 -0
  217. package/dist/tools/emulate-device.js +221 -0
  218. package/dist/tools/emulate-device.js.map +1 -0
  219. package/dist/tools/file-upload.d.ts +6 -0
  220. package/dist/tools/file-upload.d.ts.map +1 -0
  221. package/dist/tools/file-upload.js +208 -0
  222. package/dist/tools/file-upload.js.map +1 -0
  223. package/dist/tools/fill-form.d.ts +8 -0
  224. package/dist/tools/fill-form.d.ts.map +1 -0
  225. package/dist/tools/fill-form.js +342 -0
  226. package/dist/tools/fill-form.js.map +1 -0
  227. package/dist/tools/find.d.ts +6 -0
  228. package/dist/tools/find.d.ts.map +1 -0
  229. package/dist/tools/find.js +330 -0
  230. package/dist/tools/find.js.map +1 -0
  231. package/dist/tools/form-input.d.ts +6 -0
  232. package/dist/tools/form-input.d.ts.map +1 -0
  233. package/dist/tools/form-input.js +181 -0
  234. package/dist/tools/form-input.js.map +1 -0
  235. package/dist/tools/geolocation.d.ts +6 -0
  236. package/dist/tools/geolocation.d.ts.map +1 -0
  237. package/dist/tools/geolocation.js +172 -0
  238. package/dist/tools/geolocation.js.map +1 -0
  239. package/dist/tools/http-auth.d.ts +6 -0
  240. package/dist/tools/http-auth.d.ts.map +1 -0
  241. package/dist/tools/http-auth.js +136 -0
  242. package/dist/tools/http-auth.js.map +1 -0
  243. package/dist/tools/index.d.ts +6 -0
  244. package/dist/tools/index.d.ts.map +1 -0
  245. package/dist/tools/index.js +104 -0
  246. package/dist/tools/index.js.map +1 -0
  247. package/dist/tools/javascript.d.ts +6 -0
  248. package/dist/tools/javascript.d.ts.map +1 -0
  249. package/dist/tools/javascript.js +138 -0
  250. package/dist/tools/javascript.js.map +1 -0
  251. package/dist/tools/lightweight-scroll.d.ts +11 -0
  252. package/dist/tools/lightweight-scroll.d.ts.map +1 -0
  253. package/dist/tools/lightweight-scroll.js +266 -0
  254. package/dist/tools/lightweight-scroll.js.map +1 -0
  255. package/dist/tools/memory.d.ts +10 -0
  256. package/dist/tools/memory.d.ts.map +1 -0
  257. package/dist/tools/memory.js +141 -0
  258. package/dist/tools/memory.js.map +1 -0
  259. package/dist/tools/navigate.d.ts +6 -0
  260. package/dist/tools/navigate.d.ts.map +1 -0
  261. package/dist/tools/navigate.js +241 -0
  262. package/dist/tools/navigate.js.map +1 -0
  263. package/dist/tools/network.d.ts +6 -0
  264. package/dist/tools/network.d.ts.map +1 -0
  265. package/dist/tools/network.js +215 -0
  266. package/dist/tools/network.js.map +1 -0
  267. package/dist/tools/orchestration.d.ts +6 -0
  268. package/dist/tools/orchestration.d.ts.map +1 -0
  269. package/dist/tools/orchestration.js +746 -0
  270. package/dist/tools/orchestration.js.map +1 -0
  271. package/dist/tools/page-content.d.ts +6 -0
  272. package/dist/tools/page-content.d.ts.map +1 -0
  273. package/dist/tools/page-content.js +120 -0
  274. package/dist/tools/page-content.js.map +1 -0
  275. package/dist/tools/page-pdf.d.ts +6 -0
  276. package/dist/tools/page-pdf.d.ts.map +1 -0
  277. package/dist/tools/page-pdf.js +245 -0
  278. package/dist/tools/page-pdf.js.map +1 -0
  279. package/dist/tools/page-reload.d.ts +6 -0
  280. package/dist/tools/page-reload.d.ts.map +1 -0
  281. package/dist/tools/page-reload.js +89 -0
  282. package/dist/tools/page-reload.js.map +1 -0
  283. package/dist/tools/performance-metrics.d.ts +6 -0
  284. package/dist/tools/performance-metrics.d.ts.map +1 -0
  285. package/dist/tools/performance-metrics.js +158 -0
  286. package/dist/tools/performance-metrics.js.map +1 -0
  287. package/dist/tools/read-page.d.ts +6 -0
  288. package/dist/tools/read-page.d.ts.map +1 -0
  289. package/dist/tools/read-page.js +287 -0
  290. package/dist/tools/read-page.js.map +1 -0
  291. package/dist/tools/request-intercept.d.ts +6 -0
  292. package/dist/tools/request-intercept.d.ts.map +1 -0
  293. package/dist/tools/request-intercept.js +439 -0
  294. package/dist/tools/request-intercept.js.map +1 -0
  295. package/dist/tools/selector-query.d.ts +6 -0
  296. package/dist/tools/selector-query.d.ts.map +1 -0
  297. package/dist/tools/selector-query.js +206 -0
  298. package/dist/tools/selector-query.js.map +1 -0
  299. package/dist/tools/shutdown.d.ts +12 -0
  300. package/dist/tools/shutdown.d.ts.map +1 -0
  301. package/dist/tools/shutdown.js +120 -0
  302. package/dist/tools/shutdown.js.map +1 -0
  303. package/dist/tools/storage.d.ts +6 -0
  304. package/dist/tools/storage.d.ts.map +1 -0
  305. package/dist/tools/storage.js +264 -0
  306. package/dist/tools/storage.js.map +1 -0
  307. package/dist/tools/tabs-close.d.ts +6 -0
  308. package/dist/tools/tabs-close.d.ts.map +1 -0
  309. package/dist/tools/tabs-close.js +124 -0
  310. package/dist/tools/tabs-close.js.map +1 -0
  311. package/dist/tools/tabs-context.d.ts +6 -0
  312. package/dist/tools/tabs-context.d.ts.map +1 -0
  313. package/dist/tools/tabs-context.js +92 -0
  314. package/dist/tools/tabs-context.js.map +1 -0
  315. package/dist/tools/tabs-create.d.ts +6 -0
  316. package/dist/tools/tabs-create.d.ts.map +1 -0
  317. package/dist/tools/tabs-create.js +73 -0
  318. package/dist/tools/tabs-create.js.map +1 -0
  319. package/dist/tools/user-agent.d.ts +6 -0
  320. package/dist/tools/user-agent.d.ts.map +1 -0
  321. package/dist/tools/user-agent.js +128 -0
  322. package/dist/tools/user-agent.js.map +1 -0
  323. package/dist/tools/wait-and-click.d.ts +8 -0
  324. package/dist/tools/wait-and-click.d.ts.map +1 -0
  325. package/dist/tools/wait-and-click.js +290 -0
  326. package/dist/tools/wait-and-click.js.map +1 -0
  327. package/dist/tools/wait-for.d.ts +6 -0
  328. package/dist/tools/wait-for.d.ts.map +1 -0
  329. package/dist/tools/wait-for.js +248 -0
  330. package/dist/tools/wait-for.js.map +1 -0
  331. package/dist/tools/worker-create.d.ts +7 -0
  332. package/dist/tools/worker-create.d.ts.map +1 -0
  333. package/dist/tools/worker-create.js +62 -0
  334. package/dist/tools/worker-create.js.map +1 -0
  335. package/dist/tools/worker-delete.d.ts +6 -0
  336. package/dist/tools/worker-delete.d.ts.map +1 -0
  337. package/dist/tools/worker-delete.js +80 -0
  338. package/dist/tools/worker-delete.js.map +1 -0
  339. package/dist/tools/worker-list.d.ts +6 -0
  340. package/dist/tools/worker-list.d.ts.map +1 -0
  341. package/dist/tools/worker-list.js +67 -0
  342. package/dist/tools/worker-list.js.map +1 -0
  343. package/dist/tools/xpath-query.d.ts +6 -0
  344. package/dist/tools/xpath-query.d.ts.map +1 -0
  345. package/dist/tools/xpath-query.js +230 -0
  346. package/dist/tools/xpath-query.js.map +1 -0
  347. package/dist/types/browser-backend.d.ts +30 -0
  348. package/dist/types/browser-backend.d.ts.map +1 -0
  349. package/dist/types/browser-backend.js +9 -0
  350. package/dist/types/browser-backend.js.map +1 -0
  351. package/dist/types/index.d.ts +3 -0
  352. package/dist/types/index.d.ts.map +1 -0
  353. package/dist/types/index.js +19 -0
  354. package/dist/types/index.js.map +1 -0
  355. package/dist/types/mcp.d.ts +54 -0
  356. package/dist/types/mcp.d.ts.map +1 -0
  357. package/dist/types/mcp.js +14 -0
  358. package/dist/types/mcp.js.map +1 -0
  359. package/dist/types/plan-cache.d.ts +121 -0
  360. package/dist/types/plan-cache.d.ts.map +1 -0
  361. package/dist/types/plan-cache.js +9 -0
  362. package/dist/types/plan-cache.js.map +1 -0
  363. package/dist/types/profile.d.ts +76 -0
  364. package/dist/types/profile.d.ts.map +1 -0
  365. package/dist/types/profile.js +35 -0
  366. package/dist/types/profile.js.map +1 -0
  367. package/dist/types/session.d.ts +65 -0
  368. package/dist/types/session.d.ts.map +1 -0
  369. package/dist/types/session.js +6 -0
  370. package/dist/types/session.js.map +1 -0
  371. package/dist/types/tool-manifest.d.ts +52 -0
  372. package/dist/types/tool-manifest.d.ts.map +1 -0
  373. package/dist/types/tool-manifest.js +37 -0
  374. package/dist/types/tool-manifest.js.map +1 -0
  375. package/dist/utils/atomic-file.d.ts +50 -0
  376. package/dist/utils/atomic-file.d.ts.map +1 -0
  377. package/dist/utils/atomic-file.js +217 -0
  378. package/dist/utils/atomic-file.js.map +1 -0
  379. package/dist/utils/index.d.ts +6 -0
  380. package/dist/utils/index.d.ts.map +1 -0
  381. package/dist/utils/index.js +22 -0
  382. package/dist/utils/index.js.map +1 -0
  383. package/dist/utils/json-validator.d.ts +40 -0
  384. package/dist/utils/json-validator.d.ts.map +1 -0
  385. package/dist/utils/json-validator.js +295 -0
  386. package/dist/utils/json-validator.js.map +1 -0
  387. package/dist/utils/ref-id-manager.d.ts +26 -0
  388. package/dist/utils/ref-id-manager.d.ts.map +1 -0
  389. package/dist/utils/ref-id-manager.js +81 -0
  390. package/dist/utils/ref-id-manager.js.map +1 -0
  391. package/dist/utils/request-queue.d.ts +37 -0
  392. package/dist/utils/request-queue.d.ts.map +1 -0
  393. package/dist/utils/request-queue.js +110 -0
  394. package/dist/utils/request-queue.js.map +1 -0
  395. package/package.json +78 -0
@@ -0,0 +1,858 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * CLI for Claude Chrome Parallel
5
+ *
6
+ * Commands:
7
+ * - install: Install extension and native messaging host
8
+ * - uninstall: Remove extension and native messaging host
9
+ * - serve: Start MCP server for Claude Code
10
+ * - sessions: List or clear sessions
11
+ * - launch: Start Claude Code with isolated config
12
+ * - doctor: Check installation status
13
+ * - recover: Recover corrupted .claude.json
14
+ */
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ const commander_1 = require("commander");
50
+ // Legacy imports - kept for backward compatibility but deprecated
51
+ // import { install, installNativeHost } from './install';
52
+ // import { uninstall } from './uninstall';
53
+ const path = __importStar(require("path"));
54
+ const fs = __importStar(require("fs"));
55
+ const os = __importStar(require("os"));
56
+ const child_process_1 = require("child_process");
57
+ const update_check_1 = require("./update-check");
58
+ const program = new commander_1.Command();
59
+ // Package info - from dist/cli/ go up two levels to root
60
+ const packageJsonPath = path.join(__dirname, '..', '..', 'package.json');
61
+ let version = '0.1.0';
62
+ try {
63
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
64
+ version = packageJson.version;
65
+ }
66
+ catch {
67
+ // Use default version
68
+ }
69
+ program
70
+ .name('claude-chrome-parallel')
71
+ .description('MCP server for parallel Claude Code browser sessions via CDP')
72
+ .version(version);
73
+ program
74
+ .command('install')
75
+ .description('[DEPRECATED] Extension install is no longer needed. Use CDP mode instead.')
76
+ .option('-f, --force', 'Force reinstall even if already installed')
77
+ .option('--extension-id <id>', 'Chrome extension ID (for native host configuration)')
78
+ .action(async () => {
79
+ console.log('⚠️ DEPRECATED: Extension installation is no longer needed.\n');
80
+ console.log('Claude Chrome Parallel now uses CDP (Chrome DevTools Protocol) mode,');
81
+ console.log('which does not require a Chrome extension.\n');
82
+ console.log('Quick Start:');
83
+ console.log(' 1. Start Chrome with debugging port:');
84
+ console.log(' chrome --remote-debugging-port=9222\n');
85
+ console.log(' 2. Add to ~/.claude.json:');
86
+ console.log(' {');
87
+ console.log(' "mcpServers": {');
88
+ console.log(' "chrome-parallel": {');
89
+ console.log(' "command": "ccp",');
90
+ console.log(' "args": ["serve"]');
91
+ console.log(' }');
92
+ console.log(' }');
93
+ console.log(' }\n');
94
+ console.log(' 3. Restart Claude Code\n');
95
+ console.log('Run "ccp doctor" to verify your setup.');
96
+ });
97
+ program
98
+ .command('uninstall')
99
+ .description('[DEPRECATED] No longer needed - CDP mode has no extension to uninstall')
100
+ .action(async () => {
101
+ console.log('⚠️ DEPRECATED: Uninstall is no longer needed.\n');
102
+ console.log('Claude Chrome Parallel now uses CDP mode, which has no extension to uninstall.');
103
+ console.log('Simply remove the MCP server config from ~/.claude.json if you want to disable it.');
104
+ });
105
+ program
106
+ .command('setup')
107
+ .description('Automatically configure MCP server for Claude Code')
108
+ .option('--dashboard', 'Enable terminal dashboard')
109
+ .option('--auto-launch', 'Auto-launch Chrome if not running (default: true)')
110
+ .option('-s, --scope <scope>', 'Installation scope: "user" (global, default) or "project" (current project only)', 'user')
111
+ .action(async (options) => {
112
+ const { execSync, spawnSync } = require('child_process');
113
+ console.log('Setting up Claude Chrome Parallel for Claude Code...\n');
114
+ // Check if claude CLI is available
115
+ try {
116
+ execSync('claude --version', { stdio: 'pipe' });
117
+ }
118
+ catch {
119
+ console.error('❌ Claude Code CLI not found.');
120
+ console.error(' Please install Claude Code first: https://claude.ai/code');
121
+ process.exit(1);
122
+ }
123
+ // Validate scope
124
+ const scope = options.scope || 'user';
125
+ if (scope !== 'user' && scope !== 'project') {
126
+ console.error('❌ Invalid scope. Use "user" (global) or "project" (current project only).');
127
+ process.exit(1);
128
+ }
129
+ // Build the serve arguments
130
+ const serveArgs = ['serve', '--auto-launch'];
131
+ if (options.dashboard) {
132
+ serveArgs.push('--dashboard');
133
+ }
134
+ // Remove existing configuration first (if any)
135
+ try {
136
+ execSync('claude mcp remove claude-chrome-parallel 2>/dev/null', { stdio: 'pipe' });
137
+ }
138
+ catch {
139
+ // Ignore if not exists
140
+ }
141
+ // Use npx for auto-updates: every server start fetches the latest version
142
+ const fullCommand = `claude mcp add claude-chrome-parallel -s ${scope} -- npx -y claude-chrome-parallel ${serveArgs.join(' ')}`;
143
+ console.log(`Running: claude mcp add claude-chrome-parallel (scope: ${scope})...`);
144
+ try {
145
+ execSync(fullCommand, { stdio: 'inherit' });
146
+ console.log('\n✅ MCP server configured successfully!\n');
147
+ console.log(`Scope: ${scope === 'user' ? 'Global (all projects)' : 'Project (this directory only)'}\n`);
148
+ console.log('Auto-updates: enabled (via npx)\n');
149
+ console.log('Next steps:');
150
+ console.log(' 1. Restart Claude Code');
151
+ console.log(' 2. Just say "ccp" — that\'s it.\n');
152
+ console.log('Examples:');
153
+ console.log(' "ccp screenshot my Gmail"');
154
+ console.log(' "use ccp to check AWS billing"');
155
+ console.log(' "ccp search on naver.com"\n');
156
+ }
157
+ catch (error) {
158
+ console.error('\n❌ Failed to configure MCP server.');
159
+ console.error(' You can manually add to ~/.claude.json:');
160
+ console.error(' {');
161
+ console.error(' "mcpServers": {');
162
+ console.error(' "claude-chrome-parallel": {');
163
+ console.error(' "command": "npx",');
164
+ console.error(` "args": ["-y", "claude-chrome-parallel", ${serveArgs.map(a => `"${a}"`).join(', ')}]`);
165
+ console.error(' }');
166
+ console.error(' }');
167
+ console.error(' }');
168
+ process.exit(1);
169
+ }
170
+ });
171
+ program
172
+ .command('serve')
173
+ .description('Start MCP server for Claude Code')
174
+ .option('-p, --port <port>', 'Chrome remote debugging port', '9222')
175
+ .option('--auto-launch', 'Auto-launch Chrome if not running (default: false)')
176
+ .option('--dashboard', 'Enable terminal dashboard for real-time monitoring')
177
+ .option('--hybrid', 'Enable hybrid mode (Lightpanda + Chrome routing)')
178
+ .option('--lp-port <port>', 'Lightpanda debugging port (default: 9223)', '9223')
179
+ .action(async (options) => {
180
+ const port = parseInt(options.port, 10);
181
+ const autoLaunch = options.autoLaunch || false;
182
+ const dashboard = options.dashboard || false;
183
+ // Non-blocking update check (fires in background)
184
+ (0, update_check_1.checkForUpdates)(version).catch(() => { });
185
+ console.error(`[claude-chrome-parallel] Starting MCP server`);
186
+ console.error(`[claude-chrome-parallel] Chrome debugging port: ${port}`);
187
+ console.error(`[claude-chrome-parallel] Auto-launch Chrome: ${autoLaunch}`);
188
+ console.error(`[claude-chrome-parallel] Dashboard: ${dashboard}`);
189
+ // Import from built dist/ files (relative to dist/cli/)
190
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
191
+ const { setGlobalConfig } = require('../config/global');
192
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
193
+ const { getMCPServer, setMCPServerOptions } = require('../mcp-server');
194
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
195
+ const { registerAllTools } = require('../tools');
196
+ // Set global config before initializing anything
197
+ setGlobalConfig({ port, autoLaunch });
198
+ // Configure hybrid mode if enabled
199
+ const hybrid = options.hybrid || false;
200
+ const lpPort = parseInt(options.lpPort || '9223', 10);
201
+ if (hybrid) {
202
+ setGlobalConfig({
203
+ hybrid: {
204
+ enabled: true,
205
+ lightpandaPort: lpPort,
206
+ },
207
+ });
208
+ console.error(`[claude-chrome-parallel] Hybrid mode: enabled`);
209
+ console.error(`[claude-chrome-parallel] Lightpanda port: ${lpPort}`);
210
+ }
211
+ // Set MCP server options (including dashboard)
212
+ setMCPServerOptions({ dashboard });
213
+ const server = getMCPServer();
214
+ registerAllTools(server);
215
+ // Initialize hybrid routing if enabled
216
+ if (hybrid) {
217
+ const { getSessionManager } = require('../session-manager');
218
+ const sm = getSessionManager();
219
+ await sm.initHybrid({
220
+ enabled: true,
221
+ lightpandaPort: lpPort,
222
+ circuitBreaker: { maxFailures: 3, cooldownMs: 60000 },
223
+ cookieSync: { intervalMs: 5000 },
224
+ });
225
+ }
226
+ server.start();
227
+ });
228
+ program
229
+ .command('sessions')
230
+ .description('List or clear sessions')
231
+ .option('--clear', 'Clear all inactive sessions')
232
+ .action(async (options) => {
233
+ console.log('Session management requires the extension to be running.');
234
+ if (options.clear) {
235
+ console.log('To clear sessions, use the extension popup.');
236
+ }
237
+ else {
238
+ console.log('To view sessions, check the extension popup in Chrome.');
239
+ }
240
+ });
241
+ program
242
+ .command('doctor')
243
+ .description('Check installation status')
244
+ .action(async () => {
245
+ console.log('Checking installation status...\n');
246
+ // Core checks (required for CDP mode)
247
+ const coreChecks = {
248
+ 'Node.js version (>=18)': checkNodeVersion(),
249
+ '.claude.json health': await checkClaudeConfigHealth(),
250
+ 'Chrome debugging port': await checkChromeDebugPort(),
251
+ };
252
+ console.log('Core Requirements:');
253
+ for (const [name, passed] of Object.entries(coreChecks)) {
254
+ const status = passed ? '✅' : '❌';
255
+ console.log(` ${status} ${name}`);
256
+ }
257
+ const allPassed = Object.values(coreChecks).every(Boolean);
258
+ console.log();
259
+ if (allPassed) {
260
+ console.log('All checks passed! Ready to use with Claude Code.');
261
+ console.log('\nUsage:');
262
+ console.log(' 1. Start Chrome with: chrome --remote-debugging-port=9222');
263
+ console.log(' 2. Add to ~/.claude.json:');
264
+ console.log(' "mcpServers": { "chrome-parallel": { "command": "ccp", "args": ["serve"] } }');
265
+ console.log(' 3. Restart Claude Code');
266
+ }
267
+ else {
268
+ if (!coreChecks['Chrome debugging port']) {
269
+ console.log('Chrome is not running with debugging port.');
270
+ console.log('Start Chrome with: chrome --remote-debugging-port=9222');
271
+ }
272
+ if (!coreChecks['.claude.json health']) {
273
+ console.log('Run "claude-chrome-parallel recover" to fix .claude.json');
274
+ }
275
+ }
276
+ });
277
+ program
278
+ .command('launch')
279
+ .description('Start Claude Code with isolated config (prevents corruption)')
280
+ .option('--sync-back', 'Sync config changes back to original after session')
281
+ .option('--keep-session', 'Keep session directory after exit (for debugging)')
282
+ .argument('[args...]', 'Arguments to pass to claude')
283
+ .action(async (args, options) => {
284
+ const sessionId = generateSessionId();
285
+ const sessionDir = path.join(getSessionsDir(), sessionId);
286
+ console.log(`Creating isolated session: ${sessionId}`);
287
+ // Create session directory
288
+ fs.mkdirSync(sessionDir, { recursive: true });
289
+ // Copy existing .claude.json if it exists
290
+ const originalConfig = path.join(os.homedir(), '.claude.json');
291
+ const sessionConfig = path.join(sessionDir, '.claude.json');
292
+ if (fs.existsSync(originalConfig)) {
293
+ // Validate before copying
294
+ const content = fs.readFileSync(originalConfig, 'utf8');
295
+ if (isValidJson(content)) {
296
+ fs.copyFileSync(originalConfig, sessionConfig);
297
+ console.log('Copied existing config to session');
298
+ }
299
+ else {
300
+ console.warn('Warning: Original .claude.json is corrupted, starting fresh');
301
+ fs.writeFileSync(sessionConfig, '{}');
302
+ }
303
+ }
304
+ else {
305
+ fs.writeFileSync(sessionConfig, '{}');
306
+ }
307
+ // Create session metadata
308
+ const metadata = {
309
+ id: sessionId,
310
+ createdAt: new Date().toISOString(),
311
+ originalHome: os.homedir(),
312
+ };
313
+ fs.writeFileSync(path.join(sessionDir, '.session-metadata.json'), JSON.stringify(metadata, null, 2));
314
+ console.log('Starting Claude Code with isolated config...\n');
315
+ // Set up environment with isolated HOME
316
+ const env = {
317
+ ...process.env,
318
+ HOME: sessionDir,
319
+ USERPROFILE: sessionDir,
320
+ CLAUDE_CONFIG_DIR: sessionDir,
321
+ };
322
+ // Find claude command
323
+ const claudeCmd = process.platform === 'win32' ? 'claude.cmd' : 'claude';
324
+ // Spawn claude with isolated environment
325
+ const child = (0, child_process_1.spawn)(claudeCmd, args, {
326
+ env,
327
+ stdio: 'inherit',
328
+ shell: true,
329
+ });
330
+ // Handle exit
331
+ child.on('close', async (code) => {
332
+ console.log(`\nClaude Code exited with code ${code}`);
333
+ // Sync back if requested
334
+ if (options.syncBack && fs.existsSync(sessionConfig)) {
335
+ console.log('Syncing config back to original location...');
336
+ const sessionContent = fs.readFileSync(sessionConfig, 'utf8');
337
+ if (isValidJson(sessionContent)) {
338
+ // Backup original first
339
+ if (fs.existsSync(originalConfig)) {
340
+ await createBackupFile(originalConfig);
341
+ }
342
+ fs.writeFileSync(originalConfig, sessionContent);
343
+ console.log('Config synced successfully');
344
+ }
345
+ else {
346
+ console.error('Session config is corrupted, not syncing back');
347
+ }
348
+ }
349
+ // Cleanup session
350
+ if (!options.keepSession) {
351
+ console.log('Cleaning up session directory...');
352
+ fs.rmSync(sessionDir, { recursive: true, force: true });
353
+ console.log('Session cleaned up');
354
+ }
355
+ else {
356
+ console.log(`Session kept at: ${sessionDir}`);
357
+ }
358
+ process.exit(code ?? 0);
359
+ });
360
+ // Forward signals
361
+ process.on('SIGINT', () => child.kill('SIGINT'));
362
+ process.on('SIGTERM', () => child.kill('SIGTERM'));
363
+ });
364
+ program
365
+ .command('recover')
366
+ .description('Recover corrupted .claude.json')
367
+ .option('--backup <name>', 'Restore from specific backup')
368
+ .option('--list-backups', 'List available backups')
369
+ .option('--force-new', 'Create new empty config (loses all data)')
370
+ .action(async (options) => {
371
+ const configPath = path.join(os.homedir(), '.claude.json');
372
+ const backupDir = path.join(os.homedir(), '.claude-chrome-parallel', 'backups');
373
+ // List backups
374
+ if (options.listBackups) {
375
+ console.log('Available backups:\n');
376
+ if (!fs.existsSync(backupDir)) {
377
+ console.log('No backups found');
378
+ return;
379
+ }
380
+ const backups = fs.readdirSync(backupDir)
381
+ .filter(f => f.startsWith('.claude.json.'))
382
+ .sort()
383
+ .reverse();
384
+ if (backups.length === 0) {
385
+ console.log('No backups found');
386
+ return;
387
+ }
388
+ for (const backup of backups) {
389
+ const stats = fs.statSync(path.join(backupDir, backup));
390
+ console.log(` ${backup} (${formatBytes(stats.size)})`);
391
+ }
392
+ return;
393
+ }
394
+ // Force new config
395
+ if (options.forceNew) {
396
+ if (fs.existsSync(configPath)) {
397
+ await createBackupFile(configPath);
398
+ }
399
+ fs.writeFileSync(configPath, '{}');
400
+ console.log('Created new empty .claude.json');
401
+ console.log('Warning: All previous settings have been lost (backup created)');
402
+ return;
403
+ }
404
+ // Restore from specific backup
405
+ if (options.backup) {
406
+ const backupPath = path.join(backupDir, options.backup);
407
+ if (!fs.existsSync(backupPath)) {
408
+ console.error(`Backup not found: ${options.backup}`);
409
+ process.exit(1);
410
+ }
411
+ const content = fs.readFileSync(backupPath, 'utf8');
412
+ if (!isValidJson(content)) {
413
+ console.error('Selected backup is also corrupted');
414
+ process.exit(1);
415
+ }
416
+ if (fs.existsSync(configPath)) {
417
+ await createBackupFile(configPath);
418
+ }
419
+ fs.writeFileSync(configPath, content);
420
+ console.log(`Restored from backup: ${options.backup}`);
421
+ return;
422
+ }
423
+ // Auto-recover
424
+ console.log('Checking .claude.json...\n');
425
+ if (!fs.existsSync(configPath)) {
426
+ console.log('No .claude.json found - nothing to recover');
427
+ return;
428
+ }
429
+ const content = fs.readFileSync(configPath, 'utf8');
430
+ if (isValidJson(content)) {
431
+ console.log('✅ .claude.json is valid - no recovery needed');
432
+ return;
433
+ }
434
+ console.log('❌ .claude.json is corrupted');
435
+ console.log('Attempting recovery...\n');
436
+ // Create backup
437
+ const backup = await createBackupFile(configPath);
438
+ console.log(`Backup created: ${backup}`);
439
+ // Try to extract valid JSON
440
+ const recovered = attemptJsonRecovery(content);
441
+ if (recovered) {
442
+ fs.writeFileSync(configPath, JSON.stringify(recovered, null, 2));
443
+ console.log('✅ Successfully recovered .claude.json');
444
+ return;
445
+ }
446
+ // Try to restore from backup
447
+ if (fs.existsSync(backupDir)) {
448
+ const backups = fs.readdirSync(backupDir)
449
+ .filter(f => f.startsWith('.claude.json.'))
450
+ .sort()
451
+ .reverse();
452
+ for (const backupFile of backups) {
453
+ const backupContent = fs.readFileSync(path.join(backupDir, backupFile), 'utf8');
454
+ if (isValidJson(backupContent)) {
455
+ fs.writeFileSync(configPath, backupContent);
456
+ console.log(`✅ Restored from backup: ${backupFile}`);
457
+ return;
458
+ }
459
+ }
460
+ }
461
+ // Last resort: create empty config
462
+ fs.writeFileSync(configPath, '{}');
463
+ console.log('⚠️ Could not recover - created new empty config');
464
+ console.log('Your corrupted file has been backed up');
465
+ });
466
+ program
467
+ .command('status')
468
+ .description('Show session manager status and statistics')
469
+ .option('--json', 'Output as JSON')
470
+ .action(async (options) => {
471
+ const sessionsDir = getSessionsDir();
472
+ const backupDir = path.join(os.homedir(), '.claude-chrome-parallel', 'backups');
473
+ const configPath = path.join(os.homedir(), '.claude.json');
474
+ // Gather statistics
475
+ let activeSessions = 0;
476
+ let totalSessionsSize = 0;
477
+ const sessionDetails = [];
478
+ if (fs.existsSync(sessionsDir)) {
479
+ const entries = fs.readdirSync(sessionsDir, { withFileTypes: true });
480
+ const now = Date.now();
481
+ for (const entry of entries) {
482
+ if (!entry.isDirectory())
483
+ continue;
484
+ const sessionDir = path.join(sessionsDir, entry.name);
485
+ const metadataPath = path.join(sessionDir, '.session-metadata.json');
486
+ activeSessions++;
487
+ const size = getDirSize(sessionDir);
488
+ totalSessionsSize += size;
489
+ let age = 'unknown';
490
+ if (fs.existsSync(metadataPath)) {
491
+ try {
492
+ const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
493
+ const createdAt = new Date(metadata.createdAt).getTime();
494
+ age = formatDuration(now - createdAt);
495
+ }
496
+ catch {
497
+ // ignore
498
+ }
499
+ }
500
+ sessionDetails.push({
501
+ id: entry.name,
502
+ age,
503
+ size: formatBytes(size),
504
+ });
505
+ }
506
+ }
507
+ // Count backups
508
+ let backupCount = 0;
509
+ let backupSize = 0;
510
+ if (fs.existsSync(backupDir)) {
511
+ const backups = fs.readdirSync(backupDir).filter(f => f.startsWith('.claude.json.'));
512
+ backupCount = backups.length;
513
+ for (const backup of backups) {
514
+ const stats = fs.statSync(path.join(backupDir, backup));
515
+ backupSize += stats.size;
516
+ }
517
+ }
518
+ // Check config health
519
+ let configHealthy = true;
520
+ let configError = '';
521
+ if (fs.existsSync(configPath)) {
522
+ const content = fs.readFileSync(configPath, 'utf8');
523
+ if (!isValidJson(content)) {
524
+ configHealthy = false;
525
+ configError = 'Invalid JSON (corrupted)';
526
+ }
527
+ }
528
+ // Memory usage
529
+ const memUsage = process.memoryUsage();
530
+ const status = {
531
+ sessions: {
532
+ active: activeSessions,
533
+ totalSize: formatBytes(totalSessionsSize),
534
+ details: sessionDetails,
535
+ },
536
+ backups: {
537
+ count: backupCount,
538
+ totalSize: formatBytes(backupSize),
539
+ },
540
+ config: {
541
+ healthy: configHealthy,
542
+ error: configError || undefined,
543
+ },
544
+ memory: {
545
+ heapUsed: formatBytes(memUsage.heapUsed),
546
+ heapTotal: formatBytes(memUsage.heapTotal),
547
+ rss: formatBytes(memUsage.rss),
548
+ },
549
+ };
550
+ if (options.json) {
551
+ console.log(JSON.stringify(status, null, 2));
552
+ return;
553
+ }
554
+ // Pretty print
555
+ console.log('Claude Chrome Parallel Status');
556
+ console.log('═'.repeat(40));
557
+ console.log();
558
+ // Sessions
559
+ console.log('Sessions');
560
+ console.log('─'.repeat(20));
561
+ console.log(` Active: ${activeSessions}`);
562
+ console.log(` Total Size: ${formatBytes(totalSessionsSize)}`);
563
+ if (sessionDetails.length > 0) {
564
+ console.log(' Details:');
565
+ for (const s of sessionDetails) {
566
+ console.log(` - ${s.id} (${s.age}, ${s.size})`);
567
+ }
568
+ }
569
+ console.log();
570
+ // Backups
571
+ console.log('Backups');
572
+ console.log('─'.repeat(20));
573
+ console.log(` Count: ${backupCount}`);
574
+ console.log(` Total Size: ${formatBytes(backupSize)}`);
575
+ console.log();
576
+ // Config
577
+ console.log('Config Health');
578
+ console.log('─'.repeat(20));
579
+ if (configHealthy) {
580
+ console.log(' ✅ .claude.json is healthy');
581
+ }
582
+ else {
583
+ console.log(` ❌ .claude.json: ${configError}`);
584
+ console.log(' Run: claude-chrome-parallel recover');
585
+ }
586
+ console.log();
587
+ // Memory
588
+ console.log('Memory');
589
+ console.log('─'.repeat(20));
590
+ console.log(` Heap Used: ${formatBytes(memUsage.heapUsed)}`);
591
+ console.log(` Heap Total: ${formatBytes(memUsage.heapTotal)}`);
592
+ console.log(` RSS: ${formatBytes(memUsage.rss)}`);
593
+ });
594
+ program
595
+ .command('cleanup')
596
+ .description('Clean up stale sessions and old backups')
597
+ .option('--max-age <hours>', 'Max session age in hours (default: 24)', '24')
598
+ .option('--keep-backups <count>', 'Number of backups to keep (default: 10)', '10')
599
+ .action((options) => {
600
+ const maxAgeMs = parseInt(options.maxAge, 10) * 60 * 60 * 1000;
601
+ const keepBackups = parseInt(options.keepBackups, 10);
602
+ console.log('Cleaning up stale sessions...\n');
603
+ // Clean up sessions
604
+ const sessionsDir = getSessionsDir();
605
+ let sessionsRemoved = 0;
606
+ if (fs.existsSync(sessionsDir)) {
607
+ const entries = fs.readdirSync(sessionsDir, { withFileTypes: true });
608
+ const now = Date.now();
609
+ for (const entry of entries) {
610
+ if (!entry.isDirectory())
611
+ continue;
612
+ const sessionDir = path.join(sessionsDir, entry.name);
613
+ const metadataPath = path.join(sessionDir, '.session-metadata.json');
614
+ let shouldDelete = false;
615
+ if (fs.existsSync(metadataPath)) {
616
+ try {
617
+ const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
618
+ const createdAt = new Date(metadata.createdAt).getTime();
619
+ shouldDelete = (now - createdAt) > maxAgeMs;
620
+ }
621
+ catch {
622
+ shouldDelete = true; // Invalid metadata
623
+ }
624
+ }
625
+ else {
626
+ shouldDelete = true; // No metadata
627
+ }
628
+ if (shouldDelete) {
629
+ fs.rmSync(sessionDir, { recursive: true, force: true });
630
+ sessionsRemoved++;
631
+ }
632
+ }
633
+ }
634
+ console.log(`Removed ${sessionsRemoved} stale session(s)`);
635
+ // Clean up backups
636
+ const backupDir = path.join(os.homedir(), '.claude-chrome-parallel', 'backups');
637
+ let backupsRemoved = 0;
638
+ if (fs.existsSync(backupDir)) {
639
+ const backups = fs.readdirSync(backupDir)
640
+ .filter(f => f.startsWith('.claude.json.'))
641
+ .sort()
642
+ .reverse();
643
+ const toRemove = backups.slice(keepBackups);
644
+ for (const backup of toRemove) {
645
+ fs.unlinkSync(path.join(backupDir, backup));
646
+ backupsRemoved++;
647
+ }
648
+ }
649
+ console.log(`Removed ${backupsRemoved} old backup(s)`);
650
+ console.log('\nCleanup complete!');
651
+ });
652
+ /**
653
+ * Get the extension installation path
654
+ */
655
+ function getExtensionPath() {
656
+ return path.join(os.homedir(), '.claude-chrome-parallel', 'extension');
657
+ }
658
+ /**
659
+ * Check if native host manifest exists
660
+ */
661
+ function checkNativeHostManifest() {
662
+ const platform = os.platform();
663
+ let manifestPath;
664
+ switch (platform) {
665
+ case 'win32':
666
+ // Check registry or user data path
667
+ manifestPath = path.join(os.homedir(), 'AppData', 'Local', 'Google', 'Chrome', 'User Data', 'NativeMessagingHosts', 'com.anthropic.claude_chrome_parallel.json');
668
+ break;
669
+ case 'darwin':
670
+ manifestPath = path.join(os.homedir(), 'Library', 'Application Support', 'Google', 'Chrome', 'NativeMessagingHosts', 'com.anthropic.claude_chrome_parallel.json');
671
+ break;
672
+ default:
673
+ manifestPath = path.join(os.homedir(), '.config', 'google-chrome', 'NativeMessagingHosts', 'com.anthropic.claude_chrome_parallel.json');
674
+ }
675
+ return fs.existsSync(manifestPath);
676
+ }
677
+ /**
678
+ * Check Node.js version
679
+ */
680
+ function checkNodeVersion() {
681
+ const version = process.version;
682
+ const major = parseInt(version.slice(1).split('.')[0], 10);
683
+ return major >= 18;
684
+ }
685
+ /**
686
+ * Check if Chrome is running with debugging port
687
+ */
688
+ async function checkChromeDebugPort(port = 9222) {
689
+ try {
690
+ const http = await Promise.resolve().then(() => __importStar(require('http')));
691
+ return new Promise((resolve) => {
692
+ const req = http.get(`http://localhost:${port}/json/version`, (res) => {
693
+ resolve(res.statusCode === 200);
694
+ });
695
+ req.on('error', () => resolve(false));
696
+ req.setTimeout(2000, () => {
697
+ req.destroy();
698
+ resolve(false);
699
+ });
700
+ });
701
+ }
702
+ catch {
703
+ return false;
704
+ }
705
+ }
706
+ /**
707
+ * Check .claude.json health
708
+ */
709
+ async function checkClaudeConfigHealth() {
710
+ const configPath = path.join(os.homedir(), '.claude.json');
711
+ if (!fs.existsSync(configPath)) {
712
+ return true; // No config is fine
713
+ }
714
+ const content = fs.readFileSync(configPath, 'utf8');
715
+ return isValidJson(content);
716
+ }
717
+ /**
718
+ * Get sessions directory
719
+ */
720
+ function getSessionsDir() {
721
+ return path.join(os.homedir(), '.claude-chrome-parallel', 'sessions');
722
+ }
723
+ /**
724
+ * Generate a unique session ID
725
+ */
726
+ function generateSessionId() {
727
+ const timestamp = Date.now().toString(36);
728
+ const random = Math.random().toString(36).substring(2, 8);
729
+ return `${timestamp}-${random}`;
730
+ }
731
+ /**
732
+ * Check if string is valid JSON
733
+ */
734
+ function isValidJson(content) {
735
+ try {
736
+ JSON.parse(content);
737
+ return true;
738
+ }
739
+ catch {
740
+ return false;
741
+ }
742
+ }
743
+ /**
744
+ * Create a backup of a file
745
+ */
746
+ async function createBackupFile(filePath) {
747
+ const backupDir = path.join(os.homedir(), '.claude-chrome-parallel', 'backups');
748
+ fs.mkdirSync(backupDir, { recursive: true });
749
+ const basename = path.basename(filePath);
750
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
751
+ const backupName = `${basename}.${timestamp}.bak`;
752
+ const backupPath = path.join(backupDir, backupName);
753
+ fs.copyFileSync(filePath, backupPath);
754
+ return backupPath;
755
+ }
756
+ /**
757
+ * Format bytes as human readable string
758
+ */
759
+ function formatBytes(bytes) {
760
+ if (bytes === 0)
761
+ return '0 B';
762
+ const k = 1024;
763
+ const sizes = ['B', 'KB', 'MB', 'GB'];
764
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
765
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
766
+ }
767
+ /**
768
+ * Format duration in milliseconds as human readable string
769
+ */
770
+ function formatDuration(ms) {
771
+ const seconds = Math.floor(ms / 1000);
772
+ const minutes = Math.floor(seconds / 60);
773
+ const hours = Math.floor(minutes / 60);
774
+ const days = Math.floor(hours / 24);
775
+ if (days > 0)
776
+ return `${days}d ${hours % 24}h`;
777
+ if (hours > 0)
778
+ return `${hours}h ${minutes % 60}m`;
779
+ if (minutes > 0)
780
+ return `${minutes}m ${seconds % 60}s`;
781
+ return `${seconds}s`;
782
+ }
783
+ /**
784
+ * Get total size of a directory recursively
785
+ */
786
+ function getDirSize(dirPath) {
787
+ let totalSize = 0;
788
+ try {
789
+ const entries = fs.readdirSync(dirPath, { withFileTypes: true });
790
+ for (const entry of entries) {
791
+ const fullPath = path.join(dirPath, entry.name);
792
+ if (entry.isDirectory()) {
793
+ totalSize += getDirSize(fullPath);
794
+ }
795
+ else if (entry.isFile()) {
796
+ totalSize += fs.statSync(fullPath).size;
797
+ }
798
+ }
799
+ }
800
+ catch {
801
+ // Permission denied or other errors
802
+ }
803
+ return totalSize;
804
+ }
805
+ /**
806
+ * Attempt to recover valid JSON from corrupted content
807
+ */
808
+ function attemptJsonRecovery(content) {
809
+ const trimmed = content.trim();
810
+ // Try to extract first valid JSON object from concatenated content
811
+ if (trimmed.includes('}{')) {
812
+ // Find matching brace for first object
813
+ let depth = 0;
814
+ let inString = false;
815
+ let escapeNext = false;
816
+ for (let i = 0; i < trimmed.length; i++) {
817
+ const char = trimmed[i];
818
+ if (escapeNext) {
819
+ escapeNext = false;
820
+ continue;
821
+ }
822
+ if (char === '\\' && inString) {
823
+ escapeNext = true;
824
+ continue;
825
+ }
826
+ if (char === '"') {
827
+ inString = !inString;
828
+ continue;
829
+ }
830
+ if (inString)
831
+ continue;
832
+ if (char === '{')
833
+ depth++;
834
+ else if (char === '}') {
835
+ depth--;
836
+ if (depth === 0) {
837
+ const firstObject = trimmed.substring(0, i + 1);
838
+ try {
839
+ return JSON.parse(firstObject);
840
+ }
841
+ catch {
842
+ // Try second object
843
+ const secondObject = trimmed.substring(i + 1);
844
+ try {
845
+ return JSON.parse(secondObject);
846
+ }
847
+ catch {
848
+ break;
849
+ }
850
+ }
851
+ }
852
+ }
853
+ }
854
+ }
855
+ return null;
856
+ }
857
+ program.parse();
858
+ //# sourceMappingURL=index.js.map