code-context-control 2.123.0__tar.gz → 2.124.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.123.0/code_context_control.egg-info → code_context_control-2.124.0}/PKG-INFO +1 -1
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/c3.py +1 -1
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/mcp_server.py +5 -18
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/compress.py +3 -2
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/read.py +4 -1
- {code_context_control-2.123.0 → code_context_control-2.124.0/code_context_control.egg-info}/PKG-INFO +1 -1
- {code_context_control-2.123.0 → code_context_control-2.124.0}/code_context_control.egg-info/SOURCES.txt +1 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/pyproject.toml +1 -1
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/file_map.py +61 -2
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/file_memory.py +107 -10
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/parser.py +41 -19
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_file_map_c1.py +4 -2
- code_context_control-2.124.0/tests/test_large_files_c4.py +154 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_map_eval.py +2 -1
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_mcp_server_smoke.py +4 -2
- {code_context_control-2.123.0 → code_context_control-2.124.0}/LICENSE +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/README.md +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/__init__.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/_hook_utils.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/_shell_writes.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/commands/__init__.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/commands/common.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/commands/parser.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/docs.html +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/edits.html +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/guide/access.html +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/guide/bitbucket.html +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/guide/credentials.html +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/guide/getting-started.html +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/guide/index.html +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/guide/masking.html +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/guide/oracle.html +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/guide/shared.css +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/guide/tools.html +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/guide/workflow.html +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hook_access_guard.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hook_artifact.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hook_auto_snapshot.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hook_c3_signal.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hook_c3read.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hook_codex_lifecycle.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hook_dispatch.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hook_edit_ledger.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hook_edit_unlock.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hook_filter.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hook_ghost_files.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hook_pretool_enforce.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hook_prompt_recall.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hook_read.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hook_session_stats.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hook_terse_advisor.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_server.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/app.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/add_project.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/config_editor.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/drill_health.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/drill_panel.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/drill_tasks.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/drill_views.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/global_search.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/hub_access.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/hub_ci.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/hub_cred_audit.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/hub_credentials.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/hub_locks.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/hub_tokens.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/mcp_manager.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/modals.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/project_card.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/project_tree.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/session_drawer.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/settings_modal.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/sidebar.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/summary_bar.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/task_board.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/toasts.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/components/topbar.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui/state.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/hub_ui.html +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/mcp_proxy.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/progress.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/server.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/__init__.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/_grants.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/_helpers.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/agent.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/artifacts.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/bitbucket.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/ci.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/credentials.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/delegate.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/edit.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/edit_verify.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/edits.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/federate.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/filter.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/impact.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/jira.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/locks.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/memory.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/override.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/project.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/search.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/session.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/shell.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/shell_job.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/shell_nudge.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/shell_parsers.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/shell_render.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/status.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/tasks.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/tools/validate.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/api.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/app.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/components/access.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/components/bitbucket.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/components/chat.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/components/credentials.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/components/dashboard.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/components/edits.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/components/enforcement.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/components/instructions.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/components/jira.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/components/memory.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/components/sessions.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/components/settings.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/components/sidebar.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/components/tasks.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/icons.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/pm_shared.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/shared.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui/theme.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui.html +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui_legacy.html +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/cli/ui_nano.html +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/code_context_control.egg-info/dependency_links.txt +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/code_context_control.egg-info/entry_points.txt +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/code_context_control.egg-info/requires.txt +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/code_context_control.egg-info/top_level.txt +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/core/__init__.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/core/codex_patch.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/core/config.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/core/host.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/core/ide.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/core/mcp_toml.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/core/web_security.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/__init__.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/config.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/mcp_oracle.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/oracle_server.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/oracle_ui.html +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/__init__.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/activity_reporter.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/api_auth.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/c3_bridge.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/chat_engine.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/chat_poll.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/chat_store.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/cross_memory.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/discovery_audit.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/federated_graph.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/health_checker.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/insight_engine.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/local_session.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/memory_reader.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/memory_writer.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/mobile_api.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/project_scanner.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/review_agent.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/tool_executor.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/services/tool_registry.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/activity.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/agents.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/app.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/busy.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/chat/conversations.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/chat/input.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/chat/markdown.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/chat/send.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/chat/stream_renderer.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/chat/toolbar.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/core.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/crossgraph.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/header.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/insights.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/projects.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/qrcode.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/settings.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/suggestions.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/oracle/ui/theme_tabs.js +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/__init__.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/access_guard.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/access_telemetry.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/activity_log.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/agent_base.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/agent_locks.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/agents.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/artifact_defs.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/artifact_store.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/atomic_json.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/auto_memory.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/background_service.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/bench/__init__.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/bench/external/__init__.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/bench/external/aider_polyglot.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/bench/external/swe_bench.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/bench/map_eval.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/bench/search_eval.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/bench/shell_eval.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/benchmark_dashboard.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/bitbucket_client.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/bitbucket_credentials.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/ci_act.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/ci_cache.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/ci_expr.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/ci_failures.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/ci_github.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/ci_impact.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/ci_intel.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/ci_runner.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/ci_workflow.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/circuit_breaker.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/claude_md.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/codex_integration.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/codex_transcript.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/compressor.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/context_snapshot.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/conversation_store.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/cred_audit.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/cred_telemetry.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/credential_store.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/dir_map.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/doc_index.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/e2e_benchmark.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/e2e_evaluator.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/e2e_tasks.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/edit_ledger.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/embedding_index.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/enforcement_policy.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/error_reporting.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/git_context.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/hub_service.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/index_store.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/indexer.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/jira_client.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/jira_cloud.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/jira_credentials.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/jira_data_center.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/jira_links.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/lexical_index.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/mask_activation.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/mask_mirror.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/mask_presets.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/memory.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/memory_consolidator.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/memory_distiller.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/memory_graph.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/memory_grounder.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/memory_queue.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/memory_scorer.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/metrics.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/notifications.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/ollama_bridge.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/ollama_client.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/ollama_credentials.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/oracle_service.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/output_filter.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/override_grants.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/override_policy.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/override_requests.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/override_wake.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/project_manager.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/project_runtime.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/protocol.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/proxy_state.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/repo_map.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/repo_shape.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/reranker.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/retention.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/retrieval.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/retrieval_broker.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/router.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/runtime.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/scanner.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/session_benchmark.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/session_manager.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/session_preloader.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/shell_jobs.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/shell_output.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/subprojects.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/task_store.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/telemetry.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/text_index.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/time_tracker.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/tool_classifier.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/transcript_index.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/validation_cache.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/vector_store.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/watcher.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/services/win_subprocess.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/setup.cfg +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_access_builtin_optout.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_access_guard.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_access_guard_meta.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_access_guard_shell_project.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_access_guard_surfaces.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_access_guard_wiring.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_activity_reporter.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_agent_locks.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_aider_polyglot.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_antigravity_transition.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_artifact_store.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_artifact_tool.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_atomic_json.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_background_service.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_bitbucket_cli_smoke.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_bitbucket_client.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_bitbucket_config_fallback.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_bitbucket_credentials.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_bitbucket_tool.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_builtin_modes.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_c3_shell.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_chat_poll.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_ci_act.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_ci_cache.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_ci_expr.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_ci_impact.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_ci_intel.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_ci_runner.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_ci_workflow.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_circuit_breaker.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_claude_md_merge.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_claude_md_updater.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_cli_smoke.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_codex_mcp_transport.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_codex_native.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_compressor_large_file.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_confirm_guard.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_confirm_guard_wiring.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_cooccurrence_bounds.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_cred_audit.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_cred_telemetry.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_credential_login_kind.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_credential_store.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_credential_ui_parity.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_credentials_routes.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_credentials_tool.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_creds_cli_smoke.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_delegate_cascade.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_delegate_version_probe.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_dir_map_c3.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_e2e_benchmark.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_edit_ledger_deadline.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_edit_ledger_hook.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_edit_locking.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_edit_normalization.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_edit_verify.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_embedding_index_deadlock.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_enforcement_flip.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_enforcement_policy.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_enforcement_routes.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_env_parser.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_failed_calls_do_not_unlock.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_federated_graph.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_filter_backoff.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_ghost_files.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_ghost_generation.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_git_branch_awareness.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_hook_access_guard.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_hook_codex_compat.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_hook_dispatch.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_hook_pretool_enforce.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_hook_prompt_recall.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_hook_smoke.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_hook_state.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_hook_utf8_stdio.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_hub_credentials_route.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_hub_credentials_routes_write.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_hub_enforcement_routes.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_hub_inspect_api.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_hub_locks_routes.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_hub_oracle_service_routes.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_hub_override_routes.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_hub_server_smoke.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_hub_subproject_links.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_ide_workflow_adaptation.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_index_cap_not_hardcoded.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_init_clear_preserves_user_content.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_init_scan.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_install_mcp_entrypoint.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_jira_cli_smoke.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_jira_client.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_jira_config_fallback.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_jira_credentials.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_jira_links.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_jira_routes.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_jira_tool.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_lazy_store_init.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_map_telemetry_c0.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_mask_guard.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_mask_routes.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_mask_surfaces.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_mcp_host_guard.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_mcp_memory_timeout.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_mcp_toml.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_memory_distiller.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_memory_graph_api.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_memory_queue.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_memory_system.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_mobile_api.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_mobile_extras.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_mobile_override_routes.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_mobile_security_api.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_no_stale_model_pins.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_notification_dedup.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_notification_discipline.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_ollama_credentials.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_oracle_api_auth.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_oracle_apikey_api.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_oracle_c3_bridge.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_oracle_chat_engine.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_oracle_chat_store.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_oracle_discovery_api.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_oracle_discovery_audit.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_oracle_health_probe.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_oracle_local_auth.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_oracle_ollama_bridge.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_oracle_scanner_cache.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_oracle_security_fixes.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_oracle_session_bootstrap.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_oracle_subproject_awareness.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_oracle_ui_bundle.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_output_filter.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_override_grants.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_override_grants_mcp.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_override_requests.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_override_wake.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_permissions.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_pm_api.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_project_manager.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_project_manager_merge.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_project_tool.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_read_coercion.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_read_edit_parity.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_related_facts.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_repo_map.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_repo_shape.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_response_boilerplate.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_retention.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_review_digest.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_search_eval.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_search_p1.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_search_p2.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_search_p2b.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_search_p3.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_search_p4.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_search_p5.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_service_durability.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_session_benchmark.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_session_budget.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_shell_budget_s1.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_shell_creds.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_shell_eval.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_shell_jobs_s3.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_shell_nudge_s4.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_shell_output.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_shell_parsers_s2.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_shell_robustness.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_shell_telemetry_s0.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_shell_write_ledger.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_shell_writes.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_subproject_clear_scope.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_subproject_depth_consumers.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_subproject_exclusion.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_subproject_federation.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_subproject_linkage_api.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_subprojects.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_swe_bench.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_task_store.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_task_tool.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_time_tracker.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_token_telemetry.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_token_tracking.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_tool_registry.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_ui_jsx_syntax.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_upgrade_and_version.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_validate.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_vault_write_guard.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_version_sync.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_web_security.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tests/test_windows_reliability.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/__init__.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/backend.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/main.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/screens/__init__.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/screens/benchmark_view.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/screens/claudemd_view.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/screens/compress_view.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/screens/index_view.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/screens/init_view.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/screens/mcp_view.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/screens/optimize_view.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/screens/pipe_view.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/screens/projects_view.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/screens/search_view.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/screens/session_view.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/screens/stats.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/screens/ui_view.py +0 -0
- {code_context_control-2.123.0 → code_context_control-2.124.0}/tui/theme.tcss +0 -0
{code_context_control-2.123.0/code_context_control.egg-info → code_context_control-2.124.0}/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.124.0
|
|
4
4
|
Summary: Local MCP code-intelligence for AI coding tools: surgical search/read/edit, agent-config version history, path-level access + masking guards, and a multi-project hub.
|
|
5
5
|
Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -47,7 +47,6 @@ C3_VERSION = _read_version()
|
|
|
47
47
|
# Tool handlers
|
|
48
48
|
from cli.tools._helpers import maybe_related_facts, validate_file_path
|
|
49
49
|
from cli.tools.agent import handle_agent
|
|
50
|
-
from cli.tools.compress import handle_compress
|
|
51
50
|
from cli.tools.delegate import handle_delegate
|
|
52
51
|
from cli.tools.edit import handle_edit
|
|
53
52
|
from cli.tools.filter import handle_filter
|
|
@@ -85,7 +84,7 @@ def _build_instructions(ide_name: str) -> str:
|
|
|
85
84
|
return (
|
|
86
85
|
"C3 — local code intelligence. Route by goal:\n"
|
|
87
86
|
" FIND candidates → c3_search\n"
|
|
88
|
-
" MAP a file → c3_read(file_path) with no symbols, then READ → c3_read(symbols=…)
|
|
87
|
+
" MAP a file/dir → c3_read(file_path) with no symbols (comma paths batch), then READ → c3_read(symbols=…)\n"
|
|
89
88
|
" EDIT code → c3_edit (always; it logs to the ledger automatically)\n"
|
|
90
89
|
" VALIDATE after every edit → c3_validate\n"
|
|
91
90
|
" BLAST RADIUS before shared-symbol edits → c3_impact\n"
|
|
@@ -598,22 +597,10 @@ async def c3_read(file_path: str, symbols: Any = None, lines: Any = None,
|
|
|
598
597
|
return await asyncio.to_thread(handle_read, file_path, symbols, lines, include_docstrings, svc, finalize)
|
|
599
598
|
|
|
600
599
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
use this form for a comma-separated batch (up to 10). mode: map (default); other modes
|
|
606
|
-
are legacy."""
|
|
607
|
-
path_err = validate_file_path(file_path)
|
|
608
|
-
if path_err:
|
|
609
|
-
return f"[c3_compress:error] {path_err}"
|
|
610
|
-
svc = _svc(ctx)
|
|
611
|
-
|
|
612
|
-
def finalize(name, args, resp, summ, **kw):
|
|
613
|
-
return _finalize_response(ctx, name, args, resp, summ, **kw)
|
|
614
|
-
|
|
615
|
-
return await asyncio.to_thread(handle_compress, file_path, mode, svc, finalize, maybe_related_facts)
|
|
616
|
-
|
|
600
|
+
# c3_compress left the MCP surface in 2.124.0: c3_read(file_path) serves the
|
|
601
|
+
# same map, c3_read('a.py,b.py') the same batch, c3_read('<dir>') a directory.
|
|
602
|
+
# handle_compress stays importable for c3_project, the Oracle bridge and the
|
|
603
|
+
# CLI (docs/file-map.md § Retired modes).
|
|
617
604
|
|
|
618
605
|
@mcp.tool()
|
|
619
606
|
async def c3_validate(file_path: str, ctx: Context = None) -> str:
|
|
@@ -102,7 +102,7 @@ def _build_map(svc, rel: str) -> str:
|
|
|
102
102
|
svc.file_memory.complete_updates(completed)
|
|
103
103
|
if failed:
|
|
104
104
|
svc.file_memory.complete_updates(failed, failed=True)
|
|
105
|
-
return svc.file_memory.get_or_build_map(rel)
|
|
105
|
+
return svc.file_memory.get_or_build_map(rel, max_tokens=svc.file_memory.MAP_TOKEN_BUDGET)
|
|
106
106
|
|
|
107
107
|
|
|
108
108
|
def _compress_single(file_path: str, requested: str, note: str, svc, finalize) -> str:
|
|
@@ -197,7 +197,8 @@ def _compress_batch(paths: list, requested: str, note: str, svc, finalize) -> st
|
|
|
197
197
|
return fp, None, None, None, "not found"
|
|
198
198
|
rel = str(full.resolve().relative_to(
|
|
199
199
|
Path(svc.project_path).resolve())).replace("\\", "/")
|
|
200
|
-
res = svc.file_memory.get_or_build_map(
|
|
200
|
+
res = svc.file_memory.get_or_build_map(
|
|
201
|
+
rel, max_tokens=svc.file_memory.MAP_TOKEN_BUDGET)
|
|
201
202
|
try:
|
|
202
203
|
raw_tok = count_tokens(full.read_text(encoding="utf-8", errors="replace"))
|
|
203
204
|
map_tok = count_tokens(res)
|
|
@@ -331,7 +331,8 @@ def handle_read(file_path: str, symbols: Any = None, lines: Any = None,
|
|
|
331
331
|
|
|
332
332
|
if not ranges:
|
|
333
333
|
map_cached = not svc.file_memory.needs_update(rel_path)
|
|
334
|
-
file_map = svc.file_memory.get_or_build_map(
|
|
334
|
+
file_map = svc.file_memory.get_or_build_map(
|
|
335
|
+
rel_path, max_tokens=svc.file_memory.MAP_TOKEN_BUDGET)
|
|
335
336
|
if count_tokens(file_map) >= full_file_tokens():
|
|
336
337
|
# A map that costs more than the file is worth nothing: serve the
|
|
337
338
|
# file (docs/file-map.md § Small files).
|
|
@@ -341,6 +342,8 @@ def handle_read(file_path: str, symbols: Any = None, lines: Any = None,
|
|
|
341
342
|
+ "\n[map only — pass lines=[start,end] or symbols=[...] for exact source]"
|
|
342
343
|
+ maybe_related_facts(svc, rel_path, top_k=3, context="read"))
|
|
343
344
|
map_tok = count_tokens(resp)
|
|
345
|
+
if finalize is None:
|
|
346
|
+
return resp
|
|
344
347
|
return finalize_with_tokens(
|
|
345
348
|
finalize, svc, "c3_read", {"file": file_path},
|
|
346
349
|
resp, f"{full_file_tokens()}->{map_tok}tok",
|
{code_context_control-2.123.0 → code_context_control-2.124.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.124.0
|
|
4
4
|
Summary: Local MCP code-intelligence for AI coding tools: surgical search/read/edit, agent-config version history, path-level access + masking guards, and a multi-project hub.
|
|
5
5
|
Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -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.124.0"
|
|
8
8
|
description = "Local MCP code-intelligence for AI coding tools: surgical search/read/edit, agent-config version history, path-level access + masking guards, and a multi-project hub."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -56,7 +56,7 @@ _PY_DEF = re.compile(r"^(?:async\s+)?def\s+[\w.]+\s*\((?P<params>.*)\)\s*(?:->\s
|
|
|
56
56
|
_PY_CLASS = re.compile(r"^class\s+\w+\s*(?:\((?P<bases>.*)\))?\s*:?$")
|
|
57
57
|
_GO_FUNC = re.compile(r"^func\s+(?:\((?P<recv>[^)]*)\)\s*)?\w+\s*\((?P<params>.*?)\)\s*(?P<ret>[^{]*?)\s*\{?$")
|
|
58
58
|
_RS_FN = re.compile(r"^(?:pub(?:\([^)]*\))?\s+)?(?:async\s+|const\s+|unsafe\s+)*fn\s+\w+(?:<[^>]*>)?\s*\((?P<params>.*)\)\s*(?:->\s*(?P<ret>[^{]+?))?\s*(?:where\b.*)?\{?$")
|
|
59
|
-
_JS_FUNC = re.compile(r"^(?:export\s+)?(?:default\s+)?(?:async\s+)?function\s*\*?\s
|
|
59
|
+
_JS_FUNC = re.compile(r"^(?:export\s+)?(?:default\s+)?(?:async\s+)?function\s*\*?\s*[\w$]*\s*(?:<[^>]*>)?\s*\((?P<params>.*)\)\s*(?::\s*(?P<ret>[^{]+?))?\s*\{?\s*$")
|
|
60
60
|
_JS_ARROW = re.compile(r"^(?:export\s+)?(?:const|let|var)\s+\w+\s*(?::[^=]+)?=\s*(?:async\s+)?\((?P<params>.*)\)\s*(?::\s*(?P<ret>[^=]+?))?\s*=>")
|
|
61
61
|
_JS_ARROW1 = re.compile(r"^(?:export\s+)?(?:const|let|var)\s+\w+\s*=\s*(?:async\s+)?(?P<params>\w+)\s*=>")
|
|
62
62
|
_JS_CLASS = re.compile(r"^(?:export\s+)?(?:default\s+)?(?:abstract\s+)?class\s+\w+(?:<[^>]*>)?\s*(?:extends\s+(?P<base>[\w.<>, ]+?))?\s*(?:implements\s+(?P<impl>[\w.<>, ]+?))?\s*\{?$")
|
|
@@ -67,6 +67,40 @@ def _norm(text: str) -> str:
|
|
|
67
67
|
return _WS.sub(" ", str(text or "")).strip()
|
|
68
68
|
|
|
69
69
|
|
|
70
|
+
def _declaration_head(sig: str) -> str:
|
|
71
|
+
"""Cut a brace-language signature after its parameter list and return
|
|
72
|
+
type: the text up to the body's `{`, an arrow, or a `;`. Parentheses
|
|
73
|
+
are depth-matched, so a 400-char minified chunk holding several
|
|
74
|
+
declarations yields only the first one's head."""
|
|
75
|
+
i = sig.find("(")
|
|
76
|
+
if i < 0:
|
|
77
|
+
j = sig.find("{")
|
|
78
|
+
return sig if j < 0 else sig[:j].rstrip()
|
|
79
|
+
depth = 0
|
|
80
|
+
close = -1
|
|
81
|
+
for k in range(i, len(sig)):
|
|
82
|
+
ch = sig[k]
|
|
83
|
+
if ch == "(":
|
|
84
|
+
depth += 1
|
|
85
|
+
elif ch == ")":
|
|
86
|
+
depth -= 1
|
|
87
|
+
if depth == 0:
|
|
88
|
+
close = k
|
|
89
|
+
break
|
|
90
|
+
if close < 0:
|
|
91
|
+
return sig
|
|
92
|
+
rest = sig[close + 1:]
|
|
93
|
+
cut = len(rest)
|
|
94
|
+
for stop in ("{", ";"):
|
|
95
|
+
j = rest.find(stop)
|
|
96
|
+
if 0 <= j < cut:
|
|
97
|
+
cut = j
|
|
98
|
+
j = rest.find("=>")
|
|
99
|
+
if 0 <= j < cut:
|
|
100
|
+
cut = j + 2 # keep the arrow: the arrow-function grammar needs it
|
|
101
|
+
return (sig[:close + 1] + rest[:cut]).rstrip()
|
|
102
|
+
|
|
103
|
+
|
|
70
104
|
def parse_signature(signature: str, language: str) -> dict:
|
|
71
105
|
"""Split a raw signature into params / ret / receiver / bases.
|
|
72
106
|
|
|
@@ -78,6 +112,10 @@ def parse_signature(signature: str, language: str) -> dict:
|
|
|
78
112
|
if not sig:
|
|
79
113
|
return {}
|
|
80
114
|
lang = (language or "").lower()
|
|
115
|
+
if lang in ("javascript", "typescript", "go", "rust") and not sig.lstrip().startswith(
|
|
116
|
+
("class ", "export class", "export default class", "abstract class",
|
|
117
|
+
"struct ", "pub struct", "enum ", "pub enum", "trait ", "pub trait", "impl ", "type ")):
|
|
118
|
+
sig = _declaration_head(sig)
|
|
81
119
|
out: dict = {}
|
|
82
120
|
if lang == "python":
|
|
83
121
|
m = _PY_DEF.match(sig)
|
|
@@ -290,6 +328,25 @@ def render_map(record: dict, *, include_docs: bool = False,
|
|
|
290
328
|
header = f"# {path} ({total_lines}L {language})".rstrip()
|
|
291
329
|
body: list = []
|
|
292
330
|
|
|
331
|
+
shape = record.get("shape") or {}
|
|
332
|
+
parser = str(record.get("parser") or "")
|
|
333
|
+
minified = bool(shape.get("minified"))
|
|
334
|
+
if parser == "skipped" or shape.get("oversized"):
|
|
335
|
+
body.append(f"[map:not mapped] {shape.get('bytes', 0):,} bytes on {total_lines} lines, "
|
|
336
|
+
f"longest line {shape.get('longest_line', 0):,} chars — read with lines=[a,b]")
|
|
337
|
+
return "\n".join([header] + body)
|
|
338
|
+
if parser == "lexical":
|
|
339
|
+
body.append("[map:lexical-fallback] the parse overran its deadline; "
|
|
340
|
+
"symbols come from a line scan and may be incomplete")
|
|
341
|
+
if minified:
|
|
342
|
+
# A minified bundle's `var` soup is not structure; named declarations are.
|
|
343
|
+
soup = [s for s in sections if s.get("type") in ("variable", "constant")]
|
|
344
|
+
sections = [s for s in sections if s.get("type") not in ("variable", "constant")]
|
|
345
|
+
body.append(f"[map:minified] longest line {shape.get('longest_line', 0):,} chars; "
|
|
346
|
+
f"{len(soup)} var bindings omitted")
|
|
347
|
+
elif shape.get("generated"):
|
|
348
|
+
body.append("[map:generated] the file says it is generated")
|
|
349
|
+
|
|
293
350
|
imports = [s for s in sections if s.get("type") == "import"]
|
|
294
351
|
others = [s for s in sections if s.get("type") != "import"]
|
|
295
352
|
if imports:
|
|
@@ -329,7 +386,9 @@ def render_map(record: dict, *, include_docs: bool = False,
|
|
|
329
386
|
while kept and count_tokens("\n".join([header] + kept)) > max_tokens:
|
|
330
387
|
kept.pop()
|
|
331
388
|
dropped = len(body) - len(kept)
|
|
332
|
-
text = "\n".join([header] + kept + [
|
|
389
|
+
text = "\n".join([header] + kept + [
|
|
390
|
+
f"… {dropped} more symbols (map budget {max_tokens} tokens; "
|
|
391
|
+
f"pass symbols=[…] or lines=[a,b] for the part you need)"])
|
|
333
392
|
return text
|
|
334
393
|
|
|
335
394
|
|
|
@@ -195,6 +195,10 @@ class FileMemoryStore:
|
|
|
195
195
|
"parser": parser,
|
|
196
196
|
"sections": sections,
|
|
197
197
|
}
|
|
198
|
+
shape = getattr(self, "_last_shape", None) or {}
|
|
199
|
+
if shape.get("minified") or shape.get("generated") or shape.get("oversized"):
|
|
200
|
+
record["shape"] = {k: shape[k] for k in ("minified", "generated", "oversized",
|
|
201
|
+
"longest_line", "bytes") if k in shape}
|
|
198
202
|
|
|
199
203
|
self._save(rel_path, record)
|
|
200
204
|
self._cache_map(rel_path, record)
|
|
@@ -213,17 +217,31 @@ class FileMemoryStore:
|
|
|
213
217
|
return None
|
|
214
218
|
return self._cache_map(rel_path, record)
|
|
215
219
|
|
|
216
|
-
|
|
217
|
-
|
|
220
|
+
#: Default token budget for a map served to the model (C4, 2.124.0). A
|
|
221
|
+
#: 250 KB generated module renders 117k tokens unbounded; the MCP
|
|
222
|
+
#: response cap is 25k. Over budget the map keeps its first lines and
|
|
223
|
+
#: says how many symbols it left out.
|
|
224
|
+
MAP_TOKEN_BUDGET = 6000
|
|
225
|
+
|
|
226
|
+
def get_or_build_map(self, rel_path: str, max_tokens: Optional[int] = None) -> str:
|
|
227
|
+
"""Get map if cached, otherwise build it on-demand.
|
|
228
|
+
|
|
229
|
+
`max_tokens` renders a budgeted map (never cached); None serves the
|
|
230
|
+
cached full map.
|
|
231
|
+
"""
|
|
218
232
|
record = self.get(rel_path)
|
|
219
233
|
|
|
220
234
|
# Check staleness
|
|
221
235
|
if record and not self.needs_update(rel_path):
|
|
236
|
+
if max_tokens:
|
|
237
|
+
return render_map(record, max_tokens=max_tokens)
|
|
222
238
|
return self._cache_map(rel_path, record)
|
|
223
239
|
|
|
224
240
|
# Build fresh
|
|
225
241
|
updated = self.update(rel_path)
|
|
226
242
|
if updated:
|
|
243
|
+
if max_tokens:
|
|
244
|
+
return render_map(updated, max_tokens=max_tokens)
|
|
227
245
|
return self._cache_map(rel_path, updated)
|
|
228
246
|
|
|
229
247
|
return f"[file_map] Could not build map for {rel_path} — file not found or unreadable."
|
|
@@ -556,6 +574,39 @@ class FileMemoryStore:
|
|
|
556
574
|
PARSER_TREE_SITTER = "tree_sitter"
|
|
557
575
|
PARSER_REGEX = "regex"
|
|
558
576
|
PARSER_GENERIC = "generic"
|
|
577
|
+
PARSER_LEXICAL = "lexical" # deadline or parse failure -> regex scan
|
|
578
|
+
PARSER_SKIPPED = "skipped" # minified / oversized: not parsed
|
|
579
|
+
|
|
580
|
+
#: Bounds for large files (C4, 2.124.0). A parse that overruns the
|
|
581
|
+
#: deadline is abandoned for the regex scan; a minified or oversized
|
|
582
|
+
#: file is not parsed at all.
|
|
583
|
+
PARSE_DEADLINE_S = 1.5
|
|
584
|
+
MAX_PARSE_BYTES = 2 * 1024 * 1024
|
|
585
|
+
MINIFIED_LINE_CHARS = 2000
|
|
586
|
+
MINIFIED_AVG_LINE_CHARS = 400
|
|
587
|
+
GENERATED_MARKERS = ("do not edit", "autogenerated", "auto-generated",
|
|
588
|
+
"@generated", "generated by", "generated file")
|
|
589
|
+
|
|
590
|
+
@classmethod
|
|
591
|
+
def classify_large(cls, content: str) -> dict:
|
|
592
|
+
"""Cheap shape facts before any parse: {minified, generated, longest_line, oversized}."""
|
|
593
|
+
size = len(content)
|
|
594
|
+
longest = 0
|
|
595
|
+
n_lines = 0
|
|
596
|
+
for line in content.split("\n"):
|
|
597
|
+
n_lines += 1
|
|
598
|
+
if len(line) > longest:
|
|
599
|
+
longest = len(line)
|
|
600
|
+
avg = size / max(1, n_lines)
|
|
601
|
+
head = "\n".join(content.split("\n", 6)[:6]).lower()
|
|
602
|
+
return {
|
|
603
|
+
"bytes": size,
|
|
604
|
+
"lines": n_lines,
|
|
605
|
+
"longest_line": longest,
|
|
606
|
+
"minified": longest >= cls.MINIFIED_LINE_CHARS and avg >= cls.MINIFIED_AVG_LINE_CHARS,
|
|
607
|
+
"generated": any(m in head for m in cls.GENERATED_MARKERS),
|
|
608
|
+
"oversized": size >= cls.MAX_PARSE_BYTES,
|
|
609
|
+
}
|
|
559
610
|
|
|
560
611
|
def _extract_sections(self, filepath: Path, content: str) -> list:
|
|
561
612
|
"""Extract structural sections with line ranges from source code."""
|
|
@@ -570,18 +621,56 @@ class FileMemoryStore:
|
|
|
570
621
|
older single-value call keeps working.
|
|
571
622
|
"""
|
|
572
623
|
ext = filepath.suffix.lower()
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
624
|
+
shape = self.classify_large(content)
|
|
625
|
+
self._last_shape = shape
|
|
626
|
+
if shape["oversized"]:
|
|
627
|
+
# Not worth a parse: the map says so and stops (docs/file-map.md
|
|
628
|
+
# § Large files). Minified files ARE parsed — bounded signature
|
|
629
|
+
# capture made that cheap — and the renderer drops their
|
|
630
|
+
# binding soup.
|
|
631
|
+
return [{"type": "content", "name": "(not mapped)",
|
|
632
|
+
"line_start": 1, "line_end": max(1, shape["lines"]),
|
|
633
|
+
"note": "oversized"}], self.PARSER_SKIPPED
|
|
578
634
|
|
|
579
635
|
lines = content.splitlines()
|
|
580
636
|
patterns = STRUCTURE_PATTERNS.get(ext, {})
|
|
581
637
|
|
|
638
|
+
# Try AST parser first, under a deadline. tree-sitter 0.26 has no
|
|
639
|
+
# parse timeout, so the parse runs on a worker and is abandoned
|
|
640
|
+
# (not killed) when it overruns; the regex scan answers instead.
|
|
641
|
+
ast_sections, overran = self._extract_ast_with_deadline(content, ext)
|
|
642
|
+
if ast_sections is not None:
|
|
643
|
+
return ast_sections, self.PARSER_TREE_SITTER
|
|
644
|
+
if overran and patterns:
|
|
645
|
+
secs, _ = self._extract_regex_sections(lines, ext, patterns)
|
|
646
|
+
return secs, self.PARSER_LEXICAL
|
|
647
|
+
|
|
582
648
|
if not patterns:
|
|
583
649
|
return self._extract_generic_sections(lines), self.PARSER_GENERIC
|
|
584
650
|
|
|
651
|
+
secs, _ = self._extract_regex_sections(lines, ext, patterns)
|
|
652
|
+
return secs, self.PARSER_REGEX
|
|
653
|
+
|
|
654
|
+
def _extract_ast_with_deadline(self, content: str, ext: str):
|
|
655
|
+
"""(sections | None, overran). Runs extract_sections_ast on a worker
|
|
656
|
+
thread bounded by PARSE_DEADLINE_S; the thread is daemonic so an
|
|
657
|
+
abandoned parse cannot hold the process open."""
|
|
658
|
+
import concurrent.futures as _cf
|
|
659
|
+
pool = _cf.ThreadPoolExecutor(max_workers=1, thread_name_prefix="c3-parse")
|
|
660
|
+
try:
|
|
661
|
+
fut = pool.submit(extract_sections_ast, content, ext)
|
|
662
|
+
try:
|
|
663
|
+
return fut.result(timeout=self.PARSE_DEADLINE_S), False
|
|
664
|
+
except _cf.TimeoutError:
|
|
665
|
+
self._record_diag("parse_deadline", ext, f"{len(content)} bytes")
|
|
666
|
+
return None, True
|
|
667
|
+
except Exception:
|
|
668
|
+
return None, True
|
|
669
|
+
finally:
|
|
670
|
+
pool.shutdown(wait=False)
|
|
671
|
+
|
|
672
|
+
def _extract_regex_sections(self, lines: list, ext: str, patterns: dict) -> tuple:
|
|
673
|
+
"""The regex/indentation extractor (the pre-tree-sitter path)."""
|
|
585
674
|
sections = []
|
|
586
675
|
i = 0
|
|
587
676
|
current_class = None # Track current class for method nesting
|
|
@@ -674,6 +763,14 @@ class FileMemoryStore:
|
|
|
674
763
|
|
|
675
764
|
base_indent = len(lines[start]) - len(lines[start].lstrip())
|
|
676
765
|
|
|
766
|
+
def _last_code_line(upto: int) -> int:
|
|
767
|
+
# 1-indexed line number of the last non-blank line before `upto`
|
|
768
|
+
# (0-indexed exclusive): blank lines belong to nobody.
|
|
769
|
+
j = upto
|
|
770
|
+
while j > start + 1 and not lines[j - 1].strip():
|
|
771
|
+
j -= 1
|
|
772
|
+
return j
|
|
773
|
+
|
|
677
774
|
for i in range(start + 1, len(lines)):
|
|
678
775
|
line = lines[i]
|
|
679
776
|
stripped = line.strip()
|
|
@@ -681,11 +778,11 @@ class FileMemoryStore:
|
|
|
681
778
|
continue
|
|
682
779
|
current_indent = len(line) - len(line.lstrip())
|
|
683
780
|
if current_indent <= base_indent:
|
|
684
|
-
return i # 1-indexed
|
|
781
|
+
return _last_code_line(i) # 1-indexed
|
|
685
782
|
# Check for decorators at same level (next function)
|
|
686
783
|
if current_indent == base_indent and stripped.startswith('@'):
|
|
687
|
-
return i
|
|
688
|
-
return len(lines)
|
|
784
|
+
return _last_code_line(i)
|
|
785
|
+
return _last_code_line(len(lines))
|
|
689
786
|
|
|
690
787
|
def _find_brace_block_end(self, lines: list, start: int) -> int:
|
|
691
788
|
"""Find end of a brace-delimited block.
|
|
@@ -57,6 +57,28 @@ PARSER_VERSION = "4" # 4: records carry parser attribution, no summary, posix p
|
|
|
57
57
|
|
|
58
58
|
_WS_RUN = re.compile(r"\s+")
|
|
59
59
|
|
|
60
|
+
#: A signature is never longer than this. A 680 KB minified line used to be
|
|
61
|
+
#: copied into every one of its 20,000 symbols (176 s, an 11 MB record).
|
|
62
|
+
SIGNATURE_MAX_CHARS = 400
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _sig_line(lines: List[str], node) -> str:
|
|
66
|
+
"""The node's first line from its start column, capped at SIGNATURE_MAX_CHARS."""
|
|
67
|
+
row, col = node.start_point
|
|
68
|
+
line = lines[row] if row < len(lines) else ""
|
|
69
|
+
chunk = line[col:col + SIGNATURE_MAX_CHARS] if len(line) - col > SIGNATURE_MAX_CHARS else line[col:]
|
|
70
|
+
if not chunk.strip():
|
|
71
|
+
chunk = line[:SIGNATURE_MAX_CHARS]
|
|
72
|
+
return chunk.strip()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _sig_span(lines: List[str], start_row: int, end_row: int) -> str:
|
|
76
|
+
"""Lines start_row..end_row joined, capped at SIGNATURE_MAX_CHARS."""
|
|
77
|
+
text = "\n".join(lines[start_row:end_row + 1]).strip()
|
|
78
|
+
if len(text) > SIGNATURE_MAX_CHARS:
|
|
79
|
+
text = text[:SIGNATURE_MAX_CHARS].rstrip() + "…"
|
|
80
|
+
return text
|
|
81
|
+
|
|
60
82
|
|
|
61
83
|
def _node_text(node, lines: List[str]) -> str:
|
|
62
84
|
"""The source text of a node, joined across lines, whitespace-normalized."""
|
|
@@ -157,7 +179,7 @@ def _walk_python(node, lines: List[str], sections: List[Dict[str, Any]], parent_
|
|
|
157
179
|
# Find the colon
|
|
158
180
|
colon_node = next((c for c in child.children if c.type == ':'), None)
|
|
159
181
|
sig_end = colon_node.end_point[0] if colon_node else sig_start
|
|
160
|
-
signature =
|
|
182
|
+
signature = _sig_span(lines, sig_start, sig_end)
|
|
161
183
|
|
|
162
184
|
section = {
|
|
163
185
|
"type": "class",
|
|
@@ -186,7 +208,7 @@ def _walk_python(node, lines: List[str], sections: List[Dict[str, Any]], parent_
|
|
|
186
208
|
sig_start = child.start_point[0]
|
|
187
209
|
colon_node = next((c for c in child.children if c.type == ':'), None)
|
|
188
210
|
sig_end = colon_node.end_point[0] if colon_node else sig_start
|
|
189
|
-
signature =
|
|
211
|
+
signature = _sig_span(lines, sig_start, sig_end)
|
|
190
212
|
|
|
191
213
|
is_async = any(c.type == 'async' for c in child.children)
|
|
192
214
|
|
|
@@ -232,7 +254,7 @@ def _walk_python(node, lines: List[str], sections: List[Dict[str, Any]], parent_
|
|
|
232
254
|
"name": name,
|
|
233
255
|
"line_start": child.start_point[0] + 1,
|
|
234
256
|
"line_end": child.end_point[0] + 1,
|
|
235
|
-
"signature": lines
|
|
257
|
+
"signature": _sig_line(lines, child)
|
|
236
258
|
})
|
|
237
259
|
|
|
238
260
|
elif child.type == 'comment':
|
|
@@ -249,10 +271,10 @@ def _walk_python(node, lines: List[str], sections: List[Dict[str, Any]], parent_
|
|
|
249
271
|
elif child.type in ('import_statement', 'import_from_statement'):
|
|
250
272
|
section = {
|
|
251
273
|
"type": "import",
|
|
252
|
-
"name": lines
|
|
274
|
+
"name": _sig_line(lines, child),
|
|
253
275
|
"line_start": child.start_point[0] + 1,
|
|
254
276
|
"line_end": child.end_point[0] + 1,
|
|
255
|
-
"signature": lines
|
|
277
|
+
"signature": _sig_line(lines, child)
|
|
256
278
|
}
|
|
257
279
|
if not parent_section:
|
|
258
280
|
sections.append(section)
|
|
@@ -294,7 +316,7 @@ def _walk_js_ts(node, lines: List[str], sections: List[Dict[str, Any]], parent_s
|
|
|
294
316
|
name = lines[name_node.start_point[0]][name_node.start_point[1]:name_node.end_point[1]] if name_node else 'Unknown'
|
|
295
317
|
|
|
296
318
|
# Simple signature heuristic: first line
|
|
297
|
-
signature = lines
|
|
319
|
+
signature = _sig_line(lines, child)
|
|
298
320
|
|
|
299
321
|
t = child.type.split('_')[0]
|
|
300
322
|
section = {
|
|
@@ -321,7 +343,7 @@ def _walk_js_ts(node, lines: List[str], sections: List[Dict[str, Any]], parent_s
|
|
|
321
343
|
name_node = next((c for c in child.children if c.type in ('property_identifier', 'identifier', 'private_property_identifier')), None)
|
|
322
344
|
name = lines[name_node.start_point[0]][name_node.start_point[1]:name_node.end_point[1]] if name_node else 'Unknown'
|
|
323
345
|
|
|
324
|
-
signature = lines
|
|
346
|
+
signature = _sig_line(lines, child)
|
|
325
347
|
|
|
326
348
|
is_async = any(c.type == 'async' for c in child.children)
|
|
327
349
|
|
|
@@ -373,7 +395,7 @@ def _walk_js_ts(node, lines: List[str], sections: List[Dict[str, Any]], parent_s
|
|
|
373
395
|
"name": name,
|
|
374
396
|
"line_start": child.start_point[0] + 1,
|
|
375
397
|
"line_end": child.end_point[0] + 1,
|
|
376
|
-
"signature": lines
|
|
398
|
+
"signature": _sig_line(lines, child)
|
|
377
399
|
}
|
|
378
400
|
if is_async: section["async"] = True
|
|
379
401
|
doc = _extract_docstring_js(child, lines)
|
|
@@ -391,7 +413,7 @@ def _walk_js_ts(node, lines: List[str], sections: List[Dict[str, Any]], parent_s
|
|
|
391
413
|
"name": name,
|
|
392
414
|
"line_start": child.start_point[0] + 1,
|
|
393
415
|
"line_end": child.end_point[0] + 1,
|
|
394
|
-
"signature": lines
|
|
416
|
+
"signature": _sig_line(lines, child)
|
|
395
417
|
})
|
|
396
418
|
|
|
397
419
|
elif child.type == 'comment':
|
|
@@ -408,10 +430,10 @@ def _walk_js_ts(node, lines: List[str], sections: List[Dict[str, Any]], parent_s
|
|
|
408
430
|
elif child.type == 'import_statement':
|
|
409
431
|
section = {
|
|
410
432
|
"type": "import",
|
|
411
|
-
"name": lines
|
|
433
|
+
"name": _sig_line(lines, child),
|
|
412
434
|
"line_start": child.start_point[0] + 1,
|
|
413
435
|
"line_end": child.end_point[0] + 1,
|
|
414
|
-
"signature": lines
|
|
436
|
+
"signature": _sig_line(lines, child)
|
|
415
437
|
}
|
|
416
438
|
if not parent_section:
|
|
417
439
|
sections.append(section)
|
|
@@ -446,7 +468,7 @@ def _walk_html(node, lines: List[str], sections: List[Dict[str, Any]]):
|
|
|
446
468
|
"name": f"{tag_name}: {text_content.strip()[:60]}",
|
|
447
469
|
"line_start": child.start_point[0] + 1,
|
|
448
470
|
"line_end": child.end_point[0] + 1,
|
|
449
|
-
"signature": lines
|
|
471
|
+
"signature": _sig_line(lines, child)
|
|
450
472
|
})
|
|
451
473
|
|
|
452
474
|
# Check for ID attribute
|
|
@@ -474,7 +496,7 @@ def _walk_html(node, lines: List[str], sections: List[Dict[str, Any]]):
|
|
|
474
496
|
"tag": tag_name,
|
|
475
497
|
"line_start": child.start_point[0] + 1,
|
|
476
498
|
"line_end": child.end_point[0] + 1,
|
|
477
|
-
"signature": lines
|
|
499
|
+
"signature": _sig_line(lines, child)
|
|
478
500
|
})
|
|
479
501
|
|
|
480
502
|
# Recurse into element children
|
|
@@ -504,7 +526,7 @@ def _walk_markdown(node, lines: List[str], sections: List[Dict[str, Any]]):
|
|
|
504
526
|
"name": f"{level}: {content_text.strip()[:60]}",
|
|
505
527
|
"line_start": child.start_point[0] + 1,
|
|
506
528
|
"line_end": child.end_point[0] + 1,
|
|
507
|
-
"signature": lines
|
|
529
|
+
"signature": _sig_line(lines, child)
|
|
508
530
|
})
|
|
509
531
|
|
|
510
532
|
# Recurse if needed (atx headings are top level usually, but just in case)
|
|
@@ -582,7 +604,7 @@ def _walk_go(node, lines: List[str], sections: List[Dict[str, Any]]):
|
|
|
582
604
|
name_node = next((c for c in child.children if c.type == 'identifier' or c.type == 'field_identifier'), None)
|
|
583
605
|
name = lines[name_node.start_point[0]][name_node.start_point[1]:name_node.end_point[1]] if name_node else 'Unknown'
|
|
584
606
|
|
|
585
|
-
signature = lines
|
|
607
|
+
signature = _sig_line(lines, child)
|
|
586
608
|
|
|
587
609
|
receiver = ""
|
|
588
610
|
if child.type == 'method_declaration':
|
|
@@ -609,7 +631,7 @@ def _walk_go(node, lines: List[str], sections: List[Dict[str, Any]]):
|
|
|
609
631
|
"name": _node_text(ident, lines),
|
|
610
632
|
"line_start": spec.start_point[0] + 1,
|
|
611
633
|
"line_end": spec.end_point[0] + 1,
|
|
612
|
-
"signature": lines
|
|
634
|
+
"signature": _sig_line(lines, spec)
|
|
613
635
|
})
|
|
614
636
|
elif child.type == 'type_declaration':
|
|
615
637
|
# Drill into type specs
|
|
@@ -625,7 +647,7 @@ def _walk_go(node, lines: List[str], sections: List[Dict[str, Any]]):
|
|
|
625
647
|
"name": name,
|
|
626
648
|
"line_start": child.start_point[0] + 1,
|
|
627
649
|
"line_end": child.end_point[0] + 1,
|
|
628
|
-
"signature": lines
|
|
650
|
+
"signature": _sig_line(lines, child)
|
|
629
651
|
})
|
|
630
652
|
_walk_go(child, lines, sections)
|
|
631
653
|
|
|
@@ -656,9 +678,9 @@ def _walk_rust(node, lines: List[str], sections: List[Dict[str, Any]]):
|
|
|
656
678
|
sig.append(ln)
|
|
657
679
|
if '{' in ln or ln.rstrip().endswith(';'):
|
|
658
680
|
break
|
|
659
|
-
signature = " ".join(x.strip() for x in sig)
|
|
681
|
+
signature = " ".join(x.strip() for x in sig)[:SIGNATURE_MAX_CHARS]
|
|
660
682
|
else:
|
|
661
|
-
signature = lines
|
|
683
|
+
signature = _sig_line(lines, child)
|
|
662
684
|
sections.append({
|
|
663
685
|
"type": stype,
|
|
664
686
|
"name": name,
|
|
@@ -122,8 +122,10 @@ class TestRenderGrammar(unittest.TestCase):
|
|
|
122
122
|
store, rec = self._record(tmp)
|
|
123
123
|
full = render_map(rec)
|
|
124
124
|
short = render_map(rec, max_tokens=40)
|
|
125
|
-
|
|
126
|
-
self.assertTrue(
|
|
125
|
+
note = short.splitlines()[-1]
|
|
126
|
+
self.assertTrue(note.startswith("… "))
|
|
127
|
+
self.assertIn("more symbols", note)
|
|
128
|
+
self.assertLessEqual(count_tokens(short), 40 + count_tokens(note))
|
|
127
129
|
self.assertTrue(short.startswith(full.splitlines()[0]))
|
|
128
130
|
self.assertLess(len(short.splitlines()), len(full.splitlines()))
|
|
129
131
|
|