browser-automation-cli 0.8.2__tar.gz → 0.8.4__tar.gz

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 (296) hide show
  1. browser_automation_cli-0.8.4/.github/workflows/rust-wheels.yml +123 -0
  2. browser_automation_cli-0.8.4/.gitignore +50 -0
  3. browser_automation_cli-0.8.4/AGENTS.md +52 -0
  4. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/Cargo.lock +1 -1
  5. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/Cargo.toml +1 -1
  6. browser_automation_cli-0.8.4/LICENSE.txt +21 -0
  7. browser_automation_cli-0.8.4/Makefile +24 -0
  8. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/PKG-INFO +41 -31
  9. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/README.md +39 -30
  10. browser_automation_cli-0.8.4/RELEASE.md +63 -0
  11. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/SKILL.md +10 -10
  12. browser_automation_cli-0.8.4/benchmarks/README.md +48 -0
  13. browser_automation_cli-0.8.4/benchmarks/busbench/README.md +121 -0
  14. browser_automation_cli-0.8.4/benchmarks/busbench/RESULTS.md +47 -0
  15. browser_automation_cli-0.8.4/benchmarks/busbench/judge_bu.py +198 -0
  16. browser_automation_cli-0.8.4/benchmarks/busbench/judge_runner.py +268 -0
  17. browser_automation_cli-0.8.4/benchmarks/busbench/loader.py +41 -0
  18. browser_automation_cli-0.8.4/benchmarks/busbench/record_cdp.py +126 -0
  19. browser_automation_cli-0.8.4/benchmarks/busbench/report.py +96 -0
  20. browser_automation_cli-0.8.4/benchmarks/busbench/results/0a32a0e6-6bd4-454f-b238-d7f650f71ab8/score.json +24 -0
  21. browser_automation_cli-0.8.4/benchmarks/busbench/results/0a58ebe0-9d6c-4839-9b09-d909271bb1f9/score.json +24 -0
  22. browser_automation_cli-0.8.4/benchmarks/busbench/results/0a7082f9-0bde-44c2-8b3c-0a516865a6e6/score.json +24 -0
  23. browser_automation_cli-0.8.4/benchmarks/busbench/results/0a8d83a8-32c5-4609-ac78-2e8c784315bb/score.json +24 -0
  24. browser_automation_cli-0.8.4/benchmarks/busbench/results/0be6ba06-8e22-4f62-be27-691dc882a68a/score.json +24 -0
  25. browser_automation_cli-0.8.4/benchmarks/busbench/results/0e2e0517-ccf8-483e-8693-b60cf35216bd/score.json +24 -0
  26. browser_automation_cli-0.8.4/benchmarks/busbench/results/13cfb151-3b2c-4e4c-9632-d3145a4b63ad/score.json +24 -0
  27. browser_automation_cli-0.8.4/benchmarks/busbench/results/18ac2735-e471-4784-8560-16cb6eacf3d0/score.json +24 -0
  28. browser_automation_cli-0.8.4/benchmarks/busbench/results/1bab296c-8836-453f-9008-5e5cae260cea/score.json +24 -0
  29. browser_automation_cli-0.8.4/benchmarks/busbench/results/1fd2d69b-5d3f-4d1e-8e29-4dddced1868b/score.json +30 -0
  30. browser_automation_cli-0.8.4/benchmarks/busbench/results/2085c51b-7e1a-417e-8725-b534e5a39090/score.json +24 -0
  31. browser_automation_cli-0.8.4/benchmarks/busbench/results/20c680da-1972-4ab7-8970-7ed089f21fd0/score.json +24 -0
  32. browser_automation_cli-0.8.4/benchmarks/busbench/results/22e3ff48-5c2d-4bc8-867f-261e7e9ce5b4/score.json +24 -0
  33. browser_automation_cli-0.8.4/benchmarks/busbench/results/25000017-ad2a-41e1-bb69-aa86473c314d/score.json +24 -0
  34. browser_automation_cli-0.8.4/benchmarks/busbench/results/262f00ea-98d1-42a6-ba8a-1a7ef48834bf/score.json +24 -0
  35. browser_automation_cli-0.8.4/benchmarks/busbench/results/296beb37-09d9-49f6-b644-1efa0383a483/score.json +24 -0
  36. browser_automation_cli-0.8.4/benchmarks/busbench/results/2a8e2322-f7b3-418e-a871-0819dcc55474/score.json +24 -0
  37. browser_automation_cli-0.8.4/benchmarks/busbench/results/2b28d676-5ae8-4ed3-8b67-0493db120edf/score.json +24 -0
  38. browser_automation_cli-0.8.4/benchmarks/busbench/results/2c93f863-f1e8-47c5-a731-6449d37150ee/score.json +30 -0
  39. browser_automation_cli-0.8.4/benchmarks/busbench/results/33f4cc19-2380-42bc-95fa-338e83d5ddaf/score.json +24 -0
  40. browser_automation_cli-0.8.4/benchmarks/busbench/results/34cbe431-fbeb-4d0b-b3e7-a80d3de302bc/score.json +24 -0
  41. browser_automation_cli-0.8.4/benchmarks/busbench/results/36f4e2db-4387-4163-99c3-c221d63a9733/score.json +24 -0
  42. browser_automation_cli-0.8.4/benchmarks/busbench/results/39272ced-43e3-4c3d-95c2-7ef1c7621c59/score.json +24 -0
  43. browser_automation_cli-0.8.4/benchmarks/busbench/results/3a6c4eed-1bd0-4f73-ab31-998449c5a3a4/score.json +24 -0
  44. browser_automation_cli-0.8.4/benchmarks/busbench/results/3ca72fce-117c-4de7-a95c-92cb8f1e16b4/score.json +30 -0
  45. browser_automation_cli-0.8.4/benchmarks/busbench/results/3e26342c-747e-4193-b14d-f33b12c76481/score.json +24 -0
  46. browser_automation_cli-0.8.4/benchmarks/busbench/results/3ecc7404-6d88-47fb-994e-382b66cb570d/score.json +24 -0
  47. browser_automation_cli-0.8.4/benchmarks/busbench/results/45789896-66b8-4b38-810d-6fc839df03da/score.json +24 -0
  48. browser_automation_cli-0.8.4/benchmarks/busbench/results/4d72d153-caa6-448b-b3ff-19b814e715ee/score.json +24 -0
  49. browser_automation_cli-0.8.4/benchmarks/busbench/results/4df60129-66b6-49e4-979d-f201930d732a/score.json +24 -0
  50. browser_automation_cli-0.8.4/benchmarks/busbench/results/5065986c-7142-4b67-b2a9-69f5d71127e9/score.json +24 -0
  51. browser_automation_cli-0.8.4/benchmarks/busbench/results/53cd3515-d11a-4340-b352-e73f49e70d09/score.json +24 -0
  52. browser_automation_cli-0.8.4/benchmarks/busbench/results/55371adf-23f9-4f35-88d4-f342c972bf8e/score.json +24 -0
  53. browser_automation_cli-0.8.4/benchmarks/busbench/results/5a0c2db3-a687-4dfe-b7e7-22d01eae23f6/score.json +24 -0
  54. browser_automation_cli-0.8.4/benchmarks/busbench/results/5c7f062d-e3c2-4680-9414-f870f05e6578/score.json +24 -0
  55. browser_automation_cli-0.8.4/benchmarks/busbench/results/5ea33144-d08f-43bf-95d7-4eee0ad24f9d/score.json +24 -0
  56. browser_automation_cli-0.8.4/benchmarks/busbench/results/5eca85e0-4b4d-418e-ad1a-390dc68910d1/score.json +24 -0
  57. browser_automation_cli-0.8.4/benchmarks/busbench/results/62ef9538-b0b2-474e-8844-b34fd484cb24/score.json +24 -0
  58. browser_automation_cli-0.8.4/benchmarks/busbench/results/631f887e-60d3-41b5-b2a3-97571d72d30f/score.json +24 -0
  59. browser_automation_cli-0.8.4/benchmarks/busbench/results/64e9fa0e-d9b8-49b4-aab8-82742a082592/score.json +24 -0
  60. browser_automation_cli-0.8.4/benchmarks/busbench/results/66c6641b-f949-46a2-8bcc-6d9dd388b534/score.json +24 -0
  61. browser_automation_cli-0.8.4/benchmarks/busbench/results/6aa71dee-b9a8-4897-83b9-42facca4c541/score.json +24 -0
  62. browser_automation_cli-0.8.4/benchmarks/busbench/results/6c97009d-7b10-43c0-8a4b-32db17f60c41/score.json +24 -0
  63. browser_automation_cli-0.8.4/benchmarks/busbench/results/701f7732-d2dd-4d0c-b545-49013eca6237/score.json +24 -0
  64. browser_automation_cli-0.8.4/benchmarks/busbench/results/71906b5a-577d-48c4-a253-c756790afa64/score.json +24 -0
  65. browser_automation_cli-0.8.4/benchmarks/busbench/results/755c9f4c-02e3-47fe-99ff-847a8037e227/score.json +24 -0
  66. browser_automation_cli-0.8.4/benchmarks/busbench/results/762e9505-41b1-47cd-8adc-95d19fd23c23/score.json +24 -0
  67. browser_automation_cli-0.8.4/benchmarks/busbench/results/78bdcade-3ac8-46a9-bd6f-1f4c1c219a5f/score.json +24 -0
  68. browser_automation_cli-0.8.4/benchmarks/busbench/results/79458461-3e78-499f-9ea5-2b2d639e78c9/score.json +24 -0
  69. browser_automation_cli-0.8.4/benchmarks/busbench/results/7966e6bd-f197-43d0-9ee5-88fab61c8c36/score.json +24 -0
  70. browser_automation_cli-0.8.4/benchmarks/busbench/results/7d17ab49-6539-40d0-a67d-68f12958620f/score.json +24 -0
  71. browser_automation_cli-0.8.4/benchmarks/busbench/results/7db8369d-727b-485e-9d7a-e0f0ecdd964d/score.json +24 -0
  72. browser_automation_cli-0.8.4/benchmarks/busbench/results/7fa92efb-8237-4c81-82dc-e0a5bdc0b675/score.json +24 -0
  73. browser_automation_cli-0.8.4/benchmarks/busbench/results/815307aa-4c87-4da0-867c-529b8aa55f63/score.json +24 -0
  74. browser_automation_cli-0.8.4/benchmarks/busbench/results/8c13e8a8-343d-417d-acac-fac86de1cd22/score.json +24 -0
  75. browser_automation_cli-0.8.4/benchmarks/busbench/results/8d92dbe1-bf45-4daf-ac05-02d0bd2cf9c8/score.json +24 -0
  76. browser_automation_cli-0.8.4/benchmarks/busbench/results/8e50132d-9de6-4ae1-85bd-72b9374d906d/score.json +24 -0
  77. browser_automation_cli-0.8.4/benchmarks/busbench/results/8f529c71-b308-4385-a48a-c6339c31811a/score.json +24 -0
  78. browser_automation_cli-0.8.4/benchmarks/busbench/results/90be6fd6-9f82-49df-88b9-4e119ef5b654/score.json +24 -0
  79. browser_automation_cli-0.8.4/benchmarks/busbench/results/9176d7a9-5b89-4643-837c-07d0e349f183/score.json +24 -0
  80. browser_automation_cli-0.8.4/benchmarks/busbench/results/93ce5624-b44c-41dc-9055-ca9e35c302d6/score.json +24 -0
  81. browser_automation_cli-0.8.4/benchmarks/busbench/results/97c99135-3aff-4831-af24-c9fcf8d92ef7/score.json +24 -0
  82. browser_automation_cli-0.8.4/benchmarks/busbench/results/9ba7ecfc-e5ad-43d3-9e0d-e380bb8891b6/score.json +24 -0
  83. browser_automation_cli-0.8.4/benchmarks/busbench/results/9be48103-a449-4247-9177-d6e90c76576e/score.json +24 -0
  84. browser_automation_cli-0.8.4/benchmarks/busbench/results/a07c4b00-b17d-4215-abb1-ee10a85fecf2/score.json +24 -0
  85. browser_automation_cli-0.8.4/benchmarks/busbench/results/a34dfbf1-3e36-4099-bb52-f6c688453375/score.json +24 -0
  86. browser_automation_cli-0.8.4/benchmarks/busbench/results/a43a8cbc-0e3d-465b-89e8-1fb86adf511c/score.json +24 -0
  87. browser_automation_cli-0.8.4/benchmarks/busbench/results/a4662c0f-1cb1-4208-a6bb-932735a3f007/score.json +24 -0
  88. browser_automation_cli-0.8.4/benchmarks/busbench/results/a4e0d35d-1ce0-4f65-9759-c7b0394bfb3d/score.json +24 -0
  89. browser_automation_cli-0.8.4/benchmarks/busbench/results/a527109f-4b9c-4ba6-9458-009ad0bdd3f7/score.json +24 -0
  90. browser_automation_cli-0.8.4/benchmarks/busbench/results/a54df89d-7659-499d-bbd4-2d07e9f2bd53/score.json +24 -0
  91. browser_automation_cli-0.8.4/benchmarks/busbench/results/a5580966-d7e1-4348-a0de-6e71807e6878/score.json +24 -0
  92. browser_automation_cli-0.8.4/benchmarks/busbench/results/a78f98be-efef-4d24-b826-c6d4f2cb93e6/score.json +24 -0
  93. browser_automation_cli-0.8.4/benchmarks/busbench/results/b0bf1829-1145-4008-b7de-46244d8d50c2/score.json +24 -0
  94. browser_automation_cli-0.8.4/benchmarks/busbench/results/b29bddb6-2612-48fd-ae11-345b9126f5ae/score.json +24 -0
  95. browser_automation_cli-0.8.4/benchmarks/busbench/results/b79e09f2-0cb3-4c14-bfb5-aa834d64f858/score.json +24 -0
  96. browser_automation_cli-0.8.4/benchmarks/busbench/results/bb85cb1e-679f-455d-95e5-edd421ea8205/score.json +24 -0
  97. browser_automation_cli-0.8.4/benchmarks/busbench/results/c1640562-f622-431a-bed5-da18dea68606/score.json +24 -0
  98. browser_automation_cli-0.8.4/benchmarks/busbench/results/c1f60ee6-506c-4ddb-b4eb-64106930667b/score.json +24 -0
  99. browser_automation_cli-0.8.4/benchmarks/busbench/results/c9f78efb-bdae-40fb-b4b4-78a859e506d7/score.json +24 -0
  100. browser_automation_cli-0.8.4/benchmarks/busbench/results/cd01e2b6-33dd-4949-b875-6dfb11008568/score.json +24 -0
  101. browser_automation_cli-0.8.4/benchmarks/busbench/results/cd22ee34-6f65-4bf2-acb1-34bc32a735af/score.json +24 -0
  102. browser_automation_cli-0.8.4/benchmarks/busbench/results/cecf0cdc-87eb-44ec-9c8e-17c8335afa5f/score.json +24 -0
  103. browser_automation_cli-0.8.4/benchmarks/busbench/results/d19f3978-9b9f-403f-a09c-936d41fd56fc/score.json +24 -0
  104. browser_automation_cli-0.8.4/benchmarks/busbench/results/d617325c-ca94-4557-abfc-8a1ef71b0640/score.json +24 -0
  105. browser_automation_cli-0.8.4/benchmarks/busbench/results/d61e1671-f68b-4c9a-bf8a-ef437f17901c/score.json +24 -0
  106. browser_automation_cli-0.8.4/benchmarks/busbench/results/d72b6a6b-1232-421c-b208-2a568047973e/score.json +24 -0
  107. browser_automation_cli-0.8.4/benchmarks/busbench/results/d7eea2b1-7d31-425e-977c-b803ffd28250/score.json +24 -0
  108. browser_automation_cli-0.8.4/benchmarks/busbench/results/d839901d-8444-41f8-8fcf-b565de608d56/score.json +24 -0
  109. browser_automation_cli-0.8.4/benchmarks/busbench/results/d919dc4d-dc69-431c-8af3-e52d849b9810/score.json +24 -0
  110. browser_automation_cli-0.8.4/benchmarks/busbench/results/e876e436-862e-4710-aaec-a01ca57a6c90/score.json +24 -0
  111. browser_automation_cli-0.8.4/benchmarks/busbench/results/e92e3e34-48b4-444a-8b32-1f8e3c7b3544/score.json +30 -0
  112. browser_automation_cli-0.8.4/benchmarks/busbench/results/efac7982-64c6-4f44-8c63-0ea37d24dd5e/score.json +24 -0
  113. browser_automation_cli-0.8.4/benchmarks/busbench/results/f1d9b60c-dae0-43be-adb2-de93f3e9d49b/score.json +24 -0
  114. browser_automation_cli-0.8.4/benchmarks/busbench/results/f2366e2e-ab84-4739-a493-3e81c091e00c/score.json +24 -0
  115. browser_automation_cli-0.8.4/benchmarks/busbench/results/f6e6d6f9-62db-49e6-a9b5-38df9a8d71f1/score.json +24 -0
  116. browser_automation_cli-0.8.4/benchmarks/busbench/results/f924e084-8cd6-4ef2-8fb6-68277ffe68ea/score.json +24 -0
  117. browser_automation_cli-0.8.4/benchmarks/busbench/results/fadd935f-d3dd-4c03-8366-bd7e7c146581/score.json +24 -0
  118. browser_automation_cli-0.8.4/benchmarks/busbench/results/fe521e79-3b4d-4218-8bf9-f3421e44cb5c/score.json +24 -0
  119. browser_automation_cli-0.8.4/benchmarks/busbench/results/fe7a02f0-788f-4ba8-981c-d045df4955a9/score.json +30 -0
  120. browser_automation_cli-0.8.4/benchmarks/busbench/run_suite.sh +48 -0
  121. browser_automation_cli-0.8.4/benchmarks/busbench/run_task.py +249 -0
  122. browser_automation_cli-0.8.4/benchmarks/busbench/system_prompt.md +29 -0
  123. browser_automation_cli-0.8.4/benchmarks/cpu_probe.py +39 -0
  124. browser_automation_cli-0.8.4/benchmarks/development-bench/app/hard.js +32 -0
  125. browser_automation_cli-0.8.4/benchmarks/development-bench/app/index.html +54 -0
  126. browser_automation_cli-0.8.4/benchmarks/development-bench/app/server.py +79 -0
  127. browser_automation_cli-0.8.4/benchmarks/development-bench/app/support-widget.html +3 -0
  128. browser_automation_cli-0.8.4/benchmarks/development-bench/bin/browser +13 -0
  129. browser_automation_cli-0.8.4/benchmarks/development-bench/harness.py +171 -0
  130. browser_automation_cli-0.8.4/benchmarks/development-bench/results/flags_after_click.jpg +0 -0
  131. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h10_validation.haiku-2.json +38 -0
  132. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h10_validation.haiku.json +39 -0
  133. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h10_validation.rust-2.json +32 -0
  134. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h10_validation.rust.json +31 -0
  135. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h10_validation.sonnet-2.json +37 -0
  136. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h10_validation.sonnet.json +36 -0
  137. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h1_canvas_chart.haiku-2.json +57 -0
  138. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h1_canvas_chart.haiku.json +31 -0
  139. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h1_canvas_chart.rust-2.json +31 -0
  140. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h1_canvas_chart.rust-contaminated.json +65 -0
  141. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h1_canvas_chart.rust-headed.json +50 -0
  142. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h1_canvas_chart.rust.json +29 -0
  143. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h1_canvas_chart.sonnet-2.json +28 -0
  144. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h1_canvas_chart.sonnet.json +35 -0
  145. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h2_iframe_ticket.haiku-2.json +32 -0
  146. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h2_iframe_ticket.haiku.json +31 -0
  147. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h2_iframe_ticket.rust-2.json +30 -0
  148. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h2_iframe_ticket.rust.json +28 -0
  149. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h2_iframe_ticket.sonnet-2.json +47 -0
  150. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h2_iframe_ticket.sonnet.json +457 -0
  151. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h3_shadow_flags.haiku-2.json +25 -0
  152. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h3_shadow_flags.haiku.json +30 -0
  153. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h3_shadow_flags.rust-2.json +28 -0
  154. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h3_shadow_flags.rust.json +27 -0
  155. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h3_shadow_flags.sonnet-2.json +38 -0
  156. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h3_shadow_flags.sonnet.json +37 -0
  157. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h4_audit_delayed.haiku-2.json +34 -0
  158. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h4_audit_delayed.haiku.json +41 -0
  159. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h4_audit_delayed.rust-2.json +43 -0
  160. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h4_audit_delayed.rust.json +32 -0
  161. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h4_audit_delayed.sonnet-2.json +40 -0
  162. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h4_audit_delayed.sonnet.json +39 -0
  163. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h5_banner_overlay.haiku-2.json +39 -0
  164. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h5_banner_overlay.haiku.json +36 -0
  165. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h5_banner_overlay.rust-2.json +32 -0
  166. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h5_banner_overlay.rust.json +31 -0
  167. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h5_banner_overlay.sonnet-2.json +36 -0
  168. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h5_banner_overlay.sonnet-nobanner.json +30 -0
  169. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h5_banner_overlay.sonnet.json +41 -0
  170. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h6_infinite_scroll.haiku-2.json +70 -0
  171. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h6_infinite_scroll.haiku.json +39 -0
  172. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h6_infinite_scroll.rust-2.json +88 -0
  173. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h6_infinite_scroll.rust.json +66 -0
  174. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h6_infinite_scroll.sonnet-2.json +41 -0
  175. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h6_infinite_scroll.sonnet.json +45 -0
  176. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h7_reorder.haiku-2.json +34 -0
  177. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h7_reorder.haiku.json +28 -0
  178. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h7_reorder.rust-2.json +33 -0
  179. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h7_reorder.rust.json +33 -0
  180. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h7_reorder.sonnet-2.json +33 -0
  181. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h7_reorder.sonnet.json +34 -0
  182. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h8_datepicker.haiku-2.json +41 -0
  183. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h8_datepicker.haiku.json +36 -0
  184. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h8_datepicker.rust-2.json +34 -0
  185. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h8_datepicker.rust.json +37 -0
  186. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h8_datepicker.sonnet-2.json +39 -0
  187. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h8_datepicker.sonnet.json +33 -0
  188. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h9_reauth_export.haiku-2.json +36 -0
  189. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h9_reauth_export.haiku.json +33 -0
  190. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h9_reauth_export.rust-2.json +31 -0
  191. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h9_reauth_export.rust.json +33 -0
  192. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h9_reauth_export.sonnet-2.json +33 -0
  193. browser_automation_cli-0.8.4/benchmarks/development-bench/results/h9_reauth_export.sonnet.json +36 -0
  194. browser_automation_cli-0.8.4/benchmarks/development-bench/results/schedule.png +0 -0
  195. browser_automation_cli-0.8.4/benchmarks/development-bench/results/support.png +0 -0
  196. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t1_create_project.fable.json +38 -0
  197. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t1_create_project.haiku-2.json +33 -0
  198. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t1_create_project.haiku.json +42 -0
  199. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t1_create_project.rust-2.json +37 -0
  200. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t1_create_project.rust.json +35 -0
  201. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t1_create_project.sonnet-2.json +40 -0
  202. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t1_create_project.sonnet.json +38 -0
  203. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t2_archive_project.fable.json +29 -0
  204. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t2_archive_project.haiku-2.json +31 -0
  205. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t2_archive_project.haiku.json +28 -0
  206. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t2_archive_project.rust-2.json +30 -0
  207. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t2_archive_project.rust.json +34 -0
  208. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t2_archive_project.sonnet-2.json +31 -0
  209. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t2_archive_project.sonnet.json +39 -0
  210. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t3_settings.fable.json +31 -0
  211. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t3_settings.haiku-2.json +29 -0
  212. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t3_settings.haiku.json +30 -0
  213. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t3_settings.rust-2.json +29 -0
  214. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t3_settings.rust.json +29 -0
  215. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t3_settings.sonnet-2.json +31 -0
  216. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t3_settings.sonnet.json +30 -0
  217. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t4_rename.haiku-2.json +31 -0
  218. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t4_rename.haiku.json +36 -0
  219. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t4_rename.rust-2.json +27 -0
  220. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t4_rename.rust.json +28 -0
  221. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t4_rename.sonnet-2.json +34 -0
  222. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t4_rename.sonnet.json +31 -0
  223. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t5_extract_count.haiku-2.json +34 -0
  224. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t5_extract_count.haiku.json +32 -0
  225. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t5_extract_count.rust-2.json +37 -0
  226. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t5_extract_count.rust.json +36 -0
  227. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t5_extract_count.sonnet-2.json +36 -0
  228. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t5_extract_count.sonnet.json +36 -0
  229. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t6_extract_account.haiku-2.json +28 -0
  230. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t6_extract_account.haiku.json +28 -0
  231. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t6_extract_account.rust-2.json +28 -0
  232. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t6_extract_account.rust.json +27 -0
  233. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t6_extract_account.sonnet-2.json +27 -0
  234. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t6_extract_account.sonnet.json +28 -0
  235. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t7_live_wikipedia.haiku-2.json +24 -0
  236. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t7_live_wikipedia.haiku.json +23 -0
  237. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t7_live_wikipedia.rust-2.json +22 -0
  238. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t7_live_wikipedia.rust.json +21 -0
  239. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t7_live_wikipedia.sonnet-2.json +23 -0
  240. browser_automation_cli-0.8.4/benchmarks/development-bench/results/t7_live_wikipedia.sonnet.json +22 -0
  241. browser_automation_cli-0.8.4/benchmarks/development-bench/run_suite.sh +27 -0
  242. browser_automation_cli-0.8.4/benchmarks/performance-test/bg_probe.py +28 -0
  243. browser_automation_cli-0.8.4/benchmarks/performance-test/compare.py +28 -0
  244. browser_automation_cli-0.8.4/benchmarks/performance-test/eventloss_probe.py +27 -0
  245. browser_automation_cli-0.8.4/benchmarks/performance-test/freeze_probe.py +27 -0
  246. browser_automation_cli-0.8.4/benchmarks/performance-test/headed_probe.py +28 -0
  247. browser_automation_cli-0.8.4/benchmarks/performance-test/perproc.py +17 -0
  248. browser_automation_cli-0.8.4/benchmarks/performance-test/real_pages.py +21 -0
  249. browser_automation_cli-0.8.4/benchmarks/performance-test/results/baseline.json +121 -0
  250. browser_automation_cli-0.8.4/benchmarks/performance-test/results/baseline_cf.json +123 -0
  251. browser_automation_cli-0.8.4/benchmarks/performance-test/results/final.json +126 -0
  252. browser_automation_cli-0.8.4/benchmarks/performance-test/results/final_cf.json +123 -0
  253. browser_automation_cli-0.8.4/benchmarks/performance-test/results/opt1_navigate.json +92 -0
  254. browser_automation_cli-0.8.4/benchmarks/performance-test/results/opt2_flags.json +92 -0
  255. browser_automation_cli-0.8.4/benchmarks/performance-test/results/opt2_flags_cf.json +90 -0
  256. browser_automation_cli-0.8.4/benchmarks/performance-test/results/opt3_freeze.json +92 -0
  257. browser_automation_cli-0.8.4/benchmarks/performance-test/results/opt3_freeze_cf.json +90 -0
  258. browser_automation_cli-0.8.4/benchmarks/performance-test/results/opt3_headless.json +92 -0
  259. browser_automation_cli-0.8.4/benchmarks/performance-test/results/opt3_headless_cf.json +90 -0
  260. browser_automation_cli-0.8.4/benchmarks/performance-test/results/opt4_snapshot.json +121 -0
  261. browser_automation_cli-0.8.4/benchmarks/performance-test/results/opt4_snapshot_cf.json +118 -0
  262. browser_automation_cli-0.8.4/benchmarks/performance-test/results/opt5_settle.json +121 -0
  263. browser_automation_cli-0.8.4/benchmarks/performance-test/results/real_baseline.json +26 -0
  264. browser_automation_cli-0.8.4/benchmarks/performance-test/results/real_new.json +26 -0
  265. browser_automation_cli-0.8.4/benchmarks/performance-test/results/rust.json +126 -0
  266. browser_automation_cli-0.8.4/benchmarks/performance-test/results/rust_cf.json +123 -0
  267. browser_automation_cli-0.8.4/benchmarks/performance-test/results/snap_baseline_dash.cloudflare.com.txt +1110 -0
  268. browser_automation_cli-0.8.4/benchmarks/performance-test/results/snap_baseline_en.wikipedia.org.txt +1110 -0
  269. browser_automation_cli-0.8.4/benchmarks/performance-test/results/snap_baseline_github.com.txt +934 -0
  270. browser_automation_cli-0.8.4/benchmarks/performance-test/results/snap_baseline_news.ycombinator.com.txt +1110 -0
  271. browser_automation_cli-0.8.4/benchmarks/performance-test/results/snap_new_dash.cloudflare.com.txt +23 -0
  272. browser_automation_cli-0.8.4/benchmarks/performance-test/results/snap_new_en.wikipedia.org.txt +224 -0
  273. browser_automation_cli-0.8.4/benchmarks/performance-test/results/snap_new_github.com.txt +18 -0
  274. browser_automation_cli-0.8.4/benchmarks/performance-test/results/snap_new_news.ycombinator.com.txt +233 -0
  275. browser_automation_cli-0.8.4/benchmarks/performance-test/run.py +141 -0
  276. browser_automation_cli-0.8.4/benchmarks/performance-test/site/dashboard.html +38 -0
  277. browser_automation_cli-0.8.4/benchmarks/performance-test/site/page2.html +1 -0
  278. browser_automation_cli-0.8.4/benchmarks/performance-test/site/server.py +11 -0
  279. browser_automation_cli-0.8.4/benchmarks/performance-test/thaw_probe.py +30 -0
  280. browser_automation_cli-0.8.4/docs/busbench-results.png +0 -0
  281. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/install.sh +1 -1
  282. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/pyproject.toml +1 -1
  283. browser_automation_cli-0.8.4/setup.sh +33 -0
  284. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/src/actions.rs +39 -9
  285. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/src/cdp.rs +10 -4
  286. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/src/main.rs +2 -16
  287. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/src/server.rs +13 -4
  288. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/src/session.rs +81 -3
  289. browser_automation_cli-0.8.4/tests/test_cli.py +207 -0
  290. browser_automation_cli-0.8.2/.gitignore +0 -1
  291. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/src/chrome.rs +0 -0
  292. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/src/daemon_main.rs +0 -0
  293. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/src/install.rs +0 -0
  294. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/src/js.rs +0 -0
  295. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/src/lib.rs +0 -0
  296. {browser_automation_cli-0.8.2 → browser_automation_cli-0.8.4}/src/update.rs +0 -0
@@ -0,0 +1,123 @@
1
+ name: rust-wheels
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ tags: ["v*"]
7
+ paths: ["src/**", "Cargo.toml", "Cargo.lock", "pyproject.toml", "install.sh", "tests/**", "benchmarks/performance-test/site/**", ".github/workflows/rust-wheels.yml"]
8
+ pull_request:
9
+ paths: ["src/**", "Cargo.toml", "Cargo.lock", "pyproject.toml", "tests/**", ".github/workflows/rust-wheels.yml"]
10
+ workflow_dispatch:
11
+
12
+ permissions:
13
+ contents: write
14
+
15
+ jobs:
16
+ # Linux validation: the end-to-end suite driven against the Rust daemon + Rust client.
17
+ test-linux:
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ - uses: dtolnay/rust-toolchain@stable
22
+ - uses: Swatinem/rust-cache@v2
23
+ - uses: astral-sh/setup-uv@v4
24
+ - name: Build
25
+ run: cargo build --release
26
+ - name: System libs for Chromium (via ephemeral playwright; no project dependency)
27
+ run: uvx playwright install-deps chromium
28
+ - name: Native browser install (validates the Rust installer on Linux)
29
+ run: target/release/browser install
30
+ - name: End-to-end tests on the Rust daemon
31
+ env:
32
+ BROWSER_CLI: ${{ github.workspace }}/target/release/browser
33
+ BROWSER_DAEMON: ${{ github.workspace }}/target/release/browser-daemon
34
+ BROWSER_EPHEMERAL: "1"
35
+ run: python3 -m unittest -v tests/test_cli.py
36
+ - name: End-to-end tests again with engine=system (the runner's installed Chrome)
37
+ env:
38
+ BROWSER_CLI: ${{ github.workspace }}/target/release/browser
39
+ BROWSER_DAEMON: ${{ github.workspace }}/target/release/browser-daemon
40
+ run: |
41
+ target/release/browser engine system
42
+ BROWSER_EPHEMERAL=1 python3 -m unittest tests/test_cli.py
43
+ target/release/browser engine auto
44
+ - name: Daemon log on failure
45
+ if: failure()
46
+ run: cat /tmp/test-daemon.log || true
47
+
48
+ wheels:
49
+ needs: test-linux
50
+ strategy:
51
+ fail-fast: false
52
+ matrix:
53
+ include:
54
+ - { os: ubuntu-latest, target: x86_64, manylinux: auto }
55
+ - { os: ubuntu-24.04-arm, target: aarch64, manylinux: auto } # native: ring/rustls does not cross-compile in the cross-gcc image
56
+ - { os: macos-14, target: aarch64 }
57
+ - { os: macos-15-intel, target: x86_64 }
58
+ runs-on: ${{ matrix.os }}
59
+ steps:
60
+ - uses: actions/checkout@v4
61
+ - uses: PyO3/maturin-action@v1
62
+ with:
63
+ target: ${{ matrix.target }}
64
+ manylinux: ${{ matrix.manylinux || '' }}
65
+ args: --release --out dist
66
+ - name: Smoke the client binary (every matrix entry builds natively)
67
+ run: |
68
+ set -e
69
+ pip install dist/*.whl
70
+ browser --version
71
+ - uses: actions/upload-artifact@v4
72
+ with:
73
+ name: wheel-${{ matrix.os }}-${{ matrix.target }}
74
+ path: dist/*.whl
75
+
76
+ sdist:
77
+ runs-on: ubuntu-latest
78
+ steps:
79
+ - uses: actions/checkout@v4
80
+ - uses: PyO3/maturin-action@v1
81
+ with:
82
+ command: sdist
83
+ args: --out dist
84
+ - uses: actions/upload-artifact@v4
85
+ with:
86
+ name: sdist
87
+ path: dist/*.tar.gz
88
+
89
+ release:
90
+ if: startsWith(github.ref, 'refs/tags/v')
91
+ needs: [wheels, sdist]
92
+ runs-on: ubuntu-latest
93
+ steps:
94
+ - uses: actions/download-artifact@v4
95
+ with:
96
+ path: dist
97
+ merge-multiple: true
98
+ - name: Tarballs for install.sh (binaries extracted from each wheel)
99
+ run: |
100
+ set -e
101
+ V="${GITHUB_REF_NAME#v}"
102
+ for w in dist/*.whl; do
103
+ case "$w" in *linux*x86_64*) t="linux-x86_64" ;; *linux*aarch64*) t="linux-aarch64" ;; *macosx*arm64*) t="darwin-arm64" ;; *macosx*x86_64*) t="darwin-x86_64" ;; *) continue ;; esac
104
+ rm -rf tmpw && mkdir tmpw && unzip -q "$w" -d tmpw
105
+ bin=$(find tmpw -type d -name scripts | head -1)
106
+ chmod +x "$bin"/browser "$bin"/browser-daemon
107
+ tar -C "$bin" -czf "dist/browser-cli-$V-$t.tar.gz" browser browser-daemon
108
+ (cd dist && shasum -a 256 "browser-cli-$V-$t.tar.gz" > "browser-cli-$V-$t.sha256")
109
+ done
110
+ rm -rf tmpw; ls -la dist
111
+ - name: Attach wheels and tarballs to the GitHub release
112
+ env:
113
+ GH_TOKEN: ${{ github.token }}
114
+ run: |
115
+ gh release view "${{ github.ref_name }}" --repo "${{ github.repository }}" >/dev/null 2>&1 || gh release create "${{ github.ref_name }}" --repo "${{ github.repository }}" --title "${{ github.ref_name }}" --notes "See the benchmarks/ directory for measurements." --generate-notes
116
+ gh release upload "${{ github.ref_name }}" dist/* --clobber --repo "${{ github.repository }}"
117
+ - name: Publish to PyPI (only when the PYPI_API_TOKEN secret is set)
118
+ env:
119
+ UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
120
+ run: |
121
+ if [ -z "$UV_PUBLISH_TOKEN" ]; then echo "PYPI_API_TOKEN not set; skipping PyPI publish"; exit 0; fi
122
+ pip install uv
123
+ uv publish dist/browser_automation_cli-*
@@ -0,0 +1,50 @@
1
+ # Build artifacts
2
+ dist/
3
+ build/
4
+ target/
5
+ *.egg-info/
6
+ *.egg
7
+
8
+ # Python cache
9
+ __pycache__/
10
+ *.pyc
11
+ *.pyo
12
+
13
+ # Virtual environments
14
+ .venv/
15
+ venv/
16
+
17
+ .env
18
+
19
+ # IDE
20
+ .vscode/
21
+ .idea/
22
+
23
+ # macOS
24
+ .DS_Store
25
+
26
+ # Release documentation
27
+ RELEASE.md
28
+
29
+ # Local state
30
+ *.log
31
+ *.tmp
32
+ benchmarks/development-bench/results/calls.log
33
+ benchmarks/development-bench/results/current.json
34
+
35
+ # busbench (BU Bench V1): browser-use's benchmark keeps its tasks + gold answers secret.
36
+ # Publish the sanitized aggregate (RESULTS.md) + per-task sanitized score.json ONLY.
37
+ # The full per-task record (full.json with answers/ground-truth, traces, streams, screenshots,
38
+ # and the local README index) stays local — never published.
39
+ benchmarks/busbench/results/**
40
+ !benchmarks/busbench/results/*/
41
+ !benchmarks/busbench/results/*/score.json
42
+ benchmarks/busbench/system_prompt_bu_reference.md
43
+ # local rerun/recompute scripts + leaderboard (kept locally, not published).
44
+ # run_suite.sh IS published (the recompute driver); leaderboard may embed per-task results.
45
+ benchmarks/busbench/*.sh
46
+ !benchmarks/busbench/run_suite.sh
47
+ benchmarks/busbench/leaderboard.html
48
+
49
+ # python caches
50
+ benchmarks/**/__pycache__/
@@ -0,0 +1,52 @@
1
+ # Working on this repository
2
+
3
+ This file is for coding agents (and humans) developing browser-automation-cli itself.
4
+ **If you want to *use* the tool from an agent, read [SKILL.md](SKILL.md) instead**, it is embedded in
5
+ the binary (`browser install skill` installs it into Claude Code / Codex / OpenCode).
6
+
7
+ The whole project is Rust: one binary (`browser`, with a `daemon` subcommand) plus a `browser-daemon`
8
+ compat shim, driving Chrome over raw CDP via a websocket, no Python, Playwright, or Node at runtime.
9
+
10
+ ## Layout
11
+
12
+ | path | what it is |
13
+ |---|---|
14
+ | `src/` | the Rust client + daemon (`Cargo.toml` at the repo root) |
15
+ | `src/js.rs` | all injected JavaScript: snapshot (iframe/shadow-DOM aware, `@eN` refs), target resolution (strict mode), settle. Snapshot and targeting share one role/name definition, keep it that way |
16
+ | `pyproject.toml` | maturin packaging (`bindings = "bin"`), builds the two binaries into the `browser-automation-cli` wheel |
17
+ | `install.sh` | installs prebuilt binaries from the GitHub release |
18
+ | `tests/test_cli.py` | 18 end-to-end tests that drive the real daemon through the real CLI (Python is only the test runner + the local test-site fixture; stdlib only) |
19
+ | `benchmarks/performance-test/` | tool benchmark (latency, tokens, idle CPU/RSS) and one-off probes |
20
+ | `benchmarks/development-bench/` | agent benchmark: 17 verifier-judged tasks run by fresh LLM subagents |
21
+
22
+ ## Build and test
23
+
24
+ ```bash
25
+ cargo build --release
26
+ BROWSER_CLI=$PWD/target/release/browser \
27
+ BROWSER_DAEMON=$PWD/target/release/browser-daemon \
28
+ python3 -m unittest -v tests/test_cli.py
29
+ ```
30
+
31
+ The test suite needs a `python3` on PATH (stdlib only, it's the test runner and serves the local test
32
+ site) and a Chromium for the daemon (`target/release/browser install`). `BROWSER_CLI` / `BROWSER_DAEMON`
33
+ default to `target/release/…` when unset.
34
+
35
+ CI (`.github/workflows/rust-wheels.yml`) runs the suite on Linux twice (managed build and
36
+ `engine=system`), builds wheels for 4 platforms, and on `v*` tags publishes to PyPI and attaches
37
+ release assets. Chromium system libs come from an ephemeral `uvx playwright install-deps` (no project
38
+ dependency). Lint workflow changes with `actionlint` before pushing.
39
+
40
+ ## Non-negotiables
41
+
42
+ - **Measure before and after.** Any performance/resource claim goes through `benchmarks/performance-test/run.py`
43
+ (before → change → after) or the agent benchmark; results belong in the relevant benchmark's README / RESULTS.md. macOS `ps pcpu`
44
+ is a lifetime average, the harness uses `ps -o time` deltas for a reason.
45
+ - **The test suite is the protocol contract.** Don't change request/response shapes without updating
46
+ the tests (or documenting a legacy shim, as done for `type {selector, text}`).
47
+ - **Agent benchmark subagents run on Claude Sonnet** (`model: "sonnet"`) unless explicitly comparing
48
+ models; two attempts per task (pass@2) is the minimum for judging a change.
49
+ - **Docs ship with the binary**: `README.md` becomes the PyPI description (maturin reads it at build)
50
+ and `SKILL.md` is embedded in the binary, both live at the repo root.
51
+ - **Releases**: bump `Cargo.toml` + `pyproject.toml` + `install.sh` together, tag `v<version>`, and
52
+ let CI publish. PyPI descriptions are frozen per release.
@@ -34,7 +34,7 @@ dependencies = [
34
34
 
35
35
  [[package]]
36
36
  name = "browser-cli"
37
- version = "0.8.2"
37
+ version = "0.8.4"
38
38
  dependencies = [
39
39
  "base64",
40
40
  "futures-util",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "browser-cli"
3
- version = "0.8.2"
3
+ version = "0.8.4"
4
4
  edition = "2021"
5
5
  description = "Browser automation daemon + CLI for coding agents. Persistent sessions, no MCP, no extensions."
6
6
  license = "MIT"
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Browser CLI Maintainers
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,24 @@
1
+ .PHONY: build install wheel daemon help
2
+
3
+ help:
4
+ @echo "Browser CLI (Rust) - Usage"
5
+ @echo ""
6
+ @echo " make build cargo build --release"
7
+ @echo " make install build + download Chromium"
8
+ @echo " make wheel build the PyPI wheel via maturin"
9
+ @echo " make daemon start the browser daemon (foreground)"
10
+ @echo " browser create create a new session"
11
+ @echo " browser list list sessions"
12
+ @echo " browser <id> <cmd> run a command on a session"
13
+
14
+ build:
15
+ @cargo build --release
16
+
17
+ install: build
18
+ @./target/release/browser install
19
+
20
+ wheel:
21
+ @uvx maturin build --release
22
+
23
+ daemon:
24
+ @./target/release/browser daemon
@@ -1,10 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: browser-automation-cli
3
- Version: 0.8.2
3
+ Version: 0.8.4
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: Operating System :: MacOS
7
7
  Classifier: Operating System :: POSIX :: Linux
8
+ License-File: LICENSE.txt
8
9
  Summary: Browser automation daemon + CLI for coding agents. Persistent sessions, no MCP, no extensions.
9
10
  Keywords: browser,playwright,automation,cli,agent
10
11
  License-Expression: MIT
@@ -15,7 +16,7 @@ Project-URL: Repository, https://github.com/jshan9078/browser-automation-cli
15
16
 
16
17
  # Browser Automation CLI
17
18
 
18
- > **If you are an LLM using this tool, read [SKILL.md](https://github.com/jshan9078/browser-automation-cli/blob/main/SKILL.md)** — or run `browser install skill` to add it to Claude Code / Codex / OpenCode. ([AGENTS.md](AGENTS.md) is for agents developing this repo.)
19
+ > **If you are an LLM using this tool, read [SKILL.md](https://github.com/jshan9078/browser-automation-cli/blob/main/SKILL.md)**: or run `browser install skill` to add it to Claude Code / Codex / OpenCode. ([AGENTS.md](AGENTS.md) is for agents developing this repo.)
19
20
 
20
21
  A lightweight, self-hosted browser automation tool with a background daemon and CLI client. Enables authenticated web automation, screenshots, compact page snapshots, and page interactions via simple CLI commands. Share the [`SKILL.md`](https://github.com/jshan9078/browser-automation-cli/blob/main/SKILL.md) file with your coding agent harness for seamless integration.
21
22
 
@@ -23,13 +24,23 @@ A lightweight, self-hosted browser automation tool with a background daemon and
23
24
 
24
25
  Coding agents need to interact with authenticated web apps. Existing solutions all have tradeoffs:
25
26
 
26
- * **Chrome DevTools MCP** — requires Node.js, per-agent MCP server configuration, Google telemetry by default, and complex setup for each coding agent
27
- * **BrowserMCP and similar tools** — require installing Chrome extensions, tie into specific ecosystems, and use MCP which bloats the agent's context window with tool definitions and protocol overhead
28
- * **Playwright/Puppeteer scripts** — require writing code for every interaction, no persistent auth state
29
- * **AI browser frameworks** — heavy, opinionated, and framework-locked
27
+ * **Chrome DevTools MCP**: requires Node.js, per-agent MCP server configuration, Google telemetry by default, and complex setup for each coding agent
28
+ * **BrowserMCP and similar tools**: require installing Chrome extensions, tie into specific ecosystems, and use MCP which bloats the agent's context window with tool definitions and protocol overhead
29
+ * **Playwright/Puppeteer scripts**: require writing code for every interaction, no persistent auth state
30
+ * **AI browser frameworks**: heavy, opinionated, and framework-locked
30
31
 
31
32
  Browser CLI solves this with a persistent daemon that any agent can call via subprocess. No extensions, no MCP config, no SDKs, no ecosystem lock-in. Sessions persist across agent calls (and daemon restarts) so you only log in once.
32
33
 
34
+ ## Benchmarks
35
+
36
+ On [BU Bench V1](https://github.com/browser-use/benchmark) (browser-use's 100-task benchmark, `opus-4-7`,
37
+ scored by their `gemini-2.5-flash` judge), Claude Code + browser-automation-cli tops every published
38
+ harness × browser-tool configuration:
39
+
40
+ ![BU Bench V1 results](https://raw.githubusercontent.com/jshan9078/browser-automation-cli/main/docs/busbench-results.png)
41
+
42
+ Methodology and per-task scores: [`benchmarks/busbench/`](benchmarks/busbench/RESULTS.md).
43
+
33
44
  ## Install
34
45
 
35
46
  ```bash
@@ -141,7 +152,7 @@ All print JSON (snapshot prints text). Add `-s` / `--snapshot` to any action to
141
152
  | :-- | :-- |
142
153
  | `navigate <url> [--wait load\|domcontentloaded\|networkidle]` | Returns as soon as the page is usable; never fails on a slow `networkidle` |
143
154
  | `snapshot [scope] [--all] [--max N] [--json]` | Visible interactive elements + headings. `--all` adds text blocks, `--json` gives boxes and unique selectors |
144
- | `click <target> [--double]` | Also `click --at X,Y` to click raw viewport pixels (canvas / vision — no DOM target; screenshot first, pixels map 1:1) |
155
+ | `click <target> [--double]` | Also `click --at X,Y` to click raw viewport pixels (canvas / vision, no DOM target; screenshot first, pixels map 1:1) |
145
156
  | `type <target> <text> [--sequential] [--submit]` | `fill()` by default; `--sequential` sends key events (autocomplete); `--submit` presses Enter |
146
157
  | `press <key> [target]` | `Enter`, `Tab`, `Control+a`, … |
147
158
  | `hover <target>` | |
@@ -155,16 +166,16 @@ All print JSON (snapshot prints text). Add `-s` / `--snapshot` to any action to
155
166
  | `back` / `forward` | |
156
167
  | `batch` | JSON lines on stdin, run in one round-trip, stop at first failure |
157
168
 
158
- **Targets:** `@e12` (ref from snapshot — preferred) · CSS selector · `text=Create` · `role=button[name=Create]` · `label=Email` · `placeholder=Search` · or flags `--text / --role [--name] / --label / --placeholder`. Ambiguous CSS selectors are refused (strict mode) instead of clicking the first match. For canvas / vision cases with no DOM target, `click --at X,Y` clicks raw viewport pixels (take a `screenshot` first; its pixels map 1:1 to click coordinates).
169
+ **Targets:** `@e12` (ref from snapshot, preferred) · CSS selector · `text=Create` · `role=button[name=Create]` · `label=Email` · `placeholder=Search` · or flags `--text / --role [--name] / --label / --placeholder`. Ambiguous CSS selectors are refused (strict mode) instead of clicking the first match. For canvas / vision cases with no DOM target, `click --at X,Y` clicks raw viewport pixels (take a `screenshot` first; its pixels map 1:1 to click coordinates).
159
170
 
160
171
  ***
161
172
 
162
173
  ## Architecture
163
174
 
164
175
  * **Daemon** (`browser-daemon`): Unix socket server (`~/.browser-daemon/socket`, mode 600) owning a headless Chromium, plus a headed one that exists only while some session is `show`n.
165
- * **CLI** (`browser`): ~40 ms per call, no Playwright import on the daemon path.
176
+ * **CLI** (`browser`): a native Rust binary driving Chrome over raw CDP, ~2 ms per call, no Python/Node at runtime.
166
177
  * **Sessions**: one isolated browser context each. Hidden sessions are **frozen** after 10 s idle (script execution paused, ~3% CPU on animated dashboards; callbacks that fire while frozen are dropped, so `BROWSER_FREEZE_AFTER=0` disables it) and **hibernated** to `~/.browser-daemon/sessions/<id>.json` (cookies + storage + URL) after 10 min idle or on shutdown; they are rehydrated transparently on the next command. Tune with `BROWSER_FREEZE_AFTER` / `BROWSER_HIBERNATE_AFTER` (seconds).
167
- * **Resource profile** (M4, Cloudflare dashboard parked in a session): 2% CPU / 1.1 GB vs 264% CPU / 2.1 GB for v0.2. See [AGENTBENCH.md](AGENTBENCH.md) for the measurements.
178
+ * **Resource profile** (M4, Cloudflare dashboard parked in a session): 2% CPU / 1.1 GB vs 264% CPU / 2.1 GB for v0.2. See [`benchmarks/`](benchmarks/) for methodology and measurements.
168
179
 
169
180
  ## Anti-Detection
170
181
 
@@ -197,26 +208,28 @@ Errors (exit code 1):
197
208
 
198
209
  Run `browser install skill` to install [`SKILL.md`](SKILL.md) into Claude Code / Codex / OpenCode, or share the file with any other harness.
199
210
 
200
- ## Rust implementation (preview)
211
+ ## Implementation
201
212
 
202
- `rust/` contains a Rust client and daemon with the same CLI and socket protocol — no Python, Playwright or
203
- Node at all: `browser install` downloads the same Chrome-for-Testing build Playwright pins (into the same
204
- cache, so both implementations share it), and `capture` is native too. Per-call overhead 40 ms → 2 ms,
205
- daemon RSS −90 MB, frame- and shadow-DOM-aware snapshots. See AGENTBENCH.md. Published to PyPI as
206
- 0.4.0 under the same name (wheels for Linux x86_64/aarch64, macOS arm64/x86_64).
213
+ Written entirely in Rust, one binary (`browser`, with a `daemon` subcommand) plus a `browser-daemon`
214
+ compat shim, driving Chrome over raw CDP via a websocket. No Python, Playwright, or Node at runtime:
215
+ `browser install` downloads the Chrome-for-Testing build directly, and `capture` is native too. ~2 ms
216
+ per call, daemon RSS −90 MB vs the old Python build, frame- and shadow-DOM-aware snapshots. See the
217
+ [`benchmarks/`](benchmarks/) directory for measurements. Since 0.4.0 the PyPI package ships these binaries under the same name
218
+ (wheels for Linux x86_64/aarch64, macOS arm64/x86_64).
207
219
 
208
220
  ```bash
209
- cd rust && cargo build --release
221
+ cargo build --release
210
222
  ./target/release/browser list # the daemon auto-starts (`browser daemon` runs it in the foreground)
211
223
  ```
212
224
 
213
225
  ## Development
214
226
 
215
227
  ```bash
216
- uv sync
217
- .venv/bin/python -m unittest -v tests/test_cli.py # end-to-end tests against scratch/bench/site
218
- .venv/bin/python scratch/bench/run.py <label> # benchmark (latency, tokens, idle CPU/RSS)
219
- .venv/bin/python scratch/bench/compare.py baseline <label>
228
+ cargo build --release
229
+ BROWSER_CLI=$PWD/target/release/browser BROWSER_DAEMON=$PWD/target/release/browser-daemon \
230
+ python3 -m unittest -v tests/test_cli.py # end-to-end tests (needs python3 + a Chromium)
231
+ python3 benchmarks/performance-test/run.py <label> # benchmark (latency, tokens, idle CPU/RSS)
232
+ python3 benchmarks/performance-test/compare.py baseline <label>
220
233
  ```
221
234
 
222
235
  ## Troubleshooting
@@ -224,29 +237,26 @@ uv sync
224
237
  | Symptom | Fix |
225
238
  | :-- | :-- |
226
239
  | `Command not found: browser` | `export PATH="$HOME/.local/bin:$PATH"` |
227
- | `Daemon not running` | Auto-start was disabled or failed — `browser daemon &`, check `~/.browser-daemon/daemon.log` |
240
+ | `Daemon not running` | Auto-start was disabled or failed, `browser daemon &`, check `~/.browser-daemon/daemon.log` |
228
241
  | Browser doesn't launch | `browser install` |
229
242
  | `Session not found` | `browser list` |
230
243
  | `ref @eN is unknown or stale` | Page changed; run `snapshot` again |
231
244
  | `strict mode violation` | Selector matched several elements; use an `@ref`, `--text`, or a tighter selector |
232
245
  | Stale Chromium processes | `browser cleanup` |
233
246
 
234
- ### Installing the Rust binaries
247
+ ### Installing the binaries
235
248
 
236
249
  ```bash
237
- curl -fsSL https://raw.githubusercontent.com/jshan9078/browser-automation-cli/main/rust/install.sh | sh
250
+ curl -fsSL https://raw.githubusercontent.com/jshan9078/browser-automation-cli/main/install.sh | sh
238
251
  ```
239
252
 
240
- or simply `uv tool install browser-automation-cli` (0.4.0+ wheels are the Rust binaries). The script installs
241
- `browser` and `browser-daemon` into `~/.local/bin` (set `BROWSER_CLI_BIN` to change); other platforms: `cd rust && cargo build --release`.
253
+ or simply `uv tool install browser-automation-cli` (the PyPI wheels are the Rust binaries). The script installs
254
+ `browser` and `browser-daemon` into `~/.local/bin` (set `BROWSER_CLI_BIN` to change); to build from source: `cargo build --release`.
242
255
 
243
- Wheel (same PyPI project name, so download stats carry over): `cd rust && uvx maturin build --release` →
244
- `uv tool install rust/target/wheels/browser_automation_cli-*.whl`. From 0.4.0 the PyPI package ships
245
- the Rust binaries; the Python implementation remains in `cli/` and `daemon/` for reference and for
246
- `python -m daemon.server`.
256
+ Wheel: `uvx maturin build --release` → `uv tool install target/wheels/browser_automation_cli-*.whl`.
247
257
 
248
258
  CI (`.github/workflows/rust-wheels.yml`) builds wheels for Linux x86_64/aarch64 and macOS arm64/x86_64 on every
249
- push touching `rust/`, runs the end-to-end suite against the Rust daemon on Linux, attaches wheels to the release
259
+ push touching the Rust sources, runs the end-to-end suite against the Rust daemon on Linux, attaches wheels to the release
250
260
  on `v*` tags, and publishes to PyPI when a `PYPI_API_TOKEN` repository secret exists. Windows is not a target: the
251
261
  daemon speaks over a Unix socket.
252
262
 
@@ -1,6 +1,6 @@
1
1
  # Browser Automation CLI
2
2
 
3
- > **If you are an LLM using this tool, read [SKILL.md](https://github.com/jshan9078/browser-automation-cli/blob/main/SKILL.md)** — or run `browser install skill` to add it to Claude Code / Codex / OpenCode. ([AGENTS.md](AGENTS.md) is for agents developing this repo.)
3
+ > **If you are an LLM using this tool, read [SKILL.md](https://github.com/jshan9078/browser-automation-cli/blob/main/SKILL.md)**: or run `browser install skill` to add it to Claude Code / Codex / OpenCode. ([AGENTS.md](AGENTS.md) is for agents developing this repo.)
4
4
 
5
5
  A lightweight, self-hosted browser automation tool with a background daemon and CLI client. Enables authenticated web automation, screenshots, compact page snapshots, and page interactions via simple CLI commands. Share the [`SKILL.md`](https://github.com/jshan9078/browser-automation-cli/blob/main/SKILL.md) file with your coding agent harness for seamless integration.
6
6
 
@@ -8,13 +8,23 @@ A lightweight, self-hosted browser automation tool with a background daemon and
8
8
 
9
9
  Coding agents need to interact with authenticated web apps. Existing solutions all have tradeoffs:
10
10
 
11
- * **Chrome DevTools MCP** — requires Node.js, per-agent MCP server configuration, Google telemetry by default, and complex setup for each coding agent
12
- * **BrowserMCP and similar tools** — require installing Chrome extensions, tie into specific ecosystems, and use MCP which bloats the agent's context window with tool definitions and protocol overhead
13
- * **Playwright/Puppeteer scripts** — require writing code for every interaction, no persistent auth state
14
- * **AI browser frameworks** — heavy, opinionated, and framework-locked
11
+ * **Chrome DevTools MCP**: requires Node.js, per-agent MCP server configuration, Google telemetry by default, and complex setup for each coding agent
12
+ * **BrowserMCP and similar tools**: require installing Chrome extensions, tie into specific ecosystems, and use MCP which bloats the agent's context window with tool definitions and protocol overhead
13
+ * **Playwright/Puppeteer scripts**: require writing code for every interaction, no persistent auth state
14
+ * **AI browser frameworks**: heavy, opinionated, and framework-locked
15
15
 
16
16
  Browser CLI solves this with a persistent daemon that any agent can call via subprocess. No extensions, no MCP config, no SDKs, no ecosystem lock-in. Sessions persist across agent calls (and daemon restarts) so you only log in once.
17
17
 
18
+ ## Benchmarks
19
+
20
+ On [BU Bench V1](https://github.com/browser-use/benchmark) (browser-use's 100-task benchmark, `opus-4-7`,
21
+ scored by their `gemini-2.5-flash` judge), Claude Code + browser-automation-cli tops every published
22
+ harness × browser-tool configuration:
23
+
24
+ ![BU Bench V1 results](https://raw.githubusercontent.com/jshan9078/browser-automation-cli/main/docs/busbench-results.png)
25
+
26
+ Methodology and per-task scores: [`benchmarks/busbench/`](benchmarks/busbench/RESULTS.md).
27
+
18
28
  ## Install
19
29
 
20
30
  ```bash
@@ -126,7 +136,7 @@ All print JSON (snapshot prints text). Add `-s` / `--snapshot` to any action to
126
136
  | :-- | :-- |
127
137
  | `navigate <url> [--wait load\|domcontentloaded\|networkidle]` | Returns as soon as the page is usable; never fails on a slow `networkidle` |
128
138
  | `snapshot [scope] [--all] [--max N] [--json]` | Visible interactive elements + headings. `--all` adds text blocks, `--json` gives boxes and unique selectors |
129
- | `click <target> [--double]` | Also `click --at X,Y` to click raw viewport pixels (canvas / vision — no DOM target; screenshot first, pixels map 1:1) |
139
+ | `click <target> [--double]` | Also `click --at X,Y` to click raw viewport pixels (canvas / vision, no DOM target; screenshot first, pixels map 1:1) |
130
140
  | `type <target> <text> [--sequential] [--submit]` | `fill()` by default; `--sequential` sends key events (autocomplete); `--submit` presses Enter |
131
141
  | `press <key> [target]` | `Enter`, `Tab`, `Control+a`, … |
132
142
  | `hover <target>` | |
@@ -140,16 +150,16 @@ All print JSON (snapshot prints text). Add `-s` / `--snapshot` to any action to
140
150
  | `back` / `forward` | |
141
151
  | `batch` | JSON lines on stdin, run in one round-trip, stop at first failure |
142
152
 
143
- **Targets:** `@e12` (ref from snapshot — preferred) · CSS selector · `text=Create` · `role=button[name=Create]` · `label=Email` · `placeholder=Search` · or flags `--text / --role [--name] / --label / --placeholder`. Ambiguous CSS selectors are refused (strict mode) instead of clicking the first match. For canvas / vision cases with no DOM target, `click --at X,Y` clicks raw viewport pixels (take a `screenshot` first; its pixels map 1:1 to click coordinates).
153
+ **Targets:** `@e12` (ref from snapshot, preferred) · CSS selector · `text=Create` · `role=button[name=Create]` · `label=Email` · `placeholder=Search` · or flags `--text / --role [--name] / --label / --placeholder`. Ambiguous CSS selectors are refused (strict mode) instead of clicking the first match. For canvas / vision cases with no DOM target, `click --at X,Y` clicks raw viewport pixels (take a `screenshot` first; its pixels map 1:1 to click coordinates).
144
154
 
145
155
  ***
146
156
 
147
157
  ## Architecture
148
158
 
149
159
  * **Daemon** (`browser-daemon`): Unix socket server (`~/.browser-daemon/socket`, mode 600) owning a headless Chromium, plus a headed one that exists only while some session is `show`n.
150
- * **CLI** (`browser`): ~40 ms per call, no Playwright import on the daemon path.
160
+ * **CLI** (`browser`): a native Rust binary driving Chrome over raw CDP, ~2 ms per call, no Python/Node at runtime.
151
161
  * **Sessions**: one isolated browser context each. Hidden sessions are **frozen** after 10 s idle (script execution paused, ~3% CPU on animated dashboards; callbacks that fire while frozen are dropped, so `BROWSER_FREEZE_AFTER=0` disables it) and **hibernated** to `~/.browser-daemon/sessions/<id>.json` (cookies + storage + URL) after 10 min idle or on shutdown; they are rehydrated transparently on the next command. Tune with `BROWSER_FREEZE_AFTER` / `BROWSER_HIBERNATE_AFTER` (seconds).
152
- * **Resource profile** (M4, Cloudflare dashboard parked in a session): 2% CPU / 1.1 GB vs 264% CPU / 2.1 GB for v0.2. See [AGENTBENCH.md](AGENTBENCH.md) for the measurements.
162
+ * **Resource profile** (M4, Cloudflare dashboard parked in a session): 2% CPU / 1.1 GB vs 264% CPU / 2.1 GB for v0.2. See [`benchmarks/`](benchmarks/) for methodology and measurements.
153
163
 
154
164
  ## Anti-Detection
155
165
 
@@ -182,26 +192,28 @@ Errors (exit code 1):
182
192
 
183
193
  Run `browser install skill` to install [`SKILL.md`](SKILL.md) into Claude Code / Codex / OpenCode, or share the file with any other harness.
184
194
 
185
- ## Rust implementation (preview)
195
+ ## Implementation
186
196
 
187
- `rust/` contains a Rust client and daemon with the same CLI and socket protocol — no Python, Playwright or
188
- Node at all: `browser install` downloads the same Chrome-for-Testing build Playwright pins (into the same
189
- cache, so both implementations share it), and `capture` is native too. Per-call overhead 40 ms → 2 ms,
190
- daemon RSS −90 MB, frame- and shadow-DOM-aware snapshots. See AGENTBENCH.md. Published to PyPI as
191
- 0.4.0 under the same name (wheels for Linux x86_64/aarch64, macOS arm64/x86_64).
197
+ Written entirely in Rust, one binary (`browser`, with a `daemon` subcommand) plus a `browser-daemon`
198
+ compat shim, driving Chrome over raw CDP via a websocket. No Python, Playwright, or Node at runtime:
199
+ `browser install` downloads the Chrome-for-Testing build directly, and `capture` is native too. ~2 ms
200
+ per call, daemon RSS −90 MB vs the old Python build, frame- and shadow-DOM-aware snapshots. See the
201
+ [`benchmarks/`](benchmarks/) directory for measurements. Since 0.4.0 the PyPI package ships these binaries under the same name
202
+ (wheels for Linux x86_64/aarch64, macOS arm64/x86_64).
192
203
 
193
204
  ```bash
194
- cd rust && cargo build --release
205
+ cargo build --release
195
206
  ./target/release/browser list # the daemon auto-starts (`browser daemon` runs it in the foreground)
196
207
  ```
197
208
 
198
209
  ## Development
199
210
 
200
211
  ```bash
201
- uv sync
202
- .venv/bin/python -m unittest -v tests/test_cli.py # end-to-end tests against scratch/bench/site
203
- .venv/bin/python scratch/bench/run.py <label> # benchmark (latency, tokens, idle CPU/RSS)
204
- .venv/bin/python scratch/bench/compare.py baseline <label>
212
+ cargo build --release
213
+ BROWSER_CLI=$PWD/target/release/browser BROWSER_DAEMON=$PWD/target/release/browser-daemon \
214
+ python3 -m unittest -v tests/test_cli.py # end-to-end tests (needs python3 + a Chromium)
215
+ python3 benchmarks/performance-test/run.py <label> # benchmark (latency, tokens, idle CPU/RSS)
216
+ python3 benchmarks/performance-test/compare.py baseline <label>
205
217
  ```
206
218
 
207
219
  ## Troubleshooting
@@ -209,28 +221,25 @@ uv sync
209
221
  | Symptom | Fix |
210
222
  | :-- | :-- |
211
223
  | `Command not found: browser` | `export PATH="$HOME/.local/bin:$PATH"` |
212
- | `Daemon not running` | Auto-start was disabled or failed — `browser daemon &`, check `~/.browser-daemon/daemon.log` |
224
+ | `Daemon not running` | Auto-start was disabled or failed, `browser daemon &`, check `~/.browser-daemon/daemon.log` |
213
225
  | Browser doesn't launch | `browser install` |
214
226
  | `Session not found` | `browser list` |
215
227
  | `ref @eN is unknown or stale` | Page changed; run `snapshot` again |
216
228
  | `strict mode violation` | Selector matched several elements; use an `@ref`, `--text`, or a tighter selector |
217
229
  | Stale Chromium processes | `browser cleanup` |
218
230
 
219
- ### Installing the Rust binaries
231
+ ### Installing the binaries
220
232
 
221
233
  ```bash
222
- curl -fsSL https://raw.githubusercontent.com/jshan9078/browser-automation-cli/main/rust/install.sh | sh
234
+ curl -fsSL https://raw.githubusercontent.com/jshan9078/browser-automation-cli/main/install.sh | sh
223
235
  ```
224
236
 
225
- or simply `uv tool install browser-automation-cli` (0.4.0+ wheels are the Rust binaries). The script installs
226
- `browser` and `browser-daemon` into `~/.local/bin` (set `BROWSER_CLI_BIN` to change); other platforms: `cd rust && cargo build --release`.
237
+ or simply `uv tool install browser-automation-cli` (the PyPI wheels are the Rust binaries). The script installs
238
+ `browser` and `browser-daemon` into `~/.local/bin` (set `BROWSER_CLI_BIN` to change); to build from source: `cargo build --release`.
227
239
 
228
- Wheel (same PyPI project name, so download stats carry over): `cd rust && uvx maturin build --release` →
229
- `uv tool install rust/target/wheels/browser_automation_cli-*.whl`. From 0.4.0 the PyPI package ships
230
- the Rust binaries; the Python implementation remains in `cli/` and `daemon/` for reference and for
231
- `python -m daemon.server`.
240
+ Wheel: `uvx maturin build --release` → `uv tool install target/wheels/browser_automation_cli-*.whl`.
232
241
 
233
242
  CI (`.github/workflows/rust-wheels.yml`) builds wheels for Linux x86_64/aarch64 and macOS arm64/x86_64 on every
234
- push touching `rust/`, runs the end-to-end suite against the Rust daemon on Linux, attaches wheels to the release
243
+ push touching the Rust sources, runs the end-to-end suite against the Rust daemon on Linux, attaches wheels to the release
235
244
  on `v*` tags, and publishes to PyPI when a `PYPI_API_TOKEN` repository secret exists. Windows is not a target: the
236
245
  daemon speaks over a Unix socket.