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.
- {code_puppy-0.0.595 → code_puppy-0.0.596}/PKG-INFO +1 -1
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/agent_qa_kitten.py +63 -22
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/cli_runner.py +24 -9
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/colors_menu.py +2 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/config.py +2 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/picker.py +1 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/__init__.py +13 -0
- code_puppy-0.0.596/code_puppy/tools/browser/browser_locator_resolver.py +70 -0
- code_puppy-0.0.596/code_puppy/tools/browser/browser_page_snapshot.py +148 -0
- code_puppy-0.0.596/code_puppy/tools/browser/browser_semantic_interactions.py +189 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/pyproject.toml +1 -1
- {code_puppy-0.0.595 → code_puppy-0.0.596}/.gitignore +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/LICENSE +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/README.md +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/__main__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_builder.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_compaction.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_diagnostics.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_history.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_key_listeners.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_non_streaming_render.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_run_signals.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_runtime.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/_steer_processor.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/agent_code_puppy.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/agent_creator_agent.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/agent_helios.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/agent_manager.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/agent_planning.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/base_agent.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/event_stream_handler.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/json_agent.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/run_stats.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/smooth_stream.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/agents/subagent_stream_handler.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/chatgpt_codex_client.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/claude_cache_client.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/add_model_menu.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/agent_menu.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/attachments.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/autosave_menu.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/autosave_search.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/clipboard.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/command_handler.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/command_registry.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/config_apply.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/config_commands.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/core_commands.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/diff_menu.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/file_index.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/file_path_completion.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/judges_menu.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/load_context_completion.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/base.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/catalog_server_installer.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/custom_server_form.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/custom_server_installer.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/edit_command.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/handler.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/help_command.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/install_command.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/install_menu.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/list_command.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/logs_command.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/remove_command.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/restart_command.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/search_command.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/silence_warning_command.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/start_all_command.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/start_command.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/status_command.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/stop_all_command.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/stop_command.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/utils.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp/wizard_utils.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp_binding_menu.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/mcp_completion.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/model_picker_completion.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/model_settings_menu.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/onboarding_slides.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/onboarding_wizard.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/pagination.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/pin_command_completion.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/prompt_toolkit_completion.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/session_commands.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/set_menu.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/set_menu_catalog.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/set_menu_render.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/set_menu_schema.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/set_menu_settings.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/set_menu_shims.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/set_menu_values.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/shell_passthrough.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/skills_completion.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/uc_menu.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/utils.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/command_line/wiggum_state.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/error_logging.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/gemini_code_assist.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/gemini_model.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/README.md +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/aliases.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/engine.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/executor.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/matcher.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/models.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/registry.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/hook_engine/validator.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/http_utils.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/keymap.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/list_filtering.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/main.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/agent_bindings.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/async_lifecycle.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/blocking_startup.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/captured_stdio_server.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/circuit_breaker.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/config_wizard.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/dashboard.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/error_isolation.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/examples/retry_example.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/health_monitor.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/managed_server.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/manager.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/mcp_logs.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/registry.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/retry_manager.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/server_registry_catalog.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/status_tracker.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/system_tools.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_/tool_arg_coercion.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_prompts/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/mcp_prompts/hook_creator.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/bar_painters.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/bar_rendering.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/bottom_bar.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/bus.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/commands.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/editor_actions.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/editor_completion.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/editor_display.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/editor_history.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/editor_keys.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/editor_paste.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/line_editor.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/markdown_patches.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/message_queue.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/messages.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/pause_controller.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/prompt_prefix_style.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/queue_console.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/renderers.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/rich_renderer.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/run_ui.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/run_ui_wiring.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/spinner/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/messaging/subagent_console.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/model_descriptions.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/model_factory.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/model_switching.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/model_utils.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/models.json +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/models_dev_api.json +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/models_dev_parser.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/config.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/discovery.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/downloader.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/enabled_skills.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/installer.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/metadata.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/prompt_builder.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/remote_catalog.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/skill_catalog.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/skill_commands.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/skills_install_menu.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/agent_skills/skills_menu.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/aws_bedrock/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/aws_bedrock/config.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/aws_bedrock/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/aws_bedrock/utils.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/azure_foundry/README.md +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/azure_foundry/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/azure_foundry/config.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/azure_foundry/discovery.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/azure_foundry/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/azure_foundry/token.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/azure_foundry/utils.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/btw/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/btw/inline_view.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/btw/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/btw/side_query.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/chatgpt_oauth/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/chatgpt_oauth/config.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/chatgpt_oauth/oauth_flow.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/chatgpt_oauth/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/chatgpt_oauth/test_plugin.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/chatgpt_oauth/utils.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_hooks/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_hooks/config.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_hooks/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/README.md +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/SETUP.md +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/config.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/fast_mode.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/prompt_handler.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/test_fast_mode.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/test_plugin.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/token_refresh_heartbeat.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/claude_code_oauth/utils.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/code_puppy_agent/SKILL.md +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/code_puppy_agent/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/code_puppy_agent/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/config.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/context_indicator/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/context_indicator/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/context_indicator/usage.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/copilot_auth/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/copilot_auth/config.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/copilot_auth/reasoning_client.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/copilot_auth/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/copilot_auth/utils.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/customizable_commands/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/customizable_commands/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/cancel.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/commands.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/config.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/lifecycle.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/runtime.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/startup_lock.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/workflow_ids.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/dbos_durable_exec/wrapper.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/destructive_command_guard/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/destructive_command_guard/detector.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/destructive_command_guard/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/emoji_filter/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/emoji_filter/config.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/emoji_filter/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/emoji_filter/stripper.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/example_custom_command/README.md +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/example_custom_command/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/file_permission_handler/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/file_permission_handler/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/force_push_guard/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/force_push_guard/detector.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/force_push_guard/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/force_push_guard/test_detector.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/frontend_emitter/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/frontend_emitter/emitter.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/frontend_emitter/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/frontend_emitter/session_context.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/hook_creator/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/hook_creator/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/hook_manager/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/hook_manager/config.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/hook_manager/hooks_menu.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/hook_manager/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/oauth_puppy_html.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/obsidian_agent/README.md +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/obsidian_agent/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/obsidian_agent/agent_obsidian.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/obsidian_agent/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/ollama/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/ollama/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/ollama_setup/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/ollama_setup/completer.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/ollama_setup/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/plugin_list/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/plugin_list/plugin_contributions.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/plugin_list/plugin_meta.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/plugin_list/plugin_text_utils.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/plugin_list/plugins_menu.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/plugin_list/plugins_menu_render.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/plugin_list/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/pop_command/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/pop_command/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/prompt_newline/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/prompt_newline/config.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/prompt_newline/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/prune/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/prune/prune_menu.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/prune/prune_model.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/prune/prune_render.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/prune/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/README.md +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/commands.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/config.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/kennel.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/packer.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/recorder.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/retriever.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/schema.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/state.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/tools.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_kennel/wings.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_spinner/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/puppy_spinner/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/quick_resume/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/quick_resume/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/review_pr/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/review_pr/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/shell_safety/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/shell_safety/agent_shell_safety.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/shell_safety/command_cache.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/shell_safety/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/statusline/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/statusline/config.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/statusline/payload.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/statusline/prompt_patch.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/statusline/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/statusline/runner.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/statusline/statusline_command.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/steer_queue/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/steer_queue/queue_menu.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/steer_queue/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/subagent_panel/README.md +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/subagent_panel/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/subagent_panel/coalesce_patch.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/subagent_panel/panel_render.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/subagent_panel/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/subagent_panel/resume_repaint.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/subagent_panel/state.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/switch_agent_resume/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/switch_agent_resume/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/README.md +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/bundled_palettes.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/content_styles.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/osc_palette.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/rich_themes.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/theme/themes.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/token_ratio_learner/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/token_ratio_learner/ratios.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/token_ratio_learner/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/universal_constructor/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/universal_constructor/models.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/universal_constructor/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/universal_constructor/registry.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/universal_constructor/sandbox.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/wide_completion_menu/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/wide_completion_menu/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/wiggum/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/wiggum/judge.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/wiggum/judge_config.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/wiggum/register_callbacks.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/plugins/wiggum/state.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/provider_credentials.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/provider_identity.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/pydantic_patches.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/reopenable_async_client.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/round_robin_model.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/session_lifecycle.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/session_migration.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/session_storage.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/status_display.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/summarization_agent.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/terminal_utils.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/agent_tools.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/constants.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/demo_tui.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/handler.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/models.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/registration.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/renderers.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/terminal_ui.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/theme.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/ask_user_question/tui_loop.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/__init__.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/browser_control.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/browser_interactions.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/browser_locators.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/browser_manager.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/browser_navigation.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/browser_screenshot.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/browser_scripts.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/browser/browser_workflows.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/command_runner.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/common.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/display.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/file_modifications.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/file_operations.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/image_tools.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/model_tools.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/skills_tools.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/subagent_context.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/subagent_invocation.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/tools_content.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/tools/universal_constructor.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/undo_manager.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/uvx_detection.py +0 -0
- {code_puppy-0.0.595 → code_puppy-0.0.596}/code_puppy/version_checker.py +0 -0
|
@@ -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**:
|
|
97
|
-
8. **Act**: Interact
|
|
98
|
-
9. **Validate**:
|
|
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.
|
|
112
|
-
2.
|
|
113
|
-
3.
|
|
114
|
-
4.
|
|
115
|
-
5.
|
|
116
|
-
6.
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
-
|
|
121
|
-
-
|
|
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.
|
|
136
|
-
3.
|
|
137
|
-
4. Only
|
|
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.
|
|
143
|
-
4.
|
|
144
|
-
5.
|
|
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
|
-
- **
|
|
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(
|
|
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
|
|
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
|
|
892
|
-
|
|
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
|
|
|
@@ -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)
|