code-context-control 2.140.0__tar.gz → 2.141.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.140.0 → code_context_control-2.141.0}/PKG-INFO +1 -1
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/c3.py +1 -1
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_server.py +193 -7
- {code_context_control-2.140.0 → code_context_control-2.141.0}/code_context_control.egg-info/PKG-INFO +1 -1
- {code_context_control-2.140.0 → code_context_control-2.141.0}/code_context_control.egg-info/SOURCES.txt +1 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/pyproject.toml +1 -1
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/enforcement_policy.py +38 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/override_policy.py +127 -1
- code_context_control-2.141.0/tests/test_hub_rules_routes.py +330 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/LICENSE +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/README.md +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/_hook_utils.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/_shell_writes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/commands/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/commands/common.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/commands/parser.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/docs.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/edits.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/guide/access.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/guide/bitbucket.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/guide/credentials.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/guide/getting-started.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/guide/index.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/guide/masking.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/guide/oracle.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/guide/shared.css +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/guide/tools.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/guide/workflow.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_access_guard.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_agent_model.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_artifact.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_auto_snapshot.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_c3_signal.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_c3read.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_codex_lifecycle.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_dispatch.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_edit_ledger.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_edit_unlock.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_filter.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_ghost_files.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_pretool_enforce.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_prompt_recall.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_read.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_session_end.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_session_open.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_session_stats.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hook_terse_advisor.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/app.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/add_project.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/config_editor.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/drill_health.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/drill_panel.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/drill_tasks.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/drill_views.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/global_search.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/hub_access.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/hub_ci.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/hub_cred_audit.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/hub_credentials.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/hub_locks.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/hub_tokens.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/mcp_manager.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/modals.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/project_card.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/project_tree.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/session_drawer.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/settings_modal.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/sidebar.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/summary_bar.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/task_board.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/toasts.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/components/topbar.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui/state.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/hub_ui.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/mcp_proxy.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/mcp_server.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/progress.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/server.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/_grants.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/_helpers.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/agent.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/artifacts.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/bitbucket.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/ci.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/compress.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/credentials.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/delegate.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/edit.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/edit_verify.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/edits.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/federate.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/filter.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/impact.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/jira.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/locks.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/memory.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/override.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/project.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/read.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/search.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/session.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/shell.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/shell_job.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/shell_nudge.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/shell_parsers.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/shell_render.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/status.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/tasks.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/tools/validate.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/api.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/app.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/components/access.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/components/bitbucket.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/components/chat.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/components/credentials.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/components/dashboard.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/components/edits.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/components/enforcement.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/components/instructions.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/components/jira.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/components/memory.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/components/sessions.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/components/settings.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/components/sidebar.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/components/tasks.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/icons.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/pm_shared.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/shared.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui/theme.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui_legacy.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/cli/ui_nano.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/code_context_control.egg-info/dependency_links.txt +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/code_context_control.egg-info/entry_points.txt +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/code_context_control.egg-info/requires.txt +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/code_context_control.egg-info/top_level.txt +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/core/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/core/codex_patch.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/core/config.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/core/grok_payload.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/core/hook_command.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/core/host.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/core/ide.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/core/mcp_toml.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/core/web_security.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/config.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/listeners.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/mcp_oracle.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/oracle_server.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/oracle_ui.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/activity_reporter.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/api_auth.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/c3_bridge.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/chat_engine.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/chat_poll.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/chat_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/client_tokens.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/cross_memory.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/discovery_audit.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/federated_graph.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/health_checker.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/insight_engine.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/local_session.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/memory_reader.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/memory_writer.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/mobile_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/project_scanner.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/review_agent.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/tool_executor.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/services/tool_registry.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/activity.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/agents.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/app.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/busy.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/chat/conversations.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/chat/input.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/chat/markdown.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/chat/send.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/chat/stream_renderer.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/chat/toolbar.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/core.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/crossgraph.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/header.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/insights.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/projects.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/qrcode.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/settings.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/suggestions.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/oracle/ui/theme_tabs.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/access_guard.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/access_telemetry.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/activity_log.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/agent_base.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/agent_downshift.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/agent_locks.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/agents.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/agents_workflow.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/artifact_defs.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/artifact_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/atomic_json.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/auto_memory.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/background_service.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/bench/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/bench/delegate_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/bench/delegate_write_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/bench/external/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/bench/external/aider_polyglot.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/bench/external/swe_bench.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/bench/map_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/bench/search_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/bench/shell_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/benchmark_dashboard.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/bitbucket_client.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/bitbucket_credentials.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/ci_act.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/ci_cache.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/ci_expr.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/ci_failures.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/ci_github.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/ci_impact.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/ci_intel.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/ci_runner.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/ci_workflow.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/circuit_breaker.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/claude_md.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/codex_integration.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/codex_transcript.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/compressor.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/context_snapshot.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/conversation_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/cred_audit.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/cred_telemetry.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/credential_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/delegate_agents.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/delegate_hints.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/delegate_write.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/dir_map.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/doc_index.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/e2e_benchmark.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/e2e_evaluator.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/e2e_tasks.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/edit_ledger.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/embedding_index.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/error_reporting.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/file_map.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/file_memory.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/git_context.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/grok_integration.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/grok_transcript.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/host_sessions.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/hub_service.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/index_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/indexer.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/jira_client.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/jira_cloud.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/jira_credentials.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/jira_data_center.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/jira_links.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/lexical_index.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/mask_activation.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/mask_mirror.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/mask_presets.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/memory.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/memory_consolidator.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/memory_distiller.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/memory_graph.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/memory_grounder.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/memory_queue.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/memory_scorer.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/metrics.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/notifications.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/ollama_bridge.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/ollama_client.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/ollama_credentials.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/oracle_service.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/output_filter.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/override_costs.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/override_grants.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/override_requests.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/override_wake.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/parser.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/project_manager.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/project_runtime.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/protocol.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/proxy_state.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/repo_map.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/repo_shape.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/reranker.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/retention.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/retrieval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/retrieval_broker.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/router.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/runtime.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/scanner.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/session_benchmark.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/session_live.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/session_manager.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/session_preloader.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/shell_jobs.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/shell_output.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/subprojects.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/task_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/telemetry.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/text_index.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/time_tracker.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/tool_classifier.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/transcript_index.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/validation_cache.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/vector_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/watcher.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/services/win_subprocess.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/setup.cfg +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_access_builtin_optout.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_access_guard.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_access_guard_meta.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_access_guard_shell_project.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_access_guard_surfaces.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_access_guard_wiring.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_activity_log_find_last.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_activity_reporter.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_agent_locks.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_aider_polyglot.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_antigravity_transition.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_artifact_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_artifact_tool.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_atomic_json.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_background_service.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_bitbucket_cli_smoke.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_bitbucket_client.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_bitbucket_config_fallback.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_bitbucket_credentials.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_bitbucket_tool.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_builtin_modes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_c3_shell.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_chat_poll.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_ci_act.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_ci_cache.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_ci_dag_ownership.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_ci_expr.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_ci_impact.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_ci_intel.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_ci_runner.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_ci_workflow.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_circuit_breaker.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_claude_md_merge.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_claude_md_updater.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_cli_smoke.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_codex_mcp_transport.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_codex_native.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_compressor_large_file.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_confirm_guard.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_confirm_guard_wiring.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_cooccurrence_bounds.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_cred_audit.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_cred_telemetry.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_credential_login_kind.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_credential_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_credential_ui_parity.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_credentials_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_credentials_tool.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_creds_cli_smoke.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_delegate_adoption_d4.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_delegate_auto.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_delegate_cascade.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_delegate_claude_d1.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_delegate_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_delegate_grok.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_delegate_host_d2.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_delegate_scout_d3.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_delegate_telemetry_d0.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_delegate_thinking_cap.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_delegate_tuning.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_delegate_version_probe.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_delegate_write.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_delegate_write_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_dir_map_c3.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_e2e_benchmark.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_edit_ledger_deadline.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_edit_ledger_hook.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_edit_locking.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_edit_normalization.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_edit_verify.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_embedding_index_deadlock.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_enforcement_flip.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_enforcement_policy.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_enforcement_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_env_parser.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_failed_calls_do_not_unlock.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_federated_graph.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_file_map_c1.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_filter_backoff.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_ghost_files.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_ghost_generation.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_git_branch_awareness.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_grok_native.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hook_access_guard.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hook_codex_compat.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hook_dispatch.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hook_grok_compat.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hook_pretool_enforce.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hook_prompt_recall.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hook_session_end.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hook_smoke.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hook_state.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hook_utf8_stdio.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hub_credentials_route.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hub_credentials_routes_write.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hub_enforcement_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hub_hook_migration.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hub_inspect_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hub_locks_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hub_oracle_service_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hub_override_policy_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hub_override_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hub_server_smoke.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_hub_subproject_links.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_ide_workflow_adaptation.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_index_cap_not_hardcoded.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_init_clear_preserves_user_content.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_init_scan.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_install_mcp_entrypoint.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_jira_cli_smoke.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_jira_client.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_jira_config_fallback.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_jira_credentials.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_jira_links.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_jira_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_jira_tool.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_large_files_c4.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_lazy_store_init.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_map_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_map_telemetry_c0.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_mask_guard.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_mask_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_mask_surfaces.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_mcp_host_guard.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_mcp_memory_timeout.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_mcp_server_smoke.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_mcp_toml.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_memory_distiller.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_memory_graph_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_memory_queue.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_memory_system.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_mobile_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_mobile_clients.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_mobile_extras.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_mobile_jobs_ci.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_mobile_override_costs.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_mobile_override_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_mobile_security_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_no_stale_model_pins.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_notification_dedup.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_notification_discipline.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_notification_kinds.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_ollama_credentials.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_oracle_api_auth.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_oracle_apikey_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_oracle_c3_bridge.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_oracle_chat_engine.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_oracle_chat_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_oracle_discovery_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_oracle_discovery_audit.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_oracle_health_probe.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_oracle_local_auth.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_oracle_loopback.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_oracle_ollama_bridge.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_oracle_scanner_cache.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_oracle_security_fixes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_oracle_session_bootstrap.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_oracle_subproject_awareness.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_oracle_ui_bundle.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_output_filter.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_override_costs.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_override_grants.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_override_grants_mcp.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_override_requests.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_override_wake.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_permissions.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_pm_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_project_manager.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_project_manager_merge.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_project_tool.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_read_coercion.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_read_edit_parity.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_read_outside_root.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_related_facts.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_repo_map.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_repo_shape.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_response_boilerplate.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_retention.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_review_digest.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_search_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_search_p1.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_search_p2.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_search_p2b.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_search_p3.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_search_p4.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_search_p5.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_service_durability.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_session_benchmark.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_session_budget.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_session_live.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_shell_budget_s1.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_shell_creds.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_shell_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_shell_jobs_s3.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_shell_nudge_s4.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_shell_output.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_shell_parsers_s2.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_shell_robustness.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_shell_telemetry_s0.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_shell_write_ledger.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_shell_writes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_subproject_clear_scope.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_subproject_depth_consumers.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_subproject_exclusion.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_subproject_federation.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_subproject_linkage_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_subprojects.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_swe_bench.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_task_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_task_tool.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_time_tracker.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_token_telemetry.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_token_tracking.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_tool_registry.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_ui_jsx_syntax.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_upgrade_and_version.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_validate.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_vault_write_guard.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_version_sync.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_watcher_pruning.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_web_security.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tests/test_windows_reliability.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/backend.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/main.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/screens/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/screens/benchmark_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/screens/claudemd_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/screens/compress_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/screens/index_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/screens/init_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/screens/mcp_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/screens/optimize_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/screens/pipe_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/screens/projects_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/screens/search_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/screens/session_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/screens/stats.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/screens/ui_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.141.0}/tui/theme.tcss +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-context-control
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.141.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
|
|
@@ -91,7 +91,7 @@ console = Console() if HAS_RICH else None
|
|
|
91
91
|
# Config
|
|
92
92
|
CONFIG_DIR = ".c3"
|
|
93
93
|
CONFIG_FILE = ".c3/config.json"
|
|
94
|
-
__version__ = "2.
|
|
94
|
+
__version__ = "2.141.0"
|
|
95
95
|
|
|
96
96
|
# The PreToolUse matcher for native subagent calls (installer and hub migration).
|
|
97
97
|
AGENT_MATCHER = "Agent|Task"
|
|
@@ -2982,6 +2982,65 @@ def api_projects_enforcement_set():
|
|
|
2982
2982
|
return jsonify(result)
|
|
2983
2983
|
|
|
2984
2984
|
|
|
2985
|
+
@app.route("/api/projects/enforcement/clear", methods=["POST"])
|
|
2986
|
+
def api_projects_enforcement_clear():
|
|
2987
|
+
"""Drop a scope's `enforcement` section so it inherits again.
|
|
2988
|
+
|
|
2989
|
+
Body: ``{path?, scope?}`` — same scope rules as the set route. There is
|
|
2990
|
+
no mode a surface can WRITE that means "use the global default" (resolve
|
|
2991
|
+
stops at the first section it finds), so "inherit" is a removal, and it
|
|
2992
|
+
gets its own verb rather than a magic mode string. Nothing to clear is a
|
|
2993
|
+
200 with ``cleared: false``: the caller asked for the state it is in.
|
|
2994
|
+
Audited on the target project like a set.
|
|
2995
|
+
"""
|
|
2996
|
+
from services import enforcement_policy as ep
|
|
2997
|
+
|
|
2998
|
+
data = request.get_json(silent=True) or {}
|
|
2999
|
+
path = (data.get("path") or "").strip()
|
|
3000
|
+
scope = (data.get("scope") or "project").strip().lower()
|
|
3001
|
+
if scope not in ("project", "global"):
|
|
3002
|
+
return jsonify({"error": "scope must be 'project' or 'global'"}), 400
|
|
3003
|
+
if scope == "project":
|
|
3004
|
+
if not path:
|
|
3005
|
+
return jsonify({"error": "path is required for project scope"}), 400
|
|
3006
|
+
try:
|
|
3007
|
+
resolved = _resolve_project_path(path)
|
|
3008
|
+
except ValueError as e:
|
|
3009
|
+
return jsonify({"error": str(e)}), 404
|
|
3010
|
+
else:
|
|
3011
|
+
resolved = "."
|
|
3012
|
+
|
|
3013
|
+
try:
|
|
3014
|
+
result = ep.clear(resolved, scope=scope)
|
|
3015
|
+
except (ValueError, TypeError) as e:
|
|
3016
|
+
return jsonify({"error": str(e)}), 400
|
|
3017
|
+
|
|
3018
|
+
if scope == "project" and result.get("cleared"):
|
|
3019
|
+
detail = {"kind": "enforcement", "action": "clear",
|
|
3020
|
+
"previous": result.get("previous", ""),
|
|
3021
|
+
"mode": result.get("mode", ""), "scope": result.get("scope", ""),
|
|
3022
|
+
"via": "hub"}
|
|
3023
|
+
summary = (f"tool discipline {result.get('previous') or 'default'} -> "
|
|
3024
|
+
f"inherit ({result.get('mode')} from {result.get('scope')}) "
|
|
3025
|
+
"via the Hub")
|
|
3026
|
+
try:
|
|
3027
|
+
from services.activity_log import ActivityLog
|
|
3028
|
+
ActivityLog(resolved).log("access_action", dict(detail))
|
|
3029
|
+
except Exception:
|
|
3030
|
+
pass
|
|
3031
|
+
try:
|
|
3032
|
+
from services.edit_ledger import EditLedger
|
|
3033
|
+
EditLedger(resolved).log_edit(
|
|
3034
|
+
file="enforcement://project",
|
|
3035
|
+
change_type="enforcement_clear",
|
|
3036
|
+
summary=summary,
|
|
3037
|
+
tags=["enforcement", "access"],
|
|
3038
|
+
detail=detail)
|
|
3039
|
+
except Exception:
|
|
3040
|
+
pass
|
|
3041
|
+
return jsonify(result)
|
|
3042
|
+
|
|
3043
|
+
|
|
2985
3044
|
@app.route("/api/projects/enforcement/denials/search", methods=["GET"])
|
|
2986
3045
|
def api_projects_enforcement_denials_search():
|
|
2987
3046
|
"""Search one project's raw denial events. Read-only; newest first.
|
|
@@ -3260,6 +3319,43 @@ def api_hub_override_costs():
|
|
|
3260
3319
|
"project": project_path})
|
|
3261
3320
|
|
|
3262
3321
|
|
|
3322
|
+
#: Verbatim from the spec, and the one thing a toggle screen must not let the
|
|
3323
|
+
#: reader forget: policy is a floor, not a promise.
|
|
3324
|
+
_OVERRIDE_POLICY_NOTE = (
|
|
3325
|
+
"Project and global policy merge by tightening only: a layer is "
|
|
3326
|
+
"escalatable iff both scopes allow it, and the numeric limits take "
|
|
3327
|
+
"the smaller value."
|
|
3328
|
+
)
|
|
3329
|
+
|
|
3330
|
+
|
|
3331
|
+
def _hub_policy_audit(project_path: str, action: str, detail_extra: dict) -> None:
|
|
3332
|
+
"""One activity row + ledger entry per override-POLICY edit on the target.
|
|
3333
|
+
|
|
3334
|
+
Key names and the widening list only — never values of ``wake`` (an argv
|
|
3335
|
+
this machine runs). A policy edit changes what a single tap can allow, so
|
|
3336
|
+
a surface that can make it for many projects at once must leave a trail
|
|
3337
|
+
on every one. Failure-safe.
|
|
3338
|
+
"""
|
|
3339
|
+
detail = {"kind": "override_policy", "action": action, "via": "hub"}
|
|
3340
|
+
detail.update(detail_extra or {})
|
|
3341
|
+
widened = detail.get("widened") or []
|
|
3342
|
+
summary = (f"override policy {action} via the Hub"
|
|
3343
|
+
+ (f" (widened: {', '.join(widened)})" if widened else ""))
|
|
3344
|
+
try:
|
|
3345
|
+
from services.activity_log import ActivityLog as _AL
|
|
3346
|
+
_AL(str(project_path)).log("access_action", dict(detail))
|
|
3347
|
+
except Exception:
|
|
3348
|
+
pass
|
|
3349
|
+
try:
|
|
3350
|
+
from services.edit_ledger import EditLedger
|
|
3351
|
+
EditLedger(str(project_path)).log_edit(
|
|
3352
|
+
file="override://policy",
|
|
3353
|
+
change_type=f"override_policy_{action}",
|
|
3354
|
+
summary=summary, tags=["override", "policy"], detail=dict(detail))
|
|
3355
|
+
except Exception:
|
|
3356
|
+
pass
|
|
3357
|
+
|
|
3358
|
+
|
|
3263
3359
|
@app.route("/api/hub/overrides/policy", methods=["GET"])
|
|
3264
3360
|
def api_hub_override_policy_get():
|
|
3265
3361
|
"""The effective `override` section for one project.
|
|
@@ -3289,13 +3385,7 @@ def api_hub_override_policy_get():
|
|
|
3289
3385
|
"layers": list(opol.LAYER_KEYS),
|
|
3290
3386
|
"typed_confirm_layers": sorted(opol.TYPED_CONFIRM_LAYERS),
|
|
3291
3387
|
"hard_max_ttl_s": opol.HARD_MAX_TTL_S,
|
|
3292
|
-
|
|
3293
|
-
# let the reader forget: policy is a floor, not a promise.
|
|
3294
|
-
"coverage_note": (
|
|
3295
|
-
"Project and global policy merge by tightening only: a layer is "
|
|
3296
|
-
"escalatable iff both scopes allow it, and the numeric limits take "
|
|
3297
|
-
"the smaller value."
|
|
3298
|
-
),
|
|
3388
|
+
"coverage_note": _OVERRIDE_POLICY_NOTE,
|
|
3299
3389
|
})
|
|
3300
3390
|
|
|
3301
3391
|
|
|
@@ -3334,11 +3424,107 @@ def api_hub_override_policy_set():
|
|
|
3334
3424
|
return jsonify(exc.payload), exc.status
|
|
3335
3425
|
except (OSError, ValueError) as exc:
|
|
3336
3426
|
return jsonify({"error": f"{type(exc).__name__}: {exc}"}), 500
|
|
3427
|
+
section = data.get("override") or {}
|
|
3428
|
+
keys = [k for k in section if k != "layers"]
|
|
3429
|
+
keys += [f"layers.{k}" for k in (section.get("layers") or {})]
|
|
3430
|
+
_hub_policy_audit(project_path, "set",
|
|
3431
|
+
{"keys": sorted(keys), "widened": list(widens)})
|
|
3337
3432
|
return jsonify({"path": project_path, "written": written,
|
|
3338
3433
|
"policy": opol.resolve(project_path).as_dict(),
|
|
3339
3434
|
"widened": widens})
|
|
3340
3435
|
|
|
3341
3436
|
|
|
3437
|
+
@app.route("/api/hub/overrides/policy/overview", methods=["GET"])
|
|
3438
|
+
def api_hub_override_policy_overview():
|
|
3439
|
+
"""Every registered project's effective override policy in one call.
|
|
3440
|
+
|
|
3441
|
+
The cross-project read a bulk editor needs (C3 Desk's Rules view), shaped
|
|
3442
|
+
like the enforcement overview: per-row isolation, so one unreadable
|
|
3443
|
+
project reports ``error`` instead of blanking the page, and a corrupt
|
|
3444
|
+
section is reported as corrupt rather than as the disabled policy it
|
|
3445
|
+
resolves to. ``project_keys`` names what the project pins itself, so a
|
|
3446
|
+
screen can tell an inherited value from a chosen one. The global scope is
|
|
3447
|
+
served READ-ONLY: ``write_section`` is project-scope by design.
|
|
3448
|
+
"""
|
|
3449
|
+
from services import override_policy as opol
|
|
3450
|
+
|
|
3451
|
+
rows = []
|
|
3452
|
+
for p in _pm().list_projects():
|
|
3453
|
+
ppath = str(p.get("path") or "")
|
|
3454
|
+
row = {"name": p.get("name") or Path(ppath).name, "path": ppath,
|
|
3455
|
+
"initialized": True, "error": None, "policy": None,
|
|
3456
|
+
"configured": False, "corrupt": False, "project_keys": []}
|
|
3457
|
+
try:
|
|
3458
|
+
if not (Path(ppath) / ".c3").is_dir():
|
|
3459
|
+
row["initialized"] = False
|
|
3460
|
+
else:
|
|
3461
|
+
keys, present, corrupt = opol.scope_keys(ppath)
|
|
3462
|
+
row["project_keys"] = keys
|
|
3463
|
+
row["configured"] = present
|
|
3464
|
+
row["corrupt"] = corrupt
|
|
3465
|
+
row["policy"] = opol.resolve(ppath).as_dict()
|
|
3466
|
+
except Exception as e:
|
|
3467
|
+
row["error"] = str(e)
|
|
3468
|
+
rows.append(row)
|
|
3469
|
+
|
|
3470
|
+
try:
|
|
3471
|
+
keys, present, corrupt = opol.global_scope_keys()
|
|
3472
|
+
global_policy = {"configured": present, "corrupt": corrupt,
|
|
3473
|
+
"keys": keys, "error": None,
|
|
3474
|
+
"policy": opol.resolve_global().as_dict()}
|
|
3475
|
+
except Exception as e:
|
|
3476
|
+
global_policy = {"configured": False, "corrupt": False, "keys": [],
|
|
3477
|
+
"error": str(e), "policy": None}
|
|
3478
|
+
|
|
3479
|
+
return jsonify({
|
|
3480
|
+
"projects": rows,
|
|
3481
|
+
"global_policy": global_policy,
|
|
3482
|
+
"defaults": {k: v for k, v in opol.DEFAULTS.items()
|
|
3483
|
+
if k != opol.WAKE_KEY},
|
|
3484
|
+
"layers": list(opol.LAYER_KEYS),
|
|
3485
|
+
"typed_confirm_layers": sorted(opol.TYPED_CONFIRM_LAYERS),
|
|
3486
|
+
"hard_max_ttl_s": opol.HARD_MAX_TTL_S,
|
|
3487
|
+
"coverage_note": _OVERRIDE_POLICY_NOTE,
|
|
3488
|
+
# What this Hub can do beyond the per-project GET/POST, so a client
|
|
3489
|
+
# built against a newer C3 can hide what an older one cannot serve.
|
|
3490
|
+
"features": ["clear"],
|
|
3491
|
+
})
|
|
3492
|
+
|
|
3493
|
+
|
|
3494
|
+
@app.route("/api/hub/overrides/policy/clear", methods=["POST"])
|
|
3495
|
+
def api_hub_override_policy_clear():
|
|
3496
|
+
"""Drop one project's own `override` opinions so it inherits global.
|
|
3497
|
+
|
|
3498
|
+
Body: ``{path, confirm?}``. Clearing can LOOSEN (the project may have
|
|
3499
|
+
been tighter than global), so it goes through the same widening check as
|
|
3500
|
+
a set and needs ``confirm: "widen"`` when it does. ``wake`` survives the
|
|
3501
|
+
clear. A corrupt project section is 409: it needs a human, not a reset.
|
|
3502
|
+
"""
|
|
3503
|
+
from services import override_policy as opol
|
|
3504
|
+
data = request.get_json(silent=True) or {}
|
|
3505
|
+
raw = (data.get("path") or "").strip()
|
|
3506
|
+
if not raw:
|
|
3507
|
+
return jsonify({"error": "path is required"}), 400
|
|
3508
|
+
try:
|
|
3509
|
+
project_path = str(_resolve_project_path(raw))
|
|
3510
|
+
except ValueError as e:
|
|
3511
|
+
return jsonify({"error": str(e)}), 404
|
|
3512
|
+
try:
|
|
3513
|
+
kept, widens = opol.clear_section(
|
|
3514
|
+
project_path, confirmed=(data.get("confirm") == "widen"))
|
|
3515
|
+
except opol.PolicyEditError as exc:
|
|
3516
|
+
return jsonify(exc.payload), exc.status
|
|
3517
|
+
except (OSError, ValueError) as exc:
|
|
3518
|
+
return jsonify({"error": f"{type(exc).__name__}: {exc}"}), 500
|
|
3519
|
+
cleared = kept is not None
|
|
3520
|
+
if cleared:
|
|
3521
|
+
_hub_policy_audit(project_path, "clear",
|
|
3522
|
+
{"kept": sorted(kept), "widened": list(widens)})
|
|
3523
|
+
return jsonify({"path": project_path, "cleared": cleared,
|
|
3524
|
+
"policy": opol.resolve(project_path).as_dict(),
|
|
3525
|
+
"widened": widens})
|
|
3526
|
+
|
|
3527
|
+
|
|
3342
3528
|
@app.route("/api/hub/overrides/<request_id>", methods=["POST"])
|
|
3343
3529
|
def api_hub_override_decide(request_id):
|
|
3344
3530
|
"""Approve (minting a grant) or deny one request. decided_by='desktop'.
|
{code_context_control-2.140.0 → code_context_control-2.141.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.141.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
|
|
@@ -418,6 +418,7 @@ tests/test_hub_locks_routes.py
|
|
|
418
418
|
tests/test_hub_oracle_service_routes.py
|
|
419
419
|
tests/test_hub_override_policy_routes.py
|
|
420
420
|
tests/test_hub_override_routes.py
|
|
421
|
+
tests/test_hub_rules_routes.py
|
|
421
422
|
tests/test_hub_server_smoke.py
|
|
422
423
|
tests/test_hub_subproject_links.py
|
|
423
424
|
tests/test_ide_workflow_adaptation.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "code-context-control"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.141.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"
|
{code_context_control-2.140.0 → code_context_control-2.141.0}/services/enforcement_policy.py
RENAMED
|
@@ -423,3 +423,41 @@ def set_fields(project_path: str = ".", *, scope: str = "project",
|
|
|
423
423
|
_write_config(cfg, data)
|
|
424
424
|
result["changed"] = changed
|
|
425
425
|
return result
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
def clear(project_path: str = ".", *, scope: str = "project") -> dict:
|
|
429
|
+
"""Drop a scope's whole ``enforcement`` section so it inherits again.
|
|
430
|
+
|
|
431
|
+
``resolve()`` stops at the first scope whose section exists, so there is
|
|
432
|
+
no value a surface can WRITE that means "use the global default" — only
|
|
433
|
+
removing the section does. Every field goes (mode, set_by, signal_ttl_s,
|
|
434
|
+
blocked_tools): a ttl left behind would be the mode-less partial section
|
|
435
|
+
``set_fields`` refuses to create. Clearing the global scope falls back to
|
|
436
|
+
``DEFAULT_MODE``.
|
|
437
|
+
|
|
438
|
+
Returns ``{"previous", "cleared", "mode", "scope", "path"}`` where
|
|
439
|
+
``mode``/``scope`` are the EFFECTIVE policy afterwards (``scope`` is where
|
|
440
|
+
it now comes from: global | default). No section is a no-op with
|
|
441
|
+
``cleared=False``, never an error — the surface asked for "inherit" and
|
|
442
|
+
that is already the state.
|
|
443
|
+
"""
|
|
444
|
+
if scope not in ("project", "global"):
|
|
445
|
+
raise ValueError(f"unknown scope '{scope}' — expected project|global")
|
|
446
|
+
cfg = _config_path(scope, project_path)
|
|
447
|
+
if cfg is None:
|
|
448
|
+
raise ValueError("no home directory available for the global scope")
|
|
449
|
+
|
|
450
|
+
data = _load_config_data(cfg)
|
|
451
|
+
section = data.get(_SECTION)
|
|
452
|
+
previous = (str(section.get("mode") or "")
|
|
453
|
+
if isinstance(section, dict) else "")
|
|
454
|
+
cleared = _SECTION in data
|
|
455
|
+
if cleared:
|
|
456
|
+
del data[_SECTION]
|
|
457
|
+
_write_config(cfg, data)
|
|
458
|
+
|
|
459
|
+
after = resolve(project_path) if scope == "project" else resolve_global()
|
|
460
|
+
return {"previous": previous, "cleared": cleared,
|
|
461
|
+
"mode": after.mode or DEFAULT_MODE,
|
|
462
|
+
"scope": after.scope if after.mode else "default",
|
|
463
|
+
"path": str(cfg)}
|
|
@@ -434,6 +434,10 @@ def _global_base() -> Path | None:
|
|
|
434
434
|
return None
|
|
435
435
|
|
|
436
436
|
|
|
437
|
+
#: Sentinel for :func:`_resolve` — "read the project scope from disk".
|
|
438
|
+
_READ = object()
|
|
439
|
+
|
|
440
|
+
|
|
437
441
|
def resolve(project_path: str = ".") -> OverridePolicy:
|
|
438
442
|
"""Effective policy for *project_path*: defaults ← global ← project.
|
|
439
443
|
|
|
@@ -442,6 +446,17 @@ def resolve(project_path: str = ".") -> OverridePolicy:
|
|
|
442
446
|
disables the feature outright — there is no partial-trust reading of a
|
|
443
447
|
config we could not parse.
|
|
444
448
|
"""
|
|
449
|
+
return _resolve(project_path)
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
def _resolve(project_path, project_section=_READ) -> OverridePolicy:
|
|
453
|
+
""":func:`resolve`, optionally with the project's section SUBSTITUTED.
|
|
454
|
+
|
|
455
|
+
``project_section`` other than ``_READ`` stands in for what the project's
|
|
456
|
+
config holds (``None`` = no section), so a caller can ask "what would the
|
|
457
|
+
effective policy be after this edit" without writing anything first. That
|
|
458
|
+
is what lets a clear be widening-checked before it lands.
|
|
459
|
+
"""
|
|
445
460
|
try:
|
|
446
461
|
proj = Path(project_path).resolve()
|
|
447
462
|
except Exception:
|
|
@@ -453,7 +468,10 @@ def resolve(project_path: str = ".") -> OverridePolicy:
|
|
|
453
468
|
for scope, base in (("global", gbase), ("project", proj)):
|
|
454
469
|
if base is None or (scope == "global" and gbase == proj):
|
|
455
470
|
continue
|
|
456
|
-
|
|
471
|
+
if scope == "project" and project_section is not _READ:
|
|
472
|
+
section, bad = project_section, False
|
|
473
|
+
else:
|
|
474
|
+
section, bad = _read_scope(base)
|
|
457
475
|
if bad:
|
|
458
476
|
corrupt.append(scope)
|
|
459
477
|
warnings.append(
|
|
@@ -466,7 +484,55 @@ def resolve(project_path: str = ".") -> OverridePolicy:
|
|
|
466
484
|
if corrupt:
|
|
467
485
|
return OverridePolicy(warnings=tuple(warnings),
|
|
468
486
|
corrupt_scopes=tuple(corrupt))
|
|
487
|
+
return _merge(sections, warnings)
|
|
488
|
+
|
|
469
489
|
|
|
490
|
+
def resolve_global() -> OverridePolicy:
|
|
491
|
+
"""The global (``~``) scope over the defaults, with no project opinion.
|
|
492
|
+
|
|
493
|
+
What a project that sets nothing inherits — the baseline a cross-project
|
|
494
|
+
screen shows beside each row. A corrupt global section disables the
|
|
495
|
+
feature here exactly as it does for every project.
|
|
496
|
+
"""
|
|
497
|
+
gbase = _global_base()
|
|
498
|
+
if gbase is None:
|
|
499
|
+
return _merge([], [])
|
|
500
|
+
section, bad = _read_scope(gbase)
|
|
501
|
+
if bad:
|
|
502
|
+
return OverridePolicy(
|
|
503
|
+
warnings=("[c3-override] the 'global' scope's `override` section "
|
|
504
|
+
"is invalid or unparseable — overrides are DISABLED "
|
|
505
|
+
f"(fix {gbase / '.c3' / 'config.json'} by hand)",),
|
|
506
|
+
corrupt_scopes=("global",))
|
|
507
|
+
return _merge([section] if section is not None else [], [])
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
def scope_keys(base) -> tuple[list, bool, bool]:
|
|
511
|
+
"""``(keys, present, corrupt)`` for one scope's own ``override`` section.
|
|
512
|
+
|
|
513
|
+
``keys`` names what that scope expresses an opinion on — layers as
|
|
514
|
+
``layers.<key>`` — so a screen can say which values a project pins and
|
|
515
|
+
which it inherits. ``present`` is whether a section exists at all.
|
|
516
|
+
"""
|
|
517
|
+
if base is None:
|
|
518
|
+
return [], False, False
|
|
519
|
+
section, bad = _read_scope(Path(base))
|
|
520
|
+
if bad:
|
|
521
|
+
return [], True, True
|
|
522
|
+
if section is None:
|
|
523
|
+
return [], False, False
|
|
524
|
+
keys = [k for k in section if k != "layers"]
|
|
525
|
+
keys += [f"layers.{k}" for k in (section.get("layers") or {})]
|
|
526
|
+
return sorted(keys), True, False
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
def global_scope_keys() -> tuple[list, bool, bool]:
|
|
530
|
+
""":func:`scope_keys` for the global (``~``) scope."""
|
|
531
|
+
return scope_keys(_global_base())
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
def _merge(sections: list, warnings: list) -> OverridePolicy:
|
|
535
|
+
"""Fold validated sections (global first, project last) over DEFAULTS."""
|
|
470
536
|
values = dict(DEFAULTS)
|
|
471
537
|
values["layers"] = dict(DEFAULTS["layers"])
|
|
472
538
|
|
|
@@ -677,6 +743,66 @@ def apply_section(project_path, section: dict, *, confirmed: bool = False,
|
|
|
677
743
|
return write_section(project_path, section), widens
|
|
678
744
|
|
|
679
745
|
|
|
746
|
+
def clear_section(project_path, *, confirmed: bool = False) -> tuple[dict, list]:
|
|
747
|
+
"""Drop the project's own `override` opinions so it inherits global again.
|
|
748
|
+
|
|
749
|
+
Returns ``(remaining_block, widens)``; ``remaining_block`` is ``{}`` when
|
|
750
|
+
nothing is left, and ``None`` when there was no section to clear.
|
|
751
|
+
|
|
752
|
+
``wake`` survives: it is not a permission, no remote surface may write it,
|
|
753
|
+
and "inherit the policy" is not a request to stop telling the agent about
|
|
754
|
+
decisions. Everything else goes.
|
|
755
|
+
|
|
756
|
+
Clearing is NOT automatically a tightening. Merge is tightening-only, so a
|
|
757
|
+
project section can only ever hold the policy at or below global — which
|
|
758
|
+
means removing it can loosen. The widening check runs against the policy
|
|
759
|
+
as it would resolve afterwards, and demands ``confirmed`` exactly as
|
|
760
|
+
:func:`apply_section` does.
|
|
761
|
+
|
|
762
|
+
A corrupt project section is refused rather than cleared: it currently
|
|
763
|
+
disables overrides outright, so clearing it is a silent widening of
|
|
764
|
+
whatever global allows, and the file needs a human looking at it anyway.
|
|
765
|
+
"""
|
|
766
|
+
proj = Path(project_path)
|
|
767
|
+
section, bad = _read_scope(proj)
|
|
768
|
+
if bad:
|
|
769
|
+
msg = ("the project's `override` section is invalid or unparseable "
|
|
770
|
+
"(overrides are disabled for it) — fix "
|
|
771
|
+
f"{proj / '.c3' / 'config.json'} by hand rather than clearing it")
|
|
772
|
+
raise PolicyEditError(msg, status=409,
|
|
773
|
+
payload={"error": msg, "corrupt": True})
|
|
774
|
+
if section is None:
|
|
775
|
+
return None, []
|
|
776
|
+
|
|
777
|
+
kept = {WAKE_KEY: section[WAKE_KEY]} if WAKE_KEY in section else None
|
|
778
|
+
current = resolve(str(project_path))
|
|
779
|
+
after = _resolve(str(project_path), kept)
|
|
780
|
+
widens = widenings(current, after.as_dict())
|
|
781
|
+
if widens and not confirmed:
|
|
782
|
+
msg = "clearing this widens what an approval can allow: " + ", ".join(widens)
|
|
783
|
+
raise PolicyEditError(
|
|
784
|
+
msg,
|
|
785
|
+
payload={"error": msg, "widens": widens,
|
|
786
|
+
"needs_confirmation": True, "confirm_with": "widen"},
|
|
787
|
+
widens=widens)
|
|
788
|
+
|
|
789
|
+
from services.atomic_json import write_json_atomic # noqa: PLC0415
|
|
790
|
+
|
|
791
|
+
cfg_file = proj / ".c3" / "config.json"
|
|
792
|
+
try:
|
|
793
|
+
cfg = json.loads(cfg_file.read_text(encoding="utf-8")) or {}
|
|
794
|
+
except ValueError as exc:
|
|
795
|
+
raise ValueError(f"project config is not valid JSON: {exc}") from exc
|
|
796
|
+
if not isinstance(cfg, dict):
|
|
797
|
+
raise ValueError("project config is not a JSON object")
|
|
798
|
+
if kept is None:
|
|
799
|
+
cfg.pop("override", None)
|
|
800
|
+
else:
|
|
801
|
+
cfg["override"] = kept
|
|
802
|
+
write_json_atomic(cfg_file, cfg, ensure_ascii=False, trailing_newline=False)
|
|
803
|
+
return dict(kept or {}), widens
|
|
804
|
+
|
|
805
|
+
|
|
680
806
|
def offer_line(layer_key: str, path, tool: str, op: str) -> str:
|
|
681
807
|
"""The single line appended to a refusal when a layer IS escalatable.
|
|
682
808
|
|