code-context-control 2.73.0__tar.gz → 2.74.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.73.0/code_context_control.egg-info → code_context_control-2.74.0}/PKG-INFO +1 -1
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/c3.py +1 -1
- {code_context_control-2.73.0 → code_context_control-2.74.0/code_context_control.egg-info}/PKG-INFO +1 -1
- {code_context_control-2.73.0 → code_context_control-2.74.0}/pyproject.toml +1 -1
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/access_guard.py +38 -10
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/notifications.py +22 -1
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/override_requests.py +6 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_override_requests.py +125 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/LICENSE +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/README.md +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/__init__.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/_hook_utils.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/commands/__init__.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/commands/common.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/commands/parser.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/docs.html +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/edits.html +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/guide/access.html +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/guide/bitbucket.html +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/guide/credentials.html +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/guide/getting-started.html +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/guide/index.html +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/guide/masking.html +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/guide/oracle.html +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/guide/shared.css +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/guide/tools.html +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/guide/workflow.html +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hook_access_guard.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hook_artifact.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hook_auto_snapshot.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hook_c3_signal.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hook_c3read.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hook_dispatch.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hook_edit_ledger.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hook_edit_unlock.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hook_filter.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hook_ghost_files.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hook_pretool_enforce.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hook_prompt_recall.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hook_read.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hook_session_stats.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hook_terse_advisor.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_server.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/app.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/add_project.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/config_editor.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/drill_health.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/drill_panel.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/drill_tasks.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/drill_views.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/global_search.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/hub_credentials.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/hub_locks.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/mcp_manager.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/modals.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/project_card.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/project_tree.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/session_drawer.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/settings_modal.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/sidebar.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/summary_bar.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/task_board.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/toasts.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/topbar.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/state.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui.html +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/mcp_proxy.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/mcp_server.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/progress.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/server.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/__init__.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/_grants.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/_helpers.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/agent.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/artifacts.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/bitbucket.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/compress.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/credentials.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/delegate.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/edit.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/edits.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/federate.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/filter.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/impact.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/jira.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/locks.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/memory.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/override.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/project.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/read.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/search.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/session.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/shell.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/status.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/tasks.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/tools/validate.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/api.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/app.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/components/access.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/components/bitbucket.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/components/chat.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/components/credentials.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/components/dashboard.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/components/edits.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/components/enforcement.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/components/instructions.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/components/jira.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/components/memory.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/components/sessions.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/components/settings.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/components/sidebar.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/components/tasks.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/icons.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/pm_shared.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/shared.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/theme.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui.html +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui_legacy.html +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui_nano.html +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/code_context_control.egg-info/SOURCES.txt +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/code_context_control.egg-info/dependency_links.txt +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/code_context_control.egg-info/entry_points.txt +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/code_context_control.egg-info/requires.txt +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/code_context_control.egg-info/top_level.txt +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/core/__init__.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/core/config.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/core/ide.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/core/mcp_toml.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/core/web_security.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/__init__.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/config.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/mcp_oracle.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/oracle_server.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/oracle_ui.html +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/__init__.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/activity_reporter.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/api_auth.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/c3_bridge.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/chat_engine.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/chat_store.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/cross_memory.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/discovery_audit.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/federated_graph.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/health_checker.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/insight_engine.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/local_session.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/memory_reader.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/memory_writer.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/mobile_api.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/project_scanner.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/review_agent.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/tool_executor.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/services/tool_registry.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/activity.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/agents.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/app.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/busy.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/chat/conversations.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/chat/input.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/chat/markdown.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/chat/send.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/chat/stream_renderer.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/chat/toolbar.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/core.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/crossgraph.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/header.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/insights.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/projects.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/qrcode.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/settings.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/suggestions.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/oracle/ui/theme_tabs.js +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/__init__.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/access_telemetry.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/activity_log.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/agent_base.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/agent_locks.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/agents.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/artifact_defs.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/artifact_store.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/auto_memory.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/bench/__init__.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/bench/external/__init__.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/bench/external/aider_polyglot.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/bench/external/swe_bench.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/benchmark_dashboard.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/bitbucket_client.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/bitbucket_credentials.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/circuit_breaker.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/claude_md.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/compressor.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/context_snapshot.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/conversation_store.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/credential_store.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/doc_index.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/e2e_benchmark.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/e2e_evaluator.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/e2e_tasks.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/edit_ledger.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/embedding_index.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/enforcement_policy.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/error_reporting.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/file_memory.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/git_context.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/hub_service.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/indexer.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/jira_client.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/jira_cloud.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/jira_credentials.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/jira_data_center.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/jira_links.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/mask_activation.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/mask_mirror.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/mask_presets.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/memory.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/memory_consolidator.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/memory_distiller.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/memory_graph.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/memory_grounder.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/memory_queue.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/memory_scorer.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/metrics.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/ollama_bridge.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/ollama_client.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/ollama_credentials.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/output_filter.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/override_grants.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/override_policy.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/override_wake.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/parser.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/project_manager.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/project_runtime.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/protocol.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/proxy_state.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/repo_map.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/retention.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/retrieval_broker.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/router.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/runtime.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/scanner.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/session_benchmark.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/session_manager.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/session_preloader.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/subprojects.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/task_store.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/telemetry.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/text_index.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/time_tracker.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/tool_classifier.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/transcript_index.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/validation_cache.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/vector_store.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/watcher.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/services/win_subprocess.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/setup.cfg +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_access_builtin_optout.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_access_guard.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_access_guard_meta.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_access_guard_shell_project.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_access_guard_surfaces.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_access_guard_wiring.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_activity_reporter.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_agent_locks.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_aider_polyglot.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_antigravity_transition.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_artifact_store.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_artifact_tool.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_bitbucket_cli_smoke.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_bitbucket_client.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_bitbucket_config_fallback.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_bitbucket_credentials.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_bitbucket_tool.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_c3_shell.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_circuit_breaker.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_claude_md_merge.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_cli_smoke.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_compressor_large_file.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_credential_store.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_credentials_routes.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_credentials_tool.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_creds_cli_smoke.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_delegate_cascade.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_delegate_version_probe.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_e2e_benchmark.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_edit_ledger_hook.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_edit_locking.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_edit_normalization.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_embedding_index_deadlock.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_enforcement_flip.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_enforcement_policy.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_enforcement_routes.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_federated_graph.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_filter_backoff.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_ghost_files.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_ghost_generation.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_git_branch_awareness.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_hook_access_guard.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_hook_dispatch.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_hook_pretool_enforce.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_hook_prompt_recall.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_hook_smoke.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_hook_state.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_hook_utf8_stdio.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_hub_credentials_route.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_hub_credentials_routes_write.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_hub_enforcement_routes.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_hub_inspect_api.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_hub_locks_routes.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_hub_server_smoke.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_hub_subproject_links.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_ide_workflow_adaptation.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_init_scan.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_install_mcp_entrypoint.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_jira_cli_smoke.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_jira_client.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_jira_config_fallback.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_jira_credentials.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_jira_links.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_jira_routes.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_jira_tool.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_lazy_store_init.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_mask_guard.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_mask_routes.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_mask_surfaces.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_mcp_host_guard.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_mcp_memory_timeout.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_mcp_server_smoke.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_mcp_toml.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_memory_distiller.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_memory_graph_api.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_memory_queue.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_memory_system.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_mobile_api.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_mobile_override_routes.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_mobile_security_api.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_no_stale_model_pins.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_notification_dedup.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_notification_discipline.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_ollama_credentials.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_oracle_api_auth.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_oracle_apikey_api.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_oracle_c3_bridge.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_oracle_chat_engine.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_oracle_chat_store.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_oracle_discovery_api.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_oracle_discovery_audit.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_oracle_local_auth.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_oracle_ollama_bridge.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_oracle_scanner_cache.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_oracle_security_fixes.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_oracle_session_bootstrap.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_oracle_subproject_awareness.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_oracle_ui_bundle.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_output_filter.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_override_grants.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_override_grants_mcp.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_override_wake.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_permissions.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_pm_api.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_project_manager.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_project_manager_merge.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_project_tool.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_read_coercion.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_read_edit_parity.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_related_facts.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_repo_map.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_response_boilerplate.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_retention.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_review_digest.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_service_durability.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_session_benchmark.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_session_budget.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_shell_creds.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_shell_robustness.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_subproject_exclusion.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_subproject_federation.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_subprojects.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_swe_bench.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_task_store.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_task_tool.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_time_tracker.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_token_telemetry.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_tool_registry.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_upgrade_and_version.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_validate.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_vault_write_guard.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_version_sync.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_web_security.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tests/test_windows_reliability.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/__init__.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/backend.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/main.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/screens/__init__.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/screens/benchmark_view.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/screens/claudemd_view.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/screens/compress_view.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/screens/index_view.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/screens/init_view.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/screens/mcp_view.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/screens/optimize_view.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/screens/pipe_view.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/screens/projects_view.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/screens/search_view.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/screens/session_view.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/screens/stats.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/screens/ui_view.py +0 -0
- {code_context_control-2.73.0 → code_context_control-2.74.0}/tui/theme.tcss +0 -0
{code_context_control-2.73.0/code_context_control.egg-info → code_context_control-2.74.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.74.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
|
{code_context_control-2.73.0 → code_context_control-2.74.0/code_context_control.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-context-control
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.74.0
|
|
4
4
|
Summary: Local MCP code-intelligence for AI coding tools: surgical search/read/edit, agent-config version history, path-level access + masking guards, and a multi-project hub.
|
|
5
5
|
Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "code-context-control"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.74.0"
|
|
8
8
|
description = "Local MCP code-intelligence for AI coding tools: surgical search/read/edit, agent-config version history, path-level access + masking guards, and a multi-project hub."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -709,11 +709,12 @@ def _override_offer(denial: Denial, path, operation: str, tool: str) -> str:
|
|
|
709
709
|
that can never be escalated: an agent must not learn from a refusal that
|
|
710
710
|
a request surface exists for the credential vault (§6).
|
|
711
711
|
|
|
712
|
-
Restricted to the hook surface on purpose
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
712
|
+
Restricted to the hook surface on purpose — see ``refusal``. The rule was
|
|
713
|
+
written when only the PreToolUse gates consulted grants; P2a taught the
|
|
714
|
+
``c3_*`` content surfaces to consult them too, so extending the offer to
|
|
715
|
+
the MCP surface is now defensible. It is deliberately NOT done here: that
|
|
716
|
+
is a separate, wider change (every c3_* refusal grows a line) and belongs
|
|
717
|
+
in its own review, not smuggled in beside a fix for the branch ordering.
|
|
717
718
|
"""
|
|
718
719
|
try:
|
|
719
720
|
from services import override_policy as _op # noqa: PLC0415 — cycle
|
|
@@ -738,7 +739,26 @@ def refusal(denial: Denial, path, operation: str, *, surface: str = "mcp",
|
|
|
738
739
|
the agent it may ASK (docs/override-requests.md §6). The pinned strings
|
|
739
740
|
above are unchanged: the append is absent unless the project opted in,
|
|
740
741
|
which is off by default.
|
|
742
|
+
|
|
743
|
+
The append happens HERE, once, for every kind — not inside a branch. It
|
|
744
|
+
used to live at the tail of the deny branch, which sits below the mask and
|
|
745
|
+
read-only early returns, so those two kinds could never carry an offer on
|
|
746
|
+
any surface even though `rule_class_for_denial` marks both escalatable.
|
|
747
|
+
`access_readonly` was the only layer anyone had turned on, so in practice
|
|
748
|
+
the invitation half of Override Requests had never fired once.
|
|
741
749
|
"""
|
|
750
|
+
body = _refusal_body(denial, path, operation, surface=surface,
|
|
751
|
+
tool=tool, project=project)
|
|
752
|
+
# Hook only, still: the offer promises that a 'yes' makes the retry work,
|
|
753
|
+
# and the proxy surface answers for a DIFFERENT project's policy.
|
|
754
|
+
if surface == "hook":
|
|
755
|
+
return body + _override_offer(denial, path, operation, tool)
|
|
756
|
+
return body
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
def _refusal_body(denial: Denial, path, operation: str, *, surface: str,
|
|
760
|
+
tool: str, project: str) -> str:
|
|
761
|
+
"""The pinned string itself, with no override append."""
|
|
742
762
|
p, glob, scope = _cap(path), denial.rule, denial.scope
|
|
743
763
|
if denial.kind == _KIND_MASK:
|
|
744
764
|
if operation in ("write", "create", "delete"):
|
|
@@ -762,12 +782,20 @@ def refusal(denial: Denial, path, operation: str, *, surface: str = "mcp",
|
|
|
762
782
|
"`c3 access list` or the Access tab."
|
|
763
783
|
)
|
|
764
784
|
if denial.kind == _KIND_READ_ONLY:
|
|
785
|
+
# `{operation}`, not a hardcoded "write". A read-only rule blocks the
|
|
786
|
+
# whole write class, and for a file that does not exist yet the tools
|
|
787
|
+
# call that operation `create`. Saying "write" told the agent to ask
|
|
788
|
+
# the user to approve `op='write'`, the approval was minted for
|
|
789
|
+
# `write`, and the grant matcher — which compares op exactly — then
|
|
790
|
+
# refused the `create` the tool actually attempted. A real approval
|
|
791
|
+
# was spent and silently discarded (§4 near_miss).
|
|
765
792
|
return (
|
|
766
|
-
f"{TAG_READ_ONLY}
|
|
793
|
+
f"{TAG_READ_ONLY} {operation} denied for {p} by Access Guard rule "
|
|
767
794
|
f"'{glob}' ({scope} scope). The effective policy is read-only; "
|
|
768
|
-
"reads are evaluated separately. Do not retry the
|
|
769
|
-
"the affected step blocked and continue with unaffected
|
|
770
|
-
"report the skip. Rules: `c3 access list` or the Access
|
|
795
|
+
f"reads are evaluated separately. Do not retry the {operation}. "
|
|
796
|
+
"Mark the affected step blocked and continue with unaffected "
|
|
797
|
+
"files; report the skip. Rules: `c3 access list` or the Access "
|
|
798
|
+
"tab."
|
|
771
799
|
)
|
|
772
800
|
if surface == "hook":
|
|
773
801
|
return (
|
|
@@ -776,7 +804,7 @@ def refusal(denial: Denial, path, operation: str, *, surface: str = "mcp",
|
|
|
776
804
|
"decision, not a transient error — do not retry through another "
|
|
777
805
|
"tool or the shell. Mark the affected step blocked and continue "
|
|
778
806
|
"with unaffected files. Rules: `c3 access list`."
|
|
779
|
-
)
|
|
807
|
+
)
|
|
780
808
|
if surface == "proxy":
|
|
781
809
|
return (
|
|
782
810
|
f"{TAG_DENIED} {operation} denied for {p} through project "
|
|
@@ -43,7 +43,8 @@ class NotificationStore:
|
|
|
43
43
|
self._collapsed = False
|
|
44
44
|
|
|
45
45
|
def add(self, agent: str, severity: str, title: str, message: str,
|
|
46
|
-
ai_enhanced: bool = False, replace_if_unacked: bool = False
|
|
46
|
+
ai_enhanced: bool = False, replace_if_unacked: bool = False,
|
|
47
|
+
kind: str = "", ref_id: str = "") -> dict | None:
|
|
47
48
|
"""Append a notification. Dedup: an identical (agent, title, message)
|
|
48
49
|
that is still unacknowledged collapses into the existing record — its
|
|
49
50
|
``count`` is bumped and ``last_seen`` refreshed instead of appending a
|
|
@@ -54,6 +55,13 @@ class NotificationStore:
|
|
|
54
55
|
already exists, update its message/severity in-place (bumping
|
|
55
56
|
count/last_seen) instead of appending a new entry. Use for
|
|
56
57
|
high-frequency agents (budget, index, key-file drift) to prevent pile-up.
|
|
58
|
+
kind: machine-readable class for clients that ROUTE on a tap rather
|
|
59
|
+
than parse the title — 'override' for an approval request. Omitted
|
|
60
|
+
from the record when empty, so every existing producer and every
|
|
61
|
+
stored line is unchanged.
|
|
62
|
+
ref_id: the id of the thing the notification is ABOUT (e.g. the
|
|
63
|
+
override request), which is not the notification's own ``id``.
|
|
64
|
+
A client needs both: ``id`` to acknowledge, ``ref_id`` to navigate.
|
|
57
65
|
Returns the entry if written/updated, None if deduped.
|
|
58
66
|
"""
|
|
59
67
|
with self._lock:
|
|
@@ -75,6 +83,13 @@ class NotificationStore:
|
|
|
75
83
|
existing["last_seen"] = now.isoformat()
|
|
76
84
|
existing["count"] = _entry_count(existing) + 1
|
|
77
85
|
existing["ai_enhanced"] = ai_enhanced
|
|
86
|
+
# Refresh the routing fields too: an in-place update
|
|
87
|
+
# keeps the record but the thing it points AT may have
|
|
88
|
+
# changed (a new request id under the same title).
|
|
89
|
+
if kind:
|
|
90
|
+
existing["kind"] = kind
|
|
91
|
+
if ref_id:
|
|
92
|
+
existing["ref_id"] = ref_id
|
|
78
93
|
self._write_all(entries)
|
|
79
94
|
return existing
|
|
80
95
|
# Same notification still pending — collapse into the
|
|
@@ -108,6 +123,12 @@ class NotificationStore:
|
|
|
108
123
|
"acknowledged": False,
|
|
109
124
|
"ai_enhanced": ai_enhanced,
|
|
110
125
|
}
|
|
126
|
+
# Additive only: absent keys rather than empty ones, so a client
|
|
127
|
+
# can test presence and old lines stay byte-identical in shape.
|
|
128
|
+
if kind:
|
|
129
|
+
entry["kind"] = kind
|
|
130
|
+
if ref_id:
|
|
131
|
+
entry["ref_id"] = ref_id
|
|
111
132
|
with open(self._file, "a", encoding="utf-8") as f:
|
|
112
133
|
f.write(json.dumps(entry) + "\n")
|
|
113
134
|
return entry
|
|
@@ -420,6 +420,12 @@ def _notify(project_path: str, row: dict, policy) -> None:
|
|
|
420
420
|
f"{Path(row['path']).name}?",
|
|
421
421
|
message=(f"Blocked by rule {row['rule']} ({row['rule_class']}). "
|
|
422
422
|
f"Approve once: c3 override approve {row['id']}"),
|
|
423
|
+
# A phone routes on these, not on the title. Without them a tap
|
|
424
|
+
# opens the app and drops the user wherever they were last —
|
|
425
|
+
# which, for the one notification that exists to be answered, is
|
|
426
|
+
# the same as not delivering it (§9).
|
|
427
|
+
kind="override",
|
|
428
|
+
ref_id=row["id"],
|
|
423
429
|
)
|
|
424
430
|
except Exception:
|
|
425
431
|
pass # a missing notification must never fail the request
|
|
@@ -325,5 +325,130 @@ class TestOfferLine(RequestBase):
|
|
|
325
325
|
self.assertIn("do not retry through another tool or the shell", text)
|
|
326
326
|
|
|
327
327
|
|
|
328
|
+
# ── §6 the offer must not depend on WHICH kind denied ──────────────────────
|
|
329
|
+
|
|
330
|
+
class TestOfferReachesEveryEscalatableKind(RequestBase):
|
|
331
|
+
"""The bug this class exists for.
|
|
332
|
+
|
|
333
|
+
`refusal()` used to append the offer at the tail of the deny branch, which
|
|
334
|
+
sits *below* the mask and read-only early returns. Both of those kinds map
|
|
335
|
+
to an escalatable layer in `rule_class_for_denial`, so policy said "offer
|
|
336
|
+
this" and the composer structurally could not. `access_readonly` was the
|
|
337
|
+
only layer that had ever been switched on in the wild, which made the
|
|
338
|
+
invitation half of the feature dead on the one path anybody used.
|
|
339
|
+
|
|
340
|
+
These assert on the LAYER, not on a branch, so re-introducing an early
|
|
341
|
+
return in front of the append fails here rather than in production.
|
|
342
|
+
"""
|
|
343
|
+
|
|
344
|
+
def _refuse(self, rel, operation, tool="Write"):
|
|
345
|
+
target = self.proj / rel
|
|
346
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
347
|
+
denial = ag.check(str(target), operation, str(self.proj))
|
|
348
|
+
self.assertIsNotNone(denial, f"fixture must deny {rel} on {operation}")
|
|
349
|
+
return denial, ag.refusal(denial, str(target), operation,
|
|
350
|
+
surface="hook", tool=tool)
|
|
351
|
+
|
|
352
|
+
def test_read_only_denial_carries_the_offer(self):
|
|
353
|
+
denial, text = self._refuse("docs/a.md", "write")
|
|
354
|
+
self.assertEqual(denial.kind, "read_only")
|
|
355
|
+
self.assertEqual(opol.rule_class_for_denial(denial),
|
|
356
|
+
opol.LAYER_ACCESS_READONLY)
|
|
357
|
+
self.assertIn(opol.TAG_OFFER, text)
|
|
358
|
+
self.assertIn("action='request'", text)
|
|
359
|
+
|
|
360
|
+
def test_deny_denial_still_carries_the_offer(self):
|
|
361
|
+
denial, text = self._refuse("secrets/other.txt", "read", tool="Read")
|
|
362
|
+
self.assertEqual(denial.kind, "deny")
|
|
363
|
+
self.assertIn(opol.TAG_OFFER, text)
|
|
364
|
+
|
|
365
|
+
def test_every_escalatable_kind_is_offered(self):
|
|
366
|
+
"""No kind may be silently unreachable."""
|
|
367
|
+
cases = [("docs/a.md", "write"), ("secrets/other.txt", "read")]
|
|
368
|
+
for rel, operation in cases:
|
|
369
|
+
with self.subTest(path=rel):
|
|
370
|
+
denial, text = self._refuse(rel, operation)
|
|
371
|
+
layer = opol.rule_class_for_denial(denial)
|
|
372
|
+
self.assertIsNotNone(layer)
|
|
373
|
+
self.assertIn(opol.TAG_OFFER, text)
|
|
374
|
+
|
|
375
|
+
def test_offer_still_absent_when_the_layer_is_off(self):
|
|
376
|
+
layers = dict(ALL_LAYERS_ON)
|
|
377
|
+
layers[opol.LAYER_ACCESS_READONLY] = False
|
|
378
|
+
self.write_config(layers=layers)
|
|
379
|
+
_, text = self._refuse("docs/a.md", "write")
|
|
380
|
+
self.assertNotIn(opol.TAG_OFFER, text)
|
|
381
|
+
|
|
382
|
+
def test_offer_absent_on_the_mcp_surface(self):
|
|
383
|
+
denial = ag.check(str(self.proj / "docs" / "a.md"), "write",
|
|
384
|
+
str(self.proj))
|
|
385
|
+
text = ag.refusal(denial, "docs/a.md", "write")
|
|
386
|
+
self.assertNotIn(opol.TAG_OFFER, text)
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
# ── §4 the refusal must name the operation the caller named ────────────────
|
|
390
|
+
|
|
391
|
+
class TestRefusalNamesTheRealOperation(RequestBase):
|
|
392
|
+
"""A read-only refusal that always said "write" cost a real approval.
|
|
393
|
+
|
|
394
|
+
`c3_edit` calls the operation `create` when the file does not exist. The
|
|
395
|
+
agent copied "write" out of the refusal, the human approved `write`, and
|
|
396
|
+
the grant matcher — exact on `op` — refused the `create` that followed.
|
|
397
|
+
"""
|
|
398
|
+
|
|
399
|
+
def _text(self, operation):
|
|
400
|
+
target = self.proj / "docs" / "new.md"
|
|
401
|
+
denial = ag.check(str(target), operation, str(self.proj))
|
|
402
|
+
return ag.refusal(denial, str(target), operation)
|
|
403
|
+
|
|
404
|
+
def test_create_is_named_create(self):
|
|
405
|
+
text = self._text("create")
|
|
406
|
+
self.assertIn("create denied", text)
|
|
407
|
+
self.assertNotIn("write denied", text)
|
|
408
|
+
self.assertIn("Do not retry the create", text)
|
|
409
|
+
|
|
410
|
+
def test_write_is_still_named_write(self):
|
|
411
|
+
text = self._text("write")
|
|
412
|
+
self.assertIn("write denied", text)
|
|
413
|
+
|
|
414
|
+
def test_delete_is_named_delete(self):
|
|
415
|
+
self.assertIn("delete denied", self._text("delete"))
|
|
416
|
+
|
|
417
|
+
def test_the_offer_carries_the_same_operation(self):
|
|
418
|
+
target = self.proj / "docs" / "new.md"
|
|
419
|
+
denial = ag.check(str(target), "create", str(self.proj))
|
|
420
|
+
text = ag.refusal(denial, str(target), "create", surface="hook",
|
|
421
|
+
tool="c3_edit")
|
|
422
|
+
self.assertIn("op='create'", text)
|
|
423
|
+
self.assertNotIn("op='write'", text)
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
# ── §9 the phone routes on the payload, not on the title ───────────────────
|
|
427
|
+
|
|
428
|
+
class TestNotificationPayload(RequestBase):
|
|
429
|
+
def _entries(self):
|
|
430
|
+
raw = (self.proj / ".c3" / "notifications.jsonl").read_text("utf-8")
|
|
431
|
+
return [json.loads(ln) for ln in raw.splitlines() if ln.strip()]
|
|
432
|
+
|
|
433
|
+
def test_request_notification_carries_kind_and_ref_id(self):
|
|
434
|
+
row = self.request()
|
|
435
|
+
entry = next(e for e in self._entries()
|
|
436
|
+
if e.get("title", "").startswith("Approve "))
|
|
437
|
+
self.assertEqual(entry["kind"], "override")
|
|
438
|
+
self.assertEqual(entry["ref_id"], row["id"])
|
|
439
|
+
# The notification's own id stays its own — a client needs both, one
|
|
440
|
+
# to acknowledge and one to navigate.
|
|
441
|
+
self.assertNotEqual(entry["id"], row["id"])
|
|
442
|
+
|
|
443
|
+
def test_other_producers_are_unchanged(self):
|
|
444
|
+
from services.notifications import NotificationStore
|
|
445
|
+
NotificationStore(str(self.proj)).add(
|
|
446
|
+
agent="IndexStaleness", severity="info", title="t", message="m")
|
|
447
|
+
entry = next(e for e in self._entries() if e.get("agent") ==
|
|
448
|
+
"IndexStaleness")
|
|
449
|
+
self.assertNotIn("kind", entry)
|
|
450
|
+
self.assertNotIn("ref_id", entry)
|
|
451
|
+
|
|
452
|
+
|
|
328
453
|
if __name__ == "__main__":
|
|
329
454
|
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/add_project.js
RENAMED
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/config_editor.js
RENAMED
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/drill_artifacts.js
RENAMED
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/drill_health.js
RENAMED
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/drill_panel.js
RENAMED
|
File without changes
|
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/drill_tasks.js
RENAMED
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/drill_views.js
RENAMED
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/global_search.js
RENAMED
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/hub_credentials.js
RENAMED
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/hub_enforcement.js
RENAMED
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/hub_locks.js
RENAMED
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/mcp_manager.js
RENAMED
|
File without changes
|
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/project_card.js
RENAMED
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/project_tree.js
RENAMED
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/session_drawer.js
RENAMED
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/settings_modal.js
RENAMED
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/sidebar.js
RENAMED
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/summary_bar.js
RENAMED
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/hub_ui/components/task_board.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/components/credentials.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/components/enforcement.js
RENAMED
|
File without changes
|
{code_context_control-2.73.0 → code_context_control-2.74.0}/cli/ui/components/instructions.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|