code-context-control 2.128.1__tar.gz → 2.129.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.128.1 → code_context_control-2.129.0}/PKG-INFO +1 -1
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/c3.py +1 -1
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/mcp_server.py +4 -1
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/_helpers.py +34 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/ci.py +9 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/compress.py +50 -18
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/read.py +88 -24
- {code_context_control-2.128.1 → code_context_control-2.129.0}/code_context_control.egg-info/PKG-INFO +1 -1
- {code_context_control-2.128.1 → code_context_control-2.129.0}/code_context_control.egg-info/SOURCES.txt +1 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/pyproject.toml +1 -1
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/ci_act.py +60 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/ci_runner.py +11 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/dir_map.py +42 -12
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/file_memory.py +49 -10
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_ci_act.py +78 -0
- code_context_control-2.129.0/tests/test_read_outside_root.py +289 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/LICENSE +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/README.md +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/__init__.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/_hook_utils.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/_shell_writes.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/commands/__init__.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/commands/common.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/commands/parser.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/docs.html +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/edits.html +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/guide/access.html +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/guide/bitbucket.html +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/guide/credentials.html +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/guide/getting-started.html +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/guide/index.html +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/guide/masking.html +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/guide/oracle.html +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/guide/shared.css +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/guide/tools.html +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/guide/workflow.html +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_access_guard.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_artifact.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_auto_snapshot.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_c3_signal.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_c3read.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_codex_lifecycle.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_dispatch.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_edit_ledger.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_edit_unlock.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_filter.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_ghost_files.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_pretool_enforce.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_prompt_recall.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_read.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_session_end.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_session_open.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_session_stats.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hook_terse_advisor.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_server.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/app.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/add_project.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/config_editor.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/drill_health.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/drill_panel.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/drill_tasks.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/drill_views.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/global_search.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/hub_access.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/hub_ci.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/hub_cred_audit.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/hub_credentials.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/hub_locks.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/hub_tokens.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/mcp_manager.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/modals.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/project_card.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/project_tree.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/session_drawer.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/settings_modal.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/sidebar.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/summary_bar.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/task_board.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/toasts.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/components/topbar.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui/state.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/hub_ui.html +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/mcp_proxy.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/progress.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/server.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/__init__.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/_grants.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/agent.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/artifacts.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/bitbucket.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/credentials.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/delegate.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/edit.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/edit_verify.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/edits.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/federate.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/filter.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/impact.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/jira.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/locks.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/memory.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/override.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/project.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/search.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/session.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/shell.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/shell_job.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/shell_nudge.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/shell_parsers.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/shell_render.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/status.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/tasks.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/tools/validate.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/api.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/app.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/components/access.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/components/bitbucket.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/components/chat.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/components/credentials.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/components/dashboard.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/components/edits.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/components/enforcement.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/components/instructions.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/components/jira.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/components/memory.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/components/sessions.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/components/settings.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/components/sidebar.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/components/tasks.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/icons.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/pm_shared.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/shared.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui/theme.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui.html +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui_legacy.html +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/cli/ui_nano.html +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/code_context_control.egg-info/dependency_links.txt +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/code_context_control.egg-info/entry_points.txt +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/code_context_control.egg-info/requires.txt +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/code_context_control.egg-info/top_level.txt +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/core/__init__.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/core/codex_patch.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/core/config.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/core/host.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/core/ide.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/core/mcp_toml.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/core/web_security.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/__init__.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/config.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/listeners.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/mcp_oracle.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/oracle_server.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/oracle_ui.html +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/__init__.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/activity_reporter.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/api_auth.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/c3_bridge.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/chat_engine.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/chat_poll.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/chat_store.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/client_tokens.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/cross_memory.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/discovery_audit.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/federated_graph.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/health_checker.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/insight_engine.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/local_session.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/memory_reader.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/memory_writer.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/mobile_api.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/project_scanner.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/review_agent.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/tool_executor.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/services/tool_registry.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/activity.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/agents.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/app.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/busy.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/chat/conversations.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/chat/input.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/chat/markdown.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/chat/send.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/chat/stream_renderer.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/chat/toolbar.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/core.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/crossgraph.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/header.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/insights.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/projects.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/qrcode.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/settings.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/suggestions.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/oracle/ui/theme_tabs.js +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/__init__.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/access_guard.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/access_telemetry.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/activity_log.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/agent_base.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/agent_locks.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/agents.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/artifact_defs.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/artifact_store.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/atomic_json.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/auto_memory.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/background_service.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/bench/__init__.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/bench/external/__init__.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/bench/external/aider_polyglot.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/bench/external/swe_bench.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/bench/map_eval.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/bench/search_eval.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/bench/shell_eval.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/benchmark_dashboard.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/bitbucket_client.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/bitbucket_credentials.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/ci_cache.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/ci_expr.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/ci_failures.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/ci_github.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/ci_impact.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/ci_intel.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/ci_workflow.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/circuit_breaker.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/claude_md.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/codex_integration.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/codex_transcript.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/compressor.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/context_snapshot.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/conversation_store.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/cred_audit.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/cred_telemetry.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/credential_store.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/doc_index.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/e2e_benchmark.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/e2e_evaluator.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/e2e_tasks.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/edit_ledger.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/embedding_index.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/enforcement_policy.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/error_reporting.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/file_map.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/git_context.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/host_sessions.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/hub_service.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/index_store.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/indexer.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/jira_client.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/jira_cloud.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/jira_credentials.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/jira_data_center.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/jira_links.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/lexical_index.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/mask_activation.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/mask_mirror.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/mask_presets.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/memory.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/memory_consolidator.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/memory_distiller.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/memory_graph.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/memory_grounder.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/memory_queue.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/memory_scorer.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/metrics.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/notifications.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/ollama_bridge.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/ollama_client.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/ollama_credentials.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/oracle_service.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/output_filter.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/override_costs.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/override_grants.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/override_policy.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/override_requests.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/override_wake.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/parser.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/project_manager.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/project_runtime.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/protocol.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/proxy_state.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/repo_map.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/repo_shape.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/reranker.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/retention.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/retrieval.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/retrieval_broker.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/router.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/runtime.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/scanner.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/session_benchmark.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/session_live.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/session_manager.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/session_preloader.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/shell_jobs.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/shell_output.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/subprojects.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/task_store.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/telemetry.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/text_index.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/time_tracker.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/tool_classifier.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/transcript_index.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/validation_cache.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/vector_store.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/watcher.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/services/win_subprocess.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/setup.cfg +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_access_builtin_optout.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_access_guard.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_access_guard_meta.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_access_guard_shell_project.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_access_guard_surfaces.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_access_guard_wiring.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_activity_log_find_last.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_activity_reporter.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_agent_locks.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_aider_polyglot.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_antigravity_transition.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_artifact_store.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_artifact_tool.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_atomic_json.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_background_service.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_bitbucket_cli_smoke.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_bitbucket_client.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_bitbucket_config_fallback.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_bitbucket_credentials.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_bitbucket_tool.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_builtin_modes.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_c3_shell.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_chat_poll.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_ci_cache.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_ci_expr.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_ci_impact.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_ci_intel.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_ci_runner.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_ci_workflow.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_circuit_breaker.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_claude_md_merge.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_claude_md_updater.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_cli_smoke.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_codex_mcp_transport.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_codex_native.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_compressor_large_file.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_confirm_guard.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_confirm_guard_wiring.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_cooccurrence_bounds.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_cred_audit.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_cred_telemetry.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_credential_login_kind.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_credential_store.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_credential_ui_parity.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_credentials_routes.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_credentials_tool.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_creds_cli_smoke.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_delegate_cascade.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_delegate_version_probe.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_dir_map_c3.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_e2e_benchmark.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_edit_ledger_deadline.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_edit_ledger_hook.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_edit_locking.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_edit_normalization.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_edit_verify.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_embedding_index_deadlock.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_enforcement_flip.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_enforcement_policy.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_enforcement_routes.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_env_parser.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_failed_calls_do_not_unlock.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_federated_graph.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_file_map_c1.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_filter_backoff.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_ghost_files.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_ghost_generation.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_git_branch_awareness.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hook_access_guard.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hook_codex_compat.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hook_dispatch.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hook_pretool_enforce.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hook_prompt_recall.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hook_session_end.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hook_smoke.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hook_state.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hook_utf8_stdio.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hub_credentials_route.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hub_credentials_routes_write.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hub_enforcement_routes.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hub_hook_migration.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hub_inspect_api.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hub_locks_routes.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hub_oracle_service_routes.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hub_override_routes.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hub_server_smoke.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_hub_subproject_links.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_ide_workflow_adaptation.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_index_cap_not_hardcoded.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_init_clear_preserves_user_content.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_init_scan.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_install_mcp_entrypoint.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_jira_cli_smoke.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_jira_client.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_jira_config_fallback.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_jira_credentials.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_jira_links.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_jira_routes.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_jira_tool.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_large_files_c4.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_lazy_store_init.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_map_eval.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_map_telemetry_c0.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_mask_guard.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_mask_routes.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_mask_surfaces.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_mcp_host_guard.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_mcp_memory_timeout.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_mcp_server_smoke.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_mcp_toml.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_memory_distiller.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_memory_graph_api.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_memory_queue.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_memory_system.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_mobile_api.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_mobile_clients.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_mobile_extras.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_mobile_jobs_ci.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_mobile_override_costs.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_mobile_override_routes.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_mobile_security_api.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_no_stale_model_pins.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_notification_dedup.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_notification_discipline.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_notification_kinds.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_ollama_credentials.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_oracle_api_auth.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_oracle_apikey_api.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_oracle_c3_bridge.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_oracle_chat_engine.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_oracle_chat_store.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_oracle_discovery_api.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_oracle_discovery_audit.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_oracle_health_probe.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_oracle_local_auth.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_oracle_loopback.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_oracle_ollama_bridge.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_oracle_scanner_cache.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_oracle_security_fixes.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_oracle_session_bootstrap.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_oracle_subproject_awareness.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_oracle_ui_bundle.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_output_filter.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_override_costs.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_override_grants.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_override_grants_mcp.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_override_requests.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_override_wake.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_permissions.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_pm_api.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_project_manager.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_project_manager_merge.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_project_tool.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_read_coercion.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_read_edit_parity.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_related_facts.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_repo_map.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_repo_shape.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_response_boilerplate.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_retention.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_review_digest.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_search_eval.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_search_p1.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_search_p2.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_search_p2b.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_search_p3.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_search_p4.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_search_p5.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_service_durability.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_session_benchmark.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_session_budget.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_session_live.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_shell_budget_s1.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_shell_creds.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_shell_eval.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_shell_jobs_s3.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_shell_nudge_s4.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_shell_output.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_shell_parsers_s2.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_shell_robustness.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_shell_telemetry_s0.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_shell_write_ledger.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_shell_writes.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_subproject_clear_scope.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_subproject_depth_consumers.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_subproject_exclusion.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_subproject_federation.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_subproject_linkage_api.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_subprojects.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_swe_bench.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_task_store.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_task_tool.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_time_tracker.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_token_telemetry.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_token_tracking.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_tool_registry.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_ui_jsx_syntax.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_upgrade_and_version.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_validate.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_vault_write_guard.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_version_sync.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_web_security.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tests/test_windows_reliability.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tui/__init__.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tui/backend.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tui/main.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tui/screens/__init__.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tui/screens/benchmark_view.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tui/screens/claudemd_view.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tui/screens/compress_view.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tui/screens/index_view.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tui/screens/init_view.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tui/screens/mcp_view.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tui/screens/optimize_view.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tui/screens/pipe_view.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tui/screens/projects_view.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tui/screens/search_view.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tui/screens/session_view.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tui/screens/stats.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.0}/tui/screens/ui_view.py +0 -0
- {code_context_control-2.128.1 → code_context_control-2.129.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.129.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
|
|
@@ -734,7 +734,10 @@ async def c3_read(file_path: str, symbols: Any = None, lines: Any = None,
|
|
|
734
734
|
"""READ source, or MAP a file when called with only file_path (read-only, plan-mode safe).
|
|
735
735
|
file_path: single or comma-separated. symbols: names as the map prints them (Class.method ok).
|
|
736
736
|
lines: int, [start,end], or list of ranges. No symbols/lines = one line per symbol with
|
|
737
|
-
signature and [La-Lb] range at ~10% of the file's tokens; then read the symbols you need.
|
|
737
|
+
signature and [La-Lb] range at ~10% of the file's tokens; then read the symbols you need.
|
|
738
|
+
Paths OUTSIDE the project root are read too (sibling repo, extra working dir, installed
|
|
739
|
+
package source): tagged [c3-read:external], served from a transient record, never added
|
|
740
|
+
to this project's index or related facts. Access Guard rules still apply there."""
|
|
738
741
|
path_err = validate_file_path(file_path)
|
|
739
742
|
if path_err:
|
|
740
743
|
return f"[c3_read:error] {path_err}"
|
|
@@ -147,6 +147,40 @@ _HEREDOC_MARKERS = {
|
|
|
147
147
|
_GHOST_NAMES = _PYTHON_TYPE_NAMES | _HEREDOC_MARKERS
|
|
148
148
|
|
|
149
149
|
|
|
150
|
+
EXTERNAL_TAG = "[c3-read:external]"
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def external_banner(path: str) -> str:
|
|
154
|
+
"""The one line every outside-the-root response opens with.
|
|
155
|
+
|
|
156
|
+
One definition so c3_read and c3_compress cannot drift apart on it.
|
|
157
|
+
"""
|
|
158
|
+
return (f"{EXTERNAL_TAG} {path} — outside the project root; served but "
|
|
159
|
+
f"not indexed, and absent from this project's search, map cache "
|
|
160
|
+
f"and related facts.\n")
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def project_key(full, project_path) -> tuple[str, bool]:
|
|
164
|
+
"""``(key, external)`` for an already-resolved-or-not path.
|
|
165
|
+
|
|
166
|
+
Inside the root the key is the project-relative posix path — how
|
|
167
|
+
file_memory, the edit ledger and related facts all address a file.
|
|
168
|
+
Outside it there is no such key, so the absolute posix path stands in and
|
|
169
|
+
``external`` tells the caller to serve from a transient record rather than
|
|
170
|
+
the index (docs/file-map.md § Outside the root).
|
|
171
|
+
|
|
172
|
+
This used to be a bare ``relative_to`` whose ValueError escaped as a tool
|
|
173
|
+
crash. It is not a containment check and must not become one: Access Guard
|
|
174
|
+
already rules on the absolute canonical path, and it runs before this.
|
|
175
|
+
"""
|
|
176
|
+
resolved = Path(full).resolve()
|
|
177
|
+
try:
|
|
178
|
+
rel = resolved.relative_to(Path(project_path).resolve())
|
|
179
|
+
return str(rel).replace("\\", "/"), False
|
|
180
|
+
except ValueError:
|
|
181
|
+
return resolved.as_posix(), True
|
|
182
|
+
|
|
183
|
+
|
|
150
184
|
def validate_file_path(file_path: str) -> str | None:
|
|
151
185
|
"""Return an error message if file_path looks like a ghost-file path, else None.
|
|
152
186
|
|
|
@@ -385,6 +385,15 @@ def handle_ci(action: str, job: str, run_id: str, allow_foreign: bool,
|
|
|
385
385
|
f" runs Linux jobs in a container "
|
|
386
386
|
f"({ci_act.DEFAULT_IMAGE}), real `uses:` actions included",
|
|
387
387
|
]
|
|
388
|
+
if state.get("warning"):
|
|
389
|
+
lines.append(f" WARNING: {state['warning']}")
|
|
390
|
+
# An image that is present locally is still not proof act can pull
|
|
391
|
+
# it: act sends the stored registry credential where the CLI sends
|
|
392
|
+
# none, so an expired token fails a public pull (issue #173). Say
|
|
393
|
+
# so rather than let `available` read as a guarantee.
|
|
394
|
+
lines.append(" a runner failure before any step runs is "
|
|
395
|
+
"reported as a container-setup failure, not as 0 "
|
|
396
|
+
"parsed failures")
|
|
388
397
|
else:
|
|
389
398
|
lines += [" act UNAVAILABLE", f" {state['reason']}"]
|
|
390
399
|
lines += [
|
|
@@ -11,9 +11,10 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
|
11
11
|
from pathlib import Path
|
|
12
12
|
|
|
13
13
|
from cli.tools import _grants
|
|
14
|
-
from cli.tools._helpers import finalize_with_tokens, show_token_ratios
|
|
14
|
+
from cli.tools._helpers import external_banner, finalize_with_tokens, project_key, show_token_ratios
|
|
15
15
|
from core import count_tokens
|
|
16
16
|
from services import access_guard
|
|
17
|
+
from services.file_map import render_map
|
|
17
18
|
|
|
18
19
|
#: Every mode name c3_compress ever accepted, and what to say about it now.
|
|
19
20
|
RETIRED_MODES = {
|
|
@@ -35,7 +36,8 @@ def deprecation_line(requested: str) -> str:
|
|
|
35
36
|
|
|
36
37
|
|
|
37
38
|
def map_detail(svc, rel: str, requested_mode: str, *, cache_hit: bool,
|
|
38
|
-
symbols: int = 0, fallback: str = ""
|
|
39
|
+
symbols: int = 0, fallback: str = "", record: dict = None,
|
|
40
|
+
external: bool = False) -> dict:
|
|
39
41
|
"""Telemetry `detail` for a map served from file_memory (C0, 2.120.0).
|
|
40
42
|
|
|
41
43
|
backend names the code path, parser the extractor that built the record
|
|
@@ -43,13 +45,15 @@ def map_detail(svc, rel: str, requested_mode: str, *, cache_hit: bool,
|
|
|
43
45
|
whether the record was already fresh. `symbols` is how many the caller
|
|
44
46
|
asked for and `fallback` why a read served a map instead of source.
|
|
45
47
|
`deprecated_mode` (2.122.0) is set when a retired mode name was asked for.
|
|
48
|
+
`record` is a caller-supplied transient record (an outside-the-root read,
|
|
49
|
+
which is deliberately absent from file_memory) and `external` flags it.
|
|
46
50
|
Flat so telemetry.aggregate_tool_telemetry can fold it without a schema.
|
|
47
51
|
"""
|
|
48
|
-
record
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
if record is None:
|
|
53
|
+
try:
|
|
54
|
+
record = svc.file_memory.get(rel)
|
|
55
|
+
except Exception:
|
|
56
|
+
record = None
|
|
53
57
|
if not isinstance(record, dict):
|
|
54
58
|
record = None
|
|
55
59
|
detail = {
|
|
@@ -65,6 +69,9 @@ def map_detail(svc, rel: str, requested_mode: str, *, cache_hit: bool,
|
|
|
65
69
|
detail["fallback"] = fallback
|
|
66
70
|
if requested_mode not in ("map", "read"):
|
|
67
71
|
detail["deprecated_mode"] = requested_mode
|
|
72
|
+
if external:
|
|
73
|
+
detail["backend"] = "transient"
|
|
74
|
+
detail["external"] = True
|
|
68
75
|
return detail
|
|
69
76
|
|
|
70
77
|
|
|
@@ -136,20 +143,37 @@ def _compress_single(file_path: str, requested: str, note: str, svc, finalize) -
|
|
|
136
143
|
if not full.exists():
|
|
137
144
|
return ("[file_map:error] not found. To create a new file use "
|
|
138
145
|
"c3_edit(file_path=..., old_string='', new_string=<content>).")
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
146
|
+
resolved = full.resolve()
|
|
147
|
+
rel, external = project_key(resolved, svc.project_path)
|
|
148
|
+
# Outside the root the map comes from a transient record — same parser,
|
|
149
|
+
# never written to an index keyed by project-relative path
|
|
150
|
+
# (docs/file-map.md § Outside the root). c3_read does the same thing; the
|
|
151
|
+
# two map surfaces must not disagree about where a file may live.
|
|
152
|
+
banner = external_banner(rel) if external else ""
|
|
153
|
+
if external:
|
|
154
|
+
ext_record = svc.file_memory.build_transient_record(resolved, key=rel)
|
|
155
|
+
cache_hit = False
|
|
156
|
+
body = (render_map(ext_record, max_tokens=svc.file_memory.MAP_TOKEN_BUDGET)
|
|
157
|
+
if ext_record
|
|
158
|
+
else f"[file_map] Could not build map for {rel} — unreadable.")
|
|
159
|
+
else:
|
|
160
|
+
ext_record = None
|
|
161
|
+
# C0 measurement: was the record already fresh before this call?
|
|
162
|
+
cache_hit = not svc.file_memory.needs_update(rel)
|
|
163
|
+
body = _build_map(svc, rel)
|
|
164
|
+
res = banner + body
|
|
143
165
|
raw_tokens = None
|
|
144
166
|
map_tokens = 0
|
|
145
167
|
try:
|
|
146
168
|
raw_text = full.read_text(encoding="utf-8", errors="replace")
|
|
147
169
|
raw_tokens = count_tokens(raw_text)
|
|
148
170
|
map_tokens = count_tokens(res)
|
|
149
|
-
if map_tokens >= raw_tokens and not
|
|
171
|
+
if map_tokens >= raw_tokens and not body.startswith("[file_map]"):
|
|
150
172
|
# A map that costs more than the file is worth nothing
|
|
151
173
|
# (docs/file-map.md § Small files).
|
|
152
|
-
res =
|
|
174
|
+
res = (banner
|
|
175
|
+
+ f"[compress:{file_path}] whole file — smaller than its map\n"
|
|
176
|
+
+ raw_text)
|
|
153
177
|
map_tokens = count_tokens(res)
|
|
154
178
|
summary = "map"
|
|
155
179
|
except Exception:
|
|
@@ -162,7 +186,8 @@ def _compress_single(file_path: str, requested: str, note: str, svc, finalize) -
|
|
|
162
186
|
res, summary,
|
|
163
187
|
raw_tokens=raw_tokens, optimized_tokens=map_tokens or None,
|
|
164
188
|
response_tokens=map_tokens,
|
|
165
|
-
detail=map_detail(svc, rel, requested, cache_hit=cache_hit
|
|
189
|
+
detail=map_detail(svc, rel, requested, cache_hit=cache_hit,
|
|
190
|
+
record=ext_record, external=external))
|
|
166
191
|
|
|
167
192
|
|
|
168
193
|
def _compress_batch(paths: list, requested: str, note: str, svc, finalize) -> str:
|
|
@@ -195,10 +220,17 @@ def _compress_batch(paths: list, requested: str, note: str, svc, finalize) -> st
|
|
|
195
220
|
full = Path(fp)
|
|
196
221
|
if not full.exists():
|
|
197
222
|
return fp, None, None, None, "not found"
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
223
|
+
resolved = full.resolve()
|
|
224
|
+
rel, external = project_key(resolved, svc.project_path)
|
|
225
|
+
if external:
|
|
226
|
+
record = svc.file_memory.build_transient_record(resolved, key=rel)
|
|
227
|
+
res = external_banner(rel) + (
|
|
228
|
+
render_map(record, max_tokens=svc.file_memory.MAP_TOKEN_BUDGET)
|
|
229
|
+
if record
|
|
230
|
+
else f"[file_map] Could not build map for {rel} — unreadable.")
|
|
231
|
+
else:
|
|
232
|
+
res = svc.file_memory.get_or_build_map(
|
|
233
|
+
rel, max_tokens=svc.file_memory.MAP_TOKEN_BUDGET)
|
|
202
234
|
try:
|
|
203
235
|
raw_tok = count_tokens(full.read_text(encoding="utf-8", errors="replace"))
|
|
204
236
|
map_tok = count_tokens(res)
|
|
@@ -7,10 +7,11 @@ from pathlib import Path
|
|
|
7
7
|
from typing import Any
|
|
8
8
|
|
|
9
9
|
from cli.tools import _grants
|
|
10
|
-
from cli.tools._helpers import finalize_with_tokens, maybe_related_facts
|
|
10
|
+
from cli.tools._helpers import external_banner, finalize_with_tokens, maybe_related_facts, project_key
|
|
11
11
|
from cli.tools.compress import map_detail
|
|
12
12
|
from core import count_tokens
|
|
13
13
|
from services import access_guard
|
|
14
|
+
from services.file_map import render_map
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
def _coerce_list(val: Any) -> list[str] | None:
|
|
@@ -175,7 +176,21 @@ def handle_read(file_path: str, symbols: Any = None, lines: Any = None,
|
|
|
175
176
|
if not full.exists():
|
|
176
177
|
return f"[read:error] File not found: {file_path}"
|
|
177
178
|
|
|
178
|
-
|
|
179
|
+
# A path outside the project root is READ, not refused (docs/file-map.md
|
|
180
|
+
# § Outside the root). The root was never the control here: Access Guard
|
|
181
|
+
# ruled above and its rules match the absolute canonical path as well as
|
|
182
|
+
# the project-relative one, so the builtin denies still cover an outside
|
|
183
|
+
# file; and the PreToolUse hook stands down outside the root, so native
|
|
184
|
+
# Read already went there unimpeded. Refusing only pushed the agent off
|
|
185
|
+
# the budgeted, guarded tool onto the unbudgeted one.
|
|
186
|
+
#
|
|
187
|
+
# What the root DOES decide is indexing. file_memory is keyed by
|
|
188
|
+
# project-relative path and feeds the text index, the map cache and
|
|
189
|
+
# prune_stale, so an outside file is served from a transient record and
|
|
190
|
+
# never written into this project's store.
|
|
191
|
+
resolved = full.resolve()
|
|
192
|
+
rel_path, external = project_key(resolved, svc.project_path)
|
|
193
|
+
banner = external_banner(rel_path) if external else ""
|
|
179
194
|
|
|
180
195
|
if full.is_dir():
|
|
181
196
|
# A directory maps to one line per file, budgeted
|
|
@@ -184,7 +199,9 @@ def handle_read(file_path: str, symbols: Any = None, lines: Any = None,
|
|
|
184
199
|
budget = DEFAULT_MAX_TOKENS
|
|
185
200
|
if isinstance(lines, int) and not isinstance(lines, bool) and lines > 0:
|
|
186
201
|
budget = lines
|
|
187
|
-
text, dir_detail = render_directory_map(svc, rel_path, max_tokens=budget
|
|
202
|
+
text, dir_detail = render_directory_map(svc, rel_path, max_tokens=budget,
|
|
203
|
+
external=external)
|
|
204
|
+
text = banner + text
|
|
188
205
|
tok = count_tokens(text)
|
|
189
206
|
if finalize is None:
|
|
190
207
|
return text
|
|
@@ -228,15 +245,56 @@ def handle_read(file_path: str, symbols: Any = None, lines: Any = None,
|
|
|
228
245
|
# Ensure file_memory index is fresh.
|
|
229
246
|
# When the watcher is running, it handles updates in the background —
|
|
230
247
|
# only force-update if file_memory has no record at all (first access).
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
248
|
+
# An outside-the-root file is never indexed; it gets a transient record
|
|
249
|
+
# instead, built lazily below.
|
|
250
|
+
if not external:
|
|
251
|
+
try:
|
|
252
|
+
watcher_active = (hasattr(svc, "watcher") and svc.watcher._observer.is_alive())
|
|
253
|
+
if watcher_active:
|
|
254
|
+
if not svc.file_memory.get(rel_path):
|
|
255
|
+
svc.file_memory.update(rel_path)
|
|
256
|
+
elif svc.file_memory.needs_update(rel_path):
|
|
235
257
|
svc.file_memory.update(rel_path)
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
258
|
+
except Exception:
|
|
259
|
+
pass
|
|
260
|
+
|
|
261
|
+
_ext_cache = []
|
|
262
|
+
|
|
263
|
+
def _ext_record():
|
|
264
|
+
"""The transient record for an outside file — same parser and schema
|
|
265
|
+
as an indexed one, never persisted (docs/file-map.md § Outside the
|
|
266
|
+
root).
|
|
267
|
+
|
|
268
|
+
Built at most once, and only where a map or a symbol lookup actually
|
|
269
|
+
needs it: a `lines=[a,b]` read must not pay for a full parse of the
|
|
270
|
+
file it is slicing two lines out of, which is the whole reason the
|
|
271
|
+
large-file bounds exist.
|
|
272
|
+
"""
|
|
273
|
+
if not external:
|
|
274
|
+
return None
|
|
275
|
+
if not _ext_cache:
|
|
276
|
+
_ext_cache.append(
|
|
277
|
+
svc.file_memory.build_transient_record(resolved, key=rel_path))
|
|
278
|
+
return _ext_cache[0]
|
|
279
|
+
|
|
280
|
+
def _file_map(max_tokens=None) -> str:
|
|
281
|
+
"""The map, from the project index or from the transient record."""
|
|
282
|
+
if not external:
|
|
283
|
+
return svc.file_memory.get_or_build_map(rel_path, max_tokens=max_tokens)
|
|
284
|
+
record = _ext_record()
|
|
285
|
+
if not record:
|
|
286
|
+
return f"[file_map] Could not build map for {rel_path} — unreadable."
|
|
287
|
+
return render_map(record, max_tokens=max_tokens)
|
|
288
|
+
|
|
289
|
+
def _map_cached() -> bool:
|
|
290
|
+
return False if external else not svc.file_memory.needs_update(rel_path)
|
|
291
|
+
|
|
292
|
+
def _facts() -> str:
|
|
293
|
+
# Facts are project knowledge keyed by project-relative path; an
|
|
294
|
+
# outside file has none, and matching one by basename would be a lie.
|
|
295
|
+
if external:
|
|
296
|
+
return ""
|
|
297
|
+
return maybe_related_facts(svc, rel_path, top_k=3, context="read")
|
|
240
298
|
|
|
241
299
|
raw_text = full.read_text(encoding="utf-8", errors="replace")
|
|
242
300
|
# EOL-normalize exactly the way c3_edit's matcher does (\r\n and \r → \n),
|
|
@@ -256,7 +314,9 @@ def handle_read(file_path: str, symbols: Any = None, lines: Any = None,
|
|
|
256
314
|
return _full_tok_cache[0]
|
|
257
315
|
|
|
258
316
|
if symbols:
|
|
259
|
-
matches = svc.file_memory.get_symbol_ranges(rel_path, symbols,
|
|
317
|
+
matches = svc.file_memory.get_symbol_ranges(rel_path, symbols,
|
|
318
|
+
return_matches=True,
|
|
319
|
+
record=_ext_record())
|
|
260
320
|
|
|
261
321
|
# Check for ambiguity
|
|
262
322
|
disambiguation_msgs = []
|
|
@@ -292,7 +352,7 @@ def handle_read(file_path: str, symbols: Any = None, lines: Any = None,
|
|
|
292
352
|
ranges.append(m["range"])
|
|
293
353
|
|
|
294
354
|
if '<main>' in symbols or '<globals>' in symbols:
|
|
295
|
-
record = svc.file_memory.get(rel_path)
|
|
355
|
+
record = _ext_record() or svc.file_memory.get(rel_path)
|
|
296
356
|
if record and "sections" in record:
|
|
297
357
|
covered = set()
|
|
298
358
|
|
|
@@ -318,29 +378,31 @@ def handle_read(file_path: str, symbols: Any = None, lines: Any = None,
|
|
|
318
378
|
ranges.extend(main_ranges)
|
|
319
379
|
|
|
320
380
|
if not ranges and symbols:
|
|
321
|
-
map_cached =
|
|
322
|
-
file_map =
|
|
323
|
-
resp =
|
|
381
|
+
map_cached = _map_cached()
|
|
382
|
+
file_map = _file_map()
|
|
383
|
+
resp = (banner
|
|
384
|
+
+ f"[read:{file_path}] symbols not found: {symbols}. "
|
|
385
|
+
f"Showing file map:\n{file_map}")
|
|
324
386
|
map_tok = count_tokens(file_map)
|
|
325
387
|
return finalize_with_tokens(
|
|
326
388
|
finalize, svc, "c3_read", {"file": file_path, "symbols": symbols},
|
|
327
389
|
resp, f"{full_file_tokens()}->{map_tok}tok",
|
|
328
390
|
raw_tokens=full_file_tokens(), optimized_tokens=map_tok,
|
|
329
391
|
detail=map_detail(svc, rel_path, "read", cache_hit=map_cached,
|
|
330
|
-
symbols=len(symbols), fallback="symbols_not_found"
|
|
392
|
+
symbols=len(symbols), fallback="symbols_not_found",
|
|
393
|
+
record=_ext_record(), external=external))
|
|
331
394
|
|
|
332
395
|
if not ranges:
|
|
333
|
-
map_cached =
|
|
334
|
-
file_map = svc.file_memory.
|
|
335
|
-
rel_path, max_tokens=svc.file_memory.MAP_TOKEN_BUDGET)
|
|
396
|
+
map_cached = _map_cached()
|
|
397
|
+
file_map = _file_map(max_tokens=svc.file_memory.MAP_TOKEN_BUDGET)
|
|
336
398
|
if count_tokens(file_map) >= full_file_tokens():
|
|
337
399
|
# A map that costs more than the file is worth nothing: serve the
|
|
338
400
|
# file (docs/file-map.md § Small files).
|
|
339
401
|
file_map = (f"[read:{file_path}] whole file — smaller than its map\n"
|
|
340
402
|
+ raw_text)
|
|
341
|
-
resp = (file_map
|
|
403
|
+
resp = (banner + file_map
|
|
342
404
|
+ "\n[map only — pass lines=[start,end] or symbols=[...] for exact source]"
|
|
343
|
-
+
|
|
405
|
+
+ _facts())
|
|
344
406
|
map_tok = count_tokens(resp)
|
|
345
407
|
if finalize is None:
|
|
346
408
|
return resp
|
|
@@ -350,7 +412,8 @@ def handle_read(file_path: str, symbols: Any = None, lines: Any = None,
|
|
|
350
412
|
raw_tokens=full_file_tokens(), optimized_tokens=map_tok,
|
|
351
413
|
response_tokens=map_tok,
|
|
352
414
|
detail=map_detail(svc, rel_path, "read", cache_hit=map_cached,
|
|
353
|
-
fallback="map_only")
|
|
415
|
+
fallback="map_only", record=_ext_record(),
|
|
416
|
+
external=external))
|
|
354
417
|
else:
|
|
355
418
|
# Sort and merge overlapping ranges
|
|
356
419
|
ranges.sort()
|
|
@@ -387,7 +450,7 @@ def handle_read(file_path: str, symbols: Any = None, lines: Any = None,
|
|
|
387
450
|
prev_end = end
|
|
388
451
|
|
|
389
452
|
final_content = "\n".join(parts)
|
|
390
|
-
resp = final_content +
|
|
453
|
+
resp = banner + final_content + _facts()
|
|
391
454
|
tokens = count_tokens(resp)
|
|
392
455
|
summary = f"{full_file_tokens()}->{tokens}tok" if tokens < full_file_tokens() else f"{tokens}tok"
|
|
393
456
|
# C0 measurement: what the read asked for and how much source it took.
|
|
@@ -398,6 +461,7 @@ def handle_read(file_path: str, symbols: Any = None, lines: Any = None,
|
|
|
398
461
|
"ranges": len(ranges),
|
|
399
462
|
"lines_served": sum(e - s_ + 1 for s_, e in ranges),
|
|
400
463
|
"file_lines": len(content_lines),
|
|
464
|
+
"external": external,
|
|
401
465
|
}
|
|
402
466
|
return finalize_with_tokens(
|
|
403
467
|
finalize, svc, "c3_read", {"file": file_path, "symbols": symbols}, resp, summary,
|
{code_context_control-2.128.1 → code_context_control-2.129.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.129.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
|
|
@@ -460,6 +460,7 @@ tests/test_project_manager_merge.py
|
|
|
460
460
|
tests/test_project_tool.py
|
|
461
461
|
tests/test_read_coercion.py
|
|
462
462
|
tests/test_read_edit_parity.py
|
|
463
|
+
tests/test_read_outside_root.py
|
|
463
464
|
tests/test_related_facts.py
|
|
464
465
|
tests/test_repo_map.py
|
|
465
466
|
tests/test_repo_shape.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.129.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"
|
|
@@ -116,6 +116,19 @@ def availability() -> dict:
|
|
|
116
116
|
info["docker"] = True
|
|
117
117
|
info["docker_version"] = out.strip().splitlines()[-1] if out.strip() else ""
|
|
118
118
|
info["ok"] = True
|
|
119
|
+
|
|
120
|
+
# Is the default runner image already local? Absent, the first act run
|
|
121
|
+
# pulls ~1 GB, which is worth warning about but is not unreadiness. This
|
|
122
|
+
# probe deliberately does NOT pull: it cannot, in any case, predict the
|
|
123
|
+
# failure in issue #173 — there the image is present and `docker pull`
|
|
124
|
+
# succeeds, while act's own pull fails because act sends the stored
|
|
125
|
+
# registry credential and the CLI does not. Only a real act run shows
|
|
126
|
+
# that, which is why the runner classifies it (see setup_failure).
|
|
127
|
+
rc, _ = _probe(["docker", "image", "inspect", DEFAULT_IMAGE], timeout=20)
|
|
128
|
+
info["image_present"] = rc == 0
|
|
129
|
+
if rc != 0:
|
|
130
|
+
info["warning"] = (f"runner image {DEFAULT_IMAGE} is not present "
|
|
131
|
+
"locally; the first act run pulls ~1 GB.")
|
|
119
132
|
return info
|
|
120
133
|
|
|
121
134
|
|
|
@@ -243,6 +256,53 @@ def build_command(inst, project, act_path: str, event: str = "",
|
|
|
243
256
|
_ACT_OUTPUT_LINE = re.compile(r"^\[[^\]]*\]\s{0,3}\|\s?(.*)$")
|
|
244
257
|
|
|
245
258
|
|
|
259
|
+
# ── Setup-phase failures ────────────────────────────────────────────────────
|
|
260
|
+
# act can fail BEFORE any workflow step runs: the runner image cannot be
|
|
261
|
+
# pulled, the daemon refuses, the container never starts. Nothing the failure
|
|
262
|
+
# parsers look for was ever printed, so parsing that log yields `unparsed` and
|
|
263
|
+
# `c3_ci(action='failures')` answers "0 parsed failures" — for what is really
|
|
264
|
+
# "the runner image could not be obtained" (issue #173). Classify it instead.
|
|
265
|
+
SETUP_PARSER = "container-setup"
|
|
266
|
+
|
|
267
|
+
_SETUP_FAILED = re.compile(r"(?:❌\s*)?Failure\s+-\s+Set up job", re.I)
|
|
268
|
+
_DAEMON_ERROR = re.compile(r"Error response from daemon:\s*(.+)", re.I)
|
|
269
|
+
_SETUP_REASONS = (
|
|
270
|
+
(re.compile(r"authentication required|incorrect username or password", re.I),
|
|
271
|
+
"the Docker registry rejected the runner image pull with an "
|
|
272
|
+
"authentication error. act sends the stored Docker credential where the "
|
|
273
|
+
"CLI sends none for a public image, so an expired token turns a public "
|
|
274
|
+
"pull into an auth failure — `docker logout` clears it."),
|
|
275
|
+
(re.compile(r"pull access denied|repository does not exist|manifest unknown", re.I),
|
|
276
|
+
"the runner image could not be found in the registry."),
|
|
277
|
+
(re.compile(r"Cannot connect to the Docker daemon|daemon is not running|"
|
|
278
|
+
r"docker daemon is not running", re.I),
|
|
279
|
+
"the Docker daemon is not reachable — start Docker and retry."),
|
|
280
|
+
(re.compile(r"no space left on device", re.I),
|
|
281
|
+
"the Docker host ran out of disk space pulling the runner image."),
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def setup_failure(text: str) -> str:
|
|
286
|
+
"""Why act failed before any workflow step ran, or '' if it got that far.
|
|
287
|
+
|
|
288
|
+
The verdict marker is act's own `Failure - Set up job`; the patterns after
|
|
289
|
+
it only supply a reason a human can act on. A job that reached its steps
|
|
290
|
+
and failed there is NOT a setup failure and must still go to the parsers.
|
|
291
|
+
"""
|
|
292
|
+
text = text or ""
|
|
293
|
+
if not _SETUP_FAILED.search(text):
|
|
294
|
+
return ""
|
|
295
|
+
for pattern, reason in _SETUP_REASONS:
|
|
296
|
+
if pattern.search(text):
|
|
297
|
+
return f"act could not start the runner container: {reason}"
|
|
298
|
+
daemon = _DAEMON_ERROR.search(text)
|
|
299
|
+
if daemon:
|
|
300
|
+
return ("act could not start the runner container — the Docker daemon "
|
|
301
|
+
f"said: {daemon.group(1).strip()[:200]}")
|
|
302
|
+
return ("act failed during 'Set up job': the runner container never "
|
|
303
|
+
"started, so no workflow step ran.")
|
|
304
|
+
|
|
305
|
+
|
|
246
306
|
def program_output(text: str) -> str:
|
|
247
307
|
"""Just what the commands printed, with act's prefixes removed.
|
|
248
308
|
|
|
@@ -413,6 +413,17 @@ def _run_job_act(inst, project: Path, run_dir: Path, event: str,
|
|
|
413
413
|
pass
|
|
414
414
|
|
|
415
415
|
if result.status in (FAILED, TIMEOUT):
|
|
416
|
+
# A setup-phase failure has no program output to parse: the container
|
|
417
|
+
# never started. Parsing it anyway reported `unparsed` with a log
|
|
418
|
+
# tail, so `c3_ci(action='failures')` answered "0 parsed failures" for
|
|
419
|
+
# a broken runner (issue #173). Say what actually happened. The status
|
|
420
|
+
# stays FAILED — a job that could not run is never a green light.
|
|
421
|
+
setup_reason = ci_act.setup_failure(outcome.get("output") or "")
|
|
422
|
+
if setup_reason:
|
|
423
|
+
result.reason = setup_reason
|
|
424
|
+
result.parser = ci_act.SETUP_PARSER
|
|
425
|
+
result.failures = []
|
|
426
|
+
return result
|
|
416
427
|
# Parse what the commands printed, not act's narration around it —
|
|
417
428
|
# otherwise every file path arrives wearing a `[CI/lint] |` prefix.
|
|
418
429
|
parsed = ci_failures.parse(
|
|
@@ -87,12 +87,44 @@ def _line_count(path: Path) -> int:
|
|
|
87
87
|
return 0
|
|
88
88
|
|
|
89
89
|
|
|
90
|
-
def render_directory_map(svc, rel_dir: str, *, max_tokens: int = DEFAULT_MAX_TOKENS
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
def render_directory_map(svc, rel_dir: str, *, max_tokens: int = DEFAULT_MAX_TOKENS,
|
|
91
|
+
external: bool = False) -> tuple:
|
|
92
|
+
"""Return (text, detail) for the directory `rel_dir` (project-relative, posix).
|
|
93
|
+
|
|
94
|
+
`external=True` maps a directory OUTSIDE the project root: `rel_dir` is an
|
|
95
|
+
absolute path and names are relative to it. Symbols are still extracted,
|
|
96
|
+
under the same file/deadline/byte bounds — but through transient records
|
|
97
|
+
that are never persisted or looked up, because an outside file has no
|
|
98
|
+
project-relative key and indexing it would poison a store the rest of C3
|
|
99
|
+
addresses by that key. The edit ledger, which supplies the recency
|
|
100
|
+
ranking, likewise has nothing to say about a file outside the project.
|
|
101
|
+
"""
|
|
102
|
+
store = getattr(svc, "file_memory", None)
|
|
103
|
+
if external:
|
|
104
|
+
root = Path(rel_dir).resolve()
|
|
105
|
+
target = root
|
|
106
|
+
name_base = ""
|
|
107
|
+
label = root.as_posix().rstrip("/") + "/"
|
|
108
|
+
recent = {}
|
|
109
|
+
|
|
110
|
+
def _cached(rel):
|
|
111
|
+
return None # nothing outside the root is ever in the store
|
|
112
|
+
|
|
113
|
+
def _extract(rel):
|
|
114
|
+
return store.build_transient_record(root / rel, key=rel)
|
|
115
|
+
else:
|
|
116
|
+
root = Path(svc.project_path).resolve()
|
|
117
|
+
rel_dir = str(rel_dir).replace("\\", "/").strip("/")
|
|
118
|
+
target = (root / rel_dir).resolve() if rel_dir else root
|
|
119
|
+
name_base = rel_dir
|
|
120
|
+
label = (rel_dir + "/") if rel_dir else "./"
|
|
121
|
+
recent = _recent_edit_ranks(svc)
|
|
122
|
+
|
|
123
|
+
def _cached(rel):
|
|
124
|
+
return store.get(rel)
|
|
125
|
+
|
|
126
|
+
def _extract(rel):
|
|
127
|
+
return store.update(rel)
|
|
96
128
|
|
|
97
129
|
files = []
|
|
98
130
|
capped = False
|
|
@@ -104,9 +136,6 @@ def render_directory_map(svc, rel_dir: str, *, max_tokens: int = DEFAULT_MAX_TOK
|
|
|
104
136
|
files.append(fp.resolve().relative_to(root).as_posix())
|
|
105
137
|
except ValueError:
|
|
106
138
|
continue
|
|
107
|
-
|
|
108
|
-
store = getattr(svc, "file_memory", None)
|
|
109
|
-
recent = _recent_edit_ranks(svc)
|
|
110
139
|
started = time.monotonic()
|
|
111
140
|
extracted = 0
|
|
112
141
|
rows = []
|
|
@@ -115,7 +144,7 @@ def render_directory_map(svc, rel_dir: str, *, max_tokens: int = DEFAULT_MAX_TOK
|
|
|
115
144
|
record = None
|
|
116
145
|
if store is not None:
|
|
117
146
|
try:
|
|
118
|
-
record =
|
|
147
|
+
record = _cached(rel)
|
|
119
148
|
except Exception:
|
|
120
149
|
record = None
|
|
121
150
|
ext = Path(rel).suffix.lower()
|
|
@@ -124,7 +153,7 @@ def render_directory_map(svc, rel_dir: str, *, max_tokens: int = DEFAULT_MAX_TOK
|
|
|
124
153
|
and time.monotonic() - started < EXTRACT_DEADLINE_S):
|
|
125
154
|
try:
|
|
126
155
|
if (root / rel).stat().st_size <= MAX_EXTRACT_BYTES:
|
|
127
|
-
record =
|
|
156
|
+
record = _extract(rel)
|
|
128
157
|
extracted += 1
|
|
129
158
|
except Exception:
|
|
130
159
|
record = None
|
|
@@ -135,7 +164,7 @@ def render_directory_map(svc, rel_dir: str, *, max_tokens: int = DEFAULT_MAX_TOK
|
|
|
135
164
|
symbols = _top_symbols(record)
|
|
136
165
|
rows.append({
|
|
137
166
|
"rel": rel,
|
|
138
|
-
"name": rel[len(
|
|
167
|
+
"name": rel[len(name_base) + 1:] if name_base and rel.startswith(name_base + "/") else rel,
|
|
139
168
|
"lines": lines,
|
|
140
169
|
"lang": lang,
|
|
141
170
|
"symbols": symbols,
|
|
@@ -172,5 +201,6 @@ def render_directory_map(svc, rel_dir: str, *, max_tokens: int = DEFAULT_MAX_TOK
|
|
|
172
201
|
"listed": len(kept),
|
|
173
202
|
"extracted": extracted,
|
|
174
203
|
"capped": capped,
|
|
204
|
+
"external": bool(external),
|
|
175
205
|
}
|
|
176
206
|
return text, detail
|