newcode 0.2.6__tar.gz → 0.2.8__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 (272) hide show
  1. {newcode-0.2.6 → newcode-0.2.8}/PKG-INFO +1 -1
  2. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/base_agent.py +6 -0
  3. {newcode-0.2.6 → newcode-0.2.8}/newcode/claude_cache_client.py +13 -3
  4. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/core_commands.py +15 -1
  5. {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/executor.py +1 -1
  6. {newcode-0.2.6 → newcode-0.2.8}/newcode/models.json +4 -4
  7. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/chatgpt_oauth/oauth_flow.py +3 -2
  8. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/chatgpt_oauth/test_plugin.py +7 -1
  9. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/chatgpt_oauth/utils.py +25 -1
  10. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_oauth/utils.py +39 -3
  11. {newcode-0.2.6 → newcode-0.2.8}/pyproject.toml +1 -1
  12. {newcode-0.2.6 → newcode-0.2.8}/.gitignore +0 -0
  13. {newcode-0.2.6 → newcode-0.2.8}/LICENSE +0 -0
  14. {newcode-0.2.6 → newcode-0.2.8}/README.md +0 -0
  15. {newcode-0.2.6 → newcode-0.2.8}/newcode/__init__.py +0 -0
  16. {newcode-0.2.6 → newcode-0.2.8}/newcode/__main__.py +0 -0
  17. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/__init__.py +0 -0
  18. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_c_reviewer.py +0 -0
  19. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_code_agent.py +0 -0
  20. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_code_reviewer.py +0 -0
  21. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_cpp_reviewer.py +0 -0
  22. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_creator_agent.py +0 -0
  23. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_golang_reviewer.py +0 -0
  24. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_javascript_reviewer.py +0 -0
  25. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_manager.py +0 -0
  26. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_pack_leader.py +0 -0
  27. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_planning.py +0 -0
  28. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_python_programmer.py +0 -0
  29. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_python_reviewer.py +0 -0
  30. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_qa_browser.py +0 -0
  31. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_qa_expert.py +0 -0
  32. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_security_auditor.py +0 -0
  33. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_terminal_qa.py +0 -0
  34. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_typescript_reviewer.py +0 -0
  35. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/event_stream_handler.py +0 -0
  36. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/json_agent.py +0 -0
  37. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/pack/__init__.py +0 -0
  38. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/pack/bloodhound.py +0 -0
  39. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/pack/husky.py +0 -0
  40. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/pack/retriever.py +0 -0
  41. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/pack/shepherd.py +0 -0
  42. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/pack/terrier.py +0 -0
  43. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/pack/watchdog.py +0 -0
  44. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/prompt_reviewer.py +0 -0
  45. {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/subagent_stream_handler.py +0 -0
  46. {newcode-0.2.6 → newcode-0.2.8}/newcode/api/__init__.py +0 -0
  47. {newcode-0.2.6 → newcode-0.2.8}/newcode/api/app.py +0 -0
  48. {newcode-0.2.6 → newcode-0.2.8}/newcode/api/main.py +0 -0
  49. {newcode-0.2.6 → newcode-0.2.8}/newcode/api/pty_manager.py +0 -0
  50. {newcode-0.2.6 → newcode-0.2.8}/newcode/api/routers/__init__.py +0 -0
  51. {newcode-0.2.6 → newcode-0.2.8}/newcode/api/routers/agents.py +0 -0
  52. {newcode-0.2.6 → newcode-0.2.8}/newcode/api/routers/commands.py +0 -0
  53. {newcode-0.2.6 → newcode-0.2.8}/newcode/api/routers/config.py +0 -0
  54. {newcode-0.2.6 → newcode-0.2.8}/newcode/api/routers/sessions.py +0 -0
  55. {newcode-0.2.6 → newcode-0.2.8}/newcode/api/templates/terminal.html +0 -0
  56. {newcode-0.2.6 → newcode-0.2.8}/newcode/api/websocket.py +0 -0
  57. {newcode-0.2.6 → newcode-0.2.8}/newcode/callbacks.py +0 -0
  58. {newcode-0.2.6 → newcode-0.2.8}/newcode/chatgpt_codex_client.py +0 -0
  59. {newcode-0.2.6 → newcode-0.2.8}/newcode/cli_runner.py +0 -0
  60. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/__init__.py +0 -0
  61. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/add_model_menu.py +0 -0
  62. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/agent_menu.py +0 -0
  63. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/attachments.py +0 -0
  64. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/autosave_menu.py +0 -0
  65. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/clipboard.py +0 -0
  66. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/colors_menu.py +0 -0
  67. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/command_handler.py +0 -0
  68. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/command_registry.py +0 -0
  69. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/config_commands.py +0 -0
  70. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/diff_menu.py +0 -0
  71. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/file_path_completion.py +0 -0
  72. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/load_context_completion.py +0 -0
  73. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/__init__.py +0 -0
  74. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/base.py +0 -0
  75. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/catalog_server_installer.py +0 -0
  76. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/custom_server_form.py +0 -0
  77. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/custom_server_installer.py +0 -0
  78. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/edit_command.py +0 -0
  79. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/handler.py +0 -0
  80. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/help_command.py +0 -0
  81. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/install_command.py +0 -0
  82. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/install_menu.py +0 -0
  83. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/list_command.py +0 -0
  84. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/logs_command.py +0 -0
  85. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/remove_command.py +0 -0
  86. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/restart_command.py +0 -0
  87. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/search_command.py +0 -0
  88. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/start_all_command.py +0 -0
  89. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/start_command.py +0 -0
  90. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/status_command.py +0 -0
  91. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/stop_all_command.py +0 -0
  92. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/stop_command.py +0 -0
  93. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/test_command.py +0 -0
  94. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/utils.py +0 -0
  95. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/wizard_utils.py +0 -0
  96. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp_completion.py +0 -0
  97. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/model_picker_completion.py +0 -0
  98. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/model_settings_menu.py +0 -0
  99. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/motd.py +0 -0
  100. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/onboarding_slides.py +0 -0
  101. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/onboarding_wizard.py +0 -0
  102. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/pin_command_completion.py +0 -0
  103. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/prompt_toolkit_completion.py +0 -0
  104. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/session_commands.py +0 -0
  105. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/skills_completion.py +0 -0
  106. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/uc_menu.py +0 -0
  107. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/utils.py +0 -0
  108. {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/wiggum_state.py +0 -0
  109. {newcode-0.2.6 → newcode-0.2.8}/newcode/config.py +0 -0
  110. {newcode-0.2.6 → newcode-0.2.8}/newcode/error_logging.py +0 -0
  111. {newcode-0.2.6 → newcode-0.2.8}/newcode/gemini_code_assist.py +0 -0
  112. {newcode-0.2.6 → newcode-0.2.8}/newcode/gemini_model.py +0 -0
  113. {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/README.md +0 -0
  114. {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/__init__.py +0 -0
  115. {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/aliases.py +0 -0
  116. {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/engine.py +0 -0
  117. {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/matcher.py +0 -0
  118. {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/models.py +0 -0
  119. {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/registry.py +0 -0
  120. {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/validator.py +0 -0
  121. {newcode-0.2.6 → newcode-0.2.8}/newcode/http_utils.py +0 -0
  122. {newcode-0.2.6 → newcode-0.2.8}/newcode/image_utils.py +0 -0
  123. {newcode-0.2.6 → newcode-0.2.8}/newcode/keymap.py +0 -0
  124. {newcode-0.2.6 → newcode-0.2.8}/newcode/main.py +0 -0
  125. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/__init__.py +0 -0
  126. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/async_lifecycle.py +0 -0
  127. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/blocking_startup.py +0 -0
  128. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/captured_stdio_server.py +0 -0
  129. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/circuit_breaker.py +0 -0
  130. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/config_wizard.py +0 -0
  131. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/dashboard.py +0 -0
  132. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/error_isolation.py +0 -0
  133. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/examples/retry_example.py +0 -0
  134. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/health_monitor.py +0 -0
  135. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/managed_server.py +0 -0
  136. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/manager.py +0 -0
  137. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/mcp_logs.py +0 -0
  138. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/registry.py +0 -0
  139. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/retry_manager.py +0 -0
  140. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/server_registry_catalog.py +0 -0
  141. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/status_tracker.py +0 -0
  142. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/system_tools.py +0 -0
  143. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_prompts/__init__.py +0 -0
  144. {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_prompts/hook_creator.py +0 -0
  145. {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/__init__.py +0 -0
  146. {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/bus.py +0 -0
  147. {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/commands.py +0 -0
  148. {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/markdown_patches.py +0 -0
  149. {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/message_queue.py +0 -0
  150. {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/messages.py +0 -0
  151. {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/queue_console.py +0 -0
  152. {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/renderers.py +0 -0
  153. {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/rich_renderer.py +0 -0
  154. {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/spinner/__init__.py +0 -0
  155. {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/spinner/console_spinner.py +0 -0
  156. {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/spinner/spinner_base.py +0 -0
  157. {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/subagent_console.py +0 -0
  158. {newcode-0.2.6 → newcode-0.2.8}/newcode/model_factory.py +0 -0
  159. {newcode-0.2.6 → newcode-0.2.8}/newcode/model_switching.py +0 -0
  160. {newcode-0.2.6 → newcode-0.2.8}/newcode/model_utils.py +0 -0
  161. {newcode-0.2.6 → newcode-0.2.8}/newcode/models_dev_api.json +0 -0
  162. {newcode-0.2.6 → newcode-0.2.8}/newcode/models_dev_parser.py +0 -0
  163. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/__init__.py +0 -0
  164. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/__init__.py +0 -0
  165. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/config.py +0 -0
  166. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/discovery.py +0 -0
  167. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/downloader.py +0 -0
  168. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/installer.py +0 -0
  169. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/metadata.py +0 -0
  170. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/prompt_builder.py +0 -0
  171. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/register_callbacks.py +0 -0
  172. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/remote_catalog.py +0 -0
  173. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/skill_catalog.py +0 -0
  174. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/skills_install_menu.py +0 -0
  175. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/skills_menu.py +0 -0
  176. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/__init__.py +0 -0
  177. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/accounts.py +0 -0
  178. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/antigravity_model.py +0 -0
  179. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/config.py +0 -0
  180. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/constants.py +0 -0
  181. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/oauth.py +0 -0
  182. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/register_callbacks.py +0 -0
  183. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/storage.py +0 -0
  184. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/test_plugin.py +0 -0
  185. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/token.py +0 -0
  186. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/transport.py +0 -0
  187. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/utils.py +0 -0
  188. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/chatgpt_oauth/__init__.py +0 -0
  189. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/chatgpt_oauth/config.py +0 -0
  190. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/chatgpt_oauth/register_callbacks.py +0 -0
  191. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_hooks/__init__.py +0 -0
  192. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_hooks/config.py +0 -0
  193. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_hooks/register_callbacks.py +0 -0
  194. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_oauth/README.md +0 -0
  195. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_oauth/SETUP.md +0 -0
  196. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_oauth/__init__.py +0 -0
  197. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_oauth/config.py +0 -0
  198. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_oauth/register_callbacks.py +0 -0
  199. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_oauth/test_plugin.py +0 -0
  200. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_oauth/token_refresh_heartbeat.py +0 -0
  201. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/customizable_commands/__init__.py +0 -0
  202. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/customizable_commands/register_callbacks.py +0 -0
  203. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/example_custom_command/README.md +0 -0
  204. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/example_custom_command/register_callbacks.py +0 -0
  205. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/file_permission_handler/__init__.py +0 -0
  206. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/file_permission_handler/register_callbacks.py +0 -0
  207. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/frontend_emitter/__init__.py +0 -0
  208. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/frontend_emitter/emitter.py +0 -0
  209. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/frontend_emitter/register_callbacks.py +0 -0
  210. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/hook_creator/__init__.py +0 -0
  211. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/hook_creator/register_callbacks.py +0 -0
  212. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/hook_manager/__init__.py +0 -0
  213. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/hook_manager/config.py +0 -0
  214. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/hook_manager/hooks_menu.py +0 -0
  215. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/hook_manager/register_callbacks.py +0 -0
  216. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/oauth_puppy_html.py +0 -0
  217. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/shell_safety/__init__.py +0 -0
  218. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/shell_safety/agent_shell_safety.py +0 -0
  219. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/shell_safety/command_cache.py +0 -0
  220. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/shell_safety/register_callbacks.py +0 -0
  221. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/synthetic_status/__init__.py +0 -0
  222. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/synthetic_status/register_callbacks.py +0 -0
  223. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/synthetic_status/status_api.py +0 -0
  224. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/universal_constructor/__init__.py +0 -0
  225. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/universal_constructor/models.py +0 -0
  226. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/universal_constructor/register_callbacks.py +0 -0
  227. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/universal_constructor/registry.py +0 -0
  228. {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/universal_constructor/sandbox.py +0 -0
  229. {newcode-0.2.6 → newcode-0.2.8}/newcode/prompts/antigravity_system_prompt.md +0 -0
  230. {newcode-0.2.6 → newcode-0.2.8}/newcode/pydantic_patches.py +0 -0
  231. {newcode-0.2.6 → newcode-0.2.8}/newcode/reopenable_async_client.py +0 -0
  232. {newcode-0.2.6 → newcode-0.2.8}/newcode/round_robin_model.py +0 -0
  233. {newcode-0.2.6 → newcode-0.2.8}/newcode/session_storage.py +0 -0
  234. {newcode-0.2.6 → newcode-0.2.8}/newcode/status_display.py +0 -0
  235. {newcode-0.2.6 → newcode-0.2.8}/newcode/summarization_agent.py +0 -0
  236. {newcode-0.2.6 → newcode-0.2.8}/newcode/terminal_utils.py +0 -0
  237. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/__init__.py +0 -0
  238. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/agent_tools.py +0 -0
  239. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/__init__.py +0 -0
  240. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/constants.py +0 -0
  241. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/demo_tui.py +0 -0
  242. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/handler.py +0 -0
  243. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/models.py +0 -0
  244. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/registration.py +0 -0
  245. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/renderers.py +0 -0
  246. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/terminal_ui.py +0 -0
  247. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/theme.py +0 -0
  248. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/tui_loop.py +0 -0
  249. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/__init__.py +0 -0
  250. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/browser_control.py +0 -0
  251. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/browser_interactions.py +0 -0
  252. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/browser_locators.py +0 -0
  253. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/browser_manager.py +0 -0
  254. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/browser_navigation.py +0 -0
  255. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/browser_screenshot.py +0 -0
  256. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/browser_scripts.py +0 -0
  257. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/browser_workflows.py +0 -0
  258. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/chromium_terminal_manager.py +0 -0
  259. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/terminal_command_tools.py +0 -0
  260. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/terminal_screenshot_tools.py +0 -0
  261. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/terminal_tools.py +0 -0
  262. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/command_runner.py +0 -0
  263. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/common.py +0 -0
  264. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/display.py +0 -0
  265. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/file_modifications.py +0 -0
  266. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/file_operations.py +0 -0
  267. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/skills_tools.py +0 -0
  268. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/subagent_context.py +0 -0
  269. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/tools_content.py +0 -0
  270. {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/universal_constructor.py +0 -0
  271. {newcode-0.2.6 → newcode-0.2.8}/newcode/uvx_detection.py +0 -0
  272. {newcode-0.2.6 → newcode-0.2.8}/newcode/version_checker.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: newcode
3
- Version: 0.2.6
3
+ Version: 0.2.8
4
4
  Summary: AI-powered code generation agent platform
5
5
  Project-URL: repository, https://github.com/janfeddersen-wq/new_code
6
6
  Project-URL: HomePage, https://github.com/janfeddersen-wq/new_code
@@ -1319,6 +1319,12 @@ class BaseAgent(ABC):
1319
1319
  """Force-reload the pydantic-ai Agent based on current config and model."""
1320
1320
  from newcode.tools import register_tools_for_agent
1321
1321
 
1322
+ # Invalidate the project-local rules cache so a fresh read from the
1323
+ # current working directory is performed on the next load_agent_rules()
1324
+ # call. This is critical for /cd: the user may have switched to a
1325
+ # different project that has its own AGENT.md (or none at all).
1326
+ self._agent_rules = None
1327
+
1322
1328
  if message_group is None:
1323
1329
  message_group = str(uuid.uuid4())
1324
1330
 
@@ -371,7 +371,7 @@ class ClaudeCacheAsyncClient(httpx.AsyncClient):
371
371
  is_auth_error = response.status_code in (401, 403)
372
372
 
373
373
  if response.status_code == 400:
374
- is_auth_error = self._is_cloudflare_html_error(response)
374
+ is_auth_error = await self._is_cloudflare_html_error(response)
375
375
  if is_auth_error:
376
376
  logger.info(
377
377
  "Detected Cloudflare 400 error (expired token), attempting token refresh"
@@ -531,7 +531,7 @@ class ClaudeCacheAsyncClient(httpx.AsyncClient):
531
531
  headers["Authorization"] = bearer_value
532
532
 
533
533
  @staticmethod
534
- def _is_cloudflare_html_error(response: httpx.Response) -> bool:
534
+ async def _is_cloudflare_html_error(response: httpx.Response) -> bool:
535
535
  """Check if this is a Cloudflare HTML error response.
536
536
 
537
537
  Cloudflare often returns HTML error pages with status 400 when
@@ -546,10 +546,20 @@ class ClaudeCacheAsyncClient(httpx.AsyncClient):
546
546
  """
547
547
  try:
548
548
  body = None
549
- # Try reading the body from _content first (already consumed)
549
+
550
+ # For async httpx, read the body if content is not available yet.
551
+ if not hasattr(response, "_content") or not response._content:
552
+ try:
553
+ await response.aread()
554
+ except Exception as read_exc:
555
+ logger.debug("Failed to read response body: %s", read_exc)
556
+ return False
557
+
558
+ # Prefer raw _content if present (already consumed responses).
550
559
  if hasattr(response, "_content") and response._content:
551
560
  body = response._content.decode("utf-8", errors="ignore")
552
561
  else:
562
+ # Fallback to text property.
553
563
  try:
554
564
  body = response.text
555
565
  except Exception:
@@ -55,7 +55,7 @@ def handle_cd_command(command: str) -> bool:
55
55
  # Use shlex.split to handle quoted paths properly
56
56
  import shlex
57
57
 
58
- from newcode.messaging import emit_error, emit_info, emit_success
58
+ from newcode.messaging import emit_error, emit_info, emit_success, emit_warning
59
59
 
60
60
  try:
61
61
  tokens = shlex.split(command)
@@ -77,6 +77,20 @@ def handle_cd_command(command: str) -> bool:
77
77
  if os.path.isdir(target):
78
78
  os.chdir(target)
79
79
  emit_success(f"Changed directory to: {target}")
80
+ # Reload the agent so the system prompt and project-local
81
+ # AGENT.md rules reflect the new working directory. Without
82
+ # this, the LLM keeps receiving stale path information for the
83
+ # remainder of the session (the PydanticAgent instructions are
84
+ # baked in at construction time and never refreshed otherwise).
85
+ try:
86
+ from newcode.agents import get_current_agent
87
+
88
+ get_current_agent().reload_code_generation_agent()
89
+ except Exception as e:
90
+ emit_warning(
91
+ f"Directory changed, but agent reload failed: {e}. "
92
+ "You may need to run /agent or /model to force a refresh."
93
+ )
80
94
  else:
81
95
  emit_error(f"Not a directory: {dirname}")
82
96
  return True
@@ -193,7 +193,7 @@ def _substitute_variables(
193
193
  result = command
194
194
  for var, value in substitutions.items():
195
195
  result = result.replace(f"${{{var}}}", str(value))
196
- result = re.sub(rf"\${re.escape(var)}(?=\W|$)", str(value), result)
196
+ result = re.sub(rf"\${re.escape(var)}(?=\W|$)", lambda m: str(value), result)
197
197
  return result
198
198
 
199
199
 
@@ -9,9 +9,9 @@
9
9
  "context_length": 200000,
10
10
  "supported_settings": ["temperature", "seed", "top_p"]
11
11
  },
12
- "synthetic-MiniMax-M2.1": {
12
+ "synthetic-MiniMax-M2.5": {
13
13
  "type": "custom_openai",
14
- "name": "hf:MiniMaxAI/MiniMax-M2.1",
14
+ "name": "hf:MiniMaxAI/MiniMax-M2.5",
15
15
  "custom_endpoint": {
16
16
  "url": "https://api.synthetic.new/openai/v1/",
17
17
  "api_key": "$SYN_API_KEY"
@@ -19,9 +19,9 @@
19
19
  "context_length": 195000,
20
20
  "supported_settings": ["temperature", "seed", "top_p"]
21
21
  },
22
- "synthetic-Kimi-K2-Thinking": {
22
+ "synthetic-qwen3.5-397b": {
23
23
  "type": "custom_openai",
24
- "name": "hf:moonshotai/Kimi-K2-Thinking",
24
+ "name": "hf:Qwen/Qwen3.5-397B-A17B",
25
25
  "custom_endpoint": {
26
26
  "url": "https://api.synthetic.new/openai/v1/",
27
27
  "api_key": "$SYN_API_KEY"
@@ -318,9 +318,10 @@ def run_oauth_flow() -> None:
318
318
 
319
319
  if api_key:
320
320
  emit_info("Registering ChatGPT Codex models…")
321
- from .utils import DEFAULT_CODEX_MODELS
321
+ from .utils import fetch_chatgpt_models
322
322
 
323
- models = DEFAULT_CODEX_MODELS
323
+ account_id = tokens.get("account_id", "")
324
+ models = fetch_chatgpt_models(api_key, account_id)
324
325
  if models:
325
326
  if add_models_to_extra_config(models):
326
327
  emit_success(
@@ -251,6 +251,10 @@ def test_fetch_chatgpt_models(mock_get):
251
251
 
252
252
  models = utils.fetch_chatgpt_models("test_access_token", "test_account_id")
253
253
  assert models is not None
254
+ # Required models always injected
255
+ assert "gpt-5.4" in models
256
+ assert "gpt-5.3-instant" in models
257
+ # API-returned models present too
254
258
  assert "gpt-4o" in models
255
259
  assert "gpt-3.5-turbo" in models
256
260
  assert "o1-preview" in models
@@ -267,7 +271,9 @@ def test_fetch_chatgpt_models_fallback(mock_get):
267
271
 
268
272
  models = utils.fetch_chatgpt_models("test_access_token", "test_account_id")
269
273
  assert models is not None
270
- # Should return default models
274
+ # Should return default models (including new required ones)
275
+ assert "gpt-5.4" in models
276
+ assert "gpt-5.3-instant" in models
271
277
  assert "gpt-5.3-codex-spark" in models
272
278
  assert "gpt-5.3-codex" in models
273
279
  assert "gpt-5.2-codex" in models
@@ -344,19 +344,43 @@ def exchange_code_for_tokens(
344
344
  # These are the known models that work with ChatGPT OAuth tokens
345
345
  # Based on codex-rs CLI and shell-scripts/codex-call.sh
346
346
  DEFAULT_CODEX_MODELS = [
347
+ "gpt-5.4",
348
+ "gpt-5.3-instant",
347
349
  "gpt-5.3-codex-spark",
348
350
  "gpt-5.3-codex",
349
351
  "gpt-5.2-codex",
350
352
  "gpt-5.2",
351
353
  ]
352
354
 
355
+ # Models that MUST always be registered, even if the /models endpoint
356
+ # doesn't return them (e.g. newly launched, not yet in the API catalogue).
357
+ # These are merged into whatever the endpoint returns.
358
+ REQUIRED_CODEX_MODELS = [
359
+ "gpt-5.4",
360
+ "gpt-5.3-instant",
361
+ "gpt-5.3-codex",
362
+ ]
363
+
353
364
  # Per-model context length overrides (tokens).
354
365
  # Models not listed here use CHATGPT_OAUTH_CONFIG["default_context_length"] (272,000).
355
366
  CODEX_MODEL_CONTEXT_LENGTHS = {
356
367
  "gpt-5.3-codex-spark": 131000,
368
+ "gpt-5.3-instant": 192000,
357
369
  }
358
370
 
359
371
 
372
+ def _ensure_required_models(models: List[str]) -> List[str]:
373
+ """Merge REQUIRED_CODEX_MODELS into the given list, preserving order.
374
+
375
+ Any required model not already present is prepended so it appears first.
376
+ """
377
+ existing = set(models)
378
+ missing = [m for m in REQUIRED_CODEX_MODELS if m not in existing]
379
+ if missing:
380
+ logger.info("Injecting required models not returned by API: %s", missing)
381
+ return missing + models
382
+
383
+
360
384
  def fetch_chatgpt_models(access_token: str, account_id: str) -> Optional[List[str]]:
361
385
  """Fetch available models from ChatGPT Codex API.
362
386
 
@@ -419,7 +443,7 @@ def fetch_chatgpt_models(access_token: str, account_id: str) -> Optional[List[st
419
443
  if model_id:
420
444
  models.append(model_id)
421
445
  if models:
422
- return models
446
+ return _ensure_required_models(models)
423
447
  except (json.JSONDecodeError, ValueError) as exc:
424
448
  logger.warning("Failed to parse models response: %s", exc)
425
449
 
@@ -238,7 +238,19 @@ def refresh_access_token(force: bool = False) -> Optional[str]:
238
238
  timeout=30,
239
239
  )
240
240
  if response.status_code == 200:
241
- new_tokens = response.json()
241
+ content_type = response.headers.get("content-type", "")
242
+ if not content_type.startswith("application/json"):
243
+ logger.error(
244
+ "Token refresh returned non-JSON response (Content-Type: %s): %s",
245
+ content_type,
246
+ response.text[:500],
247
+ )
248
+ return None
249
+ try:
250
+ new_tokens = response.json()
251
+ except (ValueError, json.JSONDecodeError) as e:
252
+ logger.error("Failed to parse token refresh response as JSON: %s", e)
253
+ return None
242
254
  tokens["access_token"] = new_tokens.get("access_token")
243
255
  tokens["refresh_token"] = new_tokens.get("refresh_token", refresh_token)
244
256
  expires_in_value = new_tokens.get("expires_in")
@@ -401,7 +413,19 @@ def exchange_code_for_tokens(
401
413
  logger.info("Token exchange response: %s", response.status_code)
402
414
  logger.debug("Response body: %s", response.text)
403
415
  if response.status_code == 200:
404
- token_data = response.json()
416
+ content_type = response.headers.get("content-type", "")
417
+ if not content_type.startswith("application/json"):
418
+ logger.error(
419
+ "Token exchange returned non-JSON response (Content-Type: %s): %s",
420
+ content_type,
421
+ response.text[:500],
422
+ )
423
+ return None
424
+ try:
425
+ token_data = response.json()
426
+ except (ValueError, json.JSONDecodeError) as e:
427
+ logger.error("Failed to parse token exchange response as JSON: %s", e)
428
+ return None
405
429
  token_data["expires_at"] = _calculate_expires_at(
406
430
  token_data.get("expires_in")
407
431
  )
@@ -492,7 +516,19 @@ def fetch_claude_code_models(access_token: str) -> Optional[List[str]]:
492
516
  }
493
517
  response = requests.get(api_url, headers=headers, timeout=30)
494
518
  if response.status_code == 200:
495
- data = response.json()
519
+ content_type = response.headers.get("content-type", "")
520
+ if not content_type.startswith("application/json"):
521
+ logger.error(
522
+ "Models fetch returned non-JSON response (Content-Type: %s): %s",
523
+ content_type,
524
+ response.text[:500],
525
+ )
526
+ return None
527
+ try:
528
+ data = response.json()
529
+ except (ValueError, json.JSONDecodeError) as e:
530
+ logger.error("Failed to parse models response as JSON: %s", e)
531
+ return None
496
532
  if isinstance(data.get("data"), list):
497
533
  models: List[str] = []
498
534
  for model in data["data"]:
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "newcode"
7
- version = "0.2.6"
7
+ version = "0.2.8"
8
8
  description = "AI-powered code generation agent platform"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11,<3.14"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes