code-puppy 0.0.618__tar.gz → 0.0.620__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.618 → code_puppy-0.0.620}/PKG-INFO +2 -1
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/_runtime.py +11 -2
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/agent_manager.py +36 -5
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/json_agent.py +1 -1
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/callbacks.py +64 -11
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/config.py +19 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/manager.py +11 -0
- code_puppy-0.0.620/code_puppy/plugins/acp/README.md +266 -0
- code_puppy-0.0.620/code_puppy/plugins/acp/__init__.py +8 -0
- code_puppy-0.0.620/code_puppy/plugins/acp/agent.py +456 -0
- code_puppy-0.0.620/code_puppy/plugins/acp/bridge.py +311 -0
- code_puppy-0.0.620/code_puppy/plugins/acp/capabilities.py +73 -0
- code_puppy-0.0.620/code_puppy/plugins/acp/commands.py +116 -0
- code_puppy-0.0.620/code_puppy/plugins/acp/content.py +115 -0
- code_puppy-0.0.620/code_puppy/plugins/acp/io_delegation.py +231 -0
- code_puppy-0.0.620/code_puppy/plugins/acp/mcp_config.py +66 -0
- code_puppy-0.0.620/code_puppy/plugins/acp/permissions.py +160 -0
- code_puppy-0.0.620/code_puppy/plugins/acp/persistence.py +197 -0
- code_puppy-0.0.620/code_puppy/plugins/acp/register_callbacks.py +110 -0
- code_puppy-0.0.620/code_puppy/plugins/acp/replay.py +114 -0
- code_puppy-0.0.620/code_puppy/plugins/acp/session.py +294 -0
- code_puppy-0.0.620/code_puppy/plugins/acp/session_config.py +180 -0
- code_puppy-0.0.620/code_puppy/plugins/acp/state.py +137 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/config.py +43 -1
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/file_permission_handler/register_callbacks.py +141 -4
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/plugin_list/plugins_menu.py +30 -3
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/plugin_list/plugins_menu_render.py +14 -1
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/agent_tools.py +1 -1
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/ask_user_question/tui_loop.py +33 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/command_runner.py +67 -2
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/common.py +149 -4
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/file_modifications.py +283 -70
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/file_operations.py +425 -91
- code_puppy-0.0.620/code_puppy/tools/fs_access.py +229 -0
- code_puppy-0.0.620/code_puppy/tools/io_backends.py +186 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/subagent_context.py +37 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/undo_manager.py +14 -8
- {code_puppy-0.0.618 → code_puppy-0.0.620}/pyproject.toml +2 -1
- {code_puppy-0.0.618 → code_puppy-0.0.620}/.gitignore +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/LICENSE +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/README.md +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/__main__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/_builder.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/_compaction.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/_diagnostics.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/_history.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/_key_listeners.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/_non_streaming_render.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/_run_signals.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/_steer_processor.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/agent_code_puppy.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/agent_creator_agent.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/agent_helios.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/agent_planning.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/agent_qa_kitten.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/base_agent.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/event_stream_handler.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/run_stats.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/smooth_stream.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/agents/subagent_stream_handler.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/chatgpt_codex_client.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/claude_cache_client.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/cli_runner.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/add_model_menu.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/agent_menu.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/attachments.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/autosave_menu.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/autosave_search.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/clipboard.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/colors_menu.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/command_handler.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/command_registry.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/config_apply.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/config_commands.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/core_commands.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/diff_menu.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/file_index.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/file_path_completion.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/judges_menu.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/load_context_completion.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/base.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/catalog_server_installer.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/custom_server_form.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/custom_server_installer.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/edit_command.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/handler.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/help_command.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/install_command.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/install_menu.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/list_command.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/logs_command.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/remove_command.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/restart_command.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/search_command.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/silence_warning_command.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/start_all_command.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/start_command.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/status_command.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/stop_all_command.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/stop_command.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/utils.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp/wizard_utils.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp_binding_menu.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/mcp_completion.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/model_picker_completion.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/model_settings_menu.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/onboarding_slides.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/onboarding_wizard.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/pagination.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/pin_command_completion.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/prompt_toolkit_completion.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/session_commands.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/set_menu.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/set_menu_catalog.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/set_menu_render.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/set_menu_schema.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/set_menu_settings.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/set_menu_shims.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/set_menu_values.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/shell_passthrough.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/skills_completion.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/uc_menu.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/utils.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/command_line/wiggum_state.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/error_logging.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/gemini_code_assist.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/gemini_model.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/hook_engine/README.md +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/hook_engine/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/hook_engine/aliases.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/hook_engine/engine.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/hook_engine/executor.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/hook_engine/matcher.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/hook_engine/models.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/hook_engine/registry.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/hook_engine/validator.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/http_utils.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/keymap.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/list_filtering.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/main.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/agent_bindings.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/async_lifecycle.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/blocking_startup.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/captured_stdio_server.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/circuit_breaker.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/config_wizard.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/dashboard.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/error_isolation.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/examples/retry_example.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/health_monitor.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/managed_server.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/mcp_logs.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/registry.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/retry_manager.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/server_registry_catalog.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/status_tracker.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/system_tools.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_/tool_arg_coercion.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_prompts/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/mcp_prompts/hook_creator.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/bar_painters.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/bar_rendering.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/bottom_bar.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/bus.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/chords.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/commands.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/editor_actions.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/editor_completion.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/editor_display.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/editor_history.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/editor_keys.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/editor_paste.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/external_editor.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/line_editor.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/markdown_patches.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/message_queue.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/messages.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/pause_controller.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/prompt_prefix_style.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/queue_console.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/renderers.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/rich_renderer.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/run_ui.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/run_ui_wiring.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/spinner/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/subagent_console.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/messaging/transcript_guard.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/model_descriptions.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/model_factory.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/model_switching.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/model_utils.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/models.json +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/models_dev_api.json +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/models_dev_parser.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/agent_skills/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/agent_skills/config.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/agent_skills/discovery.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/agent_skills/downloader.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/agent_skills/enabled_skills.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/agent_skills/installer.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/agent_skills/metadata.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/agent_skills/prompt_builder.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/agent_skills/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/agent_skills/remote_catalog.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/agent_skills/skill_catalog.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/agent_skills/skill_commands.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/agent_skills/skills_install_menu.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/agent_skills/skills_menu.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/aws_bedrock/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/aws_bedrock/config.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/aws_bedrock/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/aws_bedrock/utils.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/azure_foundry/README.md +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/azure_foundry/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/azure_foundry/config.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/azure_foundry/discovery.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/azure_foundry/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/azure_foundry/token.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/azure_foundry/utils.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/btw/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/btw/inline_view.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/btw/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/btw/side_query.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/chatgpt_oauth/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/chatgpt_oauth/config.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/chatgpt_oauth/oauth_flow.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/chatgpt_oauth/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/chatgpt_oauth/test_plugin.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/chatgpt_oauth/utils.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/claude_code_hooks/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/claude_code_hooks/config.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/claude_code_hooks/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/claude_code_oauth/README.md +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/claude_code_oauth/SETUP.md +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/claude_code_oauth/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/claude_code_oauth/config.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/claude_code_oauth/fast_mode.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/claude_code_oauth/prompt_handler.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/claude_code_oauth/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/claude_code_oauth/test_fast_mode.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/claude_code_oauth/test_plugin.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/claude_code_oauth/token_refresh_heartbeat.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/claude_code_oauth/utils.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/code_puppy_agent/SKILL.md +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/code_puppy_agent/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/code_puppy_agent/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/context_indicator/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/context_indicator/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/context_indicator/usage.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/copilot_auth/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/copilot_auth/config.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/copilot_auth/reasoning_client.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/copilot_auth/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/copilot_auth/utils.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/customizable_commands/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/customizable_commands/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/dbos_durable_exec/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/dbos_durable_exec/cancel.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/dbos_durable_exec/commands.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/dbos_durable_exec/config.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/dbos_durable_exec/lifecycle.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/dbos_durable_exec/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/dbos_durable_exec/runtime.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/dbos_durable_exec/startup_lock.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/dbos_durable_exec/workflow_ids.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/dbos_durable_exec/wrapper.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/destructive_command_guard/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/destructive_command_guard/detector.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/destructive_command_guard/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/emoji_filter/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/emoji_filter/config.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/emoji_filter/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/emoji_filter/stripper.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/empty_html_comment_filter/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/example_custom_command/README.md +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/example_custom_command/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/file_permission_handler/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/force_push_guard/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/force_push_guard/detector.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/force_push_guard/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/force_push_guard/test_detector.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/fork/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/fork/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/frontend_emitter/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/frontend_emitter/emitter.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/frontend_emitter/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/frontend_emitter/session_context.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/grok_oauth/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/grok_oauth/config.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/grok_oauth/oauth_flow.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/grok_oauth/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/grok_oauth/test_plugin.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/grok_oauth/utils.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/herdr/README.md +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/herdr/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/herdr/client.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/herdr/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/herdr/reporter.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/hook_creator/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/hook_creator/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/hook_manager/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/hook_manager/config.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/hook_manager/hooks_menu.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/hook_manager/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/no_tools/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/no_tools/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/oauth_puppy_html.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/obsidian_agent/README.md +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/obsidian_agent/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/obsidian_agent/agent_obsidian.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/obsidian_agent/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/ollama/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/ollama/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/ollama_setup/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/ollama_setup/completer.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/ollama_setup/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/plugin_list/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/plugin_list/plugin_contributions.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/plugin_list/plugin_meta.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/plugin_list/plugin_text_utils.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/plugin_list/plugins_menu_layout.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/plugin_list/project_trust_flow.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/plugin_list/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/pop_command/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/pop_command/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/prompt_newline/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/prompt_newline/config.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/prompt_newline/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/prune/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/prune/prune_menu.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/prune/prune_model.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/prune/prune_render.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/prune/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_kennel/README.md +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_kennel/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_kennel/commands.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_kennel/config.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_kennel/kennel.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_kennel/packer.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_kennel/recorder.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_kennel/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_kennel/retriever.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_kennel/schema.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_kennel/state.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_kennel/tools.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_kennel/wings.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_spinner/README.md +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_spinner/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_spinner/builtin_frames.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_spinner/commands.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_spinner/picker.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_spinner/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/puppy_spinner/spinners.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/quick_resume/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/quick_resume/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/review_pr/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/review_pr/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/shell_safety/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/shell_safety/agent_shell_safety.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/shell_safety/command_cache.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/shell_safety/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/stack_dump/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/stack_dump/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/statusline/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/statusline/config.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/statusline/payload.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/statusline/prompt_patch.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/statusline/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/statusline/runner.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/statusline/statusline_command.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/steer_queue/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/steer_queue/queue_menu.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/steer_queue/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/subagent_panel/README.md +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/subagent_panel/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/subagent_panel/coalesce_patch.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/subagent_panel/panel_render.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/subagent_panel/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/subagent_panel/resume_repaint.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/subagent_panel/state.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/switch_agent_resume/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/switch_agent_resume/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/theme/README.md +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/theme/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/theme/bundled_palettes.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/theme/content_styles.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/theme/osc_palette.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/theme/picker.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/theme/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/theme/rich_themes.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/theme/themes.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/token_ratio_learner/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/token_ratio_learner/ratios.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/token_ratio_learner/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/trust.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/trust_notice.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/universal_constructor/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/universal_constructor/models.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/universal_constructor/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/universal_constructor/registry.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/universal_constructor/sandbox.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/wide_completion_menu/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/wide_completion_menu/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/wiggum/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/wiggum/judge.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/wiggum/judge_config.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/wiggum/register_callbacks.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/plugins/wiggum/state.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/provider_credentials.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/provider_identity.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/pydantic_patches.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/reopenable_async_client.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/round_robin_model.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/session_lifecycle.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/session_migration.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/session_storage.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/status_display.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/summarization_agent.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/terminal_utils.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/ask_user_question/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/ask_user_question/constants.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/ask_user_question/demo_tui.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/ask_user_question/handler.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/ask_user_question/models.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/ask_user_question/registration.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/ask_user_question/renderers.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/ask_user_question/terminal_ui.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/ask_user_question/theme.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/browser/__init__.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/browser/browser_control.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/browser/browser_interactions.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/browser/browser_locator_resolver.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/browser/browser_locators.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/browser/browser_manager.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/browser/browser_navigation.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/browser/browser_page_snapshot.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/browser/browser_screenshot.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/browser/browser_scripts.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/browser/browser_semantic_interactions.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/browser/browser_workflows.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/display.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/image_tools.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/model_tools.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/shell_backgrounding.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/skills_tools.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/subagent_invocation.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/tools_content.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/tools/universal_constructor.py +0 -0
- {code_puppy-0.0.618 → code_puppy-0.0.620}/code_puppy/version_checker.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-puppy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.620
|
|
4
4
|
Summary: Code generation agent
|
|
5
5
|
Project-URL: repository, https://github.com/mpfaffenberger/code_puppy
|
|
6
6
|
Project-URL: HomePage, https://github.com/mpfaffenberger/code_puppy
|
|
@@ -15,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.13
|
|
16
16
|
Classifier: Topic :: Software Development :: Code Generators
|
|
17
17
|
Requires-Python: <3.15,>=3.11
|
|
18
|
+
Requires-Dist: agent-client-protocol<0.12,>=0.11.0
|
|
18
19
|
Requires-Dist: anthropic==0.79.0
|
|
19
20
|
Requires-Dist: azure-identity>=1.15.0
|
|
20
21
|
Requires-Dist: boto3>=1.43.9
|
|
@@ -815,10 +815,19 @@ async def _run_with_mcp_impl(
|
|
|
815
815
|
# console clamp on Windows), ^C arrives as \x03 and the key
|
|
816
816
|
# listener handles cancellation. SIGINT only fires out-of-band
|
|
817
817
|
# (kill -INT, piped stdin with no listener, cooked-mode gaps
|
|
818
|
-
# between raw readers)
|
|
818
|
+
# between raw readers) -- the handler installed here is that
|
|
819
819
|
# fallback: it cancels when ^C IS the cancel gesture, and only
|
|
820
820
|
# hints at the real key when cancel is remapped.
|
|
821
|
-
|
|
821
|
+
#
|
|
822
|
+
# Off the main thread (ACP server, embeds, worker threads) we skip
|
|
823
|
+
# SIGINT wiring entirely: signal handlers are main-thread-only in
|
|
824
|
+
# CPython, so installing one there raises "signal only works in
|
|
825
|
+
# main thread". Cancellation still flows through
|
|
826
|
+
# schedule_agent_cancel, and the stdin key listener no-ops when
|
|
827
|
+
# stdin isn't a TTY, so no cancel affordance is lost.
|
|
828
|
+
if threading.current_thread() is not threading.main_thread():
|
|
829
|
+
pass # original_handler stays None -> restore is a no-op
|
|
830
|
+
elif sigint_fallback_cancels():
|
|
822
831
|
original_handler = signal.signal(
|
|
823
832
|
signal.SIGINT, keyboard_interrupt_handler
|
|
824
833
|
)
|
|
@@ -71,8 +71,16 @@ def _is_process_alive(pid: int) -> bool:
|
|
|
71
71
|
pid: Process ID to check
|
|
72
72
|
|
|
73
73
|
Returns:
|
|
74
|
-
bool: True if process likely exists, False otherwise
|
|
74
|
+
bool: True if process likely exists, False otherwise.
|
|
75
75
|
"""
|
|
76
|
+
try:
|
|
77
|
+
process_id = int(pid)
|
|
78
|
+
except (TypeError, ValueError, OverflowError):
|
|
79
|
+
return False
|
|
80
|
+
|
|
81
|
+
if process_id <= 0:
|
|
82
|
+
return False
|
|
83
|
+
|
|
76
84
|
try:
|
|
77
85
|
if os.name == "nt":
|
|
78
86
|
# Windows: use OpenProcess to probe liveness safely
|
|
@@ -88,7 +96,7 @@ def _is_process_alive(pid: int) -> bool:
|
|
|
88
96
|
]
|
|
89
97
|
kernel32.OpenProcess.restype = wintypes.HANDLE
|
|
90
98
|
handle = kernel32.OpenProcess(
|
|
91
|
-
PROCESS_QUERY_LIMITED_INFORMATION, False,
|
|
99
|
+
PROCESS_QUERY_LIMITED_INFORMATION, False, process_id
|
|
92
100
|
)
|
|
93
101
|
if handle:
|
|
94
102
|
kernel32.CloseHandle(handle)
|
|
@@ -101,7 +109,7 @@ def _is_process_alive(pid: int) -> bool:
|
|
|
101
109
|
return False
|
|
102
110
|
else:
|
|
103
111
|
# Unix-like: signal 0 does not deliver a signal but checks existence
|
|
104
|
-
os.kill(
|
|
112
|
+
os.kill(process_id, 0)
|
|
105
113
|
return True
|
|
106
114
|
except PermissionError:
|
|
107
115
|
# No permission to signal -> process exists
|
|
@@ -182,8 +190,31 @@ def _save_session_data(sessions: dict[str, str]) -> None:
|
|
|
182
190
|
with open(temp_file, "w", encoding="utf-8") as f:
|
|
183
191
|
json.dump(cleaned_sessions, f, indent=2)
|
|
184
192
|
|
|
185
|
-
# Atomic rename (
|
|
186
|
-
|
|
193
|
+
# Atomic rename; on Windows replace() is best-effort if target exists
|
|
194
|
+
try:
|
|
195
|
+
temp_file.replace(session_file)
|
|
196
|
+
except Exception:
|
|
197
|
+
try:
|
|
198
|
+
if session_file.exists():
|
|
199
|
+
session_file.unlink(
|
|
200
|
+
missing_ok=True
|
|
201
|
+
) # Python 3.8+: ignore if missing
|
|
202
|
+
except Exception:
|
|
203
|
+
pass
|
|
204
|
+
try:
|
|
205
|
+
temp_file.replace(session_file)
|
|
206
|
+
except Exception:
|
|
207
|
+
# As a last resort, copy contents
|
|
208
|
+
try:
|
|
209
|
+
with (
|
|
210
|
+
open(temp_file, "r", encoding="utf-8") as rf,
|
|
211
|
+
open(session_file, "w", encoding="utf-8") as wf,
|
|
212
|
+
):
|
|
213
|
+
wf.write(rf.read())
|
|
214
|
+
temp_file.unlink(missing_ok=True)
|
|
215
|
+
except Exception:
|
|
216
|
+
# Give up silently; session persistence isn't critical
|
|
217
|
+
pass
|
|
187
218
|
|
|
188
219
|
except (IOError, OSError):
|
|
189
220
|
# File permission issues, etc. - just continue without persistence
|
|
@@ -15,6 +15,7 @@ PhaseType = Literal[
|
|
|
15
15
|
"delete_snippet",
|
|
16
16
|
"delete_file",
|
|
17
17
|
"run_shell_command",
|
|
18
|
+
"run_shell_command_output",
|
|
18
19
|
"load_model_config",
|
|
19
20
|
"load_models_config",
|
|
20
21
|
"load_model_descriptions",
|
|
@@ -55,6 +56,7 @@ PhaseType = Literal[
|
|
|
55
56
|
"user_prompt_submit",
|
|
56
57
|
"pre_compact",
|
|
57
58
|
"session_end",
|
|
59
|
+
"post_autosave",
|
|
58
60
|
"notification",
|
|
59
61
|
]
|
|
60
62
|
CallbackFunc = Callable[..., Any]
|
|
@@ -71,6 +73,7 @@ _callbacks: Dict[PhaseType, List[CallbackFunc]] = {
|
|
|
71
73
|
"delete_snippet": [],
|
|
72
74
|
"delete_file": [],
|
|
73
75
|
"run_shell_command": [],
|
|
76
|
+
"run_shell_command_output": [],
|
|
74
77
|
"load_model_config": [],
|
|
75
78
|
"load_models_config": [],
|
|
76
79
|
"load_model_descriptions": [],
|
|
@@ -111,6 +114,7 @@ _callbacks: Dict[PhaseType, List[CallbackFunc]] = {
|
|
|
111
114
|
"user_prompt_submit": [],
|
|
112
115
|
"pre_compact": [],
|
|
113
116
|
"session_end": [],
|
|
117
|
+
"post_autosave": [],
|
|
114
118
|
"notification": [],
|
|
115
119
|
}
|
|
116
120
|
|
|
@@ -318,8 +322,8 @@ async def on_startup() -> List[Any]:
|
|
|
318
322
|
return await _trigger_callbacks("startup")
|
|
319
323
|
|
|
320
324
|
|
|
321
|
-
|
|
322
|
-
return
|
|
325
|
+
def on_shutdown() -> List[Any]:
|
|
326
|
+
return _trigger_callbacks_sync("shutdown")
|
|
323
327
|
|
|
324
328
|
|
|
325
329
|
async def on_invoke_agent(*args, **kwargs) -> List[Any]:
|
|
@@ -388,10 +392,24 @@ async def on_run_shell_command(*args, **kwargs) -> Any:
|
|
|
388
392
|
return await _trigger_callbacks("run_shell_command", *args, **kwargs)
|
|
389
393
|
|
|
390
394
|
|
|
395
|
+
async def on_run_shell_command_output(*args, **kwargs) -> Any:
|
|
396
|
+
return await _trigger_callbacks("run_shell_command_output", *args, **kwargs)
|
|
397
|
+
|
|
398
|
+
|
|
391
399
|
def on_agent_reload(*args, **kwargs) -> Any:
|
|
392
400
|
return _trigger_callbacks_sync("agent_reload", *args, **kwargs)
|
|
393
401
|
|
|
394
402
|
|
|
403
|
+
async def on_post_autosave(*args, **kwargs) -> List[Any]:
|
|
404
|
+
"""Fire after an auto-save successfully writes a session.
|
|
405
|
+
|
|
406
|
+
Receives the autosave ``SessionMetadata`` so plugins can render
|
|
407
|
+
follow-up info lines (e.g. remaining token quota) without having
|
|
408
|
+
to reach back into the autosave plumbing themselves.
|
|
409
|
+
"""
|
|
410
|
+
return await _trigger_callbacks("post_autosave", *args, **kwargs)
|
|
411
|
+
|
|
412
|
+
|
|
395
413
|
def on_load_prompt():
|
|
396
414
|
"""Collect load_prompt fragments from plugins, dropping ``None`` results.
|
|
397
415
|
|
|
@@ -440,10 +458,13 @@ def on_file_permission(
|
|
|
440
458
|
message_group: str | None = None,
|
|
441
459
|
operation_data: Any = None,
|
|
442
460
|
) -> List[Any]:
|
|
443
|
-
"""Trigger file permission callbacks.
|
|
461
|
+
"""Trigger file permission callbacks synchronously.
|
|
444
462
|
|
|
445
|
-
This
|
|
446
|
-
|
|
463
|
+
This preserves the original sync ``file_permission`` hook contract for
|
|
464
|
+
terminal/CLI plugins. If a callback is async and no event loop is running,
|
|
465
|
+
it is executed with ``asyncio.run`` by ``_trigger_callbacks_sync``. If an
|
|
466
|
+
event loop is already running, callers that need async callbacks to be
|
|
467
|
+
awaited should use :func:`on_file_permission_async` instead.
|
|
447
468
|
|
|
448
469
|
Args:
|
|
449
470
|
context: The operation context
|
|
@@ -454,8 +475,8 @@ def on_file_permission(
|
|
|
454
475
|
operation_data: Operation-specific data for preview generation (recommended)
|
|
455
476
|
|
|
456
477
|
Returns:
|
|
457
|
-
List of
|
|
458
|
-
|
|
478
|
+
List of permission results. Callers should treat explicit ``False`` as
|
|
479
|
+
denial, ``True`` as approval, and ``None`` as no opinion.
|
|
459
480
|
"""
|
|
460
481
|
# For backward compatibility, if operation_data is provided, prefer it over preview
|
|
461
482
|
if operation_data is not None:
|
|
@@ -471,6 +492,38 @@ def on_file_permission(
|
|
|
471
492
|
)
|
|
472
493
|
|
|
473
494
|
|
|
495
|
+
async def on_file_permission_async(
|
|
496
|
+
context: Any,
|
|
497
|
+
file_path: str,
|
|
498
|
+
operation: str,
|
|
499
|
+
preview: str | None = None,
|
|
500
|
+
message_group: str | None = None,
|
|
501
|
+
operation_data: Any = None,
|
|
502
|
+
) -> List[Any]:
|
|
503
|
+
"""Trigger file permission callbacks from async tool execution.
|
|
504
|
+
|
|
505
|
+
This uses the existing ``file_permission`` hook phase and awaits async
|
|
506
|
+
callbacks while still supporting sync callbacks unchanged. It is intended
|
|
507
|
+
for async file tools, including WebSocket/browser approval flows, where the
|
|
508
|
+
tool must wait for a permission decision without dropping an unawaited
|
|
509
|
+
coroutine. Sync callbacks still run inline, matching existing behavior.
|
|
510
|
+
|
|
511
|
+
Return semantics match :func:`on_file_permission`: explicit ``False``
|
|
512
|
+
denies, ``True`` approves, and ``None`` means no opinion.
|
|
513
|
+
"""
|
|
514
|
+
if operation_data is not None:
|
|
515
|
+
preview = None
|
|
516
|
+
return await _trigger_callbacks(
|
|
517
|
+
"file_permission",
|
|
518
|
+
context,
|
|
519
|
+
file_path,
|
|
520
|
+
operation,
|
|
521
|
+
preview,
|
|
522
|
+
message_group,
|
|
523
|
+
operation_data,
|
|
524
|
+
)
|
|
525
|
+
|
|
526
|
+
|
|
474
527
|
async def on_pre_tool_call(
|
|
475
528
|
tool_name: str, tool_args: dict, context: Any = None
|
|
476
529
|
) -> List[Any]:
|
|
@@ -963,17 +1016,17 @@ def on_register_browser_types() -> List[Any]:
|
|
|
963
1016
|
|
|
964
1017
|
Plugins can register callbacks that return a dict mapping browser type names
|
|
965
1018
|
to initialization functions. This allows plugins to provide custom browser
|
|
966
|
-
implementations (
|
|
1019
|
+
implementations (such as stealth-focused or hardened browsers).
|
|
967
1020
|
|
|
968
1021
|
Each callback should return a dict with:
|
|
969
|
-
- key: str - the browser type name (e.g., "
|
|
1022
|
+
- key: str - the browser type name (e.g., "firefox-stealth", "hardened")
|
|
970
1023
|
- value: callable - async initialization function that takes (manager, **kwargs)
|
|
971
1024
|
and sets up the browser on the manager instance
|
|
972
1025
|
|
|
973
1026
|
Example callback:
|
|
974
1027
|
def register_my_browser_types():
|
|
975
1028
|
return {
|
|
976
|
-
"
|
|
1029
|
+
"firefox-stealth": initialize_firefox_stealth,
|
|
977
1030
|
"my-stealth-browser": initialize_my_stealth,
|
|
978
1031
|
}
|
|
979
1032
|
|
|
@@ -987,7 +1040,7 @@ def on_register_model_providers() -> List[Any]:
|
|
|
987
1040
|
"""Trigger callbacks to register custom model provider classes.
|
|
988
1041
|
|
|
989
1042
|
Plugins can register callbacks that return a dict mapping provider names
|
|
990
|
-
to model classes. Example: {"
|
|
1043
|
+
to model classes. Example: {"my_provider": MyCustomModel}
|
|
991
1044
|
|
|
992
1045
|
Returns:
|
|
993
1046
|
List of dicts from all registered callbacks.
|
|
@@ -1419,6 +1419,25 @@ def get_message_limit(default: int = 1000) -> int:
|
|
|
1419
1419
|
return default
|
|
1420
1420
|
|
|
1421
1421
|
|
|
1422
|
+
def get_command_timeout_seconds() -> int:
|
|
1423
|
+
"""
|
|
1424
|
+
Returns the user-configured absolute timeout for shell commands in seconds.
|
|
1425
|
+
This is the maximum time any single command can run before being terminated.
|
|
1426
|
+
Defaults to 270 seconds if unset or misconfigured.
|
|
1427
|
+
Valid range: 60-900 seconds. Values outside this range default to 270.
|
|
1428
|
+
Configurable by 'command_timeout_seconds' key.
|
|
1429
|
+
"""
|
|
1430
|
+
val = get_value("command_timeout_seconds")
|
|
1431
|
+
try:
|
|
1432
|
+
timeout = int(val) if val else 270
|
|
1433
|
+
# Enforce bounds: min 60, max 900, default 270 if outside bounds
|
|
1434
|
+
if timeout < 60 or timeout > 900:
|
|
1435
|
+
return 270
|
|
1436
|
+
return timeout
|
|
1437
|
+
except (ValueError, TypeError):
|
|
1438
|
+
return 270
|
|
1439
|
+
|
|
1440
|
+
|
|
1422
1441
|
def save_command_to_history(command: str):
|
|
1423
1442
|
"""Save a command to the history file with an ISO format timestamp.
|
|
1424
1443
|
|
|
@@ -174,6 +174,17 @@ class MCPManager:
|
|
|
174
174
|
|
|
175
175
|
for name, conf in configs.items():
|
|
176
176
|
try:
|
|
177
|
+
# The config loader is the single chokepoint for wrapper-key
|
|
178
|
+
# normalization (it accepts both mcp_servers and mcpServers
|
|
179
|
+
# and never returns wrapper keys as server names). Sync only
|
|
180
|
+
# guards against per-entry garbage.
|
|
181
|
+
if not isinstance(conf, dict):
|
|
182
|
+
logger.warning(
|
|
183
|
+
"Skipping MCP server '%s': config must be a dictionary",
|
|
184
|
+
name,
|
|
185
|
+
)
|
|
186
|
+
continue
|
|
187
|
+
|
|
177
188
|
# Create ServerConfig from the loaded configuration
|
|
178
189
|
server_config = ServerConfig(
|
|
179
190
|
id=conf.get("id", ""), # Empty ID will be auto-generated
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# `acp` — Code Puppy as a native ACP agent
|
|
2
|
+
|
|
3
|
+
Run Code Puppy inside any ACP-capable editor's agent panel (e.g.
|
|
4
|
+
[Zed](https://github.com/zed-industries/zed))
|
|
5
|
+
by speaking the **Agent Client Protocol (ACP)** — the same JSON-RPC-over-stdio
|
|
6
|
+
protocol these editors use to host Gemini CLI and Claude Code.
|
|
7
|
+
|
|
8
|
+
This plugin is built on the **official [`agent-client-protocol`](https://pypi.org/project/agent-client-protocol/)
|
|
9
|
+
Python SDK** (`acp`). The SDK owns the wire — stdio binding, JSON-RPC framing,
|
|
10
|
+
typed Pydantic models, and the bidirectional connection — so this plugin is
|
|
11
|
+
pure *behaviour*: mapping ACP sessions to Code Puppy agents, translating
|
|
12
|
+
runtime events into `session/update`s, and routing Code Puppy's I/O + approval
|
|
13
|
+
edges to the client.
|
|
14
|
+
|
|
15
|
+
> **Status:** live over real stdio. Implemented: `initialize`, `session/new`,
|
|
16
|
+
> `session/load` (replays persisted history), `session/prompt`,
|
|
17
|
+
> `session/cancel` (also kills local shells), `session/list`, `session/close`,
|
|
18
|
+
> `session/fork` (duplicates history), `session/resume` (rehydrates across
|
|
19
|
+
restarts), `session/set_mode`, `session/set_config_option`. Assistant text +
|
|
20
|
+
> thinking stream as `agent_message_chunk` / `agent_thought_chunk`; tool calls
|
|
21
|
+
> stream as `tool_call` / `tool_call_update` (with `kind`, file `locations`,
|
|
22
|
+
> friendly titles, and inline diffs); slash commands are advertised via
|
|
23
|
+
> `available_commands_update` **and executed** when the client sends one. Prompt
|
|
24
|
+
> turns report token usage; **image** input is accepted. Client-injected MCP
|
|
25
|
+
> servers and multi-root `additionalDirectories` are honoured. Workspace file
|
|
26
|
+
> I/O and shell delegate to the client (capability-gated), and **permissions**
|
|
27
|
+
> for file writes and shell commands are surfaced in the client's own allow/deny
|
|
28
|
+
> dialog in non-yolo mode.
|
|
29
|
+
>
|
|
30
|
+
> Not implemented: `elicitation/*` (the SDK's connection API exposes no
|
|
31
|
+
> elicitation call in 0.10.1), `plan` updates (Code Puppy has no plan model),
|
|
32
|
+
> and the unstable `document/*` / `nes/*` / `providers/*` surface.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## How the client hosts an external agent
|
|
37
|
+
|
|
38
|
+
1. The client launches the agent as a **subprocess** and talks JSON-RPC 2.0 over the
|
|
39
|
+
process's **stdin/stdout** (stderr is free for logging).
|
|
40
|
+
2. The agent advertises what it can do in an `initialize` handshake; the client
|
|
41
|
+
advertises what *it* can do (read/write files, run terminals, permissions).
|
|
42
|
+
3. The client drives with `session/new` then `session/prompt`; the agent streams
|
|
43
|
+
progress back with `session/update` notifications and can call *back into
|
|
44
|
+
the client* for file I/O, terminals, and permission prompts.
|
|
45
|
+
|
|
46
|
+
This is a **bidirectional** JSON-RPC connection: both sides send requests.
|
|
47
|
+
|
|
48
|
+
### Registering us in a client
|
|
49
|
+
|
|
50
|
+
Registration is client-specific. Example — Zed's `settings.json`:
|
|
51
|
+
|
|
52
|
+
```jsonc
|
|
53
|
+
{
|
|
54
|
+
"agent_servers": {
|
|
55
|
+
"Code Puppy": { "command": "code-puppy", "args": ["--acp"], "env": {} }
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Then "Code Puppy" appears in the agent panel's "New Thread" menu.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Why the official SDK
|
|
65
|
+
|
|
66
|
+
We adopted `agent-client-protocol` instead of hand-rolling JSON-RPC because it
|
|
67
|
+
gives us, maintained and spec-accurate:
|
|
68
|
+
|
|
69
|
+
* **Typed models** for the entire protocol (`InitializeResponse`,
|
|
70
|
+
`SessionNotification`, all content/capability/tool-call types).
|
|
71
|
+
* **`acp.run_agent(agent)`** — binds stdio, frames ndjson JSON-RPC, parses
|
|
72
|
+
params into models, dispatches to our `Agent`, and hands us a `Client`
|
|
73
|
+
connection for talking back.
|
|
74
|
+
* **Update builders** (`update_agent_message_text`, `start_tool_call`, …).
|
|
75
|
+
|
|
76
|
+
Net effect: ~400 lines of hand-rolled transport/framing/capability code
|
|
77
|
+
deleted, correct-by-construction wire behaviour, and a PR that speaks the
|
|
78
|
+
project's own library. Our two small **core seams stay unchanged** — only the
|
|
79
|
+
plugin's protocol layer changed.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Design decisions (locked in)
|
|
84
|
+
|
|
85
|
+
| Decision | Choice |
|
|
86
|
+
|----------|--------|
|
|
87
|
+
| **Protocol layer** | **Official `acp` SDK.** We implement its `Agent` interface; `acp.run_agent` owns stdio + framing. |
|
|
88
|
+
| **Who does I/O** | **Delegated to the client when the client supports it.** Workspace file reads/writes go through the client's `fs/read_text_file` / `fs/write_text_file` (edits land in the client's diff UI; reads see unsaved buffers), and shell commands run via the client's `terminal/*`. This rides two small, general **I/O-backend seams** in core (`code_puppy/tools/io_backends.py`): a sync `FileSystemBackend` and an async `CommandExecutor`, both `None` by default (local I/O) and installed by this plugin, capability-gated, after `initialize`. Internal writes (config, session state, agent metadata) deliberately stay local — only *workspace* edits reroute (via `common.write_project_file`). |
|
|
89
|
+
| **Permissions** | **the client is the authority (non-yolo).** Every approval — file writes and shell commands — is surfaced in the client's own allow/deny dialog via `session/request_permission`. No yolo forcing, no terminal prompts. |
|
|
90
|
+
| **Entry point** | A `--acp` CLI flag contributed via the `register_cli_args` hook; `handle_cli_args` boots the agent (on its own loop, in a thread) and short-circuits normal TUI startup. |
|
|
91
|
+
| **Core footprint** | Small, general, additive core seams — **no monkeypatching**: (1) a pluggable *approval backend* (`common.set_approval_backend`), (2) a *workspace write* wrapper (`common.write_project_file`) + backend-aware `_read_file`, and (3) `FileSystemBackend` / `CommandExecutor` registries (`tools/io_backends.py`). Each is useful to any non-terminal embedder, not ACP-specific. Everything else is this plugin + existing public hooks + the SDK. |
|
|
92
|
+
|
|
93
|
+
### Permissions in non-yolo mode (the important part)
|
|
94
|
+
|
|
95
|
+
Code Puppy has two approval edges. In a headless ACP server there is no TTY, so
|
|
96
|
+
the built-in stdin prompt would **fail closed** (auto-deny every file op — a
|
|
97
|
+
latent bug this integration also fixes). We route both edges to the client *without*
|
|
98
|
+
forcing yolo and *without* patching tool logic:
|
|
99
|
+
|
|
100
|
+
* **File operations** use the **approval-backend seam** in `tools.common`. Sync
|
|
101
|
+
file tools run in Code Puppy's tool threadpool, so the backend
|
|
102
|
+
(`permissions.py`) bridges to the ACP event loop with
|
|
103
|
+
`run_coroutine_threadsafe` to ask the client via the SDK's `request_permission`,
|
|
104
|
+
then blocks the worker thread for the answer. The loop is free to service the
|
|
105
|
+
round-trip → no deadlock (guarded against being called on the loop itself).
|
|
106
|
+
* **Shell commands** use the async `run_shell_command` hook (it runs on the ACP
|
|
107
|
+
loop and can `await` the client directly).
|
|
108
|
+
|
|
109
|
+
Both edges **fail closed** if the connection drops or the client errors.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Module layout
|
|
114
|
+
|
|
115
|
+
Every file stays well under the 600-line cap and owns one concern.
|
|
116
|
+
|
|
117
|
+
| File | Responsibility |
|
|
118
|
+
|------|----------------|
|
|
119
|
+
| `register_callbacks.py` | Register the `--acp` flag; when present, redirect the console to stderr, run `acp.run_agent(CodePuppyAgent())` on its own loop in a thread, and return `{"handled": True}` so the TUI never starts. |
|
|
120
|
+
| `agent.py` | `CodePuppyAgent(acp.Agent)` — the SDK agent implementation: initialize, new/load/resume/fork/list/close session, prompt, cancel, set_session_mode/model, set_config_option, authenticate, plus `on_connect` (stashes the client handle + installs approvals). |
|
|
121
|
+
| `capabilities.py` | Declarative capability negotiation in SDK models: our `AgentCapabilities`, and parsing the client's `ClientCapabilities` into `(fs_read, fs_write, terminal)`. |
|
|
122
|
+
| `content.py` | Parse ACP prompt content blocks → text + multimodal attachments (`BinaryContent` / `ImageUrl`), honouring `embeddedContext` + `image`. |
|
|
123
|
+
| `session.py` | `ACPSession`: one ACP session ⇄ one `BaseAgent` + its `_message_history`. Runs each turn as a cancellable `asyncio.Task`; persists history after each turn; owns the final-result fallback. |
|
|
124
|
+
| `commands.py` | Execute client-typed `/slash` commands via `command_handler`, capturing MessageBus output and forwarding it (never touches stdin). |
|
|
125
|
+
| `persistence.py` | Pickle each session's history under `AUTOSAVE_DIR/acp` keyed by session id, plus an ACP metadata sidecar (`cwd` + `additionalDirectories` + title). Rehydrate on `load`/`resume`/`fork`; enumerate for `session/list` (`list_persisted`); tombstone on `session/close` (`delete`). |
|
|
126
|
+
| `replay.py` | On `load`/`resume`, stream the rehydrated history back to the client as ordered `session/update`s (user / agent text / thinking / past tool calls) so the client rebuilds the thread UI. |
|
|
127
|
+
| `mcp_config.py` | Translate client-injected ACP MCP server specs → pydantic-ai servers on the session agent. |
|
|
128
|
+
| `session_config.py` | Build the model list (surfaced as ACP *modes*) + safe config options; apply `set_mode` / `set_config_option`. |
|
|
129
|
+
| `bridge.py` | `EventBridge`: registers `stream_event` / `pre_tool_call` / `post_tool_call` hooks and translates them into SDK `session/update`s via `connection.session_update`. (Hooks, **not** MessageBus — see *Event source*.) |
|
|
130
|
+
| `permissions.py` | Wires Code Puppy's two approval edges to the client via the SDK's `request_permission`: the `tools.common` approval backend (files, cross-thread) and the `run_shell_command` hook (shell). Fails closed. |
|
|
131
|
+
| `io_delegation.py` | `DelegatedFileSystemBackend` (sync, cross-thread) + `DelegatedCommandExecutor` (async terminal lifecycle) that plug into the core I/O seams, capability-gated. |
|
|
132
|
+
| `state.py` | Process-wide run context: the SDK connection + its loop, the active session id, and the open-tool-call stack — so the permission/I/O seams (plain module functions) can reach the running connection and correlate events. |
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
Client ──stdin──▶ acp.run_agent ──▶ CodePuppyAgent.prompt ──▶ ACPSession ──▶ agent.run_with_mcp
|
|
136
|
+
│
|
|
137
|
+
stream_event / pre_tool_call / post_tool_call hooks fire ─────┘
|
|
138
|
+
│
|
|
139
|
+
▼
|
|
140
|
+
bridge ──▶ connection.session_update ──stdout──▶ the client
|
|
141
|
+
▲
|
|
142
|
+
│ agent needs to read/write/run/ask
|
|
143
|
+
└── permissions / io_delegation ──▶ connection.{request_permission,
|
|
144
|
+
read_text_file, write_text_file, create_terminal, …} ──▶ the client
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Event source: hooks, not the MessageBus
|
|
148
|
+
|
|
149
|
+
Code Puppy's `MessageBus` is **single-consumer** and *buffers* until a renderer
|
|
150
|
+
attaches; agent text streams through pydantic-ai's `event_stream_handler`
|
|
151
|
+
(which fires the `stream_event` callback), not the bus. So the bridge taps the
|
|
152
|
+
**callback hooks** — the same seam the shipping `frontend_emitter` plugin uses:
|
|
153
|
+
|
|
154
|
+
| Hook | Fires with | ACP update |
|
|
155
|
+
|------|-----------|------------|
|
|
156
|
+
| `stream_event` (`part_delta`, `TextPartDelta`) | `event_data.delta.content_delta` | `agent_message_chunk` |
|
|
157
|
+
| `stream_event` (`part_delta`, `ThinkingPartDelta`) | `event_data.delta.content_delta` | `agent_thought_chunk` |
|
|
158
|
+
| `pre_tool_call` | `tool_name`, `tool_args` | `tool_call` (status `in_progress`) |
|
|
159
|
+
| `post_tool_call` | `tool_name`, `result` | `tool_call_update` (status `completed`/`failed`) |
|
|
160
|
+
|
|
161
|
+
Run context (active session id, whether text streamed, the open-tool-call
|
|
162
|
+
stack) lives in `state`, so `bridge`, `permissions`, and `io_delegation` share
|
|
163
|
+
one source of truth. `set_session_context(session_id)` is also set around each
|
|
164
|
+
run so streamed events carry the right session id.
|
|
165
|
+
|
|
166
|
+
### stdout is sacred
|
|
167
|
+
|
|
168
|
+
ACP speaks JSON-RPC on **stdout**, so nothing else may write there. At boot we
|
|
169
|
+
point the streaming console (`set_streaming_console`) and the root logger at
|
|
170
|
+
**stderr**; the interactive path that normally configures the console is
|
|
171
|
+
short-circuited in `--acp` mode.
|
|
172
|
+
|
|
173
|
+
### Streaming-off fallback
|
|
174
|
+
|
|
175
|
+
`use_streaming` is config-gated. When off, no `stream_event` deltas fire, so the
|
|
176
|
+
session sends the return value of `run_with_mcp` as a single final
|
|
177
|
+
`agent_message_chunk`. `state` tracks whether any text streamed so we never
|
|
178
|
+
double-send.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## ACP surface we implement
|
|
183
|
+
|
|
184
|
+
### Inbound (the client → us)
|
|
185
|
+
|
|
186
|
+
| Method | Behaviour |
|
|
187
|
+
|--------|-----------|
|
|
188
|
+
| `initialize` | Negotiate version + capabilities; install capability-gated I/O delegation. |
|
|
189
|
+
| `authenticate` / `logout` | No-op (auth is via Code Puppy's own model config/env). |
|
|
190
|
+
| `session/new` | Create an `ACPSession` (fresh `BaseAgent`) from `cwd` + `additionalDirectories`; attach client `mcpServers`; return models + config options; schedule `available_commands_update`. |
|
|
191
|
+
| `session/load` | Re-open a thread: **replay persisted history into the agent AND stream it back to the client** as `session/update`s so the client rebuilds the thread UI. |
|
|
192
|
+
| `session/resume` | Rehydrate + replay a session across a restart from persisted history. |
|
|
193
|
+
| `session/fork` | Branch a session: copy its history into a new id. Works on a live session **or** one persisted by a prior process (rehydrated from disk), so forking survives a restart. |
|
|
194
|
+
| `session/prompt` | Parse content blocks (text + image attachments) or execute a `/slash` command; run the agent as a cancellable task; stream updates; return stop reason **+ token usage**. |
|
|
195
|
+
| `session/cancel` | Cancel the in-flight run's task **and kill local shells** → `cancelled`. |
|
|
196
|
+
| `session/list` / `session/close` | List sessions (**live in-memory + persisted on disk**, deduped, so threads survive a restart and stay revivable) / drop a session (also deletes its persisted copy). |
|
|
197
|
+
| `session/set_mode` | Switch the active model, rebinding the session agent (history preserved). Code Puppy surfaces its model list as ACP *modes* (0.11 removed the separate models API). |
|
|
198
|
+
| `session/set_config_option` | Apply a safe config change (streaming toggle); never yolo. |
|
|
199
|
+
| `session/set_mode` | No-op (Code Puppy has one mode). |
|
|
200
|
+
|
|
201
|
+
Not implemented: `elicitation/*` (the SDK connection exposes no elicitation
|
|
202
|
+
call in 0.10.1), `plan` updates (no native plan model), and the unstable
|
|
203
|
+
`document/*` / `nes/*` / `providers/*` surface. The SDK router resolves any
|
|
204
|
+
unimplemented method to a clean "method not found", so we advertise honestly
|
|
205
|
+
and stub nothing.
|
|
206
|
+
|
|
207
|
+
### Outbound notifications (us → the client) — `session/update`
|
|
208
|
+
|
|
209
|
+
`agent_message_chunk`, `agent_thought_chunk`, `tool_call`, `tool_call_update`,
|
|
210
|
+
`available_commands_update`. Tool calls carry human-friendly titles
|
|
211
|
+
("Edit foo.py", "Run: pytest"), a `kind`, file `locations`, and — on completion
|
|
212
|
+
— the unified diff as an inline `diff` content block so edits are visible in
|
|
213
|
+
the client's tool-call entry.
|
|
214
|
+
|
|
215
|
+
### Outbound requests (us → the client)
|
|
216
|
+
|
|
217
|
+
`session/request_permission` (approvals), and — when the client advertises the
|
|
218
|
+
capability — `fs/read_text_file`, `fs/write_text_file`, and the `terminal/*`
|
|
219
|
+
family (`create`, `wait_for_exit`, `output`, `kill`, `release`).
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Session & history model
|
|
224
|
+
|
|
225
|
+
- One ACP session id ⇄ one `ACPSession` ⇄ one `BaseAgent` instance.
|
|
226
|
+
- Multi-turn is native: `_message_history` persists across `session/prompt`
|
|
227
|
+
calls within the same session.
|
|
228
|
+
- `cwd` from `session/new` anchors that session's tools.
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Interactive tools (`ask_user_question`)
|
|
233
|
+
|
|
234
|
+
Code Puppy's `ask_user_question` renders a terminal picker and reads stdin —
|
|
235
|
+
neither is available over ACP (stdin *is* the JSON-RPC pipe). The tool's own
|
|
236
|
+
`isatty()` guard already makes it fail closed there (no stdout corruption), but
|
|
237
|
+
the default "not an interactive terminal" error is a dead end.
|
|
238
|
+
|
|
239
|
+
So in ACP mode the `EventBridge` **blocks** `ask_user_question` at the
|
|
240
|
+
`pre_tool_call` seam (before any tool-call entry is opened) and returns guidance
|
|
241
|
+
steering the model to *ask the user directly in its normal text response* — which
|
|
242
|
+
the client renders as a regular assistant message the user can reply to. This is
|
|
243
|
+
the pragmatic stand-in until ACP ratifies structured **elicitation** (currently
|
|
244
|
+
only an [RFD](https://agentclientprotocol.com), not in stable v1 — no client,
|
|
245
|
+
including Zed, implements it yet). When elicitation lands and the SDK exposes a
|
|
246
|
+
connection method for it, this block becomes a real native picker.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Testing
|
|
251
|
+
|
|
252
|
+
`tests/test_acp_plugin.py` drives `CodePuppyAgent` directly against a fake SDK
|
|
253
|
+
connection (no real stdio) and covers:
|
|
254
|
+
|
|
255
|
+
- capability negotiation + client-cap parsing,
|
|
256
|
+
- content-block flattening (incl. embedded resources),
|
|
257
|
+
- lifecycle: initialize / new_session / prompt (stream + fallback) / cancel /
|
|
258
|
+
list / close / unknown-session error,
|
|
259
|
+
- tool-call `kind` / `locations` / pre↔post correlation,
|
|
260
|
+
- the core approval-backend seam (sync + async) + the shell hook,
|
|
261
|
+
- the **cross-thread approval bridge** (worker thread → ACP loop → the client → back),
|
|
262
|
+
- I/O delegation core seams + the client fs/terminal backends (capability-gated).
|
|
263
|
+
|
|
264
|
+
Real end-to-end: `code-puppy --acp` spawned as a subprocess answers
|
|
265
|
+
`initialize` + `session/new` with clean JSON-RPC on stdout. Manual: point a
|
|
266
|
+
real client at `code-puppy --acp` via `agent_servers`.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Code Puppy as a native Agent Client Protocol (ACP) agent.
|
|
2
|
+
|
|
3
|
+
This plugin lets Code Puppy run as an external agent inside the client's agent
|
|
4
|
+
panel by speaking the Agent Client Protocol (ACP) — JSON-RPC 2.0 over
|
|
5
|
+
stdio. See ``README.md`` in this directory for the full design.
|
|
6
|
+
|
|
7
|
+
Boot it with ``code-puppy --acp`` (the client does this for you once configured).
|
|
8
|
+
"""
|