code-context-control 2.39.0__tar.gz → 2.39.1__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.
- {code_context_control-2.39.0/code_context_control.egg-info → code_context_control-2.39.1}/PKG-INFO +1 -1
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/delegate.py +80 -2
- {code_context_control-2.39.0 → code_context_control-2.39.1/code_context_control.egg-info}/PKG-INFO +1 -1
- {code_context_control-2.39.0 → code_context_control-2.39.1}/code_context_control.egg-info/SOURCES.txt +2 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/pyproject.toml +1 -1
- code_context_control-2.39.1/services/circuit_breaker.py +86 -0
- code_context_control-2.39.1/tests/test_circuit_breaker.py +103 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/LICENSE +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/README.md +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/__init__.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/_hook_utils.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/c3.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/commands/__init__.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/commands/common.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/commands/parser.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/docs.html +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/edits.html +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/guide/bitbucket.html +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/guide/getting-started.html +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/guide/index.html +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/guide/oracle.html +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/guide/shared.css +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/guide/tools.html +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/guide/workflow.html +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/hook_auto_snapshot.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/hook_c3_signal.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/hook_c3read.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/hook_edit_ledger.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/hook_edit_unlock.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/hook_filter.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/hook_ghost_files.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/hook_pretool_enforce.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/hook_read.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/hook_session_stats.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/hook_terse_advisor.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/hub.html +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/hub_server.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/mcp_proxy.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/mcp_server.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/server.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/__init__.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/_helpers.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/agent.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/bitbucket.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/compress.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/edit.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/edits.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/filter.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/impact.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/memory.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/project.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/read.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/search.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/session.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/shell.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/status.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/tools/validate.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui/api.js +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui/app.js +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui/components/bitbucket.js +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui/components/chat.js +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui/components/dashboard.js +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui/components/edits.js +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui/components/instructions.js +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui/components/memory.js +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui/components/sessions.js +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui/components/settings.js +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui/components/sidebar.js +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui/icons.js +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui/shared.js +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui/theme.js +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui.html +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui_legacy.html +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui_nano.html +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/code_context_control.egg-info/dependency_links.txt +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/code_context_control.egg-info/entry_points.txt +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/code_context_control.egg-info/requires.txt +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/code_context_control.egg-info/top_level.txt +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/core/__init__.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/core/config.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/core/ide.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/core/mcp_toml.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/core/web_security.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/__init__.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/config.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/mcp_oracle.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/oracle.html +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/oracle_server.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/__init__.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/activity_reporter.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/api_auth.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/c3_bridge.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/chat_engine.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/chat_store.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/cross_memory.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/federated_graph.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/health_checker.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/insight_engine.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/memory_reader.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/memory_writer.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/ollama_bridge.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/project_scanner.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/review_agent.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/tool_executor.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/tool_registry.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/__init__.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/activity_log.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/agent_base.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/agents.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/auto_memory.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/bench/__init__.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/bench/external/__init__.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/bench/external/aider_polyglot.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/bench/external/swe_bench.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/benchmark_dashboard.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/bitbucket_client.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/bitbucket_credentials.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/claude_md.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/compressor.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/context_snapshot.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/conversation_store.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/doc_index.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/e2e_benchmark.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/e2e_evaluator.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/e2e_tasks.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/edit_ledger.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/embedding_index.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/error_reporting.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/file_memory.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/git_context.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/hub_service.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/indexer.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/memory.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/memory_consolidator.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/memory_graph.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/memory_grounder.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/memory_scorer.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/metrics.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/notifications.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/ollama_client.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/output_filter.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/parser.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/project_manager.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/project_runtime.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/protocol.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/proxy_state.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/retrieval_broker.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/router.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/runtime.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/session_benchmark.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/session_manager.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/session_preloader.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/text_index.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/tool_classifier.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/transcript_index.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/validation_cache.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/vector_store.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/version_tracker.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/services/watcher.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/setup.cfg +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_activity_reporter.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_aider_polyglot.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_bitbucket_cli_smoke.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_bitbucket_client.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_bitbucket_credentials.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_bitbucket_tool.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_c3_shell.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_claude_md_merge.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_cli_smoke.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_e2e_benchmark.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_edit_ledger_hook.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_edit_normalization.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_enforcement_flip.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_federated_graph.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_ghost_files.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_git_branch_awareness.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_hub_server_smoke.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_install_mcp_entrypoint.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_lazy_store_init.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_mcp_host_guard.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_mcp_server_smoke.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_mcp_toml.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_memory_graph_api.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_memory_system.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_notification_discipline.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_oracle_api_auth.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_oracle_apikey_api.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_oracle_discovery_api.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_oracle_security_fixes.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_output_filter.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_permissions.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_project_manager.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_project_manager_merge.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_project_tool.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_read_coercion.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_service_durability.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_session_benchmark.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_session_budget.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_shell_robustness.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_swe_bench.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_tool_registry.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_upgrade_and_version.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_validate.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_web_security.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tests/test_windows_reliability.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/__init__.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/backend.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/main.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/screens/__init__.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/screens/benchmark_view.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/screens/claudemd_view.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/screens/compress_view.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/screens/index_view.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/screens/init_view.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/screens/mcp_view.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/screens/optimize_view.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/screens/pipe_view.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/screens/projects_view.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/screens/search_view.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/screens/session_view.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/screens/stats.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/screens/ui_view.py +0 -0
- {code_context_control-2.39.0 → code_context_control-2.39.1}/tui/theme.tcss +0 -0
{code_context_control-2.39.0/code_context_control.egg-info → code_context_control-2.39.1}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-context-control
|
|
3
|
-
Version: 2.39.
|
|
3
|
+
Version: 2.39.1
|
|
4
4
|
Summary: Local code-intelligence layer for AI coding tools (Claude Code, Codex, Gemini, Copilot). Retrieve less, read less, edit safer.
|
|
5
5
|
Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -11,10 +11,12 @@ import os
|
|
|
11
11
|
import shutil
|
|
12
12
|
import subprocess
|
|
13
13
|
import sys
|
|
14
|
+
import threading
|
|
14
15
|
import time
|
|
15
16
|
from pathlib import Path
|
|
16
17
|
|
|
17
18
|
from core import count_tokens
|
|
19
|
+
from services.circuit_breaker import CircuitBreaker
|
|
18
20
|
|
|
19
21
|
log = logging.getLogger(__name__)
|
|
20
22
|
|
|
@@ -252,11 +254,20 @@ def _handle_claude_delegate(task: str, task_type: str, context: str,
|
|
|
252
254
|
file_path: str, svc, dcfg: dict, finalize) -> str:
|
|
253
255
|
"""Handle delegation via Claude Code CLI."""
|
|
254
256
|
timeout = int(dcfg.get("claude_timeout", 90))
|
|
257
|
+
breaker = _backend_breaker("claude", dcfg)
|
|
258
|
+
if not breaker.allow():
|
|
259
|
+
return finalize("c3_delegate", {"task_type": task_type, "backend": "claude"},
|
|
260
|
+
"[delegate:degraded] Claude skipped after repeated failures; retrying in "
|
|
261
|
+
f"~{breaker.cooldown_remaining()}s. Run 'claude --version' to diagnose.",
|
|
262
|
+
"degraded")
|
|
255
263
|
_log_progress(svc, f"[delegate] Routing {task_type} → Claude CLI...")
|
|
256
264
|
output, ok = _run_claude(task, context, cwd=str(svc.project_path), timeout=timeout)
|
|
257
265
|
if not ok:
|
|
266
|
+
if breaker.record_failure():
|
|
267
|
+
_notify_backend_degraded(svc, "claude", breaker)
|
|
258
268
|
return finalize("c3_delegate", {"task_type": task_type, "backend": "claude"},
|
|
259
269
|
output, "error")
|
|
270
|
+
breaker.record_success()
|
|
260
271
|
return finalize("c3_delegate", {"task_type": task_type, "backend": "claude"},
|
|
261
272
|
output, "ok")
|
|
262
273
|
|
|
@@ -681,6 +692,51 @@ DELEGATE_TASKS = {
|
|
|
681
692
|
_delegate_cache: dict[str, tuple[str, int]] = {}
|
|
682
693
|
_delegate_metrics = {"total_calls": 0, "tokens_saved": 0}
|
|
683
694
|
|
|
695
|
+
# Per-backend runtime circuit breakers. Distinct from the install-status flags
|
|
696
|
+
# (_gemini_available etc., which only answer "is the CLI on PATH"): these track
|
|
697
|
+
# *runtime* health so a broken-but-installed backend (expired auth, repeated
|
|
698
|
+
# timeouts) stops re-spawning a 90-120s subprocess on every call. Keyed by
|
|
699
|
+
# backend name and intentionally process-global — backend health (auth, CLI
|
|
700
|
+
# version) is a property of the host, not of any single project.
|
|
701
|
+
_backend_breakers: dict[str, CircuitBreaker] = {}
|
|
702
|
+
_backend_breakers_lock = threading.Lock()
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
def _backend_breaker(name: str, dcfg: dict | None = None) -> CircuitBreaker:
|
|
706
|
+
"""Return (creating on first use) the runtime circuit breaker for a backend."""
|
|
707
|
+
with _backend_breakers_lock:
|
|
708
|
+
breaker = _backend_breakers.get(name)
|
|
709
|
+
if breaker is None:
|
|
710
|
+
cfg = dcfg or {}
|
|
711
|
+
breaker = CircuitBreaker(
|
|
712
|
+
name,
|
|
713
|
+
failure_threshold=int(cfg.get("breaker_failure_threshold", 3) or 3),
|
|
714
|
+
cooldown_seconds=float(cfg.get("breaker_cooldown_seconds", 60) or 60),
|
|
715
|
+
)
|
|
716
|
+
_backend_breakers[name] = breaker
|
|
717
|
+
return breaker
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
def _notify_backend_degraded(svc, name: str, breaker: CircuitBreaker) -> None:
|
|
721
|
+
"""Surface a backend trip via the NotificationStore (best-effort, never raises)."""
|
|
722
|
+
notifications = getattr(svc, "notifications", None)
|
|
723
|
+
if notifications is None:
|
|
724
|
+
return
|
|
725
|
+
try:
|
|
726
|
+
notifications.add(
|
|
727
|
+
agent="c3",
|
|
728
|
+
severity="warning",
|
|
729
|
+
title=f"Delegate backend degraded: {name}",
|
|
730
|
+
message=(
|
|
731
|
+
f"{name} failed {breaker.failure_threshold}x consecutively; c3_delegate "
|
|
732
|
+
f"will skip it for ~{int(breaker.cooldown_seconds)}s instead of re-spawning "
|
|
733
|
+
f"the CLI. Run '{name} --version' to diagnose."
|
|
734
|
+
),
|
|
735
|
+
replace_if_unacked=True,
|
|
736
|
+
)
|
|
737
|
+
except Exception:
|
|
738
|
+
pass
|
|
739
|
+
|
|
684
740
|
|
|
685
741
|
def get_delegate_metrics() -> dict:
|
|
686
742
|
return dict(_delegate_metrics)
|
|
@@ -765,6 +821,13 @@ def _handle_codex_delegate(task: str, task_type: str, context: str,
|
|
|
765
821
|
"[delegate:error] Codex CLI not available. Run 'codex --version' to diagnose.",
|
|
766
822
|
"unavailable")
|
|
767
823
|
|
|
824
|
+
breaker = _backend_breaker("codex", dcfg)
|
|
825
|
+
if not breaker.allow():
|
|
826
|
+
return finalize("c3_delegate", {"task_type": task_type, "backend": "codex"},
|
|
827
|
+
"[delegate:degraded] Codex skipped after repeated failures; retrying in "
|
|
828
|
+
f"~{breaker.cooldown_remaining()}s. Run 'codex --version' to diagnose.",
|
|
829
|
+
"degraded")
|
|
830
|
+
|
|
768
831
|
# Resolve model/sandbox/reasoning from config or defaults
|
|
769
832
|
cdef = CODEX_MODELS.get(task_type, CODEX_MODELS.get("ask", {}))
|
|
770
833
|
model = dcfg.get("codex_default_model") or cdef.get("model", "gpt-5.3-codex-spark")
|
|
@@ -807,10 +870,13 @@ def _handle_codex_delegate(task: str, task_type: str, context: str,
|
|
|
807
870
|
elapsed = round(time.monotonic() - t0, 1)
|
|
808
871
|
|
|
809
872
|
if not ok:
|
|
873
|
+
if breaker.record_failure():
|
|
874
|
+
_notify_backend_degraded(svc, "codex", breaker)
|
|
810
875
|
return finalize("c3_delegate",
|
|
811
876
|
{"task_type": task_type, "backend": "codex", "model": model, "elapsed": f"{elapsed}s"},
|
|
812
877
|
output, "error")
|
|
813
878
|
|
|
879
|
+
breaker.record_success()
|
|
814
880
|
_delegate_metrics["total_calls"] += 1
|
|
815
881
|
_delegate_cache[ckey] = (output, count_tokens(output))
|
|
816
882
|
|
|
@@ -880,6 +946,13 @@ def _handle_gemini_delegate(task: str, task_type: str, context: str,
|
|
|
880
946
|
"[delegate:error] Gemini CLI not available. Run 'gemini --version' to diagnose.",
|
|
881
947
|
"unavailable")
|
|
882
948
|
|
|
949
|
+
breaker = _backend_breaker("gemini", dcfg)
|
|
950
|
+
if not breaker.allow():
|
|
951
|
+
return finalize("c3_delegate", {"task_type": task_type, "backend": "gemini"},
|
|
952
|
+
"[delegate:degraded] Gemini skipped after repeated failures; retrying in "
|
|
953
|
+
f"~{breaker.cooldown_remaining()}s. Run 'gemini --version' to diagnose.",
|
|
954
|
+
"degraded")
|
|
955
|
+
|
|
883
956
|
# Resolve model from config or defaults
|
|
884
957
|
gdef = GEMINI_MODELS.get(task_type, GEMINI_MODELS.get("ask", {}))
|
|
885
958
|
model = dcfg.get("gemini_default_model") or gdef.get("model", "gemini-2.5-flash")
|
|
@@ -919,10 +992,13 @@ def _handle_gemini_delegate(task: str, task_type: str, context: str,
|
|
|
919
992
|
elapsed = round(time.monotonic() - t0, 1)
|
|
920
993
|
|
|
921
994
|
if not ok:
|
|
995
|
+
if breaker.record_failure():
|
|
996
|
+
_notify_backend_degraded(svc, "gemini", breaker)
|
|
922
997
|
return finalize("c3_delegate",
|
|
923
998
|
{"task_type": task_type, "backend": "gemini", "model": model, "elapsed": f"{elapsed}s"},
|
|
924
999
|
output, "error")
|
|
925
1000
|
|
|
1001
|
+
breaker.record_success()
|
|
926
1002
|
_delegate_metrics["total_calls"] += 1
|
|
927
1003
|
_delegate_cache[ckey] = (output, count_tokens(output))
|
|
928
1004
|
|
|
@@ -1068,9 +1144,11 @@ def handle_delegate(task: str, task_type: str, context: str, file_path: str,
|
|
|
1068
1144
|
_gemini_avail = (_gemini_available is True) or (
|
|
1069
1145
|
_gemini_available is None and task_type not in _light_tasks and _is_gemini_on_path()
|
|
1070
1146
|
)
|
|
1071
|
-
if task_type in heavy_codex and _codex_avail and _codex_available is not False
|
|
1147
|
+
if (task_type in heavy_codex and _codex_avail and _codex_available is not False
|
|
1148
|
+
and _backend_breaker("codex", dcfg).allow()):
|
|
1072
1149
|
backend = "codex"
|
|
1073
|
-
elif task_type in heavy_gemini and _gemini_avail and _gemini_available is not False
|
|
1150
|
+
elif (task_type in heavy_gemini and _gemini_avail and _gemini_available is not False
|
|
1151
|
+
and _backend_breaker("gemini", dcfg).allow()):
|
|
1074
1152
|
backend = "gemini"
|
|
1075
1153
|
else:
|
|
1076
1154
|
backend = "ollama"
|
{code_context_control-2.39.0 → code_context_control-2.39.1/code_context_control.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-context-control
|
|
3
|
-
Version: 2.39.
|
|
3
|
+
Version: 2.39.1
|
|
4
4
|
Summary: Local code-intelligence layer for AI coding tools (Claude Code, Codex, Gemini, Copilot). Retrieve less, read less, edit safer.
|
|
5
5
|
Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -108,6 +108,7 @@ services/auto_memory.py
|
|
|
108
108
|
services/benchmark_dashboard.py
|
|
109
109
|
services/bitbucket_client.py
|
|
110
110
|
services/bitbucket_credentials.py
|
|
111
|
+
services/circuit_breaker.py
|
|
111
112
|
services/claude_md.py
|
|
112
113
|
services/compressor.py
|
|
113
114
|
services/context_snapshot.py
|
|
@@ -161,6 +162,7 @@ tests/test_bitbucket_client.py
|
|
|
161
162
|
tests/test_bitbucket_credentials.py
|
|
162
163
|
tests/test_bitbucket_tool.py
|
|
163
164
|
tests/test_c3_shell.py
|
|
165
|
+
tests/test_circuit_breaker.py
|
|
164
166
|
tests/test_claude_md_merge.py
|
|
165
167
|
tests/test_cli_smoke.py
|
|
166
168
|
tests/test_e2e_benchmark.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "code-context-control"
|
|
7
|
-
version = "2.39.
|
|
7
|
+
version = "2.39.1"
|
|
8
8
|
description = "Local code-intelligence layer for AI coding tools (Claude Code, Codex, Gemini, Copilot). Retrieve less, read less, edit safer."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"""Lightweight thread-safe circuit breaker for flapping subsystems.
|
|
2
|
+
|
|
3
|
+
Borrowed in spirit from Headroom's TransformPipeline breaker: after N
|
|
4
|
+
consecutive failures a subsystem is treated as unhealthy and calls are
|
|
5
|
+
short-circuited for a cooldown window instead of re-running (and re-failing)
|
|
6
|
+
the expensive operation every time. A single success closes the breaker.
|
|
7
|
+
|
|
8
|
+
First consumer: c3_delegate, to stop re-spawning a broken-but-installed CLI
|
|
9
|
+
backend (a 90-120s subprocess timeout) on every call. Deliberately
|
|
10
|
+
dependency-free so any call-time subsystem (e.g. the Ollama embed/generate
|
|
11
|
+
path) can reuse it later.
|
|
12
|
+
"""
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import threading
|
|
16
|
+
import time
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class CircuitBreaker:
|
|
20
|
+
"""Consecutive-failure breaker: closed, opens after N fails, half-opens to probe after a cooldown."""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
name: str = "",
|
|
25
|
+
*,
|
|
26
|
+
failure_threshold: int = 3,
|
|
27
|
+
cooldown_seconds: float = 60.0,
|
|
28
|
+
) -> None:
|
|
29
|
+
self.name = name
|
|
30
|
+
self.failure_threshold = max(1, int(failure_threshold))
|
|
31
|
+
self.cooldown_seconds = max(0.0, float(cooldown_seconds))
|
|
32
|
+
self._lock = threading.Lock()
|
|
33
|
+
self._failures = 0
|
|
34
|
+
self._open = False
|
|
35
|
+
self._opened_at = 0.0
|
|
36
|
+
|
|
37
|
+
def allow(self) -> bool:
|
|
38
|
+
"""Return True if a call may proceed.
|
|
39
|
+
|
|
40
|
+
An open breaker permits a single probe once the cooldown has elapsed
|
|
41
|
+
(half-open); the next ``record_success``/``record_failure`` resolves it.
|
|
42
|
+
"""
|
|
43
|
+
with self._lock:
|
|
44
|
+
if not self._open:
|
|
45
|
+
return True
|
|
46
|
+
return (time.monotonic() - self._opened_at) >= self.cooldown_seconds
|
|
47
|
+
|
|
48
|
+
def record_success(self) -> None:
|
|
49
|
+
"""Reset the breaker after a healthy call."""
|
|
50
|
+
with self._lock:
|
|
51
|
+
self._failures = 0
|
|
52
|
+
self._open = False
|
|
53
|
+
self._opened_at = 0.0
|
|
54
|
+
|
|
55
|
+
def record_failure(self) -> bool:
|
|
56
|
+
"""Count a failed call.
|
|
57
|
+
|
|
58
|
+
Returns True iff this failure *just* tripped the breaker into the open
|
|
59
|
+
state, so callers can emit a one-shot notification on that edge. A failed
|
|
60
|
+
half-open probe restarts the cooldown but does not re-trip.
|
|
61
|
+
"""
|
|
62
|
+
with self._lock:
|
|
63
|
+
self._failures += 1
|
|
64
|
+
if not self._open and self._failures >= self.failure_threshold:
|
|
65
|
+
self._open = True
|
|
66
|
+
self._opened_at = time.monotonic()
|
|
67
|
+
return True
|
|
68
|
+
if self._open:
|
|
69
|
+
self._opened_at = time.monotonic()
|
|
70
|
+
return False
|
|
71
|
+
|
|
72
|
+
def cooldown_remaining(self) -> int:
|
|
73
|
+
"""Whole seconds left before the next probe is allowed (0 if closed/elapsed)."""
|
|
74
|
+
with self._lock:
|
|
75
|
+
if not self._open:
|
|
76
|
+
return 0
|
|
77
|
+
remaining = self.cooldown_seconds - (time.monotonic() - self._opened_at)
|
|
78
|
+
return max(0, int(round(remaining)))
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def is_open(self) -> bool:
|
|
82
|
+
"""True while calls are actively being short-circuited (open and within cooldown)."""
|
|
83
|
+
with self._lock:
|
|
84
|
+
if not self._open:
|
|
85
|
+
return False
|
|
86
|
+
return (time.monotonic() - self._opened_at) < self.cooldown_seconds
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""Tests for the CircuitBreaker primitive and the c3_delegate demote-on-failure wiring."""
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
from services.circuit_breaker import CircuitBreaker
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_closed_until_threshold_then_opens():
|
|
8
|
+
br = CircuitBreaker("x", failure_threshold=3, cooldown_seconds=60)
|
|
9
|
+
assert br.allow()
|
|
10
|
+
assert br.record_failure() is False # 1
|
|
11
|
+
assert br.record_failure() is False # 2
|
|
12
|
+
assert br.allow() # still closed below threshold
|
|
13
|
+
assert br.record_failure() is True # 3 -> trips it open at threshold
|
|
14
|
+
assert not br.allow() # open, within cooldown
|
|
15
|
+
assert br.is_open
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_success_closes_breaker():
|
|
19
|
+
br = CircuitBreaker("x", failure_threshold=2, cooldown_seconds=60)
|
|
20
|
+
br.record_failure()
|
|
21
|
+
assert br.record_failure() is True
|
|
22
|
+
assert not br.allow()
|
|
23
|
+
br.record_success()
|
|
24
|
+
assert br.allow()
|
|
25
|
+
assert br.cooldown_remaining() == 0
|
|
26
|
+
assert not br.is_open
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_half_open_probe_after_cooldown():
|
|
30
|
+
br = CircuitBreaker("x", failure_threshold=1, cooldown_seconds=0.05)
|
|
31
|
+
assert br.record_failure() is True
|
|
32
|
+
assert not br.allow() # blocked within cooldown
|
|
33
|
+
time.sleep(0.08)
|
|
34
|
+
assert br.allow() # half-open: one probe allowed
|
|
35
|
+
assert br.record_failure() is False # failed probe re-arms, not a new trip
|
|
36
|
+
assert not br.allow()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_cooldown_remaining_within_bounds():
|
|
40
|
+
br = CircuitBreaker("x", failure_threshold=1, cooldown_seconds=30)
|
|
41
|
+
br.record_failure()
|
|
42
|
+
assert 0 < br.cooldown_remaining() <= 30
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class _FakeNotifications:
|
|
46
|
+
def __init__(self):
|
|
47
|
+
self.entries = []
|
|
48
|
+
|
|
49
|
+
def add(self, **kwargs):
|
|
50
|
+
self.entries.append(kwargs)
|
|
51
|
+
return kwargs
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class _FakeSvc:
|
|
55
|
+
def __init__(self):
|
|
56
|
+
self.project_path = "."
|
|
57
|
+
self.delegate_config = {
|
|
58
|
+
"gemini_enabled": True,
|
|
59
|
+
"auto_compress": False,
|
|
60
|
+
"breaker_failure_threshold": 3,
|
|
61
|
+
"breaker_cooldown_seconds": 60,
|
|
62
|
+
}
|
|
63
|
+
self.notifications = _FakeNotifications()
|
|
64
|
+
self.compressor = None
|
|
65
|
+
self._agent_progress_cb = None
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _finalize(_tool, _meta, _output, status):
|
|
69
|
+
return status
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def test_gemini_demotes_after_repeated_failures(monkeypatch):
|
|
73
|
+
"""The core bug fix: a broken backend must stop re-spawning the CLI every call."""
|
|
74
|
+
from cli.tools import delegate
|
|
75
|
+
|
|
76
|
+
# Isolate module-global breaker + cache + availability state.
|
|
77
|
+
delegate._backend_breakers.clear()
|
|
78
|
+
delegate._delegate_cache.clear()
|
|
79
|
+
monkeypatch.setattr(delegate, "_gemini_available", True, raising=False)
|
|
80
|
+
|
|
81
|
+
calls = {"run": 0}
|
|
82
|
+
|
|
83
|
+
def fake_run_gemini(*_a, **_k):
|
|
84
|
+
calls["run"] += 1
|
|
85
|
+
return ("boom", False, {})
|
|
86
|
+
|
|
87
|
+
monkeypatch.setattr(delegate, "_run_gemini", fake_run_gemini)
|
|
88
|
+
|
|
89
|
+
svc = _FakeSvc()
|
|
90
|
+
dcfg = svc.delegate_config
|
|
91
|
+
|
|
92
|
+
# Three real failures trip the breaker (threshold=3).
|
|
93
|
+
for _ in range(3):
|
|
94
|
+
assert delegate._handle_gemini_delegate("t", "ask", "", "", svc, dcfg, _finalize) == "error"
|
|
95
|
+
assert calls["run"] == 3
|
|
96
|
+
|
|
97
|
+
# Fourth call: breaker open -> short-circuit, NO subprocess re-spawn.
|
|
98
|
+
assert delegate._handle_gemini_delegate("t", "ask", "", "", svc, dcfg, _finalize) == "degraded"
|
|
99
|
+
assert calls["run"] == 3
|
|
100
|
+
|
|
101
|
+
# The trip emitted exactly one degradation notification.
|
|
102
|
+
degraded = [e for e in svc.notifications.entries if "degraded" in e.get("title", "").lower()]
|
|
103
|
+
assert len(degraded) == 1
|
|
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
|
{code_context_control-2.39.0 → code_context_control-2.39.1}/cli/ui/components/instructions.js
RENAMED
|
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
|
{code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/activity_reporter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/federated_graph.py
RENAMED
|
File without changes
|
{code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/health_checker.py
RENAMED
|
File without changes
|
{code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/insight_engine.py
RENAMED
|
File without changes
|
{code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/memory_reader.py
RENAMED
|
File without changes
|
{code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/memory_writer.py
RENAMED
|
File without changes
|
{code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/ollama_bridge.py
RENAMED
|
File without changes
|
{code_context_control-2.39.0 → code_context_control-2.39.1}/oracle/services/project_scanner.py
RENAMED
|
File without changes
|