code-puppy 0.0.595__tar.gz → 0.0.597__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.597}/PKG-INFO +1 -1
  2. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/agent_qa_kitten.py +63 -22
  3. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/__init__.py +13 -0
  4. code_puppy-0.0.597/code_puppy/tools/browser/browser_locator_resolver.py +70 -0
  5. code_puppy-0.0.597/code_puppy/tools/browser/browser_page_snapshot.py +148 -0
  6. code_puppy-0.0.597/code_puppy/tools/browser/browser_semantic_interactions.py +189 -0
  7. {code_puppy-0.0.595 → code_puppy-0.0.597}/pyproject.toml +1 -1
  8. {code_puppy-0.0.595 → code_puppy-0.0.597}/.gitignore +0 -0
  9. {code_puppy-0.0.595 → code_puppy-0.0.597}/LICENSE +0 -0
  10. {code_puppy-0.0.595 → code_puppy-0.0.597}/README.md +0 -0
  11. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/__init__.py +0 -0
  12. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/__main__.py +0 -0
  13. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/__init__.py +0 -0
  14. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/_builder.py +0 -0
  15. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/_compaction.py +0 -0
  16. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/_diagnostics.py +0 -0
  17. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/_history.py +0 -0
  18. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/_key_listeners.py +0 -0
  19. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/_non_streaming_render.py +0 -0
  20. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/_run_signals.py +0 -0
  21. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/_runtime.py +0 -0
  22. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/_steer_processor.py +0 -0
  23. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/agent_code_puppy.py +0 -0
  24. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/agent_creator_agent.py +0 -0
  25. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/agent_helios.py +0 -0
  26. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/agent_manager.py +0 -0
  27. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/agent_planning.py +0 -0
  28. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/base_agent.py +0 -0
  29. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/event_stream_handler.py +0 -0
  30. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/json_agent.py +0 -0
  31. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/run_stats.py +0 -0
  32. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/smooth_stream.py +0 -0
  33. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/agents/subagent_stream_handler.py +0 -0
  34. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/callbacks.py +0 -0
  35. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/chatgpt_codex_client.py +0 -0
  36. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/claude_cache_client.py +0 -0
  37. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/cli_runner.py +0 -0
  38. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/__init__.py +0 -0
  39. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/add_model_menu.py +0 -0
  40. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/agent_menu.py +0 -0
  41. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/attachments.py +0 -0
  42. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/autosave_menu.py +0 -0
  43. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/autosave_search.py +0 -0
  44. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/clipboard.py +0 -0
  45. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/colors_menu.py +0 -0
  46. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/command_handler.py +0 -0
  47. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/command_registry.py +0 -0
  48. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/config_apply.py +0 -0
  49. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/config_commands.py +0 -0
  50. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/core_commands.py +0 -0
  51. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/diff_menu.py +0 -0
  52. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/file_index.py +0 -0
  53. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/file_path_completion.py +0 -0
  54. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/judges_menu.py +0 -0
  55. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/load_context_completion.py +0 -0
  56. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/__init__.py +0 -0
  57. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/base.py +0 -0
  58. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/catalog_server_installer.py +0 -0
  59. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/custom_server_form.py +0 -0
  60. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/custom_server_installer.py +0 -0
  61. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/edit_command.py +0 -0
  62. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/handler.py +0 -0
  63. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/help_command.py +0 -0
  64. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/install_command.py +0 -0
  65. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/install_menu.py +0 -0
  66. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/list_command.py +0 -0
  67. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/logs_command.py +0 -0
  68. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/remove_command.py +0 -0
  69. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/restart_command.py +0 -0
  70. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/search_command.py +0 -0
  71. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/silence_warning_command.py +0 -0
  72. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/start_all_command.py +0 -0
  73. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/start_command.py +0 -0
  74. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/status_command.py +0 -0
  75. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/stop_all_command.py +0 -0
  76. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/stop_command.py +0 -0
  77. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/utils.py +0 -0
  78. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp/wizard_utils.py +0 -0
  79. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp_binding_menu.py +0 -0
  80. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/mcp_completion.py +0 -0
  81. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/model_picker_completion.py +0 -0
  82. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/model_settings_menu.py +0 -0
  83. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/onboarding_slides.py +0 -0
  84. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/onboarding_wizard.py +0 -0
  85. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/pagination.py +0 -0
  86. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/pin_command_completion.py +0 -0
  87. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/prompt_toolkit_completion.py +0 -0
  88. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/session_commands.py +0 -0
  89. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/set_menu.py +0 -0
  90. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/set_menu_catalog.py +0 -0
  91. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/set_menu_render.py +0 -0
  92. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/set_menu_schema.py +0 -0
  93. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/set_menu_settings.py +0 -0
  94. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/set_menu_shims.py +0 -0
  95. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/set_menu_values.py +0 -0
  96. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/shell_passthrough.py +0 -0
  97. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/skills_completion.py +0 -0
  98. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/uc_menu.py +0 -0
  99. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/utils.py +0 -0
  100. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/command_line/wiggum_state.py +0 -0
  101. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/config.py +0 -0
  102. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/error_logging.py +0 -0
  103. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/gemini_code_assist.py +0 -0
  104. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/gemini_model.py +0 -0
  105. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/hook_engine/README.md +0 -0
  106. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/hook_engine/__init__.py +0 -0
  107. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/hook_engine/aliases.py +0 -0
  108. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/hook_engine/engine.py +0 -0
  109. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/hook_engine/executor.py +0 -0
  110. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/hook_engine/matcher.py +0 -0
  111. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/hook_engine/models.py +0 -0
  112. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/hook_engine/registry.py +0 -0
  113. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/hook_engine/validator.py +0 -0
  114. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/http_utils.py +0 -0
  115. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/keymap.py +0 -0
  116. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/list_filtering.py +0 -0
  117. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/main.py +0 -0
  118. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/__init__.py +0 -0
  119. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/agent_bindings.py +0 -0
  120. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/async_lifecycle.py +0 -0
  121. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/blocking_startup.py +0 -0
  122. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/captured_stdio_server.py +0 -0
  123. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/circuit_breaker.py +0 -0
  124. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/config_wizard.py +0 -0
  125. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/dashboard.py +0 -0
  126. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/error_isolation.py +0 -0
  127. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/examples/retry_example.py +0 -0
  128. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/health_monitor.py +0 -0
  129. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/managed_server.py +0 -0
  130. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/manager.py +0 -0
  131. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/mcp_logs.py +0 -0
  132. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/registry.py +0 -0
  133. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/retry_manager.py +0 -0
  134. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/server_registry_catalog.py +0 -0
  135. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/status_tracker.py +0 -0
  136. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/system_tools.py +0 -0
  137. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_/tool_arg_coercion.py +0 -0
  138. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_prompts/__init__.py +0 -0
  139. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/mcp_prompts/hook_creator.py +0 -0
  140. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/__init__.py +0 -0
  141. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/bar_painters.py +0 -0
  142. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/bar_rendering.py +0 -0
  143. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/bottom_bar.py +0 -0
  144. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/bus.py +0 -0
  145. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/commands.py +0 -0
  146. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/editor_actions.py +0 -0
  147. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/editor_completion.py +0 -0
  148. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/editor_display.py +0 -0
  149. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/editor_history.py +0 -0
  150. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/editor_keys.py +0 -0
  151. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/editor_paste.py +0 -0
  152. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/line_editor.py +0 -0
  153. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/markdown_patches.py +0 -0
  154. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/message_queue.py +0 -0
  155. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/messages.py +0 -0
  156. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/pause_controller.py +0 -0
  157. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/prompt_prefix_style.py +0 -0
  158. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/queue_console.py +0 -0
  159. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/renderers.py +0 -0
  160. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/rich_renderer.py +0 -0
  161. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/run_ui.py +0 -0
  162. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/run_ui_wiring.py +0 -0
  163. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/spinner/__init__.py +0 -0
  164. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/messaging/subagent_console.py +0 -0
  165. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/model_descriptions.py +0 -0
  166. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/model_factory.py +0 -0
  167. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/model_switching.py +0 -0
  168. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/model_utils.py +0 -0
  169. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/models.json +0 -0
  170. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/models_dev_api.json +0 -0
  171. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/models_dev_parser.py +0 -0
  172. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/__init__.py +0 -0
  173. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/agent_skills/__init__.py +0 -0
  174. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/agent_skills/config.py +0 -0
  175. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/agent_skills/discovery.py +0 -0
  176. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/agent_skills/downloader.py +0 -0
  177. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/agent_skills/enabled_skills.py +0 -0
  178. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/agent_skills/installer.py +0 -0
  179. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/agent_skills/metadata.py +0 -0
  180. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/agent_skills/prompt_builder.py +0 -0
  181. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/agent_skills/register_callbacks.py +0 -0
  182. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/agent_skills/remote_catalog.py +0 -0
  183. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/agent_skills/skill_catalog.py +0 -0
  184. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/agent_skills/skill_commands.py +0 -0
  185. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/agent_skills/skills_install_menu.py +0 -0
  186. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/agent_skills/skills_menu.py +0 -0
  187. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/aws_bedrock/__init__.py +0 -0
  188. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/aws_bedrock/config.py +0 -0
  189. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/aws_bedrock/register_callbacks.py +0 -0
  190. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/aws_bedrock/utils.py +0 -0
  191. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/azure_foundry/README.md +0 -0
  192. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/azure_foundry/__init__.py +0 -0
  193. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/azure_foundry/config.py +0 -0
  194. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/azure_foundry/discovery.py +0 -0
  195. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/azure_foundry/register_callbacks.py +0 -0
  196. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/azure_foundry/token.py +0 -0
  197. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/azure_foundry/utils.py +0 -0
  198. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/btw/__init__.py +0 -0
  199. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/btw/inline_view.py +0 -0
  200. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/btw/register_callbacks.py +0 -0
  201. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/btw/side_query.py +0 -0
  202. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/chatgpt_oauth/__init__.py +0 -0
  203. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/chatgpt_oauth/config.py +0 -0
  204. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/chatgpt_oauth/oauth_flow.py +0 -0
  205. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/chatgpt_oauth/register_callbacks.py +0 -0
  206. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/chatgpt_oauth/test_plugin.py +0 -0
  207. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/chatgpt_oauth/utils.py +0 -0
  208. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/claude_code_hooks/__init__.py +0 -0
  209. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/claude_code_hooks/config.py +0 -0
  210. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/claude_code_hooks/register_callbacks.py +0 -0
  211. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/claude_code_oauth/README.md +0 -0
  212. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/claude_code_oauth/SETUP.md +0 -0
  213. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/claude_code_oauth/__init__.py +0 -0
  214. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/claude_code_oauth/config.py +0 -0
  215. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/claude_code_oauth/fast_mode.py +0 -0
  216. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/claude_code_oauth/prompt_handler.py +0 -0
  217. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/claude_code_oauth/register_callbacks.py +0 -0
  218. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/claude_code_oauth/test_fast_mode.py +0 -0
  219. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/claude_code_oauth/test_plugin.py +0 -0
  220. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/claude_code_oauth/token_refresh_heartbeat.py +0 -0
  221. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/claude_code_oauth/utils.py +0 -0
  222. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/code_puppy_agent/SKILL.md +0 -0
  223. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/code_puppy_agent/__init__.py +0 -0
  224. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/code_puppy_agent/register_callbacks.py +0 -0
  225. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/config.py +0 -0
  226. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/context_indicator/__init__.py +0 -0
  227. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/context_indicator/register_callbacks.py +0 -0
  228. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/context_indicator/usage.py +0 -0
  229. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/copilot_auth/__init__.py +0 -0
  230. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/copilot_auth/config.py +0 -0
  231. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/copilot_auth/reasoning_client.py +0 -0
  232. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/copilot_auth/register_callbacks.py +0 -0
  233. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/copilot_auth/utils.py +0 -0
  234. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/customizable_commands/__init__.py +0 -0
  235. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/customizable_commands/register_callbacks.py +0 -0
  236. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/dbos_durable_exec/__init__.py +0 -0
  237. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/dbos_durable_exec/cancel.py +0 -0
  238. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/dbos_durable_exec/commands.py +0 -0
  239. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/dbos_durable_exec/config.py +0 -0
  240. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/dbos_durable_exec/lifecycle.py +0 -0
  241. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/dbos_durable_exec/register_callbacks.py +0 -0
  242. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/dbos_durable_exec/runtime.py +0 -0
  243. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/dbos_durable_exec/startup_lock.py +0 -0
  244. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/dbos_durable_exec/workflow_ids.py +0 -0
  245. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/dbos_durable_exec/wrapper.py +0 -0
  246. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/destructive_command_guard/__init__.py +0 -0
  247. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/destructive_command_guard/detector.py +0 -0
  248. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/destructive_command_guard/register_callbacks.py +0 -0
  249. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/emoji_filter/__init__.py +0 -0
  250. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/emoji_filter/config.py +0 -0
  251. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/emoji_filter/register_callbacks.py +0 -0
  252. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/emoji_filter/stripper.py +0 -0
  253. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/example_custom_command/README.md +0 -0
  254. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/example_custom_command/register_callbacks.py +0 -0
  255. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/file_permission_handler/__init__.py +0 -0
  256. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/file_permission_handler/register_callbacks.py +0 -0
  257. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/force_push_guard/__init__.py +0 -0
  258. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/force_push_guard/detector.py +0 -0
  259. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/force_push_guard/register_callbacks.py +0 -0
  260. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/force_push_guard/test_detector.py +0 -0
  261. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/frontend_emitter/__init__.py +0 -0
  262. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/frontend_emitter/emitter.py +0 -0
  263. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/frontend_emitter/register_callbacks.py +0 -0
  264. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/frontend_emitter/session_context.py +0 -0
  265. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/hook_creator/__init__.py +0 -0
  266. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/hook_creator/register_callbacks.py +0 -0
  267. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/hook_manager/__init__.py +0 -0
  268. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/hook_manager/config.py +0 -0
  269. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/hook_manager/hooks_menu.py +0 -0
  270. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/hook_manager/register_callbacks.py +0 -0
  271. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/oauth_puppy_html.py +0 -0
  272. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/obsidian_agent/README.md +0 -0
  273. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/obsidian_agent/__init__.py +0 -0
  274. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/obsidian_agent/agent_obsidian.py +0 -0
  275. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/obsidian_agent/register_callbacks.py +0 -0
  276. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/ollama/__init__.py +0 -0
  277. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/ollama/register_callbacks.py +0 -0
  278. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/ollama_setup/__init__.py +0 -0
  279. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/ollama_setup/completer.py +0 -0
  280. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/ollama_setup/register_callbacks.py +0 -0
  281. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/plugin_list/__init__.py +0 -0
  282. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/plugin_list/plugin_contributions.py +0 -0
  283. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/plugin_list/plugin_meta.py +0 -0
  284. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/plugin_list/plugin_text_utils.py +0 -0
  285. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/plugin_list/plugins_menu.py +0 -0
  286. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/plugin_list/plugins_menu_render.py +0 -0
  287. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/plugin_list/register_callbacks.py +0 -0
  288. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/pop_command/__init__.py +0 -0
  289. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/pop_command/register_callbacks.py +0 -0
  290. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/prompt_newline/__init__.py +0 -0
  291. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/prompt_newline/config.py +0 -0
  292. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/prompt_newline/register_callbacks.py +0 -0
  293. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/prune/__init__.py +0 -0
  294. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/prune/prune_menu.py +0 -0
  295. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/prune/prune_model.py +0 -0
  296. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/prune/prune_render.py +0 -0
  297. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/prune/register_callbacks.py +0 -0
  298. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/puppy_kennel/README.md +0 -0
  299. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/puppy_kennel/__init__.py +0 -0
  300. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/puppy_kennel/commands.py +0 -0
  301. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/puppy_kennel/config.py +0 -0
  302. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/puppy_kennel/kennel.py +0 -0
  303. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/puppy_kennel/packer.py +0 -0
  304. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/puppy_kennel/recorder.py +0 -0
  305. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/puppy_kennel/register_callbacks.py +0 -0
  306. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/puppy_kennel/retriever.py +0 -0
  307. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/puppy_kennel/schema.py +0 -0
  308. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/puppy_kennel/state.py +0 -0
  309. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/puppy_kennel/tools.py +0 -0
  310. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/puppy_kennel/wings.py +0 -0
  311. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/puppy_spinner/__init__.py +0 -0
  312. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/puppy_spinner/register_callbacks.py +0 -0
  313. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/quick_resume/__init__.py +0 -0
  314. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/quick_resume/register_callbacks.py +0 -0
  315. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/review_pr/__init__.py +0 -0
  316. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/review_pr/register_callbacks.py +0 -0
  317. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/shell_safety/__init__.py +0 -0
  318. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/shell_safety/agent_shell_safety.py +0 -0
  319. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/shell_safety/command_cache.py +0 -0
  320. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/shell_safety/register_callbacks.py +0 -0
  321. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/statusline/__init__.py +0 -0
  322. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/statusline/config.py +0 -0
  323. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/statusline/payload.py +0 -0
  324. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/statusline/prompt_patch.py +0 -0
  325. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/statusline/register_callbacks.py +0 -0
  326. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/statusline/runner.py +0 -0
  327. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/statusline/statusline_command.py +0 -0
  328. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/steer_queue/__init__.py +0 -0
  329. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/steer_queue/queue_menu.py +0 -0
  330. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/steer_queue/register_callbacks.py +0 -0
  331. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/subagent_panel/README.md +0 -0
  332. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/subagent_panel/__init__.py +0 -0
  333. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/subagent_panel/coalesce_patch.py +0 -0
  334. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/subagent_panel/panel_render.py +0 -0
  335. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/subagent_panel/register_callbacks.py +0 -0
  336. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/subagent_panel/resume_repaint.py +0 -0
  337. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/subagent_panel/state.py +0 -0
  338. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/switch_agent_resume/__init__.py +0 -0
  339. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/switch_agent_resume/register_callbacks.py +0 -0
  340. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/theme/README.md +0 -0
  341. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/theme/__init__.py +0 -0
  342. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/theme/bundled_palettes.py +0 -0
  343. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/theme/content_styles.py +0 -0
  344. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/theme/osc_palette.py +0 -0
  345. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/theme/picker.py +0 -0
  346. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/theme/register_callbacks.py +0 -0
  347. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/theme/rich_themes.py +0 -0
  348. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/theme/themes.py +0 -0
  349. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/token_ratio_learner/__init__.py +0 -0
  350. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/token_ratio_learner/ratios.py +0 -0
  351. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/token_ratio_learner/register_callbacks.py +0 -0
  352. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/universal_constructor/__init__.py +0 -0
  353. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/universal_constructor/models.py +0 -0
  354. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/universal_constructor/register_callbacks.py +0 -0
  355. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/universal_constructor/registry.py +0 -0
  356. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/universal_constructor/sandbox.py +0 -0
  357. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/wide_completion_menu/__init__.py +0 -0
  358. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/wide_completion_menu/register_callbacks.py +0 -0
  359. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/wiggum/__init__.py +0 -0
  360. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/wiggum/judge.py +0 -0
  361. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/wiggum/judge_config.py +0 -0
  362. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/wiggum/register_callbacks.py +0 -0
  363. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/plugins/wiggum/state.py +0 -0
  364. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/provider_credentials.py +0 -0
  365. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/provider_identity.py +0 -0
  366. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/pydantic_patches.py +0 -0
  367. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/reopenable_async_client.py +0 -0
  368. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/round_robin_model.py +0 -0
  369. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/session_lifecycle.py +0 -0
  370. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/session_migration.py +0 -0
  371. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/session_storage.py +0 -0
  372. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/status_display.py +0 -0
  373. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/summarization_agent.py +0 -0
  374. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/terminal_utils.py +0 -0
  375. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/agent_tools.py +0 -0
  376. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/ask_user_question/__init__.py +0 -0
  377. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/ask_user_question/constants.py +0 -0
  378. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/ask_user_question/demo_tui.py +0 -0
  379. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/ask_user_question/handler.py +0 -0
  380. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/ask_user_question/models.py +0 -0
  381. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/ask_user_question/registration.py +0 -0
  382. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/ask_user_question/renderers.py +0 -0
  383. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/ask_user_question/terminal_ui.py +0 -0
  384. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/ask_user_question/theme.py +0 -0
  385. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/ask_user_question/tui_loop.py +0 -0
  386. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/browser/__init__.py +0 -0
  387. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/browser/browser_control.py +0 -0
  388. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/browser/browser_interactions.py +0 -0
  389. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/browser/browser_locators.py +0 -0
  390. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/browser/browser_manager.py +0 -0
  391. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/browser/browser_navigation.py +0 -0
  392. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/browser/browser_screenshot.py +0 -0
  393. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/browser/browser_scripts.py +0 -0
  394. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/browser/browser_workflows.py +0 -0
  395. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/command_runner.py +0 -0
  396. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/common.py +0 -0
  397. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/display.py +0 -0
  398. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/file_modifications.py +0 -0
  399. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/file_operations.py +0 -0
  400. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/image_tools.py +0 -0
  401. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/model_tools.py +0 -0
  402. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/skills_tools.py +0 -0
  403. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/subagent_context.py +0 -0
  404. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/subagent_invocation.py +0 -0
  405. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/tools_content.py +0 -0
  406. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/tools/universal_constructor.py +0 -0
  407. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/undo_manager.py +0 -0
  408. {code_puppy-0.0.595 → code_puppy-0.0.597}/code_puppy/uvx_detection.py +0 -0
  409. {code_puppy-0.0.595 → code_puppy-0.0.597}/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.597
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
@@ -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)
@@ -0,0 +1,189 @@
1
+ """Semantic (accessibility-locator) interaction helpers.
2
+
3
+ These let qa-kitten act *directly* through Playwright semantic locators
4
+ (role/text/label) instead of first discovering an element and then
5
+ translating it into a raw CSS/XPath selector. This is the preferred path
6
+ for non-visual workflow progression: fewer round-trips, no fragile
7
+ selectors, deterministic errors when nothing matches.
8
+ """
9
+
10
+ from typing import Any, Dict, Optional
11
+
12
+ from pydantic_ai import RunContext
13
+
14
+ from code_puppy.messaging import emit_error, emit_info, emit_success
15
+ from code_puppy.tools.common import generate_group_id
16
+
17
+ from .browser_locator_resolver import describe_target, resolve_locator
18
+ from .browser_manager import get_session_browser_manager
19
+
20
+
21
+ async def _act_on_semantic(
22
+ strategy: str,
23
+ value: str,
24
+ action: str,
25
+ name: Optional[str] = None,
26
+ exact: bool = False,
27
+ text: Optional[str] = None,
28
+ timeout: int = 10000,
29
+ ) -> Dict[str, Any]:
30
+ """Resolve a semantic locator and perform an action on the first match.
31
+
32
+ Shared core for every semantic interaction so click/fill/check don't
33
+ duplicate the resolve-wait-act-diagnose dance (DRY).
34
+ """
35
+ target = describe_target(strategy, value, name)
36
+ group_id = generate_group_id(f"browser_{action}_by_{strategy}", target)
37
+ emit_info(
38
+ f"BROWSER {action.upper()} BY {strategy.upper()} {target}",
39
+ message_group=group_id,
40
+ )
41
+ try:
42
+ browser_manager = get_session_browser_manager()
43
+ page = await browser_manager.get_current_page()
44
+
45
+ if not page:
46
+ return {"success": False, "error": "No active browser page available"}
47
+
48
+ try:
49
+ locator = resolve_locator(page, strategy, value, name=name, exact=exact)
50
+ except ValueError as ve:
51
+ return {"success": False, "error": str(ve)}
52
+
53
+ element = locator.first
54
+
55
+ # Deterministic "no match" error instead of a raw Playwright timeout.
56
+ if await locator.count() == 0:
57
+ msg = f"No element matched {target}"
58
+ emit_error(msg, message_group=group_id)
59
+ return {"success": False, "error": msg, "target": target}
60
+
61
+ await element.wait_for(state="visible", timeout=timeout)
62
+
63
+ if action == "click":
64
+ await element.click(timeout=timeout)
65
+ elif action == "fill":
66
+ await element.fill(text or "", timeout=timeout)
67
+ elif action == "check":
68
+ await element.check(timeout=timeout)
69
+ else: # pragma: no cover - guarded by callers
70
+ return {"success": False, "error": f"Unknown action {action!r}"}
71
+
72
+ emit_success(f"{action} on {target}", message_group=group_id)
73
+ result: Dict[str, Any] = {
74
+ "success": True,
75
+ "action": action,
76
+ "strategy": strategy,
77
+ "target": target,
78
+ }
79
+ if text is not None:
80
+ result["text"] = text
81
+ return result
82
+
83
+ except Exception as e:
84
+ emit_error(f"{action} failed: {str(e)}", message_group=group_id)
85
+ return {"success": False, "error": str(e), "target": target}
86
+
87
+
88
+ async def click_by_role(
89
+ role: str, name: Optional[str] = None, exact: bool = False, timeout: int = 10000
90
+ ) -> Dict[str, Any]:
91
+ """Click the first element matching an ARIA role (and optional name)."""
92
+ return await _act_on_semantic(
93
+ "role", role, "click", name=name, exact=exact, timeout=timeout
94
+ )
95
+
96
+
97
+ async def click_by_text(
98
+ text: str, exact: bool = False, timeout: int = 10000
99
+ ) -> Dict[str, Any]:
100
+ """Click the first element containing the given visible text."""
101
+ return await _act_on_semantic("text", text, "click", exact=exact, timeout=timeout)
102
+
103
+
104
+ async def set_text_by_label(
105
+ label: str, text: str, exact: bool = False, timeout: int = 10000
106
+ ) -> Dict[str, Any]:
107
+ """Fill the input associated with the given label text."""
108
+ return await _act_on_semantic(
109
+ "label", label, "fill", exact=exact, text=text, timeout=timeout
110
+ )
111
+
112
+
113
+ def register_click_by_role(agent):
114
+ """Register the click-by-role semantic tool."""
115
+
116
+ @agent.tool
117
+ async def browser_click_by_role(
118
+ context: RunContext,
119
+ role: str,
120
+ name: Optional[str] = None,
121
+ exact: bool = False,
122
+ timeout: int = 10000,
123
+ ) -> Dict[str, Any]:
124
+ """
125
+ Click an element by ARIA role (accessibility-first, PREFERRED for
126
+ non-visual progression). No need to discover a selector first.
127
+
128
+ Args:
129
+ role: ARIA role (button, link, tab, menuitem, etc.).
130
+ name: Optional accessible name to disambiguate.
131
+ exact: Match name exactly.
132
+ timeout: Timeout in milliseconds.
133
+
134
+ Returns:
135
+ Dict with action result or a deterministic no-match error.
136
+ """
137
+ return await click_by_role(role, name=name, exact=exact, timeout=timeout)
138
+
139
+
140
+ def register_click_by_text(agent):
141
+ """Register the click-by-text semantic tool."""
142
+
143
+ @agent.tool
144
+ async def browser_click_by_text(
145
+ context: RunContext,
146
+ text: str,
147
+ exact: bool = False,
148
+ timeout: int = 10000,
149
+ ) -> Dict[str, Any]:
150
+ """
151
+ Click an element by its visible text (PREFERRED for non-visual
152
+ progression over screenshot-guided clicking).
153
+
154
+ Args:
155
+ text: Visible text to match.
156
+ exact: Match text exactly.
157
+ timeout: Timeout in milliseconds.
158
+
159
+ Returns:
160
+ Dict with action result or a deterministic no-match error.
161
+ """
162
+ return await click_by_text(text, exact=exact, timeout=timeout)
163
+
164
+
165
+ def register_set_text_by_label(agent):
166
+ """Register the fill-by-label semantic tool."""
167
+
168
+ @agent.tool
169
+ async def browser_set_text_by_label(
170
+ context: RunContext,
171
+ label: str,
172
+ text: str,
173
+ exact: bool = False,
174
+ timeout: int = 10000,
175
+ ) -> Dict[str, Any]:
176
+ """
177
+ Type text into the input associated with a label (accessibility-first,
178
+ PREFERRED for non-visual form progression).
179
+
180
+ Args:
181
+ label: Label text of the target input.
182
+ text: Text to enter.
183
+ exact: Match label exactly.
184
+ timeout: Timeout in milliseconds.
185
+
186
+ Returns:
187
+ Dict with action result or a deterministic no-match error.
188
+ """
189
+ return await set_text_by_label(label, text, exact=exact, timeout=timeout)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "code-puppy"
7
- version = "0.0.595"
7
+ version = "0.0.597"
8
8
  description = "Code generation agent"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11,<3.15"
File without changes
File without changes
File without changes