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.
Files changed (422) hide show
  1. {codepp-0.0.438 → codepp-0.0.443}/.gitignore +12 -0
  2. {codepp-0.0.438 → codepp-0.0.443}/PKG-INFO +45 -4
  3. {codepp-0.0.438 → codepp-0.0.443}/README.md +41 -2
  4. codepp-0.0.443/code_puppy/_backlog.py +53 -0
  5. codepp-0.0.443/code_puppy/_core_bridge.py +149 -0
  6. codepp-0.0.443/code_puppy/adaptive_rate_limiter.py +894 -0
  7. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/__init__.py +1 -2
  8. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_c_reviewer.py +0 -1
  9. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_code_puppy.py +9 -28
  10. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_code_reviewer.py +0 -1
  11. codepp-0.0.443/code_puppy/agents/agent_code_scout.py +143 -0
  12. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_cpp_reviewer.py +0 -1
  13. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_creator_agent.py +15 -23
  14. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_golang_reviewer.py +0 -1
  15. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_helios.py +3 -5
  16. codepp-0.0.443/code_puppy/agents/agent_identity.py +109 -0
  17. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_javascript_reviewer.py +0 -1
  18. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_manager.py +161 -93
  19. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_pack_leader.py +3 -2
  20. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_planning.py +5 -4
  21. codepp-0.0.443/code_puppy/agents/agent_prompt_mixin.py +116 -0
  22. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_python_programmer.py +1 -2
  23. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_python_reviewer.py +1 -2
  24. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_qa_expert.py +0 -1
  25. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_qa_kitten.py +2 -3
  26. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_scheduler.py +0 -1
  27. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_security_auditor.py +0 -1
  28. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_terminal_qa.py +1 -2
  29. codepp-0.0.443/code_puppy/agents/agent_turbo_executor.py +170 -0
  30. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/agent_typescript_reviewer.py +0 -1
  31. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/base_agent.py +773 -503
  32. codepp-0.0.443/code_puppy/agents/context_compactor.py +337 -0
  33. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/event_stream_handler.py +11 -19
  34. codepp-0.0.443/code_puppy/agents/history_manager.py +173 -0
  35. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/json_agent.py +9 -13
  36. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/pack/bloodhound.py +4 -3
  37. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/pack/husky.py +5 -8
  38. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/pack/retriever.py +3 -2
  39. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/pack/shepherd.py +4 -6
  40. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/pack/terrier.py +3 -2
  41. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/pack/watchdog.py +4 -3
  42. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/prompt_reviewer.py +4 -3
  43. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/subagent_stream_handler.py +15 -20
  44. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/app.py +5 -10
  45. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/pty_manager.py +17 -23
  46. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/routers/agents.py +3 -3
  47. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/routers/commands.py +11 -15
  48. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/routers/config.py +4 -4
  49. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/routers/sessions.py +64 -26
  50. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/websocket.py +2 -4
  51. codepp-0.0.443/code_puppy/app_runner.py +396 -0
  52. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/callbacks.py +171 -62
  53. codepp-0.0.443/code_puppy/capability/__init__.py +76 -0
  54. codepp-0.0.443/code_puppy/capability/builtin_providers.py +187 -0
  55. codepp-0.0.443/code_puppy/capability/registry.py +371 -0
  56. codepp-0.0.443/code_puppy/capability/types.py +84 -0
  57. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/chatgpt_codex_client.py +4 -9
  58. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/claude_cache_client.py +9 -19
  59. codepp-0.0.443/code_puppy/cli_runner.py +64 -0
  60. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/add_model_menu.py +127 -72
  61. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/agent_menu.py +49 -41
  62. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/attachments.py +12 -19
  63. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/autosave_menu.py +42 -34
  64. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/clipboard.py +14 -21
  65. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/colors_menu.py +21 -25
  66. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/command_handler.py +26 -6
  67. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/command_registry.py +10 -12
  68. codepp-0.0.443/code_puppy/command_line/concurrency_commands.py +97 -0
  69. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/config_commands.py +21 -42
  70. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/core_commands.py +47 -169
  71. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/diff_menu.py +35 -53
  72. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/file_path_completion.py +22 -23
  73. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/load_context_completion.py +2 -4
  74. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/catalog_server_installer.py +1 -2
  75. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/custom_server_form.py +34 -46
  76. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/custom_server_installer.py +1 -2
  77. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/edit_command.py +11 -21
  78. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/handler.py +2 -4
  79. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/help_command.py +1 -2
  80. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/install_command.py +9 -18
  81. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/install_menu.py +14 -13
  82. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/list_command.py +3 -6
  83. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/logs_command.py +13 -25
  84. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/remove_command.py +1 -2
  85. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/restart_command.py +5 -10
  86. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/search_command.py +10 -20
  87. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/start_all_command.py +8 -16
  88. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/start_command.py +8 -16
  89. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/status_command.py +4 -7
  90. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/stop_all_command.py +3 -6
  91. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/stop_command.py +3 -6
  92. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/test_command.py +8 -16
  93. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/utils.py +3 -4
  94. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/wizard_utils.py +15 -25
  95. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp_completion.py +5 -9
  96. codepp-0.0.443/code_puppy/command_line/model_picker_completion.py +421 -0
  97. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/model_settings_menu.py +83 -59
  98. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/motd.py +5 -5
  99. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/onboarding_slides.py +2 -3
  100. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/onboarding_wizard.py +23 -23
  101. codepp-0.0.443/code_puppy/command_line/pack_commands.py +101 -0
  102. codepp-0.0.443/code_puppy/command_line/pagination.py +43 -0
  103. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/pin_command_completion.py +12 -23
  104. codepp-0.0.443/code_puppy/command_line/preset_commands.py +85 -0
  105. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/prompt_toolkit_completion.py +18 -28
  106. codepp-0.0.443/code_puppy/command_line/repl_commands.py +174 -0
  107. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/session_commands.py +14 -17
  108. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/shell_passthrough.py +8 -3
  109. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/skills_completion.py +8 -13
  110. codepp-0.0.443/code_puppy/command_line/staged_commands.py +341 -0
  111. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/uc_menu.py +49 -39
  112. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/utils.py +1 -2
  113. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/wiggum_state.py +2 -3
  114. codepp-0.0.443/code_puppy/command_line/workflow_commands.py +109 -0
  115. codepp-0.0.443/code_puppy/concurrency_limits.py +265 -0
  116. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/config.py +124 -118
  117. codepp-0.0.443/code_puppy/config_package/README.md +42 -0
  118. codepp-0.0.443/code_puppy/config_package/__init__.py +20 -0
  119. codepp-0.0.443/code_puppy/config_presets.py +238 -0
  120. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/error_logging.py +26 -26
  121. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/gemini_code_assist.py +17 -26
  122. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/gemini_model.py +17 -35
  123. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/__init__.py +1 -2
  124. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/aliases.py +11 -11
  125. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/engine.py +21 -29
  126. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/executor.py +29 -32
  127. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/matcher.py +7 -7
  128. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/models.py +21 -21
  129. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/registry.py +5 -6
  130. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/validator.py +8 -8
  131. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/http_utils.py +86 -32
  132. codepp-0.0.438/code_puppy/cli_runner.py → codepp-0.0.443/code_puppy/interactive_loop.py +71 -553
  133. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/__init__.py +2 -4
  134. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/async_lifecycle.py +10 -14
  135. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/blocking_startup.py +25 -35
  136. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/captured_stdio_server.py +7 -10
  137. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/config_wizard.py +18 -26
  138. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/dashboard.py +5 -8
  139. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/error_isolation.py +6 -6
  140. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/examples/retry_example.py +4 -8
  141. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/health_monitor.py +31 -35
  142. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/managed_server.py +11 -16
  143. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/manager.py +32 -48
  144. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/mcp_logs.py +3 -4
  145. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/registry.py +7 -9
  146. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/retry_manager.py +10 -14
  147. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/server_registry_catalog.py +64 -135
  148. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/status_tracker.py +15 -20
  149. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/system_tools.py +8 -10
  150. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/__init__.py +7 -14
  151. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/bus.py +143 -77
  152. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/commands.py +10 -23
  153. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/markdown_patches.py +1 -2
  154. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/message_queue.py +6 -7
  155. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/messages.py +48 -96
  156. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/queue_console.py +19 -25
  157. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/renderers.py +2 -3
  158. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/rich_renderer.py +13 -20
  159. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/spinner/console_spinner.py +1 -2
  160. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/subagent_console.py +14 -19
  161. codepp-0.0.443/code_puppy/model_availability.py +117 -0
  162. codepp-0.0.443/code_puppy/model_factory.py +1072 -0
  163. codepp-0.0.443/code_puppy/model_packs.py +455 -0
  164. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/model_switching.py +2 -5
  165. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/model_utils.py +27 -16
  166. codepp-0.0.443/code_puppy/models.json +134 -0
  167. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/models_dev_parser.py +35 -40
  168. codepp-0.0.443/code_puppy/permission_decision.py +69 -0
  169. codepp-0.0.443/code_puppy/persistence.py +233 -0
  170. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/__init__.py +8 -4
  171. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/__init__.py +1 -2
  172. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/config.py +2 -3
  173. codepp-0.0.443/code_puppy/plugins/agent_skills/discovery.py +140 -0
  174. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/downloader.py +16 -30
  175. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/installer.py +1 -3
  176. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/metadata.py +11 -13
  177. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/prompt_builder.py +2 -2
  178. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/register_callbacks.py +11 -14
  179. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/remote_catalog.py +7 -10
  180. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/skill_catalog.py +9 -13
  181. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/skills_install_menu.py +64 -40
  182. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/agent_skills/skills_menu.py +47 -33
  183. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/accounts.py +31 -47
  184. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/antigravity_model.py +17 -35
  185. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/config.py +2 -2
  186. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/constants.py +33 -7
  187. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/oauth.py +19 -33
  188. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/register_callbacks.py +24 -40
  189. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/storage.py +26 -30
  190. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/test_plugin.py +4 -9
  191. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/token.py +14 -24
  192. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/transport.py +18 -30
  193. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/utils.py +9 -11
  194. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/chatgpt_oauth/__init__.py +0 -1
  195. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/chatgpt_oauth/config.py +2 -2
  196. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/chatgpt_oauth/oauth_flow.py +9 -16
  197. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/chatgpt_oauth/register_callbacks.py +9 -14
  198. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/chatgpt_oauth/utils.py +35 -38
  199. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_hooks/config.py +4 -4
  200. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_hooks/register_callbacks.py +12 -19
  201. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_oauth/__init__.py +1 -2
  202. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_oauth/config.py +2 -2
  203. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_oauth/register_callbacks.py +34 -42
  204. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_oauth/test_plugin.py +8 -16
  205. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_oauth/token_refresh_heartbeat.py +8 -15
  206. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_oauth/utils.py +36 -48
  207. codepp-0.0.443/code_puppy/plugins/clean_command/__init__.py +1 -0
  208. codepp-0.0.443/code_puppy/plugins/clean_command/register_callbacks.py +403 -0
  209. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/customizable_commands/register_callbacks.py +5 -5
  210. codepp-0.0.443/code_puppy/plugins/error_classifier/DESIGN.md +439 -0
  211. codepp-0.0.443/code_puppy/plugins/error_classifier/__init__.py +41 -0
  212. codepp-0.0.443/code_puppy/plugins/error_classifier/builtins.py +300 -0
  213. codepp-0.0.443/code_puppy/plugins/error_classifier/exinfo.py +59 -0
  214. codepp-0.0.443/code_puppy/plugins/error_classifier/register_callbacks.py +151 -0
  215. codepp-0.0.443/code_puppy/plugins/error_classifier/registry.py +169 -0
  216. codepp-0.0.443/code_puppy/plugins/error_logger/__init__.py +1 -0
  217. codepp-0.0.443/code_puppy/plugins/error_logger/register_callbacks.py +164 -0
  218. codepp-0.0.443/code_puppy/plugins/fast_puppy/register_callbacks.py +313 -0
  219. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/file_permission_handler/register_callbacks.py +32 -22
  220. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/frontend_emitter/__init__.py +1 -2
  221. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/frontend_emitter/emitter.py +9 -10
  222. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/frontend_emitter/register_callbacks.py +12 -17
  223. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/hook_manager/config.py +20 -25
  224. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/hook_manager/hooks_menu.py +25 -28
  225. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/hook_manager/register_callbacks.py +6 -8
  226. codepp-0.0.443/code_puppy/plugins/mana_bridge/__init__.py +19 -0
  227. codepp-0.0.443/code_puppy/plugins/mana_bridge/register_callbacks.py +972 -0
  228. codepp-0.0.443/code_puppy/plugins/mana_bridge/tcp_client.py +375 -0
  229. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/oauth_puppy_html.py +6 -11
  230. codepp-0.0.443/code_puppy/plugins/ollama_setup/__init__.py +5 -0
  231. codepp-0.0.443/code_puppy/plugins/ollama_setup/completer.py +38 -0
  232. codepp-0.0.443/code_puppy/plugins/ollama_setup/register_callbacks.py +365 -0
  233. codepp-0.0.443/code_puppy/plugins/pack_parallelism/__init__.py +0 -0
  234. codepp-0.0.443/code_puppy/plugins/pack_parallelism/register_callbacks.py +196 -0
  235. codepp-0.0.443/code_puppy/plugins/pop_command/__init__.py +1 -0
  236. codepp-0.0.443/code_puppy/plugins/pop_command/register_callbacks.py +191 -0
  237. codepp-0.0.443/code_puppy/plugins/remember_last_agent/__init__.py +9 -0
  238. codepp-0.0.443/code_puppy/plugins/remember_last_agent/register_callbacks.py +94 -0
  239. codepp-0.0.443/code_puppy/plugins/remember_last_agent/storage.py +64 -0
  240. codepp-0.0.443/code_puppy/plugins/repo_compass/DESIGN.md +232 -0
  241. codepp-0.0.443/code_puppy/plugins/repo_compass/__init__.py +8 -0
  242. codepp-0.0.443/code_puppy/plugins/repo_compass/config.py +40 -0
  243. codepp-0.0.443/code_puppy/plugins/repo_compass/formatter.py +38 -0
  244. codepp-0.0.443/code_puppy/plugins/repo_compass/indexer.py +102 -0
  245. codepp-0.0.443/code_puppy/plugins/repo_compass/register_callbacks.py +49 -0
  246. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/scheduler/register_callbacks.py +5 -7
  247. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/scheduler/scheduler_menu.py +41 -25
  248. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/scheduler/scheduler_wizard.py +17 -15
  249. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/shell_safety/agent_shell_safety.py +2 -2
  250. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/shell_safety/command_cache.py +9 -11
  251. codepp-0.0.443/code_puppy/plugins/shell_safety/register_callbacks.py +358 -0
  252. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/synthetic_status/register_callbacks.py +6 -11
  253. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/synthetic_status/status_api.py +3 -7
  254. codepp-0.0.443/code_puppy/plugins/ttsr/__init__.py +9 -0
  255. codepp-0.0.443/code_puppy/plugins/ttsr/register_callbacks.py +294 -0
  256. codepp-0.0.443/code_puppy/plugins/ttsr/rule_loader.py +228 -0
  257. codepp-0.0.443/code_puppy/plugins/ttsr/stream_watcher.py +277 -0
  258. codepp-0.0.443/code_puppy/plugins/turbo_executor/__init__.py +33 -0
  259. codepp-0.0.443/code_puppy/plugins/turbo_executor/models.py +153 -0
  260. codepp-0.0.443/code_puppy/plugins/turbo_executor/notifications.py +261 -0
  261. codepp-0.0.443/code_puppy/plugins/turbo_executor/orchestrator.py +470 -0
  262. codepp-0.0.443/code_puppy/plugins/turbo_executor/register_callbacks.py +461 -0
  263. codepp-0.0.443/code_puppy/plugins/turbo_executor/summarizer.py +340 -0
  264. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/universal_constructor/models.py +19 -19
  265. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/universal_constructor/registry.py +14 -15
  266. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/universal_constructor/sandbox.py +43 -29
  267. codepp-0.0.443/code_puppy/policy_config.py +60 -0
  268. codepp-0.0.443/code_puppy/policy_engine.py +266 -0
  269. codepp-0.0.443/code_puppy/prompt_runner.py +148 -0
  270. codepp-0.0.443/code_puppy/provider_identity.py +105 -0
  271. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/pydantic_patches.py +15 -17
  272. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/reopenable_async_client.py +14 -16
  273. codepp-0.0.443/code_puppy/repl_session.py +384 -0
  274. codepp-0.0.443/code_puppy/resilience.py +387 -0
  275. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/round_robin_model.py +78 -17
  276. codepp-0.0.443/code_puppy/routing/__init__.py +20 -0
  277. codepp-0.0.443/code_puppy/routing/composite.py +78 -0
  278. codepp-0.0.443/code_puppy/routing/router.py +24 -0
  279. codepp-0.0.443/code_puppy/routing/strategies/__init__.py +1 -0
  280. codepp-0.0.443/code_puppy/routing/strategies/availability.py +54 -0
  281. codepp-0.0.443/code_puppy/routing/strategies/default.py +45 -0
  282. codepp-0.0.443/code_puppy/routing/strategies/plugin.py +81 -0
  283. codepp-0.0.443/code_puppy/routing/strategy.py +44 -0
  284. codepp-0.0.443/code_puppy/run_context.py +262 -0
  285. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/__init__.py +1 -2
  286. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/config.py +7 -8
  287. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/daemon.py +5 -9
  288. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/executor.py +4 -7
  289. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/platform.py +2 -4
  290. codepp-0.0.443/code_puppy/session_storage.py +606 -0
  291. codepp-0.0.443/code_puppy/staged_changes.py +433 -0
  292. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/status_display.py +3 -7
  293. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/summarization_agent.py +4 -9
  294. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/terminal_utils.py +3 -3
  295. codepp-0.0.443/code_puppy/token_utils.py +88 -0
  296. codepp-0.0.443/code_puppy/tool_schema.py +368 -0
  297. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/__init__.py +25 -42
  298. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/agent_tools.py +206 -66
  299. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/__init__.py +1 -2
  300. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/constants.py +1 -2
  301. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/handler.py +6 -6
  302. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/models.py +16 -33
  303. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/registration.py +3 -4
  304. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/renderers.py +15 -20
  305. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/terminal_ui.py +3 -7
  306. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/theme.py +2 -6
  307. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/tui_loop.py +19 -21
  308. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/__init__.py +1 -2
  309. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/browser_control.py +17 -26
  310. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/browser_interactions.py +35 -63
  311. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/browser_locators.py +39 -69
  312. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/browser_manager.py +11 -11
  313. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/browser_navigation.py +19 -25
  314. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/browser_screenshot.py +11 -18
  315. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/browser_scripts.py +23 -43
  316. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/browser_workflows.py +17 -29
  317. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/chromium_terminal_manager.py +8 -11
  318. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/terminal_command_tools.py +20 -32
  319. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/terminal_screenshot_tools.py +163 -59
  320. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/browser/terminal_tools.py +21 -34
  321. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/command_runner.py +87 -89
  322. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/common.py +124 -153
  323. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/display.py +2 -4
  324. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/file_modifications.py +36 -61
  325. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/file_operations.py +50 -51
  326. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/scheduler_tools.py +10 -20
  327. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/skills_tools.py +19 -33
  328. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/tools_content.py +1 -2
  329. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/universal_constructor.py +66 -118
  330. codepp-0.0.443/code_puppy/tui/__init__.py +12 -0
  331. codepp-0.0.443/code_puppy/tui/app.py +798 -0
  332. codepp-0.0.443/code_puppy/tui/base_screen.py +25 -0
  333. codepp-0.0.443/code_puppy/tui/completion.py +254 -0
  334. codepp-0.0.443/code_puppy/tui/launcher.py +42 -0
  335. codepp-0.0.443/code_puppy/tui/message_bridge.py +315 -0
  336. codepp-0.0.443/code_puppy/tui/screens/__init__.py +5 -0
  337. codepp-0.0.443/code_puppy/tui/screens/add_model_screen.py +389 -0
  338. codepp-0.0.443/code_puppy/tui/screens/agent_screen.py +443 -0
  339. codepp-0.0.443/code_puppy/tui/screens/autosave_screen.py +285 -0
  340. codepp-0.0.443/code_puppy/tui/screens/colors_screen.py +383 -0
  341. codepp-0.0.443/code_puppy/tui/screens/diff_screen.py +431 -0
  342. codepp-0.0.443/code_puppy/tui/screens/hooks_screen.py +220 -0
  343. codepp-0.0.443/code_puppy/tui/screens/mcp_form_screen.py +383 -0
  344. codepp-0.0.443/code_puppy/tui/screens/mcp_screen.py +307 -0
  345. codepp-0.0.443/code_puppy/tui/screens/model_pin_screen.py +104 -0
  346. codepp-0.0.443/code_puppy/tui/screens/model_screen.py +164 -0
  347. codepp-0.0.443/code_puppy/tui/screens/model_settings_screen.py +362 -0
  348. codepp-0.0.443/code_puppy/tui/screens/onboarding_screen.py +169 -0
  349. codepp-0.0.443/code_puppy/tui/screens/question_screen.py +387 -0
  350. codepp-0.0.443/code_puppy/tui/screens/scheduler_screen.py +306 -0
  351. codepp-0.0.443/code_puppy/tui/screens/scheduler_wizard_screen.py +199 -0
  352. codepp-0.0.443/code_puppy/tui/screens/skills_install_screen.py +267 -0
  353. codepp-0.0.443/code_puppy/tui/screens/skills_screen.py +299 -0
  354. codepp-0.0.443/code_puppy/tui/screens/uc_screen.py +373 -0
  355. codepp-0.0.443/code_puppy/tui/stream_renderer.py +271 -0
  356. codepp-0.0.443/code_puppy/tui/theme.py +151 -0
  357. codepp-0.0.443/code_puppy/tui/widgets/__init__.py +8 -0
  358. codepp-0.0.443/code_puppy/tui/widgets/completion_overlay.py +108 -0
  359. codepp-0.0.443/code_puppy/tui/widgets/info_bar.py +132 -0
  360. codepp-0.0.443/code_puppy/tui/widgets/searchable_list.py +256 -0
  361. codepp-0.0.443/code_puppy/tui/widgets/split_panel.py +47 -0
  362. codepp-0.0.443/code_puppy/utils/__init__.py +24 -0
  363. codepp-0.0.443/code_puppy/utils/dag.py +121 -0
  364. codepp-0.0.443/code_puppy/utils/hashline.py +199 -0
  365. codepp-0.0.443/code_puppy/utils/parallel.py +179 -0
  366. codepp-0.0.443/code_puppy/utils/ring_buffer.py +265 -0
  367. codepp-0.0.443/code_puppy/utils/shell_split.py +90 -0
  368. codepp-0.0.443/code_puppy/utils/stream_parser.py +188 -0
  369. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/uvx_detection.py +2 -3
  370. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/version_checker.py +1 -2
  371. codepp-0.0.443/code_puppy/workflow_state.py +381 -0
  372. {codepp-0.0.438 → codepp-0.0.443}/pyproject.toml +17 -3
  373. codepp-0.0.438/code_puppy/command_line/model_picker_completion.py +0 -197
  374. codepp-0.0.438/code_puppy/model_factory.py +0 -848
  375. codepp-0.0.438/code_puppy/models.json +0 -46
  376. codepp-0.0.438/code_puppy/plugins/agent_skills/discovery.py +0 -136
  377. codepp-0.0.438/code_puppy/plugins/shell_safety/register_callbacks.py +0 -202
  378. codepp-0.0.438/code_puppy/session_storage.py +0 -338
  379. {codepp-0.0.438 → codepp-0.0.443}/LICENSE +0 -0
  380. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/__init__.py +0 -0
  381. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/__main__.py +0 -0
  382. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/agents/pack/__init__.py +0 -0
  383. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/__init__.py +0 -0
  384. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/main.py +0 -0
  385. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/routers/__init__.py +0 -0
  386. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/api/templates/terminal.html +0 -0
  387. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/__init__.py +0 -0
  388. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/__init__.py +0 -0
  389. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/command_line/mcp/base.py +0 -0
  390. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/hook_engine/README.md +0 -0
  391. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/keymap.py +0 -0
  392. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/main.py +0 -0
  393. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_/circuit_breaker.py +0 -0
  394. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_prompts/__init__.py +0 -0
  395. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/mcp_prompts/hook_creator.py +0 -0
  396. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/spinner/__init__.py +0 -0
  397. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/messaging/spinner/spinner_base.py +0 -0
  398. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/models_dev_api.json +0 -0
  399. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/antigravity_oauth/__init__.py +0 -0
  400. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/chatgpt_oauth/test_plugin.py +0 -0
  401. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_hooks/__init__.py +0 -0
  402. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_oauth/README.md +0 -0
  403. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/claude_code_oauth/SETUP.md +0 -0
  404. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/customizable_commands/__init__.py +0 -0
  405. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/example_custom_command/README.md +0 -0
  406. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/example_custom_command/register_callbacks.py +0 -0
  407. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/file_permission_handler/__init__.py +0 -0
  408. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/hook_creator/__init__.py +0 -0
  409. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/hook_creator/register_callbacks.py +0 -0
  410. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/hook_manager/__init__.py +0 -0
  411. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/scheduler/__init__.py +0 -0
  412. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/shell_safety/__init__.py +0 -0
  413. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/synthetic_status/__init__.py +0 -0
  414. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/universal_constructor/__init__.py +0 -0
  415. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/plugins/universal_constructor/register_callbacks.py +0 -0
  416. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/prompts/antigravity_system_prompt.md +0 -0
  417. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/__main__.py +0 -0
  418. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/cli.py +0 -0
  419. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/platform_unix.py +0 -0
  420. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/scheduler/platform_win.py +0 -0
  421. {codepp-0.0.438 → codepp-0.0.443}/code_puppy/tools/ask_user_question/demo_tui.py +0 -0
  422. {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.438
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.52
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
  [![Downloads](https://img.shields.io/badge/Downloads-170k%2B-brightgreen?style=for-the-badge&logo=download)](https://pypi.org/project/code-puppy/)
55
57
  [![Python](https://img.shields.io/badge/Python-3.11%2B-blue?style=for-the-badge&logo=python&logoColor=white)](https://python.org)
56
58
  [![License](https://img.shields.io/badge/License-MIT-green?style=for-the-badge)](LICENSE)
57
- [![Build Status](https://img.shields.io/badge/Build-Passing-brightgreen?style=for-the-badge&logo=github)](https://github.com/mpfaffenberger/code_puppy/actions)
58
- [![Tests](https://img.shields.io/badge/Tests-Passing-success?style=for-the-badge&logo=pytest)](https://github.com/mpfaffenberger/code_puppy/tests)
59
59
 
60
60
  [![100% Open Source](https://img.shields.io/badge/100%25-Open%20Source-blue?style=for-the-badge)](https://github.com/mpfaffenberger/code_puppy)
61
61
  [![Pydantic AI](https://img.shields.io/badge/Pydantic-AI-success?style=for-the-badge)](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
  [![Downloads](https://img.shields.io/badge/Downloads-170k%2B-brightgreen?style=for-the-badge&logo=download)](https://pypi.org/project/code-puppy/)
9
9
  [![Python](https://img.shields.io/badge/Python-3.11%2B-blue?style=for-the-badge&logo=python&logoColor=white)](https://python.org)
10
10
  [![License](https://img.shields.io/badge/License-MIT-green?style=for-the-badge)](LICENSE)
11
- [![Build Status](https://img.shields.io/badge/Build-Passing-brightgreen?style=for-the-badge&logo=github)](https://github.com/mpfaffenberger/code_puppy/actions)
12
- [![Tests](https://img.shields.io/badge/Tests-Passing-success?style=for-the-badge&logo=pytest)](https://github.com/mpfaffenberger/code_puppy/tests)
13
11
 
14
12
  [![100% Open Source](https://img.shields.io/badge/100%25-Open%20Source-blue?style=for-the-badge)](https://github.com/mpfaffenberger/code_puppy)
15
13
  [![Pydantic AI](https://img.shields.io/badge/Pydantic-AI-success?style=for-the-badge)](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]