code-puppy-core-plugins 0.0.76__tar.gz → 0.0.78__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_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/PKG-INFO +8 -1
- code_puppy_core_plugins-0.0.78/code_puppy_core_plugins/computer_use/FOCUS_INVESTIGATION.md +65 -0
- code_puppy_core_plugins-0.0.78/code_puppy_core_plugins/computer_use/PARITY.md +80 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/computer_use/README.md +32 -10
- code_puppy_core_plugins-0.0.78/code_puppy_core_plugins/computer_use/WINDOWS.md +240 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/computer_use/accessibility.py +2 -1
- code_puppy_core_plugins-0.0.78/code_puppy_core_plugins/computer_use/backend.py +28 -0
- code_puppy_core_plugins-0.0.78/code_puppy_core_plugins/computer_use/batch.py +93 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/computer_use/commands.py +12 -2
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/computer_use/inline_image.py +1 -1
- code_puppy_core_plugins-0.0.78/code_puppy_core_plugins/computer_use/locales/en-US.json +5 -0
- code_puppy_core_plugins-0.0.78/code_puppy_core_plugins/computer_use/locales/es.json +5 -0
- code_puppy_core_plugins-0.0.78/code_puppy_core_plugins/computer_use/locales/fr-CA.json +5 -0
- code_puppy_core_plugins-0.0.76/code_puppy_core_plugins/computer_use/backend.py → code_puppy_core_plugins-0.0.78/code_puppy_core_plugins/computer_use/macos_backend.py +3 -3
- code_puppy_core_plugins-0.0.78/code_puppy_core_plugins/computer_use/permissions.py +48 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/computer_use/policy.py +19 -4
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/computer_use/register_callbacks.py +19 -7
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/computer_use/settle.py +2 -1
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/computer_use/tools.py +45 -96
- code_puppy_core_plugins-0.0.78/code_puppy_core_plugins/computer_use/windows_accessibility.py +431 -0
- code_puppy_core_plugins-0.0.78/code_puppy_core_plugins/computer_use/windows_activation.py +60 -0
- code_puppy_core_plugins-0.0.78/code_puppy_core_plugins/computer_use/windows_backend.py +409 -0
- code_puppy_core_plugins-0.0.78/code_puppy_core_plugins/computer_use/windows_capture.py +193 -0
- code_puppy_core_plugins-0.0.78/code_puppy_core_plugins/computer_use/windows_input.py +133 -0
- code_puppy_core_plugins-0.0.78/code_puppy_core_plugins/computer_use/windows_native.py +265 -0
- code_puppy_core_plugins-0.0.78/code_puppy_core_plugins/computer_use/windows_runtime.py +75 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/pyproject.toml +15 -2
- code_puppy_core_plugins-0.0.76/code_puppy_core_plugins/token_ratio_learner/__init__.py +0 -5
- code_puppy_core_plugins-0.0.76/code_puppy_core_plugins/token_ratio_learner/ratios.py +0 -208
- code_puppy_core_plugins-0.0.76/code_puppy_core_plugins/token_ratio_learner/register_callbacks.py +0 -218
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/.gitignore +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/LICENSE +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/README.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/THIRD_PARTY_NOTICES.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/acp/README.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/acp/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/acp/agent.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/acp/bridge.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/acp/capabilities.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/acp/commands.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/acp/content.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/acp/io_delegation.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/acp/mcp_config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/acp/permissions.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/acp/persistence.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/acp/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/acp/replay.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/acp/session.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/acp/session_config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/acp/state.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/agent_creator_skill/SKILL.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/agent_creator_skill/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/agent_creator_skill/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/agent_skills/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/agent_skills/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/agent_skills/discovery.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/agent_skills/enabled_skills.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/agent_skills/metadata.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/agent_skills/prompt_builder.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/agent_skills/provider.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/agent_skills/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/agent_skills/skill_commands.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/agent_skills/skills_menu.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/attachment_references/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/attachment_references/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/attachment_references/tool.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/auto_continue/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/auto_continue/classifier.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/auto_continue/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/aws_bedrock/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/aws_bedrock/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/aws_bedrock/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/aws_bedrock/utils.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/azure_foundry/README.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/azure_foundry/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/azure_foundry/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/azure_foundry/discovery.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/azure_foundry/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/azure_foundry/token.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/azure_foundry/utils.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/background_agents/README.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/background_agents/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/background_agents/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/btw/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/btw/inline_view.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/btw/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/btw/side_query.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/chatgpt_oauth/IMAGEGEN_SKILL.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/chatgpt_oauth/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/chatgpt_oauth/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/chatgpt_oauth/image_generation.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/chatgpt_oauth/image_tool.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/chatgpt_oauth/model_catalog.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/chatgpt_oauth/oauth_flow.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/chatgpt_oauth/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/chatgpt_oauth/test_plugin.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/chatgpt_oauth/usage.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/chatgpt_oauth/utils.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_hooks/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_hooks/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_hooks/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_hooks/trust.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_oauth/README.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_oauth/SETUP.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_oauth/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_oauth/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_oauth/fast_mode.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_oauth/model_filter.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_oauth/model_provider.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_oauth/prompt_handler.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_oauth/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_oauth/runtime_credentials.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_oauth/test_plugin.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_oauth/token_refresh_heartbeat.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_oauth/token_store.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/claude_code_oauth/utils.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/code_puppy_agent/AGENTS_AND_TOOLS.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/code_puppy_agent/MODELS_AND_MCP.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/code_puppy_agent/PLUGINS_AND_CALLBACKS.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/code_puppy_agent/SESSIONS_AND_HISTORY.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/code_puppy_agent/SKILL.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/code_puppy_agent/SKILLS_SYSTEM.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/code_puppy_agent/SYSTEM_PROMPT_CONFIG_AND_I18N.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/code_puppy_agent/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/code_puppy_agent/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/completion_notification/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/completion_notification/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/completion_notification/locales/en-US.json +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/completion_notification/locales/es.json +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/completion_notification/locales/fr-CA.json +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/completion_notification/notifier.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/completion_notification/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/computer_use/NativeCapture.swift +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/computer_use/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/computer_use/activation.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/computer_use/backend_types.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/computer_use/capture.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/computer_use/geometry.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/computer_use/keycodes.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/computer_use/safety.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/computer_use/state.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/context_indicator/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/context_indicator/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/context_indicator/usage.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/copilot_auth/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/copilot_auth/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/copilot_auth/reasoning_client.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/copilot_auth/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/copilot_auth/responses_stream.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/copilot_auth/utils.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/customizable_commands/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/customizable_commands/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/dbos_durable_exec/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/dbos_durable_exec/cancel.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/dbos_durable_exec/commands.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/dbos_durable_exec/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/dbos_durable_exec/lifecycle.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/dbos_durable_exec/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/dbos_durable_exec/runtime.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/dbos_durable_exec/startup_lock.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/dbos_durable_exec/workflow_ids.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/dbos_durable_exec/wrapper.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/destructive_command_guard/AGENTS.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/destructive_command_guard/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/destructive_command_guard/detector.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/destructive_command_guard/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/emoji_filter/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/emoji_filter/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/emoji_filter/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/emoji_filter/stripper.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/empty_html_comment_filter/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/example_custom_command/README.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/example_custom_command/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/file_permission_handler/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/file_permission_handler/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/README.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/cheatsheet.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/pipeline.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/synopsis.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/about.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/address-feedback.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/ask.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/aug.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/auto-pilot.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/cheatsheet.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/commit.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/config.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/create-pr.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/exec.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/new.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/qa.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/rebase.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/review.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/split.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/squash-commits.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/status.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/tests.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_about.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_cheatsheet.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_status.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/installer.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/flux_bootstrap/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/force_push_guard/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/force_push_guard/detector.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/force_push_guard/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/fork/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/fork/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/frontend_emitter/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/frontend_emitter/emitter.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/frontend_emitter/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/frontend_emitter/session_context.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/grok_oauth/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/grok_oauth/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/grok_oauth/oauth_flow.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/grok_oauth/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/grok_oauth/utils.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/herdr/README.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/herdr/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/herdr/client.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/herdr/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/herdr/reporter.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/herdr/restore.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/herdr/smoke.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/herdr/sources.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/hook_creator/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/hook_creator/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/hook_manager/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/hook_manager/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/hook_manager/hooks_menu.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/hook_manager/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/hook_manager/trust_handler.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/jev_grep/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/jev_grep/chunks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/jev_grep/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/jev_grep/judge.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/jev_grep/locales/en-US.json +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/jev_grep/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/jev_grep/retrieve.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/jev_grep/search.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/jev_grep/structure.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/jev_grep/tool.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/jev_grep/treesitter.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/logfire_oauth/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/logfire_oauth/oauth.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/logfire_oauth/query_tool.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/logfire_oauth/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/logfire_sessions/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/logfire_sessions/mirror.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/logfire_sessions/query.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/logfire_sessions/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/logfire_sessions/sync.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/mcp_binding_prompt/README.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/mcp_binding_prompt/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/mcp_binding_prompt/custom_install.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/mcp_binding_prompt/http_form.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/mcp_binding_prompt/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/meta_oauth/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/meta_oauth/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/meta_oauth/oauth_flow.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/meta_oauth/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/meta_oauth/utils.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/namespace_skill_search/README.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/namespace_skill_search/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/namespace_skill_search/namespaces.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/namespace_skill_search/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/namespace_skill_search/search_tool.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/no_tools/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/no_tools/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/oauth_pasteback.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/oauth_puppy_html.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/obsidian_agent/README.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/obsidian_agent/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/obsidian_agent/agent_obsidian.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/obsidian_agent/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/ollama/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/ollama/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/ollama_setup/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/ollama_setup/completer.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/ollama_setup/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/openrouter_oauth/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/openrouter_oauth/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/openrouter_oauth/oauth_flow.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/openrouter_oauth/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/openrouter_oauth/test_plugin.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/plugin_list/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/plugin_list/plugin_contributions.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/plugin_list/plugin_meta.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/plugin_list/plugin_text_utils.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/plugin_list/plugins_menu.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/plugin_list/plugins_menu_render.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/plugin_list/project_trust_flow.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/plugin_list/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/plugin_settings.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/pop_command/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/pop_command/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/profiles/README.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/profiles/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/profiles/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/profiles/locales/en-US.json +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/profiles/menu.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/profiles/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/prompt_newline/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/prompt_newline/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/prompt_newline/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/prune/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/prune/prune_menu.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/prune/prune_model.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/prune/prune_render.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/prune/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_kennel/README.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_kennel/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_kennel/commands.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_kennel/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_kennel/kennel.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_kennel/packer.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_kennel/recorder.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_kennel/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_kennel/retriever.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_kennel/schema.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_kennel/state.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_kennel/tools.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_kennel/wings.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_spinner/README.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_spinner/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_spinner/builtin_frames.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_spinner/commands.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_spinner/picker.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_spinner/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/puppy_spinner/spinners.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/qa_kitten_skill/SKILL.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/qa_kitten_skill/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/qa_kitten_skill/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/quick_resume/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/quick_resume/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/review_pr/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/review_pr/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/session_namer/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/session_namer/namer.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/session_namer/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/spill/LICENSE.deepseek +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/spill/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/spill/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/spill/store.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/stack_dump/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/stack_dump/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/statusline/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/statusline/config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/statusline/payload.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/statusline/prompt_patch.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/statusline/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/statusline/runner.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/statusline/statusline_command.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/steer_queue/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/steer_queue/queue_menu.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/steer_queue/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/subagent_panel/README.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/subagent_panel/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/subagent_panel/coalesce_patch.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/subagent_panel/panel_render.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/subagent_panel/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/subagent_panel/resume_repaint.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/subagent_panel/state.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/switch_agent_resume/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/switch_agent_resume/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/termflow_tui.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/theme/README.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/theme/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/theme/bundled_palettes.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/theme/content_styles.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/theme/osc_palette.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/theme/picker.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/theme/prompt_toolkit_theme.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/theme/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/theme/rich_themes.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/theme/themes.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/timestamp_heartbeat/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/timestamp_heartbeat/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/universal_constructor/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/universal_constructor/models.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/universal_constructor/provider.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/universal_constructor/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/universal_constructor/registry.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/universal_constructor/sandbox.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/web_retriever_skill/SKILL.md +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/web_retriever_skill/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/web_retriever_skill/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/wiggum/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/wiggum/goal_runs.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/wiggum/judge.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/wiggum/judge_config.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/wiggum/judges_menu.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/wiggum/register_callbacks.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/wiggum/state.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/yolo_cli/__init__.py +0 -0
- {code_puppy_core_plugins-0.0.76 → code_puppy_core_plugins-0.0.78}/code_puppy_core_plugins/yolo_cli/register_callbacks.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: code-puppy-core-plugins
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.78
|
|
4
4
|
Summary: Official plugin bundle for Code Puppy
|
|
5
5
|
Project-URL: Repository, https://github.com/mpfaffenberger/code_puppy_core_plugins
|
|
6
6
|
Project-URL: Homepage, https://github.com/mpfaffenberger/code_puppy_core_plugins
|
|
@@ -34,6 +34,13 @@ Requires-Dist: tree-sitter-scala>=0.26.2
|
|
|
34
34
|
Requires-Dist: tree-sitter-swift>=0.7.3
|
|
35
35
|
Requires-Dist: tree-sitter-typescript>=0.23.2
|
|
36
36
|
Requires-Dist: tree-sitter<0.26,>=0.25.2
|
|
37
|
+
Provides-Extra: computer-use
|
|
38
|
+
Requires-Dist: pillow>=11; extra == 'computer-use'
|
|
39
|
+
Requires-Dist: pyobjc-framework-applicationservices>=10.3; (sys_platform == 'darwin') and extra == 'computer-use'
|
|
40
|
+
Requires-Dist: pyobjc-framework-cocoa>=10.3; (sys_platform == 'darwin') and extra == 'computer-use'
|
|
41
|
+
Requires-Dist: pyobjc-framework-quartz>=10.3; (sys_platform == 'darwin') and extra == 'computer-use'
|
|
42
|
+
Requires-Dist: pywinauto<0.7,>=0.6.9; (sys_platform == 'win32') and extra == 'computer-use'
|
|
43
|
+
Requires-Dist: windows-capture<3,>=2.0.1; (sys_platform == 'win32') and extra == 'computer-use'
|
|
37
44
|
Description-Content-Type: text/markdown
|
|
38
45
|
|
|
39
46
|
# Code Puppy Core Plugins
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Foreground activation investigation (2026-10-04)
|
|
2
|
+
|
|
3
|
+
## Report and reproduction
|
|
4
|
+
|
|
5
|
+
The interactive acceptance report for initial plugin commit `2bf27fc` recorded
|
|
6
|
+
successful early actions, then repeated "Target lost focus" errors while fresh
|
|
7
|
+
state was being requested. Background captures still worked. The recorded primary
|
|
8
|
+
fixture HWND no longer existed when this investigation began, so it was not reused.
|
|
9
|
+
|
|
10
|
+
A new diagnostic, `tests/live_windows_focus.py`, created two owned native fixtures
|
|
11
|
+
and exercised activation on the same COM worker used by the backend. Repeated runs
|
|
12
|
+
reproduced the failure: activating the first window succeeded; activating the
|
|
13
|
+
second with Win32 returned false and left the first window foreground.
|
|
14
|
+
|
|
15
|
+
Observed in the final instrumented run (these HWNDs are historical, not reusable):
|
|
16
|
+
|
|
17
|
+
| Operation | Observation |
|
|
18
|
+
|---|---|
|
|
19
|
+
| Raw Win32 request for HWND 108005828 | returned false; HWND 6097114 remained foreground |
|
|
20
|
+
| Patched backend requests state for HWND 108005828 | actual UIA fallback callback recorded `[108005828]` |
|
|
21
|
+
| Independent foreground verification | HWND 108005828 was foreground |
|
|
22
|
+
| State generation | valid new revision, UIA nodes, WGC PNG |
|
|
23
|
+
| Additional alternating state requests | all six succeeded |
|
|
24
|
+
|
|
25
|
+
This proves the original activation path can fail and the tested UIA recovery
|
|
26
|
+
works. It does not establish which internal Windows eligibility condition caused
|
|
27
|
+
every failure in the original interactive session.
|
|
28
|
+
|
|
29
|
+
## Fix and safety
|
|
30
|
+
|
|
31
|
+
- Try the ordinary Win32 request and allow a bounded foreground-confirmation wait.
|
|
32
|
+
- If still not foreground, request the target root's advertised UIA SetFocus.
|
|
33
|
+
Call the COM method, not pywinauto's wrapper that may inject input.
|
|
34
|
+
- Independently verify the actual foreground HWND. A successful COM return alone
|
|
35
|
+
is insufficient. If activation cannot be confirmed, refuse the operation.
|
|
36
|
+
- Recheck consent, pause, cancellation, desktop availability, process identity,
|
|
37
|
+
and policy throughout the activation attempt. Existing pre-input checks remain.
|
|
38
|
+
- Report activation refusal separately from losing focus during an action, with
|
|
39
|
+
useful HWND and request-result diagnostics and a manual recovery instruction.
|
|
40
|
+
- No synthetic Alt keys, input-queue attachment, changed system settings, elevation,
|
|
41
|
+
or relaxed foreground checks were added. Providers without root focus support
|
|
42
|
+
can still require manual focus.
|
|
43
|
+
|
|
44
|
+
## Validation
|
|
45
|
+
|
|
46
|
+
- 204 targeted computer-use tests passed, up from the original 187.
|
|
47
|
+
- New cases cover Win32 denial, UIA recovery, misleading success responses,
|
|
48
|
+
unsupported focus, cancellation, policy revocation, and process-identity changes.
|
|
49
|
+
- Real two-window diagnosis confirmed the fallback actually ran and recovered.
|
|
50
|
+
- The native harness passed on primary `(180,180)`, secondary `(2050,180)`, and
|
|
51
|
+
portrait `(-1300,180)` placements after strengthening its assertions:
|
|
52
|
+
- fractional scroll changes native SCROLLINFO position;
|
|
53
|
+
- pixel drag leaves a nonempty native EDIT selection;
|
|
54
|
+
- the complete occluded capture matches an unfocused, unobscured reference PNG.
|
|
55
|
+
- The harness still is not an LLM-driven acceptance session. Remaining entries in
|
|
56
|
+
the user's CHECKLIST.md must be resumed after restarting the development instance.
|
|
57
|
+
Live macOS validation remains outstanding.
|
|
58
|
+
|
|
59
|
+
The focus diagnostic requires existing consent and never enables it. It prints
|
|
60
|
+
exact PNG paths as evidence, closes only its own verified fixture HWNDs, and does
|
|
61
|
+
not delete unrelated screenshots. Run from the plugin checkout:
|
|
62
|
+
|
|
63
|
+
```powershell
|
|
64
|
+
.venv\Scripts\python.exe -X utf8 tests\live_windows_focus.py
|
|
65
|
+
```
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Cross-platform implementation and verification
|
|
2
|
+
|
|
3
|
+
## Architecture
|
|
4
|
+
|
|
5
|
+
`backend.py` selects macOS or Windows behind the existing twelve tool names.
|
|
6
|
+
`macos_backend.py` retains the original macOS implementation. `windows_backend.py`
|
|
7
|
+
implements the same dispatcher methods with UIA, WGC, and typed Win32 input.
|
|
8
|
+
Commands, policy, revision storage, terminal previews, tool-result images, batch
|
|
9
|
+
execution, and UI-settling logic are shared. Windows UIA objects and entire requests
|
|
10
|
+
stay on a single COM worker, never arbitrary event-loop/thread-pool threads.
|
|
11
|
+
|
|
12
|
+
The plugin keeps its existing package/entry-point name `computer_use`. Neither
|
|
13
|
+
platform needs a `windows_desktop` plugin or alternate tool schemas. The main
|
|
14
|
+
Code Puppy repository change adds Windows dependencies to its existing extra;
|
|
15
|
+
the companion core-plugins repository contains the implementation.
|
|
16
|
+
|
|
17
|
+
## Capability matrix
|
|
18
|
+
|
|
19
|
+
| Existing capability | Windows implementation | Verification |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| Twelve tools / opt-in registration | Same registrars and Pydantic-AI schemas | Automated, both platform gates |
|
|
22
|
+
| Revisioned application state | HWND identity, UIA tree, WGC screenshot | Live native fixture |
|
|
23
|
+
| Accessibility node IDs | Bounded UIA control-view traversal | Live + bounds/truncation tests |
|
|
24
|
+
| Element click | Invoke / SelectionItem / Toggle patterns | Live button/checkbox; mock pattern cases |
|
|
25
|
+
| Set control value | Value / RangeValue, read-only and password checks | Live EDIT + mock cases |
|
|
26
|
+
| Advertised control actions | Invoke, toggle, selection, expand/collapse, focus | Live invoke/focus; remaining mocked |
|
|
27
|
+
| Exact contextual text selection | TextPattern ranges, prefix/suffix, caret endpoints | Live RichEdit selection after supplementary Unicode; caret/suffix mocked |
|
|
28
|
+
| Keyboard and Unicode typing | Balanced SendInput events; literal text | Live shared batch |
|
|
29
|
+
| Fractional-page scrolling | UIA ScrollPattern view size/extent | Live vertical half-page; horizontal mocked |
|
|
30
|
+
| Pixel click and drag | DWM bounds, per-thread DPI awareness, SendInput | Live on all three monitors |
|
|
31
|
+
| Background window capture | WGC by HWND, no activation or desktop crop | Live with an opaque blue occluder |
|
|
32
|
+
| Guarded batches / UI settling | Shared batch engine and accessibility fingerprint | Live + failure/wait/cancellation tests |
|
|
33
|
+
| PNG attachment to model | Shared BinaryContent/ToolReturn | Live tools + schema tests |
|
|
34
|
+
| Inline terminal preview | Existing shared terminal helper | Existing mocked terminal tests; not live on Windows Terminal |
|
|
35
|
+
| Consent, pause, process restrictions | Shared policy plus Windows security process rules | Automated; live temporary-policy pause |
|
|
36
|
+
| Password-value redaction | UIA protected nodes/descendants, no semantic password operations | Live password EDIT + mock descendant cases |
|
|
37
|
+
|
|
38
|
+
## Results for this development change
|
|
39
|
+
|
|
40
|
+
- 220 targeted `test_computer_use*.py` tests passed on Windows after the
|
|
41
|
+
[foreground activation fix](FOCUS_INVESTIGATION.md), coordinate-metadata
|
|
42
|
+
correction, and checkpoint-based batch focus-loss fix (initial baseline: 187;
|
|
43
|
+
foreground-fix baseline: 204; coordinate-fix baseline: 209).
|
|
44
|
+
- The batch focus-loss fix is verified by mocked regressions, including the
|
|
45
|
+
serialized Windows runtime, and a subsequent focused public-session retest on
|
|
46
|
+
`219210a`. The owned sink took focus, the batch stopped, and the sentinel stayed
|
|
47
|
+
at zero. Cleanup and final owner pause were verified. The original failure is
|
|
48
|
+
retained in the acceptance evidence; earlier live results below are prior
|
|
49
|
+
evidence, not complete campaign reruns on this change.
|
|
50
|
+
- The existing macOS backend's 21 original methods were compared by Python AST
|
|
51
|
+
against the upstream baseline: unchanged. A small `invalidate_state` method was
|
|
52
|
+
added for shared failed-batch cleanup. Imports/formatting and module location changed.
|
|
53
|
+
- Existing macOS action, activation, accessibility, policy, image, and settling
|
|
54
|
+
regressions passed with their mocked native APIs.
|
|
55
|
+
- The disposable live fixture passed at `(180,180)`, `(2050,180)`, and `(-1300,180)`:
|
|
56
|
+
primary landscape, secondary landscape, and left-hand portrait monitor.
|
|
57
|
+
- Both the modified Code Puppy and core-plugins packages built as wheels.
|
|
58
|
+
- No tests enabled persistent user consent; no existing application documents
|
|
59
|
+
were used. The follow-up focus diagnostic honors already granted consent.
|
|
60
|
+
|
|
61
|
+
## What this does not prove
|
|
62
|
+
|
|
63
|
+
This is implementation of the shared capability set, **not a claim that every
|
|
64
|
+
Windows application exposes the same accessibility features as every Mac app**.
|
|
65
|
+
A control without UIA Value/Text/Scroll patterns returns unsupported. In particular,
|
|
66
|
+
Windows semantic scrolling currently needs ScrollPattern, while the macOS backend
|
|
67
|
+
can inject pixel scroll events. The model can use supported keyboard/pixel actions
|
|
68
|
+
where appropriate, but the plugin does not silently pretend those are semantic
|
|
69
|
+
operations. Full application-by-application equivalence is not established.
|
|
70
|
+
|
|
71
|
+
Live tests covered native Win32 controls and the current three-monitor hardware.
|
|
72
|
+
Electron/Chromium apps, mixed-DPI configurations different from this machine,
|
|
73
|
+
RDP, ARM64, other Python versions, GPU/driver variations, and real macOS native
|
|
74
|
+
execution still need environment-specific validation. WGC rejects minimized,
|
|
75
|
+
protected, or mismatched-geometry captures rather than falling back to the desktop.
|
|
76
|
+
|
|
77
|
+
No live macOS host was available. Shared batch execution now runs off the event
|
|
78
|
+
loop and invalidates failed batches; this is tested with mocks but should receive
|
|
79
|
+
an actual Mac smoke test before publishing a coordinated release. An LLM-driven
|
|
80
|
+
chat session after installation/consent also remains a separate end-to-end check.
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
# macOS
|
|
1
|
+
# Computer Use (macOS and Windows)
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
One opt-in plugin, the same twelve `computer_*` tools, and the same `/computer-use`
|
|
4
|
+
commands on both platforms. macOS uses Accessibility, Quartz, and ScreenCaptureKit;
|
|
5
|
+
Windows uses UI Automation, Win32 input, and HWND-targeted Windows Graphics Capture.
|
|
6
|
+
No virtual machine, duplicate plugin, or alternate Windows tool API is required.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
**Windows installation, examples, limitations, and live tests:** [WINDOWS.md](WINDOWS.md).
|
|
9
|
+
**Implementation and verification matrix:** [PARITY.md](PARITY.md).
|
|
10
|
+
|
|
11
|
+
The macOS setup and platform-specific behavior below remain supported.
|
|
12
|
+
|
|
13
|
+
## macOS installation
|
|
8
14
|
|
|
9
15
|
```bash
|
|
10
16
|
pip install "code-puppy[computer-use]"
|
|
@@ -51,14 +57,28 @@ application is in front.
|
|
|
51
57
|
element's advertised actions.
|
|
52
58
|
3. Run one mutation, or one guarded batch of at most 20 mutations.
|
|
53
59
|
4. Fetch fresh state. A completed batch does this automatically after waiting
|
|
54
|
-
for the accessibility tree to stabilize.
|
|
60
|
+
for the accessibility tree to stabilize. Check `ui_settle.settled`: a timeout
|
|
61
|
+
is reported, not a guarantee that animations or network activity finished.
|
|
55
62
|
|
|
56
|
-
|
|
63
|
+
For a batch `perform_action` step, use `action_name` for the advertised AX/UIA
|
|
64
|
+
operation because `action` identifies the step itself, for example:
|
|
65
|
+
`{"action": "perform_action", "element_id": 7, "action_name": "AXPress"}`.
|
|
66
|
+
A failed batch invalidates the revision; the failing action may have partially
|
|
67
|
+
executed, so inspect before retrying.
|
|
68
|
+
|
|
69
|
+
On macOS, before every mutation, the target process is activated and verified as the
|
|
57
70
|
frontmost application. This is required because ScreenCaptureKit can capture a
|
|
58
71
|
background window, while Quartz sends global clicks and keystrokes to whichever
|
|
59
72
|
application is actually frontmost. Use a guarded batch for click-then-type
|
|
60
73
|
workflows so focus is retained and the result is verified in one control loop.
|
|
61
74
|
|
|
75
|
+
On Windows, standalone mutations and batch entry may activate the target. Once a
|
|
76
|
+
batch starts, validation only checks foreground ownership: detected focus loss
|
|
77
|
+
aborts the batch instead of reactivating the target. This applies during waits,
|
|
78
|
+
between actions, and through final state refresh. Already executed steps are not
|
|
79
|
+
rolled back. These are checkpoint checks, not continuous focus monitoring or
|
|
80
|
+
instant interruption of a blocking native call. See [WINDOWS.md](WINDOWS.md).
|
|
81
|
+
|
|
62
82
|
Pixel clicks and drags use window-local screenshot pixels. The backend converts
|
|
63
83
|
them to global Quartz points using the captured window bounds, so Retina scaling,
|
|
64
84
|
negative display origins, and windows on secondary displays remain consistent.
|
|
@@ -72,7 +92,9 @@ and cursor placement before or after the match.
|
|
|
72
92
|
- Persisted user consent is required before tools are exposed to the model;
|
|
73
93
|
disabling the feature removes them again and blocks future captures/actions.
|
|
74
94
|
- State revisions and element IDs are single-use and expire after 120 seconds.
|
|
75
|
-
-
|
|
95
|
+
- Ordinary physical keyboard/pointer input is not an explicit cancellation signal.
|
|
96
|
+
Windows batches additionally abort on focus loss detected at guard checkpoints.
|
|
97
|
+
Use the dedicated emergency-stop mechanism to request a stop deliberately.
|
|
76
98
|
- Every capture and mutation re-checks the application policy; the emergency
|
|
77
99
|
stop therefore also interrupts a batch at its next action boundary.
|
|
78
100
|
- Password-field values are never returned in snapshots.
|
|
@@ -100,8 +122,8 @@ xcode-select --install
|
|
|
100
122
|
## Test
|
|
101
123
|
|
|
102
124
|
```bash
|
|
103
|
-
uv run ruff check
|
|
104
|
-
uv run pytest tests/
|
|
125
|
+
uv run ruff check code_puppy_core_plugins/computer_use
|
|
126
|
+
uv run pytest tests/test_computer_use_*.py -q --no-cov
|
|
105
127
|
```
|
|
106
128
|
|
|
107
129
|
For a live Ghostty smoke test, launch Code Puppy from Ghostty and ask for
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# Windows Computer Use
|
|
2
|
+
|
|
3
|
+
This is the Windows backend of the existing `computer_use` plugin, not a second
|
|
4
|
+
plugin. It exposes the same twelve tools and `/computer-use` commands as macOS.
|
|
5
|
+
The earlier standalone `windows_desktop` prototype is not needed.
|
|
6
|
+
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
- Windows 10 (1903 or later) or Windows 11 with an unlocked interactive desktop
|
|
10
|
+
and Windows Graphics Capture support. Native wheels must be available for your
|
|
11
|
+
Python/architecture; the live tests used CPython 3.12 on Windows x64.
|
|
12
|
+
- The `computer-use` extra: pywinauto 0.6.9, windows-capture 2.x, and their dependencies.
|
|
13
|
+
pywinauto supplies pywin32/comtypes; Pillow encodes screenshots.
|
|
14
|
+
- A vision-capable model for screenshots/pixel actions.
|
|
15
|
+
- Standard privileges. Do not elevate Code Puppy to bypass application protections.
|
|
16
|
+
|
|
17
|
+
## Install this source change safely
|
|
18
|
+
|
|
19
|
+
The implementation now lives in the upstream **code_puppy_core_plugins** package.
|
|
20
|
+
Do **not** copy this directory into `~/.code_puppy/plugins`: that would register
|
|
21
|
+
another copy of the existing plugin, potentially duplicating hooks and commands.
|
|
22
|
+
|
|
23
|
+
For source testing, replace these placeholders with your checkout locations and
|
|
24
|
+
try an isolated environment first (PowerShell):
|
|
25
|
+
|
|
26
|
+
```powershell
|
|
27
|
+
uv run --isolated --no-project --python 3.12 `
|
|
28
|
+
--with "C:\path\to\code_puppy" `
|
|
29
|
+
--with "C:\path\to\code_puppy_core_plugins[computer-use]" `
|
|
30
|
+
code-puppy
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This uses both modified source packages without replacing your normal Code Puppy
|
|
34
|
+
installation. `--isolated` isolates Python dependencies, **not** your Code Puppy
|
|
35
|
+
configuration: the normal user configuration/plugins and policy still apply.
|
|
36
|
+
If the prototype is installed, disable it with `/windows-desktop disable` before
|
|
37
|
+
using this implementation, and move its directory out of the plugin folder while
|
|
38
|
+
Code Puppy is closed. No prototype consent is silently migrated.
|
|
39
|
+
|
|
40
|
+
Once a plugin release containing this change is published, install its Windows
|
|
41
|
+
dependencies into the same environment as Code Puppy:
|
|
42
|
+
|
|
43
|
+
```powershell
|
|
44
|
+
python -m pip install "code-puppy-core-plugins[computer-use]"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The currently published `code-puppy[computer-use]` extra only supplies macOS
|
|
48
|
+
libraries; it does not yet install Windows dependencies. A companion core
|
|
49
|
+
packaging update can delegate to the plugin extra. Until this plugin change is
|
|
50
|
+
published, use the source checkout above rather than expecting the existing
|
|
51
|
+
published plugin version to contain it.
|
|
52
|
+
|
|
53
|
+
Inside the new session:
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
/computer-use status
|
|
57
|
+
/computer-use enable
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Enable consent yourself, then restart the isolated session to refresh tools.
|
|
61
|
+
Use `/computer-use disable` to revoke consent immediately. The setting is stored
|
|
62
|
+
in the normal `computer_use_policy.json`; existing macOS policy schema is retained.
|
|
63
|
+
Windows writes a protected DACL allowing the current user and LocalSystem, rather
|
|
64
|
+
than pretending POSIX chmod bits enforce Windows permissions.
|
|
65
|
+
|
|
66
|
+
## Workflow and API
|
|
67
|
+
|
|
68
|
+
1. Call `computer_get_app_state(app_name="notepad.exe")`.
|
|
69
|
+
2. Inspect the screenshot and UIA `nodes`. Use only each node's advertised actions.
|
|
70
|
+
3. Use the returned `state_revision` for one mutation or a guarded batch.
|
|
71
|
+
4. Inspect fresh state after every standalone mutation. Successful batches return it.
|
|
72
|
+
|
|
73
|
+
### Batch focus-loss safety
|
|
74
|
+
|
|
75
|
+
A new standalone mutation or batch may activate its explicitly targeted window.
|
|
76
|
+
After Windows batch entry, focus checks never automatically reactivate it. If
|
|
77
|
+
another window is foreground at a guard checkpoint, the batch stops, invalidates
|
|
78
|
+
its revision, and reports completed steps. Pending sentinel actions must not run.
|
|
79
|
+
This includes wait polling (up to 50ms sleeps), action boundaries, and the final
|
|
80
|
+
settling/state-refresh phase. Even final refresh cannot steal focus back.
|
|
81
|
+
|
|
82
|
+
This is checkpoint-based detection: a transient loss and return between checks
|
|
83
|
+
can go unobserved, and a blocking UIA call cannot necessarily be interrupted.
|
|
84
|
+
Completed actions are not rolled back. A provider action that opens another
|
|
85
|
+
window can therefore abort the remainder of its batch; inspect fresh state and
|
|
86
|
+
explicitly target that window in a new request instead of retrying blindly.
|
|
87
|
+
Explicit cancellation, consent/policy, emergency stop, expiry, process identity,
|
|
88
|
+
and geometry guards remain in force. Standalone activation and the macOS backend
|
|
89
|
+
retain their existing behavior.
|
|
90
|
+
|
|
91
|
+
The focus-loss fix has mocked regression coverage, including the serialized UIA
|
|
92
|
+
runtime path, plus a focused public-session retest on `219210a`: the owned sink
|
|
93
|
+
took focus, the batch stopped without reactivation, and the sentinel stayed at
|
|
94
|
+
zero. Cleanup and final owner pause were verified. The original failure remains
|
|
95
|
+
historical evidence. This closes that regression, not all deferred acceptance
|
|
96
|
+
coverage or universal application compatibility.
|
|
97
|
+
|
|
98
|
+
`app_name` accepts an exact executable basename (`notepad.exe`), basename without
|
|
99
|
+
extension (`notepad`), exact window title, full executable path, or `hwnd:NUMBER`.
|
|
100
|
+
An ambiguous match returns matching titles and `hwnd:` selectors instead of guessing
|
|
101
|
+
which document to change. State returns an HWND selector as `application` so a title
|
|
102
|
+
change does not cause subsequent batch verification to target another window.
|
|
103
|
+
|
|
104
|
+
All existing tools are present:
|
|
105
|
+
|
|
106
|
+
- `computer_get_app_state`, `computer_snapshot`, `computer_screenshot`
|
|
107
|
+
- `computer_click`, `computer_set_value`, `computer_perform_action`
|
|
108
|
+
- `computer_select_text`, `computer_press_key`, `computer_type_text`
|
|
109
|
+
- `computer_scroll`, `computer_drag`, `computer_use_batch`
|
|
110
|
+
|
|
111
|
+
Examples:
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{"state_revision":"...","element_id":7,"value":"Updated text"}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{"state_revision":"...","element_id":9,"text":"dog","prefix":"blue ","mode":"cursor_after"}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{"state_revision":"...","steps":[
|
|
123
|
+
{"action":"perform_action","element_id":7,"action_name":"UIASetFocus"},
|
|
124
|
+
{"action":"press_key","key":"a","modifiers":["control"]},
|
|
125
|
+
{"action":"type_text","text":"Literal Unicode text"}
|
|
126
|
+
]}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
The batch discriminator is `action`; `action_name` specifies the UIA/AX operation
|
|
130
|
+
for a `perform_action` step. Use `text`, `cursor_before`, or `cursor_after` for text
|
|
131
|
+
selection. Exact ambiguous matches require prefix/suffix context. Selection uses
|
|
132
|
+
UIA text ranges/endpoints, including text after supplementary Unicode characters.
|
|
133
|
+
|
|
134
|
+
`control`/`ctrl`, `shift`, `option`/`alt`, and `command`/`win` are accepted modifiers.
|
|
135
|
+
**command means the Windows key**, not Ctrl. Use `control` for Windows shortcuts.
|
|
136
|
+
Newline/tab in typed text send Enter/Tab; these can submit a form. The clipboard
|
|
137
|
+
is not modified. Secure-attention and lock-screen shortcuts are blocked.
|
|
138
|
+
|
|
139
|
+
## Multiple displays and DPI
|
|
140
|
+
|
|
141
|
+
Screenshots and x/y action coordinates use original **window-local physical pixels**.
|
|
142
|
+
Native input maps those pixels to global Windows physical coordinates. Portrait
|
|
143
|
+
screens, negative monitor origins, and different display scaling are handled via
|
|
144
|
+
per-thread DPI awareness and DWM visible-frame bounds. Windows display settings are
|
|
145
|
+
never changed. Moving/resizing a window requires fresh state.
|
|
146
|
+
|
|
147
|
+
`action_coordinate_system` and `screenshot_coordinate_system` both describe these
|
|
148
|
+
**window-local** physical pixels. `bounds_coordinate_system` separately identifies
|
|
149
|
+
UIA node bounds and `window_bounds_points` as **global** Windows physical pixels
|
|
150
|
+
(the legacy `window_bounds_points` field name is retained for API compatibility).
|
|
151
|
+
For a window at `(180,180)`, a global control center `(288,292)` corresponds to
|
|
152
|
+
local action coordinates `(108,112)`, not `(288,292)`. Prefer semantic element IDs.
|
|
153
|
+
Earlier development builds incorrectly labeled action coordinates as global;
|
|
154
|
+
that metadata bug is corrected without changing actual click/drag mapping.
|
|
155
|
+
|
|
156
|
+
The live fixture was tested on the user's two 1920x1080 landscape monitors and the
|
|
157
|
+
1440x2560 portrait monitor left of the primary screen, including real pixel clicks
|
|
158
|
+
and drags. These tests cover the current configuration, not every GPU/scaling/RDP
|
|
159
|
+
combination. Capture rejects mismatched frame geometry rather than guessing.
|
|
160
|
+
|
|
161
|
+
## Safety, semantics, and limits
|
|
162
|
+
|
|
163
|
+
- Consent is off by default. `/computer-use pause` stops subsequent operations;
|
|
164
|
+
`/computer-use resume` requires the user to confirm it is safe to continue.
|
|
165
|
+
- Holding **Pause/Break** or moving to the primary display's top-left 2x2 pixels
|
|
166
|
+
is an additional Windows emergency stop. It takes effect at the next check.
|
|
167
|
+
A blocking provider/OS call must return before cooperative cancellation can act.
|
|
168
|
+
- Deny an executable with `/computer-use deny notepad.exe`; allow removes an
|
|
169
|
+
explicit denial. Hardcoded security-process restrictions cannot be removed.
|
|
170
|
+
Locked/UAC/non-default desktops are rejected. This is not a security sandbox.
|
|
171
|
+
- UIA password nodes and protected descendants have names/help/values redacted;
|
|
172
|
+
semantic text operations on them are refused. **Screenshots are not redacted.**
|
|
173
|
+
PNGs/metadata go to the configured model and may be retained in chat/session data.
|
|
174
|
+
- App state activates the target before inspecting it, as macOS does. Explicit
|
|
175
|
+
`computer_screenshot(app_name=...)` captures the HWND in the background without
|
|
176
|
+
activating it or including an overlapping window. Minimized/protected/uncapturable
|
|
177
|
+
windows can fail. There is no desktop-crop or PrintWindow fallback.
|
|
178
|
+
- Semantic click/value/text operations require the relevant UIA patterns. Custom
|
|
179
|
+
controls and some legacy EDIT providers may not implement them. Unsupported is
|
|
180
|
+
returned honestly, not replaced by guessed typing. Pixel clicks/drags and keyboard
|
|
181
|
+
input remain available where the app permits them.
|
|
182
|
+
- Fractional-page scrolling uses UIA ScrollPattern view size and extent. A window
|
|
183
|
+
with no scroll provider returns unsupported; wheel notches are not mislabeled as
|
|
184
|
+
pixels/pages. Horizontal support also depends on the provider.
|
|
185
|
+
- The tree examines at most 2,000 nodes and returns 1-500 nodes, with truncation
|
|
186
|
+
metadata. A stability fingerprint is not proof that the user's task completed.
|
|
187
|
+
- Revisions are single-use and expire after 120 seconds. Batches stop on failure;
|
|
188
|
+
actions are not transactional and cannot undo already delivered input.
|
|
189
|
+
- Screenshots use unique temporary PNG files, like the macOS backend. Explicit
|
|
190
|
+
output paths are never overwritten. WGC startup/frame/cleanup waits are bounded;
|
|
191
|
+
a wedged native driver may retain a daemon cleanup worker until process exit.
|
|
192
|
+
- Inline previews use the same best-effort terminal helper as macOS. Ordinary
|
|
193
|
+
Windows Terminal may not support its protocols; the model still receives the PNG.
|
|
194
|
+
|
|
195
|
+
## Diagnosing background-capture focus changes
|
|
196
|
+
|
|
197
|
+
Explicit Windows screenshots include `foreground_observation.before_capture` and
|
|
198
|
+
`foreground_observation.after_capture`: HWND samples taken immediately around the
|
|
199
|
+
native HWND capture. They do not include subsequent image presentation, terminal
|
|
200
|
+
UI work, compaction, or a later verification shell call. Equal samples do not rule
|
|
201
|
+
out a transient focus change, and different samples do not establish causality.
|
|
202
|
+
|
|
203
|
+
If a separate shell check reports the controller foreground afterward, inspect
|
|
204
|
+
these samples before blaming capture. The screenshot path does not activate or
|
|
205
|
+
restore a foreground window; it must not steal focus back from user activity.
|
|
206
|
+
The interactive acceptance report's controller-focus observation remains unresolved
|
|
207
|
+
until measured with this instrumentation in that session.
|
|
208
|
+
|
|
209
|
+
## Foreground activation troubleshooting
|
|
210
|
+
|
|
211
|
+
Windows can refuse a plain `SetForegroundWindow` request even for a visible,
|
|
212
|
+
allowed target. The backend first tries that API, then requests real UIA
|
|
213
|
+
`SetFocus` on the target when available. It independently checks the foreground
|
|
214
|
+
HWND before proceeding and rechecks policy, cancellation, and process identity.
|
|
215
|
+
It never injects Alt keys, attaches input queues, changes foreground-lock settings,
|
|
216
|
+
or elevates privileges to force activation.
|
|
217
|
+
|
|
218
|
+
If both methods fail, the error includes the requested/current HWND, the Win32
|
|
219
|
+
request result, and whether UIA was attempted. Manually focus the target and get
|
|
220
|
+
fresh state; do not forge revisions or disable focus checks. This recovery is
|
|
221
|
+
provider-dependent, not a promise that Windows will always allow activation.
|
|
222
|
+
|
|
223
|
+
See [FOCUS_INVESTIGATION.md](FOCUS_INVESTIGATION.md) for the reproduced failure and
|
|
224
|
+
verification. Existing sessions must restart to load the source fix.
|
|
225
|
+
|
|
226
|
+
## Tests
|
|
227
|
+
|
|
228
|
+
The checkout's `.venv` is a test environment; normal installation is not altered.
|
|
229
|
+
|
|
230
|
+
```powershell
|
|
231
|
+
.venv\Scripts\python.exe -c "import glob,pytest; raise SystemExit(pytest.main([*glob.glob('tests/test_computer_use*.py'),'-q','--no-cov']))"
|
|
232
|
+
.venv\Scripts\python.exe tests\live_windows_computer_use.py --x 180 --y 180
|
|
233
|
+
.venv\Scripts\python.exe tests\live_windows_computer_use.py --x 2050 --y 180
|
|
234
|
+
.venv\Scripts\python.exe tests\live_windows_computer_use.py --x -1300 --y 180
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Only use coordinates inside your own active monitor layout. The live test creates
|
|
238
|
+
native EDIT, password EDIT, RichEdit, button, checkbox, and solid-color occluder
|
|
239
|
+
fixtures. It uses temporary consent/screenshots and closes only its own processes.
|
|
240
|
+
It does not open or modify existing documents or enable persistent user consent.
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from collections import Counter
|
|
6
|
-
from
|
|
6
|
+
from collections.abc import Callable
|
|
7
|
+
from typing import Any
|
|
7
8
|
|
|
8
9
|
MAX_SCAN_NODES = 4_000
|
|
9
10
|
# Electron embeds its web accessibility tree beneath a deep stack of generic
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Platform selection behind the stable computer_* tool contract.
|
|
2
|
+
|
|
3
|
+
Native frameworks are lazy: importing the plugin never captures the desktop,
|
|
4
|
+
initializes COM, or prompts for accessibility permissions.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
from .backend_types import ComputerUseError
|
|
12
|
+
from .macos_backend import MacOSBackend
|
|
13
|
+
|
|
14
|
+
__all__ = ["ComputerUseError", "MacOSBackend", "backend", "create_backend"]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def create_backend(platform: str | None = None):
|
|
18
|
+
platform = platform or sys.platform
|
|
19
|
+
if platform == "win32":
|
|
20
|
+
from .windows_runtime import WindowsRuntime
|
|
21
|
+
|
|
22
|
+
return WindowsRuntime()
|
|
23
|
+
# Keep the importable macOS backend for existing callers and non-native unit
|
|
24
|
+
# tests. Registration separately gates tools to the two supported platforms.
|
|
25
|
+
return MacOSBackend()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
backend = create_backend()
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""Shared, synchronous batch engine; the async adapter offloads the entire batch."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import math
|
|
6
|
+
import time
|
|
7
|
+
from contextlib import ExitStack
|
|
8
|
+
|
|
9
|
+
from .backend_types import ComputerUseError
|
|
10
|
+
|
|
11
|
+
MAX_BATCH_STEPS = 20
|
|
12
|
+
ACTIONS = {
|
|
13
|
+
"set_value": "set_value",
|
|
14
|
+
"perform_action": "perform_action",
|
|
15
|
+
"select_text": "select_text",
|
|
16
|
+
"press_key": "press_key",
|
|
17
|
+
"type_text": "type_text",
|
|
18
|
+
"scroll": "scroll_pages",
|
|
19
|
+
"drag": "drag_pixel",
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def run_batch(backend, revision, steps, settler):
|
|
24
|
+
if not 1 <= len(steps) <= MAX_BATCH_STEPS:
|
|
25
|
+
return {"success": False, "error": "A batch must contain 1 to 20 steps."}
|
|
26
|
+
completed = []
|
|
27
|
+
initial = None
|
|
28
|
+
scope = ExitStack()
|
|
29
|
+
try:
|
|
30
|
+
batch_scope = getattr(backend, "batch_scope", None)
|
|
31
|
+
if batch_scope is not None:
|
|
32
|
+
scope.enter_context(batch_scope(revision))
|
|
33
|
+
initial = backend.require_state(revision)
|
|
34
|
+
for index, step in enumerate(steps):
|
|
35
|
+
action = str(step.get("action", ""))
|
|
36
|
+
kwargs = {key: value for key, value in step.items() if key != "action"}
|
|
37
|
+
try:
|
|
38
|
+
# Even wait steps honor expiry and emergency pause.
|
|
39
|
+
backend.require_state(revision)
|
|
40
|
+
if action == "wait":
|
|
41
|
+
seconds = float(kwargs.get("seconds", 1))
|
|
42
|
+
if not math.isfinite(seconds) or not 0 <= seconds <= 10:
|
|
43
|
+
raise ComputerUseError(
|
|
44
|
+
"Wait seconds must be finite and within 0..10"
|
|
45
|
+
)
|
|
46
|
+
deadline = time.monotonic() + seconds
|
|
47
|
+
while time.monotonic() < deadline:
|
|
48
|
+
backend.require_state(revision)
|
|
49
|
+
time.sleep(min(0.05, max(0, deadline - time.monotonic())))
|
|
50
|
+
result = {"success": True, "seconds": seconds}
|
|
51
|
+
elif action == "click":
|
|
52
|
+
if "element_id" in kwargs and ("x" in kwargs or "y" in kwargs):
|
|
53
|
+
raise ComputerUseError("Provide element_id or x/y, not both")
|
|
54
|
+
method = (
|
|
55
|
+
backend.click if "element_id" in kwargs else backend.click_pixel
|
|
56
|
+
)
|
|
57
|
+
result = method(revision, consume=False, **kwargs)
|
|
58
|
+
elif action in ACTIONS:
|
|
59
|
+
if action == "perform_action":
|
|
60
|
+
# The outer 'action' is the batch discriminator.
|
|
61
|
+
kwargs["action"] = kwargs.pop("action_name")
|
|
62
|
+
result = getattr(backend, ACTIONS[action])(
|
|
63
|
+
revision, consume=False, **kwargs
|
|
64
|
+
)
|
|
65
|
+
else:
|
|
66
|
+
raise ComputerUseError(f"Unknown action: {action}")
|
|
67
|
+
except Exception as exc: # noqa: BLE001 - stop the batch on any provider failure.
|
|
68
|
+
result = {"success": False, "error": str(exc)}
|
|
69
|
+
completed.append({"index": index, "action": action, "result": result})
|
|
70
|
+
if not result.get("success"):
|
|
71
|
+
backend.invalidate_state()
|
|
72
|
+
return {
|
|
73
|
+
"success": False,
|
|
74
|
+
"completed_steps": completed,
|
|
75
|
+
"warning": "A failed action may have partially executed; inspect before retrying.",
|
|
76
|
+
}
|
|
77
|
+
backend.require_state(revision, consume=True)
|
|
78
|
+
settle = settler(backend.snapshot, initial.application)
|
|
79
|
+
updated = backend.get_app_state(initial.application, 100)
|
|
80
|
+
if not updated.get("success"):
|
|
81
|
+
return {
|
|
82
|
+
"success": True,
|
|
83
|
+
"completed_steps": completed,
|
|
84
|
+
"updated_state_error": updated.get("error"),
|
|
85
|
+
}
|
|
86
|
+
updated["completed_steps"] = completed
|
|
87
|
+
updated["ui_settle"] = settle
|
|
88
|
+
return updated
|
|
89
|
+
except Exception as exc: # noqa: BLE001 - stop the batch on any provider failure.
|
|
90
|
+
backend.invalidate_state()
|
|
91
|
+
return {"success": False, "error": str(exc), "completed_steps": completed}
|
|
92
|
+
finally:
|
|
93
|
+
scope.close()
|
|
@@ -4,8 +4,10 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import shlex
|
|
6
6
|
|
|
7
|
+
from code_puppy.i18n import t
|
|
7
8
|
from code_puppy.messaging import emit_error, emit_info, emit_success, emit_warning
|
|
8
9
|
|
|
10
|
+
from .backend_types import ComputerUseError
|
|
9
11
|
from .policy import policy_store
|
|
10
12
|
|
|
11
13
|
|
|
@@ -13,12 +15,20 @@ def command_help() -> list[tuple[str, str]]:
|
|
|
13
15
|
return [
|
|
14
16
|
(
|
|
15
17
|
"computer-use",
|
|
16
|
-
"
|
|
18
|
+
t("plugin.computer-use.command.help"),
|
|
17
19
|
)
|
|
18
20
|
]
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
def handle_command(command: str, name: str) -> bool | None:
|
|
24
|
+
try:
|
|
25
|
+
return _handle_command(command, name)
|
|
26
|
+
except (ComputerUseError, OSError) as exc:
|
|
27
|
+
emit_error(str(exc))
|
|
28
|
+
return True
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _handle_command(command: str, name: str) -> bool | None:
|
|
22
32
|
if name != "computer-use":
|
|
23
33
|
return None
|
|
24
34
|
try:
|
|
@@ -46,7 +56,7 @@ def handle_command(command: str, name: str) -> bool | None:
|
|
|
46
56
|
emit_success("Computer Use resumed.")
|
|
47
57
|
elif subcommand in {"allow", "deny"}:
|
|
48
58
|
if len(tokens) < 3:
|
|
49
|
-
emit_error("
|
|
59
|
+
emit_error(t("plugin.computer-use.command.policy_usage"))
|
|
50
60
|
return True
|
|
51
61
|
bundle_id = tokens[2]
|
|
52
62
|
if subcommand == "deny":
|