code-context-control 2.140.0__tar.gz → 2.142.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.142.0}/PKG-INFO +1 -1
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/c3.py +1 -1
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_server.py +371 -9
- {code_context_control-2.140.0 → code_context_control-2.142.0}/code_context_control.egg-info/PKG-INFO +1 -1
- {code_context_control-2.140.0 → code_context_control-2.142.0}/code_context_control.egg-info/SOURCES.txt +2 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/pyproject.toml +1 -1
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/access_guard.py +22 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/enforcement_policy.py +38 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/override_policy.py +127 -1
- code_context_control-2.142.0/tests/test_hub_access_routes.py +230 -0
- code_context_control-2.142.0/tests/test_hub_rules_routes.py +330 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/LICENSE +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/README.md +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/_hook_utils.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/_shell_writes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/commands/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/commands/common.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/commands/parser.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/docs.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/edits.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/guide/access.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/guide/bitbucket.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/guide/credentials.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/guide/getting-started.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/guide/index.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/guide/masking.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/guide/oracle.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/guide/shared.css +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/guide/tools.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/guide/workflow.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_access_guard.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_agent_model.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_artifact.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_auto_snapshot.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_c3_signal.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_c3read.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_codex_lifecycle.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_dispatch.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_edit_ledger.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_edit_unlock.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_filter.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_ghost_files.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_pretool_enforce.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_prompt_recall.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_read.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_session_end.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_session_open.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_session_stats.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hook_terse_advisor.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/app.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/add_project.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/config_editor.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/drill_health.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/drill_panel.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/drill_tasks.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/drill_views.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/global_search.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/hub_access.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/hub_ci.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/hub_cred_audit.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/hub_credentials.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/hub_locks.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/hub_tokens.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/mcp_manager.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/modals.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/project_card.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/project_tree.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/session_drawer.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/settings_modal.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/sidebar.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/summary_bar.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/task_board.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/toasts.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/components/topbar.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui/state.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/hub_ui.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/mcp_proxy.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/mcp_server.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/progress.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/server.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/_grants.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/_helpers.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/agent.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/artifacts.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/bitbucket.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/ci.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/compress.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/credentials.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/delegate.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/edit.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/edit_verify.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/edits.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/federate.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/filter.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/impact.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/jira.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/locks.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/memory.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/override.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/project.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/read.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/search.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/session.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/shell.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/shell_job.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/shell_nudge.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/shell_parsers.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/shell_render.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/status.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/tasks.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/tools/validate.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/api.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/app.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/components/access.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/components/bitbucket.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/components/chat.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/components/credentials.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/components/dashboard.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/components/edits.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/components/enforcement.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/components/instructions.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/components/jira.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/components/memory.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/components/sessions.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/components/settings.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/components/sidebar.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/components/tasks.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/icons.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/pm_shared.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/shared.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui/theme.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui_legacy.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/cli/ui_nano.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/code_context_control.egg-info/dependency_links.txt +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/code_context_control.egg-info/entry_points.txt +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/code_context_control.egg-info/requires.txt +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/code_context_control.egg-info/top_level.txt +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/core/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/core/codex_patch.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/core/config.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/core/grok_payload.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/core/hook_command.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/core/host.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/core/ide.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/core/mcp_toml.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/core/web_security.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/config.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/listeners.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/mcp_oracle.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/oracle_server.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/oracle_ui.html +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/activity_reporter.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/api_auth.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/c3_bridge.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/chat_engine.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/chat_poll.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/chat_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/client_tokens.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/cross_memory.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/discovery_audit.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/federated_graph.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/health_checker.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/insight_engine.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/local_session.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/memory_reader.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/memory_writer.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/mobile_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/project_scanner.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/review_agent.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/tool_executor.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/services/tool_registry.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/activity.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/agents.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/app.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/busy.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/chat/conversations.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/chat/input.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/chat/markdown.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/chat/send.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/chat/stream_renderer.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/chat/toolbar.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/core.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/crossgraph.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/header.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/insights.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/projects.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/qrcode.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/settings.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/suggestions.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/oracle/ui/theme_tabs.js +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/access_telemetry.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/activity_log.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/agent_base.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/agent_downshift.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/agent_locks.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/agents.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/agents_workflow.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/artifact_defs.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/artifact_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/atomic_json.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/auto_memory.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/background_service.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/bench/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/bench/delegate_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/bench/delegate_write_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/bench/external/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/bench/external/aider_polyglot.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/bench/external/swe_bench.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/bench/map_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/bench/search_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/bench/shell_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/benchmark_dashboard.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/bitbucket_client.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/bitbucket_credentials.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/ci_act.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/ci_cache.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/ci_expr.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/ci_failures.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/ci_github.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/ci_impact.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/ci_intel.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/ci_runner.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/ci_workflow.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/circuit_breaker.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/claude_md.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/codex_integration.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/codex_transcript.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/compressor.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/context_snapshot.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/conversation_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/cred_audit.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/cred_telemetry.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/credential_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/delegate_agents.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/delegate_hints.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/delegate_write.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/dir_map.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/doc_index.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/e2e_benchmark.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/e2e_evaluator.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/e2e_tasks.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/edit_ledger.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/embedding_index.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/error_reporting.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/file_map.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/file_memory.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/git_context.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/grok_integration.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/grok_transcript.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/host_sessions.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/hub_service.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/index_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/indexer.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/jira_client.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/jira_cloud.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/jira_credentials.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/jira_data_center.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/jira_links.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/lexical_index.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/mask_activation.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/mask_mirror.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/mask_presets.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/memory.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/memory_consolidator.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/memory_distiller.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/memory_graph.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/memory_grounder.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/memory_queue.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/memory_scorer.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/metrics.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/notifications.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/ollama_bridge.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/ollama_client.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/ollama_credentials.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/oracle_service.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/output_filter.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/override_costs.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/override_grants.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/override_requests.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/override_wake.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/parser.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/project_manager.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/project_runtime.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/protocol.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/proxy_state.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/repo_map.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/repo_shape.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/reranker.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/retention.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/retrieval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/retrieval_broker.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/router.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/runtime.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/scanner.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/session_benchmark.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/session_live.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/session_manager.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/session_preloader.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/shell_jobs.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/shell_output.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/subprojects.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/task_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/telemetry.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/text_index.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/time_tracker.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/tool_classifier.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/transcript_index.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/validation_cache.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/vector_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/watcher.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/services/win_subprocess.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/setup.cfg +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_access_builtin_optout.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_access_guard.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_access_guard_meta.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_access_guard_shell_project.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_access_guard_surfaces.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_access_guard_wiring.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_activity_log_find_last.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_activity_reporter.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_agent_locks.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_aider_polyglot.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_antigravity_transition.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_artifact_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_artifact_tool.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_atomic_json.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_background_service.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_bitbucket_cli_smoke.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_bitbucket_client.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_bitbucket_config_fallback.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_bitbucket_credentials.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_bitbucket_tool.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_builtin_modes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_c3_shell.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_chat_poll.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_ci_act.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_ci_cache.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_ci_dag_ownership.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_ci_expr.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_ci_impact.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_ci_intel.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_ci_runner.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_ci_workflow.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_circuit_breaker.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_claude_md_merge.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_claude_md_updater.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_cli_smoke.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_codex_mcp_transport.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_codex_native.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_compressor_large_file.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_confirm_guard.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_confirm_guard_wiring.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_cooccurrence_bounds.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_cred_audit.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_cred_telemetry.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_credential_login_kind.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_credential_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_credential_ui_parity.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_credentials_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_credentials_tool.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_creds_cli_smoke.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_delegate_adoption_d4.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_delegate_auto.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_delegate_cascade.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_delegate_claude_d1.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_delegate_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_delegate_grok.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_delegate_host_d2.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_delegate_scout_d3.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_delegate_telemetry_d0.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_delegate_thinking_cap.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_delegate_tuning.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_delegate_version_probe.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_delegate_write.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_delegate_write_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_dir_map_c3.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_e2e_benchmark.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_edit_ledger_deadline.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_edit_ledger_hook.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_edit_locking.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_edit_normalization.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_edit_verify.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_embedding_index_deadlock.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_enforcement_flip.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_enforcement_policy.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_enforcement_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_env_parser.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_failed_calls_do_not_unlock.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_federated_graph.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_file_map_c1.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_filter_backoff.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_ghost_files.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_ghost_generation.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_git_branch_awareness.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_grok_native.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hook_access_guard.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hook_codex_compat.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hook_dispatch.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hook_grok_compat.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hook_pretool_enforce.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hook_prompt_recall.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hook_session_end.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hook_smoke.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hook_state.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hook_utf8_stdio.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hub_credentials_route.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hub_credentials_routes_write.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hub_enforcement_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hub_hook_migration.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hub_inspect_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hub_locks_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hub_oracle_service_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hub_override_policy_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hub_override_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hub_server_smoke.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_hub_subproject_links.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_ide_workflow_adaptation.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_index_cap_not_hardcoded.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_init_clear_preserves_user_content.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_init_scan.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_install_mcp_entrypoint.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_jira_cli_smoke.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_jira_client.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_jira_config_fallback.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_jira_credentials.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_jira_links.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_jira_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_jira_tool.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_large_files_c4.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_lazy_store_init.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_map_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_map_telemetry_c0.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_mask_guard.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_mask_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_mask_surfaces.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_mcp_host_guard.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_mcp_memory_timeout.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_mcp_server_smoke.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_mcp_toml.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_memory_distiller.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_memory_graph_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_memory_queue.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_memory_system.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_mobile_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_mobile_clients.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_mobile_extras.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_mobile_jobs_ci.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_mobile_override_costs.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_mobile_override_routes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_mobile_security_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_no_stale_model_pins.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_notification_dedup.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_notification_discipline.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_notification_kinds.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_ollama_credentials.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_oracle_api_auth.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_oracle_apikey_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_oracle_c3_bridge.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_oracle_chat_engine.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_oracle_chat_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_oracle_discovery_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_oracle_discovery_audit.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_oracle_health_probe.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_oracle_local_auth.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_oracle_loopback.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_oracle_ollama_bridge.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_oracle_scanner_cache.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_oracle_security_fixes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_oracle_session_bootstrap.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_oracle_subproject_awareness.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_oracle_ui_bundle.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_output_filter.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_override_costs.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_override_grants.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_override_grants_mcp.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_override_requests.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_override_wake.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_permissions.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_pm_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_project_manager.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_project_manager_merge.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_project_tool.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_read_coercion.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_read_edit_parity.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_read_outside_root.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_related_facts.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_repo_map.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_repo_shape.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_response_boilerplate.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_retention.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_review_digest.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_search_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_search_p1.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_search_p2.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_search_p2b.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_search_p3.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_search_p4.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_search_p5.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_service_durability.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_session_benchmark.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_session_budget.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_session_live.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_shell_budget_s1.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_shell_creds.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_shell_eval.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_shell_jobs_s3.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_shell_nudge_s4.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_shell_output.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_shell_parsers_s2.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_shell_robustness.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_shell_telemetry_s0.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_shell_write_ledger.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_shell_writes.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_subproject_clear_scope.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_subproject_depth_consumers.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_subproject_exclusion.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_subproject_federation.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_subproject_linkage_api.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_subprojects.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_swe_bench.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_task_store.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_task_tool.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_time_tracker.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_token_telemetry.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_token_tracking.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_tool_registry.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_ui_jsx_syntax.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_upgrade_and_version.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_validate.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_vault_write_guard.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_version_sync.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_watcher_pruning.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_web_security.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tests/test_windows_reliability.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tui/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tui/backend.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tui/main.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tui/screens/__init__.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tui/screens/benchmark_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tui/screens/claudemd_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tui/screens/compress_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tui/screens/index_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tui/screens/init_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tui/screens/mcp_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tui/screens/optimize_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tui/screens/pipe_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tui/screens/projects_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tui/screens/search_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tui/screens/session_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tui/screens/stats.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.0}/tui/screens/ui_view.py +0 -0
- {code_context_control-2.140.0 → code_context_control-2.142.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.142.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.142.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'.
|
|
@@ -3472,8 +3658,10 @@ def api_hub_access():
|
|
|
3472
3658
|
"""Effective Access Guard rules + override policy for one project.
|
|
3473
3659
|
|
|
3474
3660
|
Read-only companion to the approvals list: the per-project mode matrix
|
|
3475
|
-
the tab renders under the pending cards.
|
|
3476
|
-
|
|
3661
|
+
the tab renders under the pending cards. This route never writes; rule
|
|
3662
|
+
mutation from the Hub is ``/api/hub/access/rule`` (add) and
|
|
3663
|
+
``/api/hub/access/rule/remove`` (v2.142.0), besides the per-project
|
|
3664
|
+
server and the CLI.
|
|
3477
3665
|
"""
|
|
3478
3666
|
from services import access_guard
|
|
3479
3667
|
from services import override_policy as opol
|
|
@@ -3493,6 +3681,180 @@ def api_hub_access():
|
|
|
3493
3681
|
"policy": policy})
|
|
3494
3682
|
|
|
3495
3683
|
|
|
3684
|
+
# ── Access Guard by file type, across projects (v2.142.0) ─────────────────
|
|
3685
|
+
# The desktop surface for path rules. The phone's /api/mobile/access/rule
|
|
3686
|
+
# cannot carry a bulk edit — 12 security calls a minute and no global scope,
|
|
3687
|
+
# both on purpose for a device that leaves the building — and the per-project
|
|
3688
|
+
# server only runs while its project's UI is open. So the Hub, loopback and
|
|
3689
|
+
# human-only, gains the same two verbs with the same asymmetry: adding a rule
|
|
3690
|
+
# tightens and is one call; removing a deny rule, or ANY global-scope rule,
|
|
3691
|
+
# needs the glob retyped. Every write is audited on the target (a global
|
|
3692
|
+
# write in ~/.c3, since it has no single target project).
|
|
3693
|
+
|
|
3694
|
+
def _hub_access_audit(action: str, glob: str, kind: str, scope: str,
|
|
3695
|
+
project) -> None:
|
|
3696
|
+
"""Globs only — never file content. Failure-safe. Mirrors the phone's
|
|
3697
|
+
``_access_audit`` with ``via='hub'``."""
|
|
3698
|
+
detail = {"kind": "access", "action": action, "glob": glob,
|
|
3699
|
+
"rule_kind": kind, "scope": scope, "via": "hub"}
|
|
3700
|
+
if project is not None:
|
|
3701
|
+
try:
|
|
3702
|
+
from services.activity_log import ActivityLog as _AL
|
|
3703
|
+
_AL(str(project)).log("access_action", dict(detail))
|
|
3704
|
+
except Exception:
|
|
3705
|
+
pass
|
|
3706
|
+
try:
|
|
3707
|
+
from services.edit_ledger import EditLedger
|
|
3708
|
+
EditLedger(str(project)).log_edit(
|
|
3709
|
+
file=f"access://{glob}", change_type=f"access_{action}",
|
|
3710
|
+
summary=f"{action} {kind} rule {glob} ({scope}) via the Hub",
|
|
3711
|
+
tags=["access", action], detail=dict(detail))
|
|
3712
|
+
except Exception:
|
|
3713
|
+
pass
|
|
3714
|
+
if scope == "global":
|
|
3715
|
+
try:
|
|
3716
|
+
from services import credential_store as cred_store
|
|
3717
|
+
from services.activity_log import ActivityLog as _AL
|
|
3718
|
+
home = cred_store.global_base()
|
|
3719
|
+
if home is not None:
|
|
3720
|
+
_AL(str(home)).log("access_action", dict(detail))
|
|
3721
|
+
except Exception:
|
|
3722
|
+
pass
|
|
3723
|
+
|
|
3724
|
+
|
|
3725
|
+
def _hub_access_target(data: dict):
|
|
3726
|
+
"""``(scope, project_path_or_None, error_response_or_None)``."""
|
|
3727
|
+
scope = str(data.get("scope") or "project").strip().lower()
|
|
3728
|
+
if scope not in ("project", "global"):
|
|
3729
|
+
return scope, None, (jsonify(
|
|
3730
|
+
{"error": "scope must be 'project' or 'global'"}), 400)
|
|
3731
|
+
if scope == "global":
|
|
3732
|
+
return scope, None, None
|
|
3733
|
+
raw = str(data.get("path") or "").strip()
|
|
3734
|
+
if not raw:
|
|
3735
|
+
return scope, None, (jsonify(
|
|
3736
|
+
{"error": "path is required for project scope"}), 400)
|
|
3737
|
+
try:
|
|
3738
|
+
resolved = _resolve_project_path(raw)
|
|
3739
|
+
except ValueError as e:
|
|
3740
|
+
return scope, None, (jsonify({"error": str(e)}), 404)
|
|
3741
|
+
# set_rule would create .c3/config.json in any directory it is handed;
|
|
3742
|
+
# a rule in a folder C3 does not manage protects nothing and says it does.
|
|
3743
|
+
if not (Path(resolved) / ".c3").is_dir():
|
|
3744
|
+
return scope, None, (jsonify(
|
|
3745
|
+
{"error": "not initialized for C3", "needs_init": True}), 409)
|
|
3746
|
+
return scope, str(resolved), None
|
|
3747
|
+
|
|
3748
|
+
|
|
3749
|
+
@app.route("/api/hub/access/overview", methods=["GET"])
|
|
3750
|
+
def api_hub_access_overview():
|
|
3751
|
+
"""Every registered project's own path rules, plus global and builtin.
|
|
3752
|
+
|
|
3753
|
+
Per-row isolation like the enforcement and policy overviews: a project we
|
|
3754
|
+
could not read reports ``error`` rather than an empty rule list — "no
|
|
3755
|
+
rules" is a claim about a repo, and we would be making it blind. A corrupt
|
|
3756
|
+
scope is reported as corrupt: it evaluates deny-all until repaired by
|
|
3757
|
+
hand, which is the opposite of what an empty list would suggest.
|
|
3758
|
+
Builtin rules are read once, from the global realm; a project-scope
|
|
3759
|
+
builtin mode (set with the CLI) is not reflected per row.
|
|
3760
|
+
"""
|
|
3761
|
+
empty = {"deny": [], "read_only": [], "confirm": [], "mask": 0,
|
|
3762
|
+
"corrupt": False}
|
|
3763
|
+
rows = []
|
|
3764
|
+
for p in _pm().list_projects():
|
|
3765
|
+
ppath = str(p.get("path") or "")
|
|
3766
|
+
row = {"name": p.get("name") or Path(ppath).name, "path": ppath,
|
|
3767
|
+
"initialized": True, "error": None, "rules": dict(empty)}
|
|
3768
|
+
try:
|
|
3769
|
+
if not (Path(ppath) / ".c3").is_dir():
|
|
3770
|
+
row["initialized"] = False
|
|
3771
|
+
else:
|
|
3772
|
+
row["rules"] = access_guard.scope_rules("project", ppath)
|
|
3773
|
+
except Exception as e:
|
|
3774
|
+
row["error"] = str(e)
|
|
3775
|
+
rows.append(row)
|
|
3776
|
+
|
|
3777
|
+
try:
|
|
3778
|
+
global_rules = {**access_guard.scope_rules("global"), "error": None}
|
|
3779
|
+
except Exception as e:
|
|
3780
|
+
global_rules = {**empty, "error": str(e)}
|
|
3781
|
+
try:
|
|
3782
|
+
home = access_guard._global_base()
|
|
3783
|
+
b = access_guard.list_rules(str(home) if home else ".")["builtin"]
|
|
3784
|
+
builtin = {"deny": list(b.get("deny") or []),
|
|
3785
|
+
"read_only": list(b.get("read_only") or []),
|
|
3786
|
+
"confirm": list(b.get("confirm") or []), "error": None}
|
|
3787
|
+
except Exception as e:
|
|
3788
|
+
builtin = {"deny": [], "read_only": [], "confirm": [], "error": str(e)}
|
|
3789
|
+
|
|
3790
|
+
return jsonify({
|
|
3791
|
+
"projects": rows,
|
|
3792
|
+
"global": global_rules,
|
|
3793
|
+
"builtin": builtin,
|
|
3794
|
+
# Strictest last. "allow" is the absence of a rule, not a kind.
|
|
3795
|
+
"kinds": ["confirm", "read_only", "deny"],
|
|
3796
|
+
"coverage_note": access_guard.COVERAGE_MATRIX,
|
|
3797
|
+
})
|
|
3798
|
+
|
|
3799
|
+
|
|
3800
|
+
@app.route("/api/hub/access/rule", methods=["POST"])
|
|
3801
|
+
def api_hub_access_rule_add():
|
|
3802
|
+
"""Add one deny / read_only / confirm rule. Tightening — no confirmation.
|
|
3803
|
+
|
|
3804
|
+
Body: ``{path?, scope?, glob, kind}``. ``added: false`` when an equivalent
|
|
3805
|
+
glob is already there (a 200, not an error: the caller asked for the
|
|
3806
|
+
state it is in).
|
|
3807
|
+
"""
|
|
3808
|
+
data = request.get_json(silent=True) or {}
|
|
3809
|
+
scope, project, err = _hub_access_target(data)
|
|
3810
|
+
if err:
|
|
3811
|
+
return err
|
|
3812
|
+
glob = str(data.get("glob") or "")
|
|
3813
|
+
kind = str(data.get("kind") or "").strip()
|
|
3814
|
+
try:
|
|
3815
|
+
result = access_guard.set_rule(glob, kind, scope, project or ".")
|
|
3816
|
+
except ValueError as exc:
|
|
3817
|
+
return jsonify({"error": str(exc)}), 400
|
|
3818
|
+
if result["added"]:
|
|
3819
|
+
_hub_access_audit("add", result["glob"], kind, scope, project)
|
|
3820
|
+
return jsonify({"rule": result})
|
|
3821
|
+
|
|
3822
|
+
|
|
3823
|
+
@app.route("/api/hub/access/rule/remove", methods=["POST"])
|
|
3824
|
+
def api_hub_access_rule_remove():
|
|
3825
|
+
"""Remove one rule. Loosening.
|
|
3826
|
+
|
|
3827
|
+
Body: ``{path?, scope?, glob, kind, confirm?}``. A ``deny`` rule, and any
|
|
3828
|
+
rule in the GLOBAL scope (it governs every project on the machine), needs
|
|
3829
|
+
``confirm`` equal to the glob — the CLI's "type the glob again". A
|
|
3830
|
+
read_only or confirm rule in one project does not: it downgrades writes
|
|
3831
|
+
to writable-or-ask, not to fully visible. POST rather than DELETE so the
|
|
3832
|
+
body survives every client.
|
|
3833
|
+
"""
|
|
3834
|
+
data = request.get_json(silent=True) or {}
|
|
3835
|
+
scope, project, err = _hub_access_target(data)
|
|
3836
|
+
if err:
|
|
3837
|
+
return err
|
|
3838
|
+
glob = str(data.get("glob") or "")
|
|
3839
|
+
kind = str(data.get("kind") or "").strip()
|
|
3840
|
+
canon = access_guard._norm_glob(glob)
|
|
3841
|
+
if kind == "deny" or scope == "global":
|
|
3842
|
+
if access_guard._norm_glob(data.get("confirm")) != canon or not canon:
|
|
3843
|
+
return jsonify({
|
|
3844
|
+
"error": ("removing a deny rule weakens protection"
|
|
3845
|
+
if kind == "deny" else
|
|
3846
|
+
"removing a global rule weakens every project"),
|
|
3847
|
+
"needs_confirmation": True, "confirm_with": canon,
|
|
3848
|
+
}), 400
|
|
3849
|
+
try:
|
|
3850
|
+
result = access_guard.remove_rule(glob, kind, scope, project or ".")
|
|
3851
|
+
except ValueError as exc:
|
|
3852
|
+
return jsonify({"error": str(exc)}), 400
|
|
3853
|
+
if result["removed"]:
|
|
3854
|
+
_hub_access_audit("remove", result["glob"], kind, scope, project)
|
|
3855
|
+
return jsonify(result)
|
|
3856
|
+
|
|
3857
|
+
|
|
3496
3858
|
# ── Project management: tasks / milestones / notes (v2.45.0) ──────────────
|
|
3497
3859
|
# Direct TaskStore per request (reload-per-op store — no runtime build needed
|
|
3498
3860
|
# for mutations); every write audited to the target project's activity log.
|
{code_context_control-2.140.0 → code_context_control-2.142.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.142.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
|
|
@@ -409,6 +409,7 @@ tests/test_hook_session_end.py
|
|
|
409
409
|
tests/test_hook_smoke.py
|
|
410
410
|
tests/test_hook_state.py
|
|
411
411
|
tests/test_hook_utf8_stdio.py
|
|
412
|
+
tests/test_hub_access_routes.py
|
|
412
413
|
tests/test_hub_credentials_route.py
|
|
413
414
|
tests/test_hub_credentials_routes_write.py
|
|
414
415
|
tests/test_hub_enforcement_routes.py
|
|
@@ -418,6 +419,7 @@ tests/test_hub_locks_routes.py
|
|
|
418
419
|
tests/test_hub_oracle_service_routes.py
|
|
419
420
|
tests/test_hub_override_policy_routes.py
|
|
420
421
|
tests/test_hub_override_routes.py
|
|
422
|
+
tests/test_hub_rules_routes.py
|
|
421
423
|
tests/test_hub_server_smoke.py
|
|
422
424
|
tests/test_hub_subproject_links.py
|
|
423
425
|
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.142.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"
|
|
@@ -1439,6 +1439,28 @@ def list_rules(project_path: str = ".") -> dict:
|
|
|
1439
1439
|
return out
|
|
1440
1440
|
|
|
1441
1441
|
|
|
1442
|
+
def scope_rules(scope: str, project_path: str = ".") -> dict:
|
|
1443
|
+
"""One scope's OWN list rules, for a cross-project screen.
|
|
1444
|
+
|
|
1445
|
+
``{"deny": [...], "read_only": [...], "confirm": [...], "mask": <count>,
|
|
1446
|
+
"corrupt": bool}``. Globs come back in the canonical storage form
|
|
1447
|
+
(:func:`_norm_glob`), which is what :func:`set_rule` writes and what
|
|
1448
|
+
:func:`remove_rule` compares against, so a caller can match a row to the
|
|
1449
|
+
rule it would remove without re-deriving the spelling. A missing file is
|
|
1450
|
+
an empty scope; an unreadable one is ``corrupt`` (it evaluates deny-all
|
|
1451
|
+
until repaired by hand). Unlike :func:`list_rules` this touches no
|
|
1452
|
+
keyring and computes no builtin modes, so it is cheap enough to run over
|
|
1453
|
+
every registered project in one request.
|
|
1454
|
+
"""
|
|
1455
|
+
cfg = _scope_config_path(scope, project_path)
|
|
1456
|
+
section, corrupt = _raw_scope_section(cfg)
|
|
1457
|
+
out = {k: [_norm_glob(g) for g in _str_list(section.get(k))]
|
|
1458
|
+
for k in _LIST_KINDS}
|
|
1459
|
+
out[_KIND_MASK] = len(_mask_list(section.get(_KIND_MASK)))
|
|
1460
|
+
out["corrupt"] = corrupt
|
|
1461
|
+
return out
|
|
1462
|
+
|
|
1463
|
+
|
|
1442
1464
|
def _load_config_for_write(cfg: Path) -> tuple:
|
|
1443
1465
|
"""(config_dict, access_section) for read-modify-write of one scope.
|
|
1444
1466
|
|
{code_context_control-2.140.0 → code_context_control-2.142.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)}
|