code-context-control 2.65.0__tar.gz → 2.67.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.65.0/code_context_control.egg-info → code_context_control-2.67.0}/PKG-INFO +53 -3
- {code_context_control-2.65.0 → code_context_control-2.67.0}/README.md +52 -2
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/_hook_utils.py +106 -3
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/c3.py +271 -9
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/commands/parser.py +39 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_access_guard.py +26 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_pretool_enforce.py +167 -45
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_server.py +278 -2
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/app.js +3 -1
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_panel.js +2 -0
- code_context_control-2.67.0/cli/hub_ui/components/hub_enforcement.js +1162 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/topbar.js +1 -1
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/server.py +115 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/app.js +4 -0
- code_context_control-2.67.0/cli/ui/components/enforcement.js +334 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/icons.js +1 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0/code_context_control.egg-info}/PKG-INFO +53 -3
- {code_context_control-2.65.0 → code_context_control-2.67.0}/code_context_control.egg-info/SOURCES.txt +7 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/pyproject.toml +1 -1
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/access_guard.py +25 -0
- code_context_control-2.67.0/services/access_telemetry.py +262 -0
- code_context_control-2.67.0/services/enforcement_policy.py +419 -0
- code_context_control-2.67.0/tests/test_enforcement_policy.py +672 -0
- code_context_control-2.67.0/tests/test_enforcement_routes.py +182 -0
- code_context_control-2.67.0/tests/test_hub_enforcement_routes.py +438 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/LICENSE +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/__init__.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/commands/__init__.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/commands/common.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/docs.html +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/edits.html +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/access.html +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/bitbucket.html +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/credentials.html +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/getting-started.html +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/index.html +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/masking.html +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/oracle.html +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/shared.css +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/tools.html +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/workflow.html +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_artifact.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_auto_snapshot.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_c3_signal.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_c3read.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_dispatch.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_edit_ledger.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_edit_unlock.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_filter.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_ghost_files.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_prompt_recall.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_read.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_session_stats.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_terse_advisor.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/add_project.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/config_editor.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_health.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_tasks.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_views.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/global_search.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/hub_credentials.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/hub_locks.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/mcp_manager.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/modals.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/project_card.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/project_tree.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/session_drawer.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/settings_modal.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/sidebar.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/summary_bar.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/task_board.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/toasts.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/state.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui.html +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/mcp_proxy.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/mcp_server.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/progress.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/__init__.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/_helpers.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/agent.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/artifacts.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/bitbucket.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/compress.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/credentials.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/delegate.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/edit.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/edits.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/federate.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/filter.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/impact.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/jira.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/locks.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/memory.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/project.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/read.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/search.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/session.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/shell.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/status.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/tasks.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/validate.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/api.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/access.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/bitbucket.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/chat.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/credentials.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/dashboard.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/edits.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/instructions.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/jira.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/memory.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/sessions.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/settings.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/sidebar.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/tasks.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/pm_shared.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/shared.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/theme.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui.html +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui_legacy.html +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui_nano.html +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/code_context_control.egg-info/dependency_links.txt +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/code_context_control.egg-info/entry_points.txt +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/code_context_control.egg-info/requires.txt +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/code_context_control.egg-info/top_level.txt +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/core/__init__.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/core/config.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/core/ide.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/core/mcp_toml.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/core/web_security.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/__init__.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/config.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/mcp_oracle.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/oracle_server.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/oracle_ui.html +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/__init__.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/activity_reporter.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/api_auth.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/c3_bridge.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/chat_engine.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/chat_store.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/cross_memory.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/discovery_audit.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/federated_graph.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/health_checker.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/insight_engine.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/local_session.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/memory_reader.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/memory_writer.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/project_scanner.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/review_agent.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/tool_executor.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/tool_registry.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/activity.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/agents.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/app.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/busy.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/chat/conversations.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/chat/input.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/chat/markdown.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/chat/send.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/chat/stream_renderer.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/chat/toolbar.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/core.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/crossgraph.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/header.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/insights.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/projects.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/settings.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/suggestions.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/theme_tabs.js +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/__init__.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/activity_log.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/agent_base.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/agent_locks.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/agents.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/artifact_defs.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/artifact_store.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/auto_memory.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/bench/__init__.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/bench/external/__init__.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/bench/external/aider_polyglot.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/bench/external/swe_bench.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/benchmark_dashboard.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/bitbucket_client.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/bitbucket_credentials.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/circuit_breaker.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/claude_md.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/compressor.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/context_snapshot.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/conversation_store.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/credential_store.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/doc_index.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/e2e_benchmark.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/e2e_evaluator.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/e2e_tasks.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/edit_ledger.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/embedding_index.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/error_reporting.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/file_memory.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/git_context.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/hub_service.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/indexer.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/jira_client.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/jira_cloud.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/jira_credentials.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/jira_data_center.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/jira_links.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/mask_activation.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/mask_mirror.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/mask_presets.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/memory.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/memory_consolidator.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/memory_distiller.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/memory_graph.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/memory_grounder.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/memory_queue.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/memory_scorer.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/metrics.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/notifications.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/ollama_bridge.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/ollama_client.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/ollama_credentials.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/output_filter.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/parser.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/project_manager.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/project_runtime.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/protocol.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/proxy_state.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/repo_map.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/retention.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/retrieval_broker.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/router.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/runtime.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/scanner.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/session_benchmark.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/session_manager.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/session_preloader.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/subprojects.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/task_store.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/telemetry.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/text_index.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/time_tracker.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/tool_classifier.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/transcript_index.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/validation_cache.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/vector_store.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/watcher.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/services/win_subprocess.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/setup.cfg +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_access_builtin_optout.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_access_guard.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_access_guard_meta.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_access_guard_shell_project.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_access_guard_surfaces.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_access_guard_wiring.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_activity_reporter.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_agent_locks.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_aider_polyglot.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_antigravity_transition.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_artifact_store.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_artifact_tool.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_bitbucket_cli_smoke.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_bitbucket_client.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_bitbucket_config_fallback.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_bitbucket_credentials.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_bitbucket_tool.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_c3_shell.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_circuit_breaker.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_claude_md_merge.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_cli_smoke.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_compressor_large_file.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_credential_store.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_credentials_routes.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_credentials_tool.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_creds_cli_smoke.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_delegate_cascade.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_e2e_benchmark.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_edit_ledger_hook.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_edit_locking.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_edit_normalization.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_enforcement_flip.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_federated_graph.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_filter_backoff.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_ghost_files.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_ghost_generation.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_git_branch_awareness.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hook_access_guard.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hook_dispatch.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hook_pretool_enforce.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hook_prompt_recall.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hook_smoke.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hook_state.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hook_utf8_stdio.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hub_credentials_route.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hub_credentials_routes_write.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hub_inspect_api.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hub_locks_routes.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hub_server_smoke.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hub_subproject_links.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_ide_workflow_adaptation.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_init_scan.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_install_mcp_entrypoint.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_jira_cli_smoke.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_jira_client.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_jira_config_fallback.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_jira_credentials.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_jira_links.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_jira_routes.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_jira_tool.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_lazy_store_init.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_mask_guard.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_mask_routes.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_mask_surfaces.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_mcp_host_guard.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_mcp_memory_timeout.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_mcp_server_smoke.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_mcp_toml.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_memory_distiller.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_memory_graph_api.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_memory_queue.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_memory_system.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_no_stale_model_pins.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_notification_dedup.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_notification_discipline.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_ollama_credentials.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_api_auth.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_apikey_api.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_c3_bridge.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_chat_engine.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_chat_store.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_discovery_api.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_discovery_audit.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_local_auth.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_ollama_bridge.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_scanner_cache.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_security_fixes.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_session_bootstrap.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_subproject_awareness.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_ui_bundle.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_output_filter.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_permissions.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_pm_api.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_project_manager.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_project_manager_merge.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_project_tool.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_read_coercion.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_read_edit_parity.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_related_facts.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_repo_map.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_response_boilerplate.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_retention.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_review_digest.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_service_durability.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_session_benchmark.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_session_budget.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_shell_creds.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_shell_robustness.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_subproject_exclusion.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_subproject_federation.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_subprojects.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_swe_bench.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_task_store.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_task_tool.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_time_tracker.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_token_telemetry.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_tool_registry.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_upgrade_and_version.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_validate.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_vault_write_guard.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_version_sync.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_web_security.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_windows_reliability.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/__init__.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/backend.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/main.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/__init__.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/benchmark_view.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/claudemd_view.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/compress_view.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/index_view.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/init_view.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/mcp_view.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/optimize_view.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/pipe_view.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/projects_view.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/search_view.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/session_view.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/stats.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/ui_view.py +0 -0
- {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/theme.tcss +0 -0
{code_context_control-2.65.0/code_context_control.egg-info → code_context_control-2.67.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.67.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
|
|
@@ -186,7 +186,7 @@ Twelve tabs. The dashboard above shows token savings, indexed files, the live se
|
|
|
186
186
|
|
|
187
187
|
## The MCP tool suite
|
|
188
188
|
|
|
189
|
-
C3 exposes **
|
|
189
|
+
C3 exposes **21 tools** as a native MCP server. Your IDE calls them directly:
|
|
190
190
|
|
|
191
191
|
| Tool | What it does |
|
|
192
192
|
|---|---|
|
|
@@ -201,6 +201,7 @@ C3 exposes **20 tools** as a native MCP server. Your IDE calls them directly:
|
|
|
201
201
|
| `c3_memory` | Fact store with categories, recall, graph queries, `index`→`fetch` two-step |
|
|
202
202
|
| `c3_session` | Snapshot, restore, log decisions, compact history |
|
|
203
203
|
| `c3_impact` | Blast-radius analysis before editing shared symbols |
|
|
204
|
+
| `c3_locks` | Agent leases — who is working on which file, so two agents don't collide (v2.65.0) |
|
|
204
205
|
| `c3_delegate` | Offload heavy work to local Ollama / Codex / Gemini |
|
|
205
206
|
| `c3_agent` | Workflows: `review_changes`, `investigate`, `preflight`, `prepare_context`, `validate_compress` |
|
|
206
207
|
| `c3_edits` | Edit-ledger queries, version diffs, restore points, per-branch filter |
|
|
@@ -211,7 +212,7 @@ C3 exposes **20 tools** as a native MCP server. Your IDE calls them directly:
|
|
|
211
212
|
| `c3_jira` | Jira Cloud + Data Center — JQL, issues, transitions (v2.56.0) |
|
|
212
213
|
| `c3_project` | Cross-project discovery & operations; guarded writes (v2.31.0) |
|
|
213
214
|
|
|
214
|
-
Every tool is **read-only safe in plan mode** except `c3_edit`, `c3_shell`, `c3_artifacts(action='restore')`, `c3_delegate` with write delegation enabled, and write actions on `c3_bitbucket` / `c3_jira` / `c3_credentials` / `c3_project` / `c3_task`.
|
|
215
|
+
Every tool is **read-only safe in plan mode** except `c3_edit`, `c3_shell`, `c3_artifacts(action='restore')`, `c3_delegate` with write delegation enabled, and write actions on `c3_bitbucket` / `c3_jira` / `c3_credentials` / `c3_project` / `c3_task` / `c3_locks`.
|
|
215
216
|
|
|
216
217
|
On Windows `c3_shell` uses Git Bash when available. Git Bash bundles no `jq`; use `python -m json.tool` for portable JSON formatting.
|
|
217
218
|
|
|
@@ -242,12 +243,61 @@ c3 access mask activate # purge pre-mask artifacts, buil
|
|
|
242
243
|
- **Masked means read-only, always.** Cropped rows have no inverse, so an edit in transformed coordinates would corrupt the one file you protected.
|
|
243
244
|
- **Four deterministic presets, no LLM in the read path:** `redact_secrets`, `redact_columns` (salted one-way pseudonyms — joins survive, no reverse dictionary), `sample_rows`, `signatures_only`.
|
|
244
245
|
- **Rule changes are human-only** (UI tab or CLI) and ledger-logged. Agents have no mutation surface.
|
|
246
|
+
- **Built-ins can be switched off when you need to** (v2.65.0). `**/.env*`, `**/.c3/**`, `**/.claude/settings*.json` and `**/.git/**` yield to `c3 access builtin disable <glob>`, which makes you retype the glob first. It takes **two keys** — a config entry *and* a keyring attestation — so an agent that manages to write `config.json` still cannot grant itself write access to your settings. The credential vault stays absolute.
|
|
245
247
|
- **Honest coverage.** This guards *cooperative* agents against mistakes and prompt injection. It is not a sandbox — a raw shell outside C3's tools still sees the real bytes.
|
|
246
248
|
|
|
247
249
|
→ [Access Guard](https://github.com/drknowhow/code-context-control/blob/main/docs/access-guard.md) · [Mask Guard](https://github.com/drknowhow/code-context-control/blob/main/docs/mask-guard.md)
|
|
248
250
|
|
|
249
251
|
---
|
|
250
252
|
|
|
253
|
+
## Agent Locks — several agents, one repo (v2.65.0)
|
|
254
|
+
|
|
255
|
+
Guards answer *may the agent touch this?* Locks answer *is someone already touching it?*
|
|
256
|
+
|
|
257
|
+
Two agents editing one file used to be silent data loss. `c3_edit` serialized
|
|
258
|
+
same-file edits with an in-process lock, but every session runs its own `c3-mcp`
|
|
259
|
+
server — so two sessions could interleave read → replace → write and lose an edit
|
|
260
|
+
with no error on either side. Create mode was worse: both agents "succeeded" and
|
|
261
|
+
one file won.
|
|
262
|
+
|
|
263
|
+
Now there are two mechanisms, because they solve different problems:
|
|
264
|
+
|
|
265
|
+
- **Torn writes** — a cross-process file lock, held across create, single-edit and
|
|
266
|
+
batch alike. No daemon, no configuration, nothing to switch on.
|
|
267
|
+
- **Overlapping work** — a *lease*. `c3_edit` takes one on the file it edits,
|
|
268
|
+
carrying the intent from your edit summary. A second agent gets told who holds
|
|
269
|
+
it and why:
|
|
270
|
+
|
|
271
|
+
```text
|
|
272
|
+
[c3-lock:held] services/router.py is held by claude-code:a3f19c2b.
|
|
273
|
+
intent: "refactor retry backoff"
|
|
274
|
+
lease expires in 6m12s.
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
c3 locks list # who holds what, across the project
|
|
279
|
+
c3 locks force-release services/router.py # break a stuck lease (human-only, audited)
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
- **TTL is the real release mechanism.** Agents forget to release, so nothing
|
|
283
|
+
assumes they will — a crashed agent can never wedge a repo.
|
|
284
|
+
- **Acquisition is all-or-nothing** over a sorted path list, so two agents grabbing
|
|
285
|
+
the same pair in opposite order cannot deadlock.
|
|
286
|
+
- **`force-release` bumps a fencing counter**, so a holder that comes back is stale
|
|
287
|
+
by construction rather than by hope. It lives in the CLI and the Hub, never in
|
|
288
|
+
the agent-facing tool.
|
|
289
|
+
- **The Hub's Locks tab badges a project it cannot read as `UNREADABLE`**, not as
|
|
290
|
+
zero leases — "all clear" is a different claim from "we don't know".
|
|
291
|
+
- **Honest coverage, again.** Leases gate C3's own tool surfaces. A raw `c3_shell`
|
|
292
|
+
redirect, a non-Claude agent, or a human in an editor is *not* covered, and the
|
|
293
|
+
UI says so on screen.
|
|
294
|
+
|
|
295
|
+
Set `locks.enabled: false` in `.c3/config.json` to opt out.
|
|
296
|
+
|
|
297
|
+
→ [Agent Locks](https://github.com/drknowhow/code-context-control/blob/main/docs/agent-locks.md)
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
251
301
|
## Integrations
|
|
252
302
|
|
|
253
303
|
| | What you get | Guide |
|
|
@@ -123,7 +123,7 @@ Twelve tabs. The dashboard above shows token savings, indexed files, the live se
|
|
|
123
123
|
|
|
124
124
|
## The MCP tool suite
|
|
125
125
|
|
|
126
|
-
C3 exposes **
|
|
126
|
+
C3 exposes **21 tools** as a native MCP server. Your IDE calls them directly:
|
|
127
127
|
|
|
128
128
|
| Tool | What it does |
|
|
129
129
|
|---|---|
|
|
@@ -138,6 +138,7 @@ C3 exposes **20 tools** as a native MCP server. Your IDE calls them directly:
|
|
|
138
138
|
| `c3_memory` | Fact store with categories, recall, graph queries, `index`→`fetch` two-step |
|
|
139
139
|
| `c3_session` | Snapshot, restore, log decisions, compact history |
|
|
140
140
|
| `c3_impact` | Blast-radius analysis before editing shared symbols |
|
|
141
|
+
| `c3_locks` | Agent leases — who is working on which file, so two agents don't collide (v2.65.0) |
|
|
141
142
|
| `c3_delegate` | Offload heavy work to local Ollama / Codex / Gemini |
|
|
142
143
|
| `c3_agent` | Workflows: `review_changes`, `investigate`, `preflight`, `prepare_context`, `validate_compress` |
|
|
143
144
|
| `c3_edits` | Edit-ledger queries, version diffs, restore points, per-branch filter |
|
|
@@ -148,7 +149,7 @@ C3 exposes **20 tools** as a native MCP server. Your IDE calls them directly:
|
|
|
148
149
|
| `c3_jira` | Jira Cloud + Data Center — JQL, issues, transitions (v2.56.0) |
|
|
149
150
|
| `c3_project` | Cross-project discovery & operations; guarded writes (v2.31.0) |
|
|
150
151
|
|
|
151
|
-
Every tool is **read-only safe in plan mode** except `c3_edit`, `c3_shell`, `c3_artifacts(action='restore')`, `c3_delegate` with write delegation enabled, and write actions on `c3_bitbucket` / `c3_jira` / `c3_credentials` / `c3_project` / `c3_task`.
|
|
152
|
+
Every tool is **read-only safe in plan mode** except `c3_edit`, `c3_shell`, `c3_artifacts(action='restore')`, `c3_delegate` with write delegation enabled, and write actions on `c3_bitbucket` / `c3_jira` / `c3_credentials` / `c3_project` / `c3_task` / `c3_locks`.
|
|
152
153
|
|
|
153
154
|
On Windows `c3_shell` uses Git Bash when available. Git Bash bundles no `jq`; use `python -m json.tool` for portable JSON formatting.
|
|
154
155
|
|
|
@@ -179,12 +180,61 @@ c3 access mask activate # purge pre-mask artifacts, buil
|
|
|
179
180
|
- **Masked means read-only, always.** Cropped rows have no inverse, so an edit in transformed coordinates would corrupt the one file you protected.
|
|
180
181
|
- **Four deterministic presets, no LLM in the read path:** `redact_secrets`, `redact_columns` (salted one-way pseudonyms — joins survive, no reverse dictionary), `sample_rows`, `signatures_only`.
|
|
181
182
|
- **Rule changes are human-only** (UI tab or CLI) and ledger-logged. Agents have no mutation surface.
|
|
183
|
+
- **Built-ins can be switched off when you need to** (v2.65.0). `**/.env*`, `**/.c3/**`, `**/.claude/settings*.json` and `**/.git/**` yield to `c3 access builtin disable <glob>`, which makes you retype the glob first. It takes **two keys** — a config entry *and* a keyring attestation — so an agent that manages to write `config.json` still cannot grant itself write access to your settings. The credential vault stays absolute.
|
|
182
184
|
- **Honest coverage.** This guards *cooperative* agents against mistakes and prompt injection. It is not a sandbox — a raw shell outside C3's tools still sees the real bytes.
|
|
183
185
|
|
|
184
186
|
→ [Access Guard](https://github.com/drknowhow/code-context-control/blob/main/docs/access-guard.md) · [Mask Guard](https://github.com/drknowhow/code-context-control/blob/main/docs/mask-guard.md)
|
|
185
187
|
|
|
186
188
|
---
|
|
187
189
|
|
|
190
|
+
## Agent Locks — several agents, one repo (v2.65.0)
|
|
191
|
+
|
|
192
|
+
Guards answer *may the agent touch this?* Locks answer *is someone already touching it?*
|
|
193
|
+
|
|
194
|
+
Two agents editing one file used to be silent data loss. `c3_edit` serialized
|
|
195
|
+
same-file edits with an in-process lock, but every session runs its own `c3-mcp`
|
|
196
|
+
server — so two sessions could interleave read → replace → write and lose an edit
|
|
197
|
+
with no error on either side. Create mode was worse: both agents "succeeded" and
|
|
198
|
+
one file won.
|
|
199
|
+
|
|
200
|
+
Now there are two mechanisms, because they solve different problems:
|
|
201
|
+
|
|
202
|
+
- **Torn writes** — a cross-process file lock, held across create, single-edit and
|
|
203
|
+
batch alike. No daemon, no configuration, nothing to switch on.
|
|
204
|
+
- **Overlapping work** — a *lease*. `c3_edit` takes one on the file it edits,
|
|
205
|
+
carrying the intent from your edit summary. A second agent gets told who holds
|
|
206
|
+
it and why:
|
|
207
|
+
|
|
208
|
+
```text
|
|
209
|
+
[c3-lock:held] services/router.py is held by claude-code:a3f19c2b.
|
|
210
|
+
intent: "refactor retry backoff"
|
|
211
|
+
lease expires in 6m12s.
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
c3 locks list # who holds what, across the project
|
|
216
|
+
c3 locks force-release services/router.py # break a stuck lease (human-only, audited)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
- **TTL is the real release mechanism.** Agents forget to release, so nothing
|
|
220
|
+
assumes they will — a crashed agent can never wedge a repo.
|
|
221
|
+
- **Acquisition is all-or-nothing** over a sorted path list, so two agents grabbing
|
|
222
|
+
the same pair in opposite order cannot deadlock.
|
|
223
|
+
- **`force-release` bumps a fencing counter**, so a holder that comes back is stale
|
|
224
|
+
by construction rather than by hope. It lives in the CLI and the Hub, never in
|
|
225
|
+
the agent-facing tool.
|
|
226
|
+
- **The Hub's Locks tab badges a project it cannot read as `UNREADABLE`**, not as
|
|
227
|
+
zero leases — "all clear" is a different claim from "we don't know".
|
|
228
|
+
- **Honest coverage, again.** Leases gate C3's own tool surfaces. A raw `c3_shell`
|
|
229
|
+
redirect, a non-Claude agent, or a human in an editor is *not* covered, and the
|
|
230
|
+
UI says so on screen.
|
|
231
|
+
|
|
232
|
+
Set `locks.enabled: false` in `.c3/config.json` to opt out.
|
|
233
|
+
|
|
234
|
+
→ [Agent Locks](https://github.com/drknowhow/code-context-control/blob/main/docs/agent-locks.md)
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
188
238
|
## Integrations
|
|
189
239
|
|
|
190
240
|
| | What you get | Guide |
|
|
@@ -96,12 +96,111 @@ def _empty_state(session_id: str = "") -> dict:
|
|
|
96
96
|
return {"session_id": session_id or "", "last_c3_call": None, "unlocked_files": {}}
|
|
97
97
|
|
|
98
98
|
|
|
99
|
+
#: os.replace retries for when Windows briefly holds a handle on the target —
|
|
100
|
+
#: AV scanner, Search indexer, or a concurrent hook reading the same state.
|
|
101
|
+
_REPLACE_ATTEMPTS = 4
|
|
102
|
+
_REPLACE_BACKOFF_S = 0.02
|
|
103
|
+
|
|
104
|
+
|
|
99
105
|
def _atomic_write_json(path: Path, data: dict) -> None:
|
|
100
|
-
"""Write JSON
|
|
106
|
+
"""Write JSON durably: temp file in the same directory + os.replace.
|
|
107
|
+
|
|
108
|
+
Three failure modes this guards against, all observed in the wild
|
|
109
|
+
(10 orphaned .tmp<pid> files and a truncated enforcement_state.json on a
|
|
110
|
+
Windows box before v2.66):
|
|
111
|
+
|
|
112
|
+
1. **Torn write.** Without fsync, os.replace can publish a file whose
|
|
113
|
+
bytes are still in the OS cache. A crash or power loss then leaves a
|
|
114
|
+
zero-length or half-written JSON that every later read quarantines —
|
|
115
|
+
which silently drops all sticky unlocks and makes enforcement *more*
|
|
116
|
+
aggressive, not less.
|
|
117
|
+
2. **Orphaned temp files.** If os.replace raised, the temp file was
|
|
118
|
+
simply abandoned. They accumulate forever in .c3/ and are easy to
|
|
119
|
+
mistake for real state.
|
|
120
|
+
3. **Transient Windows sharing violations.** Another process holding a
|
|
121
|
+
read handle on the target makes os.replace raise PermissionError; a
|
|
122
|
+
single attempt turned that into a lost write.
|
|
123
|
+
"""
|
|
124
|
+
import time
|
|
125
|
+
|
|
101
126
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
102
127
|
tmp = path.with_name(f"{path.name}.tmp{os.getpid()}")
|
|
103
|
-
|
|
104
|
-
|
|
128
|
+
try:
|
|
129
|
+
with open(tmp, "w", encoding="utf-8") as fh:
|
|
130
|
+
json.dump(data, fh)
|
|
131
|
+
fh.flush()
|
|
132
|
+
os.fsync(fh.fileno()) # durability before publish (fixes #1)
|
|
133
|
+
|
|
134
|
+
last_exc = None
|
|
135
|
+
for attempt in range(_REPLACE_ATTEMPTS):
|
|
136
|
+
try:
|
|
137
|
+
os.replace(tmp, path)
|
|
138
|
+
return
|
|
139
|
+
except PermissionError as exc: # fixes #3
|
|
140
|
+
last_exc = exc
|
|
141
|
+
if attempt < _REPLACE_ATTEMPTS - 1:
|
|
142
|
+
time.sleep(_REPLACE_BACKOFF_S * (2 ** attempt))
|
|
143
|
+
if last_exc is not None:
|
|
144
|
+
raise last_exc
|
|
145
|
+
finally:
|
|
146
|
+
# fixes #2 — a successful replace already consumed tmp, so this only
|
|
147
|
+
# fires on the failure paths.
|
|
148
|
+
try:
|
|
149
|
+
if tmp.exists():
|
|
150
|
+
tmp.unlink()
|
|
151
|
+
except OSError:
|
|
152
|
+
pass
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def sweep_stale_temps(project_path: Path | None = None) -> int:
|
|
156
|
+
"""Remove orphaned *.tmp<pid> files left by older C3 builds.
|
|
157
|
+
|
|
158
|
+
Only touches temp files whose owning PID is gone, so a concurrent hook
|
|
159
|
+
mid-write is never disturbed. Returns how many were removed; never raises.
|
|
160
|
+
"""
|
|
161
|
+
removed = 0
|
|
162
|
+
try:
|
|
163
|
+
base = project_path if project_path is not None else Path.cwd()
|
|
164
|
+
c3_dir = base / ".c3"
|
|
165
|
+
if not c3_dir.is_dir():
|
|
166
|
+
return 0
|
|
167
|
+
for tmp in c3_dir.glob("*.tmp*"):
|
|
168
|
+
suffix = tmp.name.rsplit(".tmp", 1)[-1]
|
|
169
|
+
if not suffix.isdigit():
|
|
170
|
+
continue
|
|
171
|
+
if _pid_alive(int(suffix)):
|
|
172
|
+
continue
|
|
173
|
+
try:
|
|
174
|
+
tmp.unlink()
|
|
175
|
+
removed += 1
|
|
176
|
+
except OSError:
|
|
177
|
+
pass
|
|
178
|
+
except Exception:
|
|
179
|
+
pass
|
|
180
|
+
return removed
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def _pid_alive(pid: int) -> bool:
|
|
184
|
+
"""Best-effort liveness check. On error assume ALIVE (don't delete)."""
|
|
185
|
+
if pid <= 0:
|
|
186
|
+
return False
|
|
187
|
+
try:
|
|
188
|
+
if os.name == "nt":
|
|
189
|
+
import ctypes
|
|
190
|
+
# PROCESS_QUERY_LIMITED_INFORMATION — works without elevation.
|
|
191
|
+
handle = ctypes.windll.kernel32.OpenProcess(0x1000, False, pid)
|
|
192
|
+
if not handle:
|
|
193
|
+
return False
|
|
194
|
+
ctypes.windll.kernel32.CloseHandle(handle)
|
|
195
|
+
return True
|
|
196
|
+
os.kill(pid, 0)
|
|
197
|
+
return True
|
|
198
|
+
except ProcessLookupError:
|
|
199
|
+
return False
|
|
200
|
+
except PermissionError:
|
|
201
|
+
return True # exists but not ours
|
|
202
|
+
except Exception:
|
|
203
|
+
return True # unknown → conservative
|
|
105
204
|
|
|
106
205
|
|
|
107
206
|
def _read_legacy_state(base: Path) -> dict:
|
|
@@ -163,6 +262,10 @@ def load_enforcement_state(project_path: Path | None = None, session_id: str = "
|
|
|
163
262
|
state_path.replace(state_path.with_name(state_path.name + ".corrupt"))
|
|
164
263
|
except Exception:
|
|
165
264
|
pass
|
|
265
|
+
# Corruption is the one reliable signal that a previous write went
|
|
266
|
+
# wrong, so it is also the moment to clear any temp files that
|
|
267
|
+
# write orphaned (pre-v2.66 _atomic_write_json had no cleanup).
|
|
268
|
+
sweep_stale_temps(base)
|
|
166
269
|
STATE_WARNINGS.append(
|
|
167
270
|
"[c3:hook-error] enforcement_state: corrupted "
|
|
168
271
|
f"{ENFORCEMENT_STATE_FILE} quarantined ({type(exc).__name__}); "
|