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.
- {newcode-0.2.6 → newcode-0.2.8}/PKG-INFO +1 -1
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/base_agent.py +6 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/claude_cache_client.py +13 -3
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/core_commands.py +15 -1
- {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/executor.py +1 -1
- {newcode-0.2.6 → newcode-0.2.8}/newcode/models.json +4 -4
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/chatgpt_oauth/oauth_flow.py +3 -2
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/chatgpt_oauth/test_plugin.py +7 -1
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/chatgpt_oauth/utils.py +25 -1
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_oauth/utils.py +39 -3
- {newcode-0.2.6 → newcode-0.2.8}/pyproject.toml +1 -1
- {newcode-0.2.6 → newcode-0.2.8}/.gitignore +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/LICENSE +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/README.md +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/__main__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_c_reviewer.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_code_agent.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_code_reviewer.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_cpp_reviewer.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_creator_agent.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_golang_reviewer.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_javascript_reviewer.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_manager.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_pack_leader.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_planning.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_python_programmer.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_python_reviewer.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_qa_browser.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_qa_expert.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_security_auditor.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_terminal_qa.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/agent_typescript_reviewer.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/event_stream_handler.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/json_agent.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/pack/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/pack/bloodhound.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/pack/husky.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/pack/retriever.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/pack/shepherd.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/pack/terrier.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/pack/watchdog.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/prompt_reviewer.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/agents/subagent_stream_handler.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/api/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/api/app.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/api/main.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/api/pty_manager.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/api/routers/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/api/routers/agents.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/api/routers/commands.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/api/routers/config.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/api/routers/sessions.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/api/templates/terminal.html +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/api/websocket.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/callbacks.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/chatgpt_codex_client.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/cli_runner.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/add_model_menu.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/agent_menu.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/attachments.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/autosave_menu.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/clipboard.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/colors_menu.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/command_handler.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/command_registry.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/config_commands.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/diff_menu.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/file_path_completion.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/load_context_completion.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/base.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/catalog_server_installer.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/custom_server_form.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/custom_server_installer.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/edit_command.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/handler.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/help_command.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/install_command.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/install_menu.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/list_command.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/logs_command.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/remove_command.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/restart_command.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/search_command.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/start_all_command.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/start_command.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/status_command.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/stop_all_command.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/stop_command.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/test_command.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/utils.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp/wizard_utils.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/mcp_completion.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/model_picker_completion.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/model_settings_menu.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/motd.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/onboarding_slides.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/onboarding_wizard.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/pin_command_completion.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/prompt_toolkit_completion.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/session_commands.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/skills_completion.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/uc_menu.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/utils.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/command_line/wiggum_state.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/config.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/error_logging.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/gemini_code_assist.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/gemini_model.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/README.md +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/aliases.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/engine.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/matcher.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/models.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/registry.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/hook_engine/validator.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/http_utils.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/image_utils.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/keymap.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/main.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/async_lifecycle.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/blocking_startup.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/captured_stdio_server.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/circuit_breaker.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/config_wizard.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/dashboard.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/error_isolation.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/examples/retry_example.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/health_monitor.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/managed_server.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/manager.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/mcp_logs.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/registry.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/retry_manager.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/server_registry_catalog.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/status_tracker.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_/system_tools.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_prompts/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/mcp_prompts/hook_creator.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/bus.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/commands.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/markdown_patches.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/message_queue.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/messages.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/queue_console.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/renderers.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/rich_renderer.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/spinner/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/spinner/console_spinner.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/spinner/spinner_base.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/messaging/subagent_console.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/model_factory.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/model_switching.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/model_utils.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/models_dev_api.json +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/models_dev_parser.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/config.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/discovery.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/downloader.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/installer.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/metadata.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/prompt_builder.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/register_callbacks.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/remote_catalog.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/skill_catalog.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/skills_install_menu.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/agent_skills/skills_menu.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/accounts.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/antigravity_model.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/config.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/constants.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/oauth.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/register_callbacks.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/storage.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/test_plugin.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/token.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/transport.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/antigravity_oauth/utils.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/chatgpt_oauth/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/chatgpt_oauth/config.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/chatgpt_oauth/register_callbacks.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_hooks/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_hooks/config.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_hooks/register_callbacks.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_oauth/README.md +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_oauth/SETUP.md +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_oauth/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_oauth/config.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_oauth/register_callbacks.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_oauth/test_plugin.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/claude_code_oauth/token_refresh_heartbeat.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/customizable_commands/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/customizable_commands/register_callbacks.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/example_custom_command/README.md +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/example_custom_command/register_callbacks.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/file_permission_handler/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/file_permission_handler/register_callbacks.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/frontend_emitter/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/frontend_emitter/emitter.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/frontend_emitter/register_callbacks.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/hook_creator/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/hook_creator/register_callbacks.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/hook_manager/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/hook_manager/config.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/hook_manager/hooks_menu.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/hook_manager/register_callbacks.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/oauth_puppy_html.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/shell_safety/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/shell_safety/agent_shell_safety.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/shell_safety/command_cache.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/shell_safety/register_callbacks.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/synthetic_status/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/synthetic_status/register_callbacks.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/synthetic_status/status_api.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/universal_constructor/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/universal_constructor/models.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/universal_constructor/register_callbacks.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/universal_constructor/registry.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/plugins/universal_constructor/sandbox.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/prompts/antigravity_system_prompt.md +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/pydantic_patches.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/reopenable_async_client.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/round_robin_model.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/session_storage.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/status_display.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/summarization_agent.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/terminal_utils.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/agent_tools.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/constants.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/demo_tui.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/handler.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/models.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/registration.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/renderers.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/terminal_ui.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/theme.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/ask_user_question/tui_loop.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/__init__.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/browser_control.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/browser_interactions.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/browser_locators.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/browser_manager.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/browser_navigation.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/browser_screenshot.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/browser_scripts.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/browser_workflows.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/chromium_terminal_manager.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/terminal_command_tools.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/terminal_screenshot_tools.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/browser/terminal_tools.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/command_runner.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/common.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/display.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/file_modifications.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/file_operations.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/skills_tools.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/subagent_context.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/tools_content.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/tools/universal_constructor.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/uvx_detection.py +0 -0
- {newcode-0.2.6 → newcode-0.2.8}/newcode/version_checker.py +0 -0
|
@@ -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
|
-
|
|
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.
|
|
12
|
+
"synthetic-MiniMax-M2.5": {
|
|
13
13
|
"type": "custom_openai",
|
|
14
|
-
"name": "hf:MiniMaxAI/MiniMax-M2.
|
|
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-
|
|
22
|
+
"synthetic-qwen3.5-397b": {
|
|
23
23
|
"type": "custom_openai",
|
|
24
|
-
"name": "hf:
|
|
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
|
|
321
|
+
from .utils import fetch_chatgpt_models
|
|
322
322
|
|
|
323
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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"]:
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|