code-puppy 0.0.595__tar.gz → 0.0.596__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 (409) hide show
  1. {code_puppy-0.0.595 → code_puppy-0.0.596}/PKG-INFO +1 -1
  2. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/agent_qa_kitten.py +63 -22
  3. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/cli_runner.py +24 -9
  4. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/colors_menu.py +2 -0
  5. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/config.py +2 -0
  6. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/picker.py +1 -0
  7. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/__init__.py +13 -0
  8. code_puppy-0.0.596/code_puppy/tools/browser/browser_locator_resolver.py +70 -0
  9. code_puppy-0.0.596/code_puppy/tools/browser/browser_page_snapshot.py +148 -0
  10. code_puppy-0.0.596/code_puppy/tools/browser/browser_semantic_interactions.py +189 -0
  11. {code_puppy-0.0.595 → code_puppy-0.0.596}/pyproject.toml +1 -1
  12. {code_puppy-0.0.595 → code_puppy-0.0.596}/.gitignore +0 -0
  13. {code_puppy-0.0.595 → code_puppy-0.0.596}/LICENSE +0 -0
  14. {code_puppy-0.0.595 → code_puppy-0.0.596}/README.md +0 -0
  15. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/__init__.py +0 -0
  16. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/__main__.py +0 -0
  17. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/__init__.py +0 -0
  18. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_builder.py +0 -0
  19. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_compaction.py +0 -0
  20. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_diagnostics.py +0 -0
  21. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_history.py +0 -0
  22. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_key_listeners.py +0 -0
  23. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_non_streaming_render.py +0 -0
  24. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_run_signals.py +0 -0
  25. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_runtime.py +0 -0
  26. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_steer_processor.py +0 -0
  27. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/agent_code_puppy.py +0 -0
  28. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/agent_creator_agent.py +0 -0
  29. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/agent_helios.py +0 -0
  30. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/agent_manager.py +0 -0
  31. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/agent_planning.py +0 -0
  32. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/base_agent.py +0 -0
  33. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/event_stream_handler.py +0 -0
  34. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/json_agent.py +0 -0
  35. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/run_stats.py +0 -0
  36. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/smooth_stream.py +0 -0
  37. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/subagent_stream_handler.py +0 -0
  38. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/callbacks.py +0 -0
  39. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/chatgpt_codex_client.py +0 -0
  40. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/claude_cache_client.py +0 -0
  41. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/__init__.py +0 -0
  42. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/add_model_menu.py +0 -0
  43. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/agent_menu.py +0 -0
  44. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/attachments.py +0 -0
  45. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/autosave_menu.py +0 -0
  46. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/autosave_search.py +0 -0
  47. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/clipboard.py +0 -0
  48. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/command_handler.py +0 -0
  49. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/command_registry.py +0 -0
  50. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/config_apply.py +0 -0
  51. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/config_commands.py +0 -0
  52. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/core_commands.py +0 -0
  53. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/diff_menu.py +0 -0
  54. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/file_index.py +0 -0
  55. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/file_path_completion.py +0 -0
  56. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/judges_menu.py +0 -0
  57. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/load_context_completion.py +0 -0
  58. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/__init__.py +0 -0
  59. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/base.py +0 -0
  60. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/catalog_server_installer.py +0 -0
  61. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/custom_server_form.py +0 -0
  62. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/custom_server_installer.py +0 -0
  63. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/edit_command.py +0 -0
  64. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/handler.py +0 -0
  65. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/help_command.py +0 -0
  66. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/install_command.py +0 -0
  67. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/install_menu.py +0 -0
  68. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/list_command.py +0 -0
  69. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/logs_command.py +0 -0
  70. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/remove_command.py +0 -0
  71. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/restart_command.py +0 -0
  72. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/search_command.py +0 -0
  73. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/silence_warning_command.py +0 -0
  74. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/start_all_command.py +0 -0
  75. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/start_command.py +0 -0
  76. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/status_command.py +0 -0
  77. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/stop_all_command.py +0 -0
  78. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/stop_command.py +0 -0
  79. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/utils.py +0 -0
  80. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/wizard_utils.py +0 -0
  81. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp_binding_menu.py +0 -0
  82. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp_completion.py +0 -0
  83. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/model_picker_completion.py +0 -0
  84. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/model_settings_menu.py +0 -0
  85. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/onboarding_slides.py +0 -0
  86. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/onboarding_wizard.py +0 -0
  87. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/pagination.py +0 -0
  88. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/pin_command_completion.py +0 -0
  89. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/prompt_toolkit_completion.py +0 -0
  90. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/session_commands.py +0 -0
  91. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/set_menu.py +0 -0
  92. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/set_menu_catalog.py +0 -0
  93. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/set_menu_render.py +0 -0
  94. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/set_menu_schema.py +0 -0
  95. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/set_menu_settings.py +0 -0
  96. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/set_menu_shims.py +0 -0
  97. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/set_menu_values.py +0 -0
  98. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/shell_passthrough.py +0 -0
  99. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/skills_completion.py +0 -0
  100. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/uc_menu.py +0 -0
  101. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/utils.py +0 -0
  102. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/wiggum_state.py +0 -0
  103. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/error_logging.py +0 -0
  104. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/gemini_code_assist.py +0 -0
  105. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/gemini_model.py +0 -0
  106. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/README.md +0 -0
  107. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/__init__.py +0 -0
  108. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/aliases.py +0 -0
  109. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/engine.py +0 -0
  110. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/executor.py +0 -0
  111. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/matcher.py +0 -0
  112. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/models.py +0 -0
  113. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/registry.py +0 -0
  114. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/validator.py +0 -0
  115. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/http_utils.py +0 -0
  116. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/keymap.py +0 -0
  117. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/list_filtering.py +0 -0
  118. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/main.py +0 -0
  119. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/__init__.py +0 -0
  120. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/agent_bindings.py +0 -0
  121. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/async_lifecycle.py +0 -0
  122. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/blocking_startup.py +0 -0
  123. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/captured_stdio_server.py +0 -0
  124. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/circuit_breaker.py +0 -0
  125. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/config_wizard.py +0 -0
  126. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/dashboard.py +0 -0
  127. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/error_isolation.py +0 -0
  128. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/examples/retry_example.py +0 -0
  129. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/health_monitor.py +0 -0
  130. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/managed_server.py +0 -0
  131. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/manager.py +0 -0
  132. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/mcp_logs.py +0 -0
  133. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/registry.py +0 -0
  134. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/retry_manager.py +0 -0
  135. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/server_registry_catalog.py +0 -0
  136. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/status_tracker.py +0 -0
  137. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/system_tools.py +0 -0
  138. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/tool_arg_coercion.py +0 -0
  139. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_prompts/__init__.py +0 -0
  140. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_prompts/hook_creator.py +0 -0
  141. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/__init__.py +0 -0
  142. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/bar_painters.py +0 -0
  143. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/bar_rendering.py +0 -0
  144. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/bottom_bar.py +0 -0
  145. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/bus.py +0 -0
  146. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/commands.py +0 -0
  147. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/editor_actions.py +0 -0
  148. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/editor_completion.py +0 -0
  149. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/editor_display.py +0 -0
  150. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/editor_history.py +0 -0
  151. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/editor_keys.py +0 -0
  152. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/editor_paste.py +0 -0
  153. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/line_editor.py +0 -0
  154. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/markdown_patches.py +0 -0
  155. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/message_queue.py +0 -0
  156. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/messages.py +0 -0
  157. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/pause_controller.py +0 -0
  158. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/prompt_prefix_style.py +0 -0
  159. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/queue_console.py +0 -0
  160. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/renderers.py +0 -0
  161. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/rich_renderer.py +0 -0
  162. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/run_ui.py +0 -0
  163. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/run_ui_wiring.py +0 -0
  164. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/spinner/__init__.py +0 -0
  165. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/subagent_console.py +0 -0
  166. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/model_descriptions.py +0 -0
  167. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/model_factory.py +0 -0
  168. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/model_switching.py +0 -0
  169. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/model_utils.py +0 -0
  170. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/models.json +0 -0
  171. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/models_dev_api.json +0 -0
  172. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/models_dev_parser.py +0 -0
  173. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/__init__.py +0 -0
  174. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/__init__.py +0 -0
  175. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/config.py +0 -0
  176. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/discovery.py +0 -0
  177. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/downloader.py +0 -0
  178. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/enabled_skills.py +0 -0
  179. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/installer.py +0 -0
  180. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/metadata.py +0 -0
  181. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/prompt_builder.py +0 -0
  182. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/register_callbacks.py +0 -0
  183. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/remote_catalog.py +0 -0
  184. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/skill_catalog.py +0 -0
  185. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/skill_commands.py +0 -0
  186. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/skills_install_menu.py +0 -0
  187. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/skills_menu.py +0 -0
  188. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/aws_bedrock/__init__.py +0 -0
  189. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/aws_bedrock/config.py +0 -0
  190. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/aws_bedrock/register_callbacks.py +0 -0
  191. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/aws_bedrock/utils.py +0 -0
  192. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/azure_foundry/README.md +0 -0
  193. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/azure_foundry/__init__.py +0 -0
  194. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/azure_foundry/config.py +0 -0
  195. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/azure_foundry/discovery.py +0 -0
  196. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/azure_foundry/register_callbacks.py +0 -0
  197. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/azure_foundry/token.py +0 -0
  198. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/azure_foundry/utils.py +0 -0
  199. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/btw/__init__.py +0 -0
  200. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/btw/inline_view.py +0 -0
  201. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/btw/register_callbacks.py +0 -0
  202. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/btw/side_query.py +0 -0
  203. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/chatgpt_oauth/__init__.py +0 -0
  204. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/chatgpt_oauth/config.py +0 -0
  205. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/chatgpt_oauth/oauth_flow.py +0 -0
  206. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/chatgpt_oauth/register_callbacks.py +0 -0
  207. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/chatgpt_oauth/test_plugin.py +0 -0
  208. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/chatgpt_oauth/utils.py +0 -0
  209. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_hooks/__init__.py +0 -0
  210. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_hooks/config.py +0 -0
  211. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_hooks/register_callbacks.py +0 -0
  212. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/README.md +0 -0
  213. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/SETUP.md +0 -0
  214. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/__init__.py +0 -0
  215. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/config.py +0 -0
  216. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/fast_mode.py +0 -0
  217. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/prompt_handler.py +0 -0
  218. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/register_callbacks.py +0 -0
  219. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/test_fast_mode.py +0 -0
  220. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/test_plugin.py +0 -0
  221. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/token_refresh_heartbeat.py +0 -0
  222. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/utils.py +0 -0
  223. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/code_puppy_agent/SKILL.md +0 -0
  224. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/code_puppy_agent/__init__.py +0 -0
  225. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/code_puppy_agent/register_callbacks.py +0 -0
  226. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/config.py +0 -0
  227. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/context_indicator/__init__.py +0 -0
  228. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/context_indicator/register_callbacks.py +0 -0
  229. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/context_indicator/usage.py +0 -0
  230. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/copilot_auth/__init__.py +0 -0
  231. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/copilot_auth/config.py +0 -0
  232. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/copilot_auth/reasoning_client.py +0 -0
  233. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/copilot_auth/register_callbacks.py +0 -0
  234. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/copilot_auth/utils.py +0 -0
  235. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/customizable_commands/__init__.py +0 -0
  236. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/customizable_commands/register_callbacks.py +0 -0
  237. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/__init__.py +0 -0
  238. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/cancel.py +0 -0
  239. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/commands.py +0 -0
  240. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/config.py +0 -0
  241. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/lifecycle.py +0 -0
  242. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/register_callbacks.py +0 -0
  243. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/runtime.py +0 -0
  244. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/startup_lock.py +0 -0
  245. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/workflow_ids.py +0 -0
  246. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/wrapper.py +0 -0
  247. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/destructive_command_guard/__init__.py +0 -0
  248. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/destructive_command_guard/detector.py +0 -0
  249. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/destructive_command_guard/register_callbacks.py +0 -0
  250. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/emoji_filter/__init__.py +0 -0
  251. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/emoji_filter/config.py +0 -0
  252. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/emoji_filter/register_callbacks.py +0 -0
  253. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/emoji_filter/stripper.py +0 -0
  254. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/example_custom_command/README.md +0 -0
  255. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/example_custom_command/register_callbacks.py +0 -0
  256. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/file_permission_handler/__init__.py +0 -0
  257. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/file_permission_handler/register_callbacks.py +0 -0
  258. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/force_push_guard/__init__.py +0 -0
  259. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/force_push_guard/detector.py +0 -0
  260. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/force_push_guard/register_callbacks.py +0 -0
  261. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/force_push_guard/test_detector.py +0 -0
  262. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/frontend_emitter/__init__.py +0 -0
  263. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/frontend_emitter/emitter.py +0 -0
  264. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/frontend_emitter/register_callbacks.py +0 -0
  265. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/frontend_emitter/session_context.py +0 -0
  266. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/hook_creator/__init__.py +0 -0
  267. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/hook_creator/register_callbacks.py +0 -0
  268. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/hook_manager/__init__.py +0 -0
  269. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/hook_manager/config.py +0 -0
  270. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/hook_manager/hooks_menu.py +0 -0
  271. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/hook_manager/register_callbacks.py +0 -0
  272. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/oauth_puppy_html.py +0 -0
  273. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/obsidian_agent/README.md +0 -0
  274. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/obsidian_agent/__init__.py +0 -0
  275. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/obsidian_agent/agent_obsidian.py +0 -0
  276. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/obsidian_agent/register_callbacks.py +0 -0
  277. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/ollama/__init__.py +0 -0
  278. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/ollama/register_callbacks.py +0 -0
  279. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/ollama_setup/__init__.py +0 -0
  280. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/ollama_setup/completer.py +0 -0
  281. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/ollama_setup/register_callbacks.py +0 -0
  282. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/plugin_list/__init__.py +0 -0
  283. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/plugin_list/plugin_contributions.py +0 -0
  284. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/plugin_list/plugin_meta.py +0 -0
  285. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/plugin_list/plugin_text_utils.py +0 -0
  286. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/plugin_list/plugins_menu.py +0 -0
  287. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/plugin_list/plugins_menu_render.py +0 -0
  288. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/plugin_list/register_callbacks.py +0 -0
  289. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/pop_command/__init__.py +0 -0
  290. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/pop_command/register_callbacks.py +0 -0
  291. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/prompt_newline/__init__.py +0 -0
  292. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/prompt_newline/config.py +0 -0
  293. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/prompt_newline/register_callbacks.py +0 -0
  294. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/prune/__init__.py +0 -0
  295. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/prune/prune_menu.py +0 -0
  296. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/prune/prune_model.py +0 -0
  297. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/prune/prune_render.py +0 -0
  298. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/prune/register_callbacks.py +0 -0
  299. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/README.md +0 -0
  300. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/__init__.py +0 -0
  301. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/commands.py +0 -0
  302. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/config.py +0 -0
  303. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/kennel.py +0 -0
  304. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/packer.py +0 -0
  305. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/recorder.py +0 -0
  306. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/register_callbacks.py +0 -0
  307. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/retriever.py +0 -0
  308. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/schema.py +0 -0
  309. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/state.py +0 -0
  310. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/tools.py +0 -0
  311. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/wings.py +0 -0
  312. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_spinner/__init__.py +0 -0
  313. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_spinner/register_callbacks.py +0 -0
  314. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/quick_resume/__init__.py +0 -0
  315. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/quick_resume/register_callbacks.py +0 -0
  316. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/review_pr/__init__.py +0 -0
  317. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/review_pr/register_callbacks.py +0 -0
  318. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/shell_safety/__init__.py +0 -0
  319. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/shell_safety/agent_shell_safety.py +0 -0
  320. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/shell_safety/command_cache.py +0 -0
  321. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/shell_safety/register_callbacks.py +0 -0
  322. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/statusline/__init__.py +0 -0
  323. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/statusline/config.py +0 -0
  324. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/statusline/payload.py +0 -0
  325. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/statusline/prompt_patch.py +0 -0
  326. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/statusline/register_callbacks.py +0 -0
  327. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/statusline/runner.py +0 -0
  328. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/statusline/statusline_command.py +0 -0
  329. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/steer_queue/__init__.py +0 -0
  330. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/steer_queue/queue_menu.py +0 -0
  331. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/steer_queue/register_callbacks.py +0 -0
  332. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/subagent_panel/README.md +0 -0
  333. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/subagent_panel/__init__.py +0 -0
  334. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/subagent_panel/coalesce_patch.py +0 -0
  335. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/subagent_panel/panel_render.py +0 -0
  336. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/subagent_panel/register_callbacks.py +0 -0
  337. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/subagent_panel/resume_repaint.py +0 -0
  338. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/subagent_panel/state.py +0 -0
  339. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/switch_agent_resume/__init__.py +0 -0
  340. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/switch_agent_resume/register_callbacks.py +0 -0
  341. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/README.md +0 -0
  342. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/__init__.py +0 -0
  343. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/bundled_palettes.py +0 -0
  344. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/content_styles.py +0 -0
  345. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/osc_palette.py +0 -0
  346. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/register_callbacks.py +0 -0
  347. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/rich_themes.py +0 -0
  348. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/themes.py +0 -0
  349. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/token_ratio_learner/__init__.py +0 -0
  350. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/token_ratio_learner/ratios.py +0 -0
  351. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/token_ratio_learner/register_callbacks.py +0 -0
  352. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/universal_constructor/__init__.py +0 -0
  353. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/universal_constructor/models.py +0 -0
  354. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/universal_constructor/register_callbacks.py +0 -0
  355. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/universal_constructor/registry.py +0 -0
  356. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/universal_constructor/sandbox.py +0 -0
  357. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/wide_completion_menu/__init__.py +0 -0
  358. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/wide_completion_menu/register_callbacks.py +0 -0
  359. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/wiggum/__init__.py +0 -0
  360. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/wiggum/judge.py +0 -0
  361. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/wiggum/judge_config.py +0 -0
  362. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/wiggum/register_callbacks.py +0 -0
  363. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/wiggum/state.py +0 -0
  364. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/provider_credentials.py +0 -0
  365. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/provider_identity.py +0 -0
  366. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/pydantic_patches.py +0 -0
  367. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/reopenable_async_client.py +0 -0
  368. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/round_robin_model.py +0 -0
  369. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/session_lifecycle.py +0 -0
  370. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/session_migration.py +0 -0
  371. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/session_storage.py +0 -0
  372. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/status_display.py +0 -0
  373. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/summarization_agent.py +0 -0
  374. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/terminal_utils.py +0 -0
  375. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/agent_tools.py +0 -0
  376. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/__init__.py +0 -0
  377. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/constants.py +0 -0
  378. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/demo_tui.py +0 -0
  379. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/handler.py +0 -0
  380. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/models.py +0 -0
  381. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/registration.py +0 -0
  382. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/renderers.py +0 -0
  383. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/terminal_ui.py +0 -0
  384. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/theme.py +0 -0
  385. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/tui_loop.py +0 -0
  386. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/__init__.py +0 -0
  387. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/browser_control.py +0 -0
  388. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/browser_interactions.py +0 -0
  389. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/browser_locators.py +0 -0
  390. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/browser_manager.py +0 -0
  391. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/browser_navigation.py +0 -0
  392. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/browser_screenshot.py +0 -0
  393. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/browser_scripts.py +0 -0
  394. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/browser_workflows.py +0 -0
  395. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/command_runner.py +0 -0
  396. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/common.py +0 -0
  397. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/display.py +0 -0
  398. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/file_modifications.py +0 -0
  399. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/file_operations.py +0 -0
  400. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/image_tools.py +0 -0
  401. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/model_tools.py +0 -0
  402. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/skills_tools.py +0 -0
  403. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/subagent_context.py +0 -0
  404. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/subagent_invocation.py +0 -0
  405. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/tools_content.py +0 -0
  406. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/universal_constructor.py +0 -0
  407. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/undo_manager.py +0 -0
  408. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/uvx_detection.py +0 -0
  409. {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/version_checker.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-puppy
3
- Version: 0.0.595
3
+ Version: 0.0.596
4
4
  Summary: Code generation agent
5
5
  Project-URL: repository, https://github.com/mpfaffenberger/code_puppy
6
6
  Project-URL: HomePage, https://github.com/mpfaffenberger/code_puppy
@@ -35,6 +35,8 @@ class QualityAssuranceKittenAgent(BaseAgent):
35
35
  "browser_go_forward",
36
36
  "browser_reload",
37
37
  "browser_wait_for_load",
38
+ # Page state (DOM-first progression, PREFERRED for non-visual steps)
39
+ "browser_page_snapshot",
38
40
  # Element discovery (semantic locators preferred)
39
41
  "browser_find_by_role",
40
42
  "browser_find_by_text",
@@ -44,6 +46,10 @@ class QualityAssuranceKittenAgent(BaseAgent):
44
46
  "browser_find_buttons",
45
47
  "browser_find_links",
46
48
  "browser_xpath_query", # Fallback when semantic locators fail
49
+ # Semantic interactions (accessibility-first, PREFERRED for progression)
50
+ "browser_click_by_role",
51
+ "browser_click_by_text",
52
+ "browser_set_text_by_label",
47
53
  # Element interactions
48
54
  "browser_click",
49
55
  "browser_double_click",
@@ -84,6 +90,36 @@ You specialize in:
84
90
  🧪 **Web automation** - filling forms, clicking buttons, navigating sites with precision
85
91
  🐛 **Bug detection** - identifying UI issues, broken functionality, and accessibility problems
86
92
 
93
+ ## DOM-First Progression vs Visual Validation (READ THIS FIRST)
94
+
95
+ Every step you take is one of two kinds. Classify it before you act:
96
+
97
+ **1. Functional / progression steps** (the default) - clicking through a
98
+ flow, filling forms, navigating, checking that an action "worked" or that
99
+ the page reached the expected state.
100
+ - **PREFER DOM/text/accessibility locators and Playwright-style events.**
101
+ - Use `browser_page_snapshot` to read page state cheaply, and the semantic
102
+ action tools (`browser_click_by_role`, `browser_click_by_text`,
103
+ `browser_set_text_by_label`) plus the `browser_find_by_*` locators.
104
+ - **Validate success via the DOM**: URL, title, visible text, element
105
+ values, checked state, ARIA attributes - NOT screenshots.
106
+ - **Do NOT take a screenshot just to decide whether an action progressed.**
107
+ Screenshots are fragile here: window moves, resizes, external monitors,
108
+ and harmless visual diffs cause false failures, and they're slow/expensive.
109
+
110
+ **2. Visual / UX-UI validation steps** - rendering, layout, spacing,
111
+ color, occlusion/overlap, responsive behavior, visual diffs, or comparison
112
+ against a mockup/reference.
113
+ - **THIS is when screenshots earn their keep.** Use
114
+ `browser_screenshot_analyze` and `load_image_for_analysis` freely.
115
+
116
+ **Fallback rule:** If DOM-first strategies genuinely fail (element truly
117
+ not locatable semantically), you may fall back to a screenshot to
118
+ diagnose - but say so explicitly.
119
+
120
+ **Always report which mode you used** ("DOM-first" or "visual fallback")
121
+ when you describe a step or a failure, so problems are easy to diagnose.
122
+
87
123
  ## Core Workflow Philosophy
88
124
 
89
125
  For any browser task, follow this approach:
@@ -92,10 +128,10 @@ For any browser task, follow this approach:
92
128
  3. **Plan & Reason**: Break down complex tasks and explain your approach clearly
93
129
  4. **Initialize**: Always start with browser_initialize if browser isn't running
94
130
  5. **Navigate**: Use browser_navigate to reach the target page
95
- 6. **Discover**: Use semantic locators (PREFERRED) for element discovery
96
- 7. **Verify**: Use highlighting and screenshots to confirm elements
97
- 8. **Act**: Interact with elements through clicks, typing, etc.
98
- 9. **Validate**: Take screenshots or query DOM to verify actions worked
131
+ 6. **Discover**: Use `browser_page_snapshot` and semantic locators (PREFERRED) for element discovery
132
+ 7. **Verify**: Confirm the target via DOM state; reserve highlighting/screenshots for visual checks
133
+ 8. **Act**: Interact via semantic actions (click_by_role/text, set_text_by_label) or selector clicks/typing
134
+ 9. **Validate**: Query the DOM (snapshot/URL/text/value) to verify actions worked; screenshot only for visual assertions
99
135
  10. **Document Success**: Use browser_save_workflow to save successful patterns for future reuse
100
136
 
101
137
  ## Tool Usage Guidelines
@@ -108,17 +144,18 @@ For any browser task, follow this approach:
108
144
  ### Element Discovery Best Practices (ACCESSIBILITY FIRST! 🌟)
109
145
  - **PREFER semantic locators** - they're more reliable and follow accessibility standards
110
146
  - Priority order:
111
- 1. browser_find_by_role (button, link, textbox, heading, etc.)
112
- 2. browser_find_by_label (for form inputs)
113
- 3. browser_find_by_text (for visible text)
114
- 4. browser_find_by_placeholder (for input hints)
115
- 5. browser_find_by_test_id (for test-friendly elements)
116
- 6. browser_xpath_query (ONLY as last resort)
117
-
118
- ### Visual Verification Workflow
119
- - **Before critical actions**: Use browser_highlight_element to visually confirm
120
- - **After interactions**: Use browser_screenshot_analyze to verify results
121
- - The screenshot is returned directly as an image you can see and analyze
147
+ 1. browser_page_snapshot (cheap structured overview of the whole page)
148
+ 2. browser_find_by_role (button, link, textbox, heading, etc.)
149
+ 3. browser_find_by_label (for form inputs)
150
+ 4. browser_find_by_text (for visible text)
151
+ 5. browser_find_by_placeholder (for input hints)
152
+ 6. browser_find_by_test_id (for test-friendly elements)
153
+ 7. browser_xpath_query (ONLY as last resort)
154
+
155
+ ### Visual Verification Workflow (VISUAL ASSERTIONS ONLY)
156
+ - Use screenshots for rendering, layout, color, occlusion, responsive, or mockup comparison - NOT to confirm functional progression
157
+ - **Before critical visual checks**: Use browser_highlight_element to visually confirm
158
+ - **For visual results**: Use browser_screenshot_analyze - returned directly as an image you can see and analyze
122
159
  - No need to ask questions - just analyze what you see in the returned image
123
160
  - Use load_image_for_analysis to load mockups or reference images for comparison
124
161
 
@@ -132,16 +169,18 @@ For any browser task, follow this approach:
132
169
 
133
170
  **When Element Discovery Fails:**
134
171
  1. Try different semantic locators first
135
- 2. Use browser_find_buttons or browser_find_links to see available elements
136
- 3. Take a screenshot with browser_screenshot_analyze to see and understand the page layout
137
- 4. Only use XPath as absolute last resort
172
+ 2. Call browser_page_snapshot to see all buttons/links/inputs/text at once
173
+ 3. Use browser_find_buttons or browser_find_links to see available elements
174
+ 4. Only take a screenshot (browser_screenshot_analyze) as a visual fallback - note that you fell back to visual
175
+ 5. Only use XPath as absolute last resort
138
176
 
139
177
  **When Page Interactions Fail:**
140
178
  1. Check if element is visible with browser_wait_for_element
141
179
  2. Scroll element into view with browser_scroll_to_element
142
- 3. Use browser_highlight_element to confirm element location
143
- 4. Take a screenshot with browser_screenshot_analyze to see the actual page state
144
- 5. Try browser_execute_js for complex interactions
180
+ 3. Re-check state with browser_page_snapshot (did the DOM change?)
181
+ 4. Use browser_highlight_element to confirm element location
182
+ 5. Take a screenshot with browser_screenshot_analyze only as a visual fallback - note that you fell back to visual
183
+ 6. Try browser_execute_js for complex interactions
145
184
 
146
185
  ### JavaScript Execution
147
186
  - Use browser_execute_js for:
@@ -197,7 +236,9 @@ For any browser task, follow this approach:
197
236
  - **ALWAYS use browser_initialize before any browser operations**
198
237
  - **ALWAYS close the browser at the end of every task** using browser_close
199
238
  - **PREFER semantic locators over XPath** - they're more maintainable and accessible
200
- - **Use visual verification for critical actions** - highlight elements and take screenshots
239
+ - **PREFER DOM-first progression over screenshots** - use browser_page_snapshot and DOM state to validate functional steps; reserve screenshots for visual assertions
240
+ - **Report your mode** - state whether a step used DOM-first or a visual fallback
241
+ - **Use visual verification for critical VISUAL actions** - highlight elements and take screenshots for layout/color/rendering checks
201
242
  - **Be explicit about your reasoning** for complex workflows
202
243
  - **Handle errors gracefully** - provide helpful debugging information
203
244
  - **Follow accessibility best practices** - your automation should work for everyone
@@ -625,6 +625,26 @@ def _persistent_prompt_parts() -> tuple:
625
625
  return ">>> ", []
626
626
 
627
627
 
628
+ def _user_prompt_echo(task: str):
629
+ """Transcript echo for a submitted prompt, banner-tagged.
630
+
631
+ The persistent editor clears its row on submit, so scrollback needs
632
+ a record of what was asked. A bare ``> `` marker looked like an
633
+ orphaned prompt row (especially on Windows); tag it like every other
634
+ transcript block (AGENT RESPONSE, SHELL COMMAND, ...) instead.
635
+ Built with ``Text`` (not markup) so bracket-y input renders as-is.
636
+ """
637
+ from rich.text import Text
638
+
639
+ from code_puppy.config import get_banner_color
640
+
641
+ color = get_banner_color("user_prompt")
642
+ echo = Text("\n")
643
+ echo.append(" USER ", style=f"bold white on {color}")
644
+ echo.append(f" {task}", style="bold")
645
+ return echo
646
+
647
+
628
648
  def _interactive_sigint_guard(_sig, _frame):
629
649
  """Baseline SIGINT handler for the interactive REPL.
630
650
 
@@ -857,8 +877,6 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
857
877
 
858
878
  try:
859
879
  if persistent_prompt:
860
- from rich.text import Text as _EchoText
861
-
862
880
  from code_puppy.messaging.run_ui import (
863
881
  set_idle_prompt_prefix,
864
882
  wait_for_idle_submission,
@@ -878,19 +896,16 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
878
896
  queued_task = _get_pc().pop_next_steer_queued()
879
897
  if queued_task is not None:
880
898
  task = queued_task
881
- emit_info(_EchoText(f"\n> {task}", style="bold"))
899
+ emit_info(_user_prompt_echo(task))
882
900
  emit_info("⏭ running queued prompt")
883
901
  else:
884
902
  # Raises EOFError on Ctrl+D-with-empty-buffer, which the
885
903
  # existing quit branch below handles.
886
904
  task = await wait_for_idle_submission()
887
- # Echo into the transcript: the editor clears its row
888
- # on submit, so scrollback needs the record of what was
889
- # asked. JUST the user's text (bold, '> ' marker) --
905
+ # Echo into the transcript (see _user_prompt_echo) --
890
906
  # repeating the whole prompt chrome doubled every
891
- # line's noise. Text() (not markup) so bracket-y input
892
- # renders as-is.
893
- emit_info(_EchoText(f"\n> {task}", style="bold"))
907
+ # line's noise, so it's just a tag + the user's text.
908
+ emit_info(_user_prompt_echo(task))
894
909
  else:
895
910
  # Use prompt_toolkit for enhanced input with path completion
896
911
  try:
@@ -38,6 +38,7 @@ BANNER_DISPLAY_INFO = {
38
38
  "universal_constructor": ("UNIVERSAL CONSTRUCTOR", "🔧"),
39
39
  "terminal_tool": ("TERMINAL TOOL", "🖥️"),
40
40
  "llm_judge": ("LLM JUDGE", "⚖️"),
41
+ "user_prompt": ("USER", "🧑"),
41
42
  }
42
43
 
43
44
  # Sample content to show after each banner
@@ -59,6 +60,7 @@ BANNER_SAMPLE_CONTENT = {
59
60
  "universal_constructor": "action=create tool_name=api.weather\n✅ Created successfully",
60
61
  "terminal_tool": "$ chromium --headless\nBrowser terminal session started",
61
62
  "llm_judge": "🎯 Verdict: Complete ✅\nGoal verified — all tests pass.",
63
+ "user_prompt": "Fix the flaky test in tests/test_api.py",
62
64
  }
63
65
 
64
66
  # Available background colors grouped by theme
@@ -1701,6 +1701,8 @@ DEFAULT_BANNER_COLORS = {
1701
1701
  "shell_passthrough": "medium_sea_green", # Green - user's own shell commands
1702
1702
  # LLM Judge - goal-mode verdict (distinct from agent reasoning)
1703
1703
  "llm_judge": "gold3", # Gold - judicial authority / gavel
1704
+ # Transcript echo of the user's submitted prompt (persistent prompt path)
1705
+ "user_prompt": "dark_green", # Green - the human speaks
1704
1706
  }
1705
1707
 
1706
1708
 
@@ -37,6 +37,7 @@ from .themes import (
37
37
 
38
38
  # A few representative banners to show in the preview pane (keeps it readable).
39
39
  PREVIEW_BANNERS = [
40
+ "user_prompt",
40
41
  "thinking",
41
42
  "agent_response",
42
43
  "shell_command",
@@ -36,6 +36,14 @@ from code_puppy.tools.browser.browser_locators import (
36
36
  register_find_links,
37
37
  register_run_xpath_query,
38
38
  )
39
+ from code_puppy.tools.browser.browser_page_snapshot import (
40
+ register_get_page_snapshot,
41
+ )
42
+ from code_puppy.tools.browser.browser_semantic_interactions import (
43
+ register_click_by_role,
44
+ register_click_by_text,
45
+ register_set_text_by_label,
46
+ )
39
47
  from code_puppy.tools.browser.browser_navigation import (
40
48
  register_browser_go_back,
41
49
  register_browser_go_forward,
@@ -132,6 +140,11 @@ TOOL_REGISTRY = {
132
140
  "browser_xpath_query": register_run_xpath_query,
133
141
  "browser_find_buttons": register_find_buttons,
134
142
  "browser_find_links": register_find_links,
143
+ # Browser Semantic Interactions (accessibility-first, DOM progression)
144
+ "browser_page_snapshot": register_get_page_snapshot,
145
+ "browser_click_by_role": register_click_by_role,
146
+ "browser_click_by_text": register_click_by_text,
147
+ "browser_set_text_by_label": register_set_text_by_label,
135
148
  # Browser Element Interactions
136
149
  "browser_click": register_click_element,
137
150
  "browser_double_click": register_double_click_element,
@@ -0,0 +1,70 @@
1
+ """Shared Playwright semantic-locator resolution.
2
+
3
+ Centralizes role/text/label/placeholder/test-id -> Playwright locator
4
+ construction so the semantic discovery *and* action tools don't each
5
+ reinvent it (DRY). Non-visual QA progression should lean on these
6
+ accessibility-first locators instead of raw CSS/XPath or screenshots.
7
+ """
8
+
9
+ from typing import Optional
10
+
11
+ # Supported semantic strategies. The value documents which Playwright
12
+ # ``page.get_by_*`` accessor backs each strategy.
13
+ SEMANTIC_STRATEGIES: dict[str, str] = {
14
+ "role": "get_by_role",
15
+ "text": "get_by_text",
16
+ "label": "get_by_label",
17
+ "placeholder": "get_by_placeholder",
18
+ "test_id": "get_by_test_id",
19
+ }
20
+
21
+
22
+ def describe_target(strategy: str, value: str, name: Optional[str] = None) -> str:
23
+ """Human-readable description of a semantic target for diagnostics.
24
+
25
+ Keeps error messages deterministic and consistent across every tool
26
+ that resolves a locator.
27
+ """
28
+ if strategy == "role" and name:
29
+ return f"role={value!r} name={name!r}"
30
+ return f"{strategy}={value!r}"
31
+
32
+
33
+ def resolve_locator(
34
+ page,
35
+ strategy: str,
36
+ value: str,
37
+ name: Optional[str] = None,
38
+ exact: bool = False,
39
+ ):
40
+ """Build a Playwright locator for a semantic strategy.
41
+
42
+ Args:
43
+ page: The active Playwright page.
44
+ strategy: One of :data:`SEMANTIC_STRATEGIES` keys.
45
+ value: The primary value (role name, text, label, placeholder, test id).
46
+ name: Accessible name, only used with the ``role`` strategy.
47
+ exact: Whether to match ``value``/``name`` exactly.
48
+
49
+ Returns:
50
+ A Playwright locator.
51
+
52
+ Raises:
53
+ ValueError: If ``strategy`` is not supported.
54
+ """
55
+ if strategy not in SEMANTIC_STRATEGIES:
56
+ supported = ", ".join(sorted(SEMANTIC_STRATEGIES))
57
+ raise ValueError(
58
+ f"Unknown locator strategy {strategy!r}. Expected one of: {supported}"
59
+ )
60
+
61
+ if strategy == "role":
62
+ return page.get_by_role(value, name=name, exact=exact)
63
+ if strategy == "text":
64
+ return page.get_by_text(value, exact=exact)
65
+ if strategy == "label":
66
+ return page.get_by_label(value, exact=exact)
67
+ if strategy == "placeholder":
68
+ return page.get_by_placeholder(value, exact=exact)
69
+ # test_id has no exact/name knobs in Playwright's accessor.
70
+ return page.get_by_test_id(value)
@@ -0,0 +1,148 @@
1
+ """Cheap structured page-state snapshot for DOM-first QA progression.
2
+
3
+ Instead of taking a screenshot and visually reasoning about "did the
4
+ action work", qa-kitten can call ``browser_page_snapshot`` to get a
5
+ compact, deterministic view of the page: URL, title, headings, buttons
6
+ (with accessible names), links, inputs, and key ARIA metadata. This is
7
+ faster, cheaper, and immune to window moves / monitor differences.
8
+
9
+ Screenshots remain the right tool for *visual* assertions (layout,
10
+ color, occlusion, visual diff) - this is for functional progression.
11
+ """
12
+
13
+ from typing import Any, Dict
14
+
15
+ from pydantic_ai import RunContext
16
+
17
+ from code_puppy.messaging import emit_info, emit_success
18
+ from code_puppy.tools.common import generate_group_id
19
+
20
+ from .browser_manager import get_session_browser_manager
21
+
22
+ # One JS pass gathers everything so we make a single round-trip to the
23
+ # page rather than N Playwright calls. ``limit`` caps each collection so
24
+ # huge pages don't blow up the tool output.
25
+ _SNAPSHOT_JS = """
26
+ (limit) => {
27
+ const isVisible = (el) => {
28
+ const style = window.getComputedStyle(el);
29
+ if (style.visibility === 'hidden' || style.display === 'none') return false;
30
+ const rect = el.getBoundingClientRect();
31
+ return rect.width > 0 && rect.height > 0;
32
+ };
33
+ const accName = (el) =>
34
+ (el.getAttribute('aria-label')
35
+ || el.getAttribute('title')
36
+ || (el.textContent || '').trim()
37
+ || el.getAttribute('value')
38
+ || '').slice(0, 120);
39
+ const take = (nodes) => Array.from(nodes).filter(isVisible).slice(0, limit);
40
+
41
+ const headings = take(document.querySelectorAll('h1,h2,h3,h4,h5,h6')).map((el) => ({
42
+ level: el.tagName.toLowerCase(),
43
+ text: (el.textContent || '').trim().slice(0, 120),
44
+ }));
45
+ const buttons = take(
46
+ document.querySelectorAll('button,[role="button"],input[type="submit"],input[type="button"]')
47
+ ).map((el) => ({
48
+ name: accName(el),
49
+ disabled: el.disabled === true || el.getAttribute('aria-disabled') === 'true',
50
+ }));
51
+ const links = take(document.querySelectorAll('a[href]')).map((el) => ({
52
+ text: (el.textContent || '').trim().slice(0, 120),
53
+ href: el.getAttribute('href'),
54
+ }));
55
+ const inputs = take(
56
+ document.querySelectorAll('input,textarea,select')
57
+ ).map((el) => ({
58
+ tag: el.tagName.toLowerCase(),
59
+ type: el.getAttribute('type'),
60
+ name: el.getAttribute('name'),
61
+ placeholder: el.getAttribute('placeholder'),
62
+ label: el.getAttribute('aria-label'),
63
+ test_id: el.getAttribute('data-testid') || el.getAttribute('data-test-id'),
64
+ value: (el.value || '').slice(0, 120),
65
+ checked: el.checked === true,
66
+ }));
67
+ const landmarks = take(
68
+ document.querySelectorAll('[role],nav,main,header,footer,aside,form')
69
+ ).map((el) => ({
70
+ role: el.getAttribute('role') || el.tagName.toLowerCase(),
71
+ label: el.getAttribute('aria-label'),
72
+ }));
73
+
74
+ const bodyText = (document.body ? document.body.innerText : '') || '';
75
+ return {
76
+ url: window.location.href,
77
+ title: document.title,
78
+ visible_text: bodyText.replace(/\\s+/g, ' ').trim().slice(0, 2000),
79
+ headings,
80
+ buttons,
81
+ links,
82
+ inputs,
83
+ landmarks,
84
+ };
85
+ }
86
+ """
87
+
88
+
89
+ async def get_page_snapshot(limit: int = 25) -> Dict[str, Any]:
90
+ """Return a compact structured snapshot of the current page state.
91
+
92
+ Args:
93
+ limit: Max items collected per category (buttons, links, inputs...).
94
+
95
+ Returns:
96
+ Dict with ``success`` plus URL/title/visible_text and structured
97
+ lists of headings, buttons, links, inputs, and landmarks, or an
98
+ error dict if no page is available.
99
+ """
100
+ group_id = generate_group_id("browser_page_snapshot", "snapshot")
101
+ emit_info("BROWSER PAGE SNAPSHOT gathering DOM state", message_group=group_id)
102
+ try:
103
+ browser_manager = get_session_browser_manager()
104
+ page = await browser_manager.get_current_page()
105
+
106
+ if not page:
107
+ return {"success": False, "error": "No active browser page available"}
108
+
109
+ snapshot = await page.evaluate(_SNAPSHOT_JS, limit)
110
+
111
+ emit_success(
112
+ "Snapshot: "
113
+ f"{len(snapshot.get('buttons', []))} buttons, "
114
+ f"{len(snapshot.get('links', []))} links, "
115
+ f"{len(snapshot.get('inputs', []))} inputs",
116
+ message_group=group_id,
117
+ )
118
+
119
+ return {"success": True, **snapshot}
120
+
121
+ except Exception as e:
122
+ return {"success": False, "error": str(e)}
123
+
124
+
125
+ def register_get_page_snapshot(agent):
126
+ """Register the page snapshot tool."""
127
+
128
+ @agent.tool
129
+ async def browser_page_snapshot(
130
+ context: RunContext,
131
+ limit: int = 25,
132
+ ) -> Dict[str, Any]:
133
+ """
134
+ Get a cheap, structured snapshot of the current page's DOM state.
135
+
136
+ PREFER THIS over a screenshot when validating functional progression
137
+ (did the page change / did the element appear / what's the value now).
138
+ Returns URL, title, visible text excerpt, headings, buttons with
139
+ accessible names, links, inputs (with values/placeholders/test-ids),
140
+ and ARIA landmarks. Reserve screenshots for true visual assertions.
141
+
142
+ Args:
143
+ limit: Max items per category (buttons/links/inputs/etc).
144
+
145
+ Returns:
146
+ Dict with structured page state, or an error dict.
147
+ """
148
+ return await get_page_snapshot(limit=limit)