code-context-control 2.50.0__tar.gz → 2.52.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.50.0/code_context_control.egg-info → code_context_control-2.52.0}/PKG-INFO +9 -5
- {code_context_control-2.50.0 → code_context_control-2.52.0}/README.md +7 -3
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/_hook_utils.py +22 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/c3.py +190 -121
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/commands/parser.py +3 -3
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/docs.html +10 -30
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/guide/getting-started.html +6 -8
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/guide/tools.html +6 -3
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hook_dispatch.py +18 -4
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hook_edit_ledger.py +7 -1
- code_context_control-2.52.0/cli/hook_prompt_recall.py +97 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hook_terse_advisor.py +3 -1
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_server.py +8 -3
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/config_editor.js +8 -2
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/mcp_server.py +44 -3
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/server.py +65 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/_helpers.py +51 -3
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/read.py +5 -4
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/session.py +18 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/shell.py +141 -20
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui/components/settings.js +120 -4
- {code_context_control-2.50.0 → code_context_control-2.52.0/code_context_control.egg-info}/PKG-INFO +9 -5
- {code_context_control-2.50.0 → code_context_control-2.52.0}/code_context_control.egg-info/SOURCES.txt +13 -1
- {code_context_control-2.50.0 → code_context_control-2.52.0}/core/config.py +41 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/core/ide.py +5 -23
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/oracle_server.py +1 -1
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/services/chat_engine.py +1 -1
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/services/insight_engine.py +1 -1
- {code_context_control-2.50.0 → code_context_control-2.52.0}/pyproject.toml +2 -2
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/agents.py +70 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/artifact_defs.py +6 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/embedding_index.py +16 -5
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/memory.py +19 -7
- code_context_control-2.52.0/services/memory_distiller.py +591 -0
- code_context_control-2.52.0/services/memory_queue.py +107 -0
- {code_context_control-2.50.0/oracle → code_context_control-2.52.0}/services/ollama_bridge.py +20 -2
- code_context_control-2.52.0/services/ollama_credentials.py +78 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/runtime.py +14 -1
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/vector_store.py +21 -5
- code_context_control-2.52.0/tests/test_antigravity_transition.py +80 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_c3_shell.py +102 -3
- code_context_control-2.52.0/tests/test_hook_prompt_recall.py +105 -0
- code_context_control-2.52.0/tests/test_hook_utf8_stdio.py +128 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_lazy_store_init.py +28 -0
- code_context_control-2.52.0/tests/test_mcp_memory_timeout.py +37 -0
- code_context_control-2.52.0/tests/test_memory_distiller.py +409 -0
- code_context_control-2.52.0/tests/test_memory_queue.py +87 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_memory_system.py +25 -0
- code_context_control-2.52.0/tests/test_ollama_credentials.py +102 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_oracle_ollama_bridge.py +2 -2
- code_context_control-2.52.0/tests/test_related_facts.py +74 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/screens/claudemd_view.py +1 -1
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/screens/init_view.py +1 -1
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/screens/mcp_view.py +1 -1
- {code_context_control-2.50.0 → code_context_control-2.52.0}/LICENSE +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/__init__.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/commands/__init__.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/commands/common.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/edits.html +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/guide/bitbucket.html +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/guide/index.html +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/guide/oracle.html +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/guide/shared.css +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/guide/workflow.html +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hook_artifact.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hook_auto_snapshot.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hook_c3_signal.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hook_c3read.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hook_edit_unlock.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hook_filter.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hook_ghost_files.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hook_pretool_enforce.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hook_read.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hook_session_stats.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub.html +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/app.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/add_project.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/drill_health.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/drill_panel.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/drill_tasks.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/drill_views.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/global_search.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/mcp_manager.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/modals.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/project_card.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/project_tree.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/session_drawer.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/settings_modal.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/sidebar.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/summary_bar.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/task_board.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/toasts.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/components/topbar.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui/state.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/hub_ui.html +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/mcp_proxy.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/__init__.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/agent.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/artifacts.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/bitbucket.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/compress.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/delegate.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/edit.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/edits.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/federate.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/filter.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/impact.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/memory.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/project.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/search.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/status.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/tasks.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/tools/validate.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui/api.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui/app.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui/components/bitbucket.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui/components/chat.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui/components/dashboard.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui/components/edits.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui/components/instructions.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui/components/memory.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui/components/sessions.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui/components/sidebar.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui/components/tasks.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui/icons.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui/pm_shared.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui/shared.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui/theme.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui.html +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui_legacy.html +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/cli/ui_nano.html +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/code_context_control.egg-info/dependency_links.txt +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/code_context_control.egg-info/entry_points.txt +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/code_context_control.egg-info/requires.txt +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/code_context_control.egg-info/top_level.txt +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/core/__init__.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/core/mcp_toml.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/core/web_security.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/__init__.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/config.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/mcp_oracle.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/oracle_ui.html +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/services/__init__.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/services/activity_reporter.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/services/api_auth.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/services/c3_bridge.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/services/chat_store.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/services/cross_memory.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/services/federated_graph.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/services/health_checker.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/services/local_session.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/services/memory_reader.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/services/memory_writer.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/services/project_scanner.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/services/review_agent.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/services/tool_executor.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/services/tool_registry.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/activity.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/agents.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/app.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/busy.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/chat/conversations.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/chat/input.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/chat/markdown.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/chat/send.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/chat/stream_renderer.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/chat/toolbar.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/core.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/crossgraph.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/header.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/insights.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/projects.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/settings.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/suggestions.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/oracle/ui/theme_tabs.js +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/__init__.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/activity_log.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/agent_base.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/artifact_store.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/auto_memory.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/bench/__init__.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/bench/external/__init__.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/bench/external/aider_polyglot.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/bench/external/swe_bench.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/benchmark_dashboard.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/bitbucket_client.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/bitbucket_credentials.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/circuit_breaker.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/claude_md.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/compressor.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/context_snapshot.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/conversation_store.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/doc_index.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/e2e_benchmark.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/e2e_evaluator.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/e2e_tasks.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/edit_ledger.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/error_reporting.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/file_memory.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/git_context.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/hub_service.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/indexer.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/memory_consolidator.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/memory_graph.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/memory_grounder.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/memory_scorer.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/metrics.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/notifications.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/ollama_client.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/output_filter.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/parser.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/project_manager.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/project_runtime.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/protocol.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/proxy_state.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/retention.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/retrieval_broker.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/router.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/session_benchmark.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/session_manager.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/session_preloader.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/subprojects.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/task_store.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/telemetry.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/text_index.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/tool_classifier.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/transcript_index.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/validation_cache.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/watcher.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/services/win_subprocess.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/setup.cfg +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_activity_reporter.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_aider_polyglot.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_artifact_store.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_artifact_tool.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_bitbucket_cli_smoke.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_bitbucket_client.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_bitbucket_config_fallback.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_bitbucket_credentials.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_bitbucket_tool.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_circuit_breaker.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_claude_md_merge.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_cli_smoke.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_compressor_large_file.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_delegate_cascade.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_e2e_benchmark.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_edit_ledger_hook.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_edit_normalization.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_enforcement_flip.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_federated_graph.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_filter_backoff.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_ghost_files.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_ghost_generation.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_git_branch_awareness.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_hook_dispatch.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_hook_pretool_enforce.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_hook_smoke.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_hook_state.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_hub_inspect_api.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_hub_server_smoke.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_install_mcp_entrypoint.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_mcp_host_guard.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_mcp_server_smoke.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_mcp_toml.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_memory_graph_api.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_notification_dedup.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_notification_discipline.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_oracle_api_auth.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_oracle_apikey_api.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_oracle_c3_bridge.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_oracle_chat_engine.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_oracle_discovery_api.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_oracle_local_auth.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_oracle_scanner_cache.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_oracle_security_fixes.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_oracle_subproject_awareness.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_oracle_ui_bundle.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_output_filter.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_permissions.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_pm_api.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_project_manager.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_project_manager_merge.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_project_tool.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_read_coercion.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_read_edit_parity.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_response_boilerplate.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_retention.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_review_digest.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_service_durability.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_session_benchmark.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_session_budget.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_shell_robustness.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_subproject_exclusion.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_subproject_federation.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_subprojects.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_swe_bench.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_task_store.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_task_tool.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_token_telemetry.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_tool_registry.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_upgrade_and_version.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_validate.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_web_security.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tests/test_windows_reliability.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/__init__.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/backend.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/main.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/screens/__init__.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/screens/benchmark_view.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/screens/compress_view.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/screens/index_view.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/screens/optimize_view.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/screens/pipe_view.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/screens/projects_view.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/screens/search_view.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/screens/session_view.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/screens/stats.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/screens/ui_view.py +0 -0
- {code_context_control-2.50.0 → code_context_control-2.52.0}/tui/theme.tcss +0 -0
{code_context_control-2.50.0/code_context_control.egg-info → code_context_control-2.52.0}/PKG-INFO
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-context-control
|
|
3
|
-
Version: 2.
|
|
4
|
-
Summary: Local code-intelligence layer for AI coding tools (Claude Code, Codex,
|
|
3
|
+
Version: 2.52.0
|
|
4
|
+
Summary: Local code-intelligence layer for AI coding tools (Claude Code, Codex, Copilot, Cursor, Antigravity). Retrieve less, read less, edit safer — and version the configs that shape your agent (CLAUDE.md, skills, hooks, MCP).
|
|
5
5
|
Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
7
7
|
Project-URL: Homepage, https://github.com/drknowhow/code-context-control
|
|
@@ -66,7 +66,7 @@ Dynamic: license-file
|
|
|
66
66
|
<p align="center">
|
|
67
67
|
<strong>The local code-intelligence layer for AI coding tools.</strong><br>
|
|
68
68
|
Stop burning tokens on whole-file reads, blind greps, and unbounded log dumps.<br>
|
|
69
|
-
Works with Claude Code, Codex,
|
|
69
|
+
Works with Claude Code, Codex, Copilot, Cursor, and Antigravity.
|
|
70
70
|
</p>
|
|
71
71
|
|
|
72
72
|
<p align="center">
|
|
@@ -100,7 +100,7 @@ A thin **local** layer that sits between your IDE and your repo. Every AI tool c
|
|
|
100
100
|
| Edit, hope it compiled | `c3_edit` writes via a ledger + `c3_validate` runs `pyright`/`tsc` automatically |
|
|
101
101
|
| `Bash` test runs that hang on Windows | `c3_shell` returns structured `{exit_code, stdout, stderr, duration}` with auto-filter |
|
|
102
102
|
| Lose all context on `/clear` | `c3_session(snapshot)` + `c3_memory` persist decisions across sessions |
|
|
103
|
-
| Re-explain the project every session | Auto-synced `CLAUDE.md` / `AGENTS.md` / `
|
|
103
|
+
| Re-explain the project every session | Auto-synced `CLAUDE.md` / `AGENTS.md` / `copilot-instructions.md` from a single source of truth |
|
|
104
104
|
|
|
105
105
|
Everything runs **locally**. No source code, prompts, or model output ever leaves your machine unless you explicitly opt into a third-party model API.
|
|
106
106
|
|
|
@@ -125,7 +125,7 @@ c3 init /path/to/your/project
|
|
|
125
125
|
```
|
|
126
126
|
|
|
127
127
|
Running `c3` with no arguments opens the interactive TUI. `c3 init` walks you through:
|
|
128
|
-
1. **IDE selection** (Claude Code CLI/App, Codex CLI,
|
|
128
|
+
1. **IDE selection** (Claude Code CLI/App, Codex CLI, VS Code, Cursor, Antigravity, or Custom — the Gemini CLI profile was removed in v2.52; use Antigravity, which reads AGENTS.md)
|
|
129
129
|
2. Optional local `git init`
|
|
130
130
|
3. MCP server registration (auto-wired into your IDE)
|
|
131
131
|
4. (Claude Code only) Permission tier selection
|
|
@@ -278,6 +278,10 @@ C3 exposes 18 tools as a native MCP server. Your IDE calls them directly:
|
|
|
278
278
|
| `c3_task` | Durable per-project tasks, milestones, and decision notes (v2.45.0) |
|
|
279
279
|
| `c3_artifacts` | Agent-config tracking — version history, diff & restore for CLAUDE.md, settings/hooks, MCP configs, skills (v2.46.0) |
|
|
280
280
|
|
|
281
|
+
On Windows, `c3_shell` uses Git Bash when available. Git Bash does not bundle
|
|
282
|
+
optional utilities such as `jq`; use `python -m json.tool` for portable JSON
|
|
283
|
+
formatting, or install `jq` separately when filter expressions are required.
|
|
284
|
+
|
|
281
285
|
Every tool is **read-only safe in plan mode** (except `c3_edit`, `c3_shell`, `c3_artifacts(action='restore')`, and write actions on `c3_bitbucket` / `c3_project` / `c3_task`).
|
|
282
286
|
|
|
283
287
|
### Bitbucket Data Center / Server (v2.30.0)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<p align="center">
|
|
4
4
|
<strong>The local code-intelligence layer for AI coding tools.</strong><br>
|
|
5
5
|
Stop burning tokens on whole-file reads, blind greps, and unbounded log dumps.<br>
|
|
6
|
-
Works with Claude Code, Codex,
|
|
6
|
+
Works with Claude Code, Codex, Copilot, Cursor, and Antigravity.
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
@@ -37,7 +37,7 @@ A thin **local** layer that sits between your IDE and your repo. Every AI tool c
|
|
|
37
37
|
| Edit, hope it compiled | `c3_edit` writes via a ledger + `c3_validate` runs `pyright`/`tsc` automatically |
|
|
38
38
|
| `Bash` test runs that hang on Windows | `c3_shell` returns structured `{exit_code, stdout, stderr, duration}` with auto-filter |
|
|
39
39
|
| Lose all context on `/clear` | `c3_session(snapshot)` + `c3_memory` persist decisions across sessions |
|
|
40
|
-
| Re-explain the project every session | Auto-synced `CLAUDE.md` / `AGENTS.md` / `
|
|
40
|
+
| Re-explain the project every session | Auto-synced `CLAUDE.md` / `AGENTS.md` / `copilot-instructions.md` from a single source of truth |
|
|
41
41
|
|
|
42
42
|
Everything runs **locally**. No source code, prompts, or model output ever leaves your machine unless you explicitly opt into a third-party model API.
|
|
43
43
|
|
|
@@ -62,7 +62,7 @@ c3 init /path/to/your/project
|
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
Running `c3` with no arguments opens the interactive TUI. `c3 init` walks you through:
|
|
65
|
-
1. **IDE selection** (Claude Code CLI/App, Codex CLI,
|
|
65
|
+
1. **IDE selection** (Claude Code CLI/App, Codex CLI, VS Code, Cursor, Antigravity, or Custom — the Gemini CLI profile was removed in v2.52; use Antigravity, which reads AGENTS.md)
|
|
66
66
|
2. Optional local `git init`
|
|
67
67
|
3. MCP server registration (auto-wired into your IDE)
|
|
68
68
|
4. (Claude Code only) Permission tier selection
|
|
@@ -215,6 +215,10 @@ C3 exposes 18 tools as a native MCP server. Your IDE calls them directly:
|
|
|
215
215
|
| `c3_task` | Durable per-project tasks, milestones, and decision notes (v2.45.0) |
|
|
216
216
|
| `c3_artifacts` | Agent-config tracking — version history, diff & restore for CLAUDE.md, settings/hooks, MCP configs, skills (v2.46.0) |
|
|
217
217
|
|
|
218
|
+
On Windows, `c3_shell` uses Git Bash when available. Git Bash does not bundle
|
|
219
|
+
optional utilities such as `jq`; use `python -m json.tool` for portable JSON
|
|
220
|
+
formatting, or install `jq` separately when filter expressions are required.
|
|
221
|
+
|
|
218
222
|
Every tool is **read-only safe in plan mode** (except `c3_edit`, `c3_shell`, `c3_artifacts(action='restore')`, and write actions on `c3_bitbucket` / `c3_project` / `c3_task`).
|
|
219
223
|
|
|
220
224
|
### Bitbucket Data Center / Server (v2.30.0)
|
|
@@ -33,6 +33,28 @@ LEGACY_UNLOCK_FILE = ".c3/unlocked_files.json"
|
|
|
33
33
|
STATE_WARNINGS: list = []
|
|
34
34
|
|
|
35
35
|
|
|
36
|
+
def ensure_utf8_stdio() -> None:
|
|
37
|
+
"""Force UTF-8 on the hook process's stdio pipes.
|
|
38
|
+
|
|
39
|
+
On Windows a hook subprocess gets cp1252 stdout/stdin (piped, non-TTY),
|
|
40
|
+
so printing user-visible text containing box-drawing chars ("─") or emoji
|
|
41
|
+
raises UnicodeEncodeError and surfaces as a "Stop hook error" in the IDE.
|
|
42
|
+
Claude Code reads hook stdout as UTF-8. Call this at the top of every
|
|
43
|
+
entrypoint that prints raw (non-json.dumps) text. Never raises.
|
|
44
|
+
"""
|
|
45
|
+
for stream in (sys.stdout, sys.stderr):
|
|
46
|
+
try:
|
|
47
|
+
if hasattr(stream, "reconfigure"):
|
|
48
|
+
stream.reconfigure(encoding="utf-8", errors="replace")
|
|
49
|
+
except Exception:
|
|
50
|
+
pass
|
|
51
|
+
try:
|
|
52
|
+
if hasattr(sys.stdin, "reconfigure"):
|
|
53
|
+
sys.stdin.reconfigure(encoding="utf-8", errors="strict")
|
|
54
|
+
except Exception:
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
|
|
36
58
|
def log_hook_error(hook_name: str, exc: BaseException) -> None:
|
|
37
59
|
"""Append a timestamped error entry to .c3/hook_errors.log.
|
|
38
60
|
|
|
@@ -60,7 +60,14 @@ from cli.commands.common import cmd_stats as common_cmd_stats
|
|
|
60
60
|
from cli.commands.common import cmd_ui as common_cmd_ui
|
|
61
61
|
from cli.commands.parser import build_parser
|
|
62
62
|
from core import count_tokens, format_token_count
|
|
63
|
-
from core.config import
|
|
63
|
+
from core.config import (
|
|
64
|
+
AGENT_DEFAULTS,
|
|
65
|
+
BITBUCKET_DEFAULTS,
|
|
66
|
+
DELEGATE_DEFAULTS,
|
|
67
|
+
MEMORY_LLM_DEFAULTS,
|
|
68
|
+
PROXY_DEFAULTS,
|
|
69
|
+
load_delegate_config,
|
|
70
|
+
)
|
|
64
71
|
from core.config import DEFAULTS as HYBRID_DEFAULTS
|
|
65
72
|
from core.ide import PROFILES, detect_ide, get_profile, load_ide_config, normalize_ide_name
|
|
66
73
|
from services.compressor import CodeCompressor
|
|
@@ -85,7 +92,7 @@ console = Console() if HAS_RICH else None
|
|
|
85
92
|
# Config
|
|
86
93
|
CONFIG_DIR = ".c3"
|
|
87
94
|
CONFIG_FILE = ".c3/config.json"
|
|
88
|
-
__version__ = "2.
|
|
95
|
+
__version__ = "2.52.0"
|
|
89
96
|
|
|
90
97
|
|
|
91
98
|
def _command_deps() -> CommandDeps:
|
|
@@ -165,6 +172,7 @@ def _build_init_config(project_path: str) -> dict:
|
|
|
165
172
|
"delegate": deepcopy(DELEGATE_DEFAULTS),
|
|
166
173
|
"agents": deepcopy(AGENT_DEFAULTS),
|
|
167
174
|
"bitbucket": deepcopy(BITBUCKET_DEFAULTS),
|
|
175
|
+
"memory_llm": deepcopy(MEMORY_LLM_DEFAULTS),
|
|
168
176
|
}
|
|
169
177
|
merged = _deep_merge_dict(defaults, existing if isinstance(existing, dict) else {})
|
|
170
178
|
# Always persist current path/version on init/update.
|
|
@@ -703,8 +711,7 @@ def _select_init_ide(default_ide: str) -> str:
|
|
|
703
711
|
"VS Code — .vscode/mcp.json + Copilot instructions",
|
|
704
712
|
"Cursor — .cursor/mcp.json",
|
|
705
713
|
"Codex — .codex/config.toml + AGENTS.md",
|
|
706
|
-
"
|
|
707
|
-
"Antigravity — ~/.gemini/antigravity/mcp_config.json",
|
|
714
|
+
"Antigravity — ~/.gemini/antigravity/mcp_config.json + AGENTS.md",
|
|
708
715
|
]
|
|
709
716
|
selected = _prompt_choice("Step 1/3 — Choose IDE profile", choices)
|
|
710
717
|
mapping = {
|
|
@@ -713,14 +720,87 @@ def _select_init_ide(default_ide: str) -> str:
|
|
|
713
720
|
choices[2]: "vscode",
|
|
714
721
|
choices[3]: "cursor",
|
|
715
722
|
choices[4]: "codex",
|
|
716
|
-
choices[5]: "
|
|
717
|
-
choices[6]: "antigravity",
|
|
723
|
+
choices[5]: "antigravity",
|
|
718
724
|
}
|
|
719
725
|
chosen = mapping.get(selected or "", normalize_ide_name(default_ide) if default_ide != "auto" else "auto")
|
|
720
726
|
print(f" IDE profile: {chosen}")
|
|
721
727
|
return chosen
|
|
722
728
|
|
|
723
729
|
|
|
730
|
+
def _prompt_memory_llm(project_path: str) -> None:
|
|
731
|
+
"""Interactive memory_llm setup: privacy-first local model + optional cloud opt-in.
|
|
732
|
+
|
|
733
|
+
Skipped entirely under --force (that path never enters _prompt_init_steps),
|
|
734
|
+
which keeps the privacy defaults: distillation on, cloud OFF.
|
|
735
|
+
"""
|
|
736
|
+
print()
|
|
737
|
+
choice = _prompt_choice(
|
|
738
|
+
"Memory — distill each session into durable project facts with an LLM?",
|
|
739
|
+
[
|
|
740
|
+
"Local only — a local Ollama model, nothing leaves this machine (recommended)",
|
|
741
|
+
"Cloud — a Sonnet-class Ollama Cloud model (API key or signed-in daemon)",
|
|
742
|
+
"Off — keep the basic pattern-based capture only",
|
|
743
|
+
],
|
|
744
|
+
)
|
|
745
|
+
if not choice:
|
|
746
|
+
return # EOF/Ctrl+C — keep defaults (local-only, cloud off)
|
|
747
|
+
|
|
748
|
+
existing = load_config(project_path).get("memory_llm")
|
|
749
|
+
section = dict(existing) if isinstance(existing, dict) else {}
|
|
750
|
+
|
|
751
|
+
if choice.startswith("Off"):
|
|
752
|
+
section["enabled"] = False
|
|
753
|
+
section["cloud_enabled"] = False
|
|
754
|
+
save_config({"memory_llm": section}, project_path)
|
|
755
|
+
print("Memory distillation: off (regex capture only).")
|
|
756
|
+
return
|
|
757
|
+
|
|
758
|
+
section["enabled"] = True
|
|
759
|
+
section["cloud_enabled"] = choice.startswith("Cloud")
|
|
760
|
+
|
|
761
|
+
# Local model pick — it is the only tier in local mode and the privacy
|
|
762
|
+
# fallback tier in cloud mode.
|
|
763
|
+
default_local = section.get("local_model") or MEMORY_LLM_DEFAULTS["local_model"]
|
|
764
|
+
models = None
|
|
765
|
+
try:
|
|
766
|
+
client = OllamaClient()
|
|
767
|
+
if client.is_available(timeout=2):
|
|
768
|
+
models = client.list_models()
|
|
769
|
+
except Exception:
|
|
770
|
+
models = None
|
|
771
|
+
if models:
|
|
772
|
+
options = [f"Keep default — {default_local}"] + [m for m in models if m != default_local][:8]
|
|
773
|
+
pick = _prompt_choice("Pick the local model for distillation:", options)
|
|
774
|
+
if pick and not pick.startswith("Keep default"):
|
|
775
|
+
section["local_model"] = pick
|
|
776
|
+
else:
|
|
777
|
+
print(f" (Local Ollama not reachable — keeping '{default_local}'; "
|
|
778
|
+
"change it later in the Settings UI.)")
|
|
779
|
+
|
|
780
|
+
if section["cloud_enabled"]:
|
|
781
|
+
if os.environ.get("OLLAMA_API_KEY"):
|
|
782
|
+
print(" Cloud key: using OLLAMA_API_KEY from the environment.")
|
|
783
|
+
else:
|
|
784
|
+
try:
|
|
785
|
+
key = input(" Paste Ollama Cloud API key (Enter to skip — a signed-in "
|
|
786
|
+
"local daemon also works): ").strip()
|
|
787
|
+
except (EOFError, KeyboardInterrupt):
|
|
788
|
+
key = ""
|
|
789
|
+
if key:
|
|
790
|
+
try:
|
|
791
|
+
from services.ollama_credentials import save_api_key
|
|
792
|
+
save_api_key(key, section.get("cloud_base_url")
|
|
793
|
+
or MEMORY_LLM_DEFAULTS["cloud_base_url"])
|
|
794
|
+
print(" Key stored in the OS keyring (never in config.json).")
|
|
795
|
+
except Exception as exc:
|
|
796
|
+
print(f" Could not store key in keyring ({exc}); "
|
|
797
|
+
"set the OLLAMA_API_KEY environment variable instead.")
|
|
798
|
+
|
|
799
|
+
save_config({"memory_llm": section}, project_path)
|
|
800
|
+
print("Memory distillation: "
|
|
801
|
+
+ ("cloud + local fallback." if section["cloud_enabled"] else "local only (private)."))
|
|
802
|
+
|
|
803
|
+
|
|
724
804
|
def _prompt_init_steps(project_path: str, ide_name: str, default_mode: str = "direct") -> tuple[str, bool]:
|
|
725
805
|
"""Run guided post-init setup steps for Git and MCP."""
|
|
726
806
|
chosen_ide = _select_init_ide(ide_name or "auto")
|
|
@@ -739,6 +819,8 @@ def _prompt_init_steps(project_path: str, ide_name: str, default_mode: str = "di
|
|
|
739
819
|
else:
|
|
740
820
|
print("Git: skipped.")
|
|
741
821
|
|
|
822
|
+
_prompt_memory_llm(project_path)
|
|
823
|
+
|
|
742
824
|
print()
|
|
743
825
|
install_choice = _prompt_choice(
|
|
744
826
|
"Step 3/3 — Install MCP tooling for this project?",
|
|
@@ -803,7 +885,7 @@ def _parse_cli_ide_arg(value: str) -> str:
|
|
|
803
885
|
normalized = normalize_ide_name(raw)
|
|
804
886
|
if normalized not in PROFILES:
|
|
805
887
|
raise argparse.ArgumentTypeError(
|
|
806
|
-
"Unsupported IDE. Use one of: auto, claude, vscode, cursor, codex,
|
|
888
|
+
"Unsupported IDE. Use one of: auto, claude, vscode, cursor, codex, antigravity."
|
|
807
889
|
)
|
|
808
890
|
return normalized
|
|
809
891
|
|
|
@@ -3929,29 +4011,6 @@ enabled = true
|
|
|
3929
4011
|
```
|
|
3930
4012
|
"""
|
|
3931
4013
|
|
|
3932
|
-
_GEMINI_MD_CONTENT = _C3_COMPACT_WORKFLOW + """
|
|
3933
|
-
|
|
3934
|
-
## IDE Configuration (Gemini CLI)
|
|
3935
|
-
This project uses project-scoped MCP servers. Ensure your `.gemini/settings.json` includes:
|
|
3936
|
-
```json
|
|
3937
|
-
{
|
|
3938
|
-
"mcpServers": {
|
|
3939
|
-
"c3": {
|
|
3940
|
-
"command": "c3-mcp",
|
|
3941
|
-
"args": ["--project", "."]
|
|
3942
|
-
}
|
|
3943
|
-
}
|
|
3944
|
-
}
|
|
3945
|
-
```
|
|
3946
|
-
|
|
3947
|
-
## Gemini Enforcement
|
|
3948
|
-
- `c3 init` and `c3 install-mcp` install this file as a required workflow, not a suggestion.
|
|
3949
|
-
- After install, use the `c3` MCP server for recall, search, structural mapping, surgical reads, filtering, and session logging before native Gemini repo exploration.
|
|
3950
|
-
- Do not bypass C3 with broad native search/read steps unless a matching `c3_*` tool failed or was too narrow for a final follow-up.
|
|
3951
|
-
- If fallback is necessary, say which `c3_*` tool was attempted or skipped and why.
|
|
3952
|
-
"""
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
4014
|
_TERSE_SKILL_CONTENT = """\
|
|
3956
4015
|
# /terse — Terse Output Mode
|
|
3957
4016
|
|
|
@@ -4029,28 +4088,16 @@ Say "normal mode", start a new session, or let the turn counter expire.
|
|
|
4029
4088
|
_TERSE_SKILL_MARKER = "# /terse — Terse Output Mode"
|
|
4030
4089
|
|
|
4031
4090
|
|
|
4032
|
-
_TERSE_GEMINI_TOML = (
|
|
4033
|
-
'description = "Terse output mode. Usage: /terse [lite|full|ultra] (default: full)."\n'
|
|
4034
|
-
"prompt = '''\n"
|
|
4035
|
-
+ _TERSE_SKILL_CONTENT.replace("'''", "''\\''")
|
|
4036
|
-
+ "\n'''\n"
|
|
4037
|
-
)
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
4091
|
def _ensure_terse_skill(ide: str = "claude-code") -> None:
|
|
4041
4092
|
"""Install the /terse slash command for the given IDE profile.
|
|
4042
4093
|
|
|
4043
4094
|
claude-code -> ~/.claude/commands/terse.md
|
|
4044
4095
|
codex -> ~/.codex/prompts/terse.md
|
|
4045
|
-
gemini -> ~/.gemini/commands/terse.toml
|
|
4046
4096
|
"""
|
|
4047
4097
|
home = Path.home()
|
|
4048
4098
|
if ide == "codex":
|
|
4049
4099
|
skill_path = home / ".codex" / "prompts" / "terse.md"
|
|
4050
4100
|
content = _TERSE_SKILL_CONTENT
|
|
4051
|
-
elif ide == "gemini":
|
|
4052
|
-
skill_path = home / ".gemini" / "commands" / "terse.toml"
|
|
4053
|
-
content = _TERSE_GEMINI_TOML
|
|
4054
4101
|
else:
|
|
4055
4102
|
skill_path = home / ".claude" / "commands" / "terse.md"
|
|
4056
4103
|
content = _TERSE_SKILL_CONTENT
|
|
@@ -4273,7 +4320,7 @@ def _upsert_json_mcp_server(config_path: Path, config_key: str, server_name: str
|
|
|
4273
4320
|
|
|
4274
4321
|
def _ensure_project_session_configs(target: Path, server_script: str, primary_profile: str | None = None,
|
|
4275
4322
|
c3_mcp_exe: str | None = None) -> None:
|
|
4276
|
-
"""Keep project-local Codex
|
|
4323
|
+
"""Keep the project-local Codex MCP config in sync for new sessions."""
|
|
4277
4324
|
# Ensure forward slashes for config portability and avoid Windows path-splitting issues
|
|
4278
4325
|
server_script_posix = Path(server_script).as_posix()
|
|
4279
4326
|
if c3_mcp_exe:
|
|
@@ -4297,26 +4344,16 @@ def _ensure_project_session_configs(target: Path, server_script: str, primary_pr
|
|
|
4297
4344
|
)
|
|
4298
4345
|
print(f"{codex_state.capitalize()} {codex_path}")
|
|
4299
4346
|
|
|
4300
|
-
if primary_profile != "gemini":
|
|
4301
|
-
gemini_path = target / ".gemini" / "settings.json"
|
|
4302
|
-
gemini_state = _upsert_json_mcp_server(
|
|
4303
|
-
gemini_path,
|
|
4304
|
-
"mcpServers",
|
|
4305
|
-
"c3",
|
|
4306
|
-
{
|
|
4307
|
-
"command": mcp_command,
|
|
4308
|
-
"args": server_args,
|
|
4309
|
-
},
|
|
4310
|
-
)
|
|
4311
|
-
print(f"{gemini_state.capitalize()} {gemini_path}")
|
|
4312
4347
|
|
|
4313
4348
|
|
|
4314
|
-
|
|
4315
|
-
|
|
4349
|
+
|
|
4350
|
+
def _ensure_global_session_fallbacks(server_script: str, c3_mcp_exe: str | None = None,
|
|
4351
|
+
primary_profile: str | None = None) -> None:
|
|
4352
|
+
"""Keep user-global Codex/Antigravity MCP configs pointing at C3.
|
|
4316
4353
|
|
|
4317
4354
|
These fallback entries omit `--project` so the MCP server can resolve the
|
|
4318
4355
|
active working directory dynamically when a session starts in a project that
|
|
4319
|
-
does not yet have project-local Codex
|
|
4356
|
+
does not yet have a project-local Codex config file.
|
|
4320
4357
|
"""
|
|
4321
4358
|
server_script_posix = Path(server_script).as_posix()
|
|
4322
4359
|
# With the installed entry point, no script path is needed; --project stays
|
|
@@ -4339,20 +4376,25 @@ def _ensure_global_session_fallbacks(server_script: str, c3_mcp_exe: str | None
|
|
|
4339
4376
|
except PermissionError:
|
|
4340
4377
|
print(f"Warning: Could not update {codex_path} (global fallback skipped)")
|
|
4341
4378
|
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4379
|
+
# Antigravity shares the ~/.gemini home dir but reads its own MCP config.
|
|
4380
|
+
# When Antigravity is the primary profile, the main install flow already
|
|
4381
|
+
# wrote this file — here we only keep it fresh for codex installs
|
|
4382
|
+
# on machines that have Antigravity (its config dir exists).
|
|
4383
|
+
antigravity_path = Path.home() / ".gemini" / "antigravity" / "mcp_config.json"
|
|
4384
|
+
if primary_profile != "antigravity" and antigravity_path.parent.is_dir():
|
|
4385
|
+
try:
|
|
4386
|
+
ag_state = _upsert_json_mcp_server(
|
|
4387
|
+
antigravity_path,
|
|
4388
|
+
"mcpServers",
|
|
4389
|
+
"c3",
|
|
4390
|
+
{
|
|
4391
|
+
"command": c3_mcp_exe or sys.executable,
|
|
4392
|
+
"args": fallback_args,
|
|
4393
|
+
},
|
|
4394
|
+
)
|
|
4395
|
+
print(f"{ag_state.capitalize()} {antigravity_path} (global fallback)")
|
|
4396
|
+
except PermissionError:
|
|
4397
|
+
print(f"Warning: Could not update {antigravity_path} (global fallback skipped)")
|
|
4356
4398
|
|
|
4357
4399
|
|
|
4358
4400
|
def _uninstall_mcp_all(project_path: str):
|
|
@@ -4390,8 +4432,8 @@ def _uninstall_mcp_all(project_path: str):
|
|
|
4390
4432
|
config_paths.append(Path.home() / profile.config_path)
|
|
4391
4433
|
else:
|
|
4392
4434
|
config_paths.append(target / profile.config_path)
|
|
4393
|
-
# For Codex
|
|
4394
|
-
if ide_name
|
|
4435
|
+
# For Codex, also check the global fallback in home dir
|
|
4436
|
+
if ide_name == "codex":
|
|
4395
4437
|
config_paths.append(Path.home() / profile.config_path)
|
|
4396
4438
|
|
|
4397
4439
|
for mcp_config_path in config_paths:
|
|
@@ -4513,6 +4555,22 @@ def _uninstall_mcp_all(project_path: str):
|
|
|
4513
4555
|
except Exception as e:
|
|
4514
4556
|
print(f" Warning: Could not update {vscode_settings_path}: {e}")
|
|
4515
4557
|
|
|
4558
|
+
# Legacy Gemini CLI configs (profile removed in v2.52) — still strip the c3 entry.
|
|
4559
|
+
for legacy_cfg in (target / ".gemini" / "settings.json",
|
|
4560
|
+
Path.home() / ".gemini" / "settings.json"):
|
|
4561
|
+
if not legacy_cfg.exists():
|
|
4562
|
+
continue
|
|
4563
|
+
try:
|
|
4564
|
+
with open(legacy_cfg, encoding="utf-8") as f:
|
|
4565
|
+
legacy_data = json.load(f)
|
|
4566
|
+
if "c3" in (legacy_data.get("mcpServers") or {}):
|
|
4567
|
+
del legacy_data["mcpServers"]["c3"]
|
|
4568
|
+
with open(legacy_cfg, "w", encoding="utf-8") as f:
|
|
4569
|
+
json.dump(legacy_data, f, indent=2)
|
|
4570
|
+
print(f" Removed C3 from {legacy_cfg}")
|
|
4571
|
+
except Exception as e:
|
|
4572
|
+
print(f" Warning: Could not update {legacy_cfg}: {e}")
|
|
4573
|
+
|
|
4516
4574
|
# Final pass: clean up empty IDE directories (.claude, .codex, .gemini, .vscode, .github)
|
|
4517
4575
|
dirs_to_check = [".claude", ".codex", ".gemini", ".vscode", ".github"]
|
|
4518
4576
|
for dname in dirs_to_check:
|
|
@@ -4631,11 +4689,27 @@ def _ensure_global_claude_md() -> None:
|
|
|
4631
4689
|
|
|
4632
4690
|
|
|
4633
4691
|
def _instruction_documents_for_project() -> list[tuple[str, str]]:
|
|
4634
|
-
"""Return
|
|
4692
|
+
"""Return every project-local instruction document C3 has ever managed.
|
|
4693
|
+
|
|
4694
|
+
Used by uninstall/cleanup paths, so it must keep listing legacy docs
|
|
4695
|
+
(GEMINI.md — profile removed in v2.52; empty template, never generated).
|
|
4696
|
+
"""
|
|
4635
4697
|
return [
|
|
4636
4698
|
("CLAUDE.md", _CLAUDE_MD_CONTENT),
|
|
4637
4699
|
("AGENTS.md", _AGENTS_MD_CONTENT),
|
|
4638
|
-
("GEMINI.md",
|
|
4700
|
+
("GEMINI.md", ""),
|
|
4701
|
+
]
|
|
4702
|
+
|
|
4703
|
+
|
|
4704
|
+
_LEGACY_INSTRUCTION_DOCS = ("GEMINI.md",) # Gemini CLI profile removed in v2.52
|
|
4705
|
+
|
|
4706
|
+
|
|
4707
|
+
def _instruction_documents_to_generate() -> list[tuple[str, str]]:
|
|
4708
|
+
"""Instruction docs to write for a project (legacy docs excluded)."""
|
|
4709
|
+
return [
|
|
4710
|
+
(name, template)
|
|
4711
|
+
for name, template in _instruction_documents_for_project()
|
|
4712
|
+
if name not in _LEGACY_INSTRUCTION_DOCS
|
|
4639
4713
|
]
|
|
4640
4714
|
|
|
4641
4715
|
|
|
@@ -4643,7 +4717,7 @@ def _sync_project_instruction_docs(project_path: str, sm: SessionManager) -> Non
|
|
|
4643
4717
|
"""Write the current C3 instruction docs into the project root."""
|
|
4644
4718
|
repo_root = Path(__file__).resolve().parent.parent
|
|
4645
4719
|
synced: list[str] = []
|
|
4646
|
-
for instructions_file, template in
|
|
4720
|
+
for instructions_file, template in _instruction_documents_to_generate():
|
|
4647
4721
|
print(f"Generating {instructions_file}...")
|
|
4648
4722
|
# Resolve placeholder for project-scoped MCP configs
|
|
4649
4723
|
resolved_template = template.replace("<path-to-c3>", str(repo_root).replace("\\", "/"))
|
|
@@ -4909,8 +4983,8 @@ def cmd_install_mcp(args):
|
|
|
4909
4983
|
if _found:
|
|
4910
4984
|
c3_mcp_exe = Path(_found).resolve().as_posix()
|
|
4911
4985
|
|
|
4912
|
-
#
|
|
4913
|
-
#
|
|
4986
|
+
# Keep the script path as a single arg; 'python' keeps the source fallback
|
|
4987
|
+
# portable across platforms.
|
|
4914
4988
|
if c3_mcp_exe:
|
|
4915
4989
|
new_entry = {"command": c3_mcp_exe, "args": ["--project", "."]}
|
|
4916
4990
|
else:
|
|
@@ -4985,9 +5059,9 @@ def cmd_install_mcp(args):
|
|
|
4985
5059
|
# instead of letting it surface as anonymous out-of-band drift.
|
|
4986
5060
|
from services.artifact_defs import note_pending_write
|
|
4987
5061
|
note_pending_write(target, profile.config_path, "install_mcp")
|
|
4988
|
-
if profile.name in {"codex", "
|
|
5062
|
+
if profile.name in {"codex", "antigravity"}:
|
|
4989
5063
|
_ensure_project_session_configs(target, server_script, primary_profile=profile.name, c3_mcp_exe=c3_mcp_exe)
|
|
4990
|
-
_ensure_global_session_fallbacks(server_script, c3_mcp_exe=c3_mcp_exe)
|
|
5064
|
+
_ensure_global_session_fallbacks(server_script, c3_mcp_exe=c3_mcp_exe, primary_profile=profile.name)
|
|
4991
5065
|
|
|
4992
5066
|
# ── Persist IDE choice to .c3/config.json ──
|
|
4993
5067
|
c3_config_dir = target / ".c3"
|
|
@@ -5001,7 +5075,7 @@ def cmd_install_mcp(args):
|
|
|
5001
5075
|
with open(c3_config_path, 'w', encoding="utf-8") as f:
|
|
5002
5076
|
json.dump(c3_config, f, indent=2)
|
|
5003
5077
|
|
|
5004
|
-
# ── Install hooks (Claude Code
|
|
5078
|
+
# ── Install hooks (Claude Code) ──
|
|
5005
5079
|
if profile.supports_hooks and profile.settings_path:
|
|
5006
5080
|
settings_dir = target / Path(profile.settings_path).parent
|
|
5007
5081
|
settings_dir.mkdir(parents=True, exist_ok=True)
|
|
@@ -5030,27 +5104,17 @@ def cmd_install_mcp(args):
|
|
|
5030
5104
|
hook_pretool_cmd = f"{_dispatch_base} pretool"
|
|
5031
5105
|
hook_posttool_cmd = f"{_dispatch_base} posttool"
|
|
5032
5106
|
hook_stop_cmd = f"{_dispatch_base} stop"
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
else:
|
|
5045
|
-
shell_matcher = "Bash"
|
|
5046
|
-
read_matcher = "Read"
|
|
5047
|
-
grep_matcher = "Grep"
|
|
5048
|
-
glob_matcher = "Glob"
|
|
5049
|
-
edit_matcher = "Edit"
|
|
5050
|
-
write_matcher = "Write"
|
|
5051
|
-
# Claude Code also exposes MultiEdit (batch edits) and NotebookEdit;
|
|
5052
|
-
# both bypass enforcement/logging unless their matchers are registered.
|
|
5053
|
-
extra_edit_matchers = ["MultiEdit", "NotebookEdit"]
|
|
5107
|
+
hook_prompt_cmd = f"{_dispatch_base} prompt"
|
|
5108
|
+
|
|
5109
|
+
shell_matcher = "Bash"
|
|
5110
|
+
read_matcher = "Read"
|
|
5111
|
+
grep_matcher = "Grep"
|
|
5112
|
+
glob_matcher = "Glob"
|
|
5113
|
+
edit_matcher = "Edit"
|
|
5114
|
+
write_matcher = "Write"
|
|
5115
|
+
# Claude Code also exposes MultiEdit (batch edits) and NotebookEdit;
|
|
5116
|
+
# both bypass enforcement/logging unless their matchers are registered.
|
|
5117
|
+
extra_edit_matchers = ["MultiEdit", "NotebookEdit"]
|
|
5054
5118
|
|
|
5055
5119
|
# ── PostToolUse hooks ──
|
|
5056
5120
|
# Matcher set is unchanged from pre-v2.42; every matcher now points at
|
|
@@ -5108,8 +5172,7 @@ def cmd_install_mcp(args):
|
|
|
5108
5172
|
existing_post.extend(desired_post_hooks)
|
|
5109
5173
|
settings.setdefault("hooks", {})[hook_event] = existing_post
|
|
5110
5174
|
|
|
5111
|
-
|
|
5112
|
-
pre_event = "BeforeTool" if profile.name == "gemini" else "PreToolUse"
|
|
5175
|
+
pre_event = "PreToolUse"
|
|
5113
5176
|
pre_matchers = {h.get("matcher") for h in desired_pre_hooks}
|
|
5114
5177
|
existing_pre = [
|
|
5115
5178
|
h for h in settings.get("hooks", {}).get(pre_event, [])
|
|
@@ -5119,7 +5182,6 @@ def cmd_install_mcp(args):
|
|
|
5119
5182
|
settings.setdefault("hooks", {})[pre_event] = existing_pre
|
|
5120
5183
|
|
|
5121
5184
|
# ── Stop hooks (auto-snapshot + session stats on session end / Ctrl+C) ──
|
|
5122
|
-
# Stop hooks fire for both Claude Code ("Stop") and Gemini ("Stop").
|
|
5123
5185
|
desired_stop_hooks = [
|
|
5124
5186
|
{
|
|
5125
5187
|
"matcher": "",
|
|
@@ -5153,6 +5215,27 @@ def cmd_install_mcp(args):
|
|
|
5153
5215
|
existing_stop.extend(desired_stop_hooks)
|
|
5154
5216
|
settings.setdefault("hooks", {})[stop_event] = existing_stop
|
|
5155
5217
|
|
|
5218
|
+
# ── UserPromptSubmit hook (per-prompt project-memory injection) ──
|
|
5219
|
+
# Same merge discipline as Stop: replace only C3's own entries
|
|
5220
|
+
# (identified by the dispatcher script in the command), keep
|
|
5221
|
+
# user-added ones.
|
|
5222
|
+
prompt_event = "UserPromptSubmit"
|
|
5223
|
+
|
|
5224
|
+
def _is_c3_prompt_hook(entry: dict) -> bool:
|
|
5225
|
+
return any(
|
|
5226
|
+
"hook_dispatch.py" in (hk.get("command") or "")
|
|
5227
|
+
for hk in entry.get("hooks", [])
|
|
5228
|
+
)
|
|
5229
|
+
|
|
5230
|
+
existing_prompt = [
|
|
5231
|
+
h for h in settings.get("hooks", {}).get(prompt_event, [])
|
|
5232
|
+
if not _is_c3_prompt_hook(h)
|
|
5233
|
+
]
|
|
5234
|
+
existing_prompt.append(
|
|
5235
|
+
{"matcher": "", "hooks": [{"type": "command", "command": hook_prompt_cmd}]}
|
|
5236
|
+
)
|
|
5237
|
+
settings.setdefault("hooks", {})[prompt_event] = existing_prompt
|
|
5238
|
+
|
|
5156
5239
|
# Claude Code only: enable MCP server prompt settings
|
|
5157
5240
|
if profile.name == "claude-code":
|
|
5158
5241
|
settings["enableAllProjectMcpServers"] = True
|
|
@@ -5257,20 +5340,6 @@ def cmd_install_mcp(args):
|
|
|
5257
5340
|
print(f"Warning: {global_codex_cfg} has [mcp_servers.c3] enabled = false.")
|
|
5258
5341
|
print(" This can make C3 look disabled. Set it to true or remove that global c3 section.")
|
|
5259
5342
|
|
|
5260
|
-
# ── Gemini settings.json enforcement file ──────────────────
|
|
5261
|
-
if profile.name == "gemini":
|
|
5262
|
-
# Warn about a common conflict: global Gemini config pointing elsewhere.
|
|
5263
|
-
global_gemini_cfg = Path.home() / ".gemini" / "settings.json"
|
|
5264
|
-
if global_gemini_cfg.exists():
|
|
5265
|
-
try:
|
|
5266
|
-
with open(global_gemini_cfg, 'r', encoding="utf-8") as f:
|
|
5267
|
-
g_data = json.load(f)
|
|
5268
|
-
if "mcpServers" in g_data and "c3" in g_data["mcpServers"]:
|
|
5269
|
-
print(f"Note: Global config {global_gemini_cfg} also defines 'c3'.")
|
|
5270
|
-
print(" The project-local config at .gemini/settings.json should take precedence.")
|
|
5271
|
-
except Exception:
|
|
5272
|
-
pass
|
|
5273
|
-
|
|
5274
5343
|
_sync_project_instruction_docs(str(target), sm)
|
|
5275
5344
|
|
|
5276
5345
|
# ── User-global C3 enforcement ──────────────────────────────
|
|
@@ -5280,7 +5349,7 @@ def cmd_install_mcp(args):
|
|
|
5280
5349
|
print(f"Warning: Could not update global CLAUDE.md: {e}")
|
|
5281
5350
|
|
|
5282
5351
|
# ── Install /terse skill for supported IDEs ──────────────────
|
|
5283
|
-
if profile.name in ("claude-code", "codex"
|
|
5352
|
+
if profile.name in ("claude-code", "codex"):
|
|
5284
5353
|
try:
|
|
5285
5354
|
_ensure_terse_skill(profile.name)
|
|
5286
5355
|
except Exception as e:
|
|
@@ -21,7 +21,7 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
21
21
|
p_init.add_argument("project_path", nargs="?", default=".")
|
|
22
22
|
p_init.add_argument("--force", action="store_true", help="Skip prompts and apply update non-interactively")
|
|
23
23
|
p_init.add_argument("--clear", action="store_true", help="Remove all C3 files and exit without rebuilding")
|
|
24
|
-
p_init.add_argument("--ide", default="auto", type=parse_cli_ide_arg, metavar="{auto,claude,vscode,cursor,codex,
|
|
24
|
+
p_init.add_argument("--ide", default="auto", type=parse_cli_ide_arg, metavar="{auto,claude,vscode,cursor,codex,antigravity}", help="Target IDE for MCP config (default: auto-detect)")
|
|
25
25
|
p_init.add_argument("--mcp-mode", choices=["direct", "proxy"], default="direct", help="Default MCP mode if install is selected during init (default: direct)")
|
|
26
26
|
p_init.add_argument("--git", action="store_true", help="Initialize a local Git repository during init/update")
|
|
27
27
|
p_init.add_argument("--permissions", choices=["read-only", "c3-strict", "standard", "permissive"], default=None, help="Apply Claude Code permission tier (Claude Code only, used with --force)")
|
|
@@ -93,14 +93,14 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
93
93
|
|
|
94
94
|
p_install_mcp = subparsers.add_parser("install-mcp", help="Generate MCP config for your IDE")
|
|
95
95
|
p_install_mcp.add_argument("targets", nargs="*", help="Optional project path and/or IDE shorthand (for example: `claude` or `. codex`)")
|
|
96
|
-
p_install_mcp.add_argument("--ide", default="auto", type=parse_cli_ide_arg, metavar="{auto,claude,vscode,cursor,codex,
|
|
96
|
+
p_install_mcp.add_argument("--ide", default="auto", type=parse_cli_ide_arg, metavar="{auto,claude,vscode,cursor,codex,antigravity}", help="Target IDE (default: auto-detect)")
|
|
97
97
|
p_install_mcp.add_argument("--mcp-mode", choices=["direct", "proxy"], default="direct", help="MCP entrypoint mode (default: direct)")
|
|
98
98
|
p_install_mcp.add_argument("--permissions", choices=["read-only", "c3-strict", "standard", "permissive"], default=None, help="Apply Claude Code permission tier (Claude Code only)")
|
|
99
99
|
p_install_mcp.add_argument("--include-mcp-wildcard", action="store_true", help="Add mcp__* wildcard so non-C3 MCP servers don't prompt per-call")
|
|
100
100
|
|
|
101
101
|
p_mcp_install = subparsers.add_parser("mcp-install", help="Alias for install-mcp")
|
|
102
102
|
p_mcp_install.add_argument("targets", nargs="*", help="Optional project path and/or IDE shorthand")
|
|
103
|
-
p_mcp_install.add_argument("--ide", default="auto", type=parse_cli_ide_arg, metavar="{auto,claude,vscode,cursor,codex,
|
|
103
|
+
p_mcp_install.add_argument("--ide", default="auto", type=parse_cli_ide_arg, metavar="{auto,claude,vscode,cursor,codex,antigravity}", help="Target IDE (default: auto-detect)")
|
|
104
104
|
p_mcp_install.add_argument("--mcp-mode", choices=["direct", "proxy"], default="direct", help="MCP entrypoint mode (default: direct)")
|
|
105
105
|
p_mcp_install.add_argument("--permissions", choices=["read-only", "c3-strict", "standard", "permissive"], default=None, help="Apply Claude Code permission tier (Claude Code only)")
|
|
106
106
|
p_mcp_install.add_argument("--include-mcp-wildcard", action="store_true", help="Add mcp__* wildcard so non-C3 MCP servers don't prompt per-call")
|