code-context-control 2.34.0__tar.gz → 2.36.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.
Files changed (214) hide show
  1. {code_context_control-2.34.0 → code_context_control-2.36.0}/PKG-INFO +30 -7
  2. {code_context_control-2.34.0 → code_context_control-2.36.0}/README.md +29 -6
  3. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/c3.py +172 -24
  4. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/commands/parser.py +4 -0
  5. code_context_control-2.36.0/cli/guide/bitbucket.html +527 -0
  6. code_context_control-2.36.0/cli/guide/getting-started.html +441 -0
  7. code_context_control-2.36.0/cli/guide/index.html +611 -0
  8. code_context_control-2.36.0/cli/guide/oracle.html +385 -0
  9. code_context_control-2.36.0/cli/guide/shared.css +637 -0
  10. code_context_control-2.36.0/cli/guide/tools.html +1204 -0
  11. code_context_control-2.36.0/cli/guide/workflow.html +1193 -0
  12. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/hub_server.py +10 -0
  13. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/mcp_server.py +4 -3
  14. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/server.py +11 -1
  15. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/edits.py +7 -2
  16. {code_context_control-2.34.0 → code_context_control-2.36.0}/code_context_control.egg-info/PKG-INFO +30 -7
  17. {code_context_control-2.34.0 → code_context_control-2.36.0}/code_context_control.egg-info/SOURCES.txt +11 -0
  18. {code_context_control-2.34.0 → code_context_control-2.36.0}/core/config.py +6 -0
  19. {code_context_control-2.34.0 → code_context_control-2.36.0}/pyproject.toml +9 -3
  20. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/agents.py +250 -0
  21. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/context_snapshot.py +37 -0
  22. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/edit_ledger.py +24 -26
  23. code_context_control-2.36.0/services/git_context.py +243 -0
  24. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/session_manager.py +17 -0
  25. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/version_tracker.py +8 -16
  26. code_context_control-2.36.0/tests/test_git_branch_awareness.py +162 -0
  27. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_hub_server_smoke.py +20 -0
  28. code_context_control-2.36.0/tests/test_install_mcp_entrypoint.py +74 -0
  29. code_context_control-2.36.0/tests/test_upgrade_and_version.py +114 -0
  30. {code_context_control-2.34.0 → code_context_control-2.36.0}/LICENSE +0 -0
  31. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/__init__.py +0 -0
  32. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/_hook_utils.py +0 -0
  33. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/commands/__init__.py +0 -0
  34. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/commands/common.py +0 -0
  35. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/docs.html +0 -0
  36. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/edits.html +0 -0
  37. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/hook_auto_snapshot.py +0 -0
  38. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/hook_c3_signal.py +0 -0
  39. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/hook_c3read.py +0 -0
  40. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/hook_edit_ledger.py +0 -0
  41. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/hook_edit_unlock.py +0 -0
  42. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/hook_filter.py +0 -0
  43. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/hook_ghost_files.py +0 -0
  44. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/hook_pretool_enforce.py +0 -0
  45. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/hook_read.py +0 -0
  46. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/hook_session_stats.py +0 -0
  47. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/hook_terse_advisor.py +0 -0
  48. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/hub.html +0 -0
  49. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/mcp_proxy.py +0 -0
  50. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/__init__.py +0 -0
  51. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/_helpers.py +0 -0
  52. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/agent.py +0 -0
  53. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/bitbucket.py +0 -0
  54. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/compress.py +0 -0
  55. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/delegate.py +0 -0
  56. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/edit.py +0 -0
  57. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/filter.py +0 -0
  58. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/impact.py +0 -0
  59. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/memory.py +0 -0
  60. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/project.py +0 -0
  61. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/read.py +0 -0
  62. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/search.py +0 -0
  63. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/session.py +0 -0
  64. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/shell.py +0 -0
  65. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/status.py +0 -0
  66. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/tools/validate.py +0 -0
  67. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/ui/api.js +0 -0
  68. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/ui/app.js +0 -0
  69. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/ui/components/bitbucket.js +0 -0
  70. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/ui/components/chat.js +0 -0
  71. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/ui/components/dashboard.js +0 -0
  72. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/ui/components/edits.js +0 -0
  73. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/ui/components/instructions.js +0 -0
  74. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/ui/components/memory.js +0 -0
  75. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/ui/components/sessions.js +0 -0
  76. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/ui/components/settings.js +0 -0
  77. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/ui/components/sidebar.js +0 -0
  78. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/ui/icons.js +0 -0
  79. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/ui/shared.js +0 -0
  80. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/ui/theme.js +0 -0
  81. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/ui.html +0 -0
  82. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/ui_legacy.html +0 -0
  83. {code_context_control-2.34.0 → code_context_control-2.36.0}/cli/ui_nano.html +0 -0
  84. {code_context_control-2.34.0 → code_context_control-2.36.0}/code_context_control.egg-info/dependency_links.txt +0 -0
  85. {code_context_control-2.34.0 → code_context_control-2.36.0}/code_context_control.egg-info/entry_points.txt +0 -0
  86. {code_context_control-2.34.0 → code_context_control-2.36.0}/code_context_control.egg-info/requires.txt +0 -0
  87. {code_context_control-2.34.0 → code_context_control-2.36.0}/code_context_control.egg-info/top_level.txt +0 -0
  88. {code_context_control-2.34.0 → code_context_control-2.36.0}/core/__init__.py +0 -0
  89. {code_context_control-2.34.0 → code_context_control-2.36.0}/core/ide.py +0 -0
  90. {code_context_control-2.34.0 → code_context_control-2.36.0}/core/mcp_toml.py +0 -0
  91. {code_context_control-2.34.0 → code_context_control-2.36.0}/core/web_security.py +0 -0
  92. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/__init__.py +0 -0
  93. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/config.py +0 -0
  94. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/mcp_oracle.py +0 -0
  95. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/oracle.html +0 -0
  96. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/oracle_server.py +0 -0
  97. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/services/__init__.py +0 -0
  98. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/services/api_auth.py +0 -0
  99. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/services/c3_bridge.py +0 -0
  100. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/services/chat_engine.py +0 -0
  101. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/services/chat_store.py +0 -0
  102. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/services/cross_memory.py +0 -0
  103. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/services/federated_graph.py +0 -0
  104. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/services/health_checker.py +0 -0
  105. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/services/insight_engine.py +0 -0
  106. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/services/memory_reader.py +0 -0
  107. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/services/memory_writer.py +0 -0
  108. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/services/ollama_bridge.py +0 -0
  109. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/services/project_scanner.py +0 -0
  110. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/services/review_agent.py +0 -0
  111. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/services/tool_executor.py +0 -0
  112. {code_context_control-2.34.0 → code_context_control-2.36.0}/oracle/services/tool_registry.py +0 -0
  113. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/__init__.py +0 -0
  114. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/activity_log.py +0 -0
  115. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/agent_base.py +0 -0
  116. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/auto_memory.py +0 -0
  117. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/bench/__init__.py +0 -0
  118. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/bench/external/__init__.py +0 -0
  119. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/bench/external/aider_polyglot.py +0 -0
  120. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/bench/external/swe_bench.py +0 -0
  121. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/benchmark_dashboard.py +0 -0
  122. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/bitbucket_client.py +0 -0
  123. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/bitbucket_credentials.py +0 -0
  124. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/claude_md.py +0 -0
  125. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/compressor.py +0 -0
  126. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/conversation_store.py +0 -0
  127. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/doc_index.py +0 -0
  128. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/e2e_benchmark.py +0 -0
  129. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/e2e_evaluator.py +0 -0
  130. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/e2e_tasks.py +0 -0
  131. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/embedding_index.py +0 -0
  132. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/error_reporting.py +0 -0
  133. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/file_memory.py +0 -0
  134. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/hub_service.py +0 -0
  135. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/indexer.py +0 -0
  136. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/memory.py +0 -0
  137. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/memory_consolidator.py +0 -0
  138. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/memory_graph.py +0 -0
  139. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/memory_grounder.py +0 -0
  140. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/memory_scorer.py +0 -0
  141. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/metrics.py +0 -0
  142. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/notifications.py +0 -0
  143. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/ollama_client.py +0 -0
  144. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/output_filter.py +0 -0
  145. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/parser.py +0 -0
  146. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/project_manager.py +0 -0
  147. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/project_runtime.py +0 -0
  148. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/protocol.py +0 -0
  149. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/proxy_state.py +0 -0
  150. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/retrieval_broker.py +0 -0
  151. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/router.py +0 -0
  152. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/runtime.py +0 -0
  153. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/session_benchmark.py +0 -0
  154. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/session_preloader.py +0 -0
  155. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/text_index.py +0 -0
  156. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/tool_classifier.py +0 -0
  157. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/transcript_index.py +0 -0
  158. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/validation_cache.py +0 -0
  159. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/vector_store.py +0 -0
  160. {code_context_control-2.34.0 → code_context_control-2.36.0}/services/watcher.py +0 -0
  161. {code_context_control-2.34.0 → code_context_control-2.36.0}/setup.cfg +0 -0
  162. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_aider_polyglot.py +0 -0
  163. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_bitbucket_cli_smoke.py +0 -0
  164. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_bitbucket_client.py +0 -0
  165. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_bitbucket_credentials.py +0 -0
  166. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_bitbucket_tool.py +0 -0
  167. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_c3_shell.py +0 -0
  168. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_cli_smoke.py +0 -0
  169. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_e2e_benchmark.py +0 -0
  170. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_edit_normalization.py +0 -0
  171. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_enforcement_flip.py +0 -0
  172. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_federated_graph.py +0 -0
  173. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_ghost_files.py +0 -0
  174. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_mcp_host_guard.py +0 -0
  175. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_mcp_server_smoke.py +0 -0
  176. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_mcp_toml.py +0 -0
  177. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_memory_graph_api.py +0 -0
  178. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_memory_system.py +0 -0
  179. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_notification_discipline.py +0 -0
  180. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_oracle_api_auth.py +0 -0
  181. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_oracle_apikey_api.py +0 -0
  182. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_oracle_discovery_api.py +0 -0
  183. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_output_filter.py +0 -0
  184. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_permissions.py +0 -0
  185. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_project_manager.py +0 -0
  186. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_project_manager_merge.py +0 -0
  187. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_project_tool.py +0 -0
  188. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_read_coercion.py +0 -0
  189. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_session_benchmark.py +0 -0
  190. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_session_budget.py +0 -0
  191. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_shell_robustness.py +0 -0
  192. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_swe_bench.py +0 -0
  193. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_tool_registry.py +0 -0
  194. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_validate.py +0 -0
  195. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_web_security.py +0 -0
  196. {code_context_control-2.34.0 → code_context_control-2.36.0}/tests/test_windows_reliability.py +0 -0
  197. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/__init__.py +0 -0
  198. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/backend.py +0 -0
  199. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/main.py +0 -0
  200. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/screens/__init__.py +0 -0
  201. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/screens/benchmark_view.py +0 -0
  202. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/screens/claudemd_view.py +0 -0
  203. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/screens/compress_view.py +0 -0
  204. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/screens/index_view.py +0 -0
  205. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/screens/init_view.py +0 -0
  206. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/screens/mcp_view.py +0 -0
  207. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/screens/optimize_view.py +0 -0
  208. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/screens/pipe_view.py +0 -0
  209. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/screens/projects_view.py +0 -0
  210. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/screens/search_view.py +0 -0
  211. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/screens/session_view.py +0 -0
  212. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/screens/stats.py +0 -0
  213. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/screens/ui_view.py +0 -0
  214. {code_context_control-2.34.0 → code_context_control-2.36.0}/tui/theme.tcss +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-context-control
3
- Version: 2.34.0
3
+ Version: 2.36.0
4
4
  Summary: Local code-intelligence layer for AI coding tools (Claude Code, Codex, Gemini, Copilot). Retrieve less, read less, edit safer.
5
5
  Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -106,14 +106,23 @@ Everything runs **locally**. No source code, prompts, or model output ever leave
106
106
 
107
107
  ## Install
108
108
 
109
- Requires Python 3.10+.
109
+ Requires Python 3.10+. No clone needed — C3 is published on PyPI.
110
+
111
+ The recommended install is [pipx](https://pipx.pypa.io) (isolated environment, on your PATH):
112
+
113
+ ```bash
114
+ pipx install code-context-control
115
+ c3 init /path/to/your/project
116
+ ```
117
+
118
+ Or with pip:
110
119
 
111
120
  ```bash
112
- pip install code-context-control
121
+ pip install "code-context-control[tui]" # [tui] adds the optional Textual UI
113
122
  c3 init /path/to/your/project
114
123
  ```
115
124
 
116
- The interactive setup walks you through:
125
+ Running `c3` with no arguments opens the interactive TUI. `c3 init` walks you through:
117
126
  1. **IDE selection** (Claude Code CLI/App, Codex CLI, Gemini CLI, VS Code, Cursor, Antigravity, or Custom)
118
127
  2. Optional local `git init`
119
128
  3. MCP server registration (auto-wired into your IDE)
@@ -125,12 +134,26 @@ Headless / scripted install:
125
134
  c3 init /path/to/project --force --ide claude --mcp-mode direct --permissions standard
126
135
  ```
127
136
 
128
- Or install from source:
137
+ ### Upgrading
138
+
139
+ ```bash
140
+ c3 upgrade # upgrade the running install in place
141
+ c3 upgrade --check # just report whether a newer release exists
142
+ # equivalently:
143
+ pipx upgrade code-context-control
144
+ pip install -U code-context-control
145
+ ```
146
+
147
+ MCP is wired through the `c3-mcp` entry point, so upgrading needs **no per-project
148
+ reconfiguration** — your existing `.mcp.json` files keep working. C3 also nudges you
149
+ in-app when a newer release is available.
150
+
151
+ ### From source (contributors)
129
152
 
130
153
  ```bash
131
154
  git clone https://github.com/drknowhow/code-context-control.git
132
155
  cd code-context-control
133
- pip install .[tui] # add the optional Textual TUI
156
+ pip install -e ".[dev]" # editable dev install: tests, linters, build tools
134
157
  ```
135
158
 
136
159
  ---
@@ -245,7 +268,7 @@ C3 exposes 16 tools as a native MCP server. Your IDE calls them directly:
245
268
  | `c3_impact` | Blast-radius analysis before edits to shared symbols |
246
269
  | `c3_delegate` | Offload heavy work to local Ollama / Codex / Gemini / etc. |
247
270
  | `c3_agent` | Multi-step agentic workflows (review, investigate, refactor) |
248
- | `c3_edits` | Edit-ledger queries + version diffs + restore points |
271
+ | `c3_edits` | Edit-ledger queries + version diffs + restore points + per-branch filter |
249
272
  | `c3_bitbucket` | Bitbucket Data Center integration — PRs, branches, builds, repo admin (v2.30.0) |
250
273
  | `c3_project` | Cross-project — discover & operate on other c3-installed projects; guarded writes (v2.31.0) |
251
274
 
@@ -44,14 +44,23 @@ Everything runs **locally**. No source code, prompts, or model output ever leave
44
44
 
45
45
  ## Install
46
46
 
47
- Requires Python 3.10+.
47
+ Requires Python 3.10+. No clone needed — C3 is published on PyPI.
48
+
49
+ The recommended install is [pipx](https://pipx.pypa.io) (isolated environment, on your PATH):
50
+
51
+ ```bash
52
+ pipx install code-context-control
53
+ c3 init /path/to/your/project
54
+ ```
55
+
56
+ Or with pip:
48
57
 
49
58
  ```bash
50
- pip install code-context-control
59
+ pip install "code-context-control[tui]" # [tui] adds the optional Textual UI
51
60
  c3 init /path/to/your/project
52
61
  ```
53
62
 
54
- The interactive setup walks you through:
63
+ Running `c3` with no arguments opens the interactive TUI. `c3 init` walks you through:
55
64
  1. **IDE selection** (Claude Code CLI/App, Codex CLI, Gemini CLI, VS Code, Cursor, Antigravity, or Custom)
56
65
  2. Optional local `git init`
57
66
  3. MCP server registration (auto-wired into your IDE)
@@ -63,12 +72,26 @@ Headless / scripted install:
63
72
  c3 init /path/to/project --force --ide claude --mcp-mode direct --permissions standard
64
73
  ```
65
74
 
66
- Or install from source:
75
+ ### Upgrading
76
+
77
+ ```bash
78
+ c3 upgrade # upgrade the running install in place
79
+ c3 upgrade --check # just report whether a newer release exists
80
+ # equivalently:
81
+ pipx upgrade code-context-control
82
+ pip install -U code-context-control
83
+ ```
84
+
85
+ MCP is wired through the `c3-mcp` entry point, so upgrading needs **no per-project
86
+ reconfiguration** — your existing `.mcp.json` files keep working. C3 also nudges you
87
+ in-app when a newer release is available.
88
+
89
+ ### From source (contributors)
67
90
 
68
91
  ```bash
69
92
  git clone https://github.com/drknowhow/code-context-control.git
70
93
  cd code-context-control
71
- pip install .[tui] # add the optional Textual TUI
94
+ pip install -e ".[dev]" # editable dev install: tests, linters, build tools
72
95
  ```
73
96
 
74
97
  ---
@@ -183,7 +206,7 @@ C3 exposes 16 tools as a native MCP server. Your IDE calls them directly:
183
206
  | `c3_impact` | Blast-radius analysis before edits to shared symbols |
184
207
  | `c3_delegate` | Offload heavy work to local Ollama / Codex / Gemini / etc. |
185
208
  | `c3_agent` | Multi-step agentic workflows (review, investigate, refactor) |
186
- | `c3_edits` | Edit-ledger queries + version diffs + restore points |
209
+ | `c3_edits` | Edit-ledger queries + version diffs + restore points + per-branch filter |
187
210
  | `c3_bitbucket` | Bitbucket Data Center integration — PRs, branches, builds, repo admin (v2.30.0) |
188
211
  | `c3_project` | Cross-project — discover & operate on other c3-installed projects; guarded writes (v2.31.0) |
189
212
 
@@ -85,7 +85,7 @@ console = Console() if HAS_RICH else None
85
85
  # Config
86
86
  CONFIG_DIR = ".c3"
87
87
  CONFIG_FILE = ".c3/config.json"
88
- __version__ = "2.34.0"
88
+ __version__ = "2.36.0"
89
89
 
90
90
 
91
91
  def _command_deps() -> CommandDeps:
@@ -912,6 +912,12 @@ def cmd_init(args):
912
912
  health["instructions_file"] + " missing" not in " ".join(health["issues"])
913
913
  else " [MISSING]"))
914
914
 
915
+ # Version-skew notice: this project's .c3 was written by an older C3.
916
+ stored_version = _safe_read_json(c3_dir / "config.json", "config").get("version")
917
+ if stored_version and _version_tuple(str(stored_version)) < _version_tuple(__version__):
918
+ print(f"\n [upgrade] Set up with C3 v{stored_version}; now running v{__version__}.")
919
+ print(" Run 'c3 init . --force' to re-apply MCP config, hooks, and docs.")
920
+
915
921
  # Permission status (Claude Code only) — surface tier + stale-tool drift
916
922
  try:
917
923
  from core.ide import load_ide_config as _load_ide
@@ -3872,8 +3878,8 @@ _AGENTS_MD_CONTENT = _C3_COMPACT_WORKFLOW + """
3872
3878
  This project uses project-scoped MCP servers. Ensure your `.codex/config.toml` includes:
3873
3879
  ```toml
3874
3880
  [mcp_servers.c3]
3875
- command = "python"
3876
- args = ["<path-to-c3>/cli/mcp_server.py", "--project", "."]
3881
+ command = "c3-mcp"
3882
+ args = ["--project", "."]
3877
3883
  enabled = true
3878
3884
  ```
3879
3885
  """
@@ -3886,8 +3892,8 @@ This project uses project-scoped MCP servers. Ensure your `.gemini/settings.json
3886
3892
  {
3887
3893
  "mcpServers": {
3888
3894
  "c3": {
3889
- "command": "python",
3890
- "args": ["<path-to-c3>/cli/mcp_server.py", "--project", "."]
3895
+ "command": "c3-mcp",
3896
+ "args": ["--project", "."]
3891
3897
  }
3892
3898
  }
3893
3899
  }
@@ -4215,11 +4221,17 @@ def _upsert_json_mcp_server(config_path: Path, config_key: str, server_name: str
4215
4221
  return "updated" if previous_entry is not None else "written"
4216
4222
 
4217
4223
 
4218
- def _ensure_project_session_configs(target: Path, server_script: str, primary_profile: str | None = None) -> None:
4224
+ def _ensure_project_session_configs(target: Path, server_script: str, primary_profile: str | None = None,
4225
+ c3_mcp_exe: str | None = None) -> None:
4219
4226
  """Keep project-local Codex and Gemini MCP configs in sync for new sessions."""
4220
4227
  # Ensure forward slashes for config portability and avoid Windows path-splitting issues
4221
4228
  server_script_posix = Path(server_script).as_posix()
4222
- server_args = [server_script_posix, "--project", target.as_posix()]
4229
+ if c3_mcp_exe:
4230
+ mcp_command = c3_mcp_exe
4231
+ server_args = ["--project", target.as_posix()]
4232
+ else:
4233
+ mcp_command = "python"
4234
+ server_args = [server_script_posix, "--project", target.as_posix()]
4223
4235
 
4224
4236
  if primary_profile != "codex":
4225
4237
  codex_path = target / ".codex" / "config.toml"
@@ -4228,7 +4240,7 @@ def _ensure_project_session_configs(target: Path, server_script: str, primary_pr
4228
4240
  codex_path,
4229
4241
  "mcp_servers.c3",
4230
4242
  {
4231
- "command": "python",
4243
+ "command": mcp_command,
4232
4244
  "args": server_args,
4233
4245
  "enabled": True,
4234
4246
  },
@@ -4242,14 +4254,14 @@ def _ensure_project_session_configs(target: Path, server_script: str, primary_pr
4242
4254
  "mcpServers",
4243
4255
  "c3",
4244
4256
  {
4245
- "command": "python",
4257
+ "command": mcp_command,
4246
4258
  "args": server_args,
4247
4259
  },
4248
4260
  )
4249
4261
  print(f"{gemini_state.capitalize()} {gemini_path}")
4250
4262
 
4251
4263
 
4252
- def _ensure_global_session_fallbacks(server_script: str) -> None:
4264
+ def _ensure_global_session_fallbacks(server_script: str, c3_mcp_exe: str | None = None) -> None:
4253
4265
  """Keep user-global Codex/Gemini MCP configs pointing at C3.
4254
4266
 
4255
4267
  These fallback entries omit `--project` so the MCP server can resolve the
@@ -4257,7 +4269,9 @@ def _ensure_global_session_fallbacks(server_script: str) -> None:
4257
4269
  does not yet have project-local Codex/Gemini config files.
4258
4270
  """
4259
4271
  server_script_posix = Path(server_script).as_posix()
4260
- fallback_args = [server_script_posix]
4272
+ # With the installed entry point, no script path is needed; --project stays
4273
+ # omitted so the server resolves the working directory at session start.
4274
+ fallback_args = [] if c3_mcp_exe else [server_script_posix]
4261
4275
 
4262
4276
  codex_path = Path.home() / ".codex" / "config.toml"
4263
4277
  try:
@@ -4266,7 +4280,7 @@ def _ensure_global_session_fallbacks(server_script: str) -> None:
4266
4280
  codex_path,
4267
4281
  "mcp_servers.c3",
4268
4282
  {
4269
- "command": "python",
4283
+ "command": c3_mcp_exe or "python",
4270
4284
  "args": fallback_args,
4271
4285
  "enabled": True,
4272
4286
  },
@@ -4282,7 +4296,7 @@ def _ensure_global_session_fallbacks(server_script: str) -> None:
4282
4296
  "mcpServers",
4283
4297
  "c3",
4284
4298
  {
4285
- "command": sys.executable,
4299
+ "command": c3_mcp_exe or sys.executable,
4286
4300
  "args": fallback_args,
4287
4301
  },
4288
4302
  )
@@ -4825,13 +4839,25 @@ def cmd_install_mcp(args):
4825
4839
  # Use forward slashes for cross-platform compatibility in config files
4826
4840
  server_script = (cli_dir / server_filename).as_posix()
4827
4841
 
4828
- # Use 'python' for project-scoped IDE configs to be portable in templates,
4829
- # but use sys.executable for the actual config write to be precise.
4830
- # On Windows, Gemini CLI splits command args by space, so we must quote the script path.
4831
- new_entry = {
4832
- "command": "python",
4833
- "args": [server_script, "--project", "."],
4834
- }
4842
+ # Prefer the installed `c3-mcp` console script for direct mode. It survives C3
4843
+ # upgrades (pip/pipx reinstall to the same launcher path) and keeps the source-tree
4844
+ # location out of every project's MCP config, so upgrading no longer requires
4845
+ # re-running install-mcp per project. Fall back to invoking the source script with
4846
+ # `python` when running from a checkout with no installed entry point, or in proxy
4847
+ # mode (which has no console script).
4848
+ import shutil
4849
+ c3_mcp_exe = None
4850
+ if mcp_mode != "proxy":
4851
+ _found = shutil.which("c3-mcp")
4852
+ if _found:
4853
+ c3_mcp_exe = Path(_found).resolve().as_posix()
4854
+
4855
+ # On Windows, Gemini CLI splits command args by space, so the script path stays a
4856
+ # single arg. 'python' keeps the source fallback portable across platforms.
4857
+ if c3_mcp_exe:
4858
+ new_entry = {"command": c3_mcp_exe, "args": ["--project", "."]}
4859
+ else:
4860
+ new_entry = {"command": "python", "args": [server_script, "--project", "."]}
4835
4861
  if profile.needs_type_field:
4836
4862
  new_entry["type"] = "stdio"
4837
4863
 
@@ -4865,7 +4891,10 @@ def cmd_install_mcp(args):
4865
4891
  try:
4866
4892
  if profile.config_format == "toml":
4867
4893
  # Codex uses TOML: [mcp_servers.c3] with command/args
4868
- toml_entries = {"command": sys.executable, "args": [server_script, "--project", str(target)]}
4894
+ if c3_mcp_exe:
4895
+ toml_entries = {"command": c3_mcp_exe, "args": ["--project", str(target)]}
4896
+ else:
4897
+ toml_entries = {"command": sys.executable, "args": [server_script, "--project", str(target)]}
4869
4898
  if profile.name == "codex":
4870
4899
  # Codex supports explicit enable/disable per server.
4871
4900
  toml_entries["enabled"] = True
@@ -4895,8 +4924,8 @@ def cmd_install_mcp(args):
4895
4924
 
4896
4925
  print(f"Wrote {mcp_config_path}")
4897
4926
  if profile.name in {"codex", "gemini"}:
4898
- _ensure_project_session_configs(target, server_script, primary_profile=profile.name)
4899
- _ensure_global_session_fallbacks(server_script)
4927
+ _ensure_project_session_configs(target, server_script, primary_profile=profile.name, c3_mcp_exe=c3_mcp_exe)
4928
+ _ensure_global_session_fallbacks(server_script, c3_mcp_exe=c3_mcp_exe)
4900
4929
 
4901
4930
  # ── Persist IDE choice to .c3/config.json ──
4902
4931
  c3_config_dir = target / ".c3"
@@ -6342,6 +6371,123 @@ def _run_swe_bench_lite(args, project_path):
6342
6371
  pass
6343
6372
 
6344
6373
 
6374
+ def _version_tuple(v: str) -> tuple:
6375
+ """Best-effort numeric version tuple for comparisons ('2.36.0' -> (2, 36, 0))."""
6376
+ parts = []
6377
+ for chunk in str(v or "").split("."):
6378
+ digits = ""
6379
+ for ch in chunk:
6380
+ if ch.isdigit():
6381
+ digits += ch
6382
+ else:
6383
+ break
6384
+ parts.append(int(digits) if digits else 0)
6385
+ return tuple(parts) or (0,)
6386
+
6387
+
6388
+ def _latest_pypi_version(package: str = "code-context-control", timeout: float = 5.0) -> str | None:
6389
+ """Best-effort latest release of `package` on PyPI; None if unreachable."""
6390
+ import urllib.request
6391
+ try:
6392
+ url = f"https://pypi.org/pypi/{package}/json"
6393
+ with urllib.request.urlopen(url, timeout=timeout) as resp:
6394
+ data = json.loads(resp.read().decode("utf-8", "replace"))
6395
+ return (data.get("info") or {}).get("version")
6396
+ except Exception:
6397
+ return None
6398
+
6399
+
6400
+ def _installed_distribution(package: str = "code-context-control"):
6401
+ """Return the installed Distribution for `package`, or None when running from source."""
6402
+ try:
6403
+ from importlib import metadata
6404
+ return metadata.distribution(package)
6405
+ except Exception:
6406
+ return None
6407
+
6408
+
6409
+ def _is_editable_install(package: str = "code-context-control") -> bool:
6410
+ """True when `package` is pip-installed in editable/development mode."""
6411
+ dist = _installed_distribution(package)
6412
+ if dist is None:
6413
+ return False
6414
+ try:
6415
+ text = dist.read_text("direct_url.json")
6416
+ if text:
6417
+ return bool(json.loads(text).get("dir_info", {}).get("editable"))
6418
+ except Exception:
6419
+ pass
6420
+ return False
6421
+
6422
+
6423
+ def cmd_upgrade(args):
6424
+ """Upgrade C3 to the latest PyPI release (or just check with --check)."""
6425
+ current = __version__
6426
+ latest = _latest_pypi_version()
6427
+ if latest is None:
6428
+ print(" Could not reach PyPI to check for updates (offline?).")
6429
+ elif _version_tuple(latest) <= _version_tuple(current):
6430
+ print(f" C3 is up to date (v{current}).")
6431
+ return
6432
+ else:
6433
+ print(f" Update available: v{current} -> v{latest}")
6434
+
6435
+ if getattr(args, "check", False):
6436
+ return
6437
+
6438
+ if _installed_distribution() is None:
6439
+ print(" C3 is running from a source checkout (not pip-installed).")
6440
+ print(" Update with: git pull")
6441
+ return
6442
+ if _is_editable_install():
6443
+ print(" C3 is installed in editable/development mode (pip install -e .).")
6444
+ print(" Update with: git pull")
6445
+ return
6446
+
6447
+ print(" Upgrading via pip (this may take a minute)...")
6448
+ cmd = [sys.executable, "-m", "pip", "install", "-U", "code-context-control[tui]"]
6449
+ try:
6450
+ result = subprocess.run(cmd, capture_output=True, text=True)
6451
+ except Exception as e:
6452
+ print(f" Upgrade failed to launch pip: {e}")
6453
+ sys.exit(1)
6454
+ if result.returncode != 0:
6455
+ print(" pip upgrade failed:")
6456
+ print((result.stderr or result.stdout or "").strip()[-1000:])
6457
+ sys.exit(1)
6458
+ print(" Upgraded to the latest release. Restart your IDE's MCP server to load it.")
6459
+ print(" In each project, run c3 init . --force to apply any migrations.")
6460
+
6461
+
6462
+ def _launch_tui() -> None:
6463
+ """Launch the interactive TUI — what `c3` with no arguments does.
6464
+
6465
+ Runs tui/main.py as a subprocess so its bare `from screens...` imports resolve
6466
+ (its own directory lands on sys.path[0]); the package root goes on PYTHONPATH for
6467
+ cli/services imports. Falls back to help text when the optional [tui] extra
6468
+ (textual) is not installed.
6469
+ """
6470
+ pkg_root = Path(__file__).resolve().parent.parent
6471
+ tui_main = pkg_root / "tui" / "main.py"
6472
+ try:
6473
+ import textual # noqa: F401
6474
+ except Exception:
6475
+ print("The interactive TUI needs the optional 'textual' dependency.")
6476
+ print(' Install it with: pip install "code-context-control[tui]"')
6477
+ print(" Or run c3 --help to see all commands.")
6478
+ return
6479
+ if not tui_main.exists():
6480
+ print("TUI entry point not found. Run c3 --help for commands.")
6481
+ return
6482
+ env = os.environ.copy()
6483
+ existing_pp = env.get("PYTHONPATH")
6484
+ env["PYTHONPATH"] = str(pkg_root) + (os.pathsep + existing_pp if existing_pp else "")
6485
+ try:
6486
+ subprocess.run([sys.executable, str(tui_main)], env=env)
6487
+ except KeyboardInterrupt:
6488
+ pass
6489
+
6490
+
6345
6491
  def main():
6346
6492
  try:
6347
6493
  from services import error_reporting
@@ -6353,7 +6499,8 @@ def main():
6353
6499
  args = parser.parse_args()
6354
6500
 
6355
6501
  if not args.command:
6356
- parser.print_help()
6502
+ # Bare `c3` launches the interactive TUI (replaces the old c3.bat wrapper).
6503
+ _launch_tui()
6357
6504
  return
6358
6505
 
6359
6506
  commands = {
@@ -6382,6 +6529,7 @@ def main():
6382
6529
  "hub": cmd_hub,
6383
6530
  "bitbucket": cmd_bitbucket,
6384
6531
  "oracle": cmd_oracle,
6532
+ "upgrade": cmd_upgrade,
6385
6533
  }
6386
6534
 
6387
6535
  cmd_func = commands.get(args.command)
@@ -23,6 +23,10 @@ def build_parser(version: str, parse_cli_ide_arg):
23
23
  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)")
24
24
  p_init.add_argument("--include-mcp-wildcard", action="store_true", help="Add mcp__* wildcard so non-C3 MCP servers don't prompt per-call")
25
25
 
26
+ p_upgrade = subparsers.add_parser("upgrade", help="Upgrade C3 to the latest PyPI release")
27
+ p_upgrade.add_argument("--check", action="store_true",
28
+ help="Only report whether a newer version exists; don't install")
29
+
26
30
  p_index = subparsers.add_parser("index", help="Rebuild code index")
27
31
  p_index.add_argument("--max-files", type=int, default=500)
28
32