code-context-control 2.66.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.66.0/code_context_control.egg-info → code_context_control-2.67.0}/PKG-INFO +53 -3
- {code_context_control-2.66.0 → code_context_control-2.67.0}/README.md +52 -2
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/c3.py +1 -1
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_server.py +170 -37
- {code_context_control-2.66.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.66.0 → code_context_control-2.67.0}/cli/server.py +18 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0/code_context_control.egg-info}/PKG-INFO +53 -3
- {code_context_control-2.66.0 → code_context_control-2.67.0}/pyproject.toml +1 -1
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/access_telemetry.py +48 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/enforcement_policy.py +140 -30
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_enforcement_policy.py +228 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_enforcement_routes.py +19 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_hub_enforcement_routes.py +204 -0
- code_context_control-2.66.0/cli/hub_ui/components/hub_enforcement.js +0 -342
- {code_context_control-2.66.0 → code_context_control-2.67.0}/LICENSE +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/__init__.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/_hook_utils.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/commands/__init__.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/commands/common.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/commands/parser.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/docs.html +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/edits.html +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/guide/access.html +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/guide/bitbucket.html +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/guide/credentials.html +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/guide/getting-started.html +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/guide/index.html +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/guide/masking.html +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/guide/oracle.html +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/guide/shared.css +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/guide/tools.html +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/guide/workflow.html +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hook_access_guard.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hook_artifact.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hook_auto_snapshot.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hook_c3_signal.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hook_c3read.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hook_dispatch.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hook_edit_ledger.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hook_edit_unlock.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hook_filter.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hook_ghost_files.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hook_pretool_enforce.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hook_prompt_recall.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hook_read.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hook_session_stats.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hook_terse_advisor.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/app.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/add_project.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/config_editor.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_health.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_tasks.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_views.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/global_search.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/hub_credentials.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/hub_locks.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/mcp_manager.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/modals.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/project_card.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/project_tree.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/session_drawer.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/settings_modal.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/sidebar.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/summary_bar.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/task_board.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/toasts.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/topbar.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/state.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui.html +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/mcp_proxy.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/mcp_server.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/progress.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/__init__.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/_helpers.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/agent.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/artifacts.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/bitbucket.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/compress.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/credentials.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/delegate.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/edit.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/edits.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/federate.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/filter.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/impact.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/jira.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/locks.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/memory.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/project.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/read.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/search.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/session.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/shell.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/status.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/tasks.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/tools/validate.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/api.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/app.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/components/access.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/components/bitbucket.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/components/chat.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/components/credentials.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/components/dashboard.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/components/edits.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/components/enforcement.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/components/instructions.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/components/jira.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/components/memory.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/components/sessions.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/components/settings.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/components/sidebar.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/components/tasks.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/icons.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/pm_shared.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/shared.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui/theme.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui.html +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui_legacy.html +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/cli/ui_nano.html +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/code_context_control.egg-info/SOURCES.txt +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/code_context_control.egg-info/dependency_links.txt +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/code_context_control.egg-info/entry_points.txt +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/code_context_control.egg-info/requires.txt +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/code_context_control.egg-info/top_level.txt +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/core/__init__.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/core/config.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/core/ide.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/core/mcp_toml.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/core/web_security.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/__init__.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/config.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/mcp_oracle.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/oracle_server.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/oracle_ui.html +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/__init__.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/activity_reporter.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/api_auth.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/c3_bridge.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/chat_engine.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/chat_store.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/cross_memory.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/discovery_audit.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/federated_graph.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/health_checker.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/insight_engine.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/local_session.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/memory_reader.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/memory_writer.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/project_scanner.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/review_agent.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/tool_executor.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/services/tool_registry.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/activity.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/agents.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/app.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/busy.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/chat/conversations.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/chat/input.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/chat/markdown.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/chat/send.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/chat/stream_renderer.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/chat/toolbar.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/core.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/crossgraph.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/header.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/insights.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/projects.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/settings.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/suggestions.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/oracle/ui/theme_tabs.js +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/__init__.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/access_guard.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/activity_log.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/agent_base.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/agent_locks.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/agents.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/artifact_defs.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/artifact_store.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/auto_memory.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/bench/__init__.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/bench/external/__init__.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/bench/external/aider_polyglot.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/bench/external/swe_bench.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/benchmark_dashboard.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/bitbucket_client.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/bitbucket_credentials.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/circuit_breaker.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/claude_md.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/compressor.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/context_snapshot.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/conversation_store.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/credential_store.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/doc_index.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/e2e_benchmark.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/e2e_evaluator.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/e2e_tasks.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/edit_ledger.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/embedding_index.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/error_reporting.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/file_memory.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/git_context.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/hub_service.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/indexer.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/jira_client.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/jira_cloud.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/jira_credentials.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/jira_data_center.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/jira_links.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/mask_activation.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/mask_mirror.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/mask_presets.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/memory.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/memory_consolidator.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/memory_distiller.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/memory_graph.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/memory_grounder.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/memory_queue.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/memory_scorer.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/metrics.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/notifications.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/ollama_bridge.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/ollama_client.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/ollama_credentials.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/output_filter.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/parser.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/project_manager.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/project_runtime.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/protocol.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/proxy_state.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/repo_map.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/retention.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/retrieval_broker.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/router.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/runtime.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/scanner.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/session_benchmark.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/session_manager.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/session_preloader.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/subprojects.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/task_store.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/telemetry.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/text_index.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/time_tracker.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/tool_classifier.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/transcript_index.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/validation_cache.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/vector_store.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/watcher.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/services/win_subprocess.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/setup.cfg +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_access_builtin_optout.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_access_guard.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_access_guard_meta.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_access_guard_shell_project.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_access_guard_surfaces.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_access_guard_wiring.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_activity_reporter.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_agent_locks.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_aider_polyglot.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_antigravity_transition.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_artifact_store.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_artifact_tool.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_bitbucket_cli_smoke.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_bitbucket_client.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_bitbucket_config_fallback.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_bitbucket_credentials.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_bitbucket_tool.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_c3_shell.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_circuit_breaker.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_claude_md_merge.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_cli_smoke.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_compressor_large_file.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_credential_store.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_credentials_routes.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_credentials_tool.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_creds_cli_smoke.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_delegate_cascade.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_e2e_benchmark.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_edit_ledger_hook.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_edit_locking.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_edit_normalization.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_enforcement_flip.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_federated_graph.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_filter_backoff.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_ghost_files.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_ghost_generation.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_git_branch_awareness.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_hook_access_guard.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_hook_dispatch.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_hook_pretool_enforce.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_hook_prompt_recall.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_hook_smoke.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_hook_state.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_hook_utf8_stdio.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_hub_credentials_route.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_hub_credentials_routes_write.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_hub_inspect_api.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_hub_locks_routes.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_hub_server_smoke.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_hub_subproject_links.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_ide_workflow_adaptation.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_init_scan.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_install_mcp_entrypoint.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_jira_cli_smoke.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_jira_client.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_jira_config_fallback.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_jira_credentials.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_jira_links.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_jira_routes.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_jira_tool.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_lazy_store_init.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_mask_guard.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_mask_routes.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_mask_surfaces.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_mcp_host_guard.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_mcp_memory_timeout.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_mcp_server_smoke.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_mcp_toml.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_memory_distiller.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_memory_graph_api.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_memory_queue.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_memory_system.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_no_stale_model_pins.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_notification_dedup.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_notification_discipline.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_ollama_credentials.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_oracle_api_auth.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_oracle_apikey_api.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_oracle_c3_bridge.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_oracle_chat_engine.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_oracle_chat_store.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_oracle_discovery_api.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_oracle_discovery_audit.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_oracle_local_auth.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_oracle_ollama_bridge.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_oracle_scanner_cache.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_oracle_security_fixes.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_oracle_session_bootstrap.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_oracle_subproject_awareness.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_oracle_ui_bundle.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_output_filter.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_permissions.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_pm_api.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_project_manager.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_project_manager_merge.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_project_tool.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_read_coercion.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_read_edit_parity.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_related_facts.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_repo_map.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_response_boilerplate.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_retention.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_review_digest.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_service_durability.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_session_benchmark.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_session_budget.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_shell_creds.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_shell_robustness.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_subproject_exclusion.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_subproject_federation.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_subprojects.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_swe_bench.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_task_store.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_task_tool.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_time_tracker.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_token_telemetry.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_tool_registry.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_upgrade_and_version.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_validate.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_vault_write_guard.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_version_sync.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_web_security.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tests/test_windows_reliability.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/__init__.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/backend.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/main.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/screens/__init__.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/screens/benchmark_view.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/screens/claudemd_view.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/screens/compress_view.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/screens/index_view.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/screens/init_view.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/screens/mcp_view.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/screens/optimize_view.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/screens/pipe_view.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/screens/projects_view.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/screens/search_view.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/screens/session_view.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/screens/stats.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/screens/ui_view.py +0 -0
- {code_context_control-2.66.0 → code_context_control-2.67.0}/tui/theme.tcss +0 -0
{code_context_control-2.66.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 |
|
|
@@ -435,9 +435,9 @@ def api_hub_config_set():
|
|
|
435
435
|
cfg["projects_view"] = projects_view
|
|
436
436
|
if "main_view" in data:
|
|
437
437
|
main_view = str(data["main_view"]).strip().lower()
|
|
438
|
-
if main_view not in {"projects", "board", "creds", "locks"}:
|
|
438
|
+
if main_view not in {"projects", "board", "creds", "locks", "enforce"}:
|
|
439
439
|
return jsonify({"error": "main_view must be 'projects', 'board', "
|
|
440
|
-
"'creds' or '
|
|
440
|
+
"'creds', 'locks' or 'enforce'"}), 400
|
|
441
441
|
cfg["main_view"] = main_view
|
|
442
442
|
if "oracle_url" in data:
|
|
443
443
|
cfg["oracle_url"] = str(data["oracle_url"]).strip()
|
|
@@ -1723,6 +1723,9 @@ def api_search_global():
|
|
|
1723
1723
|
_CONFIG_READ_SECTIONS = ("hybrid", "agents", "delegate", "proxy", "mcp", "bitbucket", "meta",
|
|
1724
1724
|
"memory_llm")
|
|
1725
1725
|
_CONFIG_WRITE_SECTIONS = ("hybrid", "agents", "delegate", "proxy", "mcp", "meta", "memory_llm")
|
|
1726
|
+
# "enforcement" is deliberately NOT writable here: the generic deep-merge would
|
|
1727
|
+
# bypass mode/ttl/blocked_tools validation and the set_by provenance rules.
|
|
1728
|
+
# POST /api/projects/enforcement is the only write path.
|
|
1726
1729
|
# api_key: secrets never transit the hub or land in config.json — the Ollama
|
|
1727
1730
|
# cloud key lives in the OS keyring (project Settings UI / OLLAMA_API_KEY env).
|
|
1728
1731
|
_CONFIG_REFUSED_KEYS = ("version", "project_path", "permission_tier", "subprojects", "parent",
|
|
@@ -2166,6 +2169,7 @@ def api_hub_enforcement_overview():
|
|
|
2166
2169
|
row["set_by"] = policy.set_by
|
|
2167
2170
|
row["signal_ttl_s"] = policy.signal_ttl_s
|
|
2168
2171
|
row["warnings"] = list(policy.warnings)
|
|
2172
|
+
row["blocked_tools"] = sorted(policy.blocked_tools)
|
|
2169
2173
|
|
|
2170
2174
|
cfg_path = Path(ppath) / ".c3" / "config.json"
|
|
2171
2175
|
try:
|
|
@@ -2188,12 +2192,28 @@ def api_hub_enforcement_overview():
|
|
|
2188
2192
|
row["error"] = str(e)
|
|
2189
2193
|
rows.append(row)
|
|
2190
2194
|
|
|
2195
|
+
# The global (~/.c3) section, shown as its own card. A corrupt global
|
|
2196
|
+
# config must not blank the tab — report the error inside the object.
|
|
2197
|
+
try:
|
|
2198
|
+
g = ep.resolve_global()
|
|
2199
|
+
global_policy = {
|
|
2200
|
+
"configured": g.scope == "global",
|
|
2201
|
+
"mode": g.mode or None,
|
|
2202
|
+
"set_by": g.set_by,
|
|
2203
|
+
"signal_ttl_s": g.signal_ttl_s,
|
|
2204
|
+
"blocked_tools": sorted(g.blocked_tools),
|
|
2205
|
+
"warnings": list(g.warnings),
|
|
2206
|
+
}
|
|
2207
|
+
except Exception as e:
|
|
2208
|
+
global_policy = {"configured": False, "mode": None, "error": str(e)}
|
|
2209
|
+
|
|
2191
2210
|
return jsonify({
|
|
2192
2211
|
"projects": rows,
|
|
2193
2212
|
"modes": [{"id": m, "help": ep.MODE_HELP[m]} for m in ep.MODES],
|
|
2194
2213
|
"default_mode": ep.DEFAULT_MODE,
|
|
2195
2214
|
"tier_map": ep.TIER_TO_MODE,
|
|
2196
2215
|
"totals": totals,
|
|
2216
|
+
"global_policy": global_policy,
|
|
2197
2217
|
# Stated so the tab can never imply that turning discipline down also
|
|
2198
2218
|
# turns the security boundaries down. Mirrors docs/enforcement.md.
|
|
2199
2219
|
"coverage_note": (
|
|
@@ -2206,58 +2226,171 @@ def api_hub_enforcement_overview():
|
|
|
2206
2226
|
})
|
|
2207
2227
|
|
|
2208
2228
|
|
|
2229
|
+
@app.route("/api/projects/enforcement", methods=["GET"])
|
|
2230
|
+
def api_projects_enforcement_get():
|
|
2231
|
+
"""One project's effective policy plus its denial evidence.
|
|
2232
|
+
|
|
2233
|
+
Hub-side mirror of the per-project GET /api/enforcement — feeds the drill
|
|
2234
|
+
panel's Discipline tab. Optional ``?session=`` narrows the denial
|
|
2235
|
+
aggregate to one session id (full id; the event search route does prefix
|
|
2236
|
+
matching for the UI's 8-char short ids).
|
|
2237
|
+
"""
|
|
2238
|
+
from services import access_telemetry as at
|
|
2239
|
+
from services import enforcement_policy as ep
|
|
2240
|
+
|
|
2241
|
+
path = (request.args.get("path") or "").strip()
|
|
2242
|
+
if not path:
|
|
2243
|
+
return jsonify({"error": "path is required"}), 400
|
|
2244
|
+
try:
|
|
2245
|
+
resolved = _resolve_project_path(path)
|
|
2246
|
+
except ValueError as e:
|
|
2247
|
+
return jsonify({"error": str(e)}), 404
|
|
2248
|
+
|
|
2249
|
+
policy = ep.resolve(resolved)
|
|
2250
|
+
try:
|
|
2251
|
+
cfg = json.loads((Path(resolved) / ".c3" / "config.json")
|
|
2252
|
+
.read_text(encoding="utf-8"))
|
|
2253
|
+
tier = str(cfg.get("permission_tier") or "") if isinstance(cfg, dict) else ""
|
|
2254
|
+
except Exception:
|
|
2255
|
+
tier = ""
|
|
2256
|
+
session = (request.args.get("session") or "").strip()
|
|
2257
|
+
agg = at.aggregate(resolved, session_id=session)
|
|
2258
|
+
|
|
2259
|
+
return jsonify({
|
|
2260
|
+
"mode": policy.mode,
|
|
2261
|
+
"scope": policy.scope,
|
|
2262
|
+
"set_by": policy.set_by,
|
|
2263
|
+
"signal_ttl_s": policy.signal_ttl_s,
|
|
2264
|
+
"blocked_tools": sorted(policy.blocked_tools),
|
|
2265
|
+
"warnings": list(policy.warnings),
|
|
2266
|
+
"tier": tier,
|
|
2267
|
+
"tier_implies": ep.derive_from_tier(tier) if tier else "",
|
|
2268
|
+
"default_mode": ep.DEFAULT_MODE,
|
|
2269
|
+
"modes": [{"id": m, "help": ep.MODE_HELP[m]} for m in ep.MODES],
|
|
2270
|
+
"denials": {
|
|
2271
|
+
"total": agg["total"],
|
|
2272
|
+
"by_layer": agg["by_layer"],
|
|
2273
|
+
"rows": [{**r, "fix": at.suggest(r)} for r in agg["rows"][:12]],
|
|
2274
|
+
},
|
|
2275
|
+
})
|
|
2276
|
+
|
|
2277
|
+
|
|
2209
2278
|
@app.route("/api/projects/enforcement", methods=["POST"])
|
|
2210
2279
|
def api_projects_enforcement_set():
|
|
2211
|
-
"""Set
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2280
|
+
"""Set tool-discipline policy fields. Human-only, audited on target.
|
|
2281
|
+
|
|
2282
|
+
Body: ``{path?, scope?, mode?, signal_ttl_s?, blocked_tools?}``.
|
|
2283
|
+
``scope`` defaults to project (``path`` required); ``global`` writes
|
|
2284
|
+
``~/.c3`` and ignores ``path``. A body with ``mode`` goes through
|
|
2285
|
+
``set_mode`` — always ``set_by='user'``: a change made deliberately in
|
|
2286
|
+
the Hub is an explicit choice and must survive a later permission-tier
|
|
2287
|
+
change, the same as `c3 enforce`. A mode-less body goes through
|
|
2288
|
+
``set_fields``, which never touches ``mode``/``set_by``.
|
|
2216
2289
|
"""
|
|
2217
2290
|
from services import enforcement_policy as ep
|
|
2218
2291
|
|
|
2219
2292
|
data = request.get_json(force=True) or {}
|
|
2220
2293
|
path = (data.get("path") or "").strip()
|
|
2294
|
+
scope = (data.get("scope") or "project").strip().lower()
|
|
2221
2295
|
mode = (data.get("mode") or "").strip().lower()
|
|
2222
2296
|
ttl = data.get("signal_ttl_s")
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2297
|
+
blocked = data.get("blocked_tools")
|
|
2298
|
+
if scope not in ("project", "global"):
|
|
2299
|
+
return jsonify({"error": "scope must be 'project' or 'global'"}), 400
|
|
2300
|
+
if scope == "project":
|
|
2301
|
+
if not path:
|
|
2302
|
+
return jsonify({"error": "path is required for project scope"}), 400
|
|
2303
|
+
try:
|
|
2304
|
+
resolved = _resolve_project_path(path)
|
|
2305
|
+
except ValueError as e:
|
|
2306
|
+
return jsonify({"error": str(e)}), 404
|
|
2307
|
+
else:
|
|
2308
|
+
resolved = "."
|
|
2229
2309
|
|
|
2230
2310
|
try:
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2311
|
+
if mode:
|
|
2312
|
+
result = ep.set_mode(mode, resolved, set_by=ep.SET_BY_USER,
|
|
2313
|
+
scope=scope, signal_ttl_s=ttl,
|
|
2314
|
+
blocked_tools=blocked)
|
|
2315
|
+
elif ttl is not None or blocked is not None:
|
|
2316
|
+
result = ep.set_fields(resolved, scope=scope,
|
|
2317
|
+
signal_ttl_s=ttl, blocked_tools=blocked)
|
|
2318
|
+
else:
|
|
2319
|
+
return jsonify({"error": "nothing to set — pass mode, "
|
|
2320
|
+
"signal_ttl_s or blocked_tools"}), 400
|
|
2234
2321
|
except (ValueError, TypeError) as e:
|
|
2235
2322
|
return jsonify({"error": str(e)}), 400
|
|
2236
2323
|
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
summary=(f"tool discipline {result.get('previous') or 'default'} "
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2324
|
+
# Audit on the target project. Global scope has no target project to
|
|
2325
|
+
# audit into — the ~/.c3/config.json write is itself the record.
|
|
2326
|
+
if scope == "project":
|
|
2327
|
+
action = "set_mode" if mode else "set_fields"
|
|
2328
|
+
detail = {"kind": "enforcement", "action": action,
|
|
2329
|
+
"mode": result.get("mode", ""),
|
|
2330
|
+
"previous": result.get("previous", ""),
|
|
2331
|
+
"scope": result["scope"], "via": "hub"}
|
|
2332
|
+
if "signal_ttl_s" in result:
|
|
2333
|
+
detail["signal_ttl_s"] = result["signal_ttl_s"]
|
|
2334
|
+
if "blocked_tools" in result:
|
|
2335
|
+
detail["blocked_tools"] = result["blocked_tools"]
|
|
2336
|
+
if mode:
|
|
2337
|
+
summary = (f"tool discipline {result.get('previous') or 'default'} "
|
|
2338
|
+
f"-> {result['mode']} via the Hub")
|
|
2339
|
+
else:
|
|
2340
|
+
parts = []
|
|
2341
|
+
if "signal_ttl_s" in result:
|
|
2342
|
+
parts.append(f"signal_ttl_s={result['signal_ttl_s']}")
|
|
2343
|
+
if "blocked_tools" in result:
|
|
2344
|
+
parts.append("blocked_tools="
|
|
2345
|
+
+ ",".join(result["blocked_tools"] or ["<none>"]))
|
|
2346
|
+
summary = "tool discipline " + ", ".join(parts) + " via the Hub"
|
|
2347
|
+
try:
|
|
2348
|
+
from services.activity_log import ActivityLog
|
|
2349
|
+
ActivityLog(resolved).log("access_action", dict(detail))
|
|
2350
|
+
except Exception:
|
|
2351
|
+
pass
|
|
2352
|
+
try:
|
|
2353
|
+
from services.edit_ledger import EditLedger
|
|
2354
|
+
EditLedger(resolved).log_edit(
|
|
2355
|
+
file=f"enforcement://{result['scope']}",
|
|
2356
|
+
change_type=f"enforcement_{action}",
|
|
2357
|
+
summary=summary,
|
|
2358
|
+
tags=["enforcement", "access"],
|
|
2359
|
+
detail=detail)
|
|
2360
|
+
except Exception:
|
|
2361
|
+
pass
|
|
2258
2362
|
return jsonify(result)
|
|
2259
2363
|
|
|
2260
2364
|
|
|
2365
|
+
@app.route("/api/projects/enforcement/denials/search", methods=["GET"])
|
|
2366
|
+
def api_projects_enforcement_denials_search():
|
|
2367
|
+
"""Search one project's raw denial events. Read-only; newest first.
|
|
2368
|
+
|
|
2369
|
+
Params: ``path`` (required), ``q`` (AND'd case-insensitive substrings over
|
|
2370
|
+
path/rule/tool), ``layer``, ``tool`` (exact), ``session`` (prefix — the UI
|
|
2371
|
+
shows 8-char short ids), ``since`` (ISO-8601; events store
|
|
2372
|
+
second-resolution UTC isoformat, so plain string comparison is correct),
|
|
2373
|
+
``limit`` (default 200, cap 500).
|
|
2374
|
+
"""
|
|
2375
|
+
from services import access_telemetry as at
|
|
2376
|
+
|
|
2377
|
+
path = (request.args.get("path") or "").strip()
|
|
2378
|
+
if not path:
|
|
2379
|
+
return jsonify({"error": "path is required"}), 400
|
|
2380
|
+
try:
|
|
2381
|
+
resolved = _resolve_project_path(path)
|
|
2382
|
+
except ValueError as e:
|
|
2383
|
+
return jsonify({"error": str(e)}), 404
|
|
2384
|
+
return jsonify(at.search_events(
|
|
2385
|
+
resolved,
|
|
2386
|
+
q=request.args.get("q") or "",
|
|
2387
|
+
layer=request.args.get("layer") or "",
|
|
2388
|
+
tool=request.args.get("tool") or "",
|
|
2389
|
+
session=request.args.get("session") or "",
|
|
2390
|
+
since=request.args.get("since") or "",
|
|
2391
|
+
limit=request.args.get("limit") or 200))
|
|
2392
|
+
|
|
2393
|
+
|
|
2261
2394
|
@app.route("/api/projects/enforcement/denials", methods=["DELETE"])
|
|
2262
2395
|
def api_projects_enforcement_denials_clear():
|
|
2263
2396
|
"""Reset one project's denial counters (they are diagnostics, not audit)."""
|
{code_context_control-2.66.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_panel.js
RENAMED
|
@@ -14,6 +14,7 @@ const DRILL_PANEL_TABS = [
|
|
|
14
14
|
['health', 'Health'],
|
|
15
15
|
['budget', 'Budget'],
|
|
16
16
|
['creds', 'Credentials'],
|
|
17
|
+
['discipline', 'Discipline'],
|
|
17
18
|
['config', 'Config'],
|
|
18
19
|
['mcp', 'MCP'],
|
|
19
20
|
];
|
|
@@ -134,6 +135,7 @@ function DrillPanel({ project, tab, setTab, onClose, onChanged, onOpenModal, pro
|
|
|
134
135
|
case 'health': return <DrillHealth project={project} onChanged={onChanged} />;
|
|
135
136
|
case 'budget': return <DrillBudget project={project} />;
|
|
136
137
|
case 'creds': return <DrillCredentials project={project} />;
|
|
138
|
+
case 'discipline': return <DrillDiscipline project={project} />;
|
|
137
139
|
case 'config': return <ConfigEditor project={project} />;
|
|
138
140
|
case 'mcp': return <McpManager project={project} onChanged={onChanged} />;
|
|
139
141
|
default: return <DrillOverview project={project} onChanged={onChanged} setTab={setTab} />;
|