code-context-control 2.146.0__tar.gz → 2.149.1__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.146.0 → code_context_control-2.149.1}/PKG-INFO +1 -1
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/c3.py +1 -1
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_access_guard.py +1 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_server.py +231 -20
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/hub_access.js +119 -2
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/modals.js +34 -12
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/settings_modal.js +11 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/mcp_server.py +11 -1
- {code_context_control-2.146.0 → code_context_control-2.149.1}/code_context_control.egg-info/PKG-INFO +1 -1
- {code_context_control-2.146.0 → code_context_control-2.149.1}/code_context_control.egg-info/SOURCES.txt +4 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/pyproject.toml +1 -1
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/access_guard.py +60 -4
- code_context_control-2.149.1/services/builtin_leases.py +182 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/project_manager.py +10 -2
- code_context_control-2.149.1/tests/test_builtin_leases.py +210 -0
- code_context_control-2.149.1/tests/test_hub_builtin_routes.py +163 -0
- code_context_control-2.149.1/tests/test_hub_ide_cmd.py +125 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/LICENSE +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/README.md +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/__init__.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/_hook_utils.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/_shell_writes.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/commands/__init__.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/commands/common.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/commands/parser.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/docs.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/edits.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/guide/access.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/guide/bitbucket.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/guide/ci.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/guide/credentials.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/guide/delegate.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/guide/getting-started.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/guide/index.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/guide/jira.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/guide/masking.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/guide/oracle.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/guide/sessions.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/guide/shared.css +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/guide/tools.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/guide/workflow.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_agent_model.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_artifact.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_auto_snapshot.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_c3_signal.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_c3read.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_codex_lifecycle.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_dispatch.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_edit_ledger.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_edit_unlock.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_filter.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_ghost_files.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_pretool_enforce.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_prompt_recall.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_read.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_session_end.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_session_open.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_session_stats.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hook_terse_advisor.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/app.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/add_project.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/config_editor.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/drill_artifacts.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/drill_health.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/drill_panel.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/drill_subprojects.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/drill_tasks.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/drill_views.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/global_search.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/hub_ci.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/hub_cred_audit.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/hub_credentials.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/hub_enforcement.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/hub_locks.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/hub_sessions.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/hub_tokens.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/mcp_manager.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/project_card.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/project_tree.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/session_drawer.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/sidebar.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/summary_bar.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/task_board.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/toasts.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/topbar.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/state.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/mcp_proxy.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/progress.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/server.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/__init__.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/_grants.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/_helpers.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/agent.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/artifacts.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/bitbucket.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/ci.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/compress.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/credentials.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/delegate.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/edit.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/edit_verify.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/edits.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/federate.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/filter.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/impact.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/jira.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/locks.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/memory.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/override.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/project.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/read.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/search.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/session.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/shell.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/shell_job.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/shell_nudge.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/shell_parsers.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/shell_render.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/status.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/tasks.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/tools/validate.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/api.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/app.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/components/access.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/components/bitbucket.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/components/chat.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/components/credentials.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/components/dashboard.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/components/edits.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/components/enforcement.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/components/instructions.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/components/jira.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/components/memory.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/components/sessions.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/components/settings.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/components/sidebar.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/components/tasks.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/icons.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/pm_shared.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/shared.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui/theme.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui_legacy.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/cli/ui_nano.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/code_context_control.egg-info/dependency_links.txt +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/code_context_control.egg-info/entry_points.txt +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/code_context_control.egg-info/requires.txt +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/code_context_control.egg-info/top_level.txt +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/core/__init__.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/core/codex_patch.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/core/config.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/core/grok_payload.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/core/hook_command.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/core/host.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/core/ide.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/core/mcp_toml.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/core/web_security.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/__init__.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/config.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/listeners.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/mcp_oracle.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/oracle_server.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/oracle_ui.html +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/__init__.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/activity_reporter.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/api_auth.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/c3_bridge.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/chat_engine.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/chat_poll.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/chat_store.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/client_tokens.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/cross_memory.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/discovery_audit.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/federated_graph.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/health_checker.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/insight_engine.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/local_session.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/memory_reader.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/memory_writer.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/mobile_api.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/project_scanner.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/review_agent.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/tool_executor.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/services/tool_registry.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/activity.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/agents.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/app.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/busy.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/chat/conversations.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/chat/input.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/chat/markdown.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/chat/send.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/chat/stream_renderer.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/chat/toolbar.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/core.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/crossgraph.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/header.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/insights.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/projects.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/qrcode.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/settings.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/suggestions.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/oracle/ui/theme_tabs.js +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/__init__.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/access_telemetry.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/activity_log.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/agent_base.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/agent_downshift.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/agent_locks.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/agents.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/agents_workflow.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/artifact_defs.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/artifact_store.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/atomic_json.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/auto_memory.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/background_service.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/bench/__init__.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/bench/delegate_eval.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/bench/delegate_write_eval.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/bench/external/__init__.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/bench/external/aider_polyglot.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/bench/external/swe_bench.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/bench/map_eval.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/bench/search_eval.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/bench/shell_eval.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/benchmark_dashboard.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/bitbucket_client.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/bitbucket_credentials.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/ci_act.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/ci_cache.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/ci_expr.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/ci_failures.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/ci_github.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/ci_impact.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/ci_intel.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/ci_runner.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/ci_workflow.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/circuit_breaker.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/claude_md.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/codex_integration.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/codex_transcript.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/compressor.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/context_snapshot.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/conversation_store.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/cred_audit.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/cred_telemetry.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/credential_backup.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/credential_store.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/delegate_agents.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/delegate_hints.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/delegate_write.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/dir_map.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/doc_index.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/e2e_benchmark.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/e2e_evaluator.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/e2e_tasks.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/edit_ledger.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/embedding_index.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/enforcement_policy.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/error_reporting.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/file_map.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/file_memory.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/git_context.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/grok_integration.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/grok_transcript.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/host_sessions.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/hub_service.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/index_store.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/indexer.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/jira_client.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/jira_cloud.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/jira_credentials.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/jira_data_center.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/jira_links.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/lexical_index.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/mask_activation.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/mask_mirror.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/mask_presets.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/memory.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/memory_consolidator.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/memory_distiller.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/memory_graph.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/memory_grounder.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/memory_queue.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/memory_scorer.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/metrics.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/notifications.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/ollama_bridge.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/ollama_client.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/ollama_credentials.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/oracle_service.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/output_filter.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/override_costs.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/override_grants.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/override_policy.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/override_requests.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/override_wake.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/parser.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/project_runtime.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/protocol.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/proxy_state.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/repo_map.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/repo_shape.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/reranker.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/retention.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/retrieval.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/retrieval_broker.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/router.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/runtime.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/scanner.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/session_benchmark.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/session_catalog.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/session_live.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/session_manager.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/session_preloader.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/shell_jobs.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/shell_output.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/subprojects.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/task_store.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/telemetry.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/terminal_launch.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/text_index.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/time_tracker.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/tool_classifier.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/transcript_index.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/validation_cache.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/vector_store.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/watcher.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/services/win_subprocess.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/setup.cfg +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_access_builtin_optout.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_access_guard.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_access_guard_meta.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_access_guard_shell_project.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_access_guard_surfaces.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_access_guard_wiring.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_activity_log_find_last.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_activity_reporter.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_agent_locks.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_aider_polyglot.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_antigravity_transition.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_artifact_store.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_artifact_tool.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_atomic_json.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_background_service.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_bitbucket_cli_smoke.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_bitbucket_client.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_bitbucket_config_fallback.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_bitbucket_credentials.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_bitbucket_tool.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_builtin_modes.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_c3_bridge_project_artifacts.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_c3_shell.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_chat_poll.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_ci_act.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_ci_cache.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_ci_dag_ownership.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_ci_expr.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_ci_impact.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_ci_intel.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_ci_runner.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_ci_workflow.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_circuit_breaker.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_claude_md_merge.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_claude_md_updater.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_cli_smoke.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_codex_mcp_transport.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_codex_native.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_compressor_large_file.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_confirm_guard.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_confirm_guard_wiring.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_cooccurrence_bounds.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_cred_audit.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_cred_telemetry.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_credential_backup.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_credential_login_kind.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_credential_store.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_credential_ui_parity.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_credentials_routes.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_credentials_tool.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_creds_cli_smoke.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_delegate_adoption_d4.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_delegate_auto.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_delegate_cascade.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_delegate_claude_d1.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_delegate_eval.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_delegate_grok.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_delegate_host_d2.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_delegate_scout_d3.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_delegate_telemetry_d0.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_delegate_thinking_cap.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_delegate_tuning.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_delegate_version_probe.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_delegate_write.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_delegate_write_eval.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_dir_map_c3.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_e2e_benchmark.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_edit_ledger_deadline.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_edit_ledger_hook.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_edit_locking.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_edit_normalization.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_edit_verify.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_embedding_index_corrupt_store.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_embedding_index_deadlock.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_enforcement_flip.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_enforcement_policy.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_enforcement_routes.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_env_parser.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_failed_calls_do_not_unlock.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_federated_graph.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_file_map_c1.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_filter_backoff.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_ghost_files.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_ghost_generation.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_git_branch_awareness.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_grok_native.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hook_access_guard.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hook_codex_compat.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hook_dispatch.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hook_grok_compat.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hook_pretool_enforce.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hook_prompt_recall.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hook_session_end.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hook_smoke.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hook_state.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hook_utf8_stdio.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hub_access_routes.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hub_credentials_route.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hub_credentials_routes_write.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hub_enforcement_routes.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hub_hook_migration.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hub_inspect_api.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hub_locks_routes.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hub_oracle_service_routes.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hub_override_policy_routes.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hub_override_routes.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hub_rules_routes.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hub_server_smoke.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hub_sessions_routes.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_hub_subproject_links.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_ide_workflow_adaptation.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_index_cap_not_hardcoded.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_init_clear_preserves_user_content.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_init_scan.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_install_mcp_entrypoint.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_jira_cli_smoke.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_jira_client.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_jira_config_fallback.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_jira_credentials.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_jira_links.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_jira_routes.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_jira_tool.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_large_files_c4.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_lazy_store_init.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_map_eval.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_map_telemetry_c0.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_mask_guard.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_mask_routes.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_mask_surfaces.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_mcp_host_guard.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_mcp_memory_timeout.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_mcp_server_smoke.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_mcp_toml.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_memory_distiller.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_memory_graph_api.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_memory_queue.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_memory_system.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_mobile_api.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_mobile_clients.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_mobile_extras.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_mobile_jobs_ci.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_mobile_override_costs.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_mobile_override_routes.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_mobile_security_api.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_no_stale_model_pins.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_notification_dedup.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_notification_discipline.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_notification_kinds.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_ollama_credentials.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_oracle_api_auth.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_oracle_apikey_api.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_oracle_c3_bridge.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_oracle_chat_engine.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_oracle_chat_store.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_oracle_discovery_api.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_oracle_discovery_audit.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_oracle_health_probe.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_oracle_local_auth.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_oracle_loopback.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_oracle_ollama_bridge.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_oracle_scanner_cache.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_oracle_security_fixes.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_oracle_session_bootstrap.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_oracle_subproject_awareness.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_oracle_ui_bundle.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_output_filter.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_override_costs.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_override_grants.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_override_grants_mcp.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_override_requests.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_override_wake.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_permissions.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_pm_api.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_project_manager.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_project_manager_merge.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_project_tool.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_read_coercion.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_read_edit_parity.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_read_outside_root.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_related_facts.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_repo_map.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_repo_shape.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_response_boilerplate.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_retention.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_review_digest.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_search_eval.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_search_p1.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_search_p2.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_search_p2b.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_search_p3.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_search_p4.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_search_p5.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_service_durability.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_session_benchmark.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_session_budget.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_session_catalog.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_session_live.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_session_tool.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_shell_budget_s1.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_shell_creds.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_shell_eval.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_shell_jobs_s3.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_shell_nudge_s4.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_shell_output.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_shell_parsers_s2.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_shell_robustness.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_shell_telemetry_s0.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_shell_write_ledger.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_shell_writes.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_subproject_clear_scope.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_subproject_depth_consumers.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_subproject_exclusion.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_subproject_federation.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_subproject_linkage_api.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_subprojects.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_swe_bench.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_task_store.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_task_tool.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_time_tracker.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_token_telemetry.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_token_tracking.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_tool_registry.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_ui_jsx_syntax.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_upgrade_and_version.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_validate.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_vault_write_guard.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_version_sync.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_watcher_pruning.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_web_security.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tests/test_windows_reliability.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/__init__.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/backend.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/main.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/screens/__init__.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/screens/benchmark_view.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/screens/claudemd_view.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/screens/compress_view.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/screens/index_view.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/screens/init_view.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/screens/mcp_view.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/screens/optimize_view.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/screens/pipe_view.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/screens/projects_view.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/screens/search_view.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/screens/session_view.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/screens/stats.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/screens/ui_view.py +0 -0
- {code_context_control-2.146.0 → code_context_control-2.149.1}/tui/theme.tcss +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-context-control
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.149.1
|
|
4
4
|
Summary: Local MCP code-intelligence for AI coding tools: surgical search/read/edit, agent-config version history, path-level access + masking guards, and a multi-project hub.
|
|
5
5
|
Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -91,7 +91,7 @@ console = Console() if HAS_RICH else None
|
|
|
91
91
|
# Config
|
|
92
92
|
CONFIG_DIR = ".c3"
|
|
93
93
|
CONFIG_FILE = ".c3/config.json"
|
|
94
|
-
__version__ = "2.
|
|
94
|
+
__version__ = "2.149.1"
|
|
95
95
|
|
|
96
96
|
# The PreToolUse matcher for native subagent calls (installer and hub migration).
|
|
97
97
|
AGENT_MATCHER = "Agent|Task"
|
|
@@ -447,6 +447,7 @@ def run(payload: dict, project_path: Path | None = None,
|
|
|
447
447
|
tool_input = payload.get("tool_input", {}) or {}
|
|
448
448
|
base = str(project_path if project_path is not None else Path.cwd())
|
|
449
449
|
session_id = str(payload.get("session_id") or "")
|
|
450
|
+
ag.bind_session(session_id)
|
|
450
451
|
|
|
451
452
|
if tool in _WRITE_TOOLS or tool in _READ_TOOLS:
|
|
452
453
|
fp = _target(tool_input)
|
|
@@ -72,6 +72,10 @@ _HUB_CONFIG_DEFAULTS = {
|
|
|
72
72
|
"projects_view": "list",
|
|
73
73
|
"main_view": "projects",
|
|
74
74
|
"oracle_url": "",
|
|
75
|
+
# Per-IDE launch command overrides, e.g. {"claude-code": "yep"} when the
|
|
76
|
+
# agent is started through a wrapper script instead of the stock binary.
|
|
77
|
+
# A project's own `ide_cmd` (projects.json) wins over this.
|
|
78
|
+
"ide_cmds": {},
|
|
75
79
|
# Minutes of project silence, with no session heartbeat left, before a UI
|
|
76
80
|
# server that an IDE session launched is stopped. 0 = never reap.
|
|
77
81
|
"ui_reap_minutes": 30,
|
|
@@ -81,6 +85,48 @@ _HUB_CONFIG_DEFAULTS = {
|
|
|
81
85
|
_MAIN_VIEWS = {"projects", "board", "ci", "creds", "tokens", "locks", "access",
|
|
82
86
|
"enforce", "sessions"}
|
|
83
87
|
|
|
88
|
+
# Stock command per IDE id, and whether it takes the project path as an
|
|
89
|
+
# argument (GUI) instead of being run inside a terminal at that path.
|
|
90
|
+
_IDE_DEFAULT_CMDS = {
|
|
91
|
+
"claude-code": ("claude", False),
|
|
92
|
+
"claude-app": ("claude-app", True),
|
|
93
|
+
"codex": ("codex", False),
|
|
94
|
+
"grok": ("grok", False),
|
|
95
|
+
"gemini": ("gemini", False),
|
|
96
|
+
"antigravity": ("antigravity", False),
|
|
97
|
+
"vscode": ("code", True),
|
|
98
|
+
"cursor": ("cursor", True),
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _resolve_ide_cmd(ide: str, path: str, custom_cmd: str = "") -> tuple:
|
|
103
|
+
"""Resolve the command to launch for `ide` in `path`.
|
|
104
|
+
|
|
105
|
+
Precedence: explicit custom_cmd (this launch) → the project's stored
|
|
106
|
+
`ide_cmd` → hub config `ide_cmds[ide]` → the stock command.
|
|
107
|
+
Returns (cmd, is_gui, error) — error is a message when nothing resolves.
|
|
108
|
+
"""
|
|
109
|
+
default_cmd, is_gui = _IDE_DEFAULT_CMDS.get(ide, ("", False))
|
|
110
|
+
if ide != "custom" and not default_cmd:
|
|
111
|
+
return "", False, f"Unknown IDE: {ide}"
|
|
112
|
+
cmd = (custom_cmd or "").strip()
|
|
113
|
+
if not cmd:
|
|
114
|
+
try:
|
|
115
|
+
cmd = _pm().get_ide_cmd(path)
|
|
116
|
+
except Exception:
|
|
117
|
+
cmd = ""
|
|
118
|
+
if not cmd:
|
|
119
|
+
overrides = _read_hub_config().get("ide_cmds") or {}
|
|
120
|
+
if isinstance(overrides, dict):
|
|
121
|
+
cmd = str(overrides.get(ide) or "").strip()
|
|
122
|
+
if not cmd:
|
|
123
|
+
cmd = default_cmd
|
|
124
|
+
if not cmd:
|
|
125
|
+
return "", False, "custom_cmd is required for custom IDE"
|
|
126
|
+
# An overridden command replaces the binary, not the launch style: a
|
|
127
|
+
# wrapper for a terminal CLI is still a terminal CLI.
|
|
128
|
+
return cmd, is_gui, ""
|
|
129
|
+
|
|
84
130
|
# How often the hub reaps orphaned UI servers and chases autostart projects.
|
|
85
131
|
_UI_SWEEP_INTERVAL_S = 60
|
|
86
132
|
|
|
@@ -460,6 +506,15 @@ def api_hub_config_set():
|
|
|
460
506
|
cfg["main_view"] = main_view
|
|
461
507
|
if "oracle_url" in data:
|
|
462
508
|
cfg["oracle_url"] = str(data["oracle_url"]).strip()
|
|
509
|
+
if "ide_cmds" in data:
|
|
510
|
+
raw = data["ide_cmds"]
|
|
511
|
+
if not isinstance(raw, dict):
|
|
512
|
+
return jsonify({"error": "ide_cmds must be an object"}), 400
|
|
513
|
+
# Empty string = "back to the stock command", so the key is dropped
|
|
514
|
+
# rather than stored blank.
|
|
515
|
+
cfg["ide_cmds"] = {
|
|
516
|
+
str(k): str(v).strip() for k, v in raw.items() if str(v or "").strip()
|
|
517
|
+
}
|
|
463
518
|
if "sidebar_group" in data:
|
|
464
519
|
cfg["sidebar_group"] = str(data["sidebar_group"]).strip()
|
|
465
520
|
if "sidebar_collapsed" in data:
|
|
@@ -718,17 +773,11 @@ def api_projects_open():
|
|
|
718
773
|
|
|
719
774
|
@app.route("/api/projects/launch-ide", methods=["POST"])
|
|
720
775
|
def api_launch_ide():
|
|
721
|
-
"""Launch an IDE or CLI tool in the project directory. Body: {path, ide, custom_cmd?}
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
"grok": ("grok", False),
|
|
727
|
-
"gemini": ("gemini", False),
|
|
728
|
-
"antigravity": ("antigravity", False),
|
|
729
|
-
"vscode": ("code", True),
|
|
730
|
-
"cursor": ("cursor", True),
|
|
731
|
-
}
|
|
776
|
+
"""Launch an IDE or CLI tool in the project directory. Body: {path, ide, custom_cmd?}
|
|
777
|
+
|
|
778
|
+
The command itself is resolved by _resolve_ide_cmd, so a project or the
|
|
779
|
+
hub can point `claude-code` at a wrapper such as `yep`.
|
|
780
|
+
"""
|
|
732
781
|
try:
|
|
733
782
|
data = request.get_json(force=True) or {}
|
|
734
783
|
path_str = (data.get("path") or "").strip()
|
|
@@ -744,14 +793,9 @@ def api_launch_ide():
|
|
|
744
793
|
if not path.exists():
|
|
745
794
|
return jsonify({"error": f"Path does not exist: {path_str}"}), 404
|
|
746
795
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
cmd, is_gui = custom_cmd, False
|
|
751
|
-
elif ide in _IDE_CMDS:
|
|
752
|
-
cmd, is_gui = _IDE_CMDS[ide]
|
|
753
|
-
else:
|
|
754
|
-
return jsonify({"error": f"Unknown IDE: {ide}"}), 400
|
|
796
|
+
cmd, is_gui, err = _resolve_ide_cmd(ide, str(path), custom_cmd)
|
|
797
|
+
if err:
|
|
798
|
+
return jsonify({"error": err}), 400
|
|
755
799
|
|
|
756
800
|
if is_gui:
|
|
757
801
|
# GUI IDEs (VS Code, Cursor) accept a path argument directly
|
|
@@ -795,7 +839,7 @@ def api_launch_ide():
|
|
|
795
839
|
|
|
796
840
|
@app.route("/api/projects/update", methods=["POST"])
|
|
797
841
|
def api_projects_update():
|
|
798
|
-
"""Update editable project fields
|
|
842
|
+
"""Update editable project fields. Body: {path, name?, tags?, notes?, ide_cmd?}"""
|
|
799
843
|
data = request.get_json(force=True) or {}
|
|
800
844
|
path = (data.get("path") or "").strip()
|
|
801
845
|
if not path:
|
|
@@ -812,6 +856,9 @@ def api_projects_update():
|
|
|
812
856
|
fields["tags"] = [t.strip() for t in str(raw).split(",") if t.strip()]
|
|
813
857
|
if "notes" in data:
|
|
814
858
|
fields["notes"] = str(data["notes"])
|
|
859
|
+
if "ide_cmd" in data:
|
|
860
|
+
# Blank clears the override and falls back to the stock command.
|
|
861
|
+
fields["ide_cmd"] = str(data["ide_cmd"] or "").strip()
|
|
815
862
|
try:
|
|
816
863
|
ok = _pm().update_project(path, **fields)
|
|
817
864
|
return jsonify({"updated": ok})
|
|
@@ -3839,6 +3886,170 @@ def api_hub_access_rule_remove():
|
|
|
3839
3886
|
return jsonify(result)
|
|
3840
3887
|
|
|
3841
3888
|
|
|
3889
|
+
# ── Builtin guard modes (v2.147.0) ─────────────────────────────────────────
|
|
3890
|
+
|
|
3891
|
+
def _hub_human():
|
|
3892
|
+
"""The Desk client behind ``Authorization: Bearer``, else ``None``.
|
|
3893
|
+
|
|
3894
|
+
Loopback and the CSRF guard stop a browser, not a process on this
|
|
3895
|
+
machine: an agent can POST here as easily as a person. A Desk client
|
|
3896
|
+
token is minted only with ``bootstrap.key``, which Access Guard denies
|
|
3897
|
+
to agents, and is stored as a hash, so presenting one is the proof a
|
|
3898
|
+
loosening builtin change needs. A phone token does not count: builtin
|
|
3899
|
+
guards are not loosened from a device that leaves the building.
|
|
3900
|
+
"""
|
|
3901
|
+
from oracle.services import client_tokens
|
|
3902
|
+
scheme, _, token = (request.headers.get("Authorization") or "").partition(" ")
|
|
3903
|
+
if scheme.lower() != "bearer" or not token.strip():
|
|
3904
|
+
return None
|
|
3905
|
+
who = client_tokens.principal_for(token.strip())
|
|
3906
|
+
return who if who and who.get("kind") == "desk" else None
|
|
3907
|
+
|
|
3908
|
+
|
|
3909
|
+
@app.route("/api/hub/access/builtin", methods=["GET"])
|
|
3910
|
+
def api_hub_access_builtin():
|
|
3911
|
+
"""Every Tier-1 builtin with its live global mode, and each project's own.
|
|
3912
|
+
|
|
3913
|
+
Modes are read through the keyring (config and attestation must agree),
|
|
3914
|
+
so a mode listed here is one evaluation honours. ``projects`` holds only
|
|
3915
|
+
projects that set a mode of their own, or could not be read.
|
|
3916
|
+
``strictness`` ranks each mode 0 (allow) to 3 (full deny), so a client
|
|
3917
|
+
can tell loosening from tightening without knowing the tiers.
|
|
3918
|
+
"""
|
|
3919
|
+
try:
|
|
3920
|
+
global_modes = access_guard._scope_modes("global")
|
|
3921
|
+
except Exception as e:
|
|
3922
|
+
return jsonify({"error": str(e)}), 500
|
|
3923
|
+
home = access_guard._global_base()
|
|
3924
|
+
guards = []
|
|
3925
|
+
for glob in access_guard.DISABLEABLE_BUILTINS:
|
|
3926
|
+
canon = access_guard._norm_builtin(glob)
|
|
3927
|
+
guards.append({
|
|
3928
|
+
"glob": canon,
|
|
3929
|
+
"global": global_modes.get(canon, "default"),
|
|
3930
|
+
"strictness": {m: access_guard.builtin_strictness(canon, m)
|
|
3931
|
+
for m in (*access_guard.BUILTIN_MODES, "default")},
|
|
3932
|
+
})
|
|
3933
|
+
projects = []
|
|
3934
|
+
for p in _pm().list_registered():
|
|
3935
|
+
ppath = str(p.get("path") or "")
|
|
3936
|
+
row = {"name": p.get("name") or Path(ppath).name, "path": ppath,
|
|
3937
|
+
"modes": {}, "error": None}
|
|
3938
|
+
try:
|
|
3939
|
+
base = Path(ppath).resolve()
|
|
3940
|
+
if (base / ".c3").is_dir() and base != home:
|
|
3941
|
+
row["modes"] = access_guard._scope_modes("project", ppath)
|
|
3942
|
+
except Exception as e:
|
|
3943
|
+
row["error"] = str(e)
|
|
3944
|
+
if row["modes"] or row["error"]:
|
|
3945
|
+
projects.append(row)
|
|
3946
|
+
from services import builtin_leases
|
|
3947
|
+
return jsonify({"guards": guards, "projects": projects,
|
|
3948
|
+
"leases": builtin_leases.active()})
|
|
3949
|
+
|
|
3950
|
+
|
|
3951
|
+
@app.route("/api/hub/access/builtin/mode", methods=["POST"])
|
|
3952
|
+
def api_hub_access_builtin_mode():
|
|
3953
|
+
"""Set a Tier-1 builtin's mode in the global realm or one project's.
|
|
3954
|
+
|
|
3955
|
+
Body: ``{scope, path?, glob, mode, confirm?}``. A mode at least as strict
|
|
3956
|
+
as the live one needs nothing more. A looser one needs a Desk client
|
|
3957
|
+
token (403 ``needs_human`` without it) and ``confirm`` equal to the glob
|
|
3958
|
+
(400 ``needs_confirmation``). A project is judged against what its
|
|
3959
|
+
agents see today, which is the global mode unless it set its own.
|
|
3960
|
+
"""
|
|
3961
|
+
data = request.get_json(silent=True) or {}
|
|
3962
|
+
scope, project, err = _hub_access_target(data)
|
|
3963
|
+
if err:
|
|
3964
|
+
return err
|
|
3965
|
+
glob = str(data.get("glob") or "")
|
|
3966
|
+
mode = str(data.get("mode") or "").strip()
|
|
3967
|
+
canon = access_guard._norm_builtin(glob)
|
|
3968
|
+
try:
|
|
3969
|
+
new = access_guard.builtin_strictness(canon, mode)
|
|
3970
|
+
live = (access_guard._scope_modes("global") if scope == "global"
|
|
3971
|
+
else access_guard.effective_builtin_modes(project))
|
|
3972
|
+
old = access_guard.builtin_strictness(canon, live.get(canon, "default"))
|
|
3973
|
+
except ValueError as exc:
|
|
3974
|
+
return jsonify({"error": str(exc)}), 400
|
|
3975
|
+
if new < old:
|
|
3976
|
+
if _hub_human() is None:
|
|
3977
|
+
return jsonify({
|
|
3978
|
+
"error": "loosening a built-in guard needs C3 Desk",
|
|
3979
|
+
"needs_human": True,
|
|
3980
|
+
"command": f'c3 access builtin mode "{canon}" {mode}'
|
|
3981
|
+
+ (f' --project --path "{project}"'
|
|
3982
|
+
if scope == "project" else ""),
|
|
3983
|
+
}), 403
|
|
3984
|
+
if access_guard._norm_builtin(data.get("confirm")) != canon:
|
|
3985
|
+
return jsonify({
|
|
3986
|
+
"error": "loosening a built-in guard weakens protection",
|
|
3987
|
+
"needs_confirmation": True, "confirm_with": canon,
|
|
3988
|
+
}), 400
|
|
3989
|
+
try:
|
|
3990
|
+
result = access_guard.set_builtin_mode(canon, mode, scope,
|
|
3991
|
+
project or ".")
|
|
3992
|
+
except ValueError as exc:
|
|
3993
|
+
return jsonify({"error": str(exc)}), 400
|
|
3994
|
+
if result["changed"]:
|
|
3995
|
+
_hub_access_audit(f"builtin_mode_{result['mode']}", result["glob"],
|
|
3996
|
+
"builtin", scope, project)
|
|
3997
|
+
return jsonify({**result, "loosened": new < old})
|
|
3998
|
+
|
|
3999
|
+
|
|
4000
|
+
@app.route("/api/hub/access/builtin/lease", methods=["POST"])
|
|
4001
|
+
def api_hub_access_builtin_lease():
|
|
4002
|
+
"""Loosen a builtin for a while: every session, or one.
|
|
4003
|
+
|
|
4004
|
+
Body: ``{scope, path?, glob, mode, ttl_s, session_id?, confirm}``. A
|
|
4005
|
+
lease only ever loosens, so it always needs a Desk client token and the
|
|
4006
|
+
glob typed back, and a lease no looser than the live mode is a 400
|
|
4007
|
+
rather than a row that would never apply. ``ttl_s`` is 60 s to 8 h.
|
|
4008
|
+
"""
|
|
4009
|
+
from services import builtin_leases
|
|
4010
|
+
data = request.get_json(silent=True) or {}
|
|
4011
|
+
scope, project, err = _hub_access_target(data)
|
|
4012
|
+
if err:
|
|
4013
|
+
return err
|
|
4014
|
+
who = _hub_human()
|
|
4015
|
+
if who is None:
|
|
4016
|
+
return jsonify({"error": "a temporary built-in change needs C3 Desk",
|
|
4017
|
+
"needs_human": True}), 403
|
|
4018
|
+
canon = access_guard._norm_builtin(data.get("glob"))
|
|
4019
|
+
mode = str(data.get("mode") or "").strip()
|
|
4020
|
+
if access_guard._norm_builtin(data.get("confirm")) != canon or not canon:
|
|
4021
|
+
return jsonify({"error": "a temporary change weakens protection",
|
|
4022
|
+
"needs_confirmation": True, "confirm_with": canon}), 400
|
|
4023
|
+
try:
|
|
4024
|
+
live = access_guard.effective_builtin_modes(project or ".") \
|
|
4025
|
+
if scope == "project" else access_guard._scope_modes("global")
|
|
4026
|
+
if access_guard.builtin_strictness(canon, mode) >= \
|
|
4027
|
+
access_guard.builtin_strictness(canon, live.get(canon, "default")):
|
|
4028
|
+
return jsonify({"error": f"{canon} is already {live.get(canon, 'default')}"
|
|
4029
|
+
f" — a {mode} lease would change nothing"}), 400
|
|
4030
|
+
row = builtin_leases.mint(
|
|
4031
|
+
canon, mode, scope=scope, project_path=project or ".",
|
|
4032
|
+
session_id=str(data.get("session_id") or ""),
|
|
4033
|
+
ttl_s=data.get("ttl_s"), created_by=who["client_id"])
|
|
4034
|
+
except ValueError as exc:
|
|
4035
|
+
return jsonify({"error": str(exc)}), 400
|
|
4036
|
+
_hub_access_audit(f"builtin_lease_{mode}", canon, "builtin", scope, project)
|
|
4037
|
+
return jsonify({"lease": row})
|
|
4038
|
+
|
|
4039
|
+
|
|
4040
|
+
@app.route("/api/hub/access/builtin/lease/revoke", methods=["POST"])
|
|
4041
|
+
def api_hub_access_builtin_lease_revoke():
|
|
4042
|
+
"""End a lease now. Tightening, so no token. Body: ``{id}``."""
|
|
4043
|
+
from services import builtin_leases
|
|
4044
|
+
lease_id = str((request.get_json(silent=True) or {}).get("id") or "")
|
|
4045
|
+
gone = builtin_leases.revoke(lease_id) if lease_id else None
|
|
4046
|
+
if gone is None:
|
|
4047
|
+
return jsonify({"error": "unknown or already-expired lease"}), 404
|
|
4048
|
+
_hub_access_audit("builtin_lease_revoke", gone["glob"], "builtin",
|
|
4049
|
+
gone["scope"], gone.get("project_path") or None)
|
|
4050
|
+
return jsonify({"revoked": lease_id})
|
|
4051
|
+
|
|
4052
|
+
|
|
3842
4053
|
# ── Project management: tasks / milestones / notes (v2.45.0) ──────────────
|
|
3843
4054
|
# Direct TaskStore per request (reload-per-op store — no runtime build needed
|
|
3844
4055
|
# for mutations); every write audited to the target project's activity log.
|
{code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/hub_access.js
RENAMED
|
@@ -19,8 +19,9 @@
|
|
|
19
19
|
// hand — the server enforces that regardless of what this UI believes);
|
|
20
20
|
// - a request that lapsed while the page showed it refreshes to its real
|
|
21
21
|
// status (the decide route answers 409), never silently mints a grant;
|
|
22
|
-
// - rule MUTATION stays on the per-project server and `c3 access
|
|
23
|
-
//
|
|
22
|
+
// - path-rule MUTATION stays on the per-project server and `c3 access`.
|
|
23
|
+
// Builtin guards may be TIGHTENED here; loosening one needs C3 Desk or
|
|
24
|
+
// the CLI, because this page holds no proof that a person clicked.
|
|
24
25
|
|
|
25
26
|
const ACC_KIND_COLOR = (kind) => (
|
|
26
27
|
kind === 'deny' ? T.error : kind === 'mask' ? T.blue
|
|
@@ -387,6 +388,121 @@ function AccRulesPanel({ projects, focus }) {
|
|
|
387
388
|
);
|
|
388
389
|
}
|
|
389
390
|
|
|
391
|
+
// ── Builtin guards ─────────────────────────────────────────────────────────
|
|
392
|
+
// The global mode of every Tier-1 builtin. Picking a stricter mode applies
|
|
393
|
+
// it; picking a looser one is refused by the server without a Desk token,
|
|
394
|
+
// and the panel shows the CLI command instead.
|
|
395
|
+
const ACC_BUILTIN_MODES = ['default', 'deny', 'confirm', 'allow'];
|
|
396
|
+
|
|
397
|
+
function AccBuiltinPanel() {
|
|
398
|
+
const [data, setData] = useState(null);
|
|
399
|
+
const [err, setErr] = useState('');
|
|
400
|
+
const [busy, setBusy] = useState('');
|
|
401
|
+
const [needs, setNeeds] = useState(null);
|
|
402
|
+
|
|
403
|
+
const load = useCallback(async () => {
|
|
404
|
+
try { setData(await api.get('/api/hub/access/builtin')); setErr(''); }
|
|
405
|
+
catch (e) { setErr(apiErr(e)); }
|
|
406
|
+
}, []);
|
|
407
|
+
useEffect(() => { load(); }, [load]);
|
|
408
|
+
usePoll(load, 15000);
|
|
409
|
+
|
|
410
|
+
const setMode = async (g, mode) => {
|
|
411
|
+
setBusy(g.glob); setNeeds(null);
|
|
412
|
+
try {
|
|
413
|
+
await api.post('/api/hub/access/builtin/mode', { scope: 'global', glob: g.glob, mode });
|
|
414
|
+
notify(`${g.glob} is now ${mode} everywhere`, 'ok');
|
|
415
|
+
} catch (e) {
|
|
416
|
+
const body = e && e.payload;
|
|
417
|
+
if (body && body.needs_human) setNeeds({ glob: g.glob, command: body.command });
|
|
418
|
+
else notify(apiErr(e), 'err');
|
|
419
|
+
}
|
|
420
|
+
setBusy('');
|
|
421
|
+
load();
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
const revoke = async (l) => {
|
|
425
|
+
setBusy(l.id);
|
|
426
|
+
try {
|
|
427
|
+
await api.post('/api/hub/access/builtin/lease/revoke', { id: l.id });
|
|
428
|
+
notify(`Ended the ${l.mode} lease on ${l.glob}`, 'ok');
|
|
429
|
+
} catch (e) { notify(apiErr(e), 'err'); }
|
|
430
|
+
setBusy('');
|
|
431
|
+
load();
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
const projects = (data && data.projects) || [];
|
|
435
|
+
const leases = (data && data.leases) || [];
|
|
436
|
+
return (
|
|
437
|
+
<div style={{
|
|
438
|
+
background: T.surface, border: `1px solid ${T.border}`, borderRadius: 10,
|
|
439
|
+
padding: '12px 16px',
|
|
440
|
+
}}>
|
|
441
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
|
|
442
|
+
<div style={{ fontSize: 12.5, fontWeight: 700, color: T.text }}>Built-in guards</div>
|
|
443
|
+
<span style={{ fontSize: 10.5, color: T.textDim }}>
|
|
444
|
+
global mode — a stricter mode applies here; loosening one needs C3 Desk or the CLI
|
|
445
|
+
</span>
|
|
446
|
+
</div>
|
|
447
|
+
{err && <div style={{ marginTop: 8, fontSize: 11.5, color: T.error }}>{err}</div>}
|
|
448
|
+
{needs && (
|
|
449
|
+
<div style={{ marginTop: 8, fontSize: 11.5, color: T.warn }}>
|
|
450
|
+
Loosening <span className="mono">{needs.glob}</span> needs C3 Desk, or run:{' '}
|
|
451
|
+
<span className="mono" style={{ color: T.text }}>{needs.command}</span>
|
|
452
|
+
</div>
|
|
453
|
+
)}
|
|
454
|
+
{data && (
|
|
455
|
+
<div style={{ marginTop: 10, display: 'grid', gridTemplateColumns: 'minmax(0,1fr) auto', gap: '4px 12px', alignItems: 'center' }}>
|
|
456
|
+
{data.guards.map(g => (
|
|
457
|
+
<React.Fragment key={g.glob}>
|
|
458
|
+
<span className="mono" style={{ fontSize: 11.5, color: T.text, overflow: 'hidden', textOverflow: 'ellipsis' }}>{g.glob}</span>
|
|
459
|
+
<select value={g.global} disabled={busy === g.glob}
|
|
460
|
+
onChange={e => setMode(g, e.target.value)}
|
|
461
|
+
style={{
|
|
462
|
+
background: T.surfaceAlt, color: g.global === 'default' ? T.textMuted : T.warn,
|
|
463
|
+
border: `1px solid ${T.border}`, borderRadius: 6, fontSize: 11.5, padding: '2px 6px',
|
|
464
|
+
}}>
|
|
465
|
+
{ACC_BUILTIN_MODES.map(m => <option key={m} value={m}>{m}</option>)}
|
|
466
|
+
</select>
|
|
467
|
+
</React.Fragment>
|
|
468
|
+
))}
|
|
469
|
+
</div>
|
|
470
|
+
)}
|
|
471
|
+
{leases.length > 0 && (
|
|
472
|
+
<div style={{ marginTop: 10, display: 'flex', flexDirection: 'column', gap: 4 }}>
|
|
473
|
+
<div style={{ fontSize: 10.5, fontWeight: 700, letterSpacing: 1, textTransform: 'uppercase', color: T.warn }}>
|
|
474
|
+
temporary changes
|
|
475
|
+
</div>
|
|
476
|
+
{leases.map(l => (
|
|
477
|
+
<div key={l.id} style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 11.5 }}>
|
|
478
|
+
<span className="mono" style={{ color: T.text }}>{l.glob}</span>
|
|
479
|
+
<span style={{ color: T.warn }}>{l.mode}</span>
|
|
480
|
+
<span style={{ color: T.textMuted }}>
|
|
481
|
+
{l.scope === 'project' ? l.project_path : 'all projects'}
|
|
482
|
+
{' · '}{l.session_id ? <>session <span className="mono">{l.session_id.slice(0, 8)}</span></> : 'all sessions'}
|
|
483
|
+
{' · '}ends in {accExpiresIn(l.expires_at) || '—'}
|
|
484
|
+
</span>
|
|
485
|
+
<div style={{ flex: 1 }} />
|
|
486
|
+
<Btn variant="ghost" disabled={busy === l.id} onClick={() => revoke(l)}>Revoke</Btn>
|
|
487
|
+
</div>
|
|
488
|
+
))}
|
|
489
|
+
</div>
|
|
490
|
+
)}
|
|
491
|
+
{projects.length > 0 && (
|
|
492
|
+
<div style={{ marginTop: 8, fontSize: 11, color: T.textDim }}>
|
|
493
|
+
Set per project:{' '}
|
|
494
|
+
{projects.map(p => (
|
|
495
|
+
<span key={p.path} className="mono" style={{ marginRight: 10 }}>
|
|
496
|
+
{p.name}: {p.error ? `unreadable (${p.error})`
|
|
497
|
+
: Object.entries(p.modes).map(([g, m]) => `${g}=${m}`).join(', ')}
|
|
498
|
+
</span>
|
|
499
|
+
))}
|
|
500
|
+
</div>
|
|
501
|
+
)}
|
|
502
|
+
</div>
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
|
|
390
506
|
// ── Active grants ──────────────────────────────────────────────────────────
|
|
391
507
|
// A rule grant can authorise many calls over hours. The only other place it
|
|
392
508
|
// shows up is a line in the agent's own transcript, which is the wrong place
|
|
@@ -762,6 +878,7 @@ function HubAccess({ projects }) {
|
|
|
762
878
|
)}
|
|
763
879
|
|
|
764
880
|
<AccGrantsPanel projects={projects} />
|
|
881
|
+
<AccBuiltinPanel />
|
|
765
882
|
<AccRulesPanel projects={projects} focus={ruleFocus} />
|
|
766
883
|
{confirmSpec && (
|
|
767
884
|
<CredConfirm spec={confirmSpec} onClose={() => setConfirmSpec(null)} />
|
{code_context_control-2.146.0 → code_context_control-2.149.1}/cli/hub_ui/components/modals.js
RENAMED
|
@@ -528,24 +528,41 @@ function ReparentModal({ project, projects, onClose, onChanged }) {
|
|
|
528
528
|
|
|
529
529
|
// ── IDE picker ─────────────────────────────────────────────────
|
|
530
530
|
// POST /api/projects/launch-ide {path, ide, custom_cmd?}
|
|
531
|
+
// The command is editable per project (stored as ide_cmd via
|
|
532
|
+
// /api/projects/update) so an agent started through a wrapper — `yep` rather
|
|
533
|
+
// than `claude` — launches from the card too, not just from here.
|
|
531
534
|
function IdePickerModal({ project, onClose, onChanged }) {
|
|
532
535
|
const known = IDE_OPTIONS.some(o => o.id === (project && project.ide));
|
|
533
536
|
const [selected, setSelected] = useState(known ? project.ide : 'claude-code');
|
|
534
|
-
const
|
|
537
|
+
const savedCmd = ((project && project.ide_cmd) || '').trim();
|
|
538
|
+
const [customCmd, setCustomCmd] = useState(savedCmd);
|
|
539
|
+
const [remember, setRemember] = useState(!!savedCmd);
|
|
535
540
|
const [busy, setBusy] = useState(false);
|
|
536
541
|
|
|
542
|
+
const stockCmd = (id) => {
|
|
543
|
+
const opt = IDE_OPTIONS.find(o => o.id === id);
|
|
544
|
+
return opt && opt.cmd !== '...' ? opt.cmd : '';
|
|
545
|
+
};
|
|
546
|
+
const effectiveCmd = customCmd.trim() || stockCmd(selected);
|
|
547
|
+
|
|
537
548
|
const launch = async () => {
|
|
538
|
-
|
|
549
|
+
const cmd = customCmd.trim();
|
|
550
|
+
if (selected === 'custom' && !cmd) {
|
|
539
551
|
notify('Enter a custom command first.', 'err');
|
|
540
552
|
return;
|
|
541
553
|
}
|
|
542
554
|
setBusy(true);
|
|
543
555
|
try {
|
|
556
|
+
// Persist first: the project card launches with no command of its own.
|
|
557
|
+
const wanted = remember ? cmd : '';
|
|
558
|
+
if (wanted !== savedCmd) {
|
|
559
|
+
await api.post('/api/projects/update', { path: project.path, ide_cmd: wanted });
|
|
560
|
+
}
|
|
544
561
|
await api.post('/api/projects/launch-ide', {
|
|
545
|
-
path: project.path, ide: selected,
|
|
546
|
-
custom_cmd: selected === 'custom' ? customCmd.trim() : '',
|
|
562
|
+
path: project.path, ide: selected, custom_cmd: cmd,
|
|
547
563
|
});
|
|
548
|
-
notify(`Launched ${ideLabel(selected)} in ${project.name || project.path}`);
|
|
564
|
+
notify(`Launched ${ideLabel(selected)} (${effectiveCmd}) in ${project.name || project.path}`);
|
|
565
|
+
if (onChanged) onChanged();
|
|
549
566
|
onClose();
|
|
550
567
|
} catch (e) {
|
|
551
568
|
notify(`Launch failed: ${e.message}`, 'err');
|
|
@@ -575,13 +592,18 @@ function IdePickerModal({ project, onClose, onChanged }) {
|
|
|
575
592
|
);
|
|
576
593
|
})}
|
|
577
594
|
</div>
|
|
578
|
-
|
|
579
|
-
<
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
595
|
+
<div>
|
|
596
|
+
<MdlLabel>Command{selected === 'custom' ? '' : ' (leave blank for the default)'}</MdlLabel>
|
|
597
|
+
<input value={customCmd} onChange={e => setCustomCmd(e.target.value)}
|
|
598
|
+
placeholder={selected === 'custom' ? 'e.g. nvim .' : `${stockCmd(selected)} — override with e.g. yep`}
|
|
599
|
+
className="mono" style={mdlInputStyle()} />
|
|
600
|
+
<label style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 6,
|
|
601
|
+
fontSize: 11, color: T.textMuted, cursor: 'pointer' }}>
|
|
602
|
+
<input type="checkbox" checked={remember}
|
|
603
|
+
onChange={e => setRemember(e.target.checked)} />
|
|
604
|
+
Remember for this project (used by the card's launch button too)
|
|
605
|
+
</label>
|
|
606
|
+
</div>
|
|
585
607
|
<MdlFooter>
|
|
586
608
|
<Btn variant="ghost" onClick={onClose}>Cancel</Btn>
|
|
587
609
|
<Btn onClick={launch} disabled={busy}>
|
|
@@ -14,6 +14,7 @@ function SettingsModal({ onClose, onChanged }) {
|
|
|
14
14
|
const [port, setPort] = useState('');
|
|
15
15
|
const [autoBrowser, setAutoBrowser] = useState(true);
|
|
16
16
|
const [oracleUrl, setOracleUrl] = useState('');
|
|
17
|
+
const [agentCmd, setAgentCmd] = useState(''); // ide_cmds['claude-code']
|
|
17
18
|
const [cacheSize, setCacheSize] = useState(8);
|
|
18
19
|
const [saving, setSaving] = useState(false);
|
|
19
20
|
const [svc, setSvc] = useState(null); // hub: {installed, running, method, port, log_path} | {error}
|
|
@@ -51,6 +52,7 @@ function SettingsModal({ onClose, onChanged }) {
|
|
|
51
52
|
setPort(d.port || 3330);
|
|
52
53
|
setAutoBrowser(!!d.auto_open_browser);
|
|
53
54
|
setOracleUrl(d.oracle_url || '');
|
|
55
|
+
setAgentCmd(((d.ide_cmds || {})['claude-code']) || '');
|
|
54
56
|
setCacheSize(d.runtime_cache_size || 8);
|
|
55
57
|
} catch {
|
|
56
58
|
notify('Could not load hub config', 'err');
|
|
@@ -70,9 +72,14 @@ function SettingsModal({ onClose, onChanged }) {
|
|
|
70
72
|
const cache = Math.max(1, parseInt(cacheSize, 10) || 8);
|
|
71
73
|
setSaving(true);
|
|
72
74
|
try {
|
|
75
|
+
// Blank restores the stock `claude`; other IDE overrides are left alone.
|
|
76
|
+
const ideCmds = { ...((cfg && cfg.ide_cmds) || {}) };
|
|
77
|
+
if (agentCmd.trim()) ideCmds['claude-code'] = agentCmd.trim();
|
|
78
|
+
else delete ideCmds['claude-code'];
|
|
73
79
|
await api.post('/api/hub/config', {
|
|
74
80
|
port: portVal, auto_open_browser: autoBrowser,
|
|
75
81
|
oracle_url: oracleUrl.trim(), runtime_cache_size: cache,
|
|
82
|
+
ide_cmds: ideCmds,
|
|
76
83
|
});
|
|
77
84
|
const portChanged = cfg && portVal !== cfg.port;
|
|
78
85
|
notify(portChanged
|
|
@@ -222,6 +229,10 @@ function SettingsModal({ onClose, onChanged }) {
|
|
|
222
229
|
<input type="number" value={cacheSize} onChange={e => setCacheSize(e.target.value)}
|
|
223
230
|
min={1} className="mono" style={inputStyle(110)} />
|
|
224
231
|
), 'Max project runtimes kept warm for drill-in and global search.')}
|
|
232
|
+
{fieldRow('Agent command', (
|
|
233
|
+
<input value={agentCmd} onChange={e => setAgentCmd(e.target.value)}
|
|
234
|
+
placeholder="claude" className="mono" style={inputStyle(220)} />
|
|
235
|
+
), 'Default command for "Claude Code CLI" launches — e.g. yep for a wrapper script. A project can override it in Open in IDE.')}
|
|
225
236
|
{fieldRow('Oracle URL', (
|
|
226
237
|
<input value={oracleUrl} onChange={e => setOracleUrl(e.target.value)}
|
|
227
238
|
placeholder="http://localhost:3331" className="mono" style={inputStyle(220)} />
|
|
@@ -23,9 +23,10 @@ sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
|
23
23
|
|
|
24
24
|
from fastmcp import Context, FastMCP
|
|
25
25
|
|
|
26
|
+
from cli.tools import _grants
|
|
26
27
|
from core.host import resolve_host
|
|
27
28
|
from core.ide import get_profile
|
|
28
|
-
from services import delegate_hints
|
|
29
|
+
from services import access_guard, delegate_hints
|
|
29
30
|
from services.auto_memory import AutoMemory
|
|
30
31
|
from services.context_snapshot import ContextSnapshot
|
|
31
32
|
from services.runtime import C3Runtime, build_runtime, start_runtime, stop_runtime
|
|
@@ -191,6 +192,14 @@ def _notify_mcp_ready(svc) -> None:
|
|
|
191
192
|
async def lifespan(server):
|
|
192
193
|
"""Initialize all services, auto-start session, start file watcher."""
|
|
193
194
|
project = PROJECT_PATH
|
|
195
|
+
# numpy's native module must load before any background thread exists: on
|
|
196
|
+
# Windows, loading it from c3-initial-index (via chromadb) while this
|
|
197
|
+
# process starts other threads deadlocks both, and the first tool call
|
|
198
|
+
# never answers. Absent numpy, nothing here needs it.
|
|
199
|
+
try:
|
|
200
|
+
import numpy # noqa: F401, PLC0415
|
|
201
|
+
except ImportError:
|
|
202
|
+
pass
|
|
194
203
|
services = build_runtime(project, ide_name=_IDE_NAME)
|
|
195
204
|
if getattr(services, "time_tracker", None) is not None:
|
|
196
205
|
try:
|
|
@@ -508,6 +517,7 @@ def _ensure_repo_map_once(rt) -> None:
|
|
|
508
517
|
def _svc(ctx: Context) -> C3Runtime:
|
|
509
518
|
rt = ctx.request_context.lifespan_context
|
|
510
519
|
_ensure_repo_map_once(rt)
|
|
520
|
+
access_guard.bind_session(_grants.session_id(rt))
|
|
511
521
|
return rt
|
|
512
522
|
|
|
513
523
|
|
{code_context_control-2.146.0 → code_context_control-2.149.1}/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.149.1
|
|
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
|
|
@@ -212,6 +212,7 @@ services/background_service.py
|
|
|
212
212
|
services/benchmark_dashboard.py
|
|
213
213
|
services/bitbucket_client.py
|
|
214
214
|
services/bitbucket_credentials.py
|
|
215
|
+
services/builtin_leases.py
|
|
215
216
|
services/ci_act.py
|
|
216
217
|
services/ci_cache.py
|
|
217
218
|
services/ci_expr.py
|
|
@@ -343,6 +344,7 @@ tests/test_bitbucket_client.py
|
|
|
343
344
|
tests/test_bitbucket_config_fallback.py
|
|
344
345
|
tests/test_bitbucket_credentials.py
|
|
345
346
|
tests/test_bitbucket_tool.py
|
|
347
|
+
tests/test_builtin_leases.py
|
|
346
348
|
tests/test_builtin_modes.py
|
|
347
349
|
tests/test_c3_bridge_project_artifacts.py
|
|
348
350
|
tests/test_c3_shell.py
|
|
@@ -420,10 +422,12 @@ tests/test_hook_smoke.py
|
|
|
420
422
|
tests/test_hook_state.py
|
|
421
423
|
tests/test_hook_utf8_stdio.py
|
|
422
424
|
tests/test_hub_access_routes.py
|
|
425
|
+
tests/test_hub_builtin_routes.py
|
|
423
426
|
tests/test_hub_credentials_route.py
|
|
424
427
|
tests/test_hub_credentials_routes_write.py
|
|
425
428
|
tests/test_hub_enforcement_routes.py
|
|
426
429
|
tests/test_hub_hook_migration.py
|
|
430
|
+
tests/test_hub_ide_cmd.py
|
|
427
431
|
tests/test_hub_inspect_api.py
|
|
428
432
|
tests/test_hub_locks_routes.py
|
|
429
433
|
tests/test_hub_oracle_service_routes.py
|