code-puppy 0.0.361__tar.gz → 0.0.363__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 (214) hide show
  1. {code_puppy-0.0.361 → code_puppy-0.0.363}/PKG-INFO +1 -1
  2. code_puppy-0.0.363/code_puppy/command_line/agent_menu.py +357 -0
  3. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/core_commands.py +1 -109
  4. {code_puppy-0.0.361 → code_puppy-0.0.363}/pyproject.toml +1 -1
  5. {code_puppy-0.0.361 → code_puppy-0.0.363}/.gitignore +0 -0
  6. {code_puppy-0.0.361 → code_puppy-0.0.363}/LICENSE +0 -0
  7. {code_puppy-0.0.361 → code_puppy-0.0.363}/README.md +0 -0
  8. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/__init__.py +0 -0
  9. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/__main__.py +0 -0
  10. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/__init__.py +0 -0
  11. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/agent_c_reviewer.py +0 -0
  12. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/agent_code_puppy.py +0 -0
  13. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/agent_code_reviewer.py +0 -0
  14. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/agent_cpp_reviewer.py +0 -0
  15. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/agent_creator_agent.py +0 -0
  16. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/agent_golang_reviewer.py +0 -0
  17. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/agent_javascript_reviewer.py +0 -0
  18. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/agent_manager.py +0 -0
  19. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/agent_pack_leader.py +0 -0
  20. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/agent_planning.py +0 -0
  21. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/agent_python_programmer.py +0 -0
  22. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/agent_python_reviewer.py +0 -0
  23. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/agent_qa_expert.py +0 -0
  24. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/agent_qa_kitten.py +0 -0
  25. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/agent_security_auditor.py +0 -0
  26. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/agent_terminal_qa.py +0 -0
  27. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/agent_typescript_reviewer.py +0 -0
  28. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/base_agent.py +0 -0
  29. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/event_stream_handler.py +0 -0
  30. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/json_agent.py +0 -0
  31. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/pack/__init__.py +0 -0
  32. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/pack/bloodhound.py +0 -0
  33. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/pack/husky.py +0 -0
  34. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/pack/retriever.py +0 -0
  35. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/pack/shepherd.py +0 -0
  36. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/pack/terrier.py +0 -0
  37. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/pack/watchdog.py +0 -0
  38. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/prompt_reviewer.py +0 -0
  39. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/agents/subagent_stream_handler.py +0 -0
  40. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/api/__init__.py +0 -0
  41. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/api/app.py +0 -0
  42. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/api/main.py +0 -0
  43. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/api/pty_manager.py +0 -0
  44. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/api/routers/__init__.py +0 -0
  45. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/api/routers/agents.py +0 -0
  46. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/api/routers/commands.py +0 -0
  47. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/api/routers/config.py +0 -0
  48. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/api/routers/sessions.py +0 -0
  49. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/api/templates/terminal.html +0 -0
  50. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/api/websocket.py +0 -0
  51. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/callbacks.py +0 -0
  52. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/chatgpt_codex_client.py +0 -0
  53. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/claude_cache_client.py +0 -0
  54. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/cli_runner.py +0 -0
  55. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/__init__.py +0 -0
  56. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/add_model_menu.py +0 -0
  57. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/attachments.py +0 -0
  58. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/autosave_menu.py +0 -0
  59. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/clipboard.py +0 -0
  60. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/colors_menu.py +0 -0
  61. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/command_handler.py +0 -0
  62. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/command_registry.py +0 -0
  63. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/config_commands.py +0 -0
  64. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/diff_menu.py +0 -0
  65. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/file_path_completion.py +0 -0
  66. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/load_context_completion.py +0 -0
  67. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/__init__.py +0 -0
  68. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/base.py +0 -0
  69. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/catalog_server_installer.py +0 -0
  70. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/custom_server_form.py +0 -0
  71. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/custom_server_installer.py +0 -0
  72. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/edit_command.py +0 -0
  73. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/handler.py +0 -0
  74. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/help_command.py +0 -0
  75. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/install_command.py +0 -0
  76. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/install_menu.py +0 -0
  77. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/list_command.py +0 -0
  78. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/logs_command.py +0 -0
  79. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/remove_command.py +0 -0
  80. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/restart_command.py +0 -0
  81. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/search_command.py +0 -0
  82. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/start_all_command.py +0 -0
  83. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/start_command.py +0 -0
  84. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/status_command.py +0 -0
  85. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/stop_all_command.py +0 -0
  86. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/stop_command.py +0 -0
  87. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/test_command.py +0 -0
  88. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/utils.py +0 -0
  89. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp/wizard_utils.py +0 -0
  90. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/mcp_completion.py +0 -0
  91. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/model_picker_completion.py +0 -0
  92. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/model_settings_menu.py +0 -0
  93. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/motd.py +0 -0
  94. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/onboarding_slides.py +0 -0
  95. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/onboarding_wizard.py +0 -0
  96. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/pin_command_completion.py +0 -0
  97. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/prompt_toolkit_completion.py +0 -0
  98. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/session_commands.py +0 -0
  99. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/command_line/utils.py +0 -0
  100. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/config.py +0 -0
  101. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/error_logging.py +0 -0
  102. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/gemini_code_assist.py +0 -0
  103. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/http_utils.py +0 -0
  104. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/keymap.py +0 -0
  105. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/main.py +0 -0
  106. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/__init__.py +0 -0
  107. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/async_lifecycle.py +0 -0
  108. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/blocking_startup.py +0 -0
  109. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/captured_stdio_server.py +0 -0
  110. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/circuit_breaker.py +0 -0
  111. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/config_wizard.py +0 -0
  112. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/dashboard.py +0 -0
  113. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/error_isolation.py +0 -0
  114. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/examples/retry_example.py +0 -0
  115. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/health_monitor.py +0 -0
  116. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/managed_server.py +0 -0
  117. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/manager.py +0 -0
  118. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/mcp_logs.py +0 -0
  119. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/registry.py +0 -0
  120. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/retry_manager.py +0 -0
  121. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/server_registry_catalog.py +0 -0
  122. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/status_tracker.py +0 -0
  123. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/mcp_/system_tools.py +0 -0
  124. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/messaging/__init__.py +0 -0
  125. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/messaging/bus.py +0 -0
  126. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/messaging/commands.py +0 -0
  127. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/messaging/markdown_patches.py +0 -0
  128. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/messaging/message_queue.py +0 -0
  129. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/messaging/messages.py +0 -0
  130. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/messaging/queue_console.py +0 -0
  131. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/messaging/renderers.py +0 -0
  132. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/messaging/rich_renderer.py +0 -0
  133. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/messaging/spinner/__init__.py +0 -0
  134. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/messaging/spinner/console_spinner.py +0 -0
  135. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/messaging/spinner/spinner_base.py +0 -0
  136. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/messaging/subagent_console.py +0 -0
  137. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/model_factory.py +0 -0
  138. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/model_utils.py +0 -0
  139. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/models.json +0 -0
  140. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/models_dev_api.json +0 -0
  141. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/models_dev_parser.py +0 -0
  142. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/__init__.py +0 -0
  143. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/antigravity_oauth/__init__.py +0 -0
  144. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/antigravity_oauth/accounts.py +0 -0
  145. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/antigravity_oauth/antigravity_model.py +0 -0
  146. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/antigravity_oauth/config.py +0 -0
  147. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/antigravity_oauth/constants.py +0 -0
  148. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/antigravity_oauth/oauth.py +0 -0
  149. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/antigravity_oauth/register_callbacks.py +0 -0
  150. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/antigravity_oauth/storage.py +0 -0
  151. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/antigravity_oauth/test_plugin.py +0 -0
  152. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/antigravity_oauth/token.py +0 -0
  153. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/antigravity_oauth/transport.py +0 -0
  154. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/antigravity_oauth/utils.py +0 -0
  155. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/chatgpt_oauth/__init__.py +0 -0
  156. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/chatgpt_oauth/config.py +0 -0
  157. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/chatgpt_oauth/oauth_flow.py +0 -0
  158. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/chatgpt_oauth/register_callbacks.py +0 -0
  159. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/chatgpt_oauth/test_plugin.py +0 -0
  160. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/chatgpt_oauth/utils.py +0 -0
  161. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/claude_code_oauth/README.md +0 -0
  162. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/claude_code_oauth/SETUP.md +0 -0
  163. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/claude_code_oauth/__init__.py +0 -0
  164. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/claude_code_oauth/config.py +0 -0
  165. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/claude_code_oauth/register_callbacks.py +0 -0
  166. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/claude_code_oauth/test_plugin.py +0 -0
  167. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/claude_code_oauth/utils.py +0 -0
  168. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/customizable_commands/__init__.py +0 -0
  169. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/customizable_commands/register_callbacks.py +0 -0
  170. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/example_custom_command/README.md +0 -0
  171. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/example_custom_command/register_callbacks.py +0 -0
  172. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/file_permission_handler/__init__.py +0 -0
  173. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/file_permission_handler/register_callbacks.py +0 -0
  174. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/frontend_emitter/__init__.py +0 -0
  175. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/frontend_emitter/emitter.py +0 -0
  176. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/frontend_emitter/register_callbacks.py +0 -0
  177. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/oauth_puppy_html.py +0 -0
  178. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/shell_safety/__init__.py +0 -0
  179. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/shell_safety/agent_shell_safety.py +0 -0
  180. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/shell_safety/command_cache.py +0 -0
  181. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/plugins/shell_safety/register_callbacks.py +0 -0
  182. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/prompts/antigravity_system_prompt.md +0 -0
  183. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/prompts/codex_system_prompt.md +0 -0
  184. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/pydantic_patches.py +0 -0
  185. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/reopenable_async_client.py +0 -0
  186. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/round_robin_model.py +0 -0
  187. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/session_storage.py +0 -0
  188. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/status_display.py +0 -0
  189. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/summarization_agent.py +0 -0
  190. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/terminal_utils.py +0 -0
  191. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/__init__.py +0 -0
  192. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/agent_tools.py +0 -0
  193. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/browser/__init__.py +0 -0
  194. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/browser/browser_control.py +0 -0
  195. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/browser/browser_interactions.py +0 -0
  196. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/browser/browser_locators.py +0 -0
  197. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/browser/browser_navigation.py +0 -0
  198. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/browser/browser_screenshot.py +0 -0
  199. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/browser/browser_scripts.py +0 -0
  200. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/browser/browser_workflows.py +0 -0
  201. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/browser/camoufox_manager.py +0 -0
  202. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/browser/chromium_terminal_manager.py +0 -0
  203. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/browser/terminal_command_tools.py +0 -0
  204. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/browser/terminal_screenshot_tools.py +0 -0
  205. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/browser/terminal_tools.py +0 -0
  206. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/command_runner.py +0 -0
  207. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/common.py +0 -0
  208. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/display.py +0 -0
  209. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/file_modifications.py +0 -0
  210. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/file_operations.py +0 -0
  211. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/subagent_context.py +0 -0
  212. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/tools/tools_content.py +0 -0
  213. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/uvx_detection.py +0 -0
  214. {code_puppy-0.0.361 → code_puppy-0.0.363}/code_puppy/version_checker.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-puppy
3
- Version: 0.0.361
3
+ Version: 0.0.363
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
@@ -0,0 +1,357 @@
1
+ """Interactive terminal UI for selecting agents.
2
+
3
+ Provides a split-panel interface for browsing and selecting agents
4
+ with live preview of agent details.
5
+ """
6
+
7
+ import sys
8
+ import time
9
+ import unicodedata
10
+ from typing import List, Optional, Tuple
11
+
12
+ from prompt_toolkit.application import Application
13
+ from prompt_toolkit.key_binding import KeyBindings
14
+ from prompt_toolkit.layout import Dimension, Layout, VSplit, Window
15
+ from prompt_toolkit.layout.controls import FormattedTextControl
16
+ from prompt_toolkit.widgets import Frame
17
+
18
+ from code_puppy.agents import (
19
+ get_agent_descriptions,
20
+ get_available_agents,
21
+ get_current_agent,
22
+ )
23
+ from code_puppy.tools.command_runner import set_awaiting_user_input
24
+
25
+ PAGE_SIZE = 10 # Agents per page
26
+
27
+
28
+ def _sanitize_display_text(text: str) -> str:
29
+ """Remove or replace characters that cause terminal rendering issues.
30
+
31
+ Args:
32
+ text: Text that may contain emojis or wide characters
33
+
34
+ Returns:
35
+ Sanitized text safe for prompt_toolkit rendering
36
+ """
37
+ # Keep only characters that render cleanly in terminals
38
+ result = []
39
+ for char in text:
40
+ # Get unicode category
41
+ cat = unicodedata.category(char)
42
+ # Keep letters, numbers, punctuation, spaces, and common symbols
43
+ # Skip "So" (Symbol, other - includes most emojis) that cause issues
44
+ if cat != "So" and cat != "Cn": # Cn = not assigned
45
+ result.append(char)
46
+ # Optionally, you could replace emojis with a placeholder:
47
+ # else:
48
+ # result.append("*")
49
+ return "".join(result).strip()
50
+
51
+
52
+ def _get_agent_entries() -> List[Tuple[str, str, str]]:
53
+ """Get all agents with their display names and descriptions.
54
+
55
+ Returns:
56
+ List of tuples (agent_name, display_name, description) sorted by name.
57
+ """
58
+ available = get_available_agents()
59
+ descriptions = get_agent_descriptions()
60
+
61
+ entries = []
62
+ for name, display_name in available.items():
63
+ description = descriptions.get(name, "No description available")
64
+ entries.append((name, display_name, description))
65
+
66
+ # Sort alphabetically by agent name
67
+ entries.sort(key=lambda x: x[0].lower())
68
+ return entries
69
+
70
+
71
+ def _render_menu_panel(
72
+ entries: List[Tuple[str, str, str]],
73
+ page: int,
74
+ selected_idx: int,
75
+ current_agent_name: str,
76
+ ) -> List:
77
+ """Render the left menu panel with pagination.
78
+
79
+ Args:
80
+ entries: List of (name, display_name, description) tuples
81
+ page: Current page number (0-indexed)
82
+ selected_idx: Currently selected index (global)
83
+ current_agent_name: Name of the current active agent
84
+
85
+ Returns:
86
+ List of (style, text) tuples for FormattedTextControl
87
+ """
88
+ lines = []
89
+ total_pages = (len(entries) + PAGE_SIZE - 1) // PAGE_SIZE if entries else 1
90
+ start_idx = page * PAGE_SIZE
91
+ end_idx = min(start_idx + PAGE_SIZE, len(entries))
92
+
93
+ lines.append(("bold", "Agents"))
94
+ lines.append(("fg:ansibrightblack", f" (Page {page + 1}/{total_pages})"))
95
+ lines.append(("", "\n\n"))
96
+
97
+ if not entries:
98
+ lines.append(("fg:yellow", " No agents found."))
99
+ lines.append(("", "\n\n"))
100
+ else:
101
+ # Show agents for current page
102
+ for i in range(start_idx, end_idx):
103
+ name, display_name, _ = entries[i]
104
+ is_selected = i == selected_idx
105
+ is_current = name == current_agent_name
106
+
107
+ # Sanitize display name to avoid emoji rendering issues
108
+ safe_display_name = _sanitize_display_text(display_name)
109
+
110
+ # Build the line
111
+ if is_selected:
112
+ lines.append(("fg:ansigreen", "▶ "))
113
+ lines.append(("fg:ansigreen bold", safe_display_name))
114
+ else:
115
+ lines.append(("", " "))
116
+ lines.append(("", safe_display_name))
117
+
118
+ # Add current marker
119
+ if is_current:
120
+ lines.append(("fg:ansicyan", " ← current"))
121
+
122
+ lines.append(("", "\n"))
123
+
124
+ # Navigation hints
125
+ lines.append(("", "\n"))
126
+ lines.append(("fg:ansibrightblack", " ↑↓ "))
127
+ lines.append(("", "Navigate\n"))
128
+ lines.append(("fg:ansibrightblack", " ←→ "))
129
+ lines.append(("", "Page\n"))
130
+ lines.append(("fg:green", " Enter "))
131
+ lines.append(("", "Select\n"))
132
+ lines.append(("fg:ansibrightred", " Ctrl+C "))
133
+ lines.append(("", "Cancel"))
134
+
135
+ return lines
136
+
137
+
138
+ def _render_preview_panel(
139
+ entry: Optional[Tuple[str, str, str]],
140
+ current_agent_name: str,
141
+ ) -> List:
142
+ """Render the right preview panel with agent details.
143
+
144
+ Args:
145
+ entry: Tuple of (name, display_name, description) or None
146
+ current_agent_name: Name of the current active agent
147
+
148
+ Returns:
149
+ List of (style, text) tuples for FormattedTextControl
150
+ """
151
+ lines = []
152
+
153
+ lines.append(("dim cyan", " AGENT DETAILS"))
154
+ lines.append(("", "\n\n"))
155
+
156
+ if not entry:
157
+ lines.append(("fg:yellow", " No agent selected."))
158
+ lines.append(("", "\n"))
159
+ return lines
160
+
161
+ name, display_name, description = entry
162
+ is_current = name == current_agent_name
163
+
164
+ # Sanitize text to avoid emoji rendering issues
165
+ safe_display_name = _sanitize_display_text(display_name)
166
+ safe_description = _sanitize_display_text(description)
167
+
168
+ # Agent name (identifier)
169
+ lines.append(("bold", "Name: "))
170
+ lines.append(("", name))
171
+ lines.append(("", "\n\n"))
172
+
173
+ # Display name
174
+ lines.append(("bold", "Display Name: "))
175
+ lines.append(("fg:ansicyan", safe_display_name))
176
+ lines.append(("", "\n\n"))
177
+
178
+ # Description
179
+ lines.append(("bold", "Description:"))
180
+ lines.append(("", "\n"))
181
+
182
+ # Wrap description to fit panel
183
+ desc_lines = safe_description.split("\n")
184
+ for desc_line in desc_lines:
185
+ # Word wrap long lines
186
+ words = desc_line.split()
187
+ current_line = ""
188
+ for word in words:
189
+ if len(current_line) + len(word) + 1 > 55:
190
+ lines.append(("fg:ansibrightblack", current_line))
191
+ lines.append(("", "\n"))
192
+ current_line = word
193
+ else:
194
+ if current_line == "":
195
+ current_line = word
196
+ else:
197
+ current_line += " " + word
198
+ if current_line.strip():
199
+ lines.append(("fg:ansibrightblack", current_line))
200
+ lines.append(("", "\n"))
201
+
202
+ lines.append(("", "\n"))
203
+
204
+ # Current status
205
+ lines.append(("bold", " Status: "))
206
+ if is_current:
207
+ lines.append(("fg:ansigreen bold", "✓ Currently Active"))
208
+ else:
209
+ lines.append(("fg:ansibrightblack", "Not active"))
210
+ lines.append(("", "\n"))
211
+
212
+ return lines
213
+
214
+
215
+ async def interactive_agent_picker() -> Optional[str]:
216
+ """Show interactive terminal UI to select an agent.
217
+
218
+ Returns:
219
+ Agent name to switch to, or None if cancelled.
220
+ """
221
+ entries = _get_agent_entries()
222
+ current_agent = get_current_agent()
223
+ current_agent_name = current_agent.name if current_agent else ""
224
+
225
+ if not entries:
226
+ from code_puppy.messaging import emit_info
227
+
228
+ emit_info("No agents found.")
229
+ return None
230
+
231
+ # State
232
+ selected_idx = [0] # Current selection (global index)
233
+ current_page = [0] # Current page
234
+ result = [None] # Selected agent name
235
+
236
+ total_pages = (len(entries) + PAGE_SIZE - 1) // PAGE_SIZE
237
+
238
+ def get_current_entry() -> Optional[Tuple[str, str, str]]:
239
+ if 0 <= selected_idx[0] < len(entries):
240
+ return entries[selected_idx[0]]
241
+ return None
242
+
243
+ # Build UI
244
+ menu_control = FormattedTextControl(text="")
245
+ preview_control = FormattedTextControl(text="")
246
+
247
+ def update_display():
248
+ """Update both panels."""
249
+ menu_control.text = _render_menu_panel(
250
+ entries, current_page[0], selected_idx[0], current_agent_name
251
+ )
252
+ preview_control.text = _render_preview_panel(
253
+ get_current_entry(), current_agent_name
254
+ )
255
+
256
+ menu_window = Window(
257
+ content=menu_control, wrap_lines=False, width=Dimension(weight=35)
258
+ )
259
+ preview_window = Window(
260
+ content=preview_control, wrap_lines=False, width=Dimension(weight=65)
261
+ )
262
+
263
+ menu_frame = Frame(menu_window, width=Dimension(weight=35), title="Agents")
264
+ preview_frame = Frame(preview_window, width=Dimension(weight=65), title="Preview")
265
+
266
+ root_container = VSplit(
267
+ [
268
+ menu_frame,
269
+ preview_frame,
270
+ ]
271
+ )
272
+
273
+ # Key bindings
274
+ kb = KeyBindings()
275
+
276
+ @kb.add("up")
277
+ def _(event):
278
+ if selected_idx[0] > 0:
279
+ selected_idx[0] -= 1
280
+ # Update page if needed
281
+ current_page[0] = selected_idx[0] // PAGE_SIZE
282
+ update_display()
283
+
284
+ @kb.add("down")
285
+ def _(event):
286
+ if selected_idx[0] < len(entries) - 1:
287
+ selected_idx[0] += 1
288
+ # Update page if needed
289
+ current_page[0] = selected_idx[0] // PAGE_SIZE
290
+ update_display()
291
+
292
+ @kb.add("left")
293
+ def _(event):
294
+ if current_page[0] > 0:
295
+ current_page[0] -= 1
296
+ selected_idx[0] = current_page[0] * PAGE_SIZE
297
+ update_display()
298
+
299
+ @kb.add("right")
300
+ def _(event):
301
+ if current_page[0] < total_pages - 1:
302
+ current_page[0] += 1
303
+ selected_idx[0] = current_page[0] * PAGE_SIZE
304
+ update_display()
305
+
306
+ @kb.add("enter")
307
+ def _(event):
308
+ entry = get_current_entry()
309
+ if entry:
310
+ result[0] = entry[0] # Store agent name
311
+ event.app.exit()
312
+
313
+ @kb.add("c-c")
314
+ def _(event):
315
+ result[0] = None
316
+ event.app.exit()
317
+
318
+ layout = Layout(root_container)
319
+ app = Application(
320
+ layout=layout,
321
+ key_bindings=kb,
322
+ full_screen=False,
323
+ mouse_support=False,
324
+ )
325
+
326
+ set_awaiting_user_input(True)
327
+
328
+ # Enter alternate screen buffer once for entire session
329
+ sys.stdout.write("\033[?1049h") # Enter alternate buffer
330
+ sys.stdout.write("\033[2J\033[H") # Clear and home
331
+ sys.stdout.flush()
332
+ time.sleep(0.05)
333
+
334
+ try:
335
+ # Initial display
336
+ update_display()
337
+
338
+ # Clear the current buffer
339
+ sys.stdout.write("\033[2J\033[H")
340
+ sys.stdout.flush()
341
+
342
+ # Run application
343
+ await app.run_async()
344
+
345
+ finally:
346
+ # Exit alternate screen buffer once at end
347
+ sys.stdout.write("\033[?1049l") # Exit alternate buffer
348
+ sys.stdout.flush()
349
+ # Reset awaiting input flag
350
+ set_awaiting_user_input(False)
351
+
352
+ # Clear exit message
353
+ from code_puppy.messaging import emit_info
354
+
355
+ emit_info("✓ Exited agent picker")
356
+
357
+ return result[0]
@@ -6,6 +6,7 @@ discovered by the command registry system.
6
6
 
7
7
  import os
8
8
 
9
+ from code_puppy.command_line.agent_menu import interactive_agent_picker
9
10
  from code_puppy.command_line.command_registry import register_command
10
11
  from code_puppy.command_line.model_picker_completion import update_model_in_input
11
12
  from code_puppy.command_line.motd import print_motd
@@ -398,115 +399,6 @@ def handle_agent_command(command: str) -> bool:
398
399
  return True
399
400
 
400
401
 
401
- async def interactive_agent_picker() -> str | None:
402
- """Show an interactive arrow-key selector to pick an agent (async version).
403
-
404
- Returns:
405
- The selected agent name, or None if cancelled
406
- """
407
- import sys
408
- import time
409
-
410
- from rich.console import Console
411
- from rich.panel import Panel
412
- from rich.text import Text
413
-
414
- from code_puppy.agents import (
415
- get_agent_descriptions,
416
- get_available_agents,
417
- get_current_agent,
418
- )
419
- from code_puppy.tools.command_runner import set_awaiting_user_input
420
- from code_puppy.tools.common import arrow_select_async
421
-
422
- # Load available agents
423
- available_agents = get_available_agents()
424
- descriptions = get_agent_descriptions()
425
- current_agent = get_current_agent()
426
-
427
- # Build choices with current agent indicator and keep track of agent names
428
- choices = []
429
- agent_names = list(available_agents.keys())
430
- for agent_name in agent_names:
431
- display_name = available_agents[agent_name]
432
- if agent_name == current_agent.name:
433
- choices.append(f"✓ {agent_name} - {display_name} (current)")
434
- else:
435
- choices.append(f" {agent_name} - {display_name}")
436
-
437
- # Create preview callback to show agent description
438
- def get_preview(index: int) -> str:
439
- """Get the description for the agent at the given index."""
440
- agent_name = agent_names[index]
441
- description = descriptions.get(agent_name, "No description available")
442
- return description
443
-
444
- # Create panel content
445
- panel_content = Text()
446
- panel_content.append("🐶 Select an agent to use\n", style="bold cyan")
447
- panel_content.append("Current agent: ", style="dim")
448
- panel_content.append(f"{current_agent.name}", style="bold green")
449
- panel_content.append(" - ", style="dim")
450
- panel_content.append(current_agent.display_name, style="bold green")
451
- panel_content.append("\n", style="dim")
452
- panel_content.append(current_agent.description, style="dim italic")
453
-
454
- # Display panel
455
- panel = Panel(
456
- panel_content,
457
- title="[bold white]Agent Selection[/bold white]",
458
- border_style="cyan",
459
- padding=(1, 2),
460
- )
461
-
462
- # Pause spinners BEFORE showing panel
463
- set_awaiting_user_input(True)
464
- time.sleep(0.3) # Let spinners fully stop
465
-
466
- local_console = Console()
467
- emit_info("")
468
- local_console.print(panel)
469
- emit_info("")
470
-
471
- # Flush output before prompt_toolkit takes control
472
- sys.stdout.flush()
473
- sys.stderr.flush()
474
- time.sleep(0.1)
475
-
476
- selected_agent = None
477
-
478
- try:
479
- # Final flush
480
- sys.stdout.flush()
481
-
482
- # Show arrow-key selector with preview (async version)
483
- choice = await arrow_select_async(
484
- "💭 Which agent would you like to use?",
485
- choices,
486
- preview_callback=get_preview,
487
- )
488
-
489
- # Extract agent name from choice (remove prefix and suffix)
490
- if choice:
491
- # Remove the "✓ " or " " prefix and extract agent name (before " - ")
492
- choice_stripped = choice.strip().lstrip("✓").strip()
493
- # Split on " - " and take the first part (agent name)
494
- agent_name = choice_stripped.split(" - ")[0].strip()
495
- # Remove " (current)" suffix if present
496
- if agent_name.endswith(" (current)"):
497
- agent_name = agent_name[:-10].strip()
498
- selected_agent = agent_name
499
-
500
- except (KeyboardInterrupt, EOFError):
501
- emit_error("Cancelled by user")
502
- selected_agent = None
503
-
504
- finally:
505
- set_awaiting_user_input(False)
506
-
507
- return selected_agent
508
-
509
-
510
402
  async def interactive_model_picker() -> str | None:
511
403
  """Show an interactive arrow-key selector to pick a model (async version).
512
404
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "code-puppy"
7
- version = "0.0.361"
7
+ version = "0.0.363"
8
8
  description = "Code generation agent"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11,<3.14"
File without changes
File without changes
File without changes