code-context-control 2.129.1__tar.gz → 2.129.2__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.129.1 → code_context_control-2.129.2}/PKG-INFO +1 -1
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/c3.py +1 -1
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_server.py +79 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/hub_access.js +183 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/code_context_control.egg-info/PKG-INFO +1 -1
- {code_context_control-2.129.1 → code_context_control-2.129.2}/code_context_control.egg-info/SOURCES.txt +1 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/mobile_api.py +29 -5
- {code_context_control-2.129.1 → code_context_control-2.129.2}/pyproject.toml +1 -1
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/override_policy.py +147 -0
- code_context_control-2.129.2/tests/test_hub_override_policy_routes.py +154 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/LICENSE +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/README.md +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/__init__.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/_hook_utils.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/_shell_writes.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/commands/__init__.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/commands/common.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/commands/parser.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/docs.html +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/edits.html +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/guide/access.html +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/guide/bitbucket.html +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/guide/credentials.html +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/guide/getting-started.html +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/guide/index.html +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/guide/masking.html +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/guide/oracle.html +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/guide/shared.css +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/guide/tools.html +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/guide/workflow.html +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_access_guard.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_artifact.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_auto_snapshot.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_c3_signal.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_c3read.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_codex_lifecycle.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_dispatch.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_edit_ledger.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_edit_unlock.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_filter.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_ghost_files.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_pretool_enforce.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_prompt_recall.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_read.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_session_end.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_session_open.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_session_stats.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hook_terse_advisor.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/app.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/add_project.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/config_editor.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/drill_artifacts.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/drill_health.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/drill_panel.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/drill_subprojects.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/drill_tasks.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/drill_views.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/global_search.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/hub_ci.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/hub_cred_audit.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/hub_credentials.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/hub_enforcement.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/hub_locks.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/hub_tokens.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/mcp_manager.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/modals.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/project_card.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/project_tree.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/session_drawer.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/settings_modal.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/sidebar.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/summary_bar.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/task_board.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/toasts.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/topbar.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/state.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui.html +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/mcp_proxy.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/mcp_server.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/progress.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/server.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/__init__.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/_grants.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/_helpers.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/agent.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/artifacts.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/bitbucket.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/ci.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/compress.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/credentials.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/delegate.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/edit.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/edit_verify.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/edits.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/federate.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/filter.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/impact.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/jira.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/locks.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/memory.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/override.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/project.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/read.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/search.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/session.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/shell.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/shell_job.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/shell_nudge.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/shell_parsers.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/shell_render.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/status.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/tasks.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/tools/validate.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/api.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/app.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/components/access.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/components/bitbucket.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/components/chat.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/components/credentials.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/components/dashboard.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/components/edits.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/components/enforcement.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/components/instructions.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/components/jira.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/components/memory.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/components/sessions.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/components/settings.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/components/sidebar.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/components/tasks.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/icons.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/pm_shared.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/shared.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui/theme.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui.html +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui_legacy.html +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/cli/ui_nano.html +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/code_context_control.egg-info/dependency_links.txt +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/code_context_control.egg-info/entry_points.txt +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/code_context_control.egg-info/requires.txt +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/code_context_control.egg-info/top_level.txt +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/core/__init__.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/core/codex_patch.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/core/config.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/core/host.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/core/ide.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/core/mcp_toml.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/core/web_security.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/__init__.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/config.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/listeners.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/mcp_oracle.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/oracle_server.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/oracle_ui.html +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/__init__.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/activity_reporter.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/api_auth.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/c3_bridge.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/chat_engine.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/chat_poll.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/chat_store.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/client_tokens.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/cross_memory.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/discovery_audit.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/federated_graph.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/health_checker.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/insight_engine.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/local_session.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/memory_reader.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/memory_writer.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/project_scanner.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/review_agent.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/tool_executor.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/services/tool_registry.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/activity.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/agents.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/app.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/busy.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/chat/conversations.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/chat/input.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/chat/markdown.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/chat/send.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/chat/stream_renderer.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/chat/toolbar.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/core.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/crossgraph.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/header.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/insights.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/projects.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/qrcode.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/settings.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/suggestions.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/oracle/ui/theme_tabs.js +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/__init__.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/access_guard.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/access_telemetry.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/activity_log.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/agent_base.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/agent_locks.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/agents.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/artifact_defs.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/artifact_store.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/atomic_json.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/auto_memory.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/background_service.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/bench/__init__.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/bench/external/__init__.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/bench/external/aider_polyglot.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/bench/external/swe_bench.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/bench/map_eval.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/bench/search_eval.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/bench/shell_eval.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/benchmark_dashboard.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/bitbucket_client.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/bitbucket_credentials.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/ci_act.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/ci_cache.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/ci_expr.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/ci_failures.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/ci_github.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/ci_impact.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/ci_intel.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/ci_runner.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/ci_workflow.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/circuit_breaker.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/claude_md.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/codex_integration.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/codex_transcript.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/compressor.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/context_snapshot.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/conversation_store.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/cred_audit.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/cred_telemetry.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/credential_store.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/dir_map.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/doc_index.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/e2e_benchmark.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/e2e_evaluator.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/e2e_tasks.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/edit_ledger.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/embedding_index.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/enforcement_policy.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/error_reporting.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/file_map.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/file_memory.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/git_context.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/host_sessions.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/hub_service.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/index_store.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/indexer.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/jira_client.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/jira_cloud.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/jira_credentials.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/jira_data_center.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/jira_links.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/lexical_index.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/mask_activation.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/mask_mirror.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/mask_presets.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/memory.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/memory_consolidator.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/memory_distiller.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/memory_graph.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/memory_grounder.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/memory_queue.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/memory_scorer.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/metrics.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/notifications.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/ollama_bridge.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/ollama_client.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/ollama_credentials.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/oracle_service.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/output_filter.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/override_costs.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/override_grants.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/override_requests.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/override_wake.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/parser.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/project_manager.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/project_runtime.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/protocol.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/proxy_state.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/repo_map.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/repo_shape.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/reranker.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/retention.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/retrieval.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/retrieval_broker.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/router.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/runtime.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/scanner.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/session_benchmark.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/session_live.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/session_manager.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/session_preloader.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/shell_jobs.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/shell_output.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/subprojects.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/task_store.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/telemetry.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/text_index.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/time_tracker.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/tool_classifier.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/transcript_index.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/validation_cache.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/vector_store.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/watcher.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/services/win_subprocess.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/setup.cfg +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_access_builtin_optout.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_access_guard.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_access_guard_meta.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_access_guard_shell_project.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_access_guard_surfaces.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_access_guard_wiring.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_activity_log_find_last.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_activity_reporter.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_agent_locks.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_aider_polyglot.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_antigravity_transition.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_artifact_store.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_artifact_tool.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_atomic_json.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_background_service.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_bitbucket_cli_smoke.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_bitbucket_client.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_bitbucket_config_fallback.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_bitbucket_credentials.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_bitbucket_tool.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_builtin_modes.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_c3_bridge_project_artifacts.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_c3_shell.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_chat_poll.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_ci_act.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_ci_cache.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_ci_expr.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_ci_impact.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_ci_intel.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_ci_runner.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_ci_workflow.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_circuit_breaker.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_claude_md_merge.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_claude_md_updater.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_cli_smoke.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_codex_mcp_transport.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_codex_native.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_compressor_large_file.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_confirm_guard.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_confirm_guard_wiring.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_cooccurrence_bounds.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_cred_audit.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_cred_telemetry.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_credential_login_kind.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_credential_store.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_credential_ui_parity.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_credentials_routes.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_credentials_tool.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_creds_cli_smoke.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_delegate_cascade.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_delegate_version_probe.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_dir_map_c3.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_e2e_benchmark.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_edit_ledger_deadline.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_edit_ledger_hook.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_edit_locking.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_edit_normalization.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_edit_verify.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_embedding_index_deadlock.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_enforcement_flip.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_enforcement_policy.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_enforcement_routes.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_env_parser.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_failed_calls_do_not_unlock.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_federated_graph.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_file_map_c1.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_filter_backoff.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_ghost_files.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_ghost_generation.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_git_branch_awareness.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hook_access_guard.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hook_codex_compat.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hook_dispatch.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hook_pretool_enforce.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hook_prompt_recall.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hook_session_end.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hook_smoke.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hook_state.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hook_utf8_stdio.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hub_credentials_route.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hub_credentials_routes_write.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hub_enforcement_routes.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hub_hook_migration.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hub_inspect_api.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hub_locks_routes.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hub_oracle_service_routes.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hub_override_routes.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hub_server_smoke.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_hub_subproject_links.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_ide_workflow_adaptation.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_index_cap_not_hardcoded.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_init_clear_preserves_user_content.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_init_scan.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_install_mcp_entrypoint.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_jira_cli_smoke.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_jira_client.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_jira_config_fallback.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_jira_credentials.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_jira_links.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_jira_routes.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_jira_tool.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_large_files_c4.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_lazy_store_init.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_map_eval.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_map_telemetry_c0.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_mask_guard.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_mask_routes.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_mask_surfaces.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_mcp_host_guard.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_mcp_memory_timeout.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_mcp_server_smoke.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_mcp_toml.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_memory_distiller.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_memory_graph_api.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_memory_queue.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_memory_system.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_mobile_api.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_mobile_clients.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_mobile_extras.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_mobile_jobs_ci.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_mobile_override_costs.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_mobile_override_routes.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_mobile_security_api.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_no_stale_model_pins.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_notification_dedup.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_notification_discipline.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_notification_kinds.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_ollama_credentials.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_oracle_api_auth.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_oracle_apikey_api.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_oracle_c3_bridge.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_oracle_chat_engine.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_oracle_chat_store.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_oracle_discovery_api.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_oracle_discovery_audit.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_oracle_health_probe.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_oracle_local_auth.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_oracle_loopback.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_oracle_ollama_bridge.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_oracle_scanner_cache.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_oracle_security_fixes.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_oracle_session_bootstrap.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_oracle_subproject_awareness.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_oracle_ui_bundle.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_output_filter.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_override_costs.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_override_grants.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_override_grants_mcp.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_override_requests.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_override_wake.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_permissions.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_pm_api.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_project_manager.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_project_manager_merge.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_project_tool.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_read_coercion.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_read_edit_parity.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_read_outside_root.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_related_facts.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_repo_map.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_repo_shape.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_response_boilerplate.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_retention.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_review_digest.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_search_eval.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_search_p1.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_search_p2.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_search_p2b.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_search_p3.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_search_p4.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_search_p5.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_service_durability.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_session_benchmark.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_session_budget.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_session_live.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_shell_budget_s1.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_shell_creds.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_shell_eval.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_shell_jobs_s3.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_shell_nudge_s4.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_shell_output.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_shell_parsers_s2.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_shell_robustness.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_shell_telemetry_s0.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_shell_write_ledger.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_shell_writes.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_subproject_clear_scope.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_subproject_depth_consumers.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_subproject_exclusion.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_subproject_federation.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_subproject_linkage_api.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_subprojects.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_swe_bench.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_task_store.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_task_tool.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_time_tracker.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_token_telemetry.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_token_tracking.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_tool_registry.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_ui_jsx_syntax.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_upgrade_and_version.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_validate.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_vault_write_guard.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_version_sync.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_watcher_pruning.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_web_security.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tests/test_windows_reliability.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/__init__.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/backend.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/main.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/screens/__init__.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/screens/benchmark_view.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/screens/claudemd_view.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/screens/compress_view.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/screens/index_view.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/screens/init_view.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/screens/mcp_view.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/screens/optimize_view.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/screens/pipe_view.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/screens/projects_view.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/screens/search_view.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/screens/session_view.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/screens/stats.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/screens/ui_view.py +0 -0
- {code_context_control-2.129.1 → code_context_control-2.129.2}/tui/theme.tcss +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-context-control
|
|
3
|
-
Version: 2.129.
|
|
3
|
+
Version: 2.129.2
|
|
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
|
|
@@ -3259,6 +3259,85 @@ def api_hub_override_costs():
|
|
|
3259
3259
|
"project": project_path})
|
|
3260
3260
|
|
|
3261
3261
|
|
|
3262
|
+
@app.route("/api/hub/overrides/policy", methods=["GET"])
|
|
3263
|
+
def api_hub_override_policy_get():
|
|
3264
|
+
"""The effective `override` section for one project.
|
|
3265
|
+
|
|
3266
|
+
WHY THE HUB NEEDS THIS. The hub could already LIST override requests and
|
|
3267
|
+
DECIDE them, but not say whether requests may exist at all — that lives in
|
|
3268
|
+
`override.enabled`, which was reachable only from the phone API or by hand-
|
|
3269
|
+
editing `.c3/config.json`. So the hub could answer a question the agent was
|
|
3270
|
+
never allowed to ask, and the only way to change that was a text editor.
|
|
3271
|
+
|
|
3272
|
+
Registered BEFORE the POST-only ``<request_id>`` route for the same reason
|
|
3273
|
+
``costs`` is: a GET on ``policy`` must never fall through to a 405 there.
|
|
3274
|
+
"""
|
|
3275
|
+
from services import override_policy as opol
|
|
3276
|
+
raw = (request.args.get("path") or "").strip()
|
|
3277
|
+
if not raw:
|
|
3278
|
+
return jsonify({"error": "path is required"}), 400
|
|
3279
|
+
try:
|
|
3280
|
+
project_path = str(_resolve_project_path(raw))
|
|
3281
|
+
except ValueError as e:
|
|
3282
|
+
return jsonify({"error": str(e)}), 404
|
|
3283
|
+
policy = opol.resolve(project_path)
|
|
3284
|
+
return jsonify({
|
|
3285
|
+
"path": project_path,
|
|
3286
|
+
"project_name": Path(project_path).name,
|
|
3287
|
+
"policy": policy.as_dict(),
|
|
3288
|
+
"layers": list(opol.LAYER_KEYS),
|
|
3289
|
+
"typed_confirm_layers": sorted(opol.TYPED_CONFIRM_LAYERS),
|
|
3290
|
+
"hard_max_ttl_s": opol.HARD_MAX_TTL_S,
|
|
3291
|
+
# Verbatim from the spec, and the one thing a toggle screen must not
|
|
3292
|
+
# let the reader forget: policy is a floor, not a promise.
|
|
3293
|
+
"coverage_note": (
|
|
3294
|
+
"Project and global policy merge by tightening only: a layer is "
|
|
3295
|
+
"escalatable iff both scopes allow it, and the numeric limits take "
|
|
3296
|
+
"the smaller value."
|
|
3297
|
+
),
|
|
3298
|
+
})
|
|
3299
|
+
|
|
3300
|
+
|
|
3301
|
+
@app.route("/api/hub/overrides/policy", methods=["POST"])
|
|
3302
|
+
def api_hub_override_policy_set():
|
|
3303
|
+
"""Edit one project's `override` section from the hub.
|
|
3304
|
+
|
|
3305
|
+
Widening — enabling the feature or turning a layer on — needs
|
|
3306
|
+
``confirm: "widen"``. Tightening never does: making the guard stricter is
|
|
3307
|
+
always allowed to be one click.
|
|
3308
|
+
|
|
3309
|
+
Validation, widening detection and the write are
|
|
3310
|
+
``services.override_policy``'s, shared verbatim with the phone route. Two
|
|
3311
|
+
implementations of "what counts as widening" would be two chances for one
|
|
3312
|
+
surface to allow what the other refuses, and this is the check that decides
|
|
3313
|
+
whether an action needs a typed confirmation.
|
|
3314
|
+
|
|
3315
|
+
``wake`` is accepted here and refused on the phone: it names a command this
|
|
3316
|
+
machine runs, and the hub is a desktop surface on this box.
|
|
3317
|
+
"""
|
|
3318
|
+
from services import override_policy as opol
|
|
3319
|
+
data = request.get_json(silent=True) or {}
|
|
3320
|
+
raw = (data.get("path") or "").strip()
|
|
3321
|
+
if not raw:
|
|
3322
|
+
return jsonify({"error": "path is required"}), 400
|
|
3323
|
+
try:
|
|
3324
|
+
project_path = str(_resolve_project_path(raw))
|
|
3325
|
+
except ValueError as e:
|
|
3326
|
+
return jsonify({"error": str(e)}), 404
|
|
3327
|
+
try:
|
|
3328
|
+
written, widens = opol.apply_section(
|
|
3329
|
+
project_path, data.get("override"),
|
|
3330
|
+
confirmed=(data.get("confirm") == "widen"),
|
|
3331
|
+
allow_wake=True)
|
|
3332
|
+
except opol.PolicyEditError as exc:
|
|
3333
|
+
return jsonify(exc.payload), exc.status
|
|
3334
|
+
except (OSError, ValueError) as exc:
|
|
3335
|
+
return jsonify({"error": f"{type(exc).__name__}: {exc}"}), 500
|
|
3336
|
+
return jsonify({"path": project_path, "written": written,
|
|
3337
|
+
"policy": opol.resolve(project_path).as_dict(),
|
|
3338
|
+
"widened": widens})
|
|
3339
|
+
|
|
3340
|
+
|
|
3262
3341
|
@app.route("/api/hub/overrides/<request_id>", methods=["POST"])
|
|
3263
3342
|
def api_hub_override_decide(request_id):
|
|
3264
3343
|
"""Approve (minting a grant) or deny one request. decided_by='desktop'.
|
{code_context_control-2.129.1 → code_context_control-2.129.2}/cli/hub_ui/components/hub_access.js
RENAMED
|
@@ -482,6 +482,187 @@ function AccGrantsPanel({ projects }) {
|
|
|
482
482
|
}
|
|
483
483
|
|
|
484
484
|
// ── The tab ────────────────────────────────────────────────────────────────
|
|
485
|
+
// ─── Override policy (the switch, not the requests) ───────────────────────
|
|
486
|
+
//
|
|
487
|
+
// WHY THIS PANEL EXISTS. This screen could already LIST override requests and
|
|
488
|
+
// DECIDE them — but not say whether requests may exist at all. That lives in
|
|
489
|
+
// `override.enabled`, and it was reachable only from the phone API or by hand-
|
|
490
|
+
// editing .c3/config.json. So the hub answered a question the agent was never
|
|
491
|
+
// allowed to ask, and the way to change that was a text editor.
|
|
492
|
+
//
|
|
493
|
+
// THE ONE RULE HERE: widening is never silent. Enabling the feature, or
|
|
494
|
+
// turning a layer on, loosens what a single approval can allow. The server
|
|
495
|
+
// refuses those without confirm:"widen"; this panel asks in plain words BEFORE
|
|
496
|
+
// sending, rather than surfacing a 400 afterwards. Tightening goes straight
|
|
497
|
+
// through — making the guard stricter should always be one click.
|
|
498
|
+
|
|
499
|
+
// Plain-language layer names. The raw keys are accurate and mean nothing to
|
|
500
|
+
// someone deciding whether to tick a box.
|
|
501
|
+
const ACC_LAYER_NAMES = {
|
|
502
|
+
discipline: 'Discipline holds (native-tool nudges)',
|
|
503
|
+
access_readonly: 'Read-only paths — e.g. .git/**, .c3/**',
|
|
504
|
+
access_deny: 'Denied paths',
|
|
505
|
+
access_builtin: 'Built-in guards',
|
|
506
|
+
access_confirm: 'Confirm holds — agent-config files',
|
|
507
|
+
mask: 'Masked paths',
|
|
508
|
+
shell_warn: 'Shell warnings',
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
function accLayerName(key) { return ACC_LAYER_NAMES[key] || key; }
|
|
512
|
+
|
|
513
|
+
function AccPolicyPanel({ projects }) {
|
|
514
|
+
const [path, setPath] = useState('');
|
|
515
|
+
const [data, setData] = useState(null);
|
|
516
|
+
const [draft, setDraft] = useState(null); // {enabled, layers}
|
|
517
|
+
const [err, setErr] = useState('');
|
|
518
|
+
const [msg, setMsg] = useState('');
|
|
519
|
+
const [busy, setBusy] = useState(false);
|
|
520
|
+
|
|
521
|
+
const load = useCallback(async (p) => {
|
|
522
|
+
if (!p) { setData(null); setDraft(null); setErr(''); setMsg(''); return; }
|
|
523
|
+
try {
|
|
524
|
+
const d = await api.get(`/api/hub/overrides/policy?path=${encodeURIComponent(p)}`);
|
|
525
|
+
setData(d);
|
|
526
|
+
setDraft({
|
|
527
|
+
enabled: !!(d.policy || {}).enabled,
|
|
528
|
+
layers: { ...((d.policy || {}).layers || {}) },
|
|
529
|
+
});
|
|
530
|
+
setErr(''); setMsg('');
|
|
531
|
+
} catch (e) { setData(null); setDraft(null); setErr(apiErr(e)); }
|
|
532
|
+
}, []);
|
|
533
|
+
|
|
534
|
+
// Mirrors the server's own rule so the question is asked before the request,
|
|
535
|
+
// not after the refusal.
|
|
536
|
+
const widenings = () => {
|
|
537
|
+
if (!data || !draft) return [];
|
|
538
|
+
const cur = data.policy || {};
|
|
539
|
+
const out = [];
|
|
540
|
+
if (draft.enabled && !cur.enabled) out.push('enable override requests');
|
|
541
|
+
Object.entries(draft.layers || {}).forEach(([k, want]) => {
|
|
542
|
+
if (want && !(cur.layers || {})[k]) out.push(`allow asking about: ${accLayerName(k)}`);
|
|
543
|
+
});
|
|
544
|
+
return out;
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
const save = async () => {
|
|
548
|
+
if (!draft || !path) return;
|
|
549
|
+
const widens = widenings();
|
|
550
|
+
if (widens.length) {
|
|
551
|
+
const ok = window.confirm(
|
|
552
|
+
`This LOOSENS the guard:\n\n • ${widens.join('\n • ')}\n\n` +
|
|
553
|
+
'A yes still only lets the agent ASK — every request needs your ' +
|
|
554
|
+
'approval, and a grant is single-use and path-exact.\n\nApply?');
|
|
555
|
+
if (!ok) { setMsg('Unchanged.'); return; }
|
|
556
|
+
}
|
|
557
|
+
setBusy(true);
|
|
558
|
+
try {
|
|
559
|
+
const d = await api.post('/api/hub/overrides/policy', {
|
|
560
|
+
path,
|
|
561
|
+
override: { enabled: draft.enabled, layers: draft.layers },
|
|
562
|
+
confirm: widens.length ? 'widen' : undefined,
|
|
563
|
+
});
|
|
564
|
+
setData(d);
|
|
565
|
+
setDraft({
|
|
566
|
+
enabled: !!(d.policy || {}).enabled,
|
|
567
|
+
layers: { ...((d.policy || {}).layers || {}) },
|
|
568
|
+
});
|
|
569
|
+
setErr('');
|
|
570
|
+
setMsg((d.widened && d.widened.length)
|
|
571
|
+
? `Saved — widened: ${d.widened.join(', ')}`
|
|
572
|
+
: 'Saved.');
|
|
573
|
+
} catch (e) { setErr(apiErr(e)); }
|
|
574
|
+
setBusy(false);
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
const typed = new Set((data && data.typed_confirm_layers) || []);
|
|
578
|
+
const dirty = !!(data && draft) && (
|
|
579
|
+
draft.enabled !== !!(data.policy || {}).enabled ||
|
|
580
|
+
Object.entries(draft.layers || {}).some(
|
|
581
|
+
([k, v]) => !!v !== !!((data.policy || {}).layers || {})[k]));
|
|
582
|
+
|
|
583
|
+
return (
|
|
584
|
+
<div style={{
|
|
585
|
+
background: T.surface, border: `1px solid ${T.border}`, borderRadius: 10,
|
|
586
|
+
padding: '12px 16px',
|
|
587
|
+
}}>
|
|
588
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
|
|
589
|
+
<div style={{ fontSize: 12.5, fontWeight: 700, color: T.text }}>May agents ask?</div>
|
|
590
|
+
<select value={path}
|
|
591
|
+
onChange={e => { setPath(e.target.value); load(e.target.value); }}
|
|
592
|
+
style={{
|
|
593
|
+
background: T.surfaceAlt, color: T.text, border: `1px solid ${T.border}`,
|
|
594
|
+
borderRadius: 6, fontSize: 12, padding: '4px 8px', maxWidth: 340,
|
|
595
|
+
}}>
|
|
596
|
+
<option value="">— pick a project —</option>
|
|
597
|
+
{(projects || []).map(p => (
|
|
598
|
+
<option key={p.path} value={p.path}>{p.name || p.path}</option>
|
|
599
|
+
))}
|
|
600
|
+
</select>
|
|
601
|
+
<span style={{ fontSize: 10.5, color: T.textDim }}>
|
|
602
|
+
off by default, per project
|
|
603
|
+
</span>
|
|
604
|
+
</div>
|
|
605
|
+
|
|
606
|
+
{err && <div style={{ marginTop: 8, fontSize: 11.5, color: T.error }}>{err}</div>}
|
|
607
|
+
|
|
608
|
+
{data && draft && (
|
|
609
|
+
<div style={{ marginTop: 10, display: 'flex', flexDirection: 'column', gap: 10 }}>
|
|
610
|
+
<label style={{ display: 'flex', alignItems: 'center', gap: 8, cursor: 'pointer', fontSize: 12 }}>
|
|
611
|
+
<input type="checkbox" checked={draft.enabled}
|
|
612
|
+
onChange={e => setDraft({ ...draft, enabled: e.target.checked })} />
|
|
613
|
+
<span style={{ color: T.text, fontWeight: 600 }}>
|
|
614
|
+
Allow override requests for this project
|
|
615
|
+
</span>
|
|
616
|
+
</label>
|
|
617
|
+
|
|
618
|
+
<div>
|
|
619
|
+
<div style={{
|
|
620
|
+
fontSize: 10.5, fontWeight: 700, letterSpacing: 1,
|
|
621
|
+
textTransform: 'uppercase', color: T.textDim, marginBottom: 4,
|
|
622
|
+
}}>Escalatable layers</div>
|
|
623
|
+
{(data.layers || []).map(k => (
|
|
624
|
+
<label key={k} style={{
|
|
625
|
+
display: 'flex', alignItems: 'center', gap: 8, cursor: 'pointer',
|
|
626
|
+
fontSize: 11.5, color: T.textMuted, padding: '2px 0',
|
|
627
|
+
}}>
|
|
628
|
+
<input type="checkbox" checked={!!draft.layers[k]}
|
|
629
|
+
onChange={e => setDraft({
|
|
630
|
+
...draft, layers: { ...draft.layers, [k]: e.target.checked },
|
|
631
|
+
})} />
|
|
632
|
+
<span>{accLayerName(k)}</span>
|
|
633
|
+
{typed.has(k) && (
|
|
634
|
+
<span style={{ fontSize: 10, color: T.textDim }}>
|
|
635
|
+
— approving one makes you retype the rule
|
|
636
|
+
</span>
|
|
637
|
+
)}
|
|
638
|
+
</label>
|
|
639
|
+
))}
|
|
640
|
+
</div>
|
|
641
|
+
|
|
642
|
+
<div style={{ fontSize: 10.5, color: T.textDim, lineHeight: 1.5 }}>
|
|
643
|
+
{data.coverage_note}
|
|
644
|
+
<br />
|
|
645
|
+
Never escalatable at any setting: the credential vault,
|
|
646
|
+
{' '}<span className="mono">.c3/secrets.enc</span>,
|
|
647
|
+
{' '}<span className="mono">.c3/cred_state.json</span>, the dispatcher
|
|
648
|
+
fail-closed deny, and the catastrophic shell blocks.
|
|
649
|
+
</div>
|
|
650
|
+
|
|
651
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
|
|
652
|
+
<button onClick={save} disabled={busy || !dirty} style={{
|
|
653
|
+
borderRadius: 6, fontSize: 12, padding: '5px 12px', cursor: dirty ? 'pointer' : 'default',
|
|
654
|
+
border: `1px solid ${dirty ? T.accent : T.border}`,
|
|
655
|
+
background: dirty ? T.accentDim : 'transparent',
|
|
656
|
+
color: dirty ? T.accent : T.textDim, fontWeight: dirty ? 700 : 400,
|
|
657
|
+
}}>{busy ? 'Saving…' : 'Save'}</button>
|
|
658
|
+
{msg && <span style={{ fontSize: 11.5, color: T.textMuted }}>{msg}</span>}
|
|
659
|
+
</div>
|
|
660
|
+
</div>
|
|
661
|
+
)}
|
|
662
|
+
</div>
|
|
663
|
+
);
|
|
664
|
+
}
|
|
665
|
+
|
|
485
666
|
function HubAccess({ projects }) {
|
|
486
667
|
const [rows, setRows] = useState([]);
|
|
487
668
|
const [loaded, setLoaded] = useState(false);
|
|
@@ -559,6 +740,8 @@ function HubAccess({ projects }) {
|
|
|
559
740
|
|
|
560
741
|
<AccCostStrip onOpenRule={openRule} />
|
|
561
742
|
|
|
743
|
+
<AccPolicyPanel projects={projects} />
|
|
744
|
+
|
|
562
745
|
{!loaded ? (
|
|
563
746
|
<div style={{ fontSize: 12, color: T.textDim }}>Loading…</div>
|
|
564
747
|
) : rows.length === 0 ? (
|
{code_context_control-2.129.1 → code_context_control-2.129.2}/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.129.
|
|
3
|
+
Version: 2.129.2
|
|
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
|
|
@@ -389,6 +389,7 @@ tests/test_hub_hook_migration.py
|
|
|
389
389
|
tests/test_hub_inspect_api.py
|
|
390
390
|
tests/test_hub_locks_routes.py
|
|
391
391
|
tests/test_hub_oracle_service_routes.py
|
|
392
|
+
tests/test_hub_override_policy_routes.py
|
|
392
393
|
tests/test_hub_override_routes.py
|
|
393
394
|
tests/test_hub_server_smoke.py
|
|
394
395
|
tests/test_hub_subproject_links.py
|
|
@@ -2332,7 +2332,7 @@ def mobile_overrides_policy_set():
|
|
|
2332
2332
|
section = data.get("override")
|
|
2333
2333
|
if not isinstance(section, dict):
|
|
2334
2334
|
return jsonify({"error": "body needs an 'override' object"}), 400
|
|
2335
|
-
if _WAKE_KEY in section:
|
|
2335
|
+
if _WAKE_KEY in section: # noqa: SIM102 — kept for the phone-specific copy
|
|
2336
2336
|
# `wake` is an argv this machine will execute. Everything else on this
|
|
2337
2337
|
# route widens what a tap can approve; this one would decide what runs
|
|
2338
2338
|
# when it does. A bearer token from a phone is authentication, not
|
|
@@ -2387,7 +2387,23 @@ def mobile_overrides_policy_set():
|
|
|
2387
2387
|
|
|
2388
2388
|
|
|
2389
2389
|
def _override_widenings(current, section: dict) -> list:
|
|
2390
|
-
"""Which requested changes LOOSEN the policy. Names, for the challenge.
|
|
2390
|
+
"""Which requested changes LOOSEN the policy. Names, for the challenge.
|
|
2391
|
+
|
|
2392
|
+
DELEGATES to ``services.override_policy.widenings`` since 2.129.2, when the
|
|
2393
|
+
hub gained its own Security screen. Two copies of "what counts as widening"
|
|
2394
|
+
is two chances for one surface to quietly allow something the other
|
|
2395
|
+
refuses — and this is the check that decides whether a tap needs a typed
|
|
2396
|
+
confirmation. The name is kept because the mobile route tests call it.
|
|
2397
|
+
"""
|
|
2398
|
+
from services import override_policy as _opol # noqa: PLC0415
|
|
2399
|
+
|
|
2400
|
+
return _opol.widenings(current, section)
|
|
2401
|
+
|
|
2402
|
+
|
|
2403
|
+
def _override_widenings_legacy(current, section: dict) -> list:
|
|
2404
|
+
"""Retired inline copy, kept only as the reference the extraction came
|
|
2405
|
+
from; ``tests/test_override_policy_shared.py`` asserts it agrees with the
|
|
2406
|
+
service so the move can be shown to have preserved behaviour."""
|
|
2391
2407
|
out = []
|
|
2392
2408
|
if section.get("enabled") and not current.enabled:
|
|
2393
2409
|
out.append("enabled")
|
|
@@ -2416,10 +2432,18 @@ def _override_widenings(current, section: dict) -> list:
|
|
|
2416
2432
|
def _write_override_section(project: Path, section: dict) -> dict:
|
|
2417
2433
|
"""Merge *section* into the project's `.c3/config.json` `override` block.
|
|
2418
2434
|
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2435
|
+
DELEGATES to ``services.override_policy.write_section`` since 2.129.2 so
|
|
2436
|
+
the hub's Security screen and the phone write the file the same way — same
|
|
2437
|
+
merge semantics for `layers`, same atomic publish. The name is kept because
|
|
2438
|
+
the mobile route tests patch it.
|
|
2422
2439
|
"""
|
|
2440
|
+
from services import override_policy as _opol # noqa: PLC0415
|
|
2441
|
+
|
|
2442
|
+
return _opol.write_section(project, section)
|
|
2443
|
+
|
|
2444
|
+
|
|
2445
|
+
def _write_override_section_legacy(project: Path, section: dict) -> dict:
|
|
2446
|
+
"""Retired inline copy; see ``_override_widenings_legacy``."""
|
|
2423
2447
|
cfg_file = Path(project) / ".c3" / "config.json"
|
|
2424
2448
|
cfg_file.parent.mkdir(parents=True, exist_ok=True)
|
|
2425
2449
|
cfg = {}
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "code-context-control"
|
|
7
|
-
version = "2.129.
|
|
7
|
+
version = "2.129.2"
|
|
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"
|
|
@@ -530,6 +530,153 @@ def resolve_for_path(path) -> OverridePolicy:
|
|
|
530
530
|
return resolve(str(root)) if root else DISABLED
|
|
531
531
|
|
|
532
532
|
|
|
533
|
+
class PolicyEditError(ValueError):
|
|
534
|
+
"""A rejected policy edit. `widens` is set when the reason is a widening.
|
|
535
|
+
|
|
536
|
+
Carries the same fields the mobile route already returned so a caller can
|
|
537
|
+
render them without re-deriving anything: `payload` is the JSON body, and
|
|
538
|
+
`status` the HTTP code the route should use.
|
|
539
|
+
"""
|
|
540
|
+
|
|
541
|
+
def __init__(self, message: str, *, status: int = 400,
|
|
542
|
+
payload: dict | None = None, widens: list | None = None):
|
|
543
|
+
super().__init__(message)
|
|
544
|
+
self.status = status
|
|
545
|
+
self.payload = dict(payload or {"error": message})
|
|
546
|
+
self.widens = list(widens or [])
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
def widenings(current: "OverridePolicy", section: dict) -> list:
|
|
550
|
+
"""Which requested changes LOOSEN the policy. Names, for the challenge.
|
|
551
|
+
|
|
552
|
+
Extracted from ``oracle.services.mobile_api`` in 2.129.2 so the hub's own
|
|
553
|
+
Security screen and the phone answer to ONE implementation. Two copies of
|
|
554
|
+
"what counts as widening" is two chances for a surface to quietly allow
|
|
555
|
+
something the other refuses, and this is the check that decides whether a
|
|
556
|
+
tap needs a typed confirmation.
|
|
557
|
+
"""
|
|
558
|
+
out: list = []
|
|
559
|
+
if section.get("enabled") and not current.enabled:
|
|
560
|
+
out.append("enabled")
|
|
561
|
+
for key, want in (section.get("layers") or {}).items():
|
|
562
|
+
if want and not current.layers.get(key, False):
|
|
563
|
+
out.append(f"layers.{key}")
|
|
564
|
+
for key in ("max_ttl_s", "default_uses", "request_ttl_s",
|
|
565
|
+
"max_pending_per_session", "max_requests_per_hour",
|
|
566
|
+
# A longer TTL or a longer idle window both mean a rule grant
|
|
567
|
+
# outlives more of the conversation, which is a loosening even
|
|
568
|
+
# though nothing about it looks like a permission.
|
|
569
|
+
"rule_grant_ttl_s", "rule_grant_idle_s"):
|
|
570
|
+
if key in section:
|
|
571
|
+
try:
|
|
572
|
+
if int(section[key]) > int(getattr(current, key)):
|
|
573
|
+
out.append(key)
|
|
574
|
+
except (TypeError, ValueError):
|
|
575
|
+
pass
|
|
576
|
+
if section.get("allow_session_grants") and not current.allow_session_grants:
|
|
577
|
+
out.append("allow_session_grants")
|
|
578
|
+
if section.get("allow_rule_grants") and not current.allow_rule_grants:
|
|
579
|
+
out.append("allow_rule_grants")
|
|
580
|
+
return out
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
def write_section(project, section: dict) -> dict:
|
|
584
|
+
"""Merge *section* into the project's `.c3/config.json` `override` block.
|
|
585
|
+
|
|
586
|
+
Project scope only. A global override policy governs every project on the
|
|
587
|
+
machine, and no remote surface has an affordance for reviewing that blast
|
|
588
|
+
radius.
|
|
589
|
+
"""
|
|
590
|
+
from services.atomic_json import write_json_atomic # noqa: PLC0415
|
|
591
|
+
|
|
592
|
+
cfg_file = Path(project) / ".c3" / "config.json"
|
|
593
|
+
cfg_file.parent.mkdir(parents=True, exist_ok=True)
|
|
594
|
+
cfg = {}
|
|
595
|
+
if cfg_file.is_file():
|
|
596
|
+
try:
|
|
597
|
+
cfg = json.loads(cfg_file.read_text(encoding="utf-8")) or {}
|
|
598
|
+
except ValueError as exc:
|
|
599
|
+
raise ValueError(f"project config is not valid JSON: {exc}") from exc
|
|
600
|
+
if not isinstance(cfg, dict):
|
|
601
|
+
raise ValueError("project config is not a JSON object")
|
|
602
|
+
block = dict(cfg.get("override") or {})
|
|
603
|
+
for key, value in section.items():
|
|
604
|
+
if key == "layers":
|
|
605
|
+
merged = dict(block.get("layers") or {})
|
|
606
|
+
merged.update({k: bool(v) for k, v in (value or {}).items()})
|
|
607
|
+
block["layers"] = merged
|
|
608
|
+
else:
|
|
609
|
+
block[key] = value
|
|
610
|
+
cfg["override"] = block
|
|
611
|
+
# Shared with the CLI and the hub, and served from a threaded API, so the
|
|
612
|
+
# publish goes through the one race-safe writer rather than a temp name
|
|
613
|
+
# every writer of this file would pick.
|
|
614
|
+
write_json_atomic(cfg_file, cfg, ensure_ascii=False, trailing_newline=False)
|
|
615
|
+
return block
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
#: The one `override` key no REMOTE surface may write: it is an argv this
|
|
619
|
+
#: machine will execute. The hub is a desktop surface on localhost, so it is
|
|
620
|
+
#: allowed to; the phone is not. Callers pass ``allow_wake``.
|
|
621
|
+
WAKE_KEY = "wake"
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
def apply_section(project_path, section: dict, *, confirmed: bool = False,
|
|
625
|
+
allow_wake: bool = False) -> tuple[dict, list]:
|
|
626
|
+
"""Validate, widening-check and write one `override` edit.
|
|
627
|
+
|
|
628
|
+
Returns ``(written_block, widens)``. Raises :class:`PolicyEditError` with
|
|
629
|
+
the status and body the caller should surface.
|
|
630
|
+
|
|
631
|
+
Widening — enabling the feature, turning a layer on, raising a ceiling, or
|
|
632
|
+
allowing session grants — needs ``confirmed=True``. Tightening never does:
|
|
633
|
+
making the guard stricter is always allowed to be one tap.
|
|
634
|
+
"""
|
|
635
|
+
if not isinstance(section, dict):
|
|
636
|
+
raise PolicyEditError("body needs an 'override' object")
|
|
637
|
+
|
|
638
|
+
if WAKE_KEY in section and not allow_wake:
|
|
639
|
+
raise PolicyEditError(
|
|
640
|
+
"'wake' cannot be set from this surface — it names a command this "
|
|
641
|
+
"machine runs. Edit .c3/config.json on the desktop.",
|
|
642
|
+
status=403, payload={"error": (
|
|
643
|
+
"'wake' cannot be set from this surface — it names a command "
|
|
644
|
+
"this machine runs. Edit .c3/config.json on the desktop."),
|
|
645
|
+
"key": WAKE_KEY})
|
|
646
|
+
|
|
647
|
+
unknown = sorted(set(section) - set(DEFAULTS))
|
|
648
|
+
if unknown:
|
|
649
|
+
# Unknown keys are a hard error, never a silent no-op.
|
|
650
|
+
raise PolicyEditError(
|
|
651
|
+
f"unknown override key(s): {', '.join(unknown)}",
|
|
652
|
+
payload={"error": f"unknown override key(s): {', '.join(unknown)}",
|
|
653
|
+
"valid": sorted(DEFAULTS)})
|
|
654
|
+
|
|
655
|
+
layers = section.get("layers")
|
|
656
|
+
if layers is not None:
|
|
657
|
+
if not isinstance(layers, dict):
|
|
658
|
+
raise PolicyEditError("'layers' must be an object")
|
|
659
|
+
bad = sorted(set(layers) - set(LAYER_KEYS))
|
|
660
|
+
if bad:
|
|
661
|
+
raise PolicyEditError(
|
|
662
|
+
f"unknown layer(s): {', '.join(bad)}",
|
|
663
|
+
payload={"error": f"unknown layer(s): {', '.join(bad)}",
|
|
664
|
+
"valid": list(LAYER_KEYS)})
|
|
665
|
+
|
|
666
|
+
current = resolve(str(project_path))
|
|
667
|
+
widens = widenings(current, section)
|
|
668
|
+
if widens and not confirmed:
|
|
669
|
+
raise PolicyEditError(
|
|
670
|
+
"this widens what an approval can allow: " + ", ".join(widens),
|
|
671
|
+
payload={"error": ("this widens what an approval can allow: "
|
|
672
|
+
+ ", ".join(widens)),
|
|
673
|
+
"widens": widens,
|
|
674
|
+
"needs_confirmation": True, "confirm_with": "widen"},
|
|
675
|
+
widens=widens)
|
|
676
|
+
|
|
677
|
+
return write_section(project_path, section), widens
|
|
678
|
+
|
|
679
|
+
|
|
533
680
|
def offer_line(layer_key: str, path, tool: str, op: str) -> str:
|
|
534
681
|
"""The single line appended to a refusal when a layer IS escalatable.
|
|
535
682
|
|