code-context-control 2.81.0__tar.gz → 2.85.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.81.0/code_context_control.egg-info → code_context_control-2.85.0}/PKG-INFO +1 -1
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/c3.py +18 -3
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/commands/parser.py +27 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_server.py +3 -6
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/hub_ci.js +25 -7
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/mcp_server.py +20 -3
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/ci.py +148 -12
- {code_context_control-2.81.0 → code_context_control-2.85.0/code_context_control.egg-info}/PKG-INFO +1 -1
- {code_context_control-2.81.0 → code_context_control-2.85.0}/code_context_control.egg-info/SOURCES.txt +7 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/pyproject.toml +1 -1
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/ci_act.py +36 -0
- code_context_control-2.85.0/services/ci_cache.py +345 -0
- code_context_control-2.85.0/services/ci_github.py +161 -0
- code_context_control-2.85.0/services/ci_impact.py +269 -0
- code_context_control-2.85.0/services/ci_intel.py +188 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/ci_runner.py +138 -5
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/ci_workflow.py +57 -9
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_ci_act.py +68 -0
- code_context_control-2.85.0/tests/test_ci_cache.py +205 -0
- code_context_control-2.85.0/tests/test_ci_impact.py +274 -0
- code_context_control-2.85.0/tests/test_ci_intel.py +179 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_ci_runner.py +1 -1
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_ci_workflow.py +5 -1
- {code_context_control-2.81.0 → code_context_control-2.85.0}/LICENSE +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/README.md +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/__init__.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/_hook_utils.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/commands/__init__.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/commands/common.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/docs.html +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/edits.html +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/guide/access.html +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/guide/bitbucket.html +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/guide/credentials.html +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/guide/getting-started.html +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/guide/index.html +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/guide/masking.html +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/guide/oracle.html +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/guide/shared.css +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/guide/tools.html +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/guide/workflow.html +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hook_access_guard.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hook_artifact.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hook_auto_snapshot.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hook_c3_signal.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hook_c3read.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hook_dispatch.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hook_edit_ledger.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hook_edit_unlock.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hook_filter.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hook_ghost_files.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hook_pretool_enforce.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hook_prompt_recall.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hook_read.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hook_session_stats.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hook_terse_advisor.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/app.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/add_project.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/config_editor.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/drill_health.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/drill_panel.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/drill_tasks.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/drill_views.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/global_search.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/hub_credentials.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/hub_locks.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/mcp_manager.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/modals.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/project_card.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/project_tree.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/session_drawer.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/settings_modal.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/sidebar.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/summary_bar.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/task_board.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/toasts.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/components/topbar.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui/state.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/hub_ui.html +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/mcp_proxy.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/progress.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/server.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/__init__.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/_grants.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/_helpers.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/agent.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/artifacts.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/bitbucket.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/compress.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/credentials.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/delegate.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/edit.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/edit_verify.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/edits.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/federate.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/filter.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/impact.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/jira.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/locks.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/memory.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/override.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/project.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/read.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/search.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/session.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/shell.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/status.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/tasks.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/tools/validate.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/api.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/app.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/components/access.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/components/bitbucket.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/components/chat.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/components/credentials.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/components/dashboard.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/components/edits.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/components/enforcement.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/components/instructions.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/components/jira.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/components/memory.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/components/sessions.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/components/settings.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/components/sidebar.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/components/tasks.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/icons.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/pm_shared.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/shared.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui/theme.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui.html +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui_legacy.html +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/cli/ui_nano.html +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/code_context_control.egg-info/dependency_links.txt +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/code_context_control.egg-info/entry_points.txt +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/code_context_control.egg-info/requires.txt +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/code_context_control.egg-info/top_level.txt +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/core/__init__.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/core/config.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/core/ide.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/core/mcp_toml.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/core/web_security.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/__init__.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/config.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/mcp_oracle.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/oracle_server.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/oracle_ui.html +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/__init__.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/activity_reporter.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/api_auth.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/c3_bridge.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/chat_engine.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/chat_poll.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/chat_store.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/cross_memory.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/discovery_audit.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/federated_graph.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/health_checker.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/insight_engine.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/local_session.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/memory_reader.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/memory_writer.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/mobile_api.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/project_scanner.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/review_agent.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/tool_executor.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/services/tool_registry.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/activity.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/agents.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/app.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/busy.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/chat/conversations.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/chat/input.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/chat/markdown.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/chat/send.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/chat/stream_renderer.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/chat/toolbar.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/core.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/crossgraph.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/header.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/insights.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/projects.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/qrcode.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/settings.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/suggestions.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/oracle/ui/theme_tabs.js +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/__init__.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/access_guard.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/access_telemetry.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/activity_log.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/agent_base.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/agent_locks.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/agents.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/artifact_defs.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/artifact_store.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/auto_memory.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/bench/__init__.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/bench/external/__init__.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/bench/external/aider_polyglot.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/bench/external/swe_bench.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/benchmark_dashboard.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/bitbucket_client.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/bitbucket_credentials.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/ci_expr.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/ci_failures.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/circuit_breaker.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/claude_md.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/compressor.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/context_snapshot.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/conversation_store.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/credential_store.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/doc_index.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/e2e_benchmark.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/e2e_evaluator.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/e2e_tasks.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/edit_ledger.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/embedding_index.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/enforcement_policy.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/error_reporting.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/file_memory.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/git_context.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/hub_service.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/indexer.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/jira_client.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/jira_cloud.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/jira_credentials.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/jira_data_center.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/jira_links.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/mask_activation.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/mask_mirror.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/mask_presets.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/memory.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/memory_consolidator.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/memory_distiller.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/memory_graph.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/memory_grounder.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/memory_queue.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/memory_scorer.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/metrics.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/notifications.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/ollama_bridge.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/ollama_client.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/ollama_credentials.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/output_filter.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/override_grants.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/override_policy.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/override_requests.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/override_wake.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/parser.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/project_manager.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/project_runtime.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/protocol.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/proxy_state.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/repo_map.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/retention.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/retrieval_broker.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/router.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/runtime.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/scanner.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/session_benchmark.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/session_manager.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/session_preloader.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/subprojects.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/task_store.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/telemetry.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/text_index.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/time_tracker.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/tool_classifier.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/transcript_index.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/validation_cache.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/vector_store.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/watcher.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/services/win_subprocess.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/setup.cfg +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_access_builtin_optout.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_access_guard.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_access_guard_meta.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_access_guard_shell_project.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_access_guard_surfaces.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_access_guard_wiring.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_activity_reporter.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_agent_locks.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_aider_polyglot.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_antigravity_transition.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_artifact_store.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_artifact_tool.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_bitbucket_cli_smoke.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_bitbucket_client.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_bitbucket_config_fallback.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_bitbucket_credentials.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_bitbucket_tool.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_c3_shell.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_chat_poll.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_ci_expr.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_circuit_breaker.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_claude_md_merge.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_cli_smoke.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_compressor_large_file.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_credential_store.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_credentials_routes.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_credentials_tool.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_creds_cli_smoke.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_delegate_cascade.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_delegate_version_probe.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_e2e_benchmark.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_edit_ledger_deadline.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_edit_ledger_hook.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_edit_locking.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_edit_normalization.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_edit_verify.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_embedding_index_deadlock.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_enforcement_flip.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_enforcement_policy.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_enforcement_routes.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_federated_graph.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_filter_backoff.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_ghost_files.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_ghost_generation.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_git_branch_awareness.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_hook_access_guard.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_hook_codex_compat.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_hook_dispatch.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_hook_pretool_enforce.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_hook_prompt_recall.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_hook_smoke.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_hook_state.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_hook_utf8_stdio.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_hub_credentials_route.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_hub_credentials_routes_write.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_hub_enforcement_routes.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_hub_inspect_api.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_hub_locks_routes.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_hub_server_smoke.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_hub_subproject_links.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_ide_workflow_adaptation.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_init_scan.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_install_mcp_entrypoint.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_jira_cli_smoke.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_jira_client.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_jira_config_fallback.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_jira_credentials.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_jira_links.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_jira_routes.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_jira_tool.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_lazy_store_init.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_mask_guard.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_mask_routes.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_mask_surfaces.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_mcp_host_guard.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_mcp_memory_timeout.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_mcp_server_smoke.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_mcp_toml.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_memory_distiller.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_memory_graph_api.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_memory_queue.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_memory_system.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_mobile_api.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_mobile_extras.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_mobile_override_routes.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_mobile_security_api.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_no_stale_model_pins.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_notification_dedup.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_notification_discipline.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_ollama_credentials.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_oracle_api_auth.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_oracle_apikey_api.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_oracle_c3_bridge.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_oracle_chat_engine.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_oracle_chat_store.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_oracle_discovery_api.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_oracle_discovery_audit.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_oracle_local_auth.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_oracle_ollama_bridge.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_oracle_scanner_cache.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_oracle_security_fixes.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_oracle_session_bootstrap.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_oracle_subproject_awareness.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_oracle_ui_bundle.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_output_filter.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_override_grants.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_override_grants_mcp.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_override_requests.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_override_wake.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_permissions.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_pm_api.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_project_manager.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_project_manager_merge.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_project_tool.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_read_coercion.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_read_edit_parity.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_related_facts.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_repo_map.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_response_boilerplate.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_retention.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_review_digest.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_service_durability.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_session_benchmark.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_session_budget.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_shell_creds.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_shell_robustness.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_subproject_exclusion.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_subproject_federation.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_subprojects.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_swe_bench.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_task_store.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_task_tool.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_time_tracker.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_token_telemetry.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_tool_registry.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_upgrade_and_version.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_validate.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_vault_write_guard.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_version_sync.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_web_security.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tests/test_windows_reliability.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/__init__.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/backend.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/main.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/screens/__init__.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/screens/benchmark_view.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/screens/claudemd_view.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/screens/compress_view.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/screens/index_view.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/screens/init_view.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/screens/mcp_view.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/screens/optimize_view.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/screens/pipe_view.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/screens/projects_view.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/screens/search_view.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/screens/session_view.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/screens/stats.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/screens/ui_view.py +0 -0
- {code_context_control-2.81.0 → code_context_control-2.85.0}/tui/theme.tcss +0 -0
{code_context_control-2.81.0/code_context_control.egg-info → code_context_control-2.85.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-context-control
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.85.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
|
|
@@ -92,7 +92,7 @@ console = Console() if HAS_RICH else None
|
|
|
92
92
|
# Config
|
|
93
93
|
CONFIG_DIR = ".c3"
|
|
94
94
|
CONFIG_FILE = ".c3/config.json"
|
|
95
|
-
__version__ = "2.
|
|
95
|
+
__version__ = "2.85.0"
|
|
96
96
|
|
|
97
97
|
|
|
98
98
|
def _compress_file_cli(compressor, path, mode="smart", **kw):
|
|
@@ -6055,6 +6055,15 @@ def _ci_main(args) -> int:
|
|
|
6055
6055
|
from cli.tools.ci import handle_ci
|
|
6056
6056
|
|
|
6057
6057
|
sub = getattr(args, "ci_cmd", None) or "inspect"
|
|
6058
|
+
if sub == "publish":
|
|
6059
|
+
if getattr(args, "dry_run", False):
|
|
6060
|
+
args.job = "dry-run"
|
|
6061
|
+
if getattr(args, "force", False):
|
|
6062
|
+
args.allow_side_effects = True
|
|
6063
|
+
if sub == "cache" and getattr(args, "clear", False):
|
|
6064
|
+
# `--clear` is a flag on the CLI; the shared handler takes it
|
|
6065
|
+
# positionally so both surfaces route through one code path.
|
|
6066
|
+
args.job = "clear"
|
|
6058
6067
|
project_path = getattr(args, "project_path", ".") or "."
|
|
6059
6068
|
as_json = bool(getattr(args, "json", False))
|
|
6060
6069
|
|
|
@@ -6065,7 +6074,9 @@ def _ci_main(args) -> int:
|
|
|
6065
6074
|
from services import ci_runner as cr
|
|
6066
6075
|
from services.ci_workflow import inspect_project
|
|
6067
6076
|
if sub == "inspect":
|
|
6068
|
-
payload = inspect_project(
|
|
6077
|
+
payload = inspect_project(
|
|
6078
|
+
project_path, event=getattr(args, "event", "") or "",
|
|
6079
|
+
engine=getattr(args, "engine", "auto") or "auto")
|
|
6069
6080
|
elif sub in ("run", "rerun"):
|
|
6070
6081
|
only = None
|
|
6071
6082
|
if sub == "rerun":
|
|
@@ -6104,7 +6115,11 @@ def _ci_main(args) -> int:
|
|
|
6104
6115
|
getattr(args, "event", "") or "",
|
|
6105
6116
|
getattr(args, "engine", "auto") or "auto",
|
|
6106
6117
|
bool(getattr(args, "allow_side_effects", False)),
|
|
6107
|
-
getattr(args, "network", "") or ""
|
|
6118
|
+
getattr(args, "network", "") or "",
|
|
6119
|
+
"required" if getattr(args, "required", False) else "full",
|
|
6120
|
+
getattr(args, "base", "") or "",
|
|
6121
|
+
bool(getattr(args, "allow_host_mutation", False)),
|
|
6122
|
+
bool(getattr(args, "no_cache", False)))
|
|
6108
6123
|
print(out)
|
|
6109
6124
|
# Exit code is the finding: a non-full verdict must not read as success to
|
|
6110
6125
|
# a shell script or a pre-push hook.
|
|
@@ -507,6 +507,17 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
507
507
|
ci_run.add_argument("--allow-side-effects", action="store_true",
|
|
508
508
|
help="Let the act engine run jobs that look like they "
|
|
509
509
|
"publish or deploy. Refused by default.")
|
|
510
|
+
ci_run.add_argument("--required", action="store_true",
|
|
511
|
+
help="Run only the jobs a change could have broken "
|
|
512
|
+
"(conservative; see `c3 ci plan`)")
|
|
513
|
+
ci_run.add_argument("--base", default="",
|
|
514
|
+
help="Diff against this ref instead of the working tree")
|
|
515
|
+
ci_run.add_argument("--allow-host-mutation", action="store_true",
|
|
516
|
+
help="Permit native steps that reconfigure this machine "
|
|
517
|
+
"(pip/npm -g/apt install). Refused by default.")
|
|
518
|
+
ci_run.add_argument("--no-cache", action="store_true",
|
|
519
|
+
help="Ignore cached results and execute every "
|
|
520
|
+
"selected job")
|
|
510
521
|
ci_run.add_argument("--network", default="",
|
|
511
522
|
help="Container network for the act engine (e.g. `none` "
|
|
512
523
|
"to cut egress). Default: act's own.")
|
|
@@ -530,6 +541,22 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
530
541
|
ci_logs.add_argument("--tail", type=int, default=200)
|
|
531
542
|
|
|
532
543
|
_ci_common(ci_subs.add_parser("runs", help="Recent local CI runs"))
|
|
544
|
+
ci_plan = _ci_common(ci_subs.add_parser(
|
|
545
|
+
"plan", help="Show which jobs a change requires, and why"))
|
|
546
|
+
ci_plan.add_argument("--base", default="",
|
|
547
|
+
help="Diff against this ref instead of the working tree")
|
|
548
|
+
ci_pub = _ci_common(ci_subs.add_parser(
|
|
549
|
+
"publish", help="Post the last run as a GitHub commit status"))
|
|
550
|
+
ci_pub.add_argument("--run", dest="run_id", default="")
|
|
551
|
+
ci_pub.add_argument("--dry-run", action="store_true")
|
|
552
|
+
ci_pub.add_argument("--force", action="store_true",
|
|
553
|
+
help="Publish a PARTIAL result as `pending`")
|
|
554
|
+
_ci_common(ci_subs.add_parser(
|
|
555
|
+
"history", help="Per-job pass/fail history and flake detection"))
|
|
556
|
+
ci_cache_p = _ci_common(ci_subs.add_parser(
|
|
557
|
+
"cache", help="Cached-result store: size, or --clear it"))
|
|
558
|
+
ci_cache_p.add_argument("--clear", action="store_true",
|
|
559
|
+
help="Drop every cached result and dependency cache")
|
|
533
560
|
_ci_common(ci_subs.add_parser(
|
|
534
561
|
"doctor", help="Which execution engines are available on this machine"))
|
|
535
562
|
|
|
@@ -1321,12 +1321,9 @@ def api_ci_inspect():
|
|
|
1321
1321
|
except ValueError as e:
|
|
1322
1322
|
return jsonify({"error": str(e)}), 404
|
|
1323
1323
|
try:
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
# "install act" is a different answer from "macOS is impossible".
|
|
1328
|
-
data["engines"] = ci_act.availability()
|
|
1329
|
-
return jsonify(data)
|
|
1324
|
+
# inspect_project owns the engine partition, so the Hub, the CLI
|
|
1325
|
+
# and the tool text can never disagree about what is runnable.
|
|
1326
|
+
return jsonify(inspect_project(resolved))
|
|
1330
1327
|
except Exception as e:
|
|
1331
1328
|
return jsonify({"error": f"{type(e).__name__}: {e}"}), 500
|
|
1332
1329
|
|
|
@@ -18,6 +18,11 @@ const CI_STATUS_STYLE = {
|
|
|
18
18
|
unsupported: ['UNSUP', 'warn'],
|
|
19
19
|
foreign: ['OTHER-OS', 'blue'],
|
|
20
20
|
deselected: ['—', 'textDim'],
|
|
21
|
+
// capability labels, used by the job graph only
|
|
22
|
+
cap_native: ['NATIVE', 'accent'],
|
|
23
|
+
cap_container: ['CONTAINER', 'accent'],
|
|
24
|
+
cap_unreachable: ['OTHER-OS', 'blue'],
|
|
25
|
+
cap_unsupported: ['UNSUP', 'warn'],
|
|
21
26
|
};
|
|
22
27
|
|
|
23
28
|
function CiStatusPill({ status, title }) {
|
|
@@ -143,6 +148,9 @@ function HubCI({ projects, onOpenDrill }) {
|
|
|
143
148
|
|
|
144
149
|
const jobs = (inspect && inspect.jobs) || [];
|
|
145
150
|
const engines = inspect && inspect.engines;
|
|
151
|
+
const runnableNative = new Set((inspect && inspect.runnable_native) || []);
|
|
152
|
+
const runnableContainer = new Set((inspect && inspect.runnable_container) || []);
|
|
153
|
+
const unsupportedKeys = new Set(((inspect && inspect.unsupported) || []).map(u => u.key));
|
|
146
154
|
const runJobs = ((run && run.jobs) || []).filter(j => j.status !== 'deselected');
|
|
147
155
|
|
|
148
156
|
return (
|
|
@@ -152,7 +160,8 @@ function HubCI({ projects, onOpenDrill }) {
|
|
|
152
160
|
<span style={{ fontSize: 14, color: T.text }}>Local CI</span>
|
|
153
161
|
<span className="mono" style={{ fontSize: 11, color: T.textMuted }}>
|
|
154
162
|
{inspect
|
|
155
|
-
? `${(inspect.runnable || []).length} of ${jobs.length}
|
|
163
|
+
? `${(inspect.runnable || []).length} of ${jobs.length} runnable here`
|
|
164
|
+
+ ` (${runnableNative.size} native, ${runnableContainer.size} container)`
|
|
156
165
|
: 'loading…'}
|
|
157
166
|
</span>
|
|
158
167
|
<div style={{ flex: 1 }} />
|
|
@@ -289,13 +298,22 @@ function HubCI({ projects, onOpenDrill }) {
|
|
|
289
298
|
display: 'flex', alignItems: 'center', gap: 9, padding: '5px 10px',
|
|
290
299
|
borderTop: `1px solid ${T.border}`, fontSize: 11,
|
|
291
300
|
}}>
|
|
301
|
+
{/* Read the server's partition; never re-derive it here. The
|
|
302
|
+
first attempt inferred runnability in JS from act_could_run,
|
|
303
|
+
which means "act has no blockers with this job" and NOT "act
|
|
304
|
+
can run it here" — act only does Linux. Every macOS cell
|
|
305
|
+
rendered as a green PASS it could never earn. */}
|
|
292
306
|
<CiStatusPill
|
|
293
|
-
status={(
|
|
294
|
-
:
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
307
|
+
status={runnableNative.has(j.key) ? 'cap_native'
|
|
308
|
+
: runnableContainer.has(j.key) ? 'cap_container'
|
|
309
|
+
: unsupportedKeys.has(j.key) ? 'cap_unsupported'
|
|
310
|
+
: 'cap_unreachable'}
|
|
311
|
+
title={runnableNative.has(j.key) ? 'runnable natively on this host'
|
|
312
|
+
: runnableContainer.has(j.key)
|
|
313
|
+
? `runs in a container (${j.runs_on}) via act`
|
|
314
|
+
: unsupportedKeys.has(j.key)
|
|
315
|
+
? (j.blockers || []).join('; ')
|
|
316
|
+
: `targets ${j.runs_on} — no available engine can run it here`} />
|
|
299
317
|
<span className="mono" style={{ color: T.textMuted }}>{j.key}</span>
|
|
300
318
|
{!!(j.needs || []).length && (
|
|
301
319
|
<span className="mono" style={{ fontSize: 10, color: T.textDim }}>
|
|
@@ -771,10 +771,25 @@ async def c3_ci(action: str = "inspect", job: str = "", run_id: str = "",
|
|
|
771
771
|
allow_foreign: bool = False, workflow: str = "",
|
|
772
772
|
tail: int = 200, timeout: int = 0, event: str = "",
|
|
773
773
|
engine: str = "auto", allow_side_effects: bool = False,
|
|
774
|
-
network: str = "",
|
|
774
|
+
network: str = "", mode: str = "full", base: str = "",
|
|
775
|
+
allow_host_mutation: bool = False,
|
|
776
|
+
no_cache: bool = False, ctx: Context = None) -> str:
|
|
775
777
|
"""RUN THIS REPO'S REAL CI LOCALLY — before pushing, not after.
|
|
776
778
|
Reads .github/workflows/*.yml as the source of truth (no second CI config).
|
|
777
|
-
actions: inspect | run | rerun | status | failures | logs | runs |
|
|
779
|
+
actions: inspect | plan | run | rerun | status | failures | logs | runs |
|
|
780
|
+
cache | history | publish | doctor. publish posts the last run as a
|
|
781
|
+
GitHub COMMIT STATUS via your gh auth; it refuses a dirty tree, an
|
|
782
|
+
unpushed commit, and (unless forced) a PARTIAL result. history reports per-job fail rates and
|
|
783
|
+
flags FLAKY jobs — ones that both passed and failed on identical
|
|
784
|
+
inputs, so the code cannot be the cause. A job whose inputs are unchanged since it last passed
|
|
785
|
+
is reused (status `cached`, nothing executed); no_cache forces it.
|
|
786
|
+
mode: full (default) | required. required runs only the jobs a change
|
|
787
|
+
could have broken; it is CONSERVATIVE — anything unmapped runs. Use
|
|
788
|
+
action='plan' to see the decision and reason for every job first.
|
|
789
|
+
allow_host_mutation: the NATIVE engine refuses steps that would
|
|
790
|
+
reconfigure this machine (pip/npm -g/apt/brew install...). It has no
|
|
791
|
+
isolation; running this repo's own CI natively once uninstalled C3.
|
|
792
|
+
Prefer engine='act'.
|
|
778
793
|
inspect: workflows, the job DAG, and which jobs are runnable on THIS host.
|
|
779
794
|
run: execute in dependency order; job='lint' or 'test (ubuntu-latest, 3.12)'
|
|
780
795
|
selects one (bare job name = all its matrix cells). A job whose dependency
|
|
@@ -798,7 +813,9 @@ async def c3_ci(action: str = "inspect", job: str = "", run_id: str = "",
|
|
|
798
813
|
return await asyncio.to_thread(handle_ci, action, job, run_id,
|
|
799
814
|
allow_foreign, workflow, tail, timeout,
|
|
800
815
|
svc, finalize, event, engine,
|
|
801
|
-
allow_side_effects, network
|
|
816
|
+
allow_side_effects, network,
|
|
817
|
+
mode, base, allow_host_mutation,
|
|
818
|
+
no_cache)
|
|
802
819
|
|
|
803
820
|
|
|
804
821
|
@mcp.tool()
|
|
@@ -12,13 +12,14 @@ That distinction is the product.
|
|
|
12
12
|
"""
|
|
13
13
|
from __future__ import annotations
|
|
14
14
|
|
|
15
|
+
from services import ci_impact
|
|
15
16
|
from services import ci_runner as cr
|
|
16
17
|
from services.ci_workflow import inspect_project
|
|
17
18
|
|
|
18
19
|
_MARK = {
|
|
19
20
|
cr.PASSED: "PASS", cr.FAILED: "FAIL", cr.SKIPPED: "SKIP",
|
|
20
21
|
cr.UNSUPPORTED: "UNSUP", cr.FOREIGN: "OTHER-OS", cr.TIMEOUT: "TIMEOUT",
|
|
21
|
-
cr.DESELECTED: "-",
|
|
22
|
+
cr.DESELECTED: "-", cr.CACHED: "CACHED",
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
# Verdicts an agent may treat as "safe to push". Deliberately one item long.
|
|
@@ -81,7 +82,10 @@ def _failure_rows(jobs: list, limit: int = 25) -> list:
|
|
|
81
82
|
def handle_ci(action: str, job: str, run_id: str, allow_foreign: bool,
|
|
82
83
|
workflow: str, tail: int, timeout: int, svc, finalize,
|
|
83
84
|
event: str = "", engine: str = "auto",
|
|
84
|
-
allow_side_effects: bool = False, network: str = ""
|
|
85
|
+
allow_side_effects: bool = False, network: str = "",
|
|
86
|
+
mode: str = "full", base: str = "",
|
|
87
|
+
allow_host_mutation: bool = False,
|
|
88
|
+
no_cache: bool = False) -> str:
|
|
85
89
|
"""Route c3_ci actions."""
|
|
86
90
|
project = str(svc.project_path)
|
|
87
91
|
action = (action or "inspect").strip().lower()
|
|
@@ -91,7 +95,7 @@ def handle_ci(action: str, job: str, run_id: str, allow_foreign: bool,
|
|
|
91
95
|
|
|
92
96
|
# ── inspect ──────────────────────────────────────────────────────────
|
|
93
97
|
if action in ("", "inspect", "jobs"):
|
|
94
|
-
data = inspect_project(project, event=event)
|
|
98
|
+
data = inspect_project(project, event=event, engine=engine)
|
|
95
99
|
if not data["workflows"]:
|
|
96
100
|
return finalize(
|
|
97
101
|
"c3_ci", args,
|
|
@@ -105,26 +109,39 @@ def handle_ci(action: str, job: str, run_id: str, allow_foreign: bool,
|
|
|
105
109
|
lines.append(f" {wf['name']} [{', '.join(wf['triggers']) or 'no triggers'}]"
|
|
106
110
|
f" jobs={len(wf['jobs'])}{err}")
|
|
107
111
|
|
|
112
|
+
native = set(data.get("runnable_native") or [])
|
|
113
|
+
container = set(data.get("runnable_container") or [])
|
|
114
|
+
|
|
108
115
|
lines.append("\nJob graph (dependency order):")
|
|
109
116
|
by_key = {j["key"]: j for j in data["jobs"]}
|
|
110
117
|
for key in data["order"]:
|
|
111
118
|
j = by_key[key]
|
|
112
119
|
needs = f" needs={','.join(j['needs'])}" if j["needs"] else ""
|
|
113
|
-
if
|
|
120
|
+
if key in native:
|
|
121
|
+
state = "runnable here"
|
|
122
|
+
elif key in container:
|
|
123
|
+
state = "runnable (container)"
|
|
124
|
+
elif not j["supported"] and not j.get("act_could_run"):
|
|
114
125
|
state = "UNSUPPORTED"
|
|
115
|
-
elif j["foreign_runner"]:
|
|
116
|
-
state = f"other-OS ({j['runs_on']})"
|
|
117
126
|
else:
|
|
118
|
-
state = "
|
|
127
|
+
state = f"other-OS ({j['runs_on']})"
|
|
119
128
|
lines.append(f" {key:<42} {state}{needs}")
|
|
120
129
|
|
|
130
|
+
engines = data.get("engines") or {}
|
|
121
131
|
lines.append(
|
|
122
|
-
f"\nRunnable
|
|
132
|
+
f"\nRunnable here: {len(data['runnable'])} of {len(data['jobs'])}"
|
|
133
|
+
f" ({len(native)} native, {len(container)} container)")
|
|
134
|
+
if engines.get("ok"):
|
|
135
|
+
lines.append(f" engines: native + act ({engines.get('act_version', '')})")
|
|
136
|
+
else:
|
|
137
|
+
lines.append(
|
|
138
|
+
f" engines: native only — {engines.get('reason', 'act unavailable')}")
|
|
123
139
|
if data["foreign"]:
|
|
124
140
|
lines.append(
|
|
125
|
-
f" other-OS ({len(data['foreign'])}): these target a
|
|
126
|
-
"
|
|
127
|
-
"anyway and labels
|
|
141
|
+
f" other-OS ({len(data['foreign'])}): these target a runner no "
|
|
142
|
+
"available engine can reproduce. c3_ci(action='run', "
|
|
143
|
+
"allow_foreign=true) attempts them on this OS anyway and labels "
|
|
144
|
+
"the result cross-OS.")
|
|
128
145
|
if data["unsupported"]:
|
|
129
146
|
lines.append(f" unsupported ({len(data['unsupported'])}):")
|
|
130
147
|
for item in data["unsupported"][:8]:
|
|
@@ -139,6 +156,43 @@ def handle_ci(action: str, job: str, run_id: str, allow_foreign: bool,
|
|
|
139
156
|
return finalize("c3_ci", args, "\n".join(lines),
|
|
140
157
|
f"{len(data['jobs'])} jobs, {len(data['runnable'])} runnable")
|
|
141
158
|
|
|
159
|
+
# ── plan (required mode, no execution) ───────────────────────────────
|
|
160
|
+
if action == "plan":
|
|
161
|
+
from services.ci_workflow import (
|
|
162
|
+
build_dag,
|
|
163
|
+
discover_workflows,
|
|
164
|
+
git_context,
|
|
165
|
+
parse_workflow,
|
|
166
|
+
)
|
|
167
|
+
wfs = [parse_workflow(p) for p in discover_workflows(project)]
|
|
168
|
+
dag = build_dag([w for w in wfs if not w.error],
|
|
169
|
+
event=event, git=git_context(project))
|
|
170
|
+
try:
|
|
171
|
+
ordered = dag.topo_order()
|
|
172
|
+
except Exception:
|
|
173
|
+
ordered = dag.instances
|
|
174
|
+
plan = ci_impact.plan_required(project, ordered, wfs, base=base,
|
|
175
|
+
event=event)
|
|
176
|
+
lines = [
|
|
177
|
+
f"Required-mode plan ({len(plan.selected)} run / "
|
|
178
|
+
f"{len(plan.skipped)} skip) vs {base or 'the working tree'}",
|
|
179
|
+
f"changed files: {len(plan.changed)}",
|
|
180
|
+
]
|
|
181
|
+
for path in plan.changed[:10]:
|
|
182
|
+
lines.append(f" {path}")
|
|
183
|
+
if len(plan.changed) > 10:
|
|
184
|
+
lines.append(f" ... and {len(plan.changed) - 10} more")
|
|
185
|
+
lines.append("")
|
|
186
|
+
for decision in plan.decisions:
|
|
187
|
+
mark = "RUN " if decision.decision == ci_impact.RUN else "skip"
|
|
188
|
+
lines.append(f" {mark} {decision.job}")
|
|
189
|
+
lines.append(f" {decision.reason}")
|
|
190
|
+
if plan.note:
|
|
191
|
+
lines.append(f"\n{plan.note}")
|
|
192
|
+
lines.append("\nRun it: c3_ci(action='run', mode='required')")
|
|
193
|
+
return finalize("c3_ci", args, "\n".join(lines),
|
|
194
|
+
f"{len(plan.selected)} required")
|
|
195
|
+
|
|
142
196
|
# ── run / rerun ──────────────────────────────────────────────────────
|
|
143
197
|
if action in ("run", "rerun"):
|
|
144
198
|
only = None
|
|
@@ -159,7 +213,9 @@ def handle_ci(action: str, job: str, run_id: str, allow_foreign: bool,
|
|
|
159
213
|
only=only, timeout=timeout or cr.DEFAULT_STEP_TIMEOUT,
|
|
160
214
|
workflow=workflow, event=event, engine=engine,
|
|
161
215
|
allow_side_effects=allow_side_effects,
|
|
162
|
-
network=network
|
|
216
|
+
network=network, mode=mode, base=base,
|
|
217
|
+
allow_host_mutation=allow_host_mutation,
|
|
218
|
+
no_cache=no_cache)
|
|
163
219
|
run = result.to_dict()
|
|
164
220
|
lines = [_verdict_line(run), f"run {run['run_id']} host={run['host_os']}"]
|
|
165
221
|
fp = run.get("fingerprint") or {}
|
|
@@ -232,6 +288,86 @@ def handle_ci(action: str, job: str, run_id: str, allow_foreign: bool,
|
|
|
232
288
|
f"{row.get('started_at', '')[:19]} {tally}")
|
|
233
289
|
return finalize("c3_ci", args, "\n".join(lines), f"{len(rows)} runs")
|
|
234
290
|
|
|
291
|
+
# ── history / intelligence ───────────────────────────────────────────
|
|
292
|
+
if action in ("history", "intel", "flaky"):
|
|
293
|
+
from services import ci_intel
|
|
294
|
+
data = ci_intel.analyse(project)
|
|
295
|
+
if not data["runs_analysed"]:
|
|
296
|
+
return finalize("c3_ci", args, data["note"], "no history")
|
|
297
|
+
lines = [data["note"], ""]
|
|
298
|
+
if data["flaky"]:
|
|
299
|
+
lines.append("FLAKY — passed AND failed on identical inputs:")
|
|
300
|
+
for job in data["flaky"]:
|
|
301
|
+
lines.append(f" {job['key']} {job['failed']}/{job['executed']} failed")
|
|
302
|
+
lines.append(" same fingerprint gave both answers, so the "
|
|
303
|
+
"code did not change between them")
|
|
304
|
+
lines.append("")
|
|
305
|
+
lines.append(f"{'job':<40}{'exec':>5}{'fail':>6}{'rate':>7}{'avg':>8}")
|
|
306
|
+
for job in data["jobs"][:15]:
|
|
307
|
+
rate = f"{job['fail_rate']:.0%}" if job["executed"] else "-"
|
|
308
|
+
avg = f"{job['avg_ms'] / 1000:.1f}s" if job["avg_ms"] else "-"
|
|
309
|
+
mark = "" if job["confident"] else " (low n)"
|
|
310
|
+
lines.append(f" {job['key']:<38}{job['executed']:>5}"
|
|
311
|
+
f"{job['failed']:>6}{rate:>7}{avg:>8}{mark}")
|
|
312
|
+
if data["slowest"]:
|
|
313
|
+
lines.append("\nSlowest: " + ", ".join(
|
|
314
|
+
f"{j['key']} {j['avg_ms'] / 1000:.1f}s" for j in data["slowest"][:3]))
|
|
315
|
+
return finalize("c3_ci", args, "\n".join(lines),
|
|
316
|
+
f"{len(data['flaky'])} flaky")
|
|
317
|
+
|
|
318
|
+
# ── publish (GitHub commit status) ───────────────────────────────────
|
|
319
|
+
if action == "publish":
|
|
320
|
+
from services import ci_github
|
|
321
|
+
run = cr.load_run(project, run_id)
|
|
322
|
+
if not run:
|
|
323
|
+
return finalize("c3_ci", args, "No run to publish.", "no runs")
|
|
324
|
+
res = ci_github.publish(project, run,
|
|
325
|
+
force=allow_side_effects,
|
|
326
|
+
dry_run=(job or "").lower() == "dry-run")
|
|
327
|
+
if res.get("dry_run"):
|
|
328
|
+
body = "\n".join([
|
|
329
|
+
f"Would POST {res['endpoint']}",
|
|
330
|
+
f" state={res['state']}",
|
|
331
|
+
f" {res['description']}",
|
|
332
|
+
])
|
|
333
|
+
return finalize("c3_ci", args, body, "dry run")
|
|
334
|
+
if not res.get("published"):
|
|
335
|
+
return finalize("c3_ci", args,
|
|
336
|
+
f"Not published: {res.get('reason')}", "refused")
|
|
337
|
+
body = (f"Published {res['state']} to {res['sha'][:8]} "
|
|
338
|
+
f"as {res['context']}.\n {res['description']}")
|
|
339
|
+
return finalize("c3_ci", args, body, res["state"])
|
|
340
|
+
|
|
341
|
+
# ── cache ────────────────────────────────────────────────────────────
|
|
342
|
+
if action == "cache":
|
|
343
|
+
from services import ci_cache
|
|
344
|
+
if (job or "").strip().lower() == "clear" or run_id == "clear":
|
|
345
|
+
freed = ci_cache.clear(project)
|
|
346
|
+
return finalize("c3_ci", args,
|
|
347
|
+
f"Cleared the CI cache ({freed / 1024:.0f} KB).",
|
|
348
|
+
"cache cleared")
|
|
349
|
+
info = ci_cache.stats(project)
|
|
350
|
+
rules = ci_impact.load_rules(project)
|
|
351
|
+
lines = [
|
|
352
|
+
f"Cached results: {info['results']}",
|
|
353
|
+
f"Dependency cache keys: {info['dependency_keys']}",
|
|
354
|
+
f"Location: {info['dir']}",
|
|
355
|
+
"",
|
|
356
|
+
"A job is reused when its definition, engine and inputs are all "
|
|
357
|
+
"unchanged since it last passed.",
|
|
358
|
+
]
|
|
359
|
+
if rules:
|
|
360
|
+
lines.append(
|
|
361
|
+
f"{len(rules)} job(s) declare inputs via ci.required_map, so "
|
|
362
|
+
"only those paths invalidate them.")
|
|
363
|
+
else:
|
|
364
|
+
lines.append(
|
|
365
|
+
"No ci.required_map: every job is fingerprinted over the whole "
|
|
366
|
+
"tree, so any edit invalidates every cached result. Declaring "
|
|
367
|
+
"inputs is what makes the cache bite.")
|
|
368
|
+
return finalize("c3_ci", args, "\n".join(lines),
|
|
369
|
+
f"{info['results']} cached")
|
|
370
|
+
|
|
235
371
|
# ── doctor ───────────────────────────────────────────────────────────
|
|
236
372
|
if action == "doctor":
|
|
237
373
|
from services import ci_act
|
{code_context_control-2.81.0 → code_context_control-2.85.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.85.0
|
|
4
4
|
Summary: Local MCP code-intelligence for AI coding tools: surgical search/read/edit, agent-config version history, path-level access + masking guards, and a multi-project hub.
|
|
5
5
|
Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -186,8 +186,12 @@ services/benchmark_dashboard.py
|
|
|
186
186
|
services/bitbucket_client.py
|
|
187
187
|
services/bitbucket_credentials.py
|
|
188
188
|
services/ci_act.py
|
|
189
|
+
services/ci_cache.py
|
|
189
190
|
services/ci_expr.py
|
|
190
191
|
services/ci_failures.py
|
|
192
|
+
services/ci_github.py
|
|
193
|
+
services/ci_impact.py
|
|
194
|
+
services/ci_intel.py
|
|
191
195
|
services/ci_runner.py
|
|
192
196
|
services/ci_workflow.py
|
|
193
197
|
services/circuit_breaker.py
|
|
@@ -283,7 +287,10 @@ tests/test_c3_bridge_project_artifacts.py
|
|
|
283
287
|
tests/test_c3_shell.py
|
|
284
288
|
tests/test_chat_poll.py
|
|
285
289
|
tests/test_ci_act.py
|
|
290
|
+
tests/test_ci_cache.py
|
|
286
291
|
tests/test_ci_expr.py
|
|
292
|
+
tests/test_ci_impact.py
|
|
293
|
+
tests/test_ci_intel.py
|
|
287
294
|
tests/test_ci_runner.py
|
|
288
295
|
tests/test_ci_workflow.py
|
|
289
296
|
tests/test_circuit_breaker.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.85.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"
|
|
@@ -154,6 +154,42 @@ def side_effects(inst) -> list:
|
|
|
154
154
|
return found
|
|
155
155
|
|
|
156
156
|
|
|
157
|
+
# ── Host-mutation gate (native engine only) ─────────────────────────────────
|
|
158
|
+
# Learned the hard way, on this repository. A required-mode run selected every
|
|
159
|
+
# job and the native engine executed C3's own `test` job, whose steps are
|
|
160
|
+
# `python -m pip install -e ".[dev]"`. That uninstalled the copied C3 from
|
|
161
|
+
# site-packages and replaced it with an editable install pointing at the repo;
|
|
162
|
+
# the run then timed out mid-write and left the package — and every project's
|
|
163
|
+
# hooks — broken.
|
|
164
|
+
#
|
|
165
|
+
# The native engine has no isolation: a `run:` step executes as the user, on
|
|
166
|
+
# the user's machine, against the user's interpreter. Most CI jobs begin by
|
|
167
|
+
# installing dependencies, so "run the repo's real CI natively" means "let a
|
|
168
|
+
# YAML file reconfigure this machine". Under act the same step is contained and
|
|
169
|
+
# harmless, which is why the refusal points there rather than just saying no.
|
|
170
|
+
_HOST_MUTATION = re.compile(
|
|
171
|
+
r"(?:^|[\s;&|])(?:"
|
|
172
|
+
r"pip\s+(?:install|uninstall)|pip3\s+(?:install|uninstall)"
|
|
173
|
+
r"|python\s+-m\s+pip\s+(?:install|uninstall)"
|
|
174
|
+
r"|npm\s+(?:i|install)\s+(?:-g|--global)|npm\s+uninstall\s+(?:-g|--global)"
|
|
175
|
+
r"|yarn\s+global\s+add|pnpm\s+add\s+(?:-g|--global)"
|
|
176
|
+
r"|apt(?:-get)?\s+(?:install|remove|purge)|yum\s+install|dnf\s+install"
|
|
177
|
+
r"|brew\s+(?:install|uninstall)|choco\s+install|winget\s+install"
|
|
178
|
+
r"|cargo\s+install|go\s+install|gem\s+install"
|
|
179
|
+
r"|rustup\s|nvm\s+install|conda\s+(?:install|remove)"
|
|
180
|
+
r")\b", re.IGNORECASE)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def host_mutations(inst) -> list:
|
|
184
|
+
"""Steps that would reconfigure THIS machine if run without a container."""
|
|
185
|
+
found: list = []
|
|
186
|
+
for step in getattr(inst, "steps", []):
|
|
187
|
+
match = _HOST_MUTATION.search(str(getattr(step, "run", "") or ""))
|
|
188
|
+
if match:
|
|
189
|
+
found.append(f"step {step.index} runs `{match.group(0).strip()}`")
|
|
190
|
+
return found
|
|
191
|
+
|
|
192
|
+
|
|
157
193
|
# ── Command construction ────────────────────────────────────────────────────
|
|
158
194
|
|
|
159
195
|
def build_command(inst, project, act_path: str, event: str = "",
|