codepp 0.0.438__tar.gz → 0.0.443__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.
- {codepp-0.0.438 → codepp-0.0.443}/.gitignore +12 -0
- {codepp-0.0.438 → codepp-0.0.443}/PKG-INFO +45 -4
- {codepp-0.0.438 → codepp-0.0.443}/README.md +41 -2
- codepp-0.0.443/code_puppy/_backlog.py +53 -0
- codepp-0.0.443/code_puppy/_core_bridge.py +149 -0
- codepp-0.0.443/code_puppy/adaptive_rate_limiter.py +894 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/__init__.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_c_reviewer.py +0 -1
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_code_puppy.py +9 -28
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_code_reviewer.py +0 -1
- codepp-0.0.443/code_puppy/agents/agent_code_scout.py +143 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_cpp_reviewer.py +0 -1
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_creator_agent.py +15 -23
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_golang_reviewer.py +0 -1
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_helios.py +3 -5
- codepp-0.0.443/code_puppy/agents/agent_identity.py +109 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_javascript_reviewer.py +0 -1
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_manager.py +161 -93
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_pack_leader.py +3 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_planning.py +5 -4
- codepp-0.0.443/code_puppy/agents/agent_prompt_mixin.py +116 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_python_programmer.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_python_reviewer.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_qa_expert.py +0 -1
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_qa_kitten.py +2 -3
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_scheduler.py +0 -1
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_security_auditor.py +0 -1
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_terminal_qa.py +1 -2
- codepp-0.0.443/code_puppy/agents/agent_turbo_executor.py +170 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_typescript_reviewer.py +0 -1
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/base_agent.py +773 -503
- codepp-0.0.443/code_puppy/agents/context_compactor.py +337 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/event_stream_handler.py +11 -19
- codepp-0.0.443/code_puppy/agents/history_manager.py +173 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/json_agent.py +9 -13
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/pack/bloodhound.py +4 -3
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/pack/husky.py +5 -8
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/pack/retriever.py +3 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/pack/shepherd.py +4 -6
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/pack/terrier.py +3 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/pack/watchdog.py +4 -3
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/prompt_reviewer.py +4 -3
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/subagent_stream_handler.py +15 -20
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/app.py +5 -10
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/pty_manager.py +17 -23
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/routers/agents.py +3 -3
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/routers/commands.py +11 -15
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/routers/config.py +4 -4
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/routers/sessions.py +64 -26
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/websocket.py +2 -4
- codepp-0.0.443/code_puppy/app_runner.py +396 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/callbacks.py +171 -62
- codepp-0.0.443/code_puppy/capability/__init__.py +76 -0
- codepp-0.0.443/code_puppy/capability/builtin_providers.py +187 -0
- codepp-0.0.443/code_puppy/capability/registry.py +371 -0
- codepp-0.0.443/code_puppy/capability/types.py +84 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/chatgpt_codex_client.py +4 -9
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/claude_cache_client.py +9 -19
- codepp-0.0.443/code_puppy/cli_runner.py +64 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/add_model_menu.py +127 -72
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/agent_menu.py +49 -41
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/attachments.py +12 -19
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/autosave_menu.py +42 -34
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/clipboard.py +14 -21
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/colors_menu.py +21 -25
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/command_handler.py +26 -6
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/command_registry.py +10 -12
- codepp-0.0.443/code_puppy/command_line/concurrency_commands.py +97 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/config_commands.py +21 -42
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/core_commands.py +47 -169
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/diff_menu.py +35 -53
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/file_path_completion.py +22 -23
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/load_context_completion.py +2 -4
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/catalog_server_installer.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/custom_server_form.py +34 -46
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/custom_server_installer.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/edit_command.py +11 -21
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/handler.py +2 -4
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/help_command.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/install_command.py +9 -18
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/install_menu.py +14 -13
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/list_command.py +3 -6
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/logs_command.py +13 -25
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/remove_command.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/restart_command.py +5 -10
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/search_command.py +10 -20
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/start_all_command.py +8 -16
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/start_command.py +8 -16
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/status_command.py +4 -7
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/stop_all_command.py +3 -6
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/stop_command.py +3 -6
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/test_command.py +8 -16
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/utils.py +3 -4
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/wizard_utils.py +15 -25
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp_completion.py +5 -9
- codepp-0.0.443/code_puppy/command_line/model_picker_completion.py +421 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/model_settings_menu.py +83 -59
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/motd.py +5 -5
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/onboarding_slides.py +2 -3
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/onboarding_wizard.py +23 -23
- codepp-0.0.443/code_puppy/command_line/pack_commands.py +101 -0
- codepp-0.0.443/code_puppy/command_line/pagination.py +43 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/pin_command_completion.py +12 -23
- codepp-0.0.443/code_puppy/command_line/preset_commands.py +85 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/prompt_toolkit_completion.py +18 -28
- codepp-0.0.443/code_puppy/command_line/repl_commands.py +174 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/session_commands.py +14 -17
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/shell_passthrough.py +8 -3
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/skills_completion.py +8 -13
- codepp-0.0.443/code_puppy/command_line/staged_commands.py +341 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/uc_menu.py +49 -39
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/utils.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/wiggum_state.py +2 -3
- codepp-0.0.443/code_puppy/command_line/workflow_commands.py +109 -0
- codepp-0.0.443/code_puppy/concurrency_limits.py +265 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/config.py +124 -118
- codepp-0.0.443/code_puppy/config_package/README.md +42 -0
- codepp-0.0.443/code_puppy/config_package/__init__.py +20 -0
- codepp-0.0.443/code_puppy/config_presets.py +238 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/error_logging.py +26 -26
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/gemini_code_assist.py +17 -26
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/gemini_model.py +17 -35
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/__init__.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/aliases.py +11 -11
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/engine.py +21 -29
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/executor.py +29 -32
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/matcher.py +7 -7
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/models.py +21 -21
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/registry.py +5 -6
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/validator.py +8 -8
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/http_utils.py +86 -32
- codepp-0.0.438/code_puppy/cli_runner.py → codepp-0.0.443/code_puppy/interactive_loop.py +71 -553
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/__init__.py +2 -4
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/async_lifecycle.py +10 -14
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/blocking_startup.py +25 -35
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/captured_stdio_server.py +7 -10
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/config_wizard.py +18 -26
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/dashboard.py +5 -8
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/error_isolation.py +6 -6
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/examples/retry_example.py +4 -8
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/health_monitor.py +31 -35
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/managed_server.py +11 -16
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/manager.py +32 -48
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/mcp_logs.py +3 -4
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/registry.py +7 -9
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/retry_manager.py +10 -14
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/server_registry_catalog.py +64 -135
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/status_tracker.py +15 -20
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/system_tools.py +8 -10
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/__init__.py +7 -14
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/bus.py +143 -77
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/commands.py +10 -23
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/markdown_patches.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/message_queue.py +6 -7
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/messages.py +48 -96
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/queue_console.py +19 -25
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/renderers.py +2 -3
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/rich_renderer.py +13 -20
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/spinner/console_spinner.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/subagent_console.py +14 -19
- codepp-0.0.443/code_puppy/model_availability.py +117 -0
- codepp-0.0.443/code_puppy/model_factory.py +1072 -0
- codepp-0.0.443/code_puppy/model_packs.py +455 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/model_switching.py +2 -5
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/model_utils.py +27 -16
- codepp-0.0.443/code_puppy/models.json +134 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/models_dev_parser.py +35 -40
- codepp-0.0.443/code_puppy/permission_decision.py +69 -0
- codepp-0.0.443/code_puppy/persistence.py +233 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/__init__.py +8 -4
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/__init__.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/config.py +2 -3
- codepp-0.0.443/code_puppy/plugins/agent_skills/discovery.py +140 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/downloader.py +16 -30
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/installer.py +1 -3
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/metadata.py +11 -13
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/prompt_builder.py +2 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/register_callbacks.py +11 -14
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/remote_catalog.py +7 -10
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/skill_catalog.py +9 -13
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/skills_install_menu.py +64 -40
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/skills_menu.py +47 -33
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/accounts.py +31 -47
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/antigravity_model.py +17 -35
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/config.py +2 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/constants.py +33 -7
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/oauth.py +19 -33
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/register_callbacks.py +24 -40
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/storage.py +26 -30
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/test_plugin.py +4 -9
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/token.py +14 -24
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/transport.py +18 -30
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/utils.py +9 -11
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/chatgpt_oauth/__init__.py +0 -1
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/chatgpt_oauth/config.py +2 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/chatgpt_oauth/oauth_flow.py +9 -16
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/chatgpt_oauth/register_callbacks.py +9 -14
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/chatgpt_oauth/utils.py +35 -38
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_hooks/config.py +4 -4
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_hooks/register_callbacks.py +12 -19
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_oauth/__init__.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_oauth/config.py +2 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_oauth/register_callbacks.py +34 -42
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_oauth/test_plugin.py +8 -16
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_oauth/token_refresh_heartbeat.py +8 -15
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_oauth/utils.py +36 -48
- codepp-0.0.443/code_puppy/plugins/clean_command/__init__.py +1 -0
- codepp-0.0.443/code_puppy/plugins/clean_command/register_callbacks.py +403 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/customizable_commands/register_callbacks.py +5 -5
- codepp-0.0.443/code_puppy/plugins/error_classifier/DESIGN.md +439 -0
- codepp-0.0.443/code_puppy/plugins/error_classifier/__init__.py +41 -0
- codepp-0.0.443/code_puppy/plugins/error_classifier/builtins.py +300 -0
- codepp-0.0.443/code_puppy/plugins/error_classifier/exinfo.py +59 -0
- codepp-0.0.443/code_puppy/plugins/error_classifier/register_callbacks.py +151 -0
- codepp-0.0.443/code_puppy/plugins/error_classifier/registry.py +169 -0
- codepp-0.0.443/code_puppy/plugins/error_logger/__init__.py +1 -0
- codepp-0.0.443/code_puppy/plugins/error_logger/register_callbacks.py +164 -0
- codepp-0.0.443/code_puppy/plugins/fast_puppy/register_callbacks.py +313 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/file_permission_handler/register_callbacks.py +32 -22
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/frontend_emitter/__init__.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/frontend_emitter/emitter.py +9 -10
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/frontend_emitter/register_callbacks.py +12 -17
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/hook_manager/config.py +20 -25
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/hook_manager/hooks_menu.py +25 -28
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/hook_manager/register_callbacks.py +6 -8
- codepp-0.0.443/code_puppy/plugins/mana_bridge/__init__.py +19 -0
- codepp-0.0.443/code_puppy/plugins/mana_bridge/register_callbacks.py +972 -0
- codepp-0.0.443/code_puppy/plugins/mana_bridge/tcp_client.py +375 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/oauth_puppy_html.py +6 -11
- codepp-0.0.443/code_puppy/plugins/ollama_setup/__init__.py +5 -0
- codepp-0.0.443/code_puppy/plugins/ollama_setup/completer.py +38 -0
- codepp-0.0.443/code_puppy/plugins/ollama_setup/register_callbacks.py +365 -0
- codepp-0.0.443/code_puppy/plugins/pack_parallelism/__init__.py +0 -0
- codepp-0.0.443/code_puppy/plugins/pack_parallelism/register_callbacks.py +196 -0
- codepp-0.0.443/code_puppy/plugins/pop_command/__init__.py +1 -0
- codepp-0.0.443/code_puppy/plugins/pop_command/register_callbacks.py +191 -0
- codepp-0.0.443/code_puppy/plugins/remember_last_agent/__init__.py +9 -0
- codepp-0.0.443/code_puppy/plugins/remember_last_agent/register_callbacks.py +94 -0
- codepp-0.0.443/code_puppy/plugins/remember_last_agent/storage.py +64 -0
- codepp-0.0.443/code_puppy/plugins/repo_compass/DESIGN.md +232 -0
- codepp-0.0.443/code_puppy/plugins/repo_compass/__init__.py +8 -0
- codepp-0.0.443/code_puppy/plugins/repo_compass/config.py +40 -0
- codepp-0.0.443/code_puppy/plugins/repo_compass/formatter.py +38 -0
- codepp-0.0.443/code_puppy/plugins/repo_compass/indexer.py +102 -0
- codepp-0.0.443/code_puppy/plugins/repo_compass/register_callbacks.py +49 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/scheduler/register_callbacks.py +5 -7
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/scheduler/scheduler_menu.py +41 -25
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/scheduler/scheduler_wizard.py +17 -15
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/shell_safety/agent_shell_safety.py +2 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/shell_safety/command_cache.py +9 -11
- codepp-0.0.443/code_puppy/plugins/shell_safety/register_callbacks.py +358 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/synthetic_status/register_callbacks.py +6 -11
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/synthetic_status/status_api.py +3 -7
- codepp-0.0.443/code_puppy/plugins/ttsr/__init__.py +9 -0
- codepp-0.0.443/code_puppy/plugins/ttsr/register_callbacks.py +294 -0
- codepp-0.0.443/code_puppy/plugins/ttsr/rule_loader.py +228 -0
- codepp-0.0.443/code_puppy/plugins/ttsr/stream_watcher.py +277 -0
- codepp-0.0.443/code_puppy/plugins/turbo_executor/__init__.py +33 -0
- codepp-0.0.443/code_puppy/plugins/turbo_executor/models.py +153 -0
- codepp-0.0.443/code_puppy/plugins/turbo_executor/notifications.py +261 -0
- codepp-0.0.443/code_puppy/plugins/turbo_executor/orchestrator.py +470 -0
- codepp-0.0.443/code_puppy/plugins/turbo_executor/register_callbacks.py +461 -0
- codepp-0.0.443/code_puppy/plugins/turbo_executor/summarizer.py +340 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/universal_constructor/models.py +19 -19
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/universal_constructor/registry.py +14 -15
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/universal_constructor/sandbox.py +43 -29
- codepp-0.0.443/code_puppy/policy_config.py +60 -0
- codepp-0.0.443/code_puppy/policy_engine.py +266 -0
- codepp-0.0.443/code_puppy/prompt_runner.py +148 -0
- codepp-0.0.443/code_puppy/provider_identity.py +105 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/pydantic_patches.py +15 -17
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/reopenable_async_client.py +14 -16
- codepp-0.0.443/code_puppy/repl_session.py +384 -0
- codepp-0.0.443/code_puppy/resilience.py +387 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/round_robin_model.py +78 -17
- codepp-0.0.443/code_puppy/routing/__init__.py +20 -0
- codepp-0.0.443/code_puppy/routing/composite.py +78 -0
- codepp-0.0.443/code_puppy/routing/router.py +24 -0
- codepp-0.0.443/code_puppy/routing/strategies/__init__.py +1 -0
- codepp-0.0.443/code_puppy/routing/strategies/availability.py +54 -0
- codepp-0.0.443/code_puppy/routing/strategies/default.py +45 -0
- codepp-0.0.443/code_puppy/routing/strategies/plugin.py +81 -0
- codepp-0.0.443/code_puppy/routing/strategy.py +44 -0
- codepp-0.0.443/code_puppy/run_context.py +262 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/__init__.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/config.py +7 -8
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/daemon.py +5 -9
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/executor.py +4 -7
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/platform.py +2 -4
- codepp-0.0.443/code_puppy/session_storage.py +606 -0
- codepp-0.0.443/code_puppy/staged_changes.py +433 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/status_display.py +3 -7
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/summarization_agent.py +4 -9
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/terminal_utils.py +3 -3
- codepp-0.0.443/code_puppy/token_utils.py +88 -0
- codepp-0.0.443/code_puppy/tool_schema.py +368 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/__init__.py +25 -42
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/agent_tools.py +206 -66
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/__init__.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/constants.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/handler.py +6 -6
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/models.py +16 -33
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/registration.py +3 -4
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/renderers.py +15 -20
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/terminal_ui.py +3 -7
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/theme.py +2 -6
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/tui_loop.py +19 -21
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/__init__.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/browser_control.py +17 -26
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/browser_interactions.py +35 -63
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/browser_locators.py +39 -69
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/browser_manager.py +11 -11
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/browser_navigation.py +19 -25
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/browser_screenshot.py +11 -18
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/browser_scripts.py +23 -43
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/browser_workflows.py +17 -29
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/chromium_terminal_manager.py +8 -11
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/terminal_command_tools.py +20 -32
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/terminal_screenshot_tools.py +163 -59
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/terminal_tools.py +21 -34
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/command_runner.py +87 -89
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/common.py +124 -153
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/display.py +2 -4
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/file_modifications.py +36 -61
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/file_operations.py +50 -51
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/scheduler_tools.py +10 -20
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/skills_tools.py +19 -33
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/tools_content.py +1 -2
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/universal_constructor.py +66 -118
- codepp-0.0.443/code_puppy/tui/__init__.py +12 -0
- codepp-0.0.443/code_puppy/tui/app.py +798 -0
- codepp-0.0.443/code_puppy/tui/base_screen.py +25 -0
- codepp-0.0.443/code_puppy/tui/completion.py +254 -0
- codepp-0.0.443/code_puppy/tui/launcher.py +42 -0
- codepp-0.0.443/code_puppy/tui/message_bridge.py +315 -0
- codepp-0.0.443/code_puppy/tui/screens/__init__.py +5 -0
- codepp-0.0.443/code_puppy/tui/screens/add_model_screen.py +389 -0
- codepp-0.0.443/code_puppy/tui/screens/agent_screen.py +443 -0
- codepp-0.0.443/code_puppy/tui/screens/autosave_screen.py +285 -0
- codepp-0.0.443/code_puppy/tui/screens/colors_screen.py +383 -0
- codepp-0.0.443/code_puppy/tui/screens/diff_screen.py +431 -0
- codepp-0.0.443/code_puppy/tui/screens/hooks_screen.py +220 -0
- codepp-0.0.443/code_puppy/tui/screens/mcp_form_screen.py +383 -0
- codepp-0.0.443/code_puppy/tui/screens/mcp_screen.py +307 -0
- codepp-0.0.443/code_puppy/tui/screens/model_pin_screen.py +104 -0
- codepp-0.0.443/code_puppy/tui/screens/model_screen.py +164 -0
- codepp-0.0.443/code_puppy/tui/screens/model_settings_screen.py +362 -0
- codepp-0.0.443/code_puppy/tui/screens/onboarding_screen.py +169 -0
- codepp-0.0.443/code_puppy/tui/screens/question_screen.py +387 -0
- codepp-0.0.443/code_puppy/tui/screens/scheduler_screen.py +306 -0
- codepp-0.0.443/code_puppy/tui/screens/scheduler_wizard_screen.py +199 -0
- codepp-0.0.443/code_puppy/tui/screens/skills_install_screen.py +267 -0
- codepp-0.0.443/code_puppy/tui/screens/skills_screen.py +299 -0
- codepp-0.0.443/code_puppy/tui/screens/uc_screen.py +373 -0
- codepp-0.0.443/code_puppy/tui/stream_renderer.py +271 -0
- codepp-0.0.443/code_puppy/tui/theme.py +151 -0
- codepp-0.0.443/code_puppy/tui/widgets/__init__.py +8 -0
- codepp-0.0.443/code_puppy/tui/widgets/completion_overlay.py +108 -0
- codepp-0.0.443/code_puppy/tui/widgets/info_bar.py +132 -0
- codepp-0.0.443/code_puppy/tui/widgets/searchable_list.py +256 -0
- codepp-0.0.443/code_puppy/tui/widgets/split_panel.py +47 -0
- codepp-0.0.443/code_puppy/utils/__init__.py +24 -0
- codepp-0.0.443/code_puppy/utils/dag.py +121 -0
- codepp-0.0.443/code_puppy/utils/hashline.py +199 -0
- codepp-0.0.443/code_puppy/utils/parallel.py +179 -0
- codepp-0.0.443/code_puppy/utils/ring_buffer.py +265 -0
- codepp-0.0.443/code_puppy/utils/shell_split.py +90 -0
- codepp-0.0.443/code_puppy/utils/stream_parser.py +188 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/uvx_detection.py +2 -3
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/version_checker.py +1 -2
- codepp-0.0.443/code_puppy/workflow_state.py +381 -0
- {codepp-0.0.438 → codepp-0.0.443}/pyproject.toml +17 -3
- codepp-0.0.438/code_puppy/command_line/model_picker_completion.py +0 -197
- codepp-0.0.438/code_puppy/model_factory.py +0 -848
- codepp-0.0.438/code_puppy/models.json +0 -46
- codepp-0.0.438/code_puppy/plugins/agent_skills/discovery.py +0 -136
- codepp-0.0.438/code_puppy/plugins/shell_safety/register_callbacks.py +0 -202
- codepp-0.0.438/code_puppy/session_storage.py +0 -338
- {codepp-0.0.438 → codepp-0.0.443}/LICENSE +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/__main__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/pack/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/main.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/routers/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/templates/terminal.html +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/base.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/README.md +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/keymap.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/main.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/circuit_breaker.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_prompts/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_prompts/hook_creator.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/spinner/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/spinner/spinner_base.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/models_dev_api.json +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/chatgpt_oauth/test_plugin.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_hooks/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_oauth/README.md +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_oauth/SETUP.md +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/customizable_commands/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/example_custom_command/README.md +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/example_custom_command/register_callbacks.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/file_permission_handler/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/hook_creator/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/hook_creator/register_callbacks.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/hook_manager/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/scheduler/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/shell_safety/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/synthetic_status/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/universal_constructor/__init__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/universal_constructor/register_callbacks.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/prompts/antigravity_system_prompt.md +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/__main__.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/cli.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/platform_unix.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/platform_win.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/demo_tui.py +0 -0
- {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/subagent_context.py +0 -0
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
# User config directory — contains OAuth tokens, session keys, and local state
|
|
2
|
+
# Must NEVER be committed (even if copied/symlinked into the repo)
|
|
3
|
+
.code_puppy/
|
|
4
|
+
|
|
1
5
|
# Python-generated files
|
|
2
6
|
__pycache__/
|
|
3
7
|
*.py[oc]
|
|
@@ -45,3 +49,11 @@ code_puppy/bundled_skills/
|
|
|
45
49
|
.claude/hooks/ts-hooks/dist/
|
|
46
50
|
|
|
47
51
|
.json
|
|
52
|
+
|
|
53
|
+
# Eval log output
|
|
54
|
+
evals/logs/
|
|
55
|
+
|
|
56
|
+
# Beads / Dolt files (added by bd init)
|
|
57
|
+
.dolt/
|
|
58
|
+
*.db
|
|
59
|
+
.beads-credential-key
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codepp
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.443
|
|
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
|
|
@@ -25,10 +25,11 @@ Requires-Dist: fastapi>=0.135.2
|
|
|
25
25
|
Requires-Dist: httpx[http2]>=0.28.1
|
|
26
26
|
Requires-Dist: json-repair>=0.58.7
|
|
27
27
|
Requires-Dist: mcp>=1.26.0
|
|
28
|
+
Requires-Dist: msgpack>=1.0.0
|
|
28
29
|
Requires-Dist: openai>=2.30.0
|
|
29
30
|
Requires-Dist: pillow>=12.1.1
|
|
30
31
|
Requires-Dist: playwright>=1.58.0
|
|
31
|
-
Requires-Dist: prompt-toolkit>=3.0.
|
|
32
|
+
Requires-Dist: prompt-toolkit>=3.0.50
|
|
32
33
|
Requires-Dist: pydantic-ai-slim[anthropic,mcp,openai]==1.60.0
|
|
33
34
|
Requires-Dist: pydantic>=2.12.5
|
|
34
35
|
Requires-Dist: pyfiglet>=1.0.4
|
|
@@ -39,6 +40,7 @@ Requires-Dist: rich>=14.3.3
|
|
|
39
40
|
Requires-Dist: ripgrep==15.0.0
|
|
40
41
|
Requires-Dist: tenacity>=9.1.4
|
|
41
42
|
Requires-Dist: termflow-md>=0.1.9
|
|
43
|
+
Requires-Dist: textual>=8.2.1
|
|
42
44
|
Requires-Dist: typer>=0.24.1
|
|
43
45
|
Requires-Dist: uvicorn[standard]>=0.42.0
|
|
44
46
|
Requires-Dist: websockets>=16.0
|
|
@@ -54,8 +56,6 @@ Description-Content-Type: text/markdown
|
|
|
54
56
|
[](https://pypi.org/project/code-puppy/)
|
|
55
57
|
[](https://python.org)
|
|
56
58
|
[](LICENSE)
|
|
57
|
-
[](https://github.com/mpfaffenberger/code_puppy/actions)
|
|
58
|
-
[](https://github.com/mpfaffenberger/code_puppy/tests)
|
|
59
59
|
|
|
60
60
|
[](https://github.com/mpfaffenberger/code_puppy)
|
|
61
61
|
[](https://github.com/pydantic/pydantic-ai)
|
|
@@ -225,6 +225,47 @@ For examples and more information about agent rules, visit [https://agent.md](ht
|
|
|
225
225
|
|
|
226
226
|
Use the `/mcp` command to manage MCP (list, start, stop, status, etc.)
|
|
227
227
|
|
|
228
|
+
## Security Model: Shell Commands and Plugins
|
|
229
|
+
|
|
230
|
+
### Shell command paths
|
|
231
|
+
|
|
232
|
+
Code Puppy has **two distinct shell execution paths**:
|
|
233
|
+
|
|
234
|
+
1. **Agent tool path** — `agent_run_shell_command`
|
|
235
|
+
- Used by agents and sub-agents
|
|
236
|
+
- Flows through the `run_shell_command` callback hook
|
|
237
|
+
- Can be governed by the `shell_safety` plugin and `PolicyEngine`
|
|
238
|
+
- In non-yolo mode, also supports interactive user confirmation
|
|
239
|
+
|
|
240
|
+
2. **Direct shell passthrough** — `!<command>`
|
|
241
|
+
- Runs a shell command immediately from the user prompt
|
|
242
|
+
- **Bypasses the AI agent entirely**
|
|
243
|
+
- **Does not use the agent/tool safety pipeline**
|
|
244
|
+
- Should be treated like running the command directly in your terminal
|
|
245
|
+
|
|
246
|
+
If you want Code Puppy safety and policy checks, use the agent tool path rather than `!<command>`.
|
|
247
|
+
If you use `!<command>`, you are explicitly choosing direct local execution.
|
|
248
|
+
|
|
249
|
+
### Plugin trust boundary
|
|
250
|
+
|
|
251
|
+
Built-in plugins ship with Code Puppy, but **user plugins are fully trusted local code**.
|
|
252
|
+
Any Python in `~/.code_puppy/plugins/` is imported and executed during plugin discovery.
|
|
253
|
+
That means user plugins can read files, execute processes, modify configuration, and access any data your local Python process can access.
|
|
254
|
+
|
|
255
|
+
Only install or keep user plugins you trust at the same level as other local developer tooling.
|
|
256
|
+
|
|
257
|
+
### Safe-mode expectations
|
|
258
|
+
|
|
259
|
+
At the moment, Code Puppy does **not** provide a fully isolated "safe mode" for user plugins.
|
|
260
|
+
If you need a more locked-down session, the safest current approach is:
|
|
261
|
+
|
|
262
|
+
- remove or rename untrusted directories under `~/.code_puppy/plugins/`
|
|
263
|
+
- avoid `!<command>` passthrough for sensitive workflows
|
|
264
|
+
- prefer non-yolo execution so agent tool calls can be reviewed
|
|
265
|
+
- use policy rules for `agent_run_shell_command` where appropriate
|
|
266
|
+
|
|
267
|
+
A future hardening direction is an explicit user-plugin disable switch and/or policy-aware shell passthrough mode.
|
|
268
|
+
|
|
228
269
|
## Round Robin Model Distribution
|
|
229
270
|
|
|
230
271
|
Code Puppy supports **Round Robin model distribution** to help you overcome rate limits and distribute load across multiple AI models. This feature automatically cycles through configured models with each request, maximizing your API usage while staying within rate limits.
|
|
@@ -8,8 +8,6 @@
|
|
|
8
8
|
[](https://pypi.org/project/code-puppy/)
|
|
9
9
|
[](https://python.org)
|
|
10
10
|
[](LICENSE)
|
|
11
|
-
[](https://github.com/mpfaffenberger/code_puppy/actions)
|
|
12
|
-
[](https://github.com/mpfaffenberger/code_puppy/tests)
|
|
13
11
|
|
|
14
12
|
[](https://github.com/mpfaffenberger/code_puppy)
|
|
15
13
|
[](https://github.com/pydantic/pydantic-ai)
|
|
@@ -179,6 +177,47 @@ For examples and more information about agent rules, visit [https://agent.md](ht
|
|
|
179
177
|
|
|
180
178
|
Use the `/mcp` command to manage MCP (list, start, stop, status, etc.)
|
|
181
179
|
|
|
180
|
+
## Security Model: Shell Commands and Plugins
|
|
181
|
+
|
|
182
|
+
### Shell command paths
|
|
183
|
+
|
|
184
|
+
Code Puppy has **two distinct shell execution paths**:
|
|
185
|
+
|
|
186
|
+
1. **Agent tool path** — `agent_run_shell_command`
|
|
187
|
+
- Used by agents and sub-agents
|
|
188
|
+
- Flows through the `run_shell_command` callback hook
|
|
189
|
+
- Can be governed by the `shell_safety` plugin and `PolicyEngine`
|
|
190
|
+
- In non-yolo mode, also supports interactive user confirmation
|
|
191
|
+
|
|
192
|
+
2. **Direct shell passthrough** — `!<command>`
|
|
193
|
+
- Runs a shell command immediately from the user prompt
|
|
194
|
+
- **Bypasses the AI agent entirely**
|
|
195
|
+
- **Does not use the agent/tool safety pipeline**
|
|
196
|
+
- Should be treated like running the command directly in your terminal
|
|
197
|
+
|
|
198
|
+
If you want Code Puppy safety and policy checks, use the agent tool path rather than `!<command>`.
|
|
199
|
+
If you use `!<command>`, you are explicitly choosing direct local execution.
|
|
200
|
+
|
|
201
|
+
### Plugin trust boundary
|
|
202
|
+
|
|
203
|
+
Built-in plugins ship with Code Puppy, but **user plugins are fully trusted local code**.
|
|
204
|
+
Any Python in `~/.code_puppy/plugins/` is imported and executed during plugin discovery.
|
|
205
|
+
That means user plugins can read files, execute processes, modify configuration, and access any data your local Python process can access.
|
|
206
|
+
|
|
207
|
+
Only install or keep user plugins you trust at the same level as other local developer tooling.
|
|
208
|
+
|
|
209
|
+
### Safe-mode expectations
|
|
210
|
+
|
|
211
|
+
At the moment, Code Puppy does **not** provide a fully isolated "safe mode" for user plugins.
|
|
212
|
+
If you need a more locked-down session, the safest current approach is:
|
|
213
|
+
|
|
214
|
+
- remove or rename untrusted directories under `~/.code_puppy/plugins/`
|
|
215
|
+
- avoid `!<command>` passthrough for sensitive workflows
|
|
216
|
+
- prefer non-yolo execution so agent tool calls can be reviewed
|
|
217
|
+
- use policy rules for `agent_run_shell_command` where appropriate
|
|
218
|
+
|
|
219
|
+
A future hardening direction is an explicit user-plugin disable switch and/or policy-aware shell passthrough mode.
|
|
220
|
+
|
|
182
221
|
## Round Robin Model Distribution
|
|
183
222
|
|
|
184
223
|
Code Puppy supports **Round Robin model distribution** to help you overcome rate limits and distribute load across multiple AI models. This feature automatically cycles through configured models with each request, maximizing your API usage while staying within rate limits.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""Event backlog for callbacks fired before listeners register.
|
|
2
|
+
|
|
3
|
+
During plugin startup, callbacks may fire for phases that have no listeners
|
|
4
|
+
yet (because the plugin that registers the listener hasn't loaded). This
|
|
5
|
+
module buffers those calls and replays them once listeners are available.
|
|
6
|
+
|
|
7
|
+
Inspired by Gemini CLI's CoreEventEmitter._emitOrQueue() pattern.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from collections import deque
|
|
11
|
+
|
|
12
|
+
# Lazy-import PhaseType to avoid circular deps at module scope
|
|
13
|
+
_MAX_BACKLOG_PER_PHASE = 100
|
|
14
|
+
|
|
15
|
+
# phase -> deque of (args_tuple, kwargs_dict) that were fired with no listeners
|
|
16
|
+
_backlog: dict[str, deque[tuple[tuple, dict]]] = {}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def buffer_event(phase: str, args: tuple, kwargs: dict) -> None:
|
|
20
|
+
"""Buffer an event that had no listeners when fired."""
|
|
21
|
+
buf = _backlog.get(phase)
|
|
22
|
+
if buf is None:
|
|
23
|
+
buf = deque(maxlen=_MAX_BACKLOG_PER_PHASE)
|
|
24
|
+
_backlog[phase] = buf
|
|
25
|
+
buf.append((args, kwargs))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def drain_backlog(phase: str) -> list[tuple[tuple, dict]]:
|
|
29
|
+
"""Pop and return all buffered events for *phase*."""
|
|
30
|
+
buf = _backlog.pop(phase, None)
|
|
31
|
+
return list(buf) if buf else []
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def drain_all() -> dict[str, list[tuple[tuple, dict]]]:
|
|
35
|
+
"""Pop and return buffered events for every phase that has any."""
|
|
36
|
+
result = {p: list(events) for p, events in _backlog.items() if events}
|
|
37
|
+
_backlog.clear()
|
|
38
|
+
return result
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def pending_count(phase: str | None = None) -> int:
|
|
42
|
+
"""Return number of buffered events, optionally filtered by phase."""
|
|
43
|
+
if phase is not None:
|
|
44
|
+
return len(_backlog.get(phase, ()))
|
|
45
|
+
return sum(len(v) for v in _backlog.values())
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def clear(phase: str | None = None) -> None:
|
|
49
|
+
"""Clear buffered events."""
|
|
50
|
+
if phase is None:
|
|
51
|
+
_backlog.clear()
|
|
52
|
+
else:
|
|
53
|
+
_backlog.pop(phase, None)
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"""Bridge to Rust extension module with Python fallback.
|
|
2
|
+
|
|
3
|
+
This is the ONLY place where pydantic-ai message objects are converted to
|
|
4
|
+
the dict format that Rust expects. The Rust module never touches pydantic-ai
|
|
5
|
+
objects directly.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from _code_puppy_core import (
|
|
14
|
+
ProcessResult,
|
|
15
|
+
PruneResult,
|
|
16
|
+
SplitResult,
|
|
17
|
+
deserialize_session,
|
|
18
|
+
process_messages_batch,
|
|
19
|
+
prune_and_filter,
|
|
20
|
+
serialize_session,
|
|
21
|
+
serialize_session_incremental,
|
|
22
|
+
split_for_summarization,
|
|
23
|
+
truncation_indices)
|
|
24
|
+
|
|
25
|
+
RUST_AVAILABLE = True
|
|
26
|
+
except ImportError:
|
|
27
|
+
RUST_AVAILABLE = False
|
|
28
|
+
|
|
29
|
+
# Provide type stubs so downstream code can reference them
|
|
30
|
+
ProcessResult = None # type: ignore[assignment,misc]
|
|
31
|
+
PruneResult = None # type: ignore[assignment,misc]
|
|
32
|
+
SplitResult = None # type: ignore[assignment,misc]
|
|
33
|
+
process_messages_batch = None # type: ignore[assignment]
|
|
34
|
+
prune_and_filter = None # type: ignore[assignment]
|
|
35
|
+
truncation_indices = None # type: ignore[assignment]
|
|
36
|
+
split_for_summarization = None # type: ignore[assignment]
|
|
37
|
+
serialize_session = None # type: ignore[assignment]
|
|
38
|
+
deserialize_session = None # type: ignore[assignment]
|
|
39
|
+
serialize_session_incremental = None # type: ignore[assignment]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# --- Hashline acceleration --------------------------------------------------
|
|
43
|
+
try:
|
|
44
|
+
from _code_puppy_core import (
|
|
45
|
+
compute_line_hash,
|
|
46
|
+
format_hashlines,
|
|
47
|
+
strip_hashline_prefixes,
|
|
48
|
+
validate_hashline_anchor,
|
|
49
|
+
)
|
|
50
|
+
HASHLINE_RUST_AVAILABLE = True
|
|
51
|
+
except ImportError:
|
|
52
|
+
HASHLINE_RUST_AVAILABLE = False
|
|
53
|
+
compute_line_hash = None # type: ignore[assignment]
|
|
54
|
+
format_hashlines = None # type: ignore[assignment]
|
|
55
|
+
strip_hashline_prefixes = None # type: ignore[assignment]
|
|
56
|
+
validate_hashline_anchor = None # type: ignore[assignment]
|
|
57
|
+
# ---------------------------------------------------------------------------
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# --- Fast Puppy toggle ---------------------------------------------------
|
|
61
|
+
# When True (default), Rust acceleration is used at runtime if the module
|
|
62
|
+
# is installed. /fast_puppy disable flips this to False so every call
|
|
63
|
+
# falls through to the Python path — no restart needed.
|
|
64
|
+
_rust_user_enabled: bool = True
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def is_rust_enabled() -> bool:
|
|
68
|
+
"""Check if Rust acceleration is both available AND enabled by the user."""
|
|
69
|
+
return RUST_AVAILABLE and _rust_user_enabled
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def set_rust_enabled(enabled: bool) -> None:
|
|
73
|
+
"""Toggle Rust acceleration on or off at runtime."""
|
|
74
|
+
global _rust_user_enabled
|
|
75
|
+
_rust_user_enabled = enabled
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def get_rust_status() -> dict:
|
|
79
|
+
"""Return diagnostic info for /fast_puppy status."""
|
|
80
|
+
return {
|
|
81
|
+
"installed": RUST_AVAILABLE,
|
|
82
|
+
"enabled": _rust_user_enabled,
|
|
83
|
+
"active": is_rust_enabled(),
|
|
84
|
+
}
|
|
85
|
+
# --------------------------------------------------------------------------
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def serialize_message_for_rust(message: Any) -> dict:
|
|
89
|
+
"""Convert a pydantic-ai ModelMessage to the dict format expected by Rust.
|
|
90
|
+
|
|
91
|
+
This is the ONLY place where pydantic-ai message objects are converted
|
|
92
|
+
to dicts. The Rust module never touches pydantic-ai objects directly.
|
|
93
|
+
"""
|
|
94
|
+
from pydantic_ai.messages import ModelRequest
|
|
95
|
+
|
|
96
|
+
kind = "request" if isinstance(message, ModelRequest) else "response"
|
|
97
|
+
role = getattr(message, "role", None)
|
|
98
|
+
instructions = getattr(message, "instructions", None)
|
|
99
|
+
|
|
100
|
+
parts: list[dict] = []
|
|
101
|
+
for part in getattr(message, "parts", []):
|
|
102
|
+
part_dict: dict[str, Any] = {
|
|
103
|
+
"part_kind": getattr(part, "part_kind", str(type(part).__name__)),
|
|
104
|
+
"content": None,
|
|
105
|
+
"content_json": None,
|
|
106
|
+
"tool_call_id": getattr(part, "tool_call_id", None),
|
|
107
|
+
"tool_name": getattr(part, "tool_name", None),
|
|
108
|
+
"args": str(getattr(part, "args", "")) if hasattr(part, "args") else None,
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
content = getattr(part, "content", None)
|
|
112
|
+
if content is None:
|
|
113
|
+
pass
|
|
114
|
+
elif isinstance(content, str):
|
|
115
|
+
part_dict["content"] = content
|
|
116
|
+
elif isinstance(content, list):
|
|
117
|
+
text_parts = []
|
|
118
|
+
for item in content:
|
|
119
|
+
if isinstance(item, str):
|
|
120
|
+
text_parts.append(item)
|
|
121
|
+
# Skip BinaryContent for token estimation
|
|
122
|
+
part_dict["content"] = "\n".join(text_parts) if text_parts else None
|
|
123
|
+
else:
|
|
124
|
+
# Dicts, Pydantic models, other — serialize to JSON string
|
|
125
|
+
try:
|
|
126
|
+
if hasattr(content, "model_dump_json"):
|
|
127
|
+
part_dict["content_json"] = content.model_dump_json(
|
|
128
|
+
sort_keys=True
|
|
129
|
+
)
|
|
130
|
+
elif isinstance(content, dict):
|
|
131
|
+
part_dict["content_json"] = json.dumps(content, sort_keys=True)
|
|
132
|
+
else:
|
|
133
|
+
part_dict["content"] = repr(content)
|
|
134
|
+
except (TypeError, ValueError):
|
|
135
|
+
part_dict["content"] = repr(content)
|
|
136
|
+
|
|
137
|
+
parts.append(part_dict)
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
"kind": kind,
|
|
141
|
+
"role": role,
|
|
142
|
+
"instructions": instructions,
|
|
143
|
+
"parts": parts,
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def serialize_messages_for_rust(messages: list) -> list[dict]:
|
|
148
|
+
"""Batch convert messages for Rust consumption."""
|
|
149
|
+
return [serialize_message_for_rust(m) for m in messages]
|