newcode 0.2.12__tar.gz → 0.3.2__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 (275) hide show
  1. {newcode-0.2.12 → newcode-0.3.2}/PKG-INFO +2 -1
  2. newcode-0.3.2/newcode/agents/_retired/__init__.py +5 -0
  3. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/agent_c_reviewer.py +1 -1
  4. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/agent_code_reviewer.py +1 -1
  5. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/agent_cpp_reviewer.py +1 -1
  6. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/agent_creator_agent.py +1 -1
  7. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/agent_golang_reviewer.py +1 -1
  8. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/agent_javascript_reviewer.py +1 -1
  9. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/agent_pack_leader.py +2 -2
  10. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/agent_python_programmer.py +1 -1
  11. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/agent_python_reviewer.py +1 -1
  12. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/agent_qa_browser.py +1 -1
  13. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/agent_qa_expert.py +1 -1
  14. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/agent_security_auditor.py +1 -1
  15. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/agent_terminal_qa.py +1 -1
  16. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/agent_typescript_reviewer.py +1 -1
  17. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/prompt_reviewer.py +2 -2
  18. {newcode-0.2.12/newcode → newcode-0.3.2/newcode/agents/_retired}/tools/browser/browser_manager.py +30 -6
  19. newcode-0.3.2/newcode/agents/agent_browser.py +204 -0
  20. {newcode-0.2.12 → newcode-0.3.2}/newcode/agents/agent_manager.py +18 -0
  21. {newcode-0.2.12 → newcode-0.3.2}/newcode/agents/base_agent.py +1 -1
  22. {newcode-0.2.12 → newcode-0.3.2}/newcode/callbacks.py +3 -3
  23. {newcode-0.2.12 → newcode-0.3.2}/newcode/cli_runner.py +47 -10
  24. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/command_handler.py +51 -17
  25. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/config_commands.py +8 -1
  26. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/core_commands.py +169 -31
  27. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/motd.py +6 -7
  28. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/onboarding_slides.py +13 -13
  29. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/onboarding_wizard.py +4 -1
  30. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/prompt_toolkit_completion.py +1 -1
  31. {newcode-0.2.12 → newcode-0.3.2}/newcode/config.py +127 -1
  32. {newcode-0.2.12 → newcode-0.3.2}/newcode/model_factory.py +0 -37
  33. {newcode-0.2.12 → newcode-0.3.2}/newcode/model_utils.py +1 -59
  34. {newcode-0.2.12 → newcode-0.3.2}/newcode/models.json +11 -0
  35. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/chatgpt_oauth/register_callbacks.py +8 -20
  36. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/claude_code_oauth/README.md +5 -5
  37. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/claude_code_oauth/SETUP.md +4 -4
  38. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/claude_code_oauth/register_callbacks.py +10 -19
  39. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/claude_code_oauth/test_plugin.py +1 -1
  40. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/__init__.py +243 -86
  41. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/agent_tools.py +6 -10
  42. newcode-0.3.2/newcode/tools/browser/__init__.py +750 -0
  43. newcode-0.3.2/newcode/tools/browser/browser_manager.py +97 -0
  44. newcode-0.3.2/newcode/tools/browser/cdp_client.py +634 -0
  45. newcode-0.3.2/newcode/tools/browser/cdp_control.py +337 -0
  46. newcode-0.3.2/newcode/tools/browser/cdp_domains.py +1112 -0
  47. newcode-0.3.2/newcode/tools/browser/cdp_interactions.py +754 -0
  48. newcode-0.3.2/newcode/tools/browser/cdp_locators.py +742 -0
  49. newcode-0.3.2/newcode/tools/browser/cdp_manager.py +643 -0
  50. newcode-0.3.2/newcode/tools/browser/cdp_navigation.py +282 -0
  51. newcode-0.3.2/newcode/tools/browser/cdp_screenshot.py +207 -0
  52. newcode-0.3.2/newcode/tools/browser/cdp_scripts.py +505 -0
  53. newcode-0.3.2/newcode/tools/browser/chrome_detector.py +518 -0
  54. {newcode-0.2.12 → newcode-0.3.2}/pyproject.toml +7 -5
  55. newcode-0.2.12/newcode/command_line/add_model_menu.py +0 -1092
  56. newcode-0.2.12/newcode/models_dev_api.json +0 -1
  57. newcode-0.2.12/newcode/models_dev_parser.py +0 -592
  58. newcode-0.2.12/newcode/plugins/antigravity_oauth/__init__.py +0 -10
  59. newcode-0.2.12/newcode/plugins/antigravity_oauth/accounts.py +0 -406
  60. newcode-0.2.12/newcode/plugins/antigravity_oauth/antigravity_model.py +0 -706
  61. newcode-0.2.12/newcode/plugins/antigravity_oauth/config.py +0 -42
  62. newcode-0.2.12/newcode/plugins/antigravity_oauth/constants.py +0 -133
  63. newcode-0.2.12/newcode/plugins/antigravity_oauth/oauth.py +0 -478
  64. newcode-0.2.12/newcode/plugins/antigravity_oauth/register_callbacks.py +0 -518
  65. newcode-0.2.12/newcode/plugins/antigravity_oauth/storage.py +0 -288
  66. newcode-0.2.12/newcode/plugins/antigravity_oauth/test_plugin.py +0 -319
  67. newcode-0.2.12/newcode/plugins/antigravity_oauth/token.py +0 -167
  68. newcode-0.2.12/newcode/plugins/antigravity_oauth/transport.py +0 -863
  69. newcode-0.2.12/newcode/plugins/antigravity_oauth/utils.py +0 -168
  70. newcode-0.2.12/newcode/prompts/antigravity_system_prompt.md +0 -1
  71. newcode-0.2.12/newcode/tools/browser/__init__.py +0 -37
  72. {newcode-0.2.12 → newcode-0.3.2}/.gitignore +0 -0
  73. {newcode-0.2.12 → newcode-0.3.2}/LICENSE +0 -0
  74. {newcode-0.2.12 → newcode-0.3.2}/README.md +0 -0
  75. {newcode-0.2.12 → newcode-0.3.2}/newcode/__init__.py +0 -0
  76. {newcode-0.2.12 → newcode-0.3.2}/newcode/__main__.py +0 -0
  77. {newcode-0.2.12 → newcode-0.3.2}/newcode/agents/__init__.py +0 -0
  78. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/pack/__init__.py +0 -0
  79. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/pack/bloodhound.py +0 -0
  80. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/pack/husky.py +0 -0
  81. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/pack/retriever.py +0 -0
  82. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/pack/shepherd.py +0 -0
  83. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/pack/terrier.py +0 -0
  84. {newcode-0.2.12/newcode/agents → newcode-0.3.2/newcode/agents/_retired}/pack/watchdog.py +0 -0
  85. {newcode-0.2.12/newcode → newcode-0.3.2/newcode/agents/_retired}/tools/browser/browser_control.py +0 -0
  86. {newcode-0.2.12/newcode → newcode-0.3.2/newcode/agents/_retired}/tools/browser/browser_interactions.py +0 -0
  87. {newcode-0.2.12/newcode → newcode-0.3.2/newcode/agents/_retired}/tools/browser/browser_locators.py +0 -0
  88. {newcode-0.2.12/newcode → newcode-0.3.2/newcode/agents/_retired}/tools/browser/browser_navigation.py +0 -0
  89. {newcode-0.2.12/newcode → newcode-0.3.2/newcode/agents/_retired}/tools/browser/browser_screenshot.py +0 -0
  90. {newcode-0.2.12/newcode → newcode-0.3.2/newcode/agents/_retired}/tools/browser/browser_scripts.py +0 -0
  91. {newcode-0.2.12 → newcode-0.3.2}/newcode/agents/agent_code_agent.py +0 -0
  92. {newcode-0.2.12 → newcode-0.3.2}/newcode/agents/agent_planning.py +0 -0
  93. {newcode-0.2.12 → newcode-0.3.2}/newcode/agents/event_stream_handler.py +0 -0
  94. {newcode-0.2.12 → newcode-0.3.2}/newcode/agents/json_agent.py +0 -0
  95. {newcode-0.2.12 → newcode-0.3.2}/newcode/agents/subagent_stream_handler.py +0 -0
  96. {newcode-0.2.12 → newcode-0.3.2}/newcode/chatgpt_codex_client.py +0 -0
  97. {newcode-0.2.12 → newcode-0.3.2}/newcode/claude_cache_client.py +0 -0
  98. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/__init__.py +0 -0
  99. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/agent_menu.py +0 -0
  100. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/attachments.py +0 -0
  101. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/autosave_menu.py +0 -0
  102. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/clipboard.py +0 -0
  103. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/colors_menu.py +0 -0
  104. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/command_registry.py +0 -0
  105. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/diff_menu.py +0 -0
  106. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/file_path_completion.py +0 -0
  107. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/load_context_completion.py +0 -0
  108. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/__init__.py +0 -0
  109. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/base.py +0 -0
  110. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/catalog_server_installer.py +0 -0
  111. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/custom_server_form.py +0 -0
  112. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/custom_server_installer.py +0 -0
  113. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/edit_command.py +0 -0
  114. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/handler.py +0 -0
  115. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/help_command.py +0 -0
  116. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/install_command.py +0 -0
  117. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/install_menu.py +0 -0
  118. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/list_command.py +0 -0
  119. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/logs_command.py +0 -0
  120. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/remove_command.py +0 -0
  121. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/restart_command.py +0 -0
  122. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/search_command.py +0 -0
  123. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/start_all_command.py +0 -0
  124. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/start_command.py +0 -0
  125. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/status_command.py +0 -0
  126. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/stop_all_command.py +0 -0
  127. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/stop_command.py +0 -0
  128. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/test_command.py +0 -0
  129. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/utils.py +0 -0
  130. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp/wizard_utils.py +0 -0
  131. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/mcp_completion.py +0 -0
  132. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/model_picker_completion.py +0 -0
  133. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/model_settings_menu.py +0 -0
  134. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/pin_command_completion.py +0 -0
  135. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/session_commands.py +0 -0
  136. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/skills_completion.py +0 -0
  137. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/uc_menu.py +0 -0
  138. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/utils.py +0 -0
  139. {newcode-0.2.12 → newcode-0.3.2}/newcode/command_line/wiggum_state.py +0 -0
  140. {newcode-0.2.12 → newcode-0.3.2}/newcode/error_logging.py +0 -0
  141. {newcode-0.2.12 → newcode-0.3.2}/newcode/gemini_code_assist.py +0 -0
  142. {newcode-0.2.12 → newcode-0.3.2}/newcode/gemini_model.py +0 -0
  143. {newcode-0.2.12 → newcode-0.3.2}/newcode/hook_engine/README.md +0 -0
  144. {newcode-0.2.12 → newcode-0.3.2}/newcode/hook_engine/__init__.py +0 -0
  145. {newcode-0.2.12 → newcode-0.3.2}/newcode/hook_engine/aliases.py +0 -0
  146. {newcode-0.2.12 → newcode-0.3.2}/newcode/hook_engine/engine.py +0 -0
  147. {newcode-0.2.12 → newcode-0.3.2}/newcode/hook_engine/executor.py +0 -0
  148. {newcode-0.2.12 → newcode-0.3.2}/newcode/hook_engine/matcher.py +0 -0
  149. {newcode-0.2.12 → newcode-0.3.2}/newcode/hook_engine/models.py +0 -0
  150. {newcode-0.2.12 → newcode-0.3.2}/newcode/hook_engine/registry.py +0 -0
  151. {newcode-0.2.12 → newcode-0.3.2}/newcode/hook_engine/validator.py +0 -0
  152. {newcode-0.2.12 → newcode-0.3.2}/newcode/http_utils.py +0 -0
  153. {newcode-0.2.12 → newcode-0.3.2}/newcode/image_utils.py +0 -0
  154. {newcode-0.2.12 → newcode-0.3.2}/newcode/keymap.py +0 -0
  155. {newcode-0.2.12 → newcode-0.3.2}/newcode/main.py +0 -0
  156. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/__init__.py +0 -0
  157. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/async_lifecycle.py +0 -0
  158. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/blocking_startup.py +0 -0
  159. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/captured_stdio_server.py +0 -0
  160. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/circuit_breaker.py +0 -0
  161. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/config_wizard.py +0 -0
  162. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/dashboard.py +0 -0
  163. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/error_isolation.py +0 -0
  164. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/examples/retry_example.py +0 -0
  165. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/health_monitor.py +0 -0
  166. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/managed_server.py +0 -0
  167. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/manager.py +0 -0
  168. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/mcp_logs.py +0 -0
  169. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/registry.py +0 -0
  170. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/retry_manager.py +0 -0
  171. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/server_registry_catalog.py +0 -0
  172. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/status_tracker.py +0 -0
  173. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_/system_tools.py +0 -0
  174. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_prompts/__init__.py +0 -0
  175. {newcode-0.2.12 → newcode-0.3.2}/newcode/mcp_prompts/hook_creator.py +0 -0
  176. {newcode-0.2.12 → newcode-0.3.2}/newcode/messaging/__init__.py +0 -0
  177. {newcode-0.2.12 → newcode-0.3.2}/newcode/messaging/bus.py +0 -0
  178. {newcode-0.2.12 → newcode-0.3.2}/newcode/messaging/commands.py +0 -0
  179. {newcode-0.2.12 → newcode-0.3.2}/newcode/messaging/markdown_patches.py +0 -0
  180. {newcode-0.2.12 → newcode-0.3.2}/newcode/messaging/message_queue.py +0 -0
  181. {newcode-0.2.12 → newcode-0.3.2}/newcode/messaging/messages.py +0 -0
  182. {newcode-0.2.12 → newcode-0.3.2}/newcode/messaging/queue_console.py +0 -0
  183. {newcode-0.2.12 → newcode-0.3.2}/newcode/messaging/renderers.py +0 -0
  184. {newcode-0.2.12 → newcode-0.3.2}/newcode/messaging/rich_renderer.py +0 -0
  185. {newcode-0.2.12 → newcode-0.3.2}/newcode/messaging/spinner/__init__.py +0 -0
  186. {newcode-0.2.12 → newcode-0.3.2}/newcode/messaging/spinner/console_spinner.py +0 -0
  187. {newcode-0.2.12 → newcode-0.3.2}/newcode/messaging/spinner/spinner_base.py +0 -0
  188. {newcode-0.2.12 → newcode-0.3.2}/newcode/messaging/subagent_console.py +0 -0
  189. {newcode-0.2.12 → newcode-0.3.2}/newcode/model_switching.py +0 -0
  190. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/__init__.py +0 -0
  191. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/agent_skills/__init__.py +0 -0
  192. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/agent_skills/config.py +0 -0
  193. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/agent_skills/discovery.py +0 -0
  194. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/agent_skills/downloader.py +0 -0
  195. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/agent_skills/installer.py +0 -0
  196. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/agent_skills/metadata.py +0 -0
  197. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/agent_skills/prompt_builder.py +0 -0
  198. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/agent_skills/register_callbacks.py +0 -0
  199. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/agent_skills/remote_catalog.py +0 -0
  200. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/agent_skills/skill_catalog.py +0 -0
  201. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/agent_skills/skills_install_menu.py +0 -0
  202. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/agent_skills/skills_menu.py +0 -0
  203. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/chatgpt_oauth/__init__.py +0 -0
  204. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/chatgpt_oauth/config.py +0 -0
  205. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/chatgpt_oauth/oauth_flow.py +0 -0
  206. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/chatgpt_oauth/test_plugin.py +0 -0
  207. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/chatgpt_oauth/utils.py +0 -0
  208. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/claude_code_hooks/__init__.py +0 -0
  209. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/claude_code_hooks/config.py +0 -0
  210. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/claude_code_hooks/register_callbacks.py +0 -0
  211. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/claude_code_oauth/__init__.py +0 -0
  212. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/claude_code_oauth/config.py +0 -0
  213. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/claude_code_oauth/token_refresh_heartbeat.py +0 -0
  214. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/claude_code_oauth/utils.py +0 -0
  215. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/customizable_commands/__init__.py +0 -0
  216. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/customizable_commands/register_callbacks.py +0 -0
  217. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/example_custom_command/README.md +0 -0
  218. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/example_custom_command/register_callbacks.py +0 -0
  219. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/file_permission_handler/__init__.py +0 -0
  220. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/file_permission_handler/register_callbacks.py +0 -0
  221. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/frontend_emitter/__init__.py +0 -0
  222. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/frontend_emitter/emitter.py +0 -0
  223. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/frontend_emitter/register_callbacks.py +0 -0
  224. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/hook_creator/__init__.py +0 -0
  225. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/hook_creator/register_callbacks.py +0 -0
  226. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/hook_manager/__init__.py +0 -0
  227. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/hook_manager/config.py +0 -0
  228. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/hook_manager/hooks_menu.py +0 -0
  229. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/hook_manager/register_callbacks.py +0 -0
  230. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/oauth_puppy_html.py +0 -0
  231. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/shell_safety/__init__.py +0 -0
  232. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/shell_safety/agent_shell_safety.py +0 -0
  233. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/shell_safety/command_cache.py +0 -0
  234. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/shell_safety/register_callbacks.py +0 -0
  235. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/synthetic_status/__init__.py +0 -0
  236. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/synthetic_status/register_callbacks.py +0 -0
  237. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/synthetic_status/status_api.py +0 -0
  238. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/universal_constructor/__init__.py +0 -0
  239. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/universal_constructor/models.py +0 -0
  240. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/universal_constructor/register_callbacks.py +0 -0
  241. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/universal_constructor/registry.py +0 -0
  242. {newcode-0.2.12 → newcode-0.3.2}/newcode/plugins/universal_constructor/sandbox.py +0 -0
  243. {newcode-0.2.12 → newcode-0.3.2}/newcode/pydantic_patches.py +0 -0
  244. {newcode-0.2.12 → newcode-0.3.2}/newcode/reopenable_async_client.py +0 -0
  245. {newcode-0.2.12 → newcode-0.3.2}/newcode/round_robin_model.py +0 -0
  246. {newcode-0.2.12 → newcode-0.3.2}/newcode/session_storage.py +0 -0
  247. {newcode-0.2.12 → newcode-0.3.2}/newcode/status_display.py +0 -0
  248. {newcode-0.2.12 → newcode-0.3.2}/newcode/summarization_agent.py +0 -0
  249. {newcode-0.2.12 → newcode-0.3.2}/newcode/terminal_utils.py +0 -0
  250. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/ask_user_question/__init__.py +0 -0
  251. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/ask_user_question/constants.py +0 -0
  252. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/ask_user_question/demo_tui.py +0 -0
  253. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/ask_user_question/handler.py +0 -0
  254. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/ask_user_question/models.py +0 -0
  255. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/ask_user_question/registration.py +0 -0
  256. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/ask_user_question/renderers.py +0 -0
  257. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/ask_user_question/terminal_ui.py +0 -0
  258. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/ask_user_question/theme.py +0 -0
  259. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/ask_user_question/tui_loop.py +0 -0
  260. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/browser/browser_workflows.py +0 -0
  261. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/browser/chromium_terminal_manager.py +0 -0
  262. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/browser/terminal_command_tools.py +0 -0
  263. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/browser/terminal_screenshot_tools.py +0 -0
  264. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/browser/terminal_tools.py +0 -0
  265. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/command_runner.py +0 -0
  266. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/common.py +0 -0
  267. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/display.py +0 -0
  268. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/file_modifications.py +0 -0
  269. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/file_operations.py +0 -0
  270. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/skills_tools.py +0 -0
  271. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/subagent_context.py +0 -0
  272. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/tools_content.py +0 -0
  273. {newcode-0.2.12 → newcode-0.3.2}/newcode/tools/universal_constructor.py +0 -0
  274. {newcode-0.2.12 → newcode-0.3.2}/newcode/uvx_detection.py +0 -0
  275. {newcode-0.2.12 → newcode-0.3.2}/newcode/version_checker.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: newcode
3
- Version: 0.2.12
3
+ Version: 0.3.2
4
4
  Summary: AI-powered code generation agent platform
5
5
  Project-URL: repository, https://github.com/janfeddersen-wq/new_code
6
6
  Project-URL: HomePage, https://github.com/janfeddersen-wq/new_code
@@ -34,6 +34,7 @@ Requires-Dist: ripgrep==14.1.0
34
34
  Requires-Dist: tenacity>=8.2.0
35
35
  Requires-Dist: termflow-md>=0.1.8
36
36
  Requires-Dist: typer>=0.12.0
37
+ Requires-Dist: websockets>=14.0
37
38
  Description-Content-Type: text/markdown
38
39
 
39
40
  # NewCode
@@ -0,0 +1,5 @@
1
+ """Retired agents that are no longer actively used but kept for reference.
2
+
3
+ These agents have been moved here from the main agents package.
4
+ They can still be imported directly if needed for backwards compatibility.
5
+ """
@@ -1,6 +1,6 @@
1
1
  """C99/C11 systems code reviewer agent."""
2
2
 
3
- from .base_agent import BaseAgent
3
+ from ..base_agent import BaseAgent
4
4
 
5
5
 
6
6
  class CReviewerAgent(BaseAgent):
@@ -1,6 +1,6 @@
1
1
  """General code review and security agent."""
2
2
 
3
- from .base_agent import BaseAgent
3
+ from ..base_agent import BaseAgent
4
4
 
5
5
 
6
6
  class CodeQualityReviewerAgent(BaseAgent):
@@ -1,4 +1,4 @@
1
- from .base_agent import BaseAgent
1
+ from ..base_agent import BaseAgent
2
2
 
3
3
 
4
4
  class CppReviewerAgent(BaseAgent):
@@ -8,7 +8,7 @@ from newcode.config import get_user_agents_directory
8
8
  from newcode.model_factory import ModelFactory
9
9
  from newcode.tools import get_available_tool_names
10
10
 
11
- from .base_agent import BaseAgent
11
+ from ..base_agent import BaseAgent
12
12
 
13
13
 
14
14
  class AgentCreatorAgent(BaseAgent):
@@ -1,6 +1,6 @@
1
1
  """Golang code reviewer agent."""
2
2
 
3
- from .base_agent import BaseAgent
3
+ from ..base_agent import BaseAgent
4
4
 
5
5
 
6
6
  class GolangReviewerAgent(BaseAgent):
@@ -1,6 +1,6 @@
1
1
  """JavaScript code reviewer agent."""
2
2
 
3
- from .base_agent import BaseAgent
3
+ from ..base_agent import BaseAgent
4
4
 
5
5
 
6
6
  class JavaScriptReviewerAgent(BaseAgent):
@@ -1,7 +1,7 @@
1
1
  """Orchestrator - The coordinator for parallel multi-agent workflows."""
2
2
 
3
- from .. import callbacks
4
- from .base_agent import BaseAgent
3
+ from ... import callbacks
4
+ from ..base_agent import BaseAgent
5
5
 
6
6
 
7
7
  class PackLeaderAgent(BaseAgent):
@@ -1,6 +1,6 @@
1
1
  """Python programmer agent for modern Python development."""
2
2
 
3
- from .base_agent import BaseAgent
3
+ from ..base_agent import BaseAgent
4
4
 
5
5
 
6
6
  class PythonProgrammerAgent(BaseAgent):
@@ -1,6 +1,6 @@
1
1
  """Python code reviewer agent."""
2
2
 
3
- from .base_agent import BaseAgent
3
+ from ..base_agent import BaseAgent
4
4
 
5
5
 
6
6
  class PythonReviewerAgent(BaseAgent):
@@ -1,6 +1,6 @@
1
1
  """QA Browser - Playwright-powered browser automation agent."""
2
2
 
3
- from .base_agent import BaseAgent
3
+ from ..base_agent import BaseAgent
4
4
 
5
5
 
6
6
  class QABrowserAgent(BaseAgent):
@@ -1,6 +1,6 @@
1
1
  """Quality assurance expert agent."""
2
2
 
3
- from .base_agent import BaseAgent
3
+ from ..base_agent import BaseAgent
4
4
 
5
5
 
6
6
  class QAExpertAgent(BaseAgent):
@@ -1,6 +1,6 @@
1
1
  """Security audit agent."""
2
2
 
3
- from .base_agent import BaseAgent
3
+ from ..base_agent import BaseAgent
4
4
 
5
5
 
6
6
  class SecurityAuditorAgent(BaseAgent):
@@ -1,6 +1,6 @@
1
1
  """Terminal QA Agent - Terminal and TUI application testing with visual analysis."""
2
2
 
3
- from .base_agent import BaseAgent
3
+ from ..base_agent import BaseAgent
4
4
 
5
5
 
6
6
  class TerminalQAAgent(BaseAgent):
@@ -1,6 +1,6 @@
1
1
  """TypeScript code reviewer agent."""
2
2
 
3
- from .base_agent import BaseAgent
3
+ from ..base_agent import BaseAgent
4
4
 
5
5
 
6
6
  class TypeScriptReviewerAgent(BaseAgent):
@@ -1,7 +1,7 @@
1
1
  """Prompt Reviewer Agent - Specializes in analyzing and reviewing prompt quality."""
2
2
 
3
- from .. import callbacks
4
- from .base_agent import BaseAgent
3
+ from ... import callbacks
4
+ from ..base_agent import BaseAgent
5
5
 
6
6
 
7
7
  class PromptReviewerAgent(BaseAgent):
@@ -13,6 +13,7 @@ from typing import Callable, Dict, Optional
13
13
  from playwright.async_api import Browser, BrowserContext, Page
14
14
 
15
15
  from newcode import config
16
+ from newcode.config import get_browser_chrome_path, get_browser_headless
16
17
  from newcode.messaging import emit_info, emit_success, emit_warning
17
18
 
18
19
  # Registry for custom browser types from plugins (e.g., Camoufox for stealth browsing)
@@ -121,11 +122,21 @@ class BrowserManager:
121
122
  self.session_id = session_id or "default"
122
123
  self.browser_type = browser_type # None means default Chromium
123
124
 
124
- # Default to headless=True (no browser spam during tests)
125
- # Override with BROWSER_HEADLESS=false to see the browser
126
- self.headless = os.getenv("BROWSER_HEADLESS", "true").lower() != "false"
125
+ # Determine headless mode with priority:
126
+ # 1. Environment variable BROWSER_HEADLESS (if set)
127
+ # 2. Config value from get_browser_headless() (defaults to False)
128
+ # 3. Default to False (visible browser) for better UX
129
+ env_headless = os.getenv("BROWSER_HEADLESS")
130
+ if env_headless is not None:
131
+ self.headless = env_headless.lower() != "false"
132
+ else:
133
+ self.headless = get_browser_headless() # From config, defaults to False
134
+
127
135
  self.homepage = "https://www.google.com"
128
136
 
137
+ # Custom Chrome executable path (if configured)
138
+ self.custom_chrome_path = get_browser_chrome_path()
139
+
129
140
  # Unique profile directory per session for browser state
130
141
  self.profile_dir = self._get_profile_directory()
131
142
 
@@ -183,11 +194,24 @@ class BrowserManager:
183
194
 
184
195
  emit_info(f"Using persistent profile: {self.profile_dir}")
185
196
 
197
+ # Check for custom Chrome path
198
+ if self.custom_chrome_path:
199
+ emit_info(f"Using custom Chrome executable: {self.custom_chrome_path}")
200
+
186
201
  pw = await async_playwright().start()
202
+
203
+ # Build launch options
204
+ launch_options = {
205
+ "user_data_dir": str(self.profile_dir),
206
+ "headless": self.headless,
207
+ }
208
+
209
+ # Add custom executable path if configured
210
+ if self.custom_chrome_path:
211
+ launch_options["executable_path"] = self.custom_chrome_path
212
+
187
213
  # Use persistent context directory for Chromium to preserve browser state
188
- context = await pw.chromium.launch_persistent_context(
189
- user_data_dir=str(self.profile_dir), headless=self.headless
190
- )
214
+ context = await pw.chromium.launch_persistent_context(**launch_options)
191
215
  self._context = context
192
216
  self._browser = context.browser
193
217
  self._initialized = True
@@ -0,0 +1,204 @@
1
+ """Browser Agent - Specialist for web browser automation."""
2
+
3
+ from .. import callbacks
4
+ from .base_agent import BaseAgent
5
+
6
+
7
+ class BrowserAgent(BaseAgent):
8
+ """Browser Agent - Specialist for web browser automation and interaction.
9
+
10
+ This agent provides comprehensive browser automation capabilities including
11
+ navigation, element interaction, form filling, screenshot analysis, and
12
+ workflow automation for repeatable tasks.
13
+
14
+ The agent requires Chrome/Chromium to be installed (auto-detected at startup).
15
+ """
16
+
17
+ @property
18
+ def name(self) -> str:
19
+ return "browser-agent"
20
+
21
+ @property
22
+ def display_name(self) -> str:
23
+ return "Browser Agent 🌐"
24
+
25
+ @property
26
+ def description(self) -> str:
27
+ return (
28
+ "Browser automation specialist for web navigation, element interaction, "
29
+ "form filling, screenshot analysis, and workflow automation. "
30
+ "Requires Chrome/Chromium (auto-detected)."
31
+ )
32
+
33
+ def get_available_tools(self) -> list[str]:
34
+ """Get the list of tools available to the Browser Agent."""
35
+ return [
36
+ # Agent Management
37
+ "list_agents",
38
+ "invoke_agent",
39
+ # File Operations
40
+ "list_files",
41
+ "read_file",
42
+ "grep",
43
+ # Shell Commands
44
+ "agent_run_shell_command",
45
+ # User Interaction
46
+ "ask_user_question",
47
+ # Browser Control
48
+ "browser_initialize",
49
+ "browser_close",
50
+ "browser_status",
51
+ "browser_new_page",
52
+ "browser_list_pages",
53
+ # Browser Navigation
54
+ "browser_navigate",
55
+ "browser_get_page_info",
56
+ "browser_go_back",
57
+ "browser_go_forward",
58
+ "browser_reload",
59
+ "browser_wait_for_load",
60
+ # Element Discovery
61
+ "browser_find_by_role",
62
+ "browser_find_by_text",
63
+ "browser_find_by_label",
64
+ "browser_find_by_placeholder",
65
+ "browser_find_by_test_id",
66
+ "browser_xpath_query",
67
+ "browser_find_buttons",
68
+ "browser_find_links",
69
+ # Element Interactions
70
+ "browser_click",
71
+ "browser_double_click",
72
+ "browser_hover",
73
+ "browser_set_text",
74
+ "browser_get_text",
75
+ "browser_get_value",
76
+ "browser_select_option",
77
+ "browser_check",
78
+ "browser_uncheck",
79
+ # Scripts & Advanced
80
+ "browser_execute_js",
81
+ "browser_scroll",
82
+ "browser_scroll_to_element",
83
+ "browser_set_viewport",
84
+ "browser_wait_for_element",
85
+ "browser_highlight_element",
86
+ "browser_clear_highlights",
87
+ # Screenshots
88
+ "browser_screenshot_analyze",
89
+ # Workflows
90
+ "browser_save_workflow",
91
+ "browser_list_workflows",
92
+ "browser_read_workflow",
93
+ ]
94
+
95
+ def get_system_prompt(self) -> str:
96
+ """Get the Browser Agent's full system prompt."""
97
+ result = """\
98
+ You are a Browser Agent specializing in web browser automation and interaction.
99
+
100
+ CAPABILITIES:
101
+ - Navigate to URLs and interact with web pages
102
+ - Find and interact with page elements (click, type, select, check/uncheck)
103
+ - Fill forms and submit data
104
+ - Execute JavaScript in the browser context
105
+ - Take screenshots and analyze page content visually
106
+ - Scroll pages and control viewport
107
+ - Create and run reusable workflows for repetitive tasks
108
+ - Wait for dynamic content to load
109
+
110
+ BROWSER AUTOMATION BEST PRACTICES:
111
+
112
+ 1. INITIALIZATION
113
+ - ALWAYS initialize the browser first with browser_initialize() before any operations
114
+ - Check browser_status() if unsure about current state
115
+ - The browser runs in visible mode by default (user can see automation)
116
+ - Close browser with browser_close() when done to free resources
117
+
118
+ 2. NAVIGATION
119
+ - Use browser_navigate() to go to URLs
120
+ - Wait for page load with browser_wait_for_load() after navigation
121
+ - Use browser_go_back(), browser_go_forward(), browser_reload() for history
122
+
123
+ 3. ELEMENT DISCOVERY
124
+ - Prefer semantic locators: browser_find_by_role(), browser_find_by_label()
125
+ - Use browser_find_by_text() for visible text content
126
+ - Use browser_find_by_placeholder() for input hints
127
+ - Use browser_find_by_test_id() for data-testid attributes
128
+ - Use browser_xpath_query() for complex queries
129
+ - Use browser_find_buttons() and browser_find_links() for quick discovery
130
+
131
+ 4. ELEMENT INTERACTION
132
+ - Always find elements before interacting with them
133
+ - Use browser_click() for buttons and links
134
+ - Use browser_set_text() to fill input fields (clears existing text)
135
+ - Use browser_select_option() for dropdowns
136
+ - Use browser_check() / browser_uncheck() for checkboxes
137
+ - Use browser_hover() for hover-triggered content
138
+ - Wait for elements with browser_wait_for_element() if needed
139
+
140
+ 5. VERIFICATION & DEBUGGING
141
+ - Take screenshots with browser_screenshot_analyze() to verify state
142
+ - Use browser_highlight_element() to visually confirm element location
143
+ - Use browser_get_page_info() to get current URL and title
144
+ - Use browser_get_text() and browser_get_value() to read element content
145
+ - Use browser_execute_js() for custom verification logic
146
+
147
+ 6. WORKFLOW AUTOMATION
148
+ - Save repetitive task sequences with browser_save_workflow()
149
+ - List available workflows with browser_list_workflows()
150
+ - Read workflow definitions with browser_read_workflow()
151
+ - Workflows capture: navigation, clicks, text input, waits, and screenshots
152
+
153
+ 7. RELIABILITY PATTERNS
154
+ - Wait for elements before interacting (browser_wait_for_element())
155
+ - Scroll elements into view with browser_scroll_to_element() if needed
156
+ - Handle dynamic content with appropriate waits
157
+ - Take screenshots after important actions to verify success
158
+ - Handle popups and overlays gracefully
159
+
160
+ 8. HEADLESS MODE
161
+ - By default, the browser runs with a visible window (headless=False)
162
+ - User can configure headless mode via browser_headless config setting
163
+ - Visible mode helps debugging but may briefly show browser window
164
+
165
+ IMPORTANT RULES:
166
+ - Initialize browser before any browser operations
167
+ - Find elements before interacting with them
168
+ - Use appropriate wait times for dynamic content
169
+ - Take screenshots to verify visual state
170
+ - Clean up by closing browser when done
171
+ - Handle errors gracefully - some elements may not exist
172
+ - Respect website terms of service and rate limits
173
+
174
+ If browser automation is not available (Chrome not installed), inform the user
175
+ to install Chrome or Chromium and ensure it's in the system PATH.
176
+
177
+ When given a browser task:
178
+ 1. Plan the automation sequence
179
+ 2. Initialize browser if needed
180
+ 3. Navigate to target URL
181
+ 4. Discover and interact with elements
182
+ 5. Verify results with screenshots
183
+ 6. Save workflows for reusable tasks
184
+ 7. Clean up resources when complete
185
+ """
186
+
187
+ prompt_additions = callbacks.on_load_prompt()
188
+ if len(prompt_additions):
189
+ result += "\n".join(prompt_additions)
190
+ return result
191
+
192
+ def is_available(self) -> bool:
193
+ """Check if the Browser Agent is available.
194
+
195
+ Returns:
196
+ True if Chrome/Chromium is installed, False otherwise.
197
+ """
198
+ # Import here to avoid circular imports at module load time
199
+ from newcode.tools.browser.chrome_detector import is_chrome_available
200
+
201
+ try:
202
+ return is_chrome_available()
203
+ except Exception:
204
+ return False
@@ -339,8 +339,10 @@ def get_available_agents() -> Dict[str, str]:
339
339
  Dict mapping agent names to display names.
340
340
  """
341
341
  from ..config import (
342
+ BROWSER_AGENT_NAMES,
342
343
  PACK_AGENT_NAMES,
343
344
  UC_AGENT_NAMES,
345
+ get_browser_agent_enabled,
344
346
  get_pack_agents_enabled,
345
347
  get_universal_constructor_enabled,
346
348
  )
@@ -355,6 +357,9 @@ def get_available_agents() -> Dict[str, str]:
355
357
  # Check if UC is enabled
356
358
  uc_enabled = get_universal_constructor_enabled()
357
359
 
360
+ # Check if browser agent is enabled (Chrome available)
361
+ browser_agent_enabled = get_browser_agent_enabled()
362
+
358
363
  agents = {}
359
364
  for name, agent_ref in _AGENT_REGISTRY.items():
360
365
  # Filter out pack agents if disabled
@@ -365,6 +370,10 @@ def get_available_agents() -> Dict[str, str]:
365
370
  if not uc_enabled and name in UC_AGENT_NAMES:
366
371
  continue
367
372
 
373
+ # Filter out browser agent if Chrome not available
374
+ if not browser_agent_enabled and name in BROWSER_AGENT_NAMES:
375
+ continue
376
+
368
377
  try:
369
378
  if isinstance(agent_ref, str): # JSON agent (file path)
370
379
  agent_instance = JSONAgent(agent_ref)
@@ -491,8 +500,10 @@ def get_agent_descriptions() -> Dict[str, str]:
491
500
  Dict mapping agent names to their descriptions.
492
501
  """
493
502
  from ..config import (
503
+ BROWSER_AGENT_NAMES,
494
504
  PACK_AGENT_NAMES,
495
505
  UC_AGENT_NAMES,
506
+ get_browser_agent_enabled,
496
507
  get_pack_agents_enabled,
497
508
  get_universal_constructor_enabled,
498
509
  )
@@ -507,6 +518,9 @@ def get_agent_descriptions() -> Dict[str, str]:
507
518
  # Check if UC is enabled
508
519
  uc_enabled = get_universal_constructor_enabled()
509
520
 
521
+ # Check if browser agent is enabled (Chrome available)
522
+ browser_agent_enabled = get_browser_agent_enabled()
523
+
510
524
  descriptions = {}
511
525
  for name, agent_ref in _AGENT_REGISTRY.items():
512
526
  # Filter out pack agents if disabled
@@ -517,6 +531,10 @@ def get_agent_descriptions() -> Dict[str, str]:
517
531
  if not uc_enabled and name in UC_AGENT_NAMES:
518
532
  continue
519
533
 
534
+ # Filter out browser agent if Chrome not available
535
+ if not browser_agent_enabled and name in BROWSER_AGENT_NAMES:
536
+ continue
537
+
520
538
  try:
521
539
  if isinstance(agent_ref, str): # JSON agent (file path)
522
540
  agent_instance = JSONAgent(agent_ref)
@@ -501,7 +501,7 @@ class BaseAgent(ABC):
501
501
 
502
502
  # 1. Estimate tokens for system prompt / instructions
503
503
  # Use prepare_prompt_for_model() to get the correct instructions for token counting.
504
- # For models that prepend system prompt to user message (claude-code, antigravity),
504
+ # For models that prepend system prompt to user message (e.g. claude-code),
505
505
  # this returns the short fixed instructions. For other models, returns full prompt.
506
506
  try:
507
507
  from newcode.model_utils import prepare_prompt_for_model
@@ -414,7 +414,7 @@ def on_register_model_types() -> List[Dict[str, Any]]:
414
414
 
415
415
  This hook allows plugins to register custom model types that can be used
416
416
  in model configurations. Each callback should return a list of dicts with:
417
- - "type": str - the model type name (e.g., "antigravity", "claude_code")
417
+ - "type": str - the model type name (e.g., "claude_code")
418
418
  - "handler": callable - function(model_name, model_config, config) -> model instance
419
419
 
420
420
  The handler function receives:
@@ -431,7 +431,7 @@ def on_register_model_types() -> List[Dict[str, Any]]:
431
431
  "handler": create_my_custom_model,
432
432
  }]
433
433
 
434
- Example return: [{"type": "antigravity", "handler": create_antigravity_model}]
434
+ Example return: [{"type": "my_custom_type", "handler": create_my_model}]
435
435
  """
436
436
  return _trigger_callbacks_sync("register_model_type")
437
437
 
@@ -442,7 +442,7 @@ def on_get_model_system_prompt(
442
442
  """Allow plugins to provide custom system prompts for specific model types.
443
443
 
444
444
  This hook allows plugins to override the system prompt handling for custom
445
- model types (like claude_code or antigravity models). Each callback receives
445
+ model types (like claude_code models). Each callback receives
446
446
  the model name and should return a dict if it handles that model type, or None.
447
447
 
448
448
  Args:
@@ -40,7 +40,6 @@ from newcode.terminal_utils import (
40
40
  reset_windows_terminal_ansi,
41
41
  reset_windows_terminal_full,
42
42
  )
43
- from newcode.tools.common import console
44
43
  from newcode.version_checker import default_version_mismatch_behavior
45
44
 
46
45
  plugins.load_plugin_callbacks()
@@ -146,6 +145,40 @@ async def main():
146
145
 
147
146
  ensure_config_exists()
148
147
 
148
+ # Detect browser availability and update browser agent status
149
+ from newcode.config import (
150
+ get_browser_headless,
151
+ refresh_browser_agent_status,
152
+ )
153
+ from newcode.tools.browser.chrome_detector import (
154
+ get_chrome_info,
155
+ )
156
+
157
+ chrome_available = refresh_browser_agent_status()
158
+ if not chrome_available:
159
+ from newcode.messaging import emit_warning
160
+
161
+ emit_warning(
162
+ "⚠️ Chrome/Chromium not found. Browser automation tools are disabled.\n"
163
+ " Install Chrome/Chromium or run 'playwright install chromium' to enable browser-agent."
164
+ )
165
+ else:
166
+ # Show Chrome detection info
167
+ chrome_info = get_chrome_info()
168
+ chrome_path = chrome_info.get("path", "unknown")
169
+ chrome_version = chrome_info.get("version", "unknown")
170
+ is_playwright = chrome_info.get("is_playwright", False)
171
+
172
+ source = "Playwright bundled" if is_playwright else "System"
173
+ emit_info(f"✓ Chrome detected ({source}): {chrome_path} (v{chrome_version})")
174
+
175
+ # Show headless mode status
176
+ headless = get_browser_headless()
177
+ if headless:
178
+ emit_info(" Browser headless mode: enabled (no visible window)")
179
+ else:
180
+ emit_info(" Browser headless mode: disabled (visible window)")
181
+
149
182
  # Validate cancel_agent_key configuration early
150
183
  try:
151
184
  validate_cancel_agent_key()
@@ -301,14 +334,15 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
301
334
  from newcode.messaging import emit_info, emit_system_message
302
335
 
303
336
  emit_system_message("Type /help for commands and shortcuts.")
304
- try:
305
- from newcode.command_line.motd import print_motd
306
-
307
- print_motd(console, force=False)
308
- except Exception as e:
309
- from newcode.messaging import emit_warning
310
-
311
- emit_warning(f"MOTD error: {e}")
337
+ # MOTD display on startup disabled
338
+ # try:
339
+ # from newcode.command_line.motd import print_motd
340
+ #
341
+ # print_motd(console, force=False)
342
+ # except Exception as e:
343
+ # from newcode.messaging import emit_warning
344
+ #
345
+ # emit_warning(f"MOTD error: {e}")
312
346
 
313
347
  # Print truecolor warning LAST so it's the most visible thing on startup
314
348
  # Big ugly red box should be impossible to miss! 🔴
@@ -403,6 +437,7 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
403
437
  if should_show_onboarding():
404
438
  import concurrent.futures
405
439
 
440
+ from newcode.command_line.core_commands import _run_firepass_setup_flow
406
441
  from newcode.command_line.onboarding_wizard import run_onboarding_wizard
407
442
  from newcode.config import set_model_name
408
443
  from newcode.messaging import emit_info
@@ -416,7 +451,7 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
416
451
  from newcode.plugins.chatgpt_oauth.oauth_flow import run_oauth_flow
417
452
 
418
453
  run_oauth_flow()
419
- set_model_name("chatgpt-gpt-5.3-codex")
454
+ set_model_name("chatgpt-gpt-5.4")
420
455
  elif result == "claude":
421
456
  emit_info("🔐 Starting Claude Code OAuth flow...")
422
457
  from newcode.plugins.claude_code_oauth.register_callbacks import (
@@ -425,6 +460,8 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
425
460
 
426
461
  _perform_authentication()
427
462
  set_model_name("claude-code-claude-opus-4-6")
463
+ elif result == "firepass":
464
+ _run_firepass_setup_flow()
428
465
  elif result == "completed":
429
466
  emit_info("🎉 Tutorial complete! Happy coding!")
430
467
  elif result == "skipped":