newcode 0.2.9__tar.gz → 0.2.11__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.9 → newcode-0.2.11}/PKG-INFO +1 -5
- {newcode-0.2.9 → newcode-0.2.11}/README.md +0 -1
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/base_agent.py +41 -6
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/core_commands.py +0 -85
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/browser/terminal_tools.py +1 -1
- {newcode-0.2.9 → newcode-0.2.11}/pyproject.toml +1 -4
- newcode-0.2.9/newcode/api/__init__.py +0 -13
- newcode-0.2.9/newcode/api/app.py +0 -169
- newcode-0.2.9/newcode/api/main.py +0 -21
- newcode-0.2.9/newcode/api/pty_manager.py +0 -453
- newcode-0.2.9/newcode/api/routers/__init__.py +0 -12
- newcode-0.2.9/newcode/api/routers/agents.py +0 -36
- newcode-0.2.9/newcode/api/routers/commands.py +0 -217
- newcode-0.2.9/newcode/api/routers/config.py +0 -75
- newcode-0.2.9/newcode/api/routers/sessions.py +0 -234
- newcode-0.2.9/newcode/api/templates/terminal.html +0 -361
- newcode-0.2.9/newcode/api/websocket.py +0 -154
- {newcode-0.2.9 → newcode-0.2.11}/.gitignore +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/LICENSE +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/__main__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/agent_c_reviewer.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/agent_code_agent.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/agent_code_reviewer.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/agent_cpp_reviewer.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/agent_creator_agent.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/agent_golang_reviewer.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/agent_javascript_reviewer.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/agent_manager.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/agent_pack_leader.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/agent_planning.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/agent_python_programmer.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/agent_python_reviewer.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/agent_qa_browser.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/agent_qa_expert.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/agent_security_auditor.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/agent_terminal_qa.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/agent_typescript_reviewer.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/event_stream_handler.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/json_agent.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/pack/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/pack/bloodhound.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/pack/husky.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/pack/retriever.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/pack/shepherd.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/pack/terrier.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/pack/watchdog.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/prompt_reviewer.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/agents/subagent_stream_handler.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/callbacks.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/chatgpt_codex_client.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/claude_cache_client.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/cli_runner.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/add_model_menu.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/agent_menu.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/attachments.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/autosave_menu.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/clipboard.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/colors_menu.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/command_handler.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/command_registry.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/config_commands.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/diff_menu.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/file_path_completion.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/load_context_completion.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/base.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/catalog_server_installer.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/custom_server_form.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/custom_server_installer.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/edit_command.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/handler.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/help_command.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/install_command.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/install_menu.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/list_command.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/logs_command.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/remove_command.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/restart_command.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/search_command.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/start_all_command.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/start_command.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/status_command.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/stop_all_command.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/stop_command.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/test_command.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/utils.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp/wizard_utils.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/mcp_completion.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/model_picker_completion.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/model_settings_menu.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/motd.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/onboarding_slides.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/onboarding_wizard.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/pin_command_completion.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/prompt_toolkit_completion.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/session_commands.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/skills_completion.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/uc_menu.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/utils.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/command_line/wiggum_state.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/config.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/error_logging.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/gemini_code_assist.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/gemini_model.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/hook_engine/README.md +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/hook_engine/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/hook_engine/aliases.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/hook_engine/engine.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/hook_engine/executor.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/hook_engine/matcher.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/hook_engine/models.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/hook_engine/registry.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/hook_engine/validator.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/http_utils.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/image_utils.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/keymap.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/main.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/async_lifecycle.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/blocking_startup.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/captured_stdio_server.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/circuit_breaker.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/config_wizard.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/dashboard.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/error_isolation.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/examples/retry_example.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/health_monitor.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/managed_server.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/manager.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/mcp_logs.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/registry.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/retry_manager.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/server_registry_catalog.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/status_tracker.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_/system_tools.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_prompts/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/mcp_prompts/hook_creator.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/messaging/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/messaging/bus.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/messaging/commands.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/messaging/markdown_patches.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/messaging/message_queue.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/messaging/messages.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/messaging/queue_console.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/messaging/renderers.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/messaging/rich_renderer.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/messaging/spinner/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/messaging/spinner/console_spinner.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/messaging/spinner/spinner_base.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/messaging/subagent_console.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/model_factory.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/model_switching.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/model_utils.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/models.json +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/models_dev_api.json +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/models_dev_parser.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/agent_skills/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/agent_skills/config.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/agent_skills/discovery.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/agent_skills/downloader.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/agent_skills/installer.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/agent_skills/metadata.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/agent_skills/prompt_builder.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/agent_skills/register_callbacks.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/agent_skills/remote_catalog.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/agent_skills/skill_catalog.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/agent_skills/skills_install_menu.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/agent_skills/skills_menu.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/antigravity_oauth/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/antigravity_oauth/accounts.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/antigravity_oauth/antigravity_model.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/antigravity_oauth/config.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/antigravity_oauth/constants.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/antigravity_oauth/oauth.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/antigravity_oauth/register_callbacks.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/antigravity_oauth/storage.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/antigravity_oauth/test_plugin.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/antigravity_oauth/token.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/antigravity_oauth/transport.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/antigravity_oauth/utils.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/chatgpt_oauth/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/chatgpt_oauth/config.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/chatgpt_oauth/oauth_flow.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/chatgpt_oauth/register_callbacks.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/chatgpt_oauth/test_plugin.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/chatgpt_oauth/utils.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/claude_code_hooks/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/claude_code_hooks/config.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/claude_code_hooks/register_callbacks.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/claude_code_oauth/README.md +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/claude_code_oauth/SETUP.md +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/claude_code_oauth/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/claude_code_oauth/config.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/claude_code_oauth/register_callbacks.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/claude_code_oauth/test_plugin.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/claude_code_oauth/token_refresh_heartbeat.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/claude_code_oauth/utils.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/customizable_commands/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/customizable_commands/register_callbacks.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/example_custom_command/README.md +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/example_custom_command/register_callbacks.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/file_permission_handler/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/file_permission_handler/register_callbacks.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/frontend_emitter/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/frontend_emitter/emitter.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/frontend_emitter/register_callbacks.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/hook_creator/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/hook_creator/register_callbacks.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/hook_manager/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/hook_manager/config.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/hook_manager/hooks_menu.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/hook_manager/register_callbacks.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/oauth_puppy_html.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/shell_safety/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/shell_safety/agent_shell_safety.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/shell_safety/command_cache.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/shell_safety/register_callbacks.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/synthetic_status/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/synthetic_status/register_callbacks.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/synthetic_status/status_api.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/universal_constructor/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/universal_constructor/models.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/universal_constructor/register_callbacks.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/universal_constructor/registry.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/plugins/universal_constructor/sandbox.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/prompts/antigravity_system_prompt.md +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/pydantic_patches.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/reopenable_async_client.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/round_robin_model.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/session_storage.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/status_display.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/summarization_agent.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/terminal_utils.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/agent_tools.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/ask_user_question/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/ask_user_question/constants.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/ask_user_question/demo_tui.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/ask_user_question/handler.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/ask_user_question/models.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/ask_user_question/registration.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/ask_user_question/renderers.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/ask_user_question/terminal_ui.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/ask_user_question/theme.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/ask_user_question/tui_loop.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/browser/__init__.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/browser/browser_control.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/browser/browser_interactions.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/browser/browser_locators.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/browser/browser_manager.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/browser/browser_navigation.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/browser/browser_screenshot.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/browser/browser_scripts.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/browser/browser_workflows.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/browser/chromium_terminal_manager.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/browser/terminal_command_tools.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/browser/terminal_screenshot_tools.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/command_runner.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/common.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/display.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/file_modifications.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/file_operations.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/skills_tools.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/subagent_context.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/tools_content.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/tools/universal_constructor.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/uvx_detection.py +0 -0
- {newcode-0.2.9 → newcode-0.2.11}/newcode/version_checker.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: newcode
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.11
|
|
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
|
|
@@ -17,7 +17,6 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
17
17
|
Classifier: Topic :: Software Development :: Code Generators
|
|
18
18
|
Requires-Python: <3.14,>=3.11
|
|
19
19
|
Requires-Dist: anthropic==0.79.0
|
|
20
|
-
Requires-Dist: fastapi>=0.109.0
|
|
21
20
|
Requires-Dist: httpx[http2]>=0.24.1
|
|
22
21
|
Requires-Dist: json-repair>=0.46.2
|
|
23
22
|
Requires-Dist: mcp>=1.9.4
|
|
@@ -35,8 +34,6 @@ Requires-Dist: ripgrep==14.1.0
|
|
|
35
34
|
Requires-Dist: tenacity>=8.2.0
|
|
36
35
|
Requires-Dist: termflow-md>=0.1.8
|
|
37
36
|
Requires-Dist: typer>=0.12.0
|
|
38
|
-
Requires-Dist: uvicorn[standard]>=0.27.0
|
|
39
|
-
Requires-Dist: websockets>=12.0
|
|
40
37
|
Description-Content-Type: text/markdown
|
|
41
38
|
|
|
42
39
|
# NewCode
|
|
@@ -94,7 +91,6 @@ On first run, NewCode starts onboarding to help configure API keys and defaults.
|
|
|
94
91
|
/model # Select or switch model
|
|
95
92
|
/agent # Select or switch agent
|
|
96
93
|
/colors # Customize terminal UI colors
|
|
97
|
-
/api # Manage built-in API server (start|stop|status)
|
|
98
94
|
```
|
|
99
95
|
|
|
100
96
|
## Requirements
|
|
@@ -53,7 +53,6 @@ On first run, NewCode starts onboarding to help configure API keys and defaults.
|
|
|
53
53
|
/model # Select or switch model
|
|
54
54
|
/agent # Select or switch agent
|
|
55
55
|
/colors # Customize terminal UI colors
|
|
56
|
-
/api # Manage built-in API server (start|stop|status)
|
|
57
56
|
```
|
|
58
57
|
|
|
59
58
|
## Requirements
|
|
@@ -1441,6 +1441,28 @@ class BaseAgent(ABC):
|
|
|
1441
1441
|
self._mcp_servers = filtered_mcp_servers
|
|
1442
1442
|
return self._code_generation_agent
|
|
1443
1443
|
|
|
1444
|
+
def _reload_live_agent_after_token_refresh(
|
|
1445
|
+
self,
|
|
1446
|
+
*,
|
|
1447
|
+
output_type: Optional[Type[Any]] = None,
|
|
1448
|
+
message_group: Optional[str] = None,
|
|
1449
|
+
) -> Optional[PydanticAgent]:
|
|
1450
|
+
"""Rebuild the live agent so refreshed OAuth tokens take effect immediately."""
|
|
1451
|
+
try:
|
|
1452
|
+
self.reload_code_generation_agent(message_group=message_group)
|
|
1453
|
+
if output_type is not None:
|
|
1454
|
+
return self._create_agent_with_output_type(output_type)
|
|
1455
|
+
return self._code_generation_agent
|
|
1456
|
+
except Exception as exc:
|
|
1457
|
+
emit_warning(
|
|
1458
|
+
(
|
|
1459
|
+
"Token refresh succeeded, but rebuilding the live model client "
|
|
1460
|
+
f"failed: {exc}"
|
|
1461
|
+
),
|
|
1462
|
+
group_id=message_group,
|
|
1463
|
+
)
|
|
1464
|
+
return None
|
|
1465
|
+
|
|
1444
1466
|
def _create_agent_with_output_type(self, output_type: Type[Any]) -> PydanticAgent:
|
|
1445
1467
|
"""Create a temporary agent configured with a custom output_type.
|
|
1446
1468
|
|
|
@@ -1763,10 +1785,11 @@ class BaseAgent(ABC):
|
|
|
1763
1785
|
pydantic_agent = (
|
|
1764
1786
|
self._code_generation_agent or self.reload_code_generation_agent()
|
|
1765
1787
|
)
|
|
1788
|
+
current_output_type = output_type
|
|
1766
1789
|
|
|
1767
1790
|
# If a custom output_type is specified, create a temporary agent with that type
|
|
1768
|
-
if
|
|
1769
|
-
pydantic_agent = self._create_agent_with_output_type(
|
|
1791
|
+
if current_output_type is not None:
|
|
1792
|
+
pydantic_agent = self._create_agent_with_output_type(current_output_type)
|
|
1770
1793
|
|
|
1771
1794
|
# Handle model-specific prompt transformations via prepare_prompt_for_model()
|
|
1772
1795
|
# This uses the get_model_system_prompt hook, so plugins can register their own handlers
|
|
@@ -1822,6 +1845,7 @@ class BaseAgent(ABC):
|
|
|
1822
1845
|
prompt_payload = prompt
|
|
1823
1846
|
|
|
1824
1847
|
async def run_agent_task():
|
|
1848
|
+
nonlocal pydantic_agent
|
|
1825
1849
|
_cloudflare_retry_attempted = False
|
|
1826
1850
|
|
|
1827
1851
|
while True:
|
|
@@ -1906,11 +1930,22 @@ class BaseAgent(ABC):
|
|
|
1906
1930
|
)
|
|
1907
1931
|
|
|
1908
1932
|
if refreshed_token:
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1933
|
+
rebuilt_agent = self._reload_live_agent_after_token_refresh(
|
|
1934
|
+
output_type=current_output_type,
|
|
1935
|
+
message_group=group_id,
|
|
1912
1936
|
)
|
|
1913
|
-
|
|
1937
|
+
if rebuilt_agent is not None:
|
|
1938
|
+
pydantic_agent = rebuilt_agent
|
|
1939
|
+
emit_info(
|
|
1940
|
+
"Token refresh successful, rebuilt Claude Code client, retrying request...",
|
|
1941
|
+
group_id=group_id,
|
|
1942
|
+
)
|
|
1943
|
+
_retry_after_cloudflare_refresh = True
|
|
1944
|
+
else:
|
|
1945
|
+
emit_info(
|
|
1946
|
+
"Token refresh succeeded, but retry aborted because the live Claude Code client could not be rebuilt.",
|
|
1947
|
+
group_id=group_id,
|
|
1948
|
+
)
|
|
1914
1949
|
|
|
1915
1950
|
if not _retry_after_cloudflare_refresh:
|
|
1916
1951
|
# Filter out CancelledError and UsageLimitExceeded from the exception group - let it propagate
|
|
@@ -678,91 +678,6 @@ def handle_mcp_command(command: str) -> bool:
|
|
|
678
678
|
return handler.handle_mcp_command(command)
|
|
679
679
|
|
|
680
680
|
|
|
681
|
-
@register_command(
|
|
682
|
-
name="api",
|
|
683
|
-
description="Manage the API server",
|
|
684
|
-
usage="/api [start|stop|status]",
|
|
685
|
-
category="core",
|
|
686
|
-
detailed_help="Start, stop, or check status of the local FastAPI server for GUI integration.",
|
|
687
|
-
)
|
|
688
|
-
def handle_api_command(command: str) -> bool:
|
|
689
|
-
"""Handle the /api command."""
|
|
690
|
-
import os
|
|
691
|
-
import signal
|
|
692
|
-
import subprocess
|
|
693
|
-
import sys
|
|
694
|
-
from pathlib import Path
|
|
695
|
-
|
|
696
|
-
from newcode.config import STATE_DIR
|
|
697
|
-
from newcode.messaging import emit_error, emit_info, emit_success
|
|
698
|
-
|
|
699
|
-
parts = command.split()
|
|
700
|
-
subcommand = parts[1] if len(parts) > 1 else "status"
|
|
701
|
-
|
|
702
|
-
pid_file = Path(STATE_DIR) / "api_server.pid"
|
|
703
|
-
|
|
704
|
-
if subcommand == "start":
|
|
705
|
-
# Check if already running
|
|
706
|
-
if pid_file.exists():
|
|
707
|
-
try:
|
|
708
|
-
pid = int(pid_file.read_text().strip())
|
|
709
|
-
os.kill(pid, 0) # Check if process exists
|
|
710
|
-
emit_info(f"API server already running (PID {pid})")
|
|
711
|
-
return True
|
|
712
|
-
except (OSError, ValueError):
|
|
713
|
-
pid_file.unlink(missing_ok=True) # Stale PID file
|
|
714
|
-
|
|
715
|
-
# Start the server in background
|
|
716
|
-
emit_info("Starting API server on http://127.0.0.1:8765 ...")
|
|
717
|
-
proc = subprocess.Popen(
|
|
718
|
-
[sys.executable, "-m", "newcode.api.main"],
|
|
719
|
-
stdout=subprocess.DEVNULL,
|
|
720
|
-
stderr=subprocess.DEVNULL,
|
|
721
|
-
start_new_session=True,
|
|
722
|
-
)
|
|
723
|
-
pid_file.parent.mkdir(parents=True, exist_ok=True)
|
|
724
|
-
pid_file.write_text(str(proc.pid))
|
|
725
|
-
emit_success(f"API server started (PID {proc.pid})")
|
|
726
|
-
emit_info("Docs available at http://127.0.0.1:8765/docs")
|
|
727
|
-
return True
|
|
728
|
-
|
|
729
|
-
elif subcommand == "stop":
|
|
730
|
-
if not pid_file.exists():
|
|
731
|
-
emit_info("API server is not running")
|
|
732
|
-
return True
|
|
733
|
-
|
|
734
|
-
try:
|
|
735
|
-
pid = int(pid_file.read_text().strip())
|
|
736
|
-
os.kill(pid, signal.SIGTERM)
|
|
737
|
-
pid_file.unlink()
|
|
738
|
-
emit_success(f"API server stopped (PID {pid})")
|
|
739
|
-
except (OSError, ValueError) as e:
|
|
740
|
-
pid_file.unlink(missing_ok=True)
|
|
741
|
-
emit_error(f"Error stopping server: {e}")
|
|
742
|
-
return True
|
|
743
|
-
|
|
744
|
-
elif subcommand == "status":
|
|
745
|
-
if not pid_file.exists():
|
|
746
|
-
emit_info("API server is not running")
|
|
747
|
-
return True
|
|
748
|
-
|
|
749
|
-
try:
|
|
750
|
-
pid = int(pid_file.read_text().strip())
|
|
751
|
-
os.kill(pid, 0) # Check if process exists
|
|
752
|
-
emit_success(f"API server is running (PID {pid})")
|
|
753
|
-
emit_info("URL: http://127.0.0.1:8765")
|
|
754
|
-
emit_info("Docs: http://127.0.0.1:8765/docs")
|
|
755
|
-
except (OSError, ValueError):
|
|
756
|
-
pid_file.unlink(missing_ok=True)
|
|
757
|
-
emit_info("API server is not running (stale PID file removed)")
|
|
758
|
-
return True
|
|
759
|
-
|
|
760
|
-
else:
|
|
761
|
-
emit_error(f"Unknown subcommand: {subcommand}")
|
|
762
|
-
emit_info("Usage: /api [start|stop|status]")
|
|
763
|
-
return True
|
|
764
|
-
|
|
765
|
-
|
|
766
681
|
@register_command(
|
|
767
682
|
name="generate-pr-description",
|
|
768
683
|
description="Generate comprehensive PR description",
|
|
@@ -317,7 +317,7 @@ async def start_api_server(port: int = 8765) -> Dict[str, Any]:
|
|
|
317
317
|
|
|
318
318
|
This starts the API server that provides the terminal endpoint for
|
|
319
319
|
browser-based terminal testing. The server runs in the background
|
|
320
|
-
and persists until
|
|
320
|
+
and persists until the process is killed.
|
|
321
321
|
|
|
322
322
|
Args:
|
|
323
323
|
port: The port to run the server on (default: 8765).
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "newcode"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.11"
|
|
8
8
|
description = "AI-powered code generation agent platform"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11,<3.14"
|
|
@@ -24,9 +24,6 @@ dependencies = [
|
|
|
24
24
|
"ripgrep==14.1.0",
|
|
25
25
|
"tenacity>=8.2.0",
|
|
26
26
|
"playwright>=1.40.0",
|
|
27
|
-
"fastapi>=0.109.0",
|
|
28
|
-
"uvicorn[standard]>=0.27.0",
|
|
29
|
-
"websockets>=12.0",
|
|
30
27
|
"termflow-md>=0.1.8",
|
|
31
28
|
"Pillow>=10.0.0",
|
|
32
29
|
"anthropic==0.79.0"
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"""REST API module.
|
|
2
|
-
|
|
3
|
-
This module provides a FastAPI-based REST API for the application configuration,
|
|
4
|
-
sessions, commands, and real-time WebSocket communication.
|
|
5
|
-
|
|
6
|
-
Exports:
|
|
7
|
-
create_app: Factory function to create the FastAPI application
|
|
8
|
-
main: Entry point to run the server
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
from newcode.api.app import create_app
|
|
12
|
-
|
|
13
|
-
__all__ = ["create_app"]
|
newcode-0.2.9/newcode/api/app.py
DELETED
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
"""FastAPI application factory."""
|
|
2
|
-
|
|
3
|
-
import asyncio
|
|
4
|
-
import logging
|
|
5
|
-
from contextlib import asynccontextmanager
|
|
6
|
-
from pathlib import Path
|
|
7
|
-
from typing import AsyncGenerator
|
|
8
|
-
|
|
9
|
-
from fastapi import FastAPI, Request
|
|
10
|
-
from fastapi.middleware.cors import CORSMiddleware
|
|
11
|
-
from fastapi.responses import FileResponse, HTMLResponse, JSONResponse
|
|
12
|
-
from starlette.middleware.base import BaseHTTPMiddleware
|
|
13
|
-
|
|
14
|
-
logger = logging.getLogger(__name__)
|
|
15
|
-
|
|
16
|
-
# Default request timeout (seconds) - fail fast!
|
|
17
|
-
REQUEST_TIMEOUT = 30.0
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class TimeoutMiddleware(BaseHTTPMiddleware):
|
|
21
|
-
"""Middleware to enforce request timeouts and prevent hanging requests."""
|
|
22
|
-
|
|
23
|
-
def __init__(self, app, timeout: float = REQUEST_TIMEOUT):
|
|
24
|
-
super().__init__(app)
|
|
25
|
-
self.timeout = timeout
|
|
26
|
-
|
|
27
|
-
async def dispatch(self, request: Request, call_next):
|
|
28
|
-
# Skip timeout for WebSocket upgrades and streaming endpoints
|
|
29
|
-
if request.headers.get(
|
|
30
|
-
"upgrade", ""
|
|
31
|
-
).lower() == "websocket" or request.url.path.startswith("/ws/"):
|
|
32
|
-
return await call_next(request)
|
|
33
|
-
|
|
34
|
-
try:
|
|
35
|
-
return await asyncio.wait_for(
|
|
36
|
-
call_next(request),
|
|
37
|
-
timeout=self.timeout,
|
|
38
|
-
)
|
|
39
|
-
except asyncio.TimeoutError:
|
|
40
|
-
return JSONResponse(
|
|
41
|
-
status_code=504,
|
|
42
|
-
content={
|
|
43
|
-
"detail": f"Request timed out after {self.timeout}s",
|
|
44
|
-
"error": "timeout",
|
|
45
|
-
},
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
@asynccontextmanager
|
|
50
|
-
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
|
|
51
|
-
"""Lifespan context manager for startup and shutdown events.
|
|
52
|
-
|
|
53
|
-
Handles graceful cleanup of resources when the server shuts down.
|
|
54
|
-
"""
|
|
55
|
-
# Startup: nothing special needed yet, but this is where you'd do it
|
|
56
|
-
logger.info("API starting up...")
|
|
57
|
-
yield
|
|
58
|
-
# Shutdown: clean up all the things!
|
|
59
|
-
logger.info("API shutting down, cleaning up...")
|
|
60
|
-
|
|
61
|
-
# 1. Close all PTY sessions
|
|
62
|
-
try:
|
|
63
|
-
from newcode.api.pty_manager import get_pty_manager
|
|
64
|
-
|
|
65
|
-
pty_manager = get_pty_manager()
|
|
66
|
-
await pty_manager.close_all()
|
|
67
|
-
logger.info("✓ All PTY sessions closed")
|
|
68
|
-
except Exception as e:
|
|
69
|
-
logger.error(f"Error closing PTY sessions: {e}")
|
|
70
|
-
|
|
71
|
-
# 2. Remove PID file so /api status knows we're gone
|
|
72
|
-
try:
|
|
73
|
-
from newcode.config import STATE_DIR
|
|
74
|
-
|
|
75
|
-
pid_file = Path(STATE_DIR) / "api_server.pid"
|
|
76
|
-
if pid_file.exists():
|
|
77
|
-
pid_file.unlink()
|
|
78
|
-
logger.info("✓ PID file removed")
|
|
79
|
-
except Exception as e:
|
|
80
|
-
logger.error(f"Error removing PID file: {e}")
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
def create_app() -> FastAPI:
|
|
84
|
-
"""Create and configure the FastAPI application."""
|
|
85
|
-
app = FastAPI(
|
|
86
|
-
lifespan=lifespan,
|
|
87
|
-
title="Code Agent API",
|
|
88
|
-
description="REST API and Interactive Terminal",
|
|
89
|
-
version="1.0.0",
|
|
90
|
-
docs_url="/docs",
|
|
91
|
-
redoc_url="/redoc",
|
|
92
|
-
)
|
|
93
|
-
|
|
94
|
-
# Timeout middleware - added first so it wraps everything
|
|
95
|
-
app.add_middleware(TimeoutMiddleware, timeout=REQUEST_TIMEOUT)
|
|
96
|
-
|
|
97
|
-
# CORS middleware for frontend access
|
|
98
|
-
app.add_middleware(
|
|
99
|
-
CORSMiddleware,
|
|
100
|
-
allow_origins=["*"], # Local/trusted
|
|
101
|
-
allow_credentials=True,
|
|
102
|
-
allow_methods=["*"],
|
|
103
|
-
allow_headers=["*"],
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
# Include routers
|
|
107
|
-
from newcode.api.routers import agents, commands, config, sessions
|
|
108
|
-
|
|
109
|
-
app.include_router(config.router, prefix="/api/config", tags=["config"])
|
|
110
|
-
app.include_router(commands.router, prefix="/api/commands", tags=["commands"])
|
|
111
|
-
app.include_router(sessions.router, prefix="/api/sessions", tags=["sessions"])
|
|
112
|
-
app.include_router(agents.router, prefix="/api/agents", tags=["agents"])
|
|
113
|
-
|
|
114
|
-
# WebSocket endpoints (events + terminal)
|
|
115
|
-
from newcode.api.websocket import setup_websocket
|
|
116
|
-
|
|
117
|
-
setup_websocket(app)
|
|
118
|
-
|
|
119
|
-
# Templates directory
|
|
120
|
-
templates_dir = Path(__file__).parent / "templates"
|
|
121
|
-
|
|
122
|
-
@app.get("/")
|
|
123
|
-
async def root():
|
|
124
|
-
"""Landing page with links to terminal and docs."""
|
|
125
|
-
return HTMLResponse(
|
|
126
|
-
content="""
|
|
127
|
-
<!DOCTYPE html>
|
|
128
|
-
<html>
|
|
129
|
-
<head>
|
|
130
|
-
<title>Code Agent</title>
|
|
131
|
-
<script src="https://cdn.tailwindcss.com"></script>
|
|
132
|
-
</head>
|
|
133
|
-
<body class="bg-gray-900 text-white min-h-screen flex items-center justify-center">
|
|
134
|
-
<div class="text-center">
|
|
135
|
-
<h1 class="text-6xl mb-4">⚙</h1>
|
|
136
|
-
<h2 class="text-3xl font-bold mb-8">Code Agent</h2>
|
|
137
|
-
<div class="space-x-4">
|
|
138
|
-
<a href="/terminal" class="px-6 py-3 bg-blue-600 hover:bg-blue-700 rounded-lg text-lg font-semibold">
|
|
139
|
-
Open Terminal
|
|
140
|
-
</a>
|
|
141
|
-
<a href="/docs" class="px-6 py-3 bg-gray-700 hover:bg-gray-600 rounded-lg text-lg">
|
|
142
|
-
API Docs
|
|
143
|
-
</a>
|
|
144
|
-
</div>
|
|
145
|
-
<p class="mt-8 text-gray-400">
|
|
146
|
-
WebSocket: ws://localhost:8765/ws/terminal
|
|
147
|
-
</p>
|
|
148
|
-
</div>
|
|
149
|
-
</body>
|
|
150
|
-
</html>
|
|
151
|
-
"""
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
@app.get("/terminal")
|
|
155
|
-
async def terminal_page():
|
|
156
|
-
"""Serve the interactive terminal page."""
|
|
157
|
-
html_file = templates_dir / "terminal.html"
|
|
158
|
-
if html_file.exists():
|
|
159
|
-
return FileResponse(html_file, media_type="text/html")
|
|
160
|
-
return HTMLResponse(
|
|
161
|
-
content="<h1>Terminal template not found</h1>",
|
|
162
|
-
status_code=404,
|
|
163
|
-
)
|
|
164
|
-
|
|
165
|
-
@app.get("/health")
|
|
166
|
-
async def health():
|
|
167
|
-
return {"status": "healthy"}
|
|
168
|
-
|
|
169
|
-
return app
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"""Entry point for running the FastAPI server."""
|
|
2
|
-
|
|
3
|
-
import uvicorn
|
|
4
|
-
|
|
5
|
-
from newcode.api.app import create_app
|
|
6
|
-
|
|
7
|
-
app = create_app()
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def main(host: str = "127.0.0.1", port: int = 8765) -> None:
|
|
11
|
-
"""Run the FastAPI server.
|
|
12
|
-
|
|
13
|
-
Args:
|
|
14
|
-
host: The host address to bind to. Defaults to localhost.
|
|
15
|
-
port: The port number to listen on. Defaults to 8765.
|
|
16
|
-
"""
|
|
17
|
-
uvicorn.run(app, host=host, port=port)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if __name__ == "__main__":
|
|
21
|
-
main()
|