code-context-control 2.110.0__tar.gz → 2.111.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 (485) hide show
  1. {code_context_control-2.110.0 → code_context_control-2.111.0}/PKG-INFO +1 -1
  2. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/c3.py +36 -1
  3. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/commands/parser.py +13 -0
  4. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/_helpers.py +8 -3
  5. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/shell.py +161 -43
  6. {code_context_control-2.110.0 → code_context_control-2.111.0}/code_context_control.egg-info/PKG-INFO +1 -1
  7. {code_context_control-2.110.0 → code_context_control-2.111.0}/code_context_control.egg-info/SOURCES.txt +4 -0
  8. {code_context_control-2.110.0 → code_context_control-2.111.0}/pyproject.toml +1 -1
  9. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/agents.py +49 -5
  10. code_context_control-2.111.0/services/bench/shell_eval.py +616 -0
  11. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/claude_md.py +18 -14
  12. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/session_manager.py +11 -1
  13. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/telemetry.py +57 -0
  14. code_context_control-2.111.0/tests/test_claude_md_updater.py +163 -0
  15. code_context_control-2.111.0/tests/test_shell_eval.py +275 -0
  16. code_context_control-2.111.0/tests/test_shell_telemetry_s0.py +240 -0
  17. {code_context_control-2.110.0 → code_context_control-2.111.0}/LICENSE +0 -0
  18. {code_context_control-2.110.0 → code_context_control-2.111.0}/README.md +0 -0
  19. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/__init__.py +0 -0
  20. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/_hook_utils.py +0 -0
  21. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/_shell_writes.py +0 -0
  22. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/commands/__init__.py +0 -0
  23. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/commands/common.py +0 -0
  24. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/docs.html +0 -0
  25. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/edits.html +0 -0
  26. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/guide/access.html +0 -0
  27. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/guide/bitbucket.html +0 -0
  28. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/guide/credentials.html +0 -0
  29. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/guide/getting-started.html +0 -0
  30. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/guide/index.html +0 -0
  31. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/guide/masking.html +0 -0
  32. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/guide/oracle.html +0 -0
  33. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/guide/shared.css +0 -0
  34. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/guide/tools.html +0 -0
  35. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/guide/workflow.html +0 -0
  36. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hook_access_guard.py +0 -0
  37. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hook_artifact.py +0 -0
  38. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hook_auto_snapshot.py +0 -0
  39. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hook_c3_signal.py +0 -0
  40. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hook_c3read.py +0 -0
  41. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hook_dispatch.py +0 -0
  42. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hook_edit_ledger.py +0 -0
  43. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hook_edit_unlock.py +0 -0
  44. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hook_filter.py +0 -0
  45. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hook_ghost_files.py +0 -0
  46. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hook_pretool_enforce.py +0 -0
  47. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hook_prompt_recall.py +0 -0
  48. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hook_read.py +0 -0
  49. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hook_session_stats.py +0 -0
  50. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hook_terse_advisor.py +0 -0
  51. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_server.py +0 -0
  52. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/app.js +0 -0
  53. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/add_project.js +0 -0
  54. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/config_editor.js +0 -0
  55. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
  56. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/drill_health.js +0 -0
  57. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/drill_panel.js +0 -0
  58. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
  59. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/drill_tasks.js +0 -0
  60. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/drill_views.js +0 -0
  61. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/global_search.js +0 -0
  62. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/hub_access.js +0 -0
  63. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/hub_ci.js +0 -0
  64. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/hub_cred_audit.js +0 -0
  65. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/hub_credentials.js +0 -0
  66. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
  67. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/hub_locks.js +0 -0
  68. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/hub_tokens.js +0 -0
  69. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/mcp_manager.js +0 -0
  70. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/modals.js +0 -0
  71. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/project_card.js +0 -0
  72. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/project_tree.js +0 -0
  73. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/session_drawer.js +0 -0
  74. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/settings_modal.js +0 -0
  75. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/sidebar.js +0 -0
  76. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/summary_bar.js +0 -0
  77. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/task_board.js +0 -0
  78. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/toasts.js +0 -0
  79. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/components/topbar.js +0 -0
  80. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui/state.js +0 -0
  81. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/hub_ui.html +0 -0
  82. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/mcp_proxy.py +0 -0
  83. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/mcp_server.py +0 -0
  84. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/progress.py +0 -0
  85. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/server.py +0 -0
  86. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/__init__.py +0 -0
  87. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/_grants.py +0 -0
  88. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/agent.py +0 -0
  89. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/artifacts.py +0 -0
  90. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/bitbucket.py +0 -0
  91. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/ci.py +0 -0
  92. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/compress.py +0 -0
  93. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/credentials.py +0 -0
  94. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/delegate.py +0 -0
  95. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/edit.py +0 -0
  96. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/edit_verify.py +0 -0
  97. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/edits.py +0 -0
  98. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/federate.py +0 -0
  99. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/filter.py +0 -0
  100. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/impact.py +0 -0
  101. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/jira.py +0 -0
  102. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/locks.py +0 -0
  103. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/memory.py +0 -0
  104. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/override.py +0 -0
  105. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/project.py +0 -0
  106. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/read.py +0 -0
  107. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/search.py +0 -0
  108. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/session.py +0 -0
  109. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/status.py +0 -0
  110. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/tasks.py +0 -0
  111. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/tools/validate.py +0 -0
  112. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/api.js +0 -0
  113. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/app.js +0 -0
  114. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/components/access.js +0 -0
  115. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/components/bitbucket.js +0 -0
  116. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/components/chat.js +0 -0
  117. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/components/credentials.js +0 -0
  118. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/components/dashboard.js +0 -0
  119. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/components/edits.js +0 -0
  120. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/components/enforcement.js +0 -0
  121. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/components/instructions.js +0 -0
  122. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/components/jira.js +0 -0
  123. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/components/memory.js +0 -0
  124. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/components/sessions.js +0 -0
  125. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/components/settings.js +0 -0
  126. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/components/sidebar.js +0 -0
  127. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/components/tasks.js +0 -0
  128. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/icons.js +0 -0
  129. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/pm_shared.js +0 -0
  130. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/shared.js +0 -0
  131. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui/theme.js +0 -0
  132. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui.html +0 -0
  133. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui_legacy.html +0 -0
  134. {code_context_control-2.110.0 → code_context_control-2.111.0}/cli/ui_nano.html +0 -0
  135. {code_context_control-2.110.0 → code_context_control-2.111.0}/code_context_control.egg-info/dependency_links.txt +0 -0
  136. {code_context_control-2.110.0 → code_context_control-2.111.0}/code_context_control.egg-info/entry_points.txt +0 -0
  137. {code_context_control-2.110.0 → code_context_control-2.111.0}/code_context_control.egg-info/requires.txt +0 -0
  138. {code_context_control-2.110.0 → code_context_control-2.111.0}/code_context_control.egg-info/top_level.txt +0 -0
  139. {code_context_control-2.110.0 → code_context_control-2.111.0}/core/__init__.py +0 -0
  140. {code_context_control-2.110.0 → code_context_control-2.111.0}/core/config.py +0 -0
  141. {code_context_control-2.110.0 → code_context_control-2.111.0}/core/ide.py +0 -0
  142. {code_context_control-2.110.0 → code_context_control-2.111.0}/core/mcp_toml.py +0 -0
  143. {code_context_control-2.110.0 → code_context_control-2.111.0}/core/web_security.py +0 -0
  144. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/__init__.py +0 -0
  145. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/config.py +0 -0
  146. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/mcp_oracle.py +0 -0
  147. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/oracle_server.py +0 -0
  148. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/oracle_ui.html +0 -0
  149. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/__init__.py +0 -0
  150. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/activity_reporter.py +0 -0
  151. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/api_auth.py +0 -0
  152. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/c3_bridge.py +0 -0
  153. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/chat_engine.py +0 -0
  154. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/chat_poll.py +0 -0
  155. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/chat_store.py +0 -0
  156. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/cross_memory.py +0 -0
  157. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/discovery_audit.py +0 -0
  158. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/federated_graph.py +0 -0
  159. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/health_checker.py +0 -0
  160. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/insight_engine.py +0 -0
  161. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/local_session.py +0 -0
  162. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/memory_reader.py +0 -0
  163. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/memory_writer.py +0 -0
  164. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/mobile_api.py +0 -0
  165. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/project_scanner.py +0 -0
  166. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/review_agent.py +0 -0
  167. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/tool_executor.py +0 -0
  168. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/services/tool_registry.py +0 -0
  169. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/activity.js +0 -0
  170. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/agents.js +0 -0
  171. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/app.js +0 -0
  172. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/busy.js +0 -0
  173. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/chat/conversations.js +0 -0
  174. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/chat/input.js +0 -0
  175. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/chat/markdown.js +0 -0
  176. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/chat/send.js +0 -0
  177. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/chat/stream_renderer.js +0 -0
  178. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/chat/toolbar.js +0 -0
  179. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/core.js +0 -0
  180. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/crossgraph.js +0 -0
  181. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/header.js +0 -0
  182. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/insights.js +0 -0
  183. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/projects.js +0 -0
  184. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/qrcode.js +0 -0
  185. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/settings.js +0 -0
  186. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/suggestions.js +0 -0
  187. {code_context_control-2.110.0 → code_context_control-2.111.0}/oracle/ui/theme_tabs.js +0 -0
  188. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/__init__.py +0 -0
  189. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/access_guard.py +0 -0
  190. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/access_telemetry.py +0 -0
  191. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/activity_log.py +0 -0
  192. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/agent_base.py +0 -0
  193. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/agent_locks.py +0 -0
  194. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/artifact_defs.py +0 -0
  195. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/artifact_store.py +0 -0
  196. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/auto_memory.py +0 -0
  197. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/background_service.py +0 -0
  198. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/bench/__init__.py +0 -0
  199. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/bench/external/__init__.py +0 -0
  200. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/bench/external/aider_polyglot.py +0 -0
  201. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/bench/external/swe_bench.py +0 -0
  202. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/bench/search_eval.py +0 -0
  203. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/benchmark_dashboard.py +0 -0
  204. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/bitbucket_client.py +0 -0
  205. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/bitbucket_credentials.py +0 -0
  206. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/ci_act.py +0 -0
  207. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/ci_cache.py +0 -0
  208. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/ci_expr.py +0 -0
  209. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/ci_failures.py +0 -0
  210. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/ci_github.py +0 -0
  211. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/ci_impact.py +0 -0
  212. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/ci_intel.py +0 -0
  213. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/ci_runner.py +0 -0
  214. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/ci_workflow.py +0 -0
  215. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/circuit_breaker.py +0 -0
  216. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/compressor.py +0 -0
  217. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/context_snapshot.py +0 -0
  218. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/conversation_store.py +0 -0
  219. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/cred_audit.py +0 -0
  220. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/cred_telemetry.py +0 -0
  221. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/credential_store.py +0 -0
  222. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/doc_index.py +0 -0
  223. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/e2e_benchmark.py +0 -0
  224. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/e2e_evaluator.py +0 -0
  225. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/e2e_tasks.py +0 -0
  226. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/edit_ledger.py +0 -0
  227. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/embedding_index.py +0 -0
  228. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/enforcement_policy.py +0 -0
  229. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/error_reporting.py +0 -0
  230. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/file_memory.py +0 -0
  231. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/git_context.py +0 -0
  232. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/hub_service.py +0 -0
  233. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/index_store.py +0 -0
  234. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/indexer.py +0 -0
  235. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/jira_client.py +0 -0
  236. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/jira_cloud.py +0 -0
  237. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/jira_credentials.py +0 -0
  238. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/jira_data_center.py +0 -0
  239. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/jira_links.py +0 -0
  240. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/lexical_index.py +0 -0
  241. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/mask_activation.py +0 -0
  242. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/mask_mirror.py +0 -0
  243. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/mask_presets.py +0 -0
  244. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/memory.py +0 -0
  245. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/memory_consolidator.py +0 -0
  246. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/memory_distiller.py +0 -0
  247. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/memory_graph.py +0 -0
  248. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/memory_grounder.py +0 -0
  249. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/memory_queue.py +0 -0
  250. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/memory_scorer.py +0 -0
  251. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/metrics.py +0 -0
  252. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/notifications.py +0 -0
  253. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/ollama_bridge.py +0 -0
  254. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/ollama_client.py +0 -0
  255. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/ollama_credentials.py +0 -0
  256. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/oracle_service.py +0 -0
  257. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/output_filter.py +0 -0
  258. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/override_grants.py +0 -0
  259. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/override_policy.py +0 -0
  260. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/override_requests.py +0 -0
  261. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/override_wake.py +0 -0
  262. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/parser.py +0 -0
  263. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/project_manager.py +0 -0
  264. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/project_runtime.py +0 -0
  265. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/protocol.py +0 -0
  266. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/proxy_state.py +0 -0
  267. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/repo_map.py +0 -0
  268. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/repo_shape.py +0 -0
  269. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/reranker.py +0 -0
  270. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/retention.py +0 -0
  271. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/retrieval.py +0 -0
  272. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/retrieval_broker.py +0 -0
  273. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/router.py +0 -0
  274. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/runtime.py +0 -0
  275. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/scanner.py +0 -0
  276. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/session_benchmark.py +0 -0
  277. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/session_preloader.py +0 -0
  278. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/subprojects.py +0 -0
  279. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/task_store.py +0 -0
  280. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/text_index.py +0 -0
  281. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/time_tracker.py +0 -0
  282. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/tool_classifier.py +0 -0
  283. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/transcript_index.py +0 -0
  284. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/validation_cache.py +0 -0
  285. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/vector_store.py +0 -0
  286. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/watcher.py +0 -0
  287. {code_context_control-2.110.0 → code_context_control-2.111.0}/services/win_subprocess.py +0 -0
  288. {code_context_control-2.110.0 → code_context_control-2.111.0}/setup.cfg +0 -0
  289. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_access_builtin_optout.py +0 -0
  290. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_access_guard.py +0 -0
  291. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_access_guard_meta.py +0 -0
  292. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_access_guard_shell_project.py +0 -0
  293. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_access_guard_surfaces.py +0 -0
  294. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_access_guard_wiring.py +0 -0
  295. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_activity_reporter.py +0 -0
  296. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_agent_locks.py +0 -0
  297. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_aider_polyglot.py +0 -0
  298. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_antigravity_transition.py +0 -0
  299. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_artifact_store.py +0 -0
  300. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_artifact_tool.py +0 -0
  301. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_background_service.py +0 -0
  302. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_bitbucket_cli_smoke.py +0 -0
  303. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_bitbucket_client.py +0 -0
  304. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_bitbucket_config_fallback.py +0 -0
  305. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_bitbucket_credentials.py +0 -0
  306. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_bitbucket_tool.py +0 -0
  307. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_builtin_modes.py +0 -0
  308. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
  309. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_c3_shell.py +0 -0
  310. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_chat_poll.py +0 -0
  311. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_ci_act.py +0 -0
  312. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_ci_cache.py +0 -0
  313. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_ci_expr.py +0 -0
  314. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_ci_impact.py +0 -0
  315. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_ci_intel.py +0 -0
  316. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_ci_runner.py +0 -0
  317. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_ci_workflow.py +0 -0
  318. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_circuit_breaker.py +0 -0
  319. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_claude_md_merge.py +0 -0
  320. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_cli_smoke.py +0 -0
  321. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_compressor_large_file.py +0 -0
  322. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_confirm_guard.py +0 -0
  323. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_confirm_guard_wiring.py +0 -0
  324. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_cooccurrence_bounds.py +0 -0
  325. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_cred_audit.py +0 -0
  326. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_cred_telemetry.py +0 -0
  327. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_credential_login_kind.py +0 -0
  328. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_credential_store.py +0 -0
  329. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_credential_ui_parity.py +0 -0
  330. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_credentials_routes.py +0 -0
  331. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_credentials_tool.py +0 -0
  332. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_creds_cli_smoke.py +0 -0
  333. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_delegate_cascade.py +0 -0
  334. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_delegate_version_probe.py +0 -0
  335. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_e2e_benchmark.py +0 -0
  336. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_edit_ledger_deadline.py +0 -0
  337. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_edit_ledger_hook.py +0 -0
  338. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_edit_locking.py +0 -0
  339. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_edit_normalization.py +0 -0
  340. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_edit_verify.py +0 -0
  341. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_embedding_index_deadlock.py +0 -0
  342. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_enforcement_flip.py +0 -0
  343. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_enforcement_policy.py +0 -0
  344. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_enforcement_routes.py +0 -0
  345. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_env_parser.py +0 -0
  346. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_failed_calls_do_not_unlock.py +0 -0
  347. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_federated_graph.py +0 -0
  348. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_filter_backoff.py +0 -0
  349. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_ghost_files.py +0 -0
  350. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_ghost_generation.py +0 -0
  351. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_git_branch_awareness.py +0 -0
  352. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_hook_access_guard.py +0 -0
  353. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_hook_codex_compat.py +0 -0
  354. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_hook_dispatch.py +0 -0
  355. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_hook_pretool_enforce.py +0 -0
  356. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_hook_prompt_recall.py +0 -0
  357. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_hook_smoke.py +0 -0
  358. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_hook_state.py +0 -0
  359. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_hook_utf8_stdio.py +0 -0
  360. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_hub_credentials_route.py +0 -0
  361. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_hub_credentials_routes_write.py +0 -0
  362. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_hub_enforcement_routes.py +0 -0
  363. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_hub_inspect_api.py +0 -0
  364. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_hub_locks_routes.py +0 -0
  365. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_hub_oracle_service_routes.py +0 -0
  366. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_hub_override_routes.py +0 -0
  367. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_hub_server_smoke.py +0 -0
  368. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_hub_subproject_links.py +0 -0
  369. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_ide_workflow_adaptation.py +0 -0
  370. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_index_cap_not_hardcoded.py +0 -0
  371. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_init_clear_preserves_user_content.py +0 -0
  372. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_init_scan.py +0 -0
  373. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_install_mcp_entrypoint.py +0 -0
  374. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_jira_cli_smoke.py +0 -0
  375. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_jira_client.py +0 -0
  376. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_jira_config_fallback.py +0 -0
  377. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_jira_credentials.py +0 -0
  378. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_jira_links.py +0 -0
  379. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_jira_routes.py +0 -0
  380. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_jira_tool.py +0 -0
  381. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_lazy_store_init.py +0 -0
  382. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_mask_guard.py +0 -0
  383. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_mask_routes.py +0 -0
  384. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_mask_surfaces.py +0 -0
  385. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_mcp_host_guard.py +0 -0
  386. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_mcp_memory_timeout.py +0 -0
  387. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_mcp_server_smoke.py +0 -0
  388. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_mcp_toml.py +0 -0
  389. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_memory_distiller.py +0 -0
  390. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_memory_graph_api.py +0 -0
  391. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_memory_queue.py +0 -0
  392. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_memory_system.py +0 -0
  393. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_mobile_api.py +0 -0
  394. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_mobile_extras.py +0 -0
  395. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_mobile_override_routes.py +0 -0
  396. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_mobile_security_api.py +0 -0
  397. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_no_stale_model_pins.py +0 -0
  398. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_notification_dedup.py +0 -0
  399. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_notification_discipline.py +0 -0
  400. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_ollama_credentials.py +0 -0
  401. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_oracle_api_auth.py +0 -0
  402. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_oracle_apikey_api.py +0 -0
  403. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_oracle_c3_bridge.py +0 -0
  404. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_oracle_chat_engine.py +0 -0
  405. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_oracle_chat_store.py +0 -0
  406. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_oracle_discovery_api.py +0 -0
  407. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_oracle_discovery_audit.py +0 -0
  408. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_oracle_health_probe.py +0 -0
  409. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_oracle_local_auth.py +0 -0
  410. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_oracle_ollama_bridge.py +0 -0
  411. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_oracle_scanner_cache.py +0 -0
  412. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_oracle_security_fixes.py +0 -0
  413. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_oracle_session_bootstrap.py +0 -0
  414. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_oracle_subproject_awareness.py +0 -0
  415. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_oracle_ui_bundle.py +0 -0
  416. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_output_filter.py +0 -0
  417. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_override_grants.py +0 -0
  418. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_override_grants_mcp.py +0 -0
  419. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_override_requests.py +0 -0
  420. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_override_wake.py +0 -0
  421. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_permissions.py +0 -0
  422. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_pm_api.py +0 -0
  423. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_project_manager.py +0 -0
  424. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_project_manager_merge.py +0 -0
  425. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_project_tool.py +0 -0
  426. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_read_coercion.py +0 -0
  427. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_read_edit_parity.py +0 -0
  428. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_related_facts.py +0 -0
  429. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_repo_map.py +0 -0
  430. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_repo_shape.py +0 -0
  431. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_response_boilerplate.py +0 -0
  432. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_retention.py +0 -0
  433. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_review_digest.py +0 -0
  434. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_search_eval.py +0 -0
  435. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_search_p1.py +0 -0
  436. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_search_p2.py +0 -0
  437. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_search_p2b.py +0 -0
  438. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_search_p3.py +0 -0
  439. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_search_p4.py +0 -0
  440. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_search_p5.py +0 -0
  441. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_service_durability.py +0 -0
  442. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_session_benchmark.py +0 -0
  443. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_session_budget.py +0 -0
  444. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_shell_creds.py +0 -0
  445. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_shell_robustness.py +0 -0
  446. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_shell_write_ledger.py +0 -0
  447. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_shell_writes.py +0 -0
  448. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_subproject_clear_scope.py +0 -0
  449. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_subproject_depth_consumers.py +0 -0
  450. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_subproject_exclusion.py +0 -0
  451. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_subproject_federation.py +0 -0
  452. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_subproject_linkage_api.py +0 -0
  453. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_subprojects.py +0 -0
  454. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_swe_bench.py +0 -0
  455. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_task_store.py +0 -0
  456. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_task_tool.py +0 -0
  457. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_time_tracker.py +0 -0
  458. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_token_telemetry.py +0 -0
  459. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_token_tracking.py +0 -0
  460. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_tool_registry.py +0 -0
  461. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_ui_jsx_syntax.py +0 -0
  462. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_upgrade_and_version.py +0 -0
  463. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_validate.py +0 -0
  464. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_vault_write_guard.py +0 -0
  465. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_version_sync.py +0 -0
  466. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_web_security.py +0 -0
  467. {code_context_control-2.110.0 → code_context_control-2.111.0}/tests/test_windows_reliability.py +0 -0
  468. {code_context_control-2.110.0 → code_context_control-2.111.0}/tui/__init__.py +0 -0
  469. {code_context_control-2.110.0 → code_context_control-2.111.0}/tui/backend.py +0 -0
  470. {code_context_control-2.110.0 → code_context_control-2.111.0}/tui/main.py +0 -0
  471. {code_context_control-2.110.0 → code_context_control-2.111.0}/tui/screens/__init__.py +0 -0
  472. {code_context_control-2.110.0 → code_context_control-2.111.0}/tui/screens/benchmark_view.py +0 -0
  473. {code_context_control-2.110.0 → code_context_control-2.111.0}/tui/screens/claudemd_view.py +0 -0
  474. {code_context_control-2.110.0 → code_context_control-2.111.0}/tui/screens/compress_view.py +0 -0
  475. {code_context_control-2.110.0 → code_context_control-2.111.0}/tui/screens/index_view.py +0 -0
  476. {code_context_control-2.110.0 → code_context_control-2.111.0}/tui/screens/init_view.py +0 -0
  477. {code_context_control-2.110.0 → code_context_control-2.111.0}/tui/screens/mcp_view.py +0 -0
  478. {code_context_control-2.110.0 → code_context_control-2.111.0}/tui/screens/optimize_view.py +0 -0
  479. {code_context_control-2.110.0 → code_context_control-2.111.0}/tui/screens/pipe_view.py +0 -0
  480. {code_context_control-2.110.0 → code_context_control-2.111.0}/tui/screens/projects_view.py +0 -0
  481. {code_context_control-2.110.0 → code_context_control-2.111.0}/tui/screens/search_view.py +0 -0
  482. {code_context_control-2.110.0 → code_context_control-2.111.0}/tui/screens/session_view.py +0 -0
  483. {code_context_control-2.110.0 → code_context_control-2.111.0}/tui/screens/stats.py +0 -0
  484. {code_context_control-2.110.0 → code_context_control-2.111.0}/tui/screens/ui_view.py +0 -0
  485. {code_context_control-2.110.0 → code_context_control-2.111.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.110.0
3
+ Version: 2.111.0
4
4
  Summary: Local MCP code-intelligence for AI coding tools: surgical search/read/edit, agent-config version history, path-level access + masking guards, and a multi-project hub.
5
5
  Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -92,7 +92,7 @@ console = Console() if HAS_RICH else None
92
92
  # Config
93
93
  CONFIG_DIR = ".c3"
94
94
  CONFIG_FILE = ".c3/config.json"
95
- __version__ = "2.110.0"
95
+ __version__ = "2.111.0"
96
96
 
97
97
 
98
98
  def _compress_file_cli(compressor, path, mode="smart", **kw):
@@ -1536,6 +1536,40 @@ def cmd_search_eval(args):
1536
1536
  sys.exit(1)
1537
1537
 
1538
1538
 
1539
+ def cmd_shell_eval(args):
1540
+ """Run the c3_shell output-shaping suite and compare it to its baseline.
1541
+
1542
+ Exit status 1 when the baseline is violated (a must_pass case failed, an
1543
+ aggregate fell under its floor or rose over its ceiling). See
1544
+ docs/shell-eval.md.
1545
+ """
1546
+ from services.bench import shell_eval as she
1547
+
1548
+ try:
1549
+ report = she.run_suite(args.suite, baseline=args.baseline)
1550
+ except FileNotFoundError as e:
1551
+ raise RuntimeError(str(e))
1552
+
1553
+ if args.update_baseline:
1554
+ path = args.baseline or she.BUNDLED_BASELINES.get(report.suite)
1555
+ if not path:
1556
+ raise RuntimeError(
1557
+ f"suite {report.suite!r} has no bundled baseline; pass --baseline PATH")
1558
+ floors = json.loads(args.floors) if args.floors else None
1559
+ ceilings = json.loads(args.ceilings) if args.ceilings else None
1560
+ she.write_baseline(report, path, floors=floors, ceilings=ceilings)
1561
+ report.baseline_violations, report.baseline_warnings = she.compare_to_baseline(
1562
+ report, she.load_baseline(path))
1563
+ print(f"baseline written: {path}")
1564
+
1565
+ if args.json:
1566
+ print(json.dumps(report.to_dict(), indent=2))
1567
+ else:
1568
+ print(report.render())
1569
+ if report.baseline_violations:
1570
+ sys.exit(1)
1571
+
1572
+
1539
1573
  def _benchmark_extract_preview(full_path: Path, compressor: CodeCompressor, pattern: str = "", max_lines: int = 50) -> str:
1540
1574
  """Approximate c3_filter behavior for local benchmarking without MCP startup."""
1541
1575
  import re as _re
@@ -9200,6 +9234,7 @@ def main():
9200
9234
  "map": cmd_map,
9201
9235
  "stats": cmd_stats,
9202
9236
  "search-eval": cmd_search_eval,
9237
+ "shell-eval": cmd_shell_eval,
9203
9238
  "benchmark": cmd_benchmark,
9204
9239
  "session-benchmark": cmd_session_benchmark,
9205
9240
  "benchmark-e2e": cmd_benchmark_e2e,
@@ -59,6 +59,19 @@ def build_parser(version: str, parse_cli_ide_arg):
59
59
  help='With --update-baseline: JSON object of metric floors, e.g. \'{"mrr": 0.85}\'')
60
60
  p_search_eval.add_argument("--json", action="store_true", help="Emit the full report as JSON")
61
61
 
62
+ p_shell_eval = subparsers.add_parser(
63
+ "shell-eval", help="Run the c3_shell output-shaping suite (docs/shell-eval.md)")
64
+ p_shell_eval.add_argument("--suite", default="fixture",
65
+ help="'fixture' (synthetic outputs, CI gate) or a .jsonl path")
66
+ p_shell_eval.add_argument("--baseline", default=None, help="Baseline JSON to compare against / write")
67
+ p_shell_eval.add_argument("--update-baseline", action="store_true",
68
+ help="Write aggregates + per-case status to the baseline (floors/ceilings are kept)")
69
+ p_shell_eval.add_argument("--floors", default=None,
70
+ help='With --update-baseline: JSON object of metric floors, e.g. \'{"must_keep_retention": 0.9}\'')
71
+ p_shell_eval.add_argument("--ceilings", default=None,
72
+ help='With --update-baseline: JSON object of metric ceilings, e.g. \'{"bytes_p95": 18432}\'')
73
+ p_shell_eval.add_argument("--json", action="store_true", help="Emit the full report as JSON")
74
+
62
75
  p_compress = subparsers.add_parser("compress", help="Compress a file")
63
76
  p_compress.add_argument("file", help="File to compress")
64
77
  p_compress.add_argument("--mode", choices=["map", "dense_map", "smart", "diff"], default="smart")
@@ -81,7 +81,7 @@ def show_token_ratios(svc) -> bool:
81
81
  def finalize_with_tokens(finalize, svc, tool_name: str, args: dict,
82
82
  response: str, summary: str = "", *,
83
83
  raw_tokens=None, optimized_tokens=None,
84
- duration_ms=None, **finalize_kwargs) -> str:
84
+ duration_ms=None, detail=None, **finalize_kwargs) -> str:
85
85
  """Finalize a tool response with STRUCTURED token accounting.
86
86
 
87
87
  This is the primary accounting path: tools pass explicitly measured
@@ -100,6 +100,10 @@ def finalize_with_tokens(finalize, svc, tool_name: str, args: dict,
100
100
  ``estimated_saved_vs_full_read`` in session token_usage and in the
101
101
  per-tool telemetry JSONL (.c3/tool_telemetry.jsonl).
102
102
 
103
+ ``detail`` is an optional flat dict of tool-specific facts about this
104
+ call; it lands under the telemetry record's ``detail`` key (see
105
+ SessionManager.record_tool_tokens).
106
+
103
107
  Failure-safe: accounting errors never break the tool response. Any extra
104
108
  keyword args (e.g. response_tokens) are forwarded to ``finalize``.
105
109
  """
@@ -107,10 +111,11 @@ def finalize_with_tokens(finalize, svc, tool_name: str, args: dict,
107
111
  session_mgr = getattr(svc, "session_mgr", None)
108
112
  if session_mgr is not None and (
109
113
  raw_tokens is not None or optimized_tokens is not None
110
- or duration_ms is not None):
114
+ or duration_ms is not None or detail):
111
115
  session_mgr.record_tool_tokens(
112
116
  tool_name, raw_tokens=raw_tokens,
113
- optimized_tokens=optimized_tokens, duration_ms=duration_ms)
117
+ optimized_tokens=optimized_tokens, duration_ms=duration_ms,
118
+ detail=detail)
114
119
  except Exception:
115
120
  pass
116
121
  return finalize(tool_name, args, response, summary, **finalize_kwargs)
@@ -27,6 +27,7 @@ from pathlib import Path
27
27
 
28
28
  from cli._shell_writes import shell_write_targets
29
29
  from cli.tools import _grants
30
+ from cli.tools._helpers import finalize_with_tokens
30
31
  from cli.tools.filter import handle_filter
31
32
  from core import count_tokens
32
33
  from services import access_guard
@@ -366,6 +367,149 @@ def _dependency_hint(cmd: str, result: dict) -> str:
366
367
  )
367
368
 
368
369
 
370
+ # ── Command classification (telemetry only) ─────────────────────────────────
371
+ #
372
+ # A coarse label per call so .c3/tool_telemetry.jsonl can say which KIND of
373
+ # command carries the tokens and the wall time. Measured 2026-09-04 over 7,278
374
+ # shell_exec events: file-read/search 48%, python 10%, git 10%, tests 5%,
375
+ # ops/device 4%, build/lint 4%. Best-effort: the first word after any leading
376
+ # `cd … &&` / `VAR=… ;` prefix, plus a few substring tells. Never used to
377
+ # change behaviour.
378
+
379
+ _CLASS_PREFIX = re.compile(
380
+ r"""^(?:\s*(?:cd\s+(?:"[^"]*"|'[^']*'|\S+)\s*(?:&&|;)\s*|\w+=(?:"[^"]*"|'[^']*'|\S*)\s*;?\s*))*""")
381
+ _CLASS_TESTS = re.compile(
382
+ r"\b(?:pytest|python\s+-m\s+(?:pytest|unittest)|npm\s+test|vitest|jest|cargo\s+test|go\s+test)\b")
383
+ _CLASS_TABLE = {
384
+ "file-read": {"cat", "head", "tail", "sed", "grep", "rg", "find", "ls", "wc",
385
+ "awk", "tree", "type", "less", "more", "stat", "file", "du"},
386
+ "git": {"git"},
387
+ "python": {"python", "python3", "py", "pythonw", "pip", "uv"},
388
+ "build": {"npm", "npx", "node", "pnpm", "yarn", "tsc", "eslint", "vite",
389
+ "gradlew", "cargo", "go", "make", "ruff", "mypy", "pyright",
390
+ "dotnet", "mvn", "gradle"},
391
+ "ops": {"curl", "wget", "adb", "powershell", "pwsh", "schtasks", "tasklist",
392
+ "taskkill", "netstat", "ps", "kill", "sleep", "timeout", "ssh",
393
+ "scp", "docker", "systemctl", "sc"},
394
+ "echo": {"echo", "printf", "test", "[", "true", "false"},
395
+ "gh": {"gh"},
396
+ "c3": {"c3", "c3-mcp"},
397
+ }
398
+
399
+
400
+ def _cmd_class(cmd: str) -> str:
401
+ """Coarse command class for telemetry (see table above)."""
402
+ try:
403
+ if _CLASS_TESTS.search(cmd):
404
+ return "tests"
405
+ rest = _CLASS_PREFIX.sub("", cmd.strip())
406
+ head = rest.split(None, 1)[0] if rest.split() else ""
407
+ head = head.rsplit("/", 1)[-1].rsplit("\\", 1)[-1].lower()
408
+ if head.endswith(".exe"):
409
+ head = head[:-4]
410
+ if head.startswith("python"):
411
+ head = "python"
412
+ for label, names in _CLASS_TABLE.items():
413
+ if head in names:
414
+ return label
415
+ return "other"
416
+ except Exception:
417
+ return "other"
418
+
419
+
420
+ def _longest_line(*texts: str) -> int:
421
+ longest = 0
422
+ for text in texts:
423
+ if not text:
424
+ continue
425
+ for line in text.split("\n"):
426
+ if len(line) > longest:
427
+ longest = len(line)
428
+ return longest
429
+
430
+
431
+ def render_shell_response(cmd: str, result: dict, svc, *,
432
+ filter_output: bool = True, warn: str = "",
433
+ capped_note: str = "", touched_files=(),
434
+ cred_names=(), swept_ghosts=()) -> tuple[str, dict]:
435
+ """Turn a finished command into the body the agent reads, plus its stats.
436
+
437
+ Pure with respect to the subprocess: ``result`` is the dict _run_sync
438
+ returns (exit_code, stdout, stderr, duration_ms, timed_out, shell), so
439
+ the shell-eval harness (services/bench/shell_eval.py) can feed captured
440
+ or synthetic streams through exactly the code path a live call uses.
441
+ Runs the same auto-filter handle_shell always ran — only stdout, only when
442
+ it has more than _FILTER_THRESHOLD_LINES newlines, never for a git
443
+ diagnostic — and assembles the same sections in the same order.
444
+
445
+ ``stats`` is what telemetry records about the call (see
446
+ SessionManager.record_tool_tokens ``detail``): stdout_bytes and
447
+ stderr_bytes are measured BEFORE filtering so a later budget phase can
448
+ size the band it changes; longest_line is the tell for the single-line
449
+ monsters (minified bundles, JSONL) that a newline-count trigger never
450
+ sees; filtered/spilled/output_id describe what this renderer did.
451
+ """
452
+ raw_stdout = result.get("stdout") or ""
453
+ raw_stderr = result.get("stderr") or ""
454
+ stats: dict = {
455
+ "exit_code": result.get("exit_code"),
456
+ "timed_out": bool(result.get("timed_out")),
457
+ "stdout_bytes": len(raw_stdout.encode("utf-8", errors="replace")),
458
+ "stderr_bytes": len(raw_stderr.encode("utf-8", errors="replace")),
459
+ "longest_line": _longest_line(raw_stdout, raw_stderr),
460
+ "filtered": False,
461
+ "spilled": False,
462
+ "output_id": None,
463
+ "cmd_class": _cmd_class(cmd),
464
+ }
465
+
466
+ stdout = raw_stdout
467
+ filtered_note = ""
468
+ if (filter_output and raw_stdout.count("\n") > _FILTER_THRESHOLD_LINES
469
+ and not _GIT_DIAGNOSTIC.search(cmd)):
470
+ try:
471
+ stdout = handle_filter(
472
+ "", raw_stdout, "", 50, "smart", True,
473
+ svc, lambda *a, **kw: a[2],
474
+ )
475
+ filtered_note = " [stdout filtered]"
476
+ stats["filtered"] = True
477
+ except Exception:
478
+ stdout = raw_stdout
479
+
480
+ if result.get("timed_out"):
481
+ status = "TIMEOUT"
482
+ elif result.get("exit_code") == 0:
483
+ status = "OK"
484
+ else:
485
+ status = f"FAIL({result.get('exit_code')})"
486
+
487
+ body = (
488
+ f"{warn}{capped_note}"
489
+ f"[c3_shell:{status}] {result.get('duration_ms', 0)}ms{filtered_note}\n"
490
+ f"$ {cmd}\n"
491
+ f"--- stdout ---\n{stdout.rstrip()}\n"
492
+ )
493
+ if raw_stderr.strip():
494
+ body += f"--- stderr ---\n{raw_stderr.rstrip()}\n"
495
+ dependency_hint = _dependency_hint(cmd, result)
496
+ if dependency_hint:
497
+ body += f"--- hint ---\n{dependency_hint}\n"
498
+ if touched_files:
499
+ body += f"--- ledger ---\nlogged {len(touched_files)} file(s)\n"
500
+ if cred_names:
501
+ body += f"--- creds ---\ninjected: {', '.join(cred_names)}\n"
502
+ if swept_ghosts:
503
+ body += (
504
+ f"--- ghost-sweep ---\nremoved {len(swept_ghosts)} stray 0-byte "
505
+ f"file(s): {', '.join(swept_ghosts)}\n"
506
+ )
507
+
508
+ stats["response_bytes"] = len(body.encode("utf-8", errors="replace"))
509
+ stats["response_tokens"] = count_tokens(body) if body else 0
510
+ return body, stats
511
+
512
+
369
513
  # ── Access Guard advisory scanner (T2c) ────────────────────────────────────
370
514
  # ADVISORY ONLY — this is best-effort, NEVER enforcement. A shell command can
371
515
  # reach paths through subshells, variables, globs, quoting, and indirection
@@ -753,22 +897,6 @@ async def handle_shell(cmd: str, cwd: str, timeout: int, filter_output: bool,
753
897
  except Exception:
754
898
  pass
755
899
 
756
- raw_stdout = result["stdout"]
757
- filtered_note = ""
758
- if (filter_output and raw_stdout.count("\n") > _FILTER_THRESHOLD_LINES
759
- and not _GIT_DIAGNOSTIC.search(cmd)):
760
- try:
761
- filtered = await asyncio.to_thread(
762
- handle_filter,
763
- "", raw_stdout, "", 50, "smart", True,
764
- svc, lambda *a, **kw: a[2],
765
- )
766
- result["stdout_raw_bytes"] = len(raw_stdout)
767
- result["stdout"] = filtered
768
- filtered_note = " [stdout filtered]"
769
- except Exception:
770
- pass
771
-
772
900
  touched_files: list[str] = []
773
901
  if log:
774
902
  touched_files = _maybe_refresh_ledger(
@@ -796,51 +924,41 @@ async def handle_shell(cmd: str, cwd: str, timeout: int, filter_output: bool,
796
924
  warn = granted + "\n"
797
925
  else:
798
926
  warn = "[c3_shell:warn] destructive pattern detected — verify before re-running\n"
927
+ capped_note = ""
799
928
  if capped_from:
800
929
  # Named at the moment of the mistake, not in documentation nobody
801
930
  # reads at the moment they need it. The alternative IS the escape
802
931
  # hatch, so the line says which one.
803
- warn += (
932
+ capped_note = (
804
933
  f"[c3_shell:capped] timeout={capped_from}s was requested but this "
805
934
  f"MCP client kills a tool call at {_ceiling}s; ran with {timeout}s. "
806
935
  f"For longer work use the native Bash tool with "
807
936
  f"run_in_background, which is not bound by this limit.\n"
808
937
  )
809
938
 
939
+ body, stats = await asyncio.to_thread(
940
+ render_shell_response, cmd, result, svc,
941
+ filter_output=filter_output, warn=warn, capped_note=capped_note,
942
+ touched_files=touched_files, cred_names=cred_names,
943
+ swept_ghosts=swept_ghosts,
944
+ )
945
+
810
946
  if result["timed_out"]:
811
947
  status = "TIMEOUT"
812
948
  elif result["exit_code"] == 0:
813
949
  status = "OK"
814
950
  else:
815
951
  status = f"FAIL({result['exit_code']})"
816
-
817
- body = (
818
- f"{warn}"
819
- f"[c3_shell:{status}] {result['duration_ms']}ms{filtered_note}\n"
820
- f"$ {cmd}\n"
821
- f"--- stdout ---\n{result['stdout'].rstrip()}\n"
822
- )
823
- if result["stderr"].strip():
824
- body += f"--- stderr ---\n{result['stderr'].rstrip()}\n"
825
- dependency_hint = _dependency_hint(cmd, result)
826
- if dependency_hint:
827
- body += f"--- hint ---\n{dependency_hint}\n"
828
- if touched_files:
829
- body += f"--- ledger ---\nlogged {len(touched_files)} file(s)\n"
830
- if cred_names:
831
- body += f"--- creds ---\ninjected: {', '.join(cred_names)}\n"
832
- if swept_ghosts:
833
- body += (
834
- f"--- ghost-sweep ---\nremoved {len(swept_ghosts)} stray 0-byte "
835
- f"file(s): {', '.join(swept_ghosts)}\n"
836
- )
837
-
838
952
  summary = f"shell {status} in {result['duration_ms']}ms"
839
- resp_tokens = count_tokens(body) if body else 0
840
- return finalize(
841
- "c3_shell",
953
+ # Telemetry: duration was always measured and never recorded (null on
954
+ # 100% of records before 2.111.0); the stats dict is the per-call detail
955
+ # a later budget phase is sized against.
956
+ return finalize_with_tokens(
957
+ finalize, svc, "c3_shell",
842
958
  {"cmd": cmd[:120], "cwd": work_cwd},
843
959
  body,
844
960
  summary,
845
- response_tokens=resp_tokens,
961
+ duration_ms=result.get("duration_ms"),
962
+ detail=stats,
963
+ response_tokens=stats.get("response_tokens", 0),
846
964
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-context-control
3
- Version: 2.110.0
3
+ Version: 2.111.0
4
4
  Summary: Local MCP code-intelligence for AI coding tools: surgical search/read/edit, agent-config version history, path-level access + masking guards, and a multi-project hub.
5
5
  Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -277,6 +277,7 @@ services/watcher.py
277
277
  services/win_subprocess.py
278
278
  services/bench/__init__.py
279
279
  services/bench/search_eval.py
280
+ services/bench/shell_eval.py
280
281
  services/bench/external/__init__.py
281
282
  services/bench/external/aider_polyglot.py
282
283
  services/bench/external/swe_bench.py
@@ -311,6 +312,7 @@ tests/test_ci_runner.py
311
312
  tests/test_ci_workflow.py
312
313
  tests/test_circuit_breaker.py
313
314
  tests/test_claude_md_merge.py
315
+ tests/test_claude_md_updater.py
314
316
  tests/test_cli_smoke.py
315
317
  tests/test_compressor_large_file.py
316
318
  tests/test_confirm_guard.py
@@ -436,7 +438,9 @@ tests/test_service_durability.py
436
438
  tests/test_session_benchmark.py
437
439
  tests/test_session_budget.py
438
440
  tests/test_shell_creds.py
441
+ tests/test_shell_eval.py
439
442
  tests/test_shell_robustness.py
443
+ tests/test_shell_telemetry_s0.py
440
444
  tests/test_shell_write_ledger.py
441
445
  tests/test_shell_writes.py
442
446
  tests/test_subproject_clear_scope.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "code-context-control"
7
- version = "2.110.0"
7
+ version = "2.111.0"
8
8
  description = "Local MCP code-intelligence for AI coding tools: surgical search/read/edit, agent-config version history, path-level access + masking guards, and a multi-project hub."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -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."""