code-context-control 2.53.0__tar.gz → 2.54.0__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.53.0 → code_context_control-2.54.0}/PKG-INFO +1 -1
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/c3.py +54 -17
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/commands/parser.py +1 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_server.py +4 -2
- code_context_control-2.54.0/cli/progress.py +49 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/code_context_control.egg-info/PKG-INFO +1 -1
- {code_context_control-2.53.0 → code_context_control-2.54.0}/code_context_control.egg-info/SOURCES.txt +3 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/pyproject.toml +1 -1
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/compressor.py +5 -13
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/doc_index.py +21 -17
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/embedding_index.py +49 -5
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/indexer.py +58 -21
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/protocol.py +37 -26
- code_context_control-2.54.0/services/scanner.py +120 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/subprojects.py +3 -1
- code_context_control-2.54.0/tests/test_init_scan.py +195 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/LICENSE +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/README.md +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/__init__.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/_hook_utils.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/commands/__init__.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/commands/common.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/docs.html +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/edits.html +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/guide/bitbucket.html +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/guide/getting-started.html +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/guide/index.html +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/guide/oracle.html +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/guide/shared.css +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/guide/tools.html +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/guide/workflow.html +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hook_artifact.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hook_auto_snapshot.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hook_c3_signal.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hook_c3read.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hook_dispatch.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hook_edit_ledger.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hook_edit_unlock.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hook_filter.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hook_ghost_files.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hook_pretool_enforce.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hook_prompt_recall.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hook_read.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hook_session_stats.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hook_terse_advisor.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub.html +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/app.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/add_project.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/config_editor.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/drill_health.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/drill_panel.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/drill_tasks.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/drill_views.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/global_search.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/mcp_manager.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/modals.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/project_card.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/project_tree.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/session_drawer.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/settings_modal.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/sidebar.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/summary_bar.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/task_board.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/toasts.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/components/topbar.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui/state.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/hub_ui.html +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/mcp_proxy.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/mcp_server.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/server.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/__init__.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/_helpers.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/agent.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/artifacts.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/bitbucket.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/compress.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/delegate.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/edit.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/edits.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/federate.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/filter.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/impact.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/memory.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/project.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/read.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/search.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/session.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/shell.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/status.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/tasks.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/tools/validate.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui/api.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui/app.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui/components/bitbucket.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui/components/chat.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui/components/dashboard.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui/components/edits.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui/components/instructions.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui/components/memory.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui/components/sessions.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui/components/settings.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui/components/sidebar.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui/components/tasks.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui/icons.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui/pm_shared.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui/shared.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui/theme.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui.html +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui_legacy.html +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/cli/ui_nano.html +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/code_context_control.egg-info/dependency_links.txt +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/code_context_control.egg-info/entry_points.txt +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/code_context_control.egg-info/requires.txt +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/code_context_control.egg-info/top_level.txt +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/core/__init__.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/core/config.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/core/ide.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/core/mcp_toml.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/core/web_security.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/__init__.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/config.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/mcp_oracle.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/oracle_server.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/oracle_ui.html +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/services/__init__.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/services/activity_reporter.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/services/api_auth.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/services/c3_bridge.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/services/chat_engine.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/services/chat_store.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/services/cross_memory.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/services/federated_graph.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/services/health_checker.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/services/insight_engine.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/services/local_session.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/services/memory_reader.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/services/memory_writer.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/services/project_scanner.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/services/review_agent.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/services/tool_executor.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/services/tool_registry.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/activity.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/agents.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/app.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/busy.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/chat/conversations.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/chat/input.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/chat/markdown.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/chat/send.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/chat/stream_renderer.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/chat/toolbar.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/core.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/crossgraph.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/header.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/insights.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/projects.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/settings.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/suggestions.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/oracle/ui/theme_tabs.js +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/__init__.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/activity_log.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/agent_base.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/agents.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/artifact_defs.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/artifact_store.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/auto_memory.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/bench/__init__.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/bench/external/__init__.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/bench/external/aider_polyglot.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/bench/external/swe_bench.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/benchmark_dashboard.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/bitbucket_client.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/bitbucket_credentials.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/circuit_breaker.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/claude_md.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/context_snapshot.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/conversation_store.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/e2e_benchmark.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/e2e_evaluator.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/e2e_tasks.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/edit_ledger.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/error_reporting.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/file_memory.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/git_context.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/hub_service.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/memory.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/memory_consolidator.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/memory_distiller.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/memory_graph.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/memory_grounder.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/memory_queue.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/memory_scorer.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/metrics.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/notifications.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/ollama_bridge.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/ollama_client.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/ollama_credentials.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/output_filter.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/parser.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/project_manager.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/project_runtime.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/proxy_state.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/retention.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/retrieval_broker.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/router.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/runtime.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/session_benchmark.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/session_manager.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/session_preloader.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/task_store.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/telemetry.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/text_index.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/time_tracker.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/tool_classifier.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/transcript_index.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/validation_cache.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/vector_store.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/watcher.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/services/win_subprocess.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/setup.cfg +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_activity_reporter.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_aider_polyglot.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_antigravity_transition.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_artifact_store.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_artifact_tool.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_bitbucket_cli_smoke.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_bitbucket_client.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_bitbucket_config_fallback.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_bitbucket_credentials.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_bitbucket_tool.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_c3_shell.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_circuit_breaker.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_claude_md_merge.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_cli_smoke.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_compressor_large_file.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_delegate_cascade.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_e2e_benchmark.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_edit_ledger_hook.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_edit_normalization.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_enforcement_flip.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_federated_graph.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_filter_backoff.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_ghost_files.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_ghost_generation.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_git_branch_awareness.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_hook_dispatch.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_hook_pretool_enforce.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_hook_prompt_recall.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_hook_smoke.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_hook_state.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_hook_utf8_stdio.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_hub_inspect_api.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_hub_server_smoke.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_install_mcp_entrypoint.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_lazy_store_init.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_mcp_host_guard.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_mcp_memory_timeout.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_mcp_server_smoke.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_mcp_toml.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_memory_distiller.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_memory_graph_api.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_memory_queue.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_memory_system.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_notification_dedup.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_notification_discipline.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_ollama_credentials.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_oracle_api_auth.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_oracle_apikey_api.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_oracle_c3_bridge.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_oracle_chat_engine.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_oracle_discovery_api.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_oracle_local_auth.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_oracle_ollama_bridge.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_oracle_scanner_cache.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_oracle_security_fixes.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_oracle_subproject_awareness.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_oracle_ui_bundle.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_output_filter.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_permissions.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_pm_api.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_project_manager.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_project_manager_merge.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_project_tool.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_read_coercion.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_read_edit_parity.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_related_facts.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_response_boilerplate.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_retention.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_review_digest.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_service_durability.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_session_benchmark.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_session_budget.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_shell_robustness.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_subproject_exclusion.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_subproject_federation.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_subprojects.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_swe_bench.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_task_store.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_task_tool.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_time_tracker.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_token_telemetry.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_tool_registry.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_upgrade_and_version.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_validate.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_web_security.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tests/test_windows_reliability.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/__init__.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/backend.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/main.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/screens/__init__.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/screens/benchmark_view.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/screens/claudemd_view.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/screens/compress_view.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/screens/index_view.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/screens/init_view.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/screens/mcp_view.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/screens/optimize_view.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/screens/pipe_view.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/screens/projects_view.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/screens/search_view.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/screens/session_view.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/screens/stats.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/screens/ui_view.py +0 -0
- {code_context_control-2.53.0 → code_context_control-2.54.0}/tui/theme.tcss +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-context-control
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.54.0
|
|
4
4
|
Summary: Local code-intelligence layer for AI coding tools (Claude Code, Codex, Copilot, Cursor, Antigravity). Retrieve less, read less, edit safer — and version the configs that shape your agent (CLAUDE.md, skills, hooks, MCP).
|
|
5
5
|
Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -92,7 +92,7 @@ console = Console() if HAS_RICH else None
|
|
|
92
92
|
# Config
|
|
93
93
|
CONFIG_DIR = ".c3"
|
|
94
94
|
CONFIG_FILE = ".c3/config.json"
|
|
95
|
-
__version__ = "2.
|
|
95
|
+
__version__ = "2.54.0"
|
|
96
96
|
|
|
97
97
|
|
|
98
98
|
def _command_deps() -> CommandDeps:
|
|
@@ -165,6 +165,7 @@ def _build_init_config(project_path: str) -> dict:
|
|
|
165
165
|
"project_path": project_path,
|
|
166
166
|
"version": __version__,
|
|
167
167
|
"index_auto_update": True,
|
|
168
|
+
"index_max_files": 2000,
|
|
168
169
|
"compression_mode": "smart",
|
|
169
170
|
"mcp": {"mode": "direct"},
|
|
170
171
|
"hybrid": deepcopy(HYBRID_DEFAULTS),
|
|
@@ -890,7 +891,7 @@ def _parse_cli_ide_arg(value: str) -> str:
|
|
|
890
891
|
return normalized
|
|
891
892
|
|
|
892
893
|
|
|
893
|
-
def _do_init(project_path: str, ide_name: str = None):
|
|
894
|
+
def _do_init(project_path: str, ide_name: str = None, no_embed: bool = False):
|
|
894
895
|
"""Run the core init steps (shared by new install and re-init after clear/reset)."""
|
|
895
896
|
config = _build_init_config(project_path)
|
|
896
897
|
save_config(config, project_path)
|
|
@@ -898,10 +899,27 @@ def _do_init(project_path: str, ide_name: str = None):
|
|
|
898
899
|
for subdir in _C3_INIT_SUBDIRS:
|
|
899
900
|
(Path(project_path) / CONFIG_DIR / subdir).mkdir(parents=True, exist_ok=True)
|
|
900
901
|
|
|
902
|
+
import time as _t
|
|
903
|
+
|
|
904
|
+
from cli.progress import ProgressLine
|
|
905
|
+
|
|
901
906
|
print("Building code index...")
|
|
907
|
+
_prog = ProgressLine()
|
|
908
|
+
_t0 = _t.perf_counter()
|
|
902
909
|
indexer = CodeIndex(project_path)
|
|
903
|
-
result = indexer.build_index(
|
|
904
|
-
|
|
910
|
+
result = indexer.build_index(
|
|
911
|
+
on_progress=lambda entries, files, chunks: _prog.update(
|
|
912
|
+
f" scanning: {entries:,} entries | {files:,} files | {chunks:,} chunks"))
|
|
913
|
+
_prog.done()
|
|
914
|
+
entries = result.get("entries_scanned", 0)
|
|
915
|
+
print(f" Indexed {result['files_indexed']} files, {result['chunks_created']} chunks "
|
|
916
|
+
f"in {_t.perf_counter() - _t0:.1f}s ({entries:,} entries scanned)")
|
|
917
|
+
capped = result.get("files_capped", 0)
|
|
918
|
+
if capped:
|
|
919
|
+
total = result["files_indexed"] + capped
|
|
920
|
+
print(f" [!] Indexed {result['files_indexed']} of {total} candidate files "
|
|
921
|
+
f"(cap: index_max_files={result.get('max_files')}).")
|
|
922
|
+
print(" Raise index_max_files in .c3/config.json for full coverage.")
|
|
905
923
|
|
|
906
924
|
# Build embedding index if Ollama is available (non-blocking on failure)
|
|
907
925
|
try:
|
|
@@ -912,13 +930,24 @@ def _do_init(project_path: str, ide_name: str = None):
|
|
|
912
930
|
ollama = OllamaClient(ollama_url)
|
|
913
931
|
embed_model = config.get("embed_model", "nomic-embed-text")
|
|
914
932
|
ei = EmbeddingIndex(project_path, ollama, embed_model=embed_model)
|
|
915
|
-
if
|
|
933
|
+
if no_embed:
|
|
934
|
+
print(" Embedding index skipped (--no-embed)")
|
|
935
|
+
elif ei.probe()["ready"]:
|
|
936
|
+
# probe() initializes the lazy backends; checking .ready on a
|
|
937
|
+
# fresh instance is always False and silently skipped the build.
|
|
916
938
|
print("Building embedding index...")
|
|
917
|
-
|
|
939
|
+
_t0 = _t.perf_counter()
|
|
940
|
+
_eprog = ProgressLine()
|
|
941
|
+
ei_result = ei.build(
|
|
942
|
+
indexer,
|
|
943
|
+
on_progress=lambda done, total, chunks: _eprog.update(
|
|
944
|
+
f" embedding: file {done}/{total} | {chunks:,} chunks"))
|
|
945
|
+
_eprog.done()
|
|
918
946
|
print(f" Embedded {ei_result.get('chunks_embedded', 0)} chunks "
|
|
919
|
-
f"({ei_result.get('files_processed', 0)} files)"
|
|
947
|
+
f"({ei_result.get('files_processed', 0)} files) "
|
|
948
|
+
f"in {_t.perf_counter() - _t0:.1f}s")
|
|
920
949
|
else:
|
|
921
|
-
print(" Embedding index skipped (
|
|
950
|
+
print(f" Embedding index skipped ({ei.unavailable_reason()})")
|
|
922
951
|
except Exception:
|
|
923
952
|
_log.debug("Embedding index build failed", exc_info=True)
|
|
924
953
|
|
|
@@ -926,15 +955,22 @@ def _do_init(project_path: str, ide_name: str = None):
|
|
|
926
955
|
try:
|
|
927
956
|
from services.doc_index import DocIndex
|
|
928
957
|
print("Building doc index...")
|
|
958
|
+
_t0 = _t.perf_counter()
|
|
959
|
+
_dprog = ProgressLine()
|
|
929
960
|
di = DocIndex(project_path)
|
|
930
|
-
di_result = di.build(
|
|
931
|
-
|
|
961
|
+
di_result = di.build(
|
|
962
|
+
on_progress=lambda done, total: _dprog.update(
|
|
963
|
+
f" docs: {done}/{total}"))
|
|
964
|
+
_dprog.done()
|
|
965
|
+
print(f" Indexed {di_result['docs_indexed']} docs, "
|
|
966
|
+
f"{di_result['chunks_created']} chunks in {_t.perf_counter() - _t0:.1f}s")
|
|
932
967
|
except Exception:
|
|
933
968
|
_log.debug("Doc index build failed", exc_info=True)
|
|
934
969
|
|
|
935
970
|
print("Building compression dictionary...")
|
|
936
971
|
protocol = CompressionProtocol(project_path)
|
|
937
|
-
|
|
972
|
+
# Mine the in-memory index instead of re-reading the whole tree.
|
|
973
|
+
new_terms = protocol.build_project_dictionary(code_index=indexer)
|
|
938
974
|
print(f" Added {len(new_terms)} project-specific terms")
|
|
939
975
|
|
|
940
976
|
from core.ide import detect_ide, load_ide_config
|
|
@@ -966,11 +1002,12 @@ def cmd_init(args):
|
|
|
966
1002
|
if requested_ide != "auto":
|
|
967
1003
|
requested_ide = normalize_ide_name(requested_ide)
|
|
968
1004
|
git_requested = getattr(args, "git", False)
|
|
1005
|
+
no_embed = bool(getattr(args, "no_embed", False))
|
|
969
1006
|
|
|
970
1007
|
# ── Brand-new install ──────────────────────────────────────
|
|
971
1008
|
if not c3_dir.exists() or not (c3_dir / "config.json").exists():
|
|
972
1009
|
print_header(f"Initializing C3 for: {project_path}")
|
|
973
|
-
_do_init(project_path, ide_name=requested_ide)
|
|
1010
|
+
_do_init(project_path, ide_name=requested_ide, no_embed=no_embed)
|
|
974
1011
|
try:
|
|
975
1012
|
from services.project_manager import ProjectManager
|
|
976
1013
|
ProjectManager().add_project(project_path)
|
|
@@ -1123,7 +1160,7 @@ def cmd_init(args):
|
|
|
1123
1160
|
ti_manifest = c3_dir / "transcript_index" / "manifest.json"
|
|
1124
1161
|
if ti_manifest.exists():
|
|
1125
1162
|
ti_manifest.write_text("{}", encoding="utf-8")
|
|
1126
|
-
_do_init(project_path, ide_name=requested_ide)
|
|
1163
|
+
_do_init(project_path, ide_name=requested_ide, no_embed=no_embed)
|
|
1127
1164
|
if git_requested:
|
|
1128
1165
|
_init_local_git_repo(project_path)
|
|
1129
1166
|
_run_install_mcp(project_path, requested_ide, mcp_mode=getattr(args, "mcp_mode", "direct"), banner="Updating MCP tools...")
|
|
@@ -1152,7 +1189,7 @@ def cmd_init(args):
|
|
|
1152
1189
|
# ── Non-interactive (--force) ──────────────────────────────
|
|
1153
1190
|
if getattr(args, "force", False):
|
|
1154
1191
|
print("\n[--force] Applying update...")
|
|
1155
|
-
_do_init(project_path, ide_name=requested_ide)
|
|
1192
|
+
_do_init(project_path, ide_name=requested_ide, no_embed=no_embed)
|
|
1156
1193
|
if git_requested:
|
|
1157
1194
|
_init_local_git_repo(project_path)
|
|
1158
1195
|
_run_install_mcp(project_path, requested_ide, mcp_mode=getattr(args, "mcp_mode", "direct"), banner="Updating MCP tools...")
|
|
@@ -1176,7 +1213,7 @@ def cmd_init(args):
|
|
|
1176
1213
|
|
|
1177
1214
|
if selected.startswith("Update"):
|
|
1178
1215
|
print()
|
|
1179
|
-
_do_init(project_path, ide_name=requested_ide)
|
|
1216
|
+
_do_init(project_path, ide_name=requested_ide, no_embed=no_embed)
|
|
1180
1217
|
if git_requested:
|
|
1181
1218
|
_init_local_git_repo(project_path)
|
|
1182
1219
|
_prompt_install_mcp(project_path, requested_ide, default_mode=getattr(args, "mcp_mode", "direct"), banner="Updating MCP tools...")
|
|
@@ -1192,7 +1229,7 @@ def cmd_init(args):
|
|
|
1192
1229
|
shutil.rmtree(target)
|
|
1193
1230
|
print(f" Removed .c3/{subdir}/")
|
|
1194
1231
|
print()
|
|
1195
|
-
_do_init(project_path, ide_name=requested_ide)
|
|
1232
|
+
_do_init(project_path, ide_name=requested_ide, no_embed=no_embed)
|
|
1196
1233
|
if git_requested:
|
|
1197
1234
|
_init_local_git_repo(project_path)
|
|
1198
1235
|
_prompt_install_mcp(project_path, requested_ide, default_mode=getattr(args, "mcp_mode", "direct"), banner="Updating MCP tools...")
|
|
@@ -1209,7 +1246,7 @@ def cmd_init(args):
|
|
|
1209
1246
|
shutil.rmtree(c3_dir)
|
|
1210
1247
|
print(" Deleted .c3/")
|
|
1211
1248
|
print()
|
|
1212
|
-
_do_init(project_path, ide_name=requested_ide)
|
|
1249
|
+
_do_init(project_path, ide_name=requested_ide, no_embed=no_embed)
|
|
1213
1250
|
if git_requested:
|
|
1214
1251
|
_init_local_git_repo(project_path)
|
|
1215
1252
|
_prompt_install_mcp(project_path, requested_ide, default_mode=getattr(args, "mcp_mode", "direct"), banner="Re-installing MCP tools...")
|
|
@@ -24,6 +24,7 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
24
24
|
p_init.add_argument("--ide", default="auto", type=parse_cli_ide_arg, metavar="{auto,claude,vscode,cursor,codex,antigravity}", help="Target IDE for MCP config (default: auto-detect)")
|
|
25
25
|
p_init.add_argument("--mcp-mode", choices=["direct", "proxy"], default="direct", help="Default MCP mode if install is selected during init (default: direct)")
|
|
26
26
|
p_init.add_argument("--git", action="store_true", help="Initialize a local Git repository during init/update")
|
|
27
|
+
p_init.add_argument("--no-embed", action="store_true", help="Skip building the semantic embedding index during init")
|
|
27
28
|
p_init.add_argument("--permissions", choices=["read-only", "c3-strict", "standard", "permissive"], default=None, help="Apply Claude Code permission tier (Claude Code only, used with --force)")
|
|
28
29
|
p_init.add_argument("--include-mcp-wildcard", action="store_true", help="Add mcp__* wildcard so non-C3 MCP servers don't prompt per-call")
|
|
29
30
|
|
|
@@ -1027,8 +1027,10 @@ def api_run_component():
|
|
|
1027
1027
|
ollama = OllamaClient(ollama_url)
|
|
1028
1028
|
embed_model = cfg.get("embed_model", "nomic-embed-text")
|
|
1029
1029
|
ei = EmbeddingIndex(resolved, ollama, embed_model=embed_model)
|
|
1030
|
-
|
|
1031
|
-
|
|
1030
|
+
# probe() initializes lazy backends; a fresh instance's .ready
|
|
1031
|
+
# is always False and would skip the build unconditionally.
|
|
1032
|
+
if not ei.probe()["ready"]:
|
|
1033
|
+
return jsonify({"success": True, "output": f"Embedding index skipped ({ei.unavailable_reason()})."})
|
|
1032
1034
|
indexer = CodeIndex(resolved)
|
|
1033
1035
|
if not indexer.chunks:
|
|
1034
1036
|
indexer._load_index()
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Single-line TTY progress for long CLI phases (index/embedding builds).
|
|
3
|
+
|
|
4
|
+
Quiet when stdout is piped - CI logs and command substitutions see only
|
|
5
|
+
the final summary lines, never carriage-return spam.
|
|
6
|
+
"""
|
|
7
|
+
import sys
|
|
8
|
+
import time
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ProgressLine:
|
|
12
|
+
"""Rewrites one status line in place; time-throttled; TTY-only."""
|
|
13
|
+
|
|
14
|
+
def __init__(self, stream=None, min_interval: float = 0.1):
|
|
15
|
+
self.stream = stream if stream is not None else sys.stdout
|
|
16
|
+
self.min_interval = min_interval
|
|
17
|
+
self._last = 0.0
|
|
18
|
+
self._width = 0
|
|
19
|
+
try:
|
|
20
|
+
self._tty = bool(self.stream.isatty())
|
|
21
|
+
except Exception:
|
|
22
|
+
self._tty = False
|
|
23
|
+
|
|
24
|
+
def update(self, text: str) -> None:
|
|
25
|
+
if not self._tty:
|
|
26
|
+
return
|
|
27
|
+
now = time.monotonic()
|
|
28
|
+
if now - self._last < self.min_interval:
|
|
29
|
+
return
|
|
30
|
+
self._last = now
|
|
31
|
+
pad = ' ' * max(0, self._width - len(text))
|
|
32
|
+
try:
|
|
33
|
+
self.stream.write('\r' + text + pad)
|
|
34
|
+
self.stream.flush()
|
|
35
|
+
except Exception:
|
|
36
|
+
self._tty = False
|
|
37
|
+
return
|
|
38
|
+
self._width = len(text)
|
|
39
|
+
|
|
40
|
+
def done(self) -> None:
|
|
41
|
+
"""Clear the in-place line so the following prints start clean."""
|
|
42
|
+
if not self._tty or not self._width:
|
|
43
|
+
return
|
|
44
|
+
try:
|
|
45
|
+
self.stream.write('\r' + ' ' * self._width + '\r')
|
|
46
|
+
self.stream.flush()
|
|
47
|
+
except Exception:
|
|
48
|
+
pass
|
|
49
|
+
self._width = 0
|
{code_context_control-2.53.0 → code_context_control-2.54.0}/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.
|
|
3
|
+
Version: 2.54.0
|
|
4
4
|
Summary: Local code-intelligence layer for AI coding tools (Claude Code, Codex, Copilot, Cursor, Antigravity). Retrieve less, read less, edit safer — and version the configs that shape your agent (CLAUDE.md, skills, hooks, MCP).
|
|
5
5
|
Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -25,6 +25,7 @@ cli/hub_server.py
|
|
|
25
25
|
cli/hub_ui.html
|
|
26
26
|
cli/mcp_proxy.py
|
|
27
27
|
cli/mcp_server.py
|
|
28
|
+
cli/progress.py
|
|
28
29
|
cli/server.py
|
|
29
30
|
cli/ui.html
|
|
30
31
|
cli/ui_legacy.html
|
|
@@ -196,6 +197,7 @@ services/retention.py
|
|
|
196
197
|
services/retrieval_broker.py
|
|
197
198
|
services/router.py
|
|
198
199
|
services/runtime.py
|
|
200
|
+
services/scanner.py
|
|
199
201
|
services/session_benchmark.py
|
|
200
202
|
services/session_manager.py
|
|
201
203
|
services/session_preloader.py
|
|
@@ -248,6 +250,7 @@ tests/test_hook_state.py
|
|
|
248
250
|
tests/test_hook_utf8_stdio.py
|
|
249
251
|
tests/test_hub_inspect_api.py
|
|
250
252
|
tests/test_hub_server_smoke.py
|
|
253
|
+
tests/test_init_scan.py
|
|
251
254
|
tests/test_install_mcp_entrypoint.py
|
|
252
255
|
tests/test_lazy_store_init.py
|
|
253
256
|
tests/test_mcp_host_guard.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "code-context-control"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.54.0"
|
|
8
8
|
description = "Local code-intelligence layer for AI coding tools (Claude Code, Codex, Copilot, Cursor, Antigravity). Retrieve less, read less, edit safer — and version the configs that shape your agent (CLAUDE.md, skills, hooks, MCP)."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -709,27 +709,19 @@ class CodeCompressor:
|
|
|
709
709
|
'.css', '.html', '.json', '.yaml', '.yml', '.md'}
|
|
710
710
|
allowed = set(extensions) if extensions else default_exts
|
|
711
711
|
|
|
712
|
-
# Skip common non-essential dirs
|
|
713
|
-
skip_dirs = {'node_modules', '.git', '__pycache__', '.c3', 'venv',
|
|
714
|
-
'env', '.venv', 'dist', 'build', '.next', '.cache'}
|
|
715
|
-
|
|
716
712
|
results = []
|
|
717
713
|
total_original = 0
|
|
718
714
|
total_compressed = 0
|
|
719
715
|
skipped_protected = []
|
|
720
716
|
|
|
721
|
-
|
|
722
|
-
|
|
717
|
+
# Pruned walk (shared SKIP_DIRS) - never descends into
|
|
718
|
+
# node_modules/.git/etc., stops as soon as the cap is reached.
|
|
719
|
+
from services.scanner import iter_files
|
|
723
720
|
|
|
724
|
-
|
|
721
|
+
count = 0
|
|
722
|
+
for fpath in iter_files(dirpath, exts={e.lower() for e in allowed}):
|
|
725
723
|
if count >= max_files:
|
|
726
724
|
break
|
|
727
|
-
if not fpath.is_file():
|
|
728
|
-
continue
|
|
729
|
-
if fpath.suffix.lower() not in allowed:
|
|
730
|
-
continue
|
|
731
|
-
if any(skip in fpath.parts for skip in skip_dirs):
|
|
732
|
-
continue
|
|
733
725
|
if self.is_protected_file(fpath):
|
|
734
726
|
skipped_protected.append(self._relative_to_project(fpath))
|
|
735
727
|
continue
|
|
@@ -92,15 +92,26 @@ class DocIndex:
|
|
|
92
92
|
|
|
93
93
|
# --- Build ---
|
|
94
94
|
|
|
95
|
-
def build(self, force: bool = False) -> dict:
|
|
96
|
-
"""Build or incrementally update the doc index.
|
|
95
|
+
def build(self, force: bool = False, on_progress=None) -> dict:
|
|
96
|
+
"""Build or incrementally update the doc index.
|
|
97
|
+
|
|
98
|
+
on_progress: callable(files_done, files_total), invoked per file.
|
|
99
|
+
"""
|
|
97
100
|
stats = {"docs_indexed": 0, "chunks_created": 0, "skipped": 0}
|
|
98
101
|
|
|
99
102
|
files_to_index = self._discover_files()
|
|
100
103
|
old_hashes = dict(self._file_hashes)
|
|
101
104
|
new_hashes = {}
|
|
105
|
+
files_total = len(files_to_index)
|
|
106
|
+
files_done = 0
|
|
102
107
|
|
|
103
108
|
for rel_path, fpath in files_to_index:
|
|
109
|
+
files_done += 1
|
|
110
|
+
if on_progress is not None:
|
|
111
|
+
try:
|
|
112
|
+
on_progress(files_done, files_total)
|
|
113
|
+
except Exception:
|
|
114
|
+
pass
|
|
104
115
|
try:
|
|
105
116
|
content = fpath.read_text(errors="replace")
|
|
106
117
|
except Exception:
|
|
@@ -154,12 +165,6 @@ class DocIndex:
|
|
|
154
165
|
|
|
155
166
|
def _discover_files(self) -> list[tuple[str, Path]]:
|
|
156
167
|
"""Find all doc, config, and code files to index."""
|
|
157
|
-
skip_dirs = {
|
|
158
|
-
"node_modules", ".git", "__pycache__", ".c3", "venv",
|
|
159
|
-
"env", ".venv", "dist", "build", ".next", ".cache",
|
|
160
|
-
"coverage", ".pytest_cache",
|
|
161
|
-
}
|
|
162
|
-
|
|
163
168
|
# Designated sub-projects keep their own doc index.
|
|
164
169
|
try:
|
|
165
170
|
from services.subprojects import make_excluder
|
|
@@ -170,15 +175,14 @@ class DocIndex:
|
|
|
170
175
|
|
|
171
176
|
files = []
|
|
172
177
|
|
|
173
|
-
# Markdown docs
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
files.append((rel, fpath))
|
|
178
|
+
# Markdown docs - one pruned walk instead of four full rglob passes
|
|
179
|
+
from services.scanner import iter_files
|
|
180
|
+
for fpath in iter_files(self.project_path,
|
|
181
|
+
exts={".md", ".mdx", ".rst", ".adoc"}):
|
|
182
|
+
if _sub_excluded(fpath):
|
|
183
|
+
continue
|
|
184
|
+
rel = str(fpath.relative_to(self.project_path))
|
|
185
|
+
files.append((rel, fpath))
|
|
182
186
|
|
|
183
187
|
# Config files at project root
|
|
184
188
|
for pattern in _CONFIG_PATTERNS:
|
|
@@ -39,6 +39,8 @@ class EmbeddingIndex:
|
|
|
39
39
|
self._collection = None
|
|
40
40
|
self._available = False
|
|
41
41
|
self._ollama_ok = False
|
|
42
|
+
self._ollama_up = False
|
|
43
|
+
self._model_ok = False
|
|
42
44
|
self._file_hashes: dict[str, str] = {} # doc_id -> content hash
|
|
43
45
|
self._lock = threading.Lock()
|
|
44
46
|
self._chunk_map: dict[str, dict] = {} # chunk_id -> metadata
|
|
@@ -101,18 +103,47 @@ class EmbeddingIndex:
|
|
|
101
103
|
self._available = False
|
|
102
104
|
|
|
103
105
|
try:
|
|
104
|
-
self.
|
|
105
|
-
|
|
106
|
-
and self.ollama.has_model(self.embed_model)
|
|
106
|
+
self._ollama_up = self.ollama.is_available(timeout=2)
|
|
107
|
+
self._model_ok = (
|
|
108
|
+
self._ollama_up and self.ollama.has_model(self.embed_model)
|
|
107
109
|
)
|
|
108
110
|
except Exception:
|
|
109
|
-
self.
|
|
111
|
+
self._ollama_up = False
|
|
112
|
+
self._model_ok = False
|
|
113
|
+
self._ollama_ok = self._ollama_up and self._model_ok
|
|
110
114
|
|
|
111
115
|
@property
|
|
112
116
|
def ready(self) -> bool:
|
|
113
117
|
"""True when both chromadb and Ollama embeddings are available."""
|
|
114
118
|
return self._available and self._ollama_ok
|
|
115
119
|
|
|
120
|
+
def probe(self) -> dict:
|
|
121
|
+
"""Explicitly initialize backends and report readiness.
|
|
122
|
+
|
|
123
|
+
``ready`` alone never triggers backend init (status reporters must
|
|
124
|
+
stay cheap for build_runtime/MCP handshake), so gating a build on a
|
|
125
|
+
fresh instance's ``ready`` always skipped. Init/CLI flows call this
|
|
126
|
+
instead: it pays the one-time backend cost, then reports truthfully.
|
|
127
|
+
"""
|
|
128
|
+
self._ensure_ready()
|
|
129
|
+
return {
|
|
130
|
+
"ready": self.ready,
|
|
131
|
+
"chromadb": self._available,
|
|
132
|
+
"ollama": self._ollama_up,
|
|
133
|
+
"model": self._model_ok,
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
def unavailable_reason(self) -> str:
|
|
137
|
+
"""Human-readable reason ``ready`` is False (after probe/init)."""
|
|
138
|
+
if not self._available:
|
|
139
|
+
return "chromadb not installed"
|
|
140
|
+
if not self._ollama_up:
|
|
141
|
+
return "Ollama not reachable"
|
|
142
|
+
if not self._model_ok:
|
|
143
|
+
return (f"embed model '{self.embed_model}' not pulled "
|
|
144
|
+
f"(run: ollama pull {self.embed_model})")
|
|
145
|
+
return ""
|
|
146
|
+
|
|
116
147
|
# ── Hash tracking ─────────────────────────────────────
|
|
117
148
|
|
|
118
149
|
def _load_hashes(self):
|
|
@@ -138,12 +169,14 @@ class EmbeddingIndex:
|
|
|
138
169
|
|
|
139
170
|
# ── Build / Update ────────────────────────────────────
|
|
140
171
|
|
|
141
|
-
def build(self, code_index, force: bool = False) -> dict:
|
|
172
|
+
def build(self, code_index, force: bool = False, on_progress=None) -> dict:
|
|
142
173
|
"""Build or incrementally update the embedding index from CodeIndex chunks.
|
|
143
174
|
|
|
144
175
|
Args:
|
|
145
176
|
code_index: A CodeIndex instance with populated chunks/documents.
|
|
146
177
|
force: If True, re-embed all files regardless of hash.
|
|
178
|
+
on_progress: callable(files_done, files_total, chunks_embedded),
|
|
179
|
+
invoked per file (skipped files count as done).
|
|
147
180
|
|
|
148
181
|
Returns:
|
|
149
182
|
Stats dict with files_processed, chunks_embedded, chunks_skipped, etc.
|
|
@@ -170,6 +203,15 @@ class EmbeddingIndex:
|
|
|
170
203
|
files_skipped = 0
|
|
171
204
|
errors = 0
|
|
172
205
|
stale_ids = []
|
|
206
|
+
files_total = len(chunks_by_file)
|
|
207
|
+
|
|
208
|
+
def _report():
|
|
209
|
+
if on_progress is not None:
|
|
210
|
+
try:
|
|
211
|
+
on_progress(files_processed + files_skipped, files_total,
|
|
212
|
+
chunks_embedded)
|
|
213
|
+
except Exception:
|
|
214
|
+
pass
|
|
173
215
|
|
|
174
216
|
with self._lock:
|
|
175
217
|
# Detect deleted files — remove their embeddings
|
|
@@ -187,6 +229,7 @@ class EmbeddingIndex:
|
|
|
187
229
|
if not force and self._file_hashes.get(doc_id) == new_hash:
|
|
188
230
|
files_skipped += 1
|
|
189
231
|
chunks_skipped += len(file_chunks)
|
|
232
|
+
_report()
|
|
190
233
|
continue
|
|
191
234
|
|
|
192
235
|
# Remove old chunks for this file before re-embedding
|
|
@@ -237,6 +280,7 @@ class EmbeddingIndex:
|
|
|
237
280
|
|
|
238
281
|
self._file_hashes[doc_id] = new_hash
|
|
239
282
|
files_processed += 1
|
|
283
|
+
_report()
|
|
240
284
|
|
|
241
285
|
self._save_hashes()
|
|
242
286
|
|
|
@@ -13,6 +13,7 @@ from collections import Counter, OrderedDict
|
|
|
13
13
|
from pathlib import Path
|
|
14
14
|
|
|
15
15
|
from core import count_tokens
|
|
16
|
+
from services.scanner import SKIP_DIRS, iter_files
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
class CodeIndex:
|
|
@@ -37,10 +38,8 @@ class CodeIndex:
|
|
|
37
38
|
self._cooccurrence = {} # term -> {term: count} for auto-synonyms
|
|
38
39
|
self._file_mtimes = {} # doc_id -> mtime for recency bias
|
|
39
40
|
|
|
40
|
-
# Config
|
|
41
|
-
self.skip_dirs =
|
|
42
|
-
'env', '.venv', 'dist', 'build', '.next', '.cache',
|
|
43
|
-
'coverage', '.pytest_cache'}
|
|
41
|
+
# Config - shared pruned-walk skip set (services/scanner.py)
|
|
42
|
+
self.skip_dirs = set(SKIP_DIRS)
|
|
44
43
|
self.code_exts = {
|
|
45
44
|
# Python
|
|
46
45
|
'.py', '.pyi', '.pyx',
|
|
@@ -87,8 +86,31 @@ class CodeIndex:
|
|
|
87
86
|
self.exclude_prefixes = []
|
|
88
87
|
self._is_excluded = None
|
|
89
88
|
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
_DEFAULT_MAX_FILES = 2000
|
|
90
|
+
|
|
91
|
+
def _configured_max_files(self) -> int:
|
|
92
|
+
"""``index_max_files`` from .c3/config.json; default 2000."""
|
|
93
|
+
try:
|
|
94
|
+
cfg = json.loads((self.project_path / '.c3' / 'config.json')
|
|
95
|
+
.read_text(encoding='utf-8'))
|
|
96
|
+
val = int(cfg.get('index_max_files', self._DEFAULT_MAX_FILES))
|
|
97
|
+
return val if val > 0 else self._DEFAULT_MAX_FILES
|
|
98
|
+
except Exception:
|
|
99
|
+
return self._DEFAULT_MAX_FILES
|
|
100
|
+
|
|
101
|
+
def build_index(self, max_files: int = None, on_progress=None) -> dict:
|
|
102
|
+
"""Build the full code index.
|
|
103
|
+
|
|
104
|
+
max_files: cap on files indexed. None reads ``index_max_files``
|
|
105
|
+
from .c3/config.json (default 2000). Traversal continues past
|
|
106
|
+
the cap only to count what was left out, so callers can report
|
|
107
|
+
"indexed N of M" instead of silently truncating.
|
|
108
|
+
on_progress: callable(entries_seen, files_indexed, chunks_created),
|
|
109
|
+
invoked during the scan (directory granularity plus per file).
|
|
110
|
+
"""
|
|
111
|
+
if max_files is None:
|
|
112
|
+
max_files = self._configured_max_files()
|
|
113
|
+
|
|
92
114
|
self.documents = {}
|
|
93
115
|
self.chunks = {}
|
|
94
116
|
self.symbols = {}
|
|
@@ -96,24 +118,35 @@ class CodeIndex:
|
|
|
96
118
|
|
|
97
119
|
files_indexed = 0
|
|
98
120
|
chunks_created = 0
|
|
121
|
+
files_capped = 0
|
|
122
|
+
scan_stats = {"entries": 0}
|
|
99
123
|
|
|
100
|
-
|
|
101
|
-
if
|
|
102
|
-
|
|
103
|
-
if not
|
|
104
|
-
continue
|
|
105
|
-
if fpath.suffix.lower() not in self.code_exts:
|
|
106
|
-
continue
|
|
107
|
-
if any(skip in fpath.parts for skip in self.skip_dirs):
|
|
108
|
-
continue
|
|
109
|
-
if self.exclude_prefixes:
|
|
124
|
+
def _report(entries_seen=None, _yielded=None):
|
|
125
|
+
if entries_seen is not None:
|
|
126
|
+
scan_stats["entries"] = entries_seen
|
|
127
|
+
if on_progress is not None:
|
|
110
128
|
try:
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
except ValueError:
|
|
129
|
+
on_progress(scan_stats["entries"], files_indexed,
|
|
130
|
+
chunks_created)
|
|
131
|
+
except Exception:
|
|
115
132
|
pass
|
|
116
133
|
|
|
134
|
+
exclude_parts = None
|
|
135
|
+
if self.exclude_prefixes and self._is_excluded is not None:
|
|
136
|
+
def exclude_parts(parts, _c=self._is_excluded,
|
|
137
|
+
_p=self.exclude_prefixes):
|
|
138
|
+
return _c(parts, _p)
|
|
139
|
+
|
|
140
|
+
for fpath in iter_files(self.project_path, exts=self.code_exts,
|
|
141
|
+
skip_dirs=self.skip_dirs,
|
|
142
|
+
exclude_parts=exclude_parts,
|
|
143
|
+
on_progress=_report):
|
|
144
|
+
if files_indexed >= max_files:
|
|
145
|
+
# Walk on (cheap after pruning) to count coverage;
|
|
146
|
+
# reading and chunking stop at the cap.
|
|
147
|
+
files_capped += 1
|
|
148
|
+
continue
|
|
149
|
+
|
|
117
150
|
try:
|
|
118
151
|
content = fpath.read_text(errors='replace')
|
|
119
152
|
except Exception:
|
|
@@ -150,6 +183,7 @@ class CodeIndex:
|
|
|
150
183
|
pass
|
|
151
184
|
|
|
152
185
|
files_indexed += 1
|
|
186
|
+
_report()
|
|
153
187
|
|
|
154
188
|
# Build TF-IDF and co-occurrence synonyms
|
|
155
189
|
self._build_tfidf()
|
|
@@ -162,7 +196,10 @@ class CodeIndex:
|
|
|
162
196
|
"files_indexed": files_indexed,
|
|
163
197
|
"chunks_created": chunks_created,
|
|
164
198
|
"unique_symbols": len(self.symbols),
|
|
165
|
-
"index_path": str(self.index_dir)
|
|
199
|
+
"index_path": str(self.index_dir),
|
|
200
|
+
"entries_scanned": scan_stats["entries"],
|
|
201
|
+
"files_capped": files_capped,
|
|
202
|
+
"max_files": max_files,
|
|
166
203
|
}
|
|
167
204
|
|
|
168
205
|
def _chunk_file(self, content: str, ext: str, doc_id: str) -> list:
|