code-context-control 2.109.0__tar.gz → 2.110.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (482) hide show
  1. {code_context_control-2.109.0 → code_context_control-2.110.1}/PKG-INFO +1 -1
  2. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/c3.py +1 -1
  3. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/mcp_server.py +6 -3
  4. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/search.py +120 -21
  5. {code_context_control-2.109.0 → code_context_control-2.110.1}/code_context_control.egg-info/PKG-INFO +1 -1
  6. {code_context_control-2.109.0 → code_context_control-2.110.1}/code_context_control.egg-info/SOURCES.txt +2 -0
  7. {code_context_control-2.109.0 → code_context_control-2.110.1}/pyproject.toml +1 -1
  8. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/agents.py +49 -5
  9. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/bench/search_eval.py +6 -2
  10. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/claude_md.py +18 -14
  11. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/indexer.py +34 -4
  12. code_context_control-2.110.1/tests/test_claude_md_updater.py +163 -0
  13. code_context_control-2.110.1/tests/test_search_p5.py +280 -0
  14. {code_context_control-2.109.0 → code_context_control-2.110.1}/LICENSE +0 -0
  15. {code_context_control-2.109.0 → code_context_control-2.110.1}/README.md +0 -0
  16. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/__init__.py +0 -0
  17. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/_hook_utils.py +0 -0
  18. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/_shell_writes.py +0 -0
  19. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/commands/__init__.py +0 -0
  20. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/commands/common.py +0 -0
  21. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/commands/parser.py +0 -0
  22. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/docs.html +0 -0
  23. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/edits.html +0 -0
  24. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/guide/access.html +0 -0
  25. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/guide/bitbucket.html +0 -0
  26. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/guide/credentials.html +0 -0
  27. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/guide/getting-started.html +0 -0
  28. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/guide/index.html +0 -0
  29. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/guide/masking.html +0 -0
  30. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/guide/oracle.html +0 -0
  31. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/guide/shared.css +0 -0
  32. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/guide/tools.html +0 -0
  33. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/guide/workflow.html +0 -0
  34. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hook_access_guard.py +0 -0
  35. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hook_artifact.py +0 -0
  36. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hook_auto_snapshot.py +0 -0
  37. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hook_c3_signal.py +0 -0
  38. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hook_c3read.py +0 -0
  39. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hook_dispatch.py +0 -0
  40. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hook_edit_ledger.py +0 -0
  41. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hook_edit_unlock.py +0 -0
  42. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hook_filter.py +0 -0
  43. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hook_ghost_files.py +0 -0
  44. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hook_pretool_enforce.py +0 -0
  45. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hook_prompt_recall.py +0 -0
  46. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hook_read.py +0 -0
  47. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hook_session_stats.py +0 -0
  48. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hook_terse_advisor.py +0 -0
  49. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_server.py +0 -0
  50. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/app.js +0 -0
  51. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/add_project.js +0 -0
  52. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/config_editor.js +0 -0
  53. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/drill_artifacts.js +0 -0
  54. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/drill_health.js +0 -0
  55. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/drill_panel.js +0 -0
  56. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/drill_subprojects.js +0 -0
  57. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/drill_tasks.js +0 -0
  58. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/drill_views.js +0 -0
  59. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/global_search.js +0 -0
  60. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/hub_access.js +0 -0
  61. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/hub_ci.js +0 -0
  62. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/hub_cred_audit.js +0 -0
  63. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/hub_credentials.js +0 -0
  64. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/hub_enforcement.js +0 -0
  65. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/hub_locks.js +0 -0
  66. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/hub_tokens.js +0 -0
  67. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/mcp_manager.js +0 -0
  68. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/modals.js +0 -0
  69. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/project_card.js +0 -0
  70. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/project_tree.js +0 -0
  71. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/session_drawer.js +0 -0
  72. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/settings_modal.js +0 -0
  73. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/sidebar.js +0 -0
  74. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/summary_bar.js +0 -0
  75. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/task_board.js +0 -0
  76. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/toasts.js +0 -0
  77. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/components/topbar.js +0 -0
  78. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui/state.js +0 -0
  79. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/hub_ui.html +0 -0
  80. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/mcp_proxy.py +0 -0
  81. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/progress.py +0 -0
  82. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/server.py +0 -0
  83. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/__init__.py +0 -0
  84. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/_grants.py +0 -0
  85. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/_helpers.py +0 -0
  86. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/agent.py +0 -0
  87. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/artifacts.py +0 -0
  88. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/bitbucket.py +0 -0
  89. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/ci.py +0 -0
  90. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/compress.py +0 -0
  91. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/credentials.py +0 -0
  92. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/delegate.py +0 -0
  93. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/edit.py +0 -0
  94. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/edit_verify.py +0 -0
  95. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/edits.py +0 -0
  96. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/federate.py +0 -0
  97. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/filter.py +0 -0
  98. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/impact.py +0 -0
  99. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/jira.py +0 -0
  100. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/locks.py +0 -0
  101. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/memory.py +0 -0
  102. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/override.py +0 -0
  103. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/project.py +0 -0
  104. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/read.py +0 -0
  105. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/session.py +0 -0
  106. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/shell.py +0 -0
  107. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/status.py +0 -0
  108. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/tasks.py +0 -0
  109. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/tools/validate.py +0 -0
  110. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/api.js +0 -0
  111. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/app.js +0 -0
  112. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/components/access.js +0 -0
  113. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/components/bitbucket.js +0 -0
  114. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/components/chat.js +0 -0
  115. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/components/credentials.js +0 -0
  116. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/components/dashboard.js +0 -0
  117. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/components/edits.js +0 -0
  118. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/components/enforcement.js +0 -0
  119. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/components/instructions.js +0 -0
  120. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/components/jira.js +0 -0
  121. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/components/memory.js +0 -0
  122. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/components/sessions.js +0 -0
  123. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/components/settings.js +0 -0
  124. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/components/sidebar.js +0 -0
  125. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/components/tasks.js +0 -0
  126. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/icons.js +0 -0
  127. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/pm_shared.js +0 -0
  128. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/shared.js +0 -0
  129. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui/theme.js +0 -0
  130. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui.html +0 -0
  131. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui_legacy.html +0 -0
  132. {code_context_control-2.109.0 → code_context_control-2.110.1}/cli/ui_nano.html +0 -0
  133. {code_context_control-2.109.0 → code_context_control-2.110.1}/code_context_control.egg-info/dependency_links.txt +0 -0
  134. {code_context_control-2.109.0 → code_context_control-2.110.1}/code_context_control.egg-info/entry_points.txt +0 -0
  135. {code_context_control-2.109.0 → code_context_control-2.110.1}/code_context_control.egg-info/requires.txt +0 -0
  136. {code_context_control-2.109.0 → code_context_control-2.110.1}/code_context_control.egg-info/top_level.txt +0 -0
  137. {code_context_control-2.109.0 → code_context_control-2.110.1}/core/__init__.py +0 -0
  138. {code_context_control-2.109.0 → code_context_control-2.110.1}/core/config.py +0 -0
  139. {code_context_control-2.109.0 → code_context_control-2.110.1}/core/ide.py +0 -0
  140. {code_context_control-2.109.0 → code_context_control-2.110.1}/core/mcp_toml.py +0 -0
  141. {code_context_control-2.109.0 → code_context_control-2.110.1}/core/web_security.py +0 -0
  142. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/__init__.py +0 -0
  143. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/config.py +0 -0
  144. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/mcp_oracle.py +0 -0
  145. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/oracle_server.py +0 -0
  146. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/oracle_ui.html +0 -0
  147. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/__init__.py +0 -0
  148. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/activity_reporter.py +0 -0
  149. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/api_auth.py +0 -0
  150. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/c3_bridge.py +0 -0
  151. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/chat_engine.py +0 -0
  152. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/chat_poll.py +0 -0
  153. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/chat_store.py +0 -0
  154. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/cross_memory.py +0 -0
  155. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/discovery_audit.py +0 -0
  156. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/federated_graph.py +0 -0
  157. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/health_checker.py +0 -0
  158. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/insight_engine.py +0 -0
  159. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/local_session.py +0 -0
  160. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/memory_reader.py +0 -0
  161. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/memory_writer.py +0 -0
  162. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/mobile_api.py +0 -0
  163. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/project_scanner.py +0 -0
  164. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/review_agent.py +0 -0
  165. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/tool_executor.py +0 -0
  166. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/services/tool_registry.py +0 -0
  167. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/activity.js +0 -0
  168. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/agents.js +0 -0
  169. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/app.js +0 -0
  170. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/busy.js +0 -0
  171. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/chat/conversations.js +0 -0
  172. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/chat/input.js +0 -0
  173. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/chat/markdown.js +0 -0
  174. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/chat/send.js +0 -0
  175. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/chat/stream_renderer.js +0 -0
  176. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/chat/toolbar.js +0 -0
  177. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/core.js +0 -0
  178. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/crossgraph.js +0 -0
  179. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/header.js +0 -0
  180. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/insights.js +0 -0
  181. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/projects.js +0 -0
  182. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/qrcode.js +0 -0
  183. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/settings.js +0 -0
  184. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/suggestions.js +0 -0
  185. {code_context_control-2.109.0 → code_context_control-2.110.1}/oracle/ui/theme_tabs.js +0 -0
  186. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/__init__.py +0 -0
  187. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/access_guard.py +0 -0
  188. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/access_telemetry.py +0 -0
  189. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/activity_log.py +0 -0
  190. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/agent_base.py +0 -0
  191. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/agent_locks.py +0 -0
  192. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/artifact_defs.py +0 -0
  193. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/artifact_store.py +0 -0
  194. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/auto_memory.py +0 -0
  195. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/background_service.py +0 -0
  196. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/bench/__init__.py +0 -0
  197. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/bench/external/__init__.py +0 -0
  198. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/bench/external/aider_polyglot.py +0 -0
  199. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/bench/external/swe_bench.py +0 -0
  200. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/benchmark_dashboard.py +0 -0
  201. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/bitbucket_client.py +0 -0
  202. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/bitbucket_credentials.py +0 -0
  203. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/ci_act.py +0 -0
  204. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/ci_cache.py +0 -0
  205. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/ci_expr.py +0 -0
  206. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/ci_failures.py +0 -0
  207. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/ci_github.py +0 -0
  208. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/ci_impact.py +0 -0
  209. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/ci_intel.py +0 -0
  210. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/ci_runner.py +0 -0
  211. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/ci_workflow.py +0 -0
  212. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/circuit_breaker.py +0 -0
  213. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/compressor.py +0 -0
  214. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/context_snapshot.py +0 -0
  215. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/conversation_store.py +0 -0
  216. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/cred_audit.py +0 -0
  217. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/cred_telemetry.py +0 -0
  218. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/credential_store.py +0 -0
  219. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/doc_index.py +0 -0
  220. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/e2e_benchmark.py +0 -0
  221. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/e2e_evaluator.py +0 -0
  222. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/e2e_tasks.py +0 -0
  223. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/edit_ledger.py +0 -0
  224. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/embedding_index.py +0 -0
  225. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/enforcement_policy.py +0 -0
  226. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/error_reporting.py +0 -0
  227. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/file_memory.py +0 -0
  228. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/git_context.py +0 -0
  229. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/hub_service.py +0 -0
  230. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/index_store.py +0 -0
  231. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/jira_client.py +0 -0
  232. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/jira_cloud.py +0 -0
  233. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/jira_credentials.py +0 -0
  234. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/jira_data_center.py +0 -0
  235. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/jira_links.py +0 -0
  236. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/lexical_index.py +0 -0
  237. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/mask_activation.py +0 -0
  238. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/mask_mirror.py +0 -0
  239. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/mask_presets.py +0 -0
  240. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/memory.py +0 -0
  241. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/memory_consolidator.py +0 -0
  242. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/memory_distiller.py +0 -0
  243. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/memory_graph.py +0 -0
  244. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/memory_grounder.py +0 -0
  245. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/memory_queue.py +0 -0
  246. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/memory_scorer.py +0 -0
  247. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/metrics.py +0 -0
  248. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/notifications.py +0 -0
  249. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/ollama_bridge.py +0 -0
  250. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/ollama_client.py +0 -0
  251. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/ollama_credentials.py +0 -0
  252. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/oracle_service.py +0 -0
  253. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/output_filter.py +0 -0
  254. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/override_grants.py +0 -0
  255. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/override_policy.py +0 -0
  256. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/override_requests.py +0 -0
  257. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/override_wake.py +0 -0
  258. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/parser.py +0 -0
  259. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/project_manager.py +0 -0
  260. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/project_runtime.py +0 -0
  261. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/protocol.py +0 -0
  262. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/proxy_state.py +0 -0
  263. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/repo_map.py +0 -0
  264. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/repo_shape.py +0 -0
  265. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/reranker.py +0 -0
  266. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/retention.py +0 -0
  267. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/retrieval.py +0 -0
  268. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/retrieval_broker.py +0 -0
  269. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/router.py +0 -0
  270. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/runtime.py +0 -0
  271. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/scanner.py +0 -0
  272. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/session_benchmark.py +0 -0
  273. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/session_manager.py +0 -0
  274. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/session_preloader.py +0 -0
  275. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/subprojects.py +0 -0
  276. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/task_store.py +0 -0
  277. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/telemetry.py +0 -0
  278. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/text_index.py +0 -0
  279. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/time_tracker.py +0 -0
  280. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/tool_classifier.py +0 -0
  281. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/transcript_index.py +0 -0
  282. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/validation_cache.py +0 -0
  283. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/vector_store.py +0 -0
  284. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/watcher.py +0 -0
  285. {code_context_control-2.109.0 → code_context_control-2.110.1}/services/win_subprocess.py +0 -0
  286. {code_context_control-2.109.0 → code_context_control-2.110.1}/setup.cfg +0 -0
  287. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_access_builtin_optout.py +0 -0
  288. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_access_guard.py +0 -0
  289. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_access_guard_meta.py +0 -0
  290. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_access_guard_shell_project.py +0 -0
  291. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_access_guard_surfaces.py +0 -0
  292. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_access_guard_wiring.py +0 -0
  293. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_activity_reporter.py +0 -0
  294. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_agent_locks.py +0 -0
  295. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_aider_polyglot.py +0 -0
  296. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_antigravity_transition.py +0 -0
  297. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_artifact_store.py +0 -0
  298. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_artifact_tool.py +0 -0
  299. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_background_service.py +0 -0
  300. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_bitbucket_cli_smoke.py +0 -0
  301. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_bitbucket_client.py +0 -0
  302. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_bitbucket_config_fallback.py +0 -0
  303. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_bitbucket_credentials.py +0 -0
  304. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_bitbucket_tool.py +0 -0
  305. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_builtin_modes.py +0 -0
  306. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_c3_bridge_project_artifacts.py +0 -0
  307. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_c3_shell.py +0 -0
  308. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_chat_poll.py +0 -0
  309. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_ci_act.py +0 -0
  310. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_ci_cache.py +0 -0
  311. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_ci_expr.py +0 -0
  312. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_ci_impact.py +0 -0
  313. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_ci_intel.py +0 -0
  314. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_ci_runner.py +0 -0
  315. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_ci_workflow.py +0 -0
  316. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_circuit_breaker.py +0 -0
  317. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_claude_md_merge.py +0 -0
  318. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_cli_smoke.py +0 -0
  319. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_compressor_large_file.py +0 -0
  320. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_confirm_guard.py +0 -0
  321. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_confirm_guard_wiring.py +0 -0
  322. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_cooccurrence_bounds.py +0 -0
  323. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_cred_audit.py +0 -0
  324. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_cred_telemetry.py +0 -0
  325. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_credential_login_kind.py +0 -0
  326. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_credential_store.py +0 -0
  327. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_credential_ui_parity.py +0 -0
  328. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_credentials_routes.py +0 -0
  329. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_credentials_tool.py +0 -0
  330. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_creds_cli_smoke.py +0 -0
  331. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_delegate_cascade.py +0 -0
  332. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_delegate_version_probe.py +0 -0
  333. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_e2e_benchmark.py +0 -0
  334. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_edit_ledger_deadline.py +0 -0
  335. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_edit_ledger_hook.py +0 -0
  336. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_edit_locking.py +0 -0
  337. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_edit_normalization.py +0 -0
  338. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_edit_verify.py +0 -0
  339. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_embedding_index_deadlock.py +0 -0
  340. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_enforcement_flip.py +0 -0
  341. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_enforcement_policy.py +0 -0
  342. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_enforcement_routes.py +0 -0
  343. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_env_parser.py +0 -0
  344. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_failed_calls_do_not_unlock.py +0 -0
  345. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_federated_graph.py +0 -0
  346. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_filter_backoff.py +0 -0
  347. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_ghost_files.py +0 -0
  348. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_ghost_generation.py +0 -0
  349. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_git_branch_awareness.py +0 -0
  350. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_hook_access_guard.py +0 -0
  351. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_hook_codex_compat.py +0 -0
  352. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_hook_dispatch.py +0 -0
  353. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_hook_pretool_enforce.py +0 -0
  354. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_hook_prompt_recall.py +0 -0
  355. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_hook_smoke.py +0 -0
  356. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_hook_state.py +0 -0
  357. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_hook_utf8_stdio.py +0 -0
  358. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_hub_credentials_route.py +0 -0
  359. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_hub_credentials_routes_write.py +0 -0
  360. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_hub_enforcement_routes.py +0 -0
  361. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_hub_inspect_api.py +0 -0
  362. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_hub_locks_routes.py +0 -0
  363. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_hub_oracle_service_routes.py +0 -0
  364. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_hub_override_routes.py +0 -0
  365. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_hub_server_smoke.py +0 -0
  366. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_hub_subproject_links.py +0 -0
  367. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_ide_workflow_adaptation.py +0 -0
  368. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_index_cap_not_hardcoded.py +0 -0
  369. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_init_clear_preserves_user_content.py +0 -0
  370. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_init_scan.py +0 -0
  371. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_install_mcp_entrypoint.py +0 -0
  372. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_jira_cli_smoke.py +0 -0
  373. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_jira_client.py +0 -0
  374. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_jira_config_fallback.py +0 -0
  375. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_jira_credentials.py +0 -0
  376. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_jira_links.py +0 -0
  377. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_jira_routes.py +0 -0
  378. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_jira_tool.py +0 -0
  379. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_lazy_store_init.py +0 -0
  380. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_mask_guard.py +0 -0
  381. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_mask_routes.py +0 -0
  382. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_mask_surfaces.py +0 -0
  383. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_mcp_host_guard.py +0 -0
  384. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_mcp_memory_timeout.py +0 -0
  385. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_mcp_server_smoke.py +0 -0
  386. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_mcp_toml.py +0 -0
  387. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_memory_distiller.py +0 -0
  388. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_memory_graph_api.py +0 -0
  389. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_memory_queue.py +0 -0
  390. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_memory_system.py +0 -0
  391. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_mobile_api.py +0 -0
  392. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_mobile_extras.py +0 -0
  393. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_mobile_override_routes.py +0 -0
  394. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_mobile_security_api.py +0 -0
  395. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_no_stale_model_pins.py +0 -0
  396. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_notification_dedup.py +0 -0
  397. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_notification_discipline.py +0 -0
  398. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_ollama_credentials.py +0 -0
  399. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_oracle_api_auth.py +0 -0
  400. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_oracle_apikey_api.py +0 -0
  401. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_oracle_c3_bridge.py +0 -0
  402. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_oracle_chat_engine.py +0 -0
  403. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_oracle_chat_store.py +0 -0
  404. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_oracle_discovery_api.py +0 -0
  405. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_oracle_discovery_audit.py +0 -0
  406. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_oracle_health_probe.py +0 -0
  407. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_oracle_local_auth.py +0 -0
  408. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_oracle_ollama_bridge.py +0 -0
  409. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_oracle_scanner_cache.py +0 -0
  410. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_oracle_security_fixes.py +0 -0
  411. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_oracle_session_bootstrap.py +0 -0
  412. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_oracle_subproject_awareness.py +0 -0
  413. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_oracle_ui_bundle.py +0 -0
  414. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_output_filter.py +0 -0
  415. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_override_grants.py +0 -0
  416. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_override_grants_mcp.py +0 -0
  417. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_override_requests.py +0 -0
  418. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_override_wake.py +0 -0
  419. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_permissions.py +0 -0
  420. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_pm_api.py +0 -0
  421. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_project_manager.py +0 -0
  422. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_project_manager_merge.py +0 -0
  423. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_project_tool.py +0 -0
  424. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_read_coercion.py +0 -0
  425. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_read_edit_parity.py +0 -0
  426. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_related_facts.py +0 -0
  427. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_repo_map.py +0 -0
  428. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_repo_shape.py +0 -0
  429. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_response_boilerplate.py +0 -0
  430. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_retention.py +0 -0
  431. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_review_digest.py +0 -0
  432. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_search_eval.py +0 -0
  433. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_search_p1.py +0 -0
  434. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_search_p2.py +0 -0
  435. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_search_p2b.py +0 -0
  436. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_search_p3.py +0 -0
  437. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_search_p4.py +0 -0
  438. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_service_durability.py +0 -0
  439. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_session_benchmark.py +0 -0
  440. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_session_budget.py +0 -0
  441. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_shell_creds.py +0 -0
  442. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_shell_robustness.py +0 -0
  443. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_shell_write_ledger.py +0 -0
  444. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_shell_writes.py +0 -0
  445. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_subproject_clear_scope.py +0 -0
  446. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_subproject_depth_consumers.py +0 -0
  447. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_subproject_exclusion.py +0 -0
  448. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_subproject_federation.py +0 -0
  449. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_subproject_linkage_api.py +0 -0
  450. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_subprojects.py +0 -0
  451. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_swe_bench.py +0 -0
  452. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_task_store.py +0 -0
  453. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_task_tool.py +0 -0
  454. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_time_tracker.py +0 -0
  455. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_token_telemetry.py +0 -0
  456. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_token_tracking.py +0 -0
  457. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_tool_registry.py +0 -0
  458. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_ui_jsx_syntax.py +0 -0
  459. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_upgrade_and_version.py +0 -0
  460. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_validate.py +0 -0
  461. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_vault_write_guard.py +0 -0
  462. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_version_sync.py +0 -0
  463. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_web_security.py +0 -0
  464. {code_context_control-2.109.0 → code_context_control-2.110.1}/tests/test_windows_reliability.py +0 -0
  465. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/__init__.py +0 -0
  466. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/backend.py +0 -0
  467. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/main.py +0 -0
  468. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/screens/__init__.py +0 -0
  469. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/screens/benchmark_view.py +0 -0
  470. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/screens/claudemd_view.py +0 -0
  471. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/screens/compress_view.py +0 -0
  472. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/screens/index_view.py +0 -0
  473. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/screens/init_view.py +0 -0
  474. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/screens/mcp_view.py +0 -0
  475. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/screens/optimize_view.py +0 -0
  476. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/screens/pipe_view.py +0 -0
  477. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/screens/projects_view.py +0 -0
  478. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/screens/search_view.py +0 -0
  479. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/screens/session_view.py +0 -0
  480. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/screens/stats.py +0 -0
  481. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/screens/ui_view.py +0 -0
  482. {code_context_control-2.109.0 → code_context_control-2.110.1}/tui/theme.tcss +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-context-control
3
- Version: 2.109.0
3
+ Version: 2.110.1
4
4
  Summary: Local MCP code-intelligence for AI coding tools: surgical search/read/edit, agent-config version history, path-level access + masking guards, and a multi-project hub.
5
5
  Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -92,7 +92,7 @@ console = Console() if HAS_RICH else None
92
92
  # Config
93
93
  CONFIG_DIR = ".c3"
94
94
  CONFIG_FILE = ".c3/config.json"
95
- __version__ = "2.109.0"
95
+ __version__ = "2.110.1"
96
96
 
97
97
 
98
98
  def _compress_file_cli(compressor, path, mode="smart", **kw):
@@ -489,13 +489,16 @@ async def c3_search(query: str, action: str = "code", top_k: int = 3,
489
489
  action: 'code' (default: BM25 over identifiers and their parts, digits kept, fused with the embedding
490
490
  index by reciprocal rank when one is ready; a query that IS a symbol name puts its definition first;
491
491
  an oversized chunk comes back as a window), 'lexical' (the BM25 ranking alone), 'exact' (regex over
492
- every indexed file; ignore_case=True for case-insensitive), 'files' (by filename: exact name, glob
493
- like 'configs/*.yml', or substring), 'semantic' (embeddings alone; falls back to code search when
494
- empty), 'transcript'.
492
+ every indexed file, definitions printed first; ignore_case=True for case-insensitive), 'files' (by
493
+ filename: exact name, glob like 'configs/*.yml', or substring), 'semantic' (embeddings alone; falls
494
+ back to code search when empty), 'transcript'.
495
495
  Filters (all actions but transcript, comma-separated): path='src/**,*.go' (globs or substrings),
496
496
  lang='python,go' (names or extensions), kind='test,doc,config,source' and/or chunk types
497
497
  'function,class,method,heading'. A query that names tests or asks a how-to question already
498
498
  leans that way; filters make it exact.
499
+ top_k: up to 50 for 'files' and 'exact', 10 otherwise. Each hit header ends in the backend that
500
+ produced it ([lexical], [dense], [lexical+dense], symbol+, reranked); a zero result says which
501
+ action to try next.
499
502
  scope: '' current project | 'all' also searches linked sub-projects | '<name>' one sub-project.
500
503
  prefetch: auto-compress top results. Next step: c3_compress/c3_read on hits."""
501
504
  svc = _svc(ctx)
@@ -14,7 +14,7 @@ from cli.tools._helpers import finalize_with_tokens, show_token_ratios
14
14
  from core import count_tokens
15
15
  from services import access_guard
16
16
  from services.indexer import DEFAULT_CODE_EXTS
17
- from services.lexical_index import Filters
17
+ from services.lexical_index import Filters, doc_kind
18
18
  from services.scanner import SKIP_DIRS, iter_files
19
19
 
20
20
  # Hard cap: responses above this are truncated to avoid filling context.
@@ -24,6 +24,32 @@ _RESPONSE_TOKEN_CAP = 2400
24
24
  # token budget and hide every other file.
25
25
  _EXACT_MAX_MATCHES_PER_FILE = 20
26
26
  _RG_TIMEOUT_SECONDS = 60
27
+ # top_k caps per action (2.110.0). A code hit spends a chunk of the token
28
+ # budget; a files row or an exact per-file block spends a line or two, so
29
+ # those actions may list many more before the response cap bites.
30
+ _TOP_K_CAP_DEFAULT = 10
31
+ _TOP_K_CAPS = {"files": 50, "exact": 50}
32
+
33
+ # `exact` orders files definitions-first (2.110.0): a hit on a line that
34
+ # declares something outranks a hit that merely mentions it, then source
35
+ # before config, docs and tests, then path order. The index's symbol table
36
+ # is consulted first when the query names one identifier; this regex is the
37
+ # language-agnostic fallback for keyword-declared definitions (def/class/
38
+ # fn/func/type/const/...) and top-level assignments. C-family functions
39
+ # without a keyword rely on the symbol table.
40
+ _DEF_LINE_RE = re.compile(
41
+ r"^\s*(?:(?:export|default|pub(?:\([^)]*\))?|public|private|protected|internal|static|"
42
+ r"abstract|final|async|unsafe|extern|declare|override|virtual|inline|constexpr)\s+)*"
43
+ r"(?:def|class|function|fn|func|type|struct|interface|enum|trait|impl|module|record|"
44
+ r"protocol|extension|object|namespace|const|let|var|val|#define)"
45
+ r"(?=\s+[A-Za-z_(*&\[]|\s*[<(])"
46
+ r"|^[A-Za-z_][\w.]*\s*(?::[^=]*)?=(?!=)")
47
+ _KIND_RANK = {"source": 0, "config": 1, "doc": 2, "test": 3}
48
+ # A forward slash or a dotted filename reads as a path; a backslash does not,
49
+ # because `\d` / `\s` in a regex are far more common in queries than Windows
50
+ # separators.
51
+ _PATHLIKE_RE = re.compile(r"/|^[\w.\-]+\.[A-Za-z0-9]{1,6}$")
52
+ _REGEX_META = set("\\^$.|?*+()[]{}")
27
53
 
28
54
 
29
55
  def _read_denied(path, svc) -> bool:
@@ -77,11 +103,66 @@ def _cap_response(resp: str) -> str:
77
103
  return "\n".join(lines[:20]) + "\n[truncated]"
78
104
 
79
105
 
106
+ def _via_tag(r: dict) -> str:
107
+ """`` [lexical+dense, reranked]`` — which backend(s) produced the hit."""
108
+ via = r.get("via")
109
+ if not via:
110
+ return ""
111
+ return f" [{via}, reranked]" if r.get("reranked") else f" [{via}]"
112
+
113
+
114
+ def _zero_hint(action: str, query: str, *, filters: Filters | None = None,
115
+ ignore_case: bool = False) -> str:
116
+ """One clause naming what to try next when an action finds nothing.
117
+
118
+ Never echoes the query: the eval harness strips it before checking for
119
+ forbidden text, and a masked canary must not be printed twice.
120
+ """
121
+ tips = []
122
+ if action == "exact":
123
+ if not ignore_case and re.search(r"[A-Za-z]", query):
124
+ tips.append("ignore_case=True")
125
+ tips.append("action='code', which matches identifiers by their parts")
126
+ elif action == "files":
127
+ if not any(ch in query for ch in "*?["):
128
+ tips.append("a glob like '**/*.yml'")
129
+ tips.append("action='exact' to search file contents")
130
+ else:
131
+ if _PATHLIKE_RE.search(query):
132
+ tips.append("action='files', which matches filenames")
133
+ elif any(ch in query for ch in _REGEX_META):
134
+ tips.append("action='exact', which takes a regex")
135
+ else:
136
+ tips.append("action='exact' for a literal or regex")
137
+ tips.append("action='files' for a filename")
138
+ if filters:
139
+ tips.append("dropping the path/lang/kind filter")
140
+ if not tips:
141
+ return ""
142
+ if len(tips) == 1:
143
+ return f"; try {tips[0]}"
144
+ return "; try " + ", ".join(tips[:-1]) + f", or {tips[-1]}"
145
+
146
+
147
+ def _symbol_definition_files(query: str, svc) -> set:
148
+ """Files whose indexed symbol table defines the identifier ``query`` names."""
149
+ idx = getattr(svc, "indexer", None)
150
+ fn = getattr(idx, "_exact_symbol_ids", None)
151
+ if not callable(fn):
152
+ return set()
153
+ try:
154
+ chunks = getattr(idx, "chunks", None) or {}
155
+ # doc ids carry the OS separator; the manifest is POSIX.
156
+ return {chunks[cid]["doc_id"].replace("\\", "/") for cid in fn(query) if cid in chunks}
157
+ except Exception:
158
+ return set()
159
+
160
+
80
161
  def handle_search(query: str, action: str, top_k: int, max_tokens: int,
81
162
  svc, finalize, maybe_facts, prefetch: bool = False,
82
163
  scope: str = "", ignore_case: bool = False,
83
164
  path: str = "", lang: str = "", kind: str = "") -> str:
84
- top_k = max(1, min(int(top_k), 10))
165
+ top_k = max(1, min(int(top_k), _TOP_K_CAPS.get(action, _TOP_K_CAP_DEFAULT)))
85
166
  max_tokens = min(max(200, int(max_tokens)), _RESPONSE_TOKEN_CAP)
86
167
  filters = Filters(path=path, lang=lang, kind=kind)
87
168
 
@@ -262,10 +343,13 @@ def _exact_search(query, top_k, max_tokens, svc, finalize, ignore_case: bool = F
262
343
  return None
263
344
  file_matches = []
264
345
  n_matches = 0
346
+ def_line = False
265
347
  for i, line in enumerate(lines):
266
348
  if not pat.search(line):
267
349
  continue
268
350
  n_matches += 1
351
+ if not def_line and _DEF_LINE_RE.match(line):
352
+ def_line = True
269
353
  if n_matches > _EXACT_MAX_MATCHES_PER_FILE:
270
354
  continue # keep counting, stop printing
271
355
  start = max(0, i - 1)
@@ -281,32 +365,45 @@ def _exact_search(query, top_k, max_tokens, svc, finalize, ignore_case: bool = F
281
365
  file_matches.append(
282
366
  f"[+{n_matches - _EXACT_MAX_MATCHES_PER_FILE} more matching lines in this file; "
283
367
  "narrow the pattern]")
284
- return (rel, file_matches) if file_matches else None
368
+ return (rel, file_matches, def_line) if file_matches else None
285
369
 
286
- matched_parts = []
287
- file_count = 0
288
- total_tokens = 0
370
+ # Every matching file is collected, then ordered definitions-first: the
371
+ # manifest walk used to decide the order, so the definition of a symbol
372
+ # could print behind a test and a doc that merely mention it.
373
+ symbol_files = _symbol_definition_files(query, svc)
374
+ hits = []
289
375
  if targets:
290
376
  with ThreadPoolExecutor(max_workers=min(len(targets), 8)) as pool:
291
377
  for result in pool.map(_scan_file, targets):
292
378
  if result is None:
293
379
  continue
294
- rel, file_matches = result
380
+ rel, file_matches, def_line = result
295
381
  if _read_denied(rel, svc):
296
382
  continue # R2: denied paths never appear in results
297
- chunk = f"--- {rel} ---\n" + "\n".join(file_matches)
298
- chunk_tokens = count_tokens(chunk)
299
- if total_tokens + chunk_tokens > max_tokens and matched_parts:
300
- break
301
- file_count += 1
302
- total_tokens += chunk_tokens
303
- matched_parts.append(chunk)
304
- if file_count >= top_k:
305
- break
383
+ def_rank = 0 if rel in symbol_files else (1 if def_line else 2)
384
+ hits.append(((def_rank, _KIND_RANK.get(doc_kind(rel), 9), rel),
385
+ rel, file_matches, def_rank < 2))
386
+ hits.sort(key=lambda h: h[0])
387
+
388
+ matched_parts = []
389
+ file_count = 0
390
+ total_tokens = 0
391
+ for _key, rel, file_matches, is_def in hits:
392
+ header = f"--- {rel} ---" + (" [definition]" if is_def else "")
393
+ chunk = header + "\n" + "\n".join(file_matches)
394
+ chunk_tokens = count_tokens(chunk)
395
+ if total_tokens + chunk_tokens > max_tokens and matched_parts:
396
+ break
397
+ file_count += 1
398
+ total_tokens += chunk_tokens
399
+ matched_parts.append(chunk)
400
+ if file_count >= top_k:
401
+ break
306
402
 
307
403
  if not matched_parts:
404
+ hint = _zero_hint("exact", query, filters=filters, ignore_case=ignore_case)
308
405
  return finalize("c3_search", {"action": "exact"},
309
- f"[search:exact:{query}] 0 results in {len(manifest)} files", "0")
406
+ f"[search:exact:{query}] 0 results in {len(manifest)} files{hint}", "0")
310
407
 
311
408
  resp = "\n".join(matched_parts)
312
409
  return finalize("c3_search", {"action": "exact"}, resp, f"{file_count}f",
@@ -418,8 +515,9 @@ def _files_search(query, top_k, svc, finalize, filters: Filters | None = None):
418
515
  **_filter_kwargs(filters))
419
516
  res = [r for r in res if not _read_denied(r.get("file", ""), svc)]
420
517
  if not res:
518
+ hint = _zero_hint("files", query, filters=filters)
421
519
  return finalize("c3_search", {"action": "files"},
422
- f"[search:files:{query}] 0 results", "0")
520
+ f"[search:files:{query}] 0 results{hint}", "0")
423
521
  parts = []
424
522
  for r in res:
425
523
  meta = f"- {r['file']} (L{r['lines']})"
@@ -519,7 +617,7 @@ def _semantic_search(query, top_k, max_tokens, svc, finalize, maybe_facts,
519
617
  total_tokens = 0
520
618
  for r in results:
521
619
  name = f" {r['name']}" if r.get('name') else ""
522
- ref = f"--- {r['file']}:L{r['lines']}{name} ({r['type']})"
620
+ ref = f"--- {r['file']}:L{r['lines']}{name} ({r['type']}) [dense]"
523
621
  lines.extend([ref, r['content']] if r.get('content') else [ref])
524
622
  total_tokens += r['tokens']
525
623
 
@@ -539,7 +637,8 @@ def _code_search(query, top_k, max_tokens, svc, finalize, maybe_facts,
539
637
  # Access Guard pre-filter BEFORE dedup/top_k (R2 deny-ENUMERATE).
540
638
  results = [r for r in results if not _read_denied(r.get("file", ""), svc)]
541
639
  if not results:
542
- return finalize("c3_search", {"query": query}, f"[search:{query}] 0 results", "0")
640
+ hint = _zero_hint("code", query, filters=filters)
641
+ return finalize("c3_search", {"query": query}, f"[search:{query}] 0 results{hint}", "0")
543
642
 
544
643
  best_score = max((r.get("score", 0.0) for r in results), default=0.0)
545
644
  if best_score > 0:
@@ -564,7 +663,7 @@ def _code_search(query, top_k, max_tokens, svc, finalize, maybe_facts,
564
663
  total_tokens = 0
565
664
  for r in deduped:
566
665
  name = f" {r['name']}" if r['name'] else ""
567
- ref = f"--- {r['file']}:L{r['lines']}{name} ({r['type']})"
666
+ ref = f"--- {r['file']}:L{r['lines']}{name} ({r['type']}){_via_tag(r)}"
568
667
  lines.extend([ref, r['content']] if r.get('content') else [ref])
569
668
  total_tokens += r['tokens']
570
669
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-context-control
3
- Version: 2.109.0
3
+ Version: 2.110.1
4
4
  Summary: Local MCP code-intelligence for AI coding tools: surgical search/read/edit, agent-config version history, path-level access + masking guards, and a multi-project hub.
5
5
  Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -311,6 +311,7 @@ tests/test_ci_runner.py
311
311
  tests/test_ci_workflow.py
312
312
  tests/test_circuit_breaker.py
313
313
  tests/test_claude_md_merge.py
314
+ tests/test_claude_md_updater.py
314
315
  tests/test_cli_smoke.py
315
316
  tests/test_compressor_large_file.py
316
317
  tests/test_confirm_guard.py
@@ -431,6 +432,7 @@ tests/test_search_p2.py
431
432
  tests/test_search_p2b.py
432
433
  tests/test_search_p3.py
433
434
  tests/test_search_p4.py
435
+ tests/test_search_p5.py
434
436
  tests/test_service_durability.py
435
437
  tests/test_session_benchmark.py
436
438
  tests/test_session_budget.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "code-context-control"
7
- version = "2.109.0"
7
+ version = "2.110.1"
8
8
  description = "Local MCP code-intelligence for AI coding tools: surgical search/read/edit, agent-config version history, path-level access + masking guards, and a multi-project hub."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -650,11 +650,12 @@ class ClaudeMdUpdaterAgent(BackgroundAgent):
650
650
 
651
651
  for action_type, data in actions:
652
652
  if action_type == "staleness":
653
- # Regenerate the auto-generated sections
653
+ # Regenerate the auto-generated sections — inside the managed
654
+ # block, so user content around it survives.
654
655
  try:
655
656
  result = self.claude_md.generate(include_sessions=True)
656
657
  if result.get("content") and self.auto_apply:
657
- self._write_claude_md(result["content"])
658
+ self._write_managed_body(result["content"])
658
659
  applied.append("Regenerated CLAUDE.md (stale)")
659
660
  elif result.get("content"):
660
661
  applied.append(f"CLAUDE.md is stale ({len(data.get('issues', []))} issues) — regeneration available")
@@ -810,16 +811,59 @@ class ClaudeMdUpdaterAgent(BackgroundAgent):
810
811
  self._write_claude_md("\n".join(lines))
811
812
  return additions
812
813
 
813
- def _write_claude_md(self, content: str):
814
- """Write content to the instructions file and update hash."""
814
+ def _md_path(self):
815
+ return self.claude_md.project_path / self.claude_md.instructions_file
816
+
817
+ def _write_managed_body(self, body: str) -> bool:
818
+ """Write regenerated C3 content INTO the managed block.
819
+
820
+ ``generate()`` returns the block body, not a whole file. Writing it
821
+ raw (2.110.0 and earlier) dropped the ``C3:BEGIN``/``C3:END`` markers
822
+ and everything the user kept outside them; the next ``c3 install-mcp``
823
+ then re-wrapped the template as a legacy doc, so a committed
824
+ CLAUDE.md went dirty on every session start. The merge in
825
+ ``write_c3_instruction_doc`` is the same one the installer uses.
826
+ """
827
+ from services.claude_md import write_c3_instruction_doc
828
+
815
829
  try:
816
- md_path = self.claude_md.project_path / self.claude_md.instructions_file
830
+ final = write_c3_instruction_doc(self._md_path(), body,
831
+ project_path=self.claude_md.project_path,
832
+ source="claude_md_updater")
833
+ self._last_content_hash = hashlib.md5(final.encode()).hexdigest()
834
+ self._last_update_time = time.time()
835
+ return True
836
+ except Exception:
837
+ return False
838
+
839
+ def _write_claude_md(self, content: str) -> bool:
840
+ """Write a WHOLE instructions file (compaction, promotions) and update hash.
841
+
842
+ Refuses when the file on disk carries the managed-block markers and
843
+ ``content`` does not: that is a block body, and writing it here would
844
+ strip the markers — route it through ``_write_managed_body``.
845
+ """
846
+ from services.claude_md import C3_BLOCK_BEGIN
847
+
848
+ try:
849
+ md_path = self._md_path()
817
850
  md_path.parent.mkdir(parents=True, exist_ok=True)
851
+ if md_path.exists() and C3_BLOCK_BEGIN not in content:
852
+ existing = md_path.read_text(encoding="utf-8", errors="replace")
853
+ if C3_BLOCK_BEGIN in existing:
854
+ return False
818
855
  md_path.write_text(content, encoding="utf-8")
819
856
  self._last_content_hash = hashlib.md5(content.encode()).hexdigest()
820
857
  self._last_update_time = time.time()
858
+ except Exception:
859
+ return False
860
+ try:
861
+ from services.artifact_defs import note_pending_write
862
+ note_pending_write(self.claude_md.project_path, self.claude_md.instructions_file,
863
+ "claude_md_updater")
821
864
  except Exception:
822
865
  pass
866
+ return True
823
867
 
824
868
  def get_status(self) -> dict:
825
869
  """Extended status including updater-specific metrics."""
@@ -330,11 +330,15 @@ def _embedding_index(project: str, indexer, *, build: bool):
330
330
 
331
331
  # ── Response parsing ────────────────────────────────────────────────────────
332
332
 
333
+ # Headers may carry a trailing ``[tag]`` (2.110.0): ``[lexical+dense]`` /
334
+ # ``[dense]`` / ``[symbol+lexical, reranked]`` on chunk hits, ``[definition]``
335
+ # on exact hits. The tag is provenance, not identity, so it is optional here.
333
336
  _RE_CHUNK = re.compile(
334
- r"^--- (?P<file>.+?):L(?P<lines>[^ ]+)(?: (?P<name>.+?))? \((?P<type>[^()]+)\)\s*$")
337
+ r"^--- (?P<file>.+?):L(?P<lines>[^ ]+)(?: (?P<name>.+?))? \((?P<type>[^()]+)\)"
338
+ r"(?: \[(?P<via>[^\]]*)\])?\s*$")
335
339
  _RE_FILE_ROW = re.compile(
336
340
  r"^- (?P<file>.+?) \(L(?P<lines>[^)]+)\)(?:.*?contains (?P<type>\S+) '(?P<name>[^']*)')?")
337
- _RE_EXACT = re.compile(r"^--- (?P<file>.+?) ---\s*$")
341
+ _RE_EXACT = re.compile(r"^--- (?P<file>.+?) ---(?: \[(?P<via>[^\]]*)\])?\s*$")
338
342
 
339
343
 
340
344
  def parse_hits(action: str, response: str) -> list[Hit]:
@@ -300,17 +300,19 @@ def strip_c3_block(existing: str) -> Optional[str]:
300
300
  return None
301
301
 
302
302
 
303
- def write_c3_instruction_doc(path, content: str, project_path=None) -> str:
303
+ def write_c3_instruction_doc(path, content: str, project_path=None,
304
+ source: str = "install_mcp") -> str:
304
305
  """Write a C3-generated instruction doc without clobbering user content.
305
306
 
306
307
  Wraps ``content`` in the C3 managed block and merges it into any existing
307
308
  file via :func:`merge_c3_block`. Returns the exact text written to disk.
308
309
 
309
- Self-reports the write to the agent-artifact tracker (source=install_mcp)
310
- so regeneration is attributed to C3 instead of surfacing as anonymous
311
- out-of-band drift. ``project_path`` pins the project root; when omitted
312
- it is inferred from the doc's location (root or one level down, e.g.
313
- .github/copilot-instructions.md).
310
+ Self-reports the write to the agent-artifact tracker under ``source``
311
+ (``install_mcp`` for the installer and CLI, ``claude_md_updater`` for the
312
+ background agent) so regeneration is attributed to C3 instead of
313
+ surfacing as anonymous out-of-band drift. ``project_path`` pins the
314
+ project root; when omitted it is inferred from the doc's location (root
315
+ or one level down, e.g. .github/copilot-instructions.md).
314
316
  """
315
317
  p = Path(path)
316
318
  p.parent.mkdir(parents=True, exist_ok=True)
@@ -329,7 +331,7 @@ def write_c3_instruction_doc(path, content: str, project_path=None) -> str:
329
331
  if (c / ".c3").is_dir()), None)
330
332
  if root is not None and (root / ".c3").is_dir():
331
333
  note_pending_write(root, str(p.resolve().relative_to(root.resolve())),
332
- "install_mcp")
334
+ source or "install_mcp")
333
335
  except Exception:
334
336
  pass
335
337
  return final
@@ -533,13 +535,15 @@ class ClaudeMdManager:
533
535
  ),
534
536
  })
535
537
 
536
- # Structure drift
537
- structure_issues = self._diff_structure(current)
538
- issues.extend(structure_issues)
539
-
540
- # Tech stack drift
541
- tech_issues = self._diff_tech_stack(current)
542
- issues.extend(tech_issues)
538
+ # Structure and tech-stack drift apply only to the legacy embedded
539
+ # tree. With the live repo map (default since 2.60.0) the doc carries
540
+ # neither — the map does — so there is nothing embedded to drift.
541
+ # Diffing anyway reported every detected technology as "not listed"
542
+ # on every check, and an auto-applying updater rewrote the file each
543
+ # time (2.110.1).
544
+ if not self._repo_map_enabled():
545
+ issues.extend(self._diff_structure(current))
546
+ issues.extend(self._diff_tech_stack(current))
543
547
 
544
548
  # Session staleness
545
549
  session_files = sorted(
@@ -230,13 +230,16 @@ class CodeIndex:
230
230
  return "off"
231
231
  return str(getattr(self.reranker, "name", None) or "on")
232
232
 
233
- def _apply_rerank(self, query: str, base_tokens: list, ranked: list, exact_ids: set) -> list:
233
+ def _apply_rerank(self, query: str, base_tokens: list, ranked: list, exact_ids: set,
234
+ reranked: set | None = None) -> list:
234
235
  """Cross-encoder pass over the top ``search_rerank_top_n`` candidates.
235
236
 
236
237
  Identifier-shaped queries are left alone (services/reranker
237
238
  .is_natural_language). Exact-symbol matches keep their place ahead of
238
239
  the reranked block; candidates beyond the block keep their order.
239
240
  Any reranker failure or empty answer leaves ``ranked`` unchanged.
241
+ ``reranked``, when given, receives the ids the model actually
242
+ reordered so the caller can label them.
240
243
  """
241
244
  from services.reranker import is_natural_language, passage_text
242
245
 
@@ -258,10 +261,12 @@ class CodeIndex:
258
261
  return ranked
259
262
  order = {cid: i for i, (cid, _) in enumerate(scored)}
260
263
  block.sort(key=lambda cs: (order.get(cs[0], len(order)), -cs[1], cs[0]))
264
+ if reranked is not None:
265
+ reranked.update(cid for cid, _ in block)
261
266
  return exact_head + block + ranked[n:]
262
267
 
263
268
  def _fuse_dense(self, query: str, lexical_ranked: list, filters: Filters,
264
- exact_ids: set, want: int) -> list:
269
+ exact_ids: set, want: int, provenance: dict | None = None) -> list:
265
270
  """RRF of the lexical ranking with the dense backend's candidates.
266
271
 
267
272
  Each list contributes its top ``n`` (20..50, from ``want``); dense ids
@@ -270,6 +275,9 @@ class CodeIndex:
270
275
  their override through the rank key. Lexical candidates beyond ``n``
271
276
  trail the fused block so budget filling can continue past it. Any
272
277
  backend failure returns the lexical ranking unchanged.
278
+ ``provenance``, when given, is filled with ``chunk_id -> {"lexical",
279
+ "dense"}`` naming the list(s) each fused id came from; it stays empty
280
+ when fusion did not happen, which the caller reads as lexical-only.
273
281
  """
274
282
  from services.retrieval import rrf
275
283
 
@@ -297,6 +305,15 @@ class CodeIndex:
297
305
  fused.setdefault(cid, 0.0)
298
306
  ranked = sorted(fused.items(), key=self._rank_key(exact_ids), reverse=True)
299
307
  tail = [(cid, score) for cid, score in lexical_ranked[n:] if cid not in fused]
308
+ if provenance is not None:
309
+ for cid in fused:
310
+ provenance[cid] = set()
311
+ for cid in lexical:
312
+ provenance[cid].add("lexical")
313
+ for cid in dense:
314
+ provenance[cid].add("dense")
315
+ for cid, _ in tail:
316
+ provenance[cid] = {"lexical"}
300
317
  return ranked + tail
301
318
 
302
319
  def _lexical_wanted(self) -> bool:
@@ -1254,10 +1271,17 @@ class CodeIndex:
1254
1271
  if ranked is None:
1255
1272
  ranked = self._rank_tfidf(query, query_tokens, query_bigrams, filters,
1256
1273
  exact_ids, max_mtime)
1274
+ # Provenance (2.110.0): which list(s) produced each id, so the tool
1275
+ # can label a hit ``[lexical+dense]`` instead of leaving the agent to
1276
+ # guess why an unrelated-looking chunk ranked. Empty = lexical only.
1277
+ provenance: dict = {}
1278
+ reranked_ids: set = set()
1257
1279
  if fuse:
1258
- ranked = self._fuse_dense(query, ranked, filters, exact_ids, want=top_k)
1280
+ ranked = self._fuse_dense(query, ranked, filters, exact_ids, want=top_k,
1281
+ provenance=provenance)
1259
1282
  if rerank_now:
1260
- ranked = self._apply_rerank(query, base_tokens, ranked, exact_ids)
1283
+ ranked = self._apply_rerank(query, base_tokens, ranked, exact_ids,
1284
+ reranked=reranked_ids)
1261
1285
 
1262
1286
  # Collect results up to token budget
1263
1287
  results = []
@@ -1298,6 +1322,12 @@ class CodeIndex:
1298
1322
  # a windowed class scores low on TF-IDF and is still the
1299
1323
  # definition the query named.
1300
1324
  result["exact_symbol"] = True
1325
+ sources = ["symbol"] if chunk_id in exact_ids else []
1326
+ lists = provenance[chunk_id] if chunk_id in provenance else {"lexical"}
1327
+ sources.extend(s for s in ("lexical", "dense") if s in lists)
1328
+ result["via"] = "+".join(sources)
1329
+ if chunk_id in reranked_ids:
1330
+ result["reranked"] = True
1301
1331
  if include_content:
1302
1332
  result["content"] = window["content"] if window else chunk["content"]
1303
1333