code-puppy 0.0.325__tar.gz → 0.0.326__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.325 → code_puppy-0.0.326}/PKG-INFO +1 -1
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/base_agent.py +11 -63
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/cli_runner.py +1 -2
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/keymap.py +2 -8
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/tools/command_runner.py +21 -48
- {code_puppy-0.0.325 → code_puppy-0.0.326}/pyproject.toml +1 -1
- {code_puppy-0.0.325 → code_puppy-0.0.326}/.gitignore +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/LICENSE +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/README.md +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/__init__.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/__main__.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/__init__.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/agent_c_reviewer.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/agent_code_puppy.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/agent_code_reviewer.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/agent_cpp_reviewer.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/agent_creator_agent.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/agent_golang_reviewer.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/agent_javascript_reviewer.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/agent_manager.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/agent_planning.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/agent_python_programmer.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/agent_python_reviewer.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/agent_qa_expert.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/agent_qa_kitten.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/agent_security_auditor.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/agent_typescript_reviewer.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/json_agent.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/agents/prompt_reviewer.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/callbacks.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/chatgpt_codex_client.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/claude_cache_client.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/__init__.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/add_model_menu.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/attachments.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/autosave_menu.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/colors_menu.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/command_handler.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/command_registry.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/config_commands.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/core_commands.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/diff_menu.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/file_path_completion.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/load_context_completion.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/__init__.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/add_command.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/base.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/catalog_server_installer.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/custom_server_form.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/custom_server_installer.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/edit_command.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/handler.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/help_command.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/install_command.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/install_menu.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/list_command.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/logs_command.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/remove_command.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/restart_command.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/search_command.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/start_all_command.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/start_command.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/status_command.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/stop_all_command.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/stop_command.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/test_command.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/utils.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/wizard_utils.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp_completion.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/model_picker_completion.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/model_settings_menu.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/motd.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/pin_command_completion.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/prompt_toolkit_completion.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/session_commands.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/utils.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/config.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/error_logging.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/gemini_code_assist.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/http_utils.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/main.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/__init__.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/async_lifecycle.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/blocking_startup.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/captured_stdio_server.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/circuit_breaker.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/config_wizard.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/dashboard.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/error_isolation.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/examples/retry_example.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/health_monitor.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/managed_server.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/manager.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/mcp_logs.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/registry.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/retry_manager.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/server_registry_catalog.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/status_tracker.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/mcp_/system_tools.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/messaging/__init__.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/messaging/bus.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/messaging/commands.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/messaging/markdown_patches.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/messaging/message_queue.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/messaging/messages.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/messaging/queue_console.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/messaging/renderers.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/messaging/rich_renderer.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/messaging/spinner/__init__.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/messaging/spinner/console_spinner.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/messaging/spinner/spinner_base.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/model_factory.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/model_utils.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/models.json +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/models_dev_api.json +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/models_dev_parser.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/__init__.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/chatgpt_oauth/__init__.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/chatgpt_oauth/config.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/chatgpt_oauth/oauth_flow.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/chatgpt_oauth/register_callbacks.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/chatgpt_oauth/test_plugin.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/chatgpt_oauth/utils.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/claude_code_oauth/README.md +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/claude_code_oauth/SETUP.md +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/claude_code_oauth/__init__.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/claude_code_oauth/config.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/claude_code_oauth/register_callbacks.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/claude_code_oauth/test_plugin.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/claude_code_oauth/utils.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/customizable_commands/__init__.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/customizable_commands/register_callbacks.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/example_custom_command/README.md +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/example_custom_command/register_callbacks.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/file_permission_handler/__init__.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/file_permission_handler/register_callbacks.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/oauth_puppy_html.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/shell_safety/__init__.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/shell_safety/agent_shell_safety.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/shell_safety/command_cache.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/shell_safety/register_callbacks.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/prompts/codex_system_prompt.md +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/pydantic_patches.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/reopenable_async_client.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/round_robin_model.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/session_storage.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/status_display.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/summarization_agent.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/terminal_utils.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/tools/__init__.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/tools/agent_tools.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/tools/browser/__init__.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/tools/browser/browser_control.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/tools/browser/browser_interactions.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/tools/browser/browser_locators.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/tools/browser/browser_navigation.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/tools/browser/browser_screenshot.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/tools/browser/browser_scripts.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/tools/browser/browser_workflows.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/tools/browser/camoufox_manager.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/tools/browser/vqa_agent.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/tools/common.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/tools/file_modifications.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/tools/file_operations.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/tools/tools_content.py +0 -0
- {code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/version_checker.py +0 -0
|
@@ -4,7 +4,6 @@ import asyncio
|
|
|
4
4
|
import json
|
|
5
5
|
import math
|
|
6
6
|
import signal
|
|
7
|
-
import sys
|
|
8
7
|
import threading
|
|
9
8
|
import uuid
|
|
10
9
|
from abc import ABC, abstractmethod
|
|
@@ -1957,69 +1956,27 @@ class BaseAgent(ABC):
|
|
|
1957
1956
|
from code_puppy.keymap import get_cancel_agent_display_name
|
|
1958
1957
|
|
|
1959
1958
|
cancel_key = get_cancel_agent_display_name()
|
|
1960
|
-
|
|
1961
|
-
# On Windows, we use keyboard listener, so SIGINT might still fire
|
|
1962
|
-
# but we handle cancellation via the key listener
|
|
1963
|
-
pass # Silent on Windows - the key listener handles it
|
|
1964
|
-
else:
|
|
1965
|
-
emit_info(f"Use {cancel_key} to cancel the agent task.")
|
|
1959
|
+
emit_info(f"Use {cancel_key} to cancel the agent task.")
|
|
1966
1960
|
|
|
1967
1961
|
original_handler = None
|
|
1968
1962
|
key_listener_stop_event = None
|
|
1969
1963
|
_key_listener_thread = None
|
|
1970
|
-
_windows_ctrl_handler = None # Store reference to prevent garbage collection
|
|
1971
1964
|
|
|
1972
1965
|
try:
|
|
1973
|
-
if
|
|
1974
|
-
#
|
|
1975
|
-
import ctypes
|
|
1976
|
-
|
|
1977
|
-
# Define the handler function type
|
|
1978
|
-
HANDLER_ROUTINE = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.c_ulong)
|
|
1979
|
-
|
|
1980
|
-
def windows_ctrl_handler(ctrl_type):
|
|
1981
|
-
"""Handle Windows console control events."""
|
|
1982
|
-
CTRL_C_EVENT = 0
|
|
1983
|
-
CTRL_BREAK_EVENT = 1
|
|
1984
|
-
|
|
1985
|
-
if ctrl_type in (CTRL_C_EVENT, CTRL_BREAK_EVENT):
|
|
1986
|
-
# Check if we're awaiting user input
|
|
1987
|
-
if is_awaiting_user_input():
|
|
1988
|
-
return False # Let default handler run
|
|
1989
|
-
|
|
1990
|
-
# Schedule agent cancellation
|
|
1991
|
-
schedule_agent_cancel()
|
|
1992
|
-
return True # We handled it, don't terminate
|
|
1993
|
-
|
|
1994
|
-
return False # Let other handlers process it
|
|
1995
|
-
|
|
1996
|
-
# Create the callback - must keep reference alive!
|
|
1997
|
-
_windows_ctrl_handler = HANDLER_ROUTINE(windows_ctrl_handler)
|
|
1998
|
-
|
|
1999
|
-
# Register the handler
|
|
2000
|
-
kernel32 = ctypes.windll.kernel32
|
|
2001
|
-
if not kernel32.SetConsoleCtrlHandler(_windows_ctrl_handler, True):
|
|
2002
|
-
emit_warning("Failed to set Windows Ctrl+C handler")
|
|
2003
|
-
|
|
2004
|
-
# Also spawn keyboard listener for Ctrl+X (shell cancel) and other keys
|
|
2005
|
-
key_listener_stop_event = threading.Event()
|
|
2006
|
-
_key_listener_thread = self._spawn_ctrl_x_key_listener(
|
|
2007
|
-
key_listener_stop_event,
|
|
2008
|
-
on_escape=lambda: None, # Ctrl+X handled by command_runner
|
|
2009
|
-
on_cancel_agent=None, # Ctrl+C handled by SetConsoleCtrlHandler above
|
|
2010
|
-
)
|
|
2011
|
-
elif cancel_agent_uses_signal():
|
|
2012
|
-
# Unix with Ctrl+C: Use SIGINT-based cancellation
|
|
1966
|
+
if cancel_agent_uses_signal():
|
|
1967
|
+
# Use SIGINT-based cancellation (default Ctrl+C behavior)
|
|
2013
1968
|
original_handler = signal.signal(
|
|
2014
1969
|
signal.SIGINT, keyboard_interrupt_handler
|
|
2015
1970
|
)
|
|
2016
1971
|
else:
|
|
2017
|
-
#
|
|
1972
|
+
# Use keyboard listener for agent cancellation
|
|
1973
|
+
# Set a graceful SIGINT handler that shows a hint
|
|
2018
1974
|
original_handler = signal.signal(signal.SIGINT, graceful_sigint_handler)
|
|
1975
|
+
# Spawn keyboard listener with the cancel agent callback
|
|
2019
1976
|
key_listener_stop_event = threading.Event()
|
|
2020
1977
|
_key_listener_thread = self._spawn_ctrl_x_key_listener(
|
|
2021
1978
|
key_listener_stop_event,
|
|
2022
|
-
on_escape=lambda: None,
|
|
1979
|
+
on_escape=lambda: None, # Ctrl+X handled by command_runner
|
|
2023
1980
|
on_cancel_agent=schedule_agent_cancel,
|
|
2024
1981
|
)
|
|
2025
1982
|
|
|
@@ -2044,17 +2001,8 @@ class BaseAgent(ABC):
|
|
|
2044
2001
|
# Stop keyboard listener if it was started
|
|
2045
2002
|
if key_listener_stop_event is not None:
|
|
2046
2003
|
key_listener_stop_event.set()
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
import ctypes
|
|
2052
|
-
|
|
2053
|
-
kernel32 = ctypes.windll.kernel32
|
|
2054
|
-
kernel32.SetConsoleCtrlHandler(_windows_ctrl_handler, False)
|
|
2055
|
-
except Exception:
|
|
2056
|
-
pass # Best effort cleanup
|
|
2057
|
-
|
|
2058
|
-
# Restore original signal handler (Unix)
|
|
2059
|
-
if original_handler is not None:
|
|
2004
|
+
# Restore original signal handler
|
|
2005
|
+
if (
|
|
2006
|
+
original_handler is not None
|
|
2007
|
+
): # Explicit None check - SIG_DFL can be 0/falsy!
|
|
2060
2008
|
signal.signal(signal.SIGINT, original_handler)
|
|
@@ -790,6 +790,5 @@ def main_entry():
|
|
|
790
790
|
DBOS.destroy()
|
|
791
791
|
return 0
|
|
792
792
|
finally:
|
|
793
|
-
# Reset terminal on
|
|
794
|
-
reset_windows_terminal_full() # Safe no-op on non-Windows
|
|
793
|
+
# Reset terminal on Unix-like systems (not Windows)
|
|
795
794
|
reset_unix_terminal()
|
|
@@ -86,15 +86,9 @@ def cancel_agent_uses_signal() -> bool:
|
|
|
86
86
|
"""Check if the cancel agent key uses SIGINT (Ctrl+C).
|
|
87
87
|
|
|
88
88
|
Returns:
|
|
89
|
-
True if the cancel key is ctrl+c
|
|
90
|
-
|
|
89
|
+
True if the cancel key is ctrl+c (uses SIGINT handler),
|
|
90
|
+
False if it uses keyboard listener approach.
|
|
91
91
|
"""
|
|
92
|
-
import sys
|
|
93
|
-
|
|
94
|
-
# On Windows, always use keyboard listener - SIGINT is unreliable
|
|
95
|
-
if sys.platform == "win32":
|
|
96
|
-
return False
|
|
97
|
-
|
|
98
92
|
return get_cancel_agent_key() == "ctrl+c"
|
|
99
93
|
|
|
100
94
|
|
|
@@ -192,11 +192,6 @@ def kill_all_running_shell_processes() -> int:
|
|
|
192
192
|
"""Kill all currently tracked running shell processes and stop reader threads.
|
|
193
193
|
|
|
194
194
|
Returns the number of processes signaled.
|
|
195
|
-
|
|
196
|
-
Implementation notes:
|
|
197
|
-
- Atomically snapshot and clear the registry to prevent race conditions
|
|
198
|
-
- Deduplicate by PID to ensure each process is killed at most once
|
|
199
|
-
- Let exceptions from _kill_process_group propagate (tests expect this)
|
|
200
195
|
"""
|
|
201
196
|
global _READER_STOP_EVENT
|
|
202
197
|
|
|
@@ -204,52 +199,30 @@ def kill_all_running_shell_processes() -> int:
|
|
|
204
199
|
if _READER_STOP_EVENT:
|
|
205
200
|
_READER_STOP_EVENT.set()
|
|
206
201
|
|
|
207
|
-
|
|
208
|
-
# This prevents other threads from seeing/processing the same processes
|
|
202
|
+
procs: list[subprocess.Popen]
|
|
209
203
|
with _RUNNING_PROCESSES_LOCK:
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
# Deduplicate by pid to ensure at-most-one kill per process
|
|
214
|
-
seen_pids: set = set()
|
|
215
|
-
killed_count = 0
|
|
216
|
-
|
|
217
|
-
for proc in procs_snapshot:
|
|
218
|
-
if proc is None:
|
|
219
|
-
continue
|
|
220
|
-
|
|
221
|
-
pid = getattr(proc, "pid", None)
|
|
222
|
-
key = pid if pid is not None else id(proc)
|
|
223
|
-
|
|
224
|
-
if key in seen_pids:
|
|
225
|
-
continue
|
|
226
|
-
seen_pids.add(key)
|
|
227
|
-
|
|
228
|
-
# Close pipes first to unblock readline()
|
|
204
|
+
procs = list(_RUNNING_PROCESSES)
|
|
205
|
+
count = 0
|
|
206
|
+
for p in procs:
|
|
229
207
|
try:
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
if proc.poll() is None:
|
|
241
|
-
# Let exceptions bubble up (tests expect this behavior)
|
|
242
|
-
_kill_process_group(proc)
|
|
243
|
-
killed_count += 1
|
|
244
|
-
|
|
245
|
-
# Track user-killed PIDs
|
|
246
|
-
if pid is not None:
|
|
247
|
-
try:
|
|
248
|
-
_USER_KILLED_PROCESSES.add(pid)
|
|
249
|
-
except Exception:
|
|
250
|
-
pass # Non-fatal bookkeeping
|
|
208
|
+
# Close pipes first to unblock readline()
|
|
209
|
+
try:
|
|
210
|
+
if p.stdout and not p.stdout.closed:
|
|
211
|
+
p.stdout.close()
|
|
212
|
+
if p.stderr and not p.stderr.closed:
|
|
213
|
+
p.stderr.close()
|
|
214
|
+
if p.stdin and not p.stdin.closed:
|
|
215
|
+
p.stdin.close()
|
|
216
|
+
except (OSError, ValueError):
|
|
217
|
+
pass
|
|
251
218
|
|
|
252
|
-
|
|
219
|
+
if p.poll() is None:
|
|
220
|
+
_kill_process_group(p)
|
|
221
|
+
count += 1
|
|
222
|
+
_USER_KILLED_PROCESSES.add(p.pid)
|
|
223
|
+
finally:
|
|
224
|
+
_unregister_process(p)
|
|
225
|
+
return count
|
|
253
226
|
|
|
254
227
|
|
|
255
228
|
def get_running_shell_process_count() -> int:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/load_context_completion.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/catalog_server_installer.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/mcp/custom_server_installer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/model_picker_completion.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/command_line/prompt_toolkit_completion.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/chatgpt_oauth/register_callbacks.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/claude_code_oauth/register_callbacks.py
RENAMED
|
File without changes
|
{code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/claude_code_oauth/test_plugin.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/customizable_commands/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/example_custom_command/README.md
RENAMED
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/file_permission_handler/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/shell_safety/agent_shell_safety.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.325 → code_puppy-0.0.326}/code_puppy/plugins/shell_safety/register_callbacks.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|