orquesta-cli 0.1.12 → 0.1.14

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 (540) hide show
  1. package/README.md +30 -4
  2. package/dist/cli.js +65 -4
  3. package/dist/constants.js +1 -1
  4. package/dist/core/config/config-manager.d.ts +13 -1
  5. package/dist/core/config/config-manager.js +83 -0
  6. package/dist/core/slash-command-handler.d.ts +1 -0
  7. package/dist/core/slash-command-handler.js +129 -0
  8. package/dist/orquesta/config-sync.d.ts +73 -0
  9. package/dist/orquesta/config-sync.js +230 -0
  10. package/dist/orquesta/prompt-reporter.d.ts +16 -0
  11. package/dist/orquesta/prompt-reporter.js +85 -0
  12. package/dist/setup/first-run-setup.d.ts +15 -0
  13. package/dist/setup/first-run-setup.js +238 -0
  14. package/dist/types/index.d.ts +11 -2
  15. package/dist/ui/TodoPanel.d.ts +1 -0
  16. package/dist/ui/TodoPanel.js +6 -1
  17. package/dist/ui/components/LLMSetupWizard.js +373 -7
  18. package/dist/ui/components/Logo.d.ts +2 -0
  19. package/dist/ui/components/Logo.js +10 -3
  20. package/dist/ui/components/OpenRouterModelBrowser.d.ts +13 -0
  21. package/dist/ui/components/OpenRouterModelBrowser.js +221 -0
  22. package/dist/ui/components/PlanExecuteApp.js +30 -4
  23. package/dist/ui/components/ProjectSelector.d.ts +8 -0
  24. package/dist/ui/components/ProjectSelector.js +119 -0
  25. package/dist/ui/components/StatusBar.d.ts +2 -0
  26. package/dist/ui/components/StatusBar.js +6 -1
  27. package/dist/ui/hooks/slashCommandProcessor.js +8 -4
  28. package/package.json +11 -5
  29. package/.eslintrc.json +0 -26
  30. package/.prettierrc.json +0 -10
  31. package/CLAUDE.md +0 -199
  32. package/SECURITY.md +0 -290
  33. package/TEST_LOCAL.md +0 -245
  34. package/dist/agents/base/base-agent.d.ts.map +0 -1
  35. package/dist/agents/base/base-agent.js.map +0 -1
  36. package/dist/agents/docs-search/index.d.ts.map +0 -1
  37. package/dist/agents/docs-search/index.js.map +0 -1
  38. package/dist/agents/index.d.ts.map +0 -1
  39. package/dist/agents/index.js.map +0 -1
  40. package/dist/agents/planner/index.d.ts.map +0 -1
  41. package/dist/agents/planner/index.js.map +0 -1
  42. package/dist/cli.d.ts.map +0 -1
  43. package/dist/cli.js.map +0 -1
  44. package/dist/constants.d.ts.map +0 -1
  45. package/dist/constants.js.map +0 -1
  46. package/dist/core/compact/compact-manager.d.ts.map +0 -1
  47. package/dist/core/compact/compact-manager.js.map +0 -1
  48. package/dist/core/compact/compact-prompts.d.ts.map +0 -1
  49. package/dist/core/compact/compact-prompts.js.map +0 -1
  50. package/dist/core/compact/context-tracker.d.ts.map +0 -1
  51. package/dist/core/compact/context-tracker.js.map +0 -1
  52. package/dist/core/compact/index.d.ts.map +0 -1
  53. package/dist/core/compact/index.js.map +0 -1
  54. package/dist/core/config/config-manager.d.ts.map +0 -1
  55. package/dist/core/config/config-manager.js.map +0 -1
  56. package/dist/core/config/index.d.ts.map +0 -1
  57. package/dist/core/config/index.js.map +0 -1
  58. package/dist/core/docs-manager.d.ts.map +0 -1
  59. package/dist/core/docs-manager.js.map +0 -1
  60. package/dist/core/git-auto-updater.d.ts.map +0 -1
  61. package/dist/core/git-auto-updater.js.map +0 -1
  62. package/dist/core/llm/index.d.ts.map +0 -1
  63. package/dist/core/llm/index.js.map +0 -1
  64. package/dist/core/llm/llm-client.d.ts.map +0 -1
  65. package/dist/core/llm/llm-client.js.map +0 -1
  66. package/dist/core/session/index.d.ts.map +0 -1
  67. package/dist/core/session/index.js.map +0 -1
  68. package/dist/core/session/session-manager.d.ts.map +0 -1
  69. package/dist/core/session/session-manager.js.map +0 -1
  70. package/dist/core/slash-command-handler.d.ts.map +0 -1
  71. package/dist/core/slash-command-handler.js.map +0 -1
  72. package/dist/core/usage-tracker.d.ts.map +0 -1
  73. package/dist/core/usage-tracker.js.map +0 -1
  74. package/dist/errors/base.d.ts.map +0 -1
  75. package/dist/errors/base.js.map +0 -1
  76. package/dist/errors/file.d.ts.map +0 -1
  77. package/dist/errors/file.js.map +0 -1
  78. package/dist/errors/index.d.ts.map +0 -1
  79. package/dist/errors/index.js.map +0 -1
  80. package/dist/errors/llm.d.ts.map +0 -1
  81. package/dist/errors/llm.js.map +0 -1
  82. package/dist/errors/network.d.ts.map +0 -1
  83. package/dist/errors/network.js.map +0 -1
  84. package/dist/errors/validation.d.ts.map +0 -1
  85. package/dist/errors/validation.js.map +0 -1
  86. package/dist/eval/eval-runner.d.ts.map +0 -1
  87. package/dist/eval/eval-runner.js.map +0 -1
  88. package/dist/eval/index.d.ts.map +0 -1
  89. package/dist/eval/index.js.map +0 -1
  90. package/dist/eval/types.d.ts.map +0 -1
  91. package/dist/eval/types.js.map +0 -1
  92. package/dist/index.d.ts.map +0 -1
  93. package/dist/index.js.map +0 -1
  94. package/dist/orchestration/index.d.ts.map +0 -1
  95. package/dist/orchestration/index.js.map +0 -1
  96. package/dist/orchestration/plan-executor.d.ts.map +0 -1
  97. package/dist/orchestration/plan-executor.js.map +0 -1
  98. package/dist/orchestration/types.d.ts.map +0 -1
  99. package/dist/orchestration/types.js.map +0 -1
  100. package/dist/orchestration/utils.d.ts.map +0 -1
  101. package/dist/orchestration/utils.js.map +0 -1
  102. package/dist/orquesta/connection.d.ts.map +0 -1
  103. package/dist/orquesta/connection.js.map +0 -1
  104. package/dist/prompts/agents/docs-search-decision.d.ts.map +0 -1
  105. package/dist/prompts/agents/docs-search-decision.js.map +0 -1
  106. package/dist/prompts/agents/docs-search.d.ts.map +0 -1
  107. package/dist/prompts/agents/docs-search.js.map +0 -1
  108. package/dist/prompts/agents/planning.d.ts.map +0 -1
  109. package/dist/prompts/agents/planning.js.map +0 -1
  110. package/dist/prompts/index.d.ts.map +0 -1
  111. package/dist/prompts/index.js.map +0 -1
  112. package/dist/prompts/shared/codebase-rules.d.ts.map +0 -1
  113. package/dist/prompts/shared/codebase-rules.js.map +0 -1
  114. package/dist/prompts/shared/git-rules.d.ts.map +0 -1
  115. package/dist/prompts/shared/git-rules.js.map +0 -1
  116. package/dist/prompts/shared/language-rules.d.ts.map +0 -1
  117. package/dist/prompts/shared/language-rules.js.map +0 -1
  118. package/dist/prompts/shared/tool-usage.d.ts.map +0 -1
  119. package/dist/prompts/shared/tool-usage.js.map +0 -1
  120. package/dist/prompts/system/compact.d.ts.map +0 -1
  121. package/dist/prompts/system/compact.js.map +0 -1
  122. package/dist/prompts/system/plan-execute.d.ts.map +0 -1
  123. package/dist/prompts/system/plan-execute.js.map +0 -1
  124. package/dist/tools/browser/browser-client.d.ts.map +0 -1
  125. package/dist/tools/browser/browser-client.js.map +0 -1
  126. package/dist/tools/browser/browser-tools.d.ts.map +0 -1
  127. package/dist/tools/browser/browser-tools.js.map +0 -1
  128. package/dist/tools/browser/index.d.ts.map +0 -1
  129. package/dist/tools/browser/index.js.map +0 -1
  130. package/dist/tools/index.d.ts.map +0 -1
  131. package/dist/tools/index.js.map +0 -1
  132. package/dist/tools/llm/agents/docs-search-tools.d.ts.map +0 -1
  133. package/dist/tools/llm/agents/docs-search-tools.js.map +0 -1
  134. package/dist/tools/llm/agents/index.d.ts.map +0 -1
  135. package/dist/tools/llm/agents/index.js.map +0 -1
  136. package/dist/tools/llm/index.d.ts.map +0 -1
  137. package/dist/tools/llm/index.js.map +0 -1
  138. package/dist/tools/llm/simple/ask-user-tool.d.ts.map +0 -1
  139. package/dist/tools/llm/simple/ask-user-tool.js.map +0 -1
  140. package/dist/tools/llm/simple/background-bash-tool.d.ts.map +0 -1
  141. package/dist/tools/llm/simple/background-bash-tool.js.map +0 -1
  142. package/dist/tools/llm/simple/background-powershell-tool.d.ts.map +0 -1
  143. package/dist/tools/llm/simple/background-powershell-tool.js.map +0 -1
  144. package/dist/tools/llm/simple/bash-tool.d.ts.map +0 -1
  145. package/dist/tools/llm/simple/bash-tool.js.map +0 -1
  146. package/dist/tools/llm/simple/docs-search-agent-tool.d.ts.map +0 -1
  147. package/dist/tools/llm/simple/docs-search-agent-tool.js.map +0 -1
  148. package/dist/tools/llm/simple/file-tools.d.ts.map +0 -1
  149. package/dist/tools/llm/simple/file-tools.js.map +0 -1
  150. package/dist/tools/llm/simple/final-response-tool.d.ts.map +0 -1
  151. package/dist/tools/llm/simple/final-response-tool.js.map +0 -1
  152. package/dist/tools/llm/simple/index.d.ts.map +0 -1
  153. package/dist/tools/llm/simple/index.js.map +0 -1
  154. package/dist/tools/llm/simple/planning-tools.d.ts.map +0 -1
  155. package/dist/tools/llm/simple/planning-tools.js.map +0 -1
  156. package/dist/tools/llm/simple/powershell-tool.d.ts.map +0 -1
  157. package/dist/tools/llm/simple/powershell-tool.js.map +0 -1
  158. package/dist/tools/llm/simple/simple-tool-executor.d.ts.map +0 -1
  159. package/dist/tools/llm/simple/simple-tool-executor.js.map +0 -1
  160. package/dist/tools/llm/simple/todo-tools.d.ts.map +0 -1
  161. package/dist/tools/llm/simple/todo-tools.js.map +0 -1
  162. package/dist/tools/llm/simple/user-interaction-tools.d.ts.map +0 -1
  163. package/dist/tools/llm/simple/user-interaction-tools.js.map +0 -1
  164. package/dist/tools/office/common/constants.d.ts.map +0 -1
  165. package/dist/tools/office/common/constants.js.map +0 -1
  166. package/dist/tools/office/common/index.d.ts.map +0 -1
  167. package/dist/tools/office/common/index.js.map +0 -1
  168. package/dist/tools/office/common/types.d.ts.map +0 -1
  169. package/dist/tools/office/common/types.js.map +0 -1
  170. package/dist/tools/office/common/utils.d.ts.map +0 -1
  171. package/dist/tools/office/common/utils.js.map +0 -1
  172. package/dist/tools/office/excel-client.d.ts.map +0 -1
  173. package/dist/tools/office/excel-client.js.map +0 -1
  174. package/dist/tools/office/excel-tools/cells.d.ts.map +0 -1
  175. package/dist/tools/office/excel-tools/cells.js.map +0 -1
  176. package/dist/tools/office/excel-tools/charts.d.ts.map +0 -1
  177. package/dist/tools/office/excel-tools/charts.js.map +0 -1
  178. package/dist/tools/office/excel-tools/comments.d.ts.map +0 -1
  179. package/dist/tools/office/excel-tools/comments.js.map +0 -1
  180. package/dist/tools/office/excel-tools/data-ops.d.ts.map +0 -1
  181. package/dist/tools/office/excel-tools/data-ops.js.map +0 -1
  182. package/dist/tools/office/excel-tools/export.d.ts.map +0 -1
  183. package/dist/tools/office/excel-tools/export.js.map +0 -1
  184. package/dist/tools/office/excel-tools/formatting.d.ts.map +0 -1
  185. package/dist/tools/office/excel-tools/formatting.js.map +0 -1
  186. package/dist/tools/office/excel-tools/index.d.ts.map +0 -1
  187. package/dist/tools/office/excel-tools/index.js.map +0 -1
  188. package/dist/tools/office/excel-tools/launch.d.ts.map +0 -1
  189. package/dist/tools/office/excel-tools/launch.js.map +0 -1
  190. package/dist/tools/office/excel-tools/media.d.ts.map +0 -1
  191. package/dist/tools/office/excel-tools/media.js.map +0 -1
  192. package/dist/tools/office/excel-tools/named-ranges.d.ts.map +0 -1
  193. package/dist/tools/office/excel-tools/named-ranges.js.map +0 -1
  194. package/dist/tools/office/excel-tools/protection.d.ts.map +0 -1
  195. package/dist/tools/office/excel-tools/protection.js.map +0 -1
  196. package/dist/tools/office/excel-tools/rows-columns.d.ts.map +0 -1
  197. package/dist/tools/office/excel-tools/rows-columns.js.map +0 -1
  198. package/dist/tools/office/excel-tools/sheets.d.ts.map +0 -1
  199. package/dist/tools/office/excel-tools/sheets.js.map +0 -1
  200. package/dist/tools/office/excel-tools/validation.d.ts.map +0 -1
  201. package/dist/tools/office/excel-tools/validation.js.map +0 -1
  202. package/dist/tools/office/excel-tools.d.ts.map +0 -1
  203. package/dist/tools/office/excel-tools.js.map +0 -1
  204. package/dist/tools/office/index.d.ts.map +0 -1
  205. package/dist/tools/office/index.js.map +0 -1
  206. package/dist/tools/office/office-client-base.d.ts.map +0 -1
  207. package/dist/tools/office/office-client-base.js.map +0 -1
  208. package/dist/tools/office/office-client.d.ts.map +0 -1
  209. package/dist/tools/office/office-client.js.map +0 -1
  210. package/dist/tools/office/powerpoint-client.d.ts.map +0 -1
  211. package/dist/tools/office/powerpoint-client.js.map +0 -1
  212. package/dist/tools/office/powerpoint-tools/effects.d.ts.map +0 -1
  213. package/dist/tools/office/powerpoint-tools/effects.js.map +0 -1
  214. package/dist/tools/office/powerpoint-tools/export.d.ts.map +0 -1
  215. package/dist/tools/office/powerpoint-tools/export.js.map +0 -1
  216. package/dist/tools/office/powerpoint-tools/index.d.ts.map +0 -1
  217. package/dist/tools/office/powerpoint-tools/index.js.map +0 -1
  218. package/dist/tools/office/powerpoint-tools/launch.d.ts.map +0 -1
  219. package/dist/tools/office/powerpoint-tools/launch.js.map +0 -1
  220. package/dist/tools/office/powerpoint-tools/media.d.ts.map +0 -1
  221. package/dist/tools/office/powerpoint-tools/media.js.map +0 -1
  222. package/dist/tools/office/powerpoint-tools/notes.d.ts.map +0 -1
  223. package/dist/tools/office/powerpoint-tools/notes.js.map +0 -1
  224. package/dist/tools/office/powerpoint-tools/sections.d.ts.map +0 -1
  225. package/dist/tools/office/powerpoint-tools/sections.js.map +0 -1
  226. package/dist/tools/office/powerpoint-tools/shapes.d.ts.map +0 -1
  227. package/dist/tools/office/powerpoint-tools/shapes.js.map +0 -1
  228. package/dist/tools/office/powerpoint-tools/slides.d.ts.map +0 -1
  229. package/dist/tools/office/powerpoint-tools/slides.js.map +0 -1
  230. package/dist/tools/office/powerpoint-tools/tables.d.ts.map +0 -1
  231. package/dist/tools/office/powerpoint-tools/tables.js.map +0 -1
  232. package/dist/tools/office/powerpoint-tools/text.d.ts.map +0 -1
  233. package/dist/tools/office/powerpoint-tools/text.js.map +0 -1
  234. package/dist/tools/office/powerpoint-tools.d.ts.map +0 -1
  235. package/dist/tools/office/powerpoint-tools.js.map +0 -1
  236. package/dist/tools/office/word-client.d.ts.map +0 -1
  237. package/dist/tools/office/word-client.js.map +0 -1
  238. package/dist/tools/office/word-tools/bookmarks.d.ts.map +0 -1
  239. package/dist/tools/office/word-tools/bookmarks.js.map +0 -1
  240. package/dist/tools/office/word-tools/comments.d.ts.map +0 -1
  241. package/dist/tools/office/word-tools/comments.js.map +0 -1
  242. package/dist/tools/office/word-tools/content.d.ts.map +0 -1
  243. package/dist/tools/office/word-tools/content.js.map +0 -1
  244. package/dist/tools/office/word-tools/export.d.ts.map +0 -1
  245. package/dist/tools/office/word-tools/export.js.map +0 -1
  246. package/dist/tools/office/word-tools/formatting.d.ts.map +0 -1
  247. package/dist/tools/office/word-tools/formatting.js.map +0 -1
  248. package/dist/tools/office/word-tools/headers-footers.d.ts.map +0 -1
  249. package/dist/tools/office/word-tools/headers-footers.js.map +0 -1
  250. package/dist/tools/office/word-tools/index.d.ts.map +0 -1
  251. package/dist/tools/office/word-tools/index.js.map +0 -1
  252. package/dist/tools/office/word-tools/launch.d.ts.map +0 -1
  253. package/dist/tools/office/word-tools/launch.js.map +0 -1
  254. package/dist/tools/office/word-tools/lists.d.ts.map +0 -1
  255. package/dist/tools/office/word-tools/lists.js.map +0 -1
  256. package/dist/tools/office/word-tools/navigation.d.ts.map +0 -1
  257. package/dist/tools/office/word-tools/navigation.js.map +0 -1
  258. package/dist/tools/office/word-tools/page-setup.d.ts.map +0 -1
  259. package/dist/tools/office/word-tools/page-setup.js.map +0 -1
  260. package/dist/tools/office/word-tools/tables.d.ts.map +0 -1
  261. package/dist/tools/office/word-tools/tables.js.map +0 -1
  262. package/dist/tools/office/word-tools/text.d.ts.map +0 -1
  263. package/dist/tools/office/word-tools/text.js.map +0 -1
  264. package/dist/tools/office/word-tools/undo-redo.d.ts.map +0 -1
  265. package/dist/tools/office/word-tools/undo-redo.js.map +0 -1
  266. package/dist/tools/office/word-tools/watermarks.d.ts.map +0 -1
  267. package/dist/tools/office/word-tools/watermarks.js.map +0 -1
  268. package/dist/tools/office/word-tools.d.ts.map +0 -1
  269. package/dist/tools/office/word-tools.js.map +0 -1
  270. package/dist/tools/registry.d.ts.map +0 -1
  271. package/dist/tools/registry.js.map +0 -1
  272. package/dist/tools/types.d.ts.map +0 -1
  273. package/dist/tools/types.js.map +0 -1
  274. package/dist/types/index.d.ts.map +0 -1
  275. package/dist/types/index.js.map +0 -1
  276. package/dist/ui/PlanExecuteView.d.ts.map +0 -1
  277. package/dist/ui/PlanExecuteView.js.map +0 -1
  278. package/dist/ui/TodoPanel.d.ts.map +0 -1
  279. package/dist/ui/TodoPanel.js.map +0 -1
  280. package/dist/ui/UpdateNotification.d.ts.map +0 -1
  281. package/dist/ui/UpdateNotification.js.map +0 -1
  282. package/dist/ui/components/ActivityIndicator.d.ts.map +0 -1
  283. package/dist/ui/components/ActivityIndicator.js.map +0 -1
  284. package/dist/ui/components/CommandBrowser.d.ts.map +0 -1
  285. package/dist/ui/components/CommandBrowser.js.map +0 -1
  286. package/dist/ui/components/CustomTextInput.d.ts.map +0 -1
  287. package/dist/ui/components/CustomTextInput.js.map +0 -1
  288. package/dist/ui/components/DocsSearchProgress.d.ts.map +0 -1
  289. package/dist/ui/components/DocsSearchProgress.js.map +0 -1
  290. package/dist/ui/components/FileBrowser.d.ts.map +0 -1
  291. package/dist/ui/components/FileBrowser.js.map +0 -1
  292. package/dist/ui/components/LLMSetupWizard.d.ts.map +0 -1
  293. package/dist/ui/components/LLMSetupWizard.js.map +0 -1
  294. package/dist/ui/components/Logo.d.ts.map +0 -1
  295. package/dist/ui/components/Logo.js.map +0 -1
  296. package/dist/ui/components/MarkdownRenderer.d.ts.map +0 -1
  297. package/dist/ui/components/MarkdownRenderer.js.map +0 -1
  298. package/dist/ui/components/ModelSelector.d.ts.map +0 -1
  299. package/dist/ui/components/ModelSelector.js.map +0 -1
  300. package/dist/ui/components/PlanExecuteApp.d.ts.map +0 -1
  301. package/dist/ui/components/PlanExecuteApp.js.map +0 -1
  302. package/dist/ui/components/ProgressBar.d.ts.map +0 -1
  303. package/dist/ui/components/ProgressBar.js.map +0 -1
  304. package/dist/ui/components/StatusBar.d.ts.map +0 -1
  305. package/dist/ui/components/StatusBar.js.map +0 -1
  306. package/dist/ui/components/ThinkingIndicator.d.ts.map +0 -1
  307. package/dist/ui/components/ThinkingIndicator.js.map +0 -1
  308. package/dist/ui/components/TodoListView.d.ts.map +0 -1
  309. package/dist/ui/components/TodoListView.js.map +0 -1
  310. package/dist/ui/components/ToolSelector.d.ts.map +0 -1
  311. package/dist/ui/components/ToolSelector.js.map +0 -1
  312. package/dist/ui/components/dialogs/ApprovalDialog.d.ts.map +0 -1
  313. package/dist/ui/components/dialogs/ApprovalDialog.js.map +0 -1
  314. package/dist/ui/components/dialogs/AskUserDialog.d.ts.map +0 -1
  315. package/dist/ui/components/dialogs/AskUserDialog.js.map +0 -1
  316. package/dist/ui/components/dialogs/DocsBrowser.d.ts.map +0 -1
  317. package/dist/ui/components/dialogs/DocsBrowser.js.map +0 -1
  318. package/dist/ui/components/dialogs/SettingsDialog.d.ts.map +0 -1
  319. package/dist/ui/components/dialogs/SettingsDialog.js.map +0 -1
  320. package/dist/ui/components/dialogs/index.d.ts.map +0 -1
  321. package/dist/ui/components/dialogs/index.js.map +0 -1
  322. package/dist/ui/components/index.d.ts.map +0 -1
  323. package/dist/ui/components/index.js.map +0 -1
  324. package/dist/ui/components/panels/LogPanel.d.ts.map +0 -1
  325. package/dist/ui/components/panels/LogPanel.js.map +0 -1
  326. package/dist/ui/components/panels/SessionPanel.d.ts.map +0 -1
  327. package/dist/ui/components/panels/SessionPanel.js.map +0 -1
  328. package/dist/ui/components/panels/index.d.ts.map +0 -1
  329. package/dist/ui/components/panels/index.js.map +0 -1
  330. package/dist/ui/components/views/ChatView.d.ts.map +0 -1
  331. package/dist/ui/components/views/ChatView.js.map +0 -1
  332. package/dist/ui/components/views/index.d.ts.map +0 -1
  333. package/dist/ui/components/views/index.js.map +0 -1
  334. package/dist/ui/contexts/TokenContext.d.ts.map +0 -1
  335. package/dist/ui/contexts/TokenContext.js.map +0 -1
  336. package/dist/ui/hooks/atFileProcessor.d.ts.map +0 -1
  337. package/dist/ui/hooks/atFileProcessor.js.map +0 -1
  338. package/dist/ui/hooks/index.d.ts.map +0 -1
  339. package/dist/ui/hooks/index.js.map +0 -1
  340. package/dist/ui/hooks/slashCommandProcessor.d.ts.map +0 -1
  341. package/dist/ui/hooks/slashCommandProcessor.js.map +0 -1
  342. package/dist/ui/hooks/useCommandBrowserState.d.ts.map +0 -1
  343. package/dist/ui/hooks/useCommandBrowserState.js.map +0 -1
  344. package/dist/ui/hooks/useFileBrowserState.d.ts.map +0 -1
  345. package/dist/ui/hooks/useFileBrowserState.js.map +0 -1
  346. package/dist/ui/hooks/useFileList.d.ts.map +0 -1
  347. package/dist/ui/hooks/useFileList.js.map +0 -1
  348. package/dist/ui/hooks/useInputHistory.d.ts.map +0 -1
  349. package/dist/ui/hooks/useInputHistory.js.map +0 -1
  350. package/dist/ui/hooks/usePlanExecution.d.ts.map +0 -1
  351. package/dist/ui/hooks/usePlanExecution.js.map +0 -1
  352. package/dist/ui/index.d.ts.map +0 -1
  353. package/dist/ui/index.js.map +0 -1
  354. package/dist/ui/ink-entry.d.ts.map +0 -1
  355. package/dist/ui/ink-entry.js.map +0 -1
  356. package/dist/utils/env-filter.d.ts.map +0 -1
  357. package/dist/utils/env-filter.js.map +0 -1
  358. package/dist/utils/file-system.d.ts.map +0 -1
  359. package/dist/utils/file-system.js.map +0 -1
  360. package/dist/utils/git-utils.d.ts.map +0 -1
  361. package/dist/utils/git-utils.js.map +0 -1
  362. package/dist/utils/json-stream-logger.d.ts.map +0 -1
  363. package/dist/utils/json-stream-logger.js.map +0 -1
  364. package/dist/utils/logger.d.ts.map +0 -1
  365. package/dist/utils/logger.js.map +0 -1
  366. package/dist/utils/platform-utils.d.ts.map +0 -1
  367. package/dist/utils/platform-utils.js.map +0 -1
  368. package/dist/utils/wsl-utils.d.ts.map +0 -1
  369. package/dist/utils/wsl-utils.js.map +0 -1
  370. package/electron.vite.config.ts +0 -63
  371. package/google374b9eba0c52b043.html +0 -1
  372. package/src/agents/base/base-agent.ts +0 -159
  373. package/src/agents/docs-search/index.ts +0 -365
  374. package/src/agents/index.ts +0 -34
  375. package/src/agents/planner/index.ts +0 -544
  376. package/src/cli.ts +0 -201
  377. package/src/constants.ts +0 -47
  378. package/src/core/compact/compact-manager.ts +0 -160
  379. package/src/core/compact/compact-prompts.ts +0 -150
  380. package/src/core/compact/context-tracker.ts +0 -164
  381. package/src/core/compact/index.ts +0 -25
  382. package/src/core/config/config-manager.ts +0 -460
  383. package/src/core/config/index.ts +0 -5
  384. package/src/core/docs-manager.ts +0 -678
  385. package/src/core/llm/index.ts +0 -7
  386. package/src/core/llm/llm-client.ts +0 -1550
  387. package/src/core/session/index.ts +0 -5
  388. package/src/core/session/session-manager.ts +0 -464
  389. package/src/core/slash-command-handler.ts +0 -410
  390. package/src/core/usage-tracker.ts +0 -438
  391. package/src/errors/base.ts +0 -81
  392. package/src/errors/file.ts +0 -183
  393. package/src/errors/index.ts +0 -95
  394. package/src/errors/llm.ts +0 -151
  395. package/src/errors/network.ts +0 -124
  396. package/src/errors/validation.ts +0 -111
  397. package/src/eval/eval-runner.ts +0 -456
  398. package/src/eval/index.ts +0 -8
  399. package/src/eval/types.ts +0 -139
  400. package/src/index.ts +0 -22
  401. package/src/orchestration/index.ts +0 -30
  402. package/src/orchestration/plan-executor.ts +0 -652
  403. package/src/orchestration/types.ts +0 -127
  404. package/src/orchestration/utils.ts +0 -119
  405. package/src/orquesta/connection.ts +0 -291
  406. package/src/prompts/agents/docs-search-decision.ts +0 -74
  407. package/src/prompts/agents/docs-search.ts +0 -84
  408. package/src/prompts/agents/planning.ts +0 -143
  409. package/src/prompts/index.ts +0 -31
  410. package/src/prompts/shared/codebase-rules.ts +0 -29
  411. package/src/prompts/shared/git-rules.ts +0 -94
  412. package/src/prompts/shared/language-rules.ts +0 -36
  413. package/src/prompts/shared/tool-usage.ts +0 -72
  414. package/src/prompts/system/compact.ts +0 -80
  415. package/src/prompts/system/plan-execute.ts +0 -89
  416. package/src/tools/browser/browser-client.ts +0 -1363
  417. package/src/tools/browser/browser-tools.ts +0 -1139
  418. package/src/tools/browser/index.ts +0 -65
  419. package/src/tools/index.ts +0 -23
  420. package/src/tools/llm/agents/docs-search-tools.ts +0 -368
  421. package/src/tools/llm/agents/index.ts +0 -22
  422. package/src/tools/llm/index.ts +0 -11
  423. package/src/tools/llm/simple/ask-user-tool.ts +0 -25
  424. package/src/tools/llm/simple/background-bash-tool.ts +0 -443
  425. package/src/tools/llm/simple/background-powershell-tool.ts +0 -421
  426. package/src/tools/llm/simple/bash-tool.ts +0 -238
  427. package/src/tools/llm/simple/docs-search-agent-tool.ts +0 -146
  428. package/src/tools/llm/simple/file-tools.ts +0 -1051
  429. package/src/tools/llm/simple/final-response-tool.ts +0 -180
  430. package/src/tools/llm/simple/index.ts +0 -42
  431. package/src/tools/llm/simple/planning-tools.ts +0 -143
  432. package/src/tools/llm/simple/powershell-tool.ts +0 -241
  433. package/src/tools/llm/simple/simple-tool-executor.ts +0 -279
  434. package/src/tools/llm/simple/todo-tools.ts +0 -207
  435. package/src/tools/llm/simple/user-interaction-tools.ts +0 -277
  436. package/src/tools/office/common/constants.ts +0 -335
  437. package/src/tools/office/common/index.ts +0 -133
  438. package/src/tools/office/common/types.ts +0 -286
  439. package/src/tools/office/common/utils.ts +0 -116
  440. package/src/tools/office/excel-client.ts +0 -1336
  441. package/src/tools/office/excel-tools/cells.ts +0 -359
  442. package/src/tools/office/excel-tools/charts.ts +0 -166
  443. package/src/tools/office/excel-tools/comments.ts +0 -155
  444. package/src/tools/office/excel-tools/data-ops.ts +0 -349
  445. package/src/tools/office/excel-tools/export.ts +0 -105
  446. package/src/tools/office/excel-tools/formatting.ts +0 -357
  447. package/src/tools/office/excel-tools/index.ts +0 -55
  448. package/src/tools/office/excel-tools/launch.ts +0 -303
  449. package/src/tools/office/excel-tools/media.ts +0 -117
  450. package/src/tools/office/excel-tools/named-ranges.ts +0 -148
  451. package/src/tools/office/excel-tools/protection.ts +0 -105
  452. package/src/tools/office/excel-tools/rows-columns.ts +0 -386
  453. package/src/tools/office/excel-tools/sheets.ts +0 -228
  454. package/src/tools/office/excel-tools/validation.ts +0 -226
  455. package/src/tools/office/excel-tools.ts +0 -9
  456. package/src/tools/office/index.ts +0 -259
  457. package/src/tools/office/office-client-base.ts +0 -242
  458. package/src/tools/office/office-client.ts +0 -377
  459. package/src/tools/office/powerpoint-client.ts +0 -1498
  460. package/src/tools/office/powerpoint-tools/effects.ts +0 -315
  461. package/src/tools/office/powerpoint-tools/export.ts +0 -138
  462. package/src/tools/office/powerpoint-tools/index.ts +0 -45
  463. package/src/tools/office/powerpoint-tools/launch.ts +0 -263
  464. package/src/tools/office/powerpoint-tools/media.ts +0 -291
  465. package/src/tools/office/powerpoint-tools/notes.ts +0 -220
  466. package/src/tools/office/powerpoint-tools/sections.ts +0 -140
  467. package/src/tools/office/powerpoint-tools/shapes.ts +0 -870
  468. package/src/tools/office/powerpoint-tools/slides.ts +0 -350
  469. package/src/tools/office/powerpoint-tools/tables.ts +0 -182
  470. package/src/tools/office/powerpoint-tools/text.ts +0 -473
  471. package/src/tools/office/powerpoint-tools.ts +0 -9
  472. package/src/tools/office/word-client.ts +0 -1697
  473. package/src/tools/office/word-tools/bookmarks.ts +0 -186
  474. package/src/tools/office/word-tools/comments.ts +0 -185
  475. package/src/tools/office/word-tools/content.ts +0 -229
  476. package/src/tools/office/word-tools/export.ts +0 -97
  477. package/src/tools/office/word-tools/formatting.ts +0 -161
  478. package/src/tools/office/word-tools/headers-footers.ts +0 -155
  479. package/src/tools/office/word-tools/index.ts +0 -57
  480. package/src/tools/office/word-tools/launch.ts +0 -312
  481. package/src/tools/office/word-tools/lists.ts +0 -97
  482. package/src/tools/office/word-tools/navigation.ts +0 -114
  483. package/src/tools/office/word-tools/page-setup.ts +0 -195
  484. package/src/tools/office/word-tools/tables.ts +0 -262
  485. package/src/tools/office/word-tools/text.ts +0 -294
  486. package/src/tools/office/word-tools/undo-redo.ts +0 -97
  487. package/src/tools/office/word-tools/watermarks.ts +0 -105
  488. package/src/tools/office/word-tools.ts +0 -9
  489. package/src/tools/registry.ts +0 -527
  490. package/src/tools/types.ts +0 -231
  491. package/src/types/index.ts +0 -181
  492. package/src/ui/PlanExecuteView.tsx +0 -119
  493. package/src/ui/TodoPanel.tsx +0 -240
  494. package/src/ui/UpdateNotification.tsx +0 -105
  495. package/src/ui/components/ActivityIndicator.tsx +0 -234
  496. package/src/ui/components/CommandBrowser.tsx +0 -114
  497. package/src/ui/components/CustomTextInput.tsx +0 -389
  498. package/src/ui/components/DocsSearchProgress.tsx +0 -85
  499. package/src/ui/components/FileBrowser.tsx +0 -93
  500. package/src/ui/components/LLMSetupWizard.tsx +0 -333
  501. package/src/ui/components/Logo.tsx +0 -125
  502. package/src/ui/components/MarkdownRenderer.tsx +0 -358
  503. package/src/ui/components/ModelSelector.tsx +0 -203
  504. package/src/ui/components/PlanExecuteApp.tsx +0 -2007
  505. package/src/ui/components/ProgressBar.tsx +0 -51
  506. package/src/ui/components/StatusBar.tsx +0 -302
  507. package/src/ui/components/ThinkingIndicator.tsx +0 -120
  508. package/src/ui/components/TodoListView.tsx +0 -140
  509. package/src/ui/components/ToolSelector.tsx +0 -215
  510. package/src/ui/components/dialogs/ApprovalDialog.tsx +0 -259
  511. package/src/ui/components/dialogs/AskUserDialog.tsx +0 -159
  512. package/src/ui/components/dialogs/DocsBrowser.tsx +0 -222
  513. package/src/ui/components/dialogs/SettingsDialog.tsx +0 -939
  514. package/src/ui/components/dialogs/index.ts +0 -13
  515. package/src/ui/components/index.ts +0 -27
  516. package/src/ui/components/panels/LogPanel.tsx +0 -385
  517. package/src/ui/components/panels/SessionPanel.tsx +0 -146
  518. package/src/ui/components/panels/index.ts +0 -13
  519. package/src/ui/components/views/ChatView.tsx +0 -447
  520. package/src/ui/components/views/index.ts +0 -5
  521. package/src/ui/contexts/TokenContext.tsx +0 -139
  522. package/src/ui/hooks/atFileProcessor.ts +0 -167
  523. package/src/ui/hooks/index.ts +0 -11
  524. package/src/ui/hooks/slashCommandProcessor.ts +0 -174
  525. package/src/ui/hooks/useCommandBrowserState.ts +0 -97
  526. package/src/ui/hooks/useFileBrowserState.ts +0 -116
  527. package/src/ui/hooks/useFileList.ts +0 -132
  528. package/src/ui/hooks/useInputHistory.ts +0 -89
  529. package/src/ui/hooks/usePlanExecution.ts +0 -339
  530. package/src/ui/index.ts +0 -10
  531. package/src/ui/ink-entry.tsx +0 -36
  532. package/src/utils/env-filter.ts +0 -164
  533. package/src/utils/file-system.ts +0 -133
  534. package/src/utils/git-utils.ts +0 -30
  535. package/src/utils/json-stream-logger.ts +0 -1259
  536. package/src/utils/logger.ts +0 -2767
  537. package/src/utils/platform-utils.ts +0 -256
  538. package/src/utils/wsl-utils.ts +0 -113
  539. package/tsconfig.electron.json +0 -39
  540. package/tsconfig.json +0 -64
@@ -1,1363 +0,0 @@
1
- /**
2
- * Browser Automation Client (Pure CDP approach)
3
- *
4
- * Launches Chrome with CDP port via PowerShell,
5
- * and controls the browser by directly connecting to CDP (Chrome DevTools Protocol) via WebSocket.
6
- *
7
- * Works without external dependencies (no playwright required).
8
- */
9
-
10
- import { spawn, ChildProcess, execSync } from 'child_process';
11
- import * as path from 'path';
12
- import * as fs from 'fs';
13
- import WebSocket from 'ws';
14
- import { logger } from '../../utils/logger.js';
15
- import { LOCAL_HOME_DIR } from '../../constants.js';
16
- import {
17
- getPlatform,
18
- getPowerShellPath,
19
- Platform,
20
- } from '../../utils/platform-utils.js';
21
-
22
- // ===========================================================================
23
- // Types
24
- // ===========================================================================
25
-
26
- interface BrowserResponse {
27
- success: boolean;
28
- message?: string;
29
- error?: string;
30
- details?: string;
31
- [key: string]: unknown;
32
- }
33
-
34
- interface HealthResponse extends BrowserResponse {
35
- status: string;
36
- version: string;
37
- browser: {
38
- active: boolean;
39
- type: string | null;
40
- chrome_available: boolean;
41
- edge_available: boolean;
42
- };
43
- }
44
-
45
- interface ScreenshotResponse extends BrowserResponse {
46
- image?: string;
47
- format?: string;
48
- encoding?: string;
49
- url?: string;
50
- title?: string;
51
- }
52
-
53
- interface NavigateResponse extends BrowserResponse {
54
- url?: string;
55
- title?: string;
56
- }
57
-
58
- interface PageInfoResponse extends BrowserResponse {
59
- url?: string;
60
- title?: string;
61
- html?: string;
62
- }
63
-
64
- interface ConsoleLogEntry {
65
- level: string;
66
- message: string;
67
- timestamp: number;
68
- }
69
-
70
- interface ConsoleResponse extends BrowserResponse {
71
- logs?: ConsoleLogEntry[];
72
- count?: number;
73
- }
74
-
75
- interface NetworkLogEntry {
76
- type: 'request' | 'response';
77
- url: string;
78
- method?: string;
79
- status?: number;
80
- statusText?: string;
81
- mimeType?: string;
82
- timestamp: number;
83
- requestId: string;
84
- }
85
-
86
- interface NetworkResponse extends BrowserResponse {
87
- logs?: NetworkLogEntry[];
88
- count?: number;
89
- }
90
-
91
- // CDP Protocol types
92
- interface CDPTarget {
93
- id: string;
94
- type: string;
95
- title: string;
96
- url: string;
97
- webSocketDebuggerUrl: string;
98
- }
99
-
100
- interface CDPMessage {
101
- id: number;
102
- method?: string;
103
- params?: Record<string, unknown>;
104
- result?: unknown;
105
- error?: {
106
- code: number;
107
- message: string;
108
- };
109
- }
110
-
111
- // ===========================================================================
112
- // CDP Client (WebSocket-based)
113
- // ===========================================================================
114
-
115
- class CDPConnection {
116
- private ws: WebSocket | null = null;
117
- private messageId: number = 0;
118
- private pendingMessages: Map<number, {
119
- resolve: (value: unknown) => void;
120
- reject: (error: Error) => void;
121
- }> = new Map();
122
- private eventHandlers: Map<string, ((params: unknown) => void)[]> = new Map();
123
-
124
- async connect(wsUrl: string): Promise<void> {
125
- return new Promise((resolve, reject) => {
126
- this.ws = new WebSocket(wsUrl);
127
-
128
- this.ws.on('open', () => {
129
- logger.debug('[CDP] WebSocket connected');
130
- resolve();
131
- });
132
-
133
- this.ws.on('message', (data: WebSocket.Data) => {
134
- try {
135
- const message: CDPMessage = JSON.parse(data.toString());
136
-
137
- if (message.id !== undefined) {
138
- // Response to a command
139
- const pending = this.pendingMessages.get(message.id);
140
- if (pending) {
141
- this.pendingMessages.delete(message.id);
142
- if (message.error) {
143
- pending.reject(new Error(message.error.message));
144
- } else {
145
- pending.resolve(message.result);
146
- }
147
- }
148
- } else if (message.method) {
149
- // Event from browser
150
- const handlers = this.eventHandlers.get(message.method) || [];
151
- for (const handler of handlers) {
152
- handler(message.params);
153
- }
154
- }
155
- } catch (e) {
156
- logger.debug('[CDP] Failed to parse message: ' + e);
157
- }
158
- });
159
-
160
- this.ws.on('error', (error) => {
161
- logger.debug('[CDP] WebSocket error: ' + error.message);
162
- reject(error);
163
- });
164
-
165
- this.ws.on('close', () => {
166
- logger.debug('[CDP] WebSocket closed');
167
- // Reject all pending messages
168
- for (const [, pending] of this.pendingMessages) {
169
- pending.reject(new Error('WebSocket closed'));
170
- }
171
- this.pendingMessages.clear();
172
- });
173
- });
174
- }
175
-
176
- async send(method: string, params?: Record<string, unknown>): Promise<unknown> {
177
- if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
178
- throw new Error('WebSocket not connected');
179
- }
180
-
181
- const id = ++this.messageId;
182
- const message: CDPMessage = { id, method, params };
183
-
184
- return new Promise((resolve, reject) => {
185
- this.pendingMessages.set(id, { resolve, reject });
186
- this.ws!.send(JSON.stringify(message));
187
-
188
- // Timeout after 30 seconds
189
- setTimeout(() => {
190
- if (this.pendingMessages.has(id)) {
191
- this.pendingMessages.delete(id);
192
- reject(new Error(`CDP command timeout: ${method}`));
193
- }
194
- }, 30000);
195
- });
196
- }
197
-
198
- on(event: string, handler: (params: unknown) => void): void {
199
- if (!this.eventHandlers.has(event)) {
200
- this.eventHandlers.set(event, []);
201
- }
202
- this.eventHandlers.get(event)!.push(handler);
203
- }
204
-
205
- off(event: string): void {
206
- this.eventHandlers.delete(event);
207
- }
208
-
209
- close(): void {
210
- if (this.ws) {
211
- this.ws.close();
212
- this.ws = null;
213
- }
214
- this.pendingMessages.clear();
215
- this.eventHandlers.clear();
216
- }
217
-
218
- isConnected(): boolean {
219
- return this.ws !== null && this.ws.readyState === WebSocket.OPEN;
220
- }
221
- }
222
-
223
- // ===========================================================================
224
- // Browser Client
225
- // ===========================================================================
226
-
227
- class BrowserClient {
228
- private cdp: CDPConnection | null = null;
229
- private browserProcess: ChildProcess | null = null;
230
- private platform: Platform;
231
- private cdpPort: number = 9222;
232
- private browserType: 'chrome' | 'edge' = 'chrome';
233
- private screenshotDir: string;
234
-
235
- // Console/Network log collection
236
- private consoleLogs: ConsoleLogEntry[] = [];
237
- private networkLogs: NetworkLogEntry[] = [];
238
-
239
- constructor() {
240
- this.platform = getPlatform();
241
- logger.debug('[BrowserClient] constructor: platform = ' + this.platform);
242
-
243
- // Create screenshot directory
244
- this.screenshotDir = path.join(LOCAL_HOME_DIR, 'screenshots', 'browser');
245
- if (!fs.existsSync(this.screenshotDir)) {
246
- fs.mkdirSync(this.screenshotDir, { recursive: true });
247
- }
248
-
249
- logger.debug('[BrowserClient] constructor: CDP URL = ' + this.getCDPUrl());
250
- }
251
-
252
- /**
253
- * Get CDP endpoint URL
254
- */
255
- private getCDPUrl(): string {
256
- return `http://localhost:${this.cdpPort}`;
257
- }
258
-
259
- /**
260
- * Get screenshot directory path
261
- */
262
- getScreenshotDir(): string {
263
- return this.screenshotDir;
264
- }
265
-
266
- /**
267
- * Find browser executable path based on platform
268
- */
269
- private findBrowserPath(windowsPaths: string[], linuxPaths?: string[]): string | null {
270
- // Native Windows - direct file system check
271
- if (this.platform === 'native-windows') {
272
- for (const p of windowsPaths) {
273
- if (fs.existsSync(p)) return p;
274
- }
275
- return null;
276
- }
277
-
278
- // WSL - use PowerShell to check Windows paths
279
- if (this.platform === 'wsl') {
280
- try {
281
- const powerShellPath = getPowerShellPath();
282
- const conditions = windowsPaths
283
- .map((p, index) => {
284
- const keyword = index === 0 ? 'if' : 'elseif';
285
- return `${keyword} (Test-Path '${p}') { Write-Output '${p}' }`;
286
- })
287
- .join(' ');
288
- const result = execSync(
289
- `${powerShellPath} -Command "${conditions}"`,
290
- { encoding: 'utf-8', timeout: 5000 }
291
- ).trim();
292
- if (result) return result;
293
- } catch (error) {
294
- logger.debug(
295
- `[BrowserClient] findBrowserPath: PowerShell check failed (${error instanceof Error ? error.message : String(error)})`
296
- );
297
- }
298
- return null;
299
- }
300
-
301
- // Native Linux - check Linux paths
302
- if (linuxPaths) {
303
- for (const p of linuxPaths) {
304
- if (fs.existsSync(p)) return p;
305
- }
306
- }
307
- return null;
308
- }
309
-
310
- private findChromePath(): string | null {
311
- return this.findBrowserPath(
312
- // Windows paths
313
- [
314
- 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
315
- 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
316
- ],
317
- // Linux paths
318
- [
319
- '/usr/bin/google-chrome',
320
- '/usr/bin/google-chrome-stable',
321
- '/usr/bin/chromium',
322
- '/usr/bin/chromium-browser',
323
- '/snap/bin/chromium',
324
- ]
325
- );
326
- }
327
-
328
- private findEdgePath(): string | null {
329
- return this.findBrowserPath(
330
- // Windows paths
331
- [
332
- 'C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe',
333
- 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
334
- ],
335
- // Linux paths (Edge for Linux)
336
- [
337
- '/usr/bin/microsoft-edge',
338
- '/usr/bin/microsoft-edge-stable',
339
- ]
340
- );
341
- }
342
-
343
- /**
344
- * Kill existing browser processes with CDP port
345
- */
346
- private killExistingBrowser(): void {
347
- logger.debug('[BrowserClient] killExistingBrowser: killing processes on port ' + this.cdpPort);
348
- try {
349
- if (this.platform === 'native-windows' || this.platform === 'wsl') {
350
- // Use PowerShell to kill processes on Windows
351
- const powerShellPath = getPowerShellPath();
352
- execSync(
353
- `${powerShellPath} -Command "Get-NetTCPConnection -LocalPort ${this.cdpPort} -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }"`,
354
- { stdio: 'ignore', timeout: 5000 }
355
- );
356
- } else {
357
- // Native Linux - use fuser or lsof
358
- try {
359
- execSync(`fuser -k ${this.cdpPort}/tcp 2>/dev/null || true`, { stdio: 'ignore', timeout: 5000 });
360
- } catch {
361
- // Try lsof as fallback
362
- try {
363
- execSync(`lsof -ti:${this.cdpPort} | xargs -r kill -9 2>/dev/null || true`, { stdio: 'ignore', timeout: 5000 });
364
- } catch {
365
- // Ignore
366
- }
367
- }
368
- }
369
- } catch {
370
- // Ignore errors
371
- }
372
- }
373
-
374
- /**
375
- * Check if CDP endpoint is available
376
- */
377
- private async isCDPAvailable(): Promise<boolean> {
378
- try {
379
- const response = await fetch(`${this.getCDPUrl()}/json/version`, {
380
- signal: AbortSignal.timeout(2000),
381
- });
382
- return response.ok;
383
- } catch {
384
- return false;
385
- }
386
- }
387
-
388
- /**
389
- * Get list of available targets (tabs)
390
- */
391
- private async getTargets(): Promise<CDPTarget[]> {
392
- const response = await fetch(`${this.getCDPUrl()}/json`);
393
- return await response.json() as CDPTarget[];
394
- }
395
-
396
- /**
397
- * Check if browser is running
398
- */
399
- async isRunning(): Promise<boolean> {
400
- return this.cdp !== null && this.cdp.isConnected();
401
- }
402
-
403
- /**
404
- * Get server health status
405
- */
406
- async getHealth(): Promise<HealthResponse | null> {
407
- const chromePath = this.findChromePath();
408
- const edgePath = this.findEdgePath();
409
-
410
- return {
411
- success: true,
412
- status: 'running',
413
- version: '2.0.0-pure-cdp',
414
- browser: {
415
- active: this.cdp !== null && this.cdp.isConnected(),
416
- type: this.browserType,
417
- chrome_available: chromePath !== null,
418
- edge_available: edgePath !== null,
419
- },
420
- };
421
- }
422
-
423
- /**
424
- * Start the browser server (for compatibility)
425
- */
426
- async startServer(): Promise<boolean> {
427
- return true;
428
- }
429
-
430
- /**
431
- * Stop the browser server (for compatibility)
432
- */
433
- async stopServer(): Promise<boolean> {
434
- return this.close().then(() => true).catch(() => true);
435
- }
436
-
437
- /**
438
- * Setup console and network logging via CDP
439
- */
440
- private setupLogging(): void {
441
- if (!this.cdp) return;
442
-
443
- // Enable Console domain
444
- this.cdp.send('Console.enable').catch(err => logger.debug('[CDP] Failed to enable Console domain: ' + err));
445
- this.cdp.on('Console.messageAdded', (params: unknown) => {
446
- const p = params as { message: { level: string; text: string } };
447
- this.consoleLogs.push({
448
- level: p.message.level.toUpperCase(),
449
- message: p.message.text,
450
- timestamp: Date.now(),
451
- });
452
- });
453
-
454
- // Enable Runtime for console.log
455
- this.cdp.send('Runtime.enable').catch(err => logger.debug('[CDP] Failed to enable Runtime domain: ' + err));
456
- this.cdp.on('Runtime.consoleAPICalled', (params: unknown) => {
457
- const p = params as { type: string; args: { value?: string; description?: string }[] };
458
- const message = p.args.map(a => a.value || a.description || '').join(' ');
459
- this.consoleLogs.push({
460
- level: p.type.toUpperCase(),
461
- message,
462
- timestamp: Date.now(),
463
- });
464
- });
465
-
466
- // Enable Network domain
467
- this.cdp.send('Network.enable').catch(err => logger.debug('[CDP] Failed to enable Network domain: ' + err));
468
- this.cdp.on('Network.requestWillBeSent', (params: unknown) => {
469
- const p = params as { requestId: string; request: { url: string; method: string } };
470
- this.networkLogs.push({
471
- type: 'request',
472
- url: p.request.url,
473
- method: p.request.method,
474
- timestamp: Date.now(),
475
- requestId: p.requestId,
476
- });
477
- });
478
-
479
- this.cdp.on('Network.responseReceived', (params: unknown) => {
480
- const p = params as { requestId: string; response: { url: string; status: number; statusText: string; mimeType: string } };
481
- this.networkLogs.push({
482
- type: 'response',
483
- url: p.response.url,
484
- status: p.response.status,
485
- statusText: p.response.statusText,
486
- mimeType: p.response.mimeType,
487
- timestamp: Date.now(),
488
- requestId: p.requestId,
489
- });
490
- });
491
- }
492
-
493
- /**
494
- * Get current page info (URL and title) - helper to reduce code duplication
495
- */
496
- private async getCurrentPageInfo(): Promise<{ url: string; title: string }> {
497
- if (!this.cdp || !this.cdp.isConnected()) {
498
- return { url: '', title: '' };
499
- }
500
-
501
- const evalResult = await this.cdp.send('Runtime.evaluate', {
502
- expression: 'JSON.stringify({ url: window.location.href, title: document.title })',
503
- returnByValue: true,
504
- }) as { result: { value: string } };
505
-
506
- return JSON.parse(evalResult.result.value);
507
- }
508
-
509
- // ===========================================================================
510
- // Browser Operations
511
- // ===========================================================================
512
-
513
- /**
514
- * Launch browser with CDP
515
- */
516
- async launch(options?: { headless?: boolean; browser?: 'chrome' | 'edge' }): Promise<BrowserResponse> {
517
- const headless = options?.headless ?? false;
518
- const preferredBrowser = options?.browser ?? 'chrome';
519
-
520
- logger.debug(`[BrowserClient] launch: starting browser (preferred=${preferredBrowser}, headless=${headless})`);
521
-
522
- try {
523
- // Clean up existing connection
524
- if (this.cdp) {
525
- this.cdp.close();
526
- this.cdp = null;
527
- }
528
-
529
- // Terminate existing CDP processes
530
- this.killExistingBrowser();
531
- await new Promise(resolve => setTimeout(resolve, 500));
532
-
533
- // Find browser path
534
- let browserPath: string | null = null;
535
- if (preferredBrowser === 'chrome') {
536
- browserPath = this.findChromePath();
537
- if (!browserPath) {
538
- browserPath = this.findEdgePath();
539
- this.browserType = 'edge';
540
- } else {
541
- this.browserType = 'chrome';
542
- }
543
- } else {
544
- browserPath = this.findEdgePath();
545
- if (!browserPath) {
546
- browserPath = this.findChromePath();
547
- this.browserType = 'chrome';
548
- } else {
549
- this.browserType = 'edge';
550
- }
551
- }
552
-
553
- if (!browserPath) {
554
- return {
555
- success: false,
556
- error: 'No browser found',
557
- details: 'Neither Chrome nor Edge is installed',
558
- };
559
- }
560
-
561
- logger.debug(`[BrowserClient] launch: using ${this.browserType} at ${browserPath}`);
562
-
563
- // Common browser arguments (without user-data-dir)
564
- const baseArgs = [
565
- `--remote-debugging-port=${this.cdpPort}`,
566
- '--no-first-run',
567
- '--no-default-browser-check',
568
- '--disable-popup-blocking',
569
- '--start-maximized',
570
- ];
571
-
572
- if (headless) {
573
- baseArgs.push('--headless=new');
574
- }
575
-
576
- // Launch browser based on platform
577
- if (this.platform === 'native-windows') {
578
- // Native Windows - spawn directly with user data dir
579
- const userDataDir = `${process.env['LOCALAPPDATA']}\\local-cli-browser-profile`;
580
- const args = [...baseArgs, `--user-data-dir=${userDataDir}`];
581
-
582
- logger.debug(`[BrowserClient] launch: spawning browser directly on Windows`);
583
- this.browserProcess = spawn(browserPath, args, {
584
- detached: true,
585
- stdio: 'ignore',
586
- });
587
- } else if (this.platform === 'wsl') {
588
- // WSL - use PowerShell to launch Windows browser
589
- // We need to use a PowerShell variable ($dir) for user-data-dir
590
- const argsForPowerShell = ['--user-data-dir=$dir', ...baseArgs];
591
- const argsString = argsForPowerShell.map(arg => `"${arg}"`).join(',');
592
- const psCommand = `$dir = "$env:LOCALAPPDATA\\local-cli-browser-profile"; Start-Process -FilePath '${browserPath}' -ArgumentList ${argsString}`;
593
-
594
- logger.debug(`[BrowserClient] launch: executing PowerShell command from WSL`);
595
-
596
- const powershellPath = getPowerShellPath();
597
- this.browserProcess = spawn(powershellPath, ['-Command', psCommand], {
598
- detached: true,
599
- stdio: 'ignore',
600
- });
601
- } else {
602
- // Native Linux - spawn directly
603
- const userDataDir = `${process.env['HOME']}/.local-cli-browser-profile`;
604
- const args = [...baseArgs, `--user-data-dir=${userDataDir}`];
605
-
606
- logger.debug(`[BrowserClient] launch: spawning browser directly on Linux`);
607
- this.browserProcess = spawn(browserPath, args, {
608
- detached: true,
609
- stdio: 'ignore',
610
- });
611
- }
612
-
613
- this.browserProcess.unref();
614
-
615
- // Wait for CDP connection
616
- logger.debug('[BrowserClient] launch: waiting for CDP endpoint...');
617
- const maxWait = 15000;
618
- const startTime = Date.now();
619
-
620
- while (Date.now() - startTime < maxWait) {
621
- if (await this.isCDPAvailable()) {
622
- break;
623
- }
624
- await new Promise(resolve => setTimeout(resolve, 500));
625
- }
626
-
627
- if (!(await this.isCDPAvailable())) {
628
- return {
629
- success: false,
630
- error: 'CDP endpoint not available',
631
- details: `Timeout waiting for browser to start on port ${this.cdpPort}`,
632
- };
633
- }
634
-
635
- // Get targets (pages)
636
- const targets = await this.getTargets();
637
- const pageTarget = targets.find(t => t.type === 'page');
638
-
639
- if (!pageTarget) {
640
- return {
641
- success: false,
642
- error: 'No page target found',
643
- details: 'Browser started but no page available',
644
- };
645
- }
646
-
647
- // Connect to CDP via WebSocket
648
- logger.debug('[BrowserClient] launch: connecting to page via WebSocket...');
649
- this.cdp = new CDPConnection();
650
- await this.cdp.connect(pageTarget.webSocketDebuggerUrl);
651
- // Target connected
652
-
653
- // Setup logging
654
- this.consoleLogs = [];
655
- this.networkLogs = [];
656
- this.setupLogging();
657
-
658
- // Enable Page domain
659
- await this.cdp.send('Page.enable');
660
-
661
- logger.debug('[BrowserClient] launch: browser connected successfully');
662
-
663
- return {
664
- success: true,
665
- message: `${this.browserType} launched successfully`,
666
- browser: this.browserType,
667
- headless,
668
- };
669
- } catch (error) {
670
- const errorMsg = error instanceof Error ? error.message : String(error);
671
- logger.debug('[BrowserClient] launch: error - ' + errorMsg);
672
- return {
673
- success: false,
674
- error: 'Failed to launch browser',
675
- details: errorMsg,
676
- };
677
- }
678
- }
679
-
680
- /**
681
- * Close browser
682
- */
683
- async close(): Promise<BrowserResponse> {
684
- try {
685
- // 1. Disconnect CDP
686
- if (this.cdp) {
687
- this.cdp.close();
688
- }
689
- this.cdp = null;
690
- // Target disconnected
691
- this.consoleLogs = [];
692
- this.networkLogs = [];
693
-
694
- // 2. Terminate browser process (platform-specific)
695
- try {
696
- if (this.platform === 'native-windows' || this.platform === 'wsl') {
697
- const processName = this.browserType === 'chrome' ? 'chrome.exe' : 'msedge.exe';
698
- execSync(
699
- `powershell.exe -Command "Get-WmiObject Win32_Process -Filter \\"name='${processName}'\\" | Where-Object { \\$_.CommandLine -like '*local-cli*' } | ForEach-Object { Stop-Process -Id \\$_.ProcessId -Force -ErrorAction SilentlyContinue }"`,
700
- { stdio: 'ignore', timeout: 10000 }
701
- );
702
- } else {
703
- // Native Linux - kill browser processes with our profile
704
- const processName = this.browserType === 'chrome' ? 'chrome' : 'msedge';
705
- execSync(
706
- `pkill -f "${processName}.*local-cli-browser-profile" 2>/dev/null || true`,
707
- { stdio: 'ignore', timeout: 10000 }
708
- );
709
- }
710
- } catch {
711
- // Process doesn't exist or already terminated
712
- }
713
-
714
- // 3. Also terminate processes using CDP port (backup)
715
- this.killExistingBrowser();
716
-
717
- return { success: true, message: 'Browser closed' };
718
- } catch (error) {
719
- return {
720
- success: false,
721
- error: 'Failed to close browser',
722
- details: error instanceof Error ? error.message : String(error),
723
- };
724
- }
725
- }
726
-
727
- /**
728
- * Navigate to URL
729
- */
730
- async navigate(url: string): Promise<NavigateResponse> {
731
- try {
732
- if (!this.cdp || !this.cdp.isConnected()) {
733
- return { success: false, error: 'Browser not running. Use launch first.' };
734
- }
735
-
736
- await this.cdp.send('Page.navigate', { url });
737
-
738
- // Wait for Page.loadEventFired event to reliably confirm page load completion
739
- await new Promise<void>((resolve, reject) => {
740
- const timeoutId = setTimeout(() => {
741
- this.cdp?.off('Page.loadEventFired');
742
- reject(new Error(`Navigation to ${url} timed out after 30 seconds`));
743
- }, 30000);
744
-
745
- const handler = () => {
746
- clearTimeout(timeoutId);
747
- this.cdp?.off('Page.loadEventFired');
748
- resolve();
749
- };
750
-
751
- this.cdp?.on('Page.loadEventFired', handler);
752
- });
753
-
754
- // Get current URL and title
755
- const pageInfo = await this.getCurrentPageInfo();
756
-
757
- return {
758
- success: true,
759
- message: 'Navigated successfully',
760
- url: pageInfo.url,
761
- title: pageInfo.title,
762
- };
763
- } catch (error) {
764
- return {
765
- success: false,
766
- error: 'Failed to navigate',
767
- details: error instanceof Error ? error.message : String(error),
768
- };
769
- }
770
- }
771
-
772
- /**
773
- * Take screenshot
774
- */
775
- async screenshot(fullPage: boolean = false): Promise<ScreenshotResponse> {
776
- try {
777
- if (!this.cdp || !this.cdp.isConnected()) {
778
- return { success: false, error: 'Browser not running. Use launch first.' };
779
- }
780
-
781
- // Screenshot options
782
- const params: Record<string, unknown> = { format: 'png' };
783
-
784
- if (fullPage) {
785
- // Get full page dimensions
786
- const layoutMetrics = await this.cdp.send('Page.getLayoutMetrics') as {
787
- contentSize: { width: number; height: number };
788
- };
789
-
790
- params['clip'] = {
791
- x: 0,
792
- y: 0,
793
- width: layoutMetrics.contentSize.width,
794
- height: layoutMetrics.contentSize.height,
795
- scale: 1,
796
- };
797
- params['captureBeyondViewport'] = true;
798
- }
799
-
800
- const result = await this.cdp.send('Page.captureScreenshot', params) as { data: string };
801
-
802
- // Get current page info
803
- const pageInfo = await this.getCurrentPageInfo();
804
-
805
- return {
806
- success: true,
807
- message: 'Screenshot captured',
808
- image: result.data,
809
- format: 'png',
810
- encoding: 'base64',
811
- url: pageInfo.url,
812
- title: pageInfo.title,
813
- };
814
- } catch (error) {
815
- return {
816
- success: false,
817
- error: 'Failed to take screenshot',
818
- details: error instanceof Error ? error.message : String(error),
819
- };
820
- }
821
- }
822
-
823
- /**
824
- * Click element by selector
825
- */
826
- async click(selector: string): Promise<BrowserResponse> {
827
- try {
828
- if (!this.cdp || !this.cdp.isConnected()) {
829
- return { success: false, error: 'Browser not running. Use launch first.' };
830
- }
831
-
832
- // Click element via JavaScript
833
- const result = await this.cdp.send('Runtime.evaluate', {
834
- expression: `
835
- (function() {
836
- const el = document.querySelector(${JSON.stringify(selector)});
837
- if (!el) return { success: false, error: 'Element not found' };
838
- el.click();
839
- return { success: true };
840
- })()
841
- `,
842
- returnByValue: true,
843
- }) as { result: { value: { success: boolean; error?: string } } };
844
-
845
- if (!result.result.value.success) {
846
- return {
847
- success: false,
848
- error: result.result.value.error || 'Click failed',
849
- };
850
- }
851
-
852
- // Get current URL
853
- const urlResult = await this.cdp.send('Runtime.evaluate', {
854
- expression: 'window.location.href',
855
- returnByValue: true,
856
- }) as { result: { value: string } };
857
-
858
- return {
859
- success: true,
860
- message: 'Element clicked',
861
- selector,
862
- current_url: urlResult.result.value,
863
- };
864
- } catch (error) {
865
- return {
866
- success: false,
867
- error: 'Failed to click element',
868
- details: error instanceof Error ? error.message : String(error),
869
- };
870
- }
871
- }
872
-
873
- /**
874
- * Fill input field
875
- */
876
- async fill(selector: string, value: string): Promise<BrowserResponse> {
877
- try {
878
- if (!this.cdp || !this.cdp.isConnected()) {
879
- return { success: false, error: 'Browser not running. Use launch first.' };
880
- }
881
-
882
- // Fill element value via JavaScript
883
- const result = await this.cdp.send('Runtime.evaluate', {
884
- expression: `
885
- (function() {
886
- const el = document.querySelector(${JSON.stringify(selector)});
887
- if (!el) return { success: false, error: 'Element not found' };
888
- el.focus();
889
- el.value = ${JSON.stringify(value)};
890
- el.dispatchEvent(new Event('input', { bubbles: true }));
891
- el.dispatchEvent(new Event('change', { bubbles: true }));
892
- return { success: true };
893
- })()
894
- `,
895
- returnByValue: true,
896
- }) as { result: { value: { success: boolean; error?: string } } };
897
-
898
- if (!result.result.value.success) {
899
- return {
900
- success: false,
901
- error: result.result.value.error || 'Fill failed',
902
- };
903
- }
904
-
905
- return {
906
- success: true,
907
- message: 'Field filled',
908
- selector,
909
- length: value.length,
910
- };
911
- } catch (error) {
912
- return {
913
- success: false,
914
- error: 'Failed to fill field',
915
- details: error instanceof Error ? error.message : String(error),
916
- };
917
- }
918
- }
919
-
920
- /**
921
- * Get element text
922
- */
923
- async getText(selector: string): Promise<BrowserResponse> {
924
- try {
925
- if (!this.cdp || !this.cdp.isConnected()) {
926
- return { success: false, error: 'Browser not running. Use launch first.' };
927
- }
928
-
929
- const result = await this.cdp.send('Runtime.evaluate', {
930
- expression: `
931
- (function() {
932
- const el = document.querySelector(${JSON.stringify(selector)});
933
- if (!el) return { success: false, error: 'Element not found' };
934
- return { success: true, text: el.textContent || '' };
935
- })()
936
- `,
937
- returnByValue: true,
938
- }) as { result: { value: { success: boolean; text?: string; error?: string } } };
939
-
940
- if (!result.result.value.success) {
941
- return {
942
- success: false,
943
- error: result.result.value.error || 'Get text failed',
944
- };
945
- }
946
-
947
- return {
948
- success: true,
949
- message: 'Text retrieved',
950
- selector,
951
- text: result.result.value.text || '',
952
- };
953
- } catch (error) {
954
- return {
955
- success: false,
956
- error: 'Failed to get text',
957
- details: error instanceof Error ? error.message : String(error),
958
- };
959
- }
960
- }
961
-
962
- /**
963
- * Get page info
964
- */
965
- async getPageInfo(): Promise<PageInfoResponse> {
966
- try {
967
- if (!this.cdp || !this.cdp.isConnected()) {
968
- return { success: false, error: 'Browser not running. Use launch first.' };
969
- }
970
-
971
- const pageInfo = await this.getCurrentPageInfo();
972
-
973
- return {
974
- success: true,
975
- message: 'Page info retrieved',
976
- url: pageInfo.url,
977
- title: pageInfo.title,
978
- };
979
- } catch (error) {
980
- return {
981
- success: false,
982
- error: 'Failed to get page info',
983
- details: error instanceof Error ? error.message : String(error),
984
- };
985
- }
986
- }
987
-
988
- /**
989
- * Get page HTML
990
- */
991
- async getHtml(): Promise<PageInfoResponse> {
992
- try {
993
- if (!this.cdp || !this.cdp.isConnected()) {
994
- return { success: false, error: 'Browser not running. Use launch first.' };
995
- }
996
-
997
- const result = await this.cdp.send('Runtime.evaluate', {
998
- expression: 'JSON.stringify({ url: window.location.href, title: document.title, html: document.documentElement.outerHTML })',
999
- returnByValue: true,
1000
- }) as { result: { value: string } };
1001
-
1002
- const pageInfo = JSON.parse(result.result.value);
1003
-
1004
- return {
1005
- success: true,
1006
- message: 'HTML retrieved',
1007
- url: pageInfo.url,
1008
- title: pageInfo.title,
1009
- html: pageInfo.html,
1010
- };
1011
- } catch (error) {
1012
- return {
1013
- success: false,
1014
- error: 'Failed to get HTML',
1015
- details: error instanceof Error ? error.message : String(error),
1016
- };
1017
- }
1018
- }
1019
-
1020
- /**
1021
- * Execute JavaScript
1022
- * Wraps script in async IIFE to support return statements and await
1023
- */
1024
- async executeScript(script: string): Promise<BrowserResponse> {
1025
- try {
1026
- if (!this.cdp || !this.cdp.isConnected()) {
1027
- return { success: false, error: 'Browser not running. Use launch first.' };
1028
- }
1029
-
1030
- // Wrap script in async IIFE to support return statements and await
1031
- const wrappedScript = `(async function() { ${script} })()`;
1032
-
1033
- const result = await this.cdp.send('Runtime.evaluate', {
1034
- expression: wrappedScript,
1035
- returnByValue: true,
1036
- awaitPromise: true,
1037
- }) as { result: { value: unknown }; exceptionDetails?: { exception?: { description?: string }; text?: string } };
1038
-
1039
- if (result.exceptionDetails) {
1040
- return {
1041
- success: false,
1042
- error: 'Script execution error',
1043
- details: result.exceptionDetails.exception?.description || result.exceptionDetails.text || 'Unknown error',
1044
- };
1045
- }
1046
-
1047
- return {
1048
- success: true,
1049
- message: 'Script executed',
1050
- result: result.result.value,
1051
- };
1052
- } catch (error) {
1053
- return {
1054
- success: false,
1055
- error: 'Failed to execute script',
1056
- details: error instanceof Error ? error.message : String(error),
1057
- };
1058
- }
1059
- }
1060
-
1061
- /**
1062
- * Get console logs
1063
- */
1064
- async getConsole(): Promise<ConsoleResponse> {
1065
- return {
1066
- success: true,
1067
- message: 'Console logs retrieved',
1068
- logs: [...this.consoleLogs],
1069
- count: this.consoleLogs.length,
1070
- };
1071
- }
1072
-
1073
- /**
1074
- * Wait for element
1075
- */
1076
- async waitFor(selector: string, timeout: number = 10): Promise<BrowserResponse> {
1077
- try {
1078
- if (!this.cdp || !this.cdp.isConnected()) {
1079
- return { success: false, error: 'Browser not running. Use launch first.' };
1080
- }
1081
-
1082
- const startTime = Date.now();
1083
- const timeoutMs = timeout * 1000;
1084
-
1085
- while (Date.now() - startTime < timeoutMs) {
1086
- const result = await this.cdp.send('Runtime.evaluate', {
1087
- expression: `document.querySelector(${JSON.stringify(selector)}) !== null`,
1088
- returnByValue: true,
1089
- }) as { result: { value: boolean } };
1090
-
1091
- if (result.result.value) {
1092
- return {
1093
- success: true,
1094
- message: 'Element found',
1095
- selector,
1096
- };
1097
- }
1098
-
1099
- await new Promise(resolve => setTimeout(resolve, 100));
1100
- }
1101
-
1102
- return {
1103
- success: false,
1104
- error: 'Timeout waiting for element',
1105
- selector,
1106
- };
1107
- } catch (error) {
1108
- return {
1109
- success: false,
1110
- error: 'Timeout waiting for element',
1111
- details: error instanceof Error ? error.message : String(error),
1112
- };
1113
- }
1114
- }
1115
-
1116
- /**
1117
- * Get network logs
1118
- */
1119
- async getNetwork(): Promise<NetworkResponse> {
1120
- return {
1121
- success: true,
1122
- message: 'Network logs retrieved',
1123
- logs: [...this.networkLogs],
1124
- count: this.networkLogs.length,
1125
- };
1126
- }
1127
-
1128
- /**
1129
- * Focus browser window
1130
- */
1131
- async focus(): Promise<BrowserResponse> {
1132
- try {
1133
- if (!this.cdp || !this.cdp.isConnected()) {
1134
- return { success: false, error: 'Browser not running. Use launch first.' };
1135
- }
1136
-
1137
- await this.cdp.send('Page.bringToFront');
1138
-
1139
- return {
1140
- success: true,
1141
- message: 'Browser window focused',
1142
- };
1143
- } catch (error) {
1144
- return {
1145
- success: false,
1146
- error: 'Failed to focus browser',
1147
- details: error instanceof Error ? error.message : String(error),
1148
- };
1149
- }
1150
- }
1151
-
1152
- /**
1153
- * Press a keyboard key
1154
- * Supports: Enter, Tab, Escape, ArrowUp, ArrowDown, ArrowLeft, ArrowRight,
1155
- * Backspace, Delete, Home, End, PageUp, PageDown, F1-F12,
1156
- * Control, Alt, Shift, Meta, and combinations like Control+A
1157
- */
1158
- async pressKey(key: string, selector?: string): Promise<BrowserResponse> {
1159
- try {
1160
- if (!this.cdp || !this.cdp.isConnected()) {
1161
- return { success: false, error: 'Browser not running. Use launch first.' };
1162
- }
1163
-
1164
- // Special key mapping (extended version)
1165
- const keyMap: Record<string, { key: string; code: string; keyCode: number }> = {
1166
- // Navigation keys
1167
- 'Enter': { key: 'Enter', code: 'Enter', keyCode: 13 },
1168
- 'Tab': { key: 'Tab', code: 'Tab', keyCode: 9 },
1169
- 'Escape': { key: 'Escape', code: 'Escape', keyCode: 27 },
1170
- 'Backspace': { key: 'Backspace', code: 'Backspace', keyCode: 8 },
1171
- 'Delete': { key: 'Delete', code: 'Delete', keyCode: 46 },
1172
- 'Space': { key: ' ', code: 'Space', keyCode: 32 },
1173
- // Arrow keys
1174
- 'ArrowUp': { key: 'ArrowUp', code: 'ArrowUp', keyCode: 38 },
1175
- 'ArrowDown': { key: 'ArrowDown', code: 'ArrowDown', keyCode: 40 },
1176
- 'ArrowLeft': { key: 'ArrowLeft', code: 'ArrowLeft', keyCode: 37 },
1177
- 'ArrowRight': { key: 'ArrowRight', code: 'ArrowRight', keyCode: 39 },
1178
- // Page navigation
1179
- 'Home': { key: 'Home', code: 'Home', keyCode: 36 },
1180
- 'End': { key: 'End', code: 'End', keyCode: 35 },
1181
- 'PageUp': { key: 'PageUp', code: 'PageUp', keyCode: 33 },
1182
- 'PageDown': { key: 'PageDown', code: 'PageDown', keyCode: 34 },
1183
- 'Insert': { key: 'Insert', code: 'Insert', keyCode: 45 },
1184
- // Modifier keys
1185
- 'Control': { key: 'Control', code: 'ControlLeft', keyCode: 17 },
1186
- 'Alt': { key: 'Alt', code: 'AltLeft', keyCode: 18 },
1187
- 'Shift': { key: 'Shift', code: 'ShiftLeft', keyCode: 16 },
1188
- 'Meta': { key: 'Meta', code: 'MetaLeft', keyCode: 91 },
1189
- // Function keys
1190
- 'F1': { key: 'F1', code: 'F1', keyCode: 112 },
1191
- 'F2': { key: 'F2', code: 'F2', keyCode: 113 },
1192
- 'F3': { key: 'F3', code: 'F3', keyCode: 114 },
1193
- 'F4': { key: 'F4', code: 'F4', keyCode: 115 },
1194
- 'F5': { key: 'F5', code: 'F5', keyCode: 116 },
1195
- 'F6': { key: 'F6', code: 'F6', keyCode: 117 },
1196
- 'F7': { key: 'F7', code: 'F7', keyCode: 118 },
1197
- 'F8': { key: 'F8', code: 'F8', keyCode: 119 },
1198
- 'F9': { key: 'F9', code: 'F9', keyCode: 120 },
1199
- 'F10': { key: 'F10', code: 'F10', keyCode: 121 },
1200
- 'F11': { key: 'F11', code: 'F11', keyCode: 122 },
1201
- 'F12': { key: 'F12', code: 'F12', keyCode: 123 },
1202
- };
1203
-
1204
- if (selector) {
1205
- // Focus on specific element
1206
- await this.cdp.send('Runtime.evaluate', {
1207
- expression: `document.querySelector(${JSON.stringify(selector)})?.focus()`,
1208
- });
1209
- }
1210
-
1211
- // Handle key combinations (e.g., Control+A, Shift+Tab)
1212
- const parts = key.split('+');
1213
- const modifiers: { ctrl?: boolean; alt?: boolean; shift?: boolean; meta?: boolean } = {};
1214
- let mainKey = key;
1215
-
1216
- if (parts.length > 1) {
1217
- for (let i = 0; i < parts.length - 1; i++) {
1218
- const mod = parts[i]?.toLowerCase();
1219
- if (mod === 'control' || mod === 'ctrl') modifiers.ctrl = true;
1220
- else if (mod === 'alt') modifiers.alt = true;
1221
- else if (mod === 'shift') modifiers.shift = true;
1222
- else if (mod === 'meta' || mod === 'cmd') modifiers.meta = true;
1223
- }
1224
- mainKey = parts[parts.length - 1] || key;
1225
- }
1226
-
1227
- // Handle single character upper/lowercase
1228
- let keyInfo = keyMap[mainKey];
1229
- if (!keyInfo) {
1230
- if (mainKey.length === 1) {
1231
- const charCode = mainKey.charCodeAt(0);
1232
- const isUpper = mainKey >= 'A' && mainKey <= 'Z';
1233
- keyInfo = {
1234
- key: mainKey,
1235
- code: `Key${mainKey.toUpperCase()}`,
1236
- keyCode: isUpper ? charCode : charCode - 32,
1237
- };
1238
- } else {
1239
- keyInfo = { key: mainKey, code: mainKey, keyCode: 0 };
1240
- }
1241
- }
1242
-
1243
- // Calculate modifier flags (for CDP)
1244
- let modifierFlags = 0;
1245
- if (modifiers.alt) modifierFlags |= 1;
1246
- if (modifiers.ctrl) modifierFlags |= 2;
1247
- if (modifiers.meta) modifierFlags |= 4;
1248
- if (modifiers.shift) modifierFlags |= 8;
1249
-
1250
- // keyDown
1251
- await this.cdp.send('Input.dispatchKeyEvent', {
1252
- type: 'keyDown',
1253
- key: keyInfo.key,
1254
- code: keyInfo.code,
1255
- windowsVirtualKeyCode: keyInfo.keyCode,
1256
- nativeVirtualKeyCode: keyInfo.keyCode,
1257
- modifiers: modifierFlags,
1258
- });
1259
-
1260
- // keyUp
1261
- await this.cdp.send('Input.dispatchKeyEvent', {
1262
- type: 'keyUp',
1263
- key: keyInfo.key,
1264
- code: keyInfo.code,
1265
- windowsVirtualKeyCode: keyInfo.keyCode,
1266
- nativeVirtualKeyCode: keyInfo.keyCode,
1267
- modifiers: modifierFlags,
1268
- });
1269
-
1270
- return {
1271
- success: true,
1272
- message: `Key "${key}" pressed successfully`,
1273
- key,
1274
- selector: selector || '(focused element)',
1275
- };
1276
- } catch (error) {
1277
- return {
1278
- success: false,
1279
- error: 'Failed to press key',
1280
- details: error instanceof Error ? error.message : String(error),
1281
- };
1282
- }
1283
- }
1284
-
1285
- /**
1286
- * Type text character by character
1287
- */
1288
- async type(text: string, selector?: string): Promise<BrowserResponse> {
1289
- try {
1290
- if (!this.cdp || !this.cdp.isConnected()) {
1291
- return { success: false, error: 'Browser not running. Use launch first.' };
1292
- }
1293
-
1294
- if (selector) {
1295
- // Focus on specific element
1296
- await this.cdp.send('Runtime.evaluate', {
1297
- expression: `document.querySelector(${JSON.stringify(selector)})?.focus()`,
1298
- });
1299
- }
1300
-
1301
- // Type character by character
1302
- for (const char of text) {
1303
- await this.cdp.send('Input.dispatchKeyEvent', {
1304
- type: 'char',
1305
- text: char,
1306
- });
1307
- await new Promise(resolve => setTimeout(resolve, 50));
1308
- }
1309
-
1310
- return {
1311
- success: true,
1312
- message: `Typed ${text.length} characters`,
1313
- length: text.length,
1314
- };
1315
- } catch (error) {
1316
- return {
1317
- success: false,
1318
- error: 'Failed to type text',
1319
- details: error instanceof Error ? error.message : String(error),
1320
- };
1321
- }
1322
- }
1323
-
1324
- /**
1325
- * Check if browser is currently active
1326
- */
1327
- async isBrowserActive(): Promise<boolean> {
1328
- return this.cdp !== null && this.cdp.isConnected();
1329
- }
1330
-
1331
- /**
1332
- * Save screenshot to file and return path
1333
- */
1334
- saveScreenshot(base64Image: string, prefix: string = 'browser'): string {
1335
- const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
1336
- const filename = `${prefix}_${timestamp}.png`;
1337
- const filepath = path.join(this.screenshotDir, filename);
1338
-
1339
- const imageBuffer = Buffer.from(base64Image, 'base64');
1340
- fs.writeFileSync(filepath, imageBuffer);
1341
-
1342
- logger.debug('[BrowserClient] saveScreenshot: saved to ' + filepath);
1343
- return filepath;
1344
- }
1345
-
1346
- /**
1347
- * For compatibility: getServerExePath
1348
- */
1349
- getServerExePath(): string | null {
1350
- return null;
1351
- }
1352
-
1353
- /**
1354
- * For compatibility: getServerUrl
1355
- */
1356
- getServerUrl(): string {
1357
- return this.getCDPUrl();
1358
- }
1359
- }
1360
-
1361
- // Export singleton instance
1362
- export const browserClient = new BrowserClient();
1363
- export type { BrowserResponse, HealthResponse, ScreenshotResponse, NavigateResponse, PageInfoResponse, ConsoleResponse, NetworkResponse };