code-context-control 2.121.0__tar.gz → 2.122.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 (511) hide show
  1. {code_context_control-2.121.0/code_context_control.egg-info → code_context_control-2.122.0}/PKG-INFO +1 -1
  2. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/c3.py +1 -1
  3. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/commands/common.py +1 -1
  4. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/commands/parser.py +2 -1
  5. code_context_control-2.122.0/cli/tools/compress.py +251 -0
  6. {code_context_control-2.121.0 → code_context_control-2.122.0/code_context_control.egg-info}/PKG-INFO +1 -1
  7. {code_context_control-2.121.0 → code_context_control-2.122.0}/pyproject.toml +1 -1
  8. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/compressor.py +69 -124
  9. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_compressor_large_file.py +15 -5
  10. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_map_telemetry_c0.py +7 -7
  11. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_response_boilerplate.py +17 -15
  12. code_context_control-2.121.0/cli/tools/compress.py +0 -347
  13. {code_context_control-2.121.0 → code_context_control-2.122.0}/LICENSE +0 -0
  14. {code_context_control-2.121.0 → code_context_control-2.122.0}/README.md +0 -0
  15. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/__init__.py +0 -0
  16. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/_hook_utils.py +0 -0
  17. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/_shell_writes.py +0 -0
  18. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/commands/__init__.py +0 -0
  19. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/docs.html +0 -0
  20. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/edits.html +0 -0
  21. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/guide/access.html +0 -0
  22. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/guide/bitbucket.html +0 -0
  23. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/guide/credentials.html +0 -0
  24. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/guide/getting-started.html +0 -0
  25. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/guide/index.html +0 -0
  26. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/guide/masking.html +0 -0
  27. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/guide/oracle.html +0 -0
  28. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/guide/shared.css +0 -0
  29. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/guide/tools.html +0 -0
  30. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/guide/workflow.html +0 -0
  31. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hook_access_guard.py +0 -0
  32. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hook_artifact.py +0 -0
  33. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hook_auto_snapshot.py +0 -0
  34. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hook_c3_signal.py +0 -0
  35. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hook_c3read.py +0 -0
  36. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hook_codex_lifecycle.py +0 -0
  37. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hook_dispatch.py +0 -0
  38. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hook_edit_ledger.py +0 -0
  39. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hook_edit_unlock.py +0 -0
  40. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hook_filter.py +0 -0
  41. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hook_ghost_files.py +0 -0
  42. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hook_pretool_enforce.py +0 -0
  43. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hook_prompt_recall.py +0 -0
  44. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hook_read.py +0 -0
  45. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hook_session_stats.py +0 -0
  46. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hook_terse_advisor.py +0 -0
  47. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_server.py +0 -0
  48. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/app.js +0 -0
  49. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/add_project.js +0 -0
  50. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/config_editor.js +0 -0
  51. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
  52. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/drill_health.js +0 -0
  53. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/drill_panel.js +0 -0
  54. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
  55. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/drill_tasks.js +0 -0
  56. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/drill_views.js +0 -0
  57. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/global_search.js +0 -0
  58. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/hub_access.js +0 -0
  59. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/hub_ci.js +0 -0
  60. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/hub_cred_audit.js +0 -0
  61. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/hub_credentials.js +0 -0
  62. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
  63. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/hub_locks.js +0 -0
  64. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/hub_tokens.js +0 -0
  65. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/mcp_manager.js +0 -0
  66. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/modals.js +0 -0
  67. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/project_card.js +0 -0
  68. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/project_tree.js +0 -0
  69. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/session_drawer.js +0 -0
  70. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/settings_modal.js +0 -0
  71. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/sidebar.js +0 -0
  72. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/summary_bar.js +0 -0
  73. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/task_board.js +0 -0
  74. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/toasts.js +0 -0
  75. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/components/topbar.js +0 -0
  76. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui/state.js +0 -0
  77. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/hub_ui.html +0 -0
  78. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/mcp_proxy.py +0 -0
  79. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/mcp_server.py +0 -0
  80. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/progress.py +0 -0
  81. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/server.py +0 -0
  82. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/__init__.py +0 -0
  83. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/_grants.py +0 -0
  84. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/_helpers.py +0 -0
  85. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/agent.py +0 -0
  86. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/artifacts.py +0 -0
  87. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/bitbucket.py +0 -0
  88. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/ci.py +0 -0
  89. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/credentials.py +0 -0
  90. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/delegate.py +0 -0
  91. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/edit.py +0 -0
  92. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/edit_verify.py +0 -0
  93. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/edits.py +0 -0
  94. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/federate.py +0 -0
  95. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/filter.py +0 -0
  96. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/impact.py +0 -0
  97. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/jira.py +0 -0
  98. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/locks.py +0 -0
  99. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/memory.py +0 -0
  100. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/override.py +0 -0
  101. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/project.py +0 -0
  102. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/read.py +0 -0
  103. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/search.py +0 -0
  104. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/session.py +0 -0
  105. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/shell.py +0 -0
  106. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/shell_job.py +0 -0
  107. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/shell_nudge.py +0 -0
  108. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/shell_parsers.py +0 -0
  109. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/shell_render.py +0 -0
  110. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/status.py +0 -0
  111. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/tasks.py +0 -0
  112. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/tools/validate.py +0 -0
  113. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/api.js +0 -0
  114. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/app.js +0 -0
  115. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/components/access.js +0 -0
  116. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/components/bitbucket.js +0 -0
  117. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/components/chat.js +0 -0
  118. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/components/credentials.js +0 -0
  119. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/components/dashboard.js +0 -0
  120. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/components/edits.js +0 -0
  121. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/components/enforcement.js +0 -0
  122. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/components/instructions.js +0 -0
  123. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/components/jira.js +0 -0
  124. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/components/memory.js +0 -0
  125. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/components/sessions.js +0 -0
  126. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/components/settings.js +0 -0
  127. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/components/sidebar.js +0 -0
  128. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/components/tasks.js +0 -0
  129. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/icons.js +0 -0
  130. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/pm_shared.js +0 -0
  131. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/shared.js +0 -0
  132. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui/theme.js +0 -0
  133. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui.html +0 -0
  134. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui_legacy.html +0 -0
  135. {code_context_control-2.121.0 → code_context_control-2.122.0}/cli/ui_nano.html +0 -0
  136. {code_context_control-2.121.0 → code_context_control-2.122.0}/code_context_control.egg-info/SOURCES.txt +0 -0
  137. {code_context_control-2.121.0 → code_context_control-2.122.0}/code_context_control.egg-info/dependency_links.txt +0 -0
  138. {code_context_control-2.121.0 → code_context_control-2.122.0}/code_context_control.egg-info/entry_points.txt +0 -0
  139. {code_context_control-2.121.0 → code_context_control-2.122.0}/code_context_control.egg-info/requires.txt +0 -0
  140. {code_context_control-2.121.0 → code_context_control-2.122.0}/code_context_control.egg-info/top_level.txt +0 -0
  141. {code_context_control-2.121.0 → code_context_control-2.122.0}/core/__init__.py +0 -0
  142. {code_context_control-2.121.0 → code_context_control-2.122.0}/core/codex_patch.py +0 -0
  143. {code_context_control-2.121.0 → code_context_control-2.122.0}/core/config.py +0 -0
  144. {code_context_control-2.121.0 → code_context_control-2.122.0}/core/host.py +0 -0
  145. {code_context_control-2.121.0 → code_context_control-2.122.0}/core/ide.py +0 -0
  146. {code_context_control-2.121.0 → code_context_control-2.122.0}/core/mcp_toml.py +0 -0
  147. {code_context_control-2.121.0 → code_context_control-2.122.0}/core/web_security.py +0 -0
  148. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/__init__.py +0 -0
  149. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/config.py +0 -0
  150. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/mcp_oracle.py +0 -0
  151. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/oracle_server.py +0 -0
  152. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/oracle_ui.html +0 -0
  153. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/__init__.py +0 -0
  154. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/activity_reporter.py +0 -0
  155. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/api_auth.py +0 -0
  156. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/c3_bridge.py +0 -0
  157. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/chat_engine.py +0 -0
  158. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/chat_poll.py +0 -0
  159. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/chat_store.py +0 -0
  160. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/cross_memory.py +0 -0
  161. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/discovery_audit.py +0 -0
  162. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/federated_graph.py +0 -0
  163. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/health_checker.py +0 -0
  164. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/insight_engine.py +0 -0
  165. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/local_session.py +0 -0
  166. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/memory_reader.py +0 -0
  167. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/memory_writer.py +0 -0
  168. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/mobile_api.py +0 -0
  169. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/project_scanner.py +0 -0
  170. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/review_agent.py +0 -0
  171. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/tool_executor.py +0 -0
  172. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/services/tool_registry.py +0 -0
  173. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/activity.js +0 -0
  174. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/agents.js +0 -0
  175. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/app.js +0 -0
  176. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/busy.js +0 -0
  177. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/chat/conversations.js +0 -0
  178. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/chat/input.js +0 -0
  179. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/chat/markdown.js +0 -0
  180. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/chat/send.js +0 -0
  181. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/chat/stream_renderer.js +0 -0
  182. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/chat/toolbar.js +0 -0
  183. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/core.js +0 -0
  184. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/crossgraph.js +0 -0
  185. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/header.js +0 -0
  186. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/insights.js +0 -0
  187. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/projects.js +0 -0
  188. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/qrcode.js +0 -0
  189. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/settings.js +0 -0
  190. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/suggestions.js +0 -0
  191. {code_context_control-2.121.0 → code_context_control-2.122.0}/oracle/ui/theme_tabs.js +0 -0
  192. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/__init__.py +0 -0
  193. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/access_guard.py +0 -0
  194. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/access_telemetry.py +0 -0
  195. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/activity_log.py +0 -0
  196. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/agent_base.py +0 -0
  197. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/agent_locks.py +0 -0
  198. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/agents.py +0 -0
  199. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/artifact_defs.py +0 -0
  200. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/artifact_store.py +0 -0
  201. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/atomic_json.py +0 -0
  202. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/auto_memory.py +0 -0
  203. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/background_service.py +0 -0
  204. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/bench/__init__.py +0 -0
  205. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/bench/external/__init__.py +0 -0
  206. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/bench/external/aider_polyglot.py +0 -0
  207. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/bench/external/swe_bench.py +0 -0
  208. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/bench/map_eval.py +0 -0
  209. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/bench/search_eval.py +0 -0
  210. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/bench/shell_eval.py +0 -0
  211. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/benchmark_dashboard.py +0 -0
  212. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/bitbucket_client.py +0 -0
  213. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/bitbucket_credentials.py +0 -0
  214. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/ci_act.py +0 -0
  215. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/ci_cache.py +0 -0
  216. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/ci_expr.py +0 -0
  217. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/ci_failures.py +0 -0
  218. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/ci_github.py +0 -0
  219. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/ci_impact.py +0 -0
  220. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/ci_intel.py +0 -0
  221. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/ci_runner.py +0 -0
  222. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/ci_workflow.py +0 -0
  223. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/circuit_breaker.py +0 -0
  224. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/claude_md.py +0 -0
  225. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/codex_integration.py +0 -0
  226. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/codex_transcript.py +0 -0
  227. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/context_snapshot.py +0 -0
  228. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/conversation_store.py +0 -0
  229. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/cred_audit.py +0 -0
  230. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/cred_telemetry.py +0 -0
  231. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/credential_store.py +0 -0
  232. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/doc_index.py +0 -0
  233. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/e2e_benchmark.py +0 -0
  234. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/e2e_evaluator.py +0 -0
  235. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/e2e_tasks.py +0 -0
  236. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/edit_ledger.py +0 -0
  237. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/embedding_index.py +0 -0
  238. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/enforcement_policy.py +0 -0
  239. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/error_reporting.py +0 -0
  240. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/file_map.py +0 -0
  241. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/file_memory.py +0 -0
  242. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/git_context.py +0 -0
  243. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/hub_service.py +0 -0
  244. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/index_store.py +0 -0
  245. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/indexer.py +0 -0
  246. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/jira_client.py +0 -0
  247. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/jira_cloud.py +0 -0
  248. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/jira_credentials.py +0 -0
  249. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/jira_data_center.py +0 -0
  250. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/jira_links.py +0 -0
  251. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/lexical_index.py +0 -0
  252. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/mask_activation.py +0 -0
  253. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/mask_mirror.py +0 -0
  254. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/mask_presets.py +0 -0
  255. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/memory.py +0 -0
  256. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/memory_consolidator.py +0 -0
  257. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/memory_distiller.py +0 -0
  258. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/memory_graph.py +0 -0
  259. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/memory_grounder.py +0 -0
  260. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/memory_queue.py +0 -0
  261. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/memory_scorer.py +0 -0
  262. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/metrics.py +0 -0
  263. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/notifications.py +0 -0
  264. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/ollama_bridge.py +0 -0
  265. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/ollama_client.py +0 -0
  266. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/ollama_credentials.py +0 -0
  267. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/oracle_service.py +0 -0
  268. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/output_filter.py +0 -0
  269. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/override_grants.py +0 -0
  270. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/override_policy.py +0 -0
  271. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/override_requests.py +0 -0
  272. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/override_wake.py +0 -0
  273. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/parser.py +0 -0
  274. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/project_manager.py +0 -0
  275. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/project_runtime.py +0 -0
  276. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/protocol.py +0 -0
  277. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/proxy_state.py +0 -0
  278. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/repo_map.py +0 -0
  279. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/repo_shape.py +0 -0
  280. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/reranker.py +0 -0
  281. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/retention.py +0 -0
  282. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/retrieval.py +0 -0
  283. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/retrieval_broker.py +0 -0
  284. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/router.py +0 -0
  285. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/runtime.py +0 -0
  286. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/scanner.py +0 -0
  287. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/session_benchmark.py +0 -0
  288. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/session_manager.py +0 -0
  289. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/session_preloader.py +0 -0
  290. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/shell_jobs.py +0 -0
  291. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/shell_output.py +0 -0
  292. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/subprojects.py +0 -0
  293. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/task_store.py +0 -0
  294. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/telemetry.py +0 -0
  295. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/text_index.py +0 -0
  296. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/time_tracker.py +0 -0
  297. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/tool_classifier.py +0 -0
  298. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/transcript_index.py +0 -0
  299. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/validation_cache.py +0 -0
  300. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/vector_store.py +0 -0
  301. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/watcher.py +0 -0
  302. {code_context_control-2.121.0 → code_context_control-2.122.0}/services/win_subprocess.py +0 -0
  303. {code_context_control-2.121.0 → code_context_control-2.122.0}/setup.cfg +0 -0
  304. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_access_builtin_optout.py +0 -0
  305. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_access_guard.py +0 -0
  306. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_access_guard_meta.py +0 -0
  307. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_access_guard_shell_project.py +0 -0
  308. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_access_guard_surfaces.py +0 -0
  309. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_access_guard_wiring.py +0 -0
  310. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_activity_reporter.py +0 -0
  311. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_agent_locks.py +0 -0
  312. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_aider_polyglot.py +0 -0
  313. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_antigravity_transition.py +0 -0
  314. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_artifact_store.py +0 -0
  315. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_artifact_tool.py +0 -0
  316. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_atomic_json.py +0 -0
  317. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_background_service.py +0 -0
  318. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_bitbucket_cli_smoke.py +0 -0
  319. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_bitbucket_client.py +0 -0
  320. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_bitbucket_config_fallback.py +0 -0
  321. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_bitbucket_credentials.py +0 -0
  322. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_bitbucket_tool.py +0 -0
  323. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_builtin_modes.py +0 -0
  324. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
  325. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_c3_shell.py +0 -0
  326. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_chat_poll.py +0 -0
  327. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_ci_act.py +0 -0
  328. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_ci_cache.py +0 -0
  329. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_ci_expr.py +0 -0
  330. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_ci_impact.py +0 -0
  331. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_ci_intel.py +0 -0
  332. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_ci_runner.py +0 -0
  333. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_ci_workflow.py +0 -0
  334. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_circuit_breaker.py +0 -0
  335. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_claude_md_merge.py +0 -0
  336. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_claude_md_updater.py +0 -0
  337. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_cli_smoke.py +0 -0
  338. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_codex_mcp_transport.py +0 -0
  339. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_codex_native.py +0 -0
  340. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_confirm_guard.py +0 -0
  341. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_confirm_guard_wiring.py +0 -0
  342. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_cooccurrence_bounds.py +0 -0
  343. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_cred_audit.py +0 -0
  344. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_cred_telemetry.py +0 -0
  345. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_credential_login_kind.py +0 -0
  346. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_credential_store.py +0 -0
  347. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_credential_ui_parity.py +0 -0
  348. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_credentials_routes.py +0 -0
  349. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_credentials_tool.py +0 -0
  350. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_creds_cli_smoke.py +0 -0
  351. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_delegate_cascade.py +0 -0
  352. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_delegate_version_probe.py +0 -0
  353. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_e2e_benchmark.py +0 -0
  354. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_edit_ledger_deadline.py +0 -0
  355. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_edit_ledger_hook.py +0 -0
  356. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_edit_locking.py +0 -0
  357. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_edit_normalization.py +0 -0
  358. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_edit_verify.py +0 -0
  359. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_embedding_index_deadlock.py +0 -0
  360. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_enforcement_flip.py +0 -0
  361. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_enforcement_policy.py +0 -0
  362. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_enforcement_routes.py +0 -0
  363. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_env_parser.py +0 -0
  364. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_failed_calls_do_not_unlock.py +0 -0
  365. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_federated_graph.py +0 -0
  366. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_file_map_c1.py +0 -0
  367. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_filter_backoff.py +0 -0
  368. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_ghost_files.py +0 -0
  369. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_ghost_generation.py +0 -0
  370. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_git_branch_awareness.py +0 -0
  371. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_hook_access_guard.py +0 -0
  372. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_hook_codex_compat.py +0 -0
  373. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_hook_dispatch.py +0 -0
  374. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_hook_pretool_enforce.py +0 -0
  375. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_hook_prompt_recall.py +0 -0
  376. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_hook_smoke.py +0 -0
  377. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_hook_state.py +0 -0
  378. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_hook_utf8_stdio.py +0 -0
  379. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_hub_credentials_route.py +0 -0
  380. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_hub_credentials_routes_write.py +0 -0
  381. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_hub_enforcement_routes.py +0 -0
  382. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_hub_inspect_api.py +0 -0
  383. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_hub_locks_routes.py +0 -0
  384. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_hub_oracle_service_routes.py +0 -0
  385. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_hub_override_routes.py +0 -0
  386. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_hub_server_smoke.py +0 -0
  387. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_hub_subproject_links.py +0 -0
  388. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_ide_workflow_adaptation.py +0 -0
  389. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_index_cap_not_hardcoded.py +0 -0
  390. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_init_clear_preserves_user_content.py +0 -0
  391. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_init_scan.py +0 -0
  392. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_install_mcp_entrypoint.py +0 -0
  393. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_jira_cli_smoke.py +0 -0
  394. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_jira_client.py +0 -0
  395. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_jira_config_fallback.py +0 -0
  396. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_jira_credentials.py +0 -0
  397. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_jira_links.py +0 -0
  398. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_jira_routes.py +0 -0
  399. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_jira_tool.py +0 -0
  400. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_lazy_store_init.py +0 -0
  401. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_map_eval.py +0 -0
  402. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_mask_guard.py +0 -0
  403. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_mask_routes.py +0 -0
  404. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_mask_surfaces.py +0 -0
  405. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_mcp_host_guard.py +0 -0
  406. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_mcp_memory_timeout.py +0 -0
  407. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_mcp_server_smoke.py +0 -0
  408. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_mcp_toml.py +0 -0
  409. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_memory_distiller.py +0 -0
  410. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_memory_graph_api.py +0 -0
  411. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_memory_queue.py +0 -0
  412. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_memory_system.py +0 -0
  413. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_mobile_api.py +0 -0
  414. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_mobile_extras.py +0 -0
  415. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_mobile_override_routes.py +0 -0
  416. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_mobile_security_api.py +0 -0
  417. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_no_stale_model_pins.py +0 -0
  418. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_notification_dedup.py +0 -0
  419. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_notification_discipline.py +0 -0
  420. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_ollama_credentials.py +0 -0
  421. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_oracle_api_auth.py +0 -0
  422. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_oracle_apikey_api.py +0 -0
  423. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_oracle_c3_bridge.py +0 -0
  424. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_oracle_chat_engine.py +0 -0
  425. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_oracle_chat_store.py +0 -0
  426. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_oracle_discovery_api.py +0 -0
  427. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_oracle_discovery_audit.py +0 -0
  428. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_oracle_health_probe.py +0 -0
  429. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_oracle_local_auth.py +0 -0
  430. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_oracle_ollama_bridge.py +0 -0
  431. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_oracle_scanner_cache.py +0 -0
  432. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_oracle_security_fixes.py +0 -0
  433. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_oracle_session_bootstrap.py +0 -0
  434. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_oracle_subproject_awareness.py +0 -0
  435. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_oracle_ui_bundle.py +0 -0
  436. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_output_filter.py +0 -0
  437. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_override_grants.py +0 -0
  438. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_override_grants_mcp.py +0 -0
  439. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_override_requests.py +0 -0
  440. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_override_wake.py +0 -0
  441. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_permissions.py +0 -0
  442. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_pm_api.py +0 -0
  443. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_project_manager.py +0 -0
  444. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_project_manager_merge.py +0 -0
  445. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_project_tool.py +0 -0
  446. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_read_coercion.py +0 -0
  447. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_read_edit_parity.py +0 -0
  448. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_related_facts.py +0 -0
  449. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_repo_map.py +0 -0
  450. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_repo_shape.py +0 -0
  451. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_retention.py +0 -0
  452. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_review_digest.py +0 -0
  453. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_search_eval.py +0 -0
  454. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_search_p1.py +0 -0
  455. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_search_p2.py +0 -0
  456. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_search_p2b.py +0 -0
  457. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_search_p3.py +0 -0
  458. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_search_p4.py +0 -0
  459. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_search_p5.py +0 -0
  460. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_service_durability.py +0 -0
  461. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_session_benchmark.py +0 -0
  462. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_session_budget.py +0 -0
  463. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_shell_budget_s1.py +0 -0
  464. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_shell_creds.py +0 -0
  465. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_shell_eval.py +0 -0
  466. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_shell_jobs_s3.py +0 -0
  467. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_shell_nudge_s4.py +0 -0
  468. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_shell_output.py +0 -0
  469. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_shell_parsers_s2.py +0 -0
  470. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_shell_robustness.py +0 -0
  471. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_shell_telemetry_s0.py +0 -0
  472. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_shell_write_ledger.py +0 -0
  473. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_shell_writes.py +0 -0
  474. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_subproject_clear_scope.py +0 -0
  475. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_subproject_depth_consumers.py +0 -0
  476. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_subproject_exclusion.py +0 -0
  477. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_subproject_federation.py +0 -0
  478. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_subproject_linkage_api.py +0 -0
  479. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_subprojects.py +0 -0
  480. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_swe_bench.py +0 -0
  481. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_task_store.py +0 -0
  482. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_task_tool.py +0 -0
  483. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_time_tracker.py +0 -0
  484. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_token_telemetry.py +0 -0
  485. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_token_tracking.py +0 -0
  486. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_tool_registry.py +0 -0
  487. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_ui_jsx_syntax.py +0 -0
  488. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_upgrade_and_version.py +0 -0
  489. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_validate.py +0 -0
  490. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_vault_write_guard.py +0 -0
  491. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_version_sync.py +0 -0
  492. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_web_security.py +0 -0
  493. {code_context_control-2.121.0 → code_context_control-2.122.0}/tests/test_windows_reliability.py +0 -0
  494. {code_context_control-2.121.0 → code_context_control-2.122.0}/tui/__init__.py +0 -0
  495. {code_context_control-2.121.0 → code_context_control-2.122.0}/tui/backend.py +0 -0
  496. {code_context_control-2.121.0 → code_context_control-2.122.0}/tui/main.py +0 -0
  497. {code_context_control-2.121.0 → code_context_control-2.122.0}/tui/screens/__init__.py +0 -0
  498. {code_context_control-2.121.0 → code_context_control-2.122.0}/tui/screens/benchmark_view.py +0 -0
  499. {code_context_control-2.121.0 → code_context_control-2.122.0}/tui/screens/claudemd_view.py +0 -0
  500. {code_context_control-2.121.0 → code_context_control-2.122.0}/tui/screens/compress_view.py +0 -0
  501. {code_context_control-2.121.0 → code_context_control-2.122.0}/tui/screens/index_view.py +0 -0
  502. {code_context_control-2.121.0 → code_context_control-2.122.0}/tui/screens/init_view.py +0 -0
  503. {code_context_control-2.121.0 → code_context_control-2.122.0}/tui/screens/mcp_view.py +0 -0
  504. {code_context_control-2.121.0 → code_context_control-2.122.0}/tui/screens/optimize_view.py +0 -0
  505. {code_context_control-2.121.0 → code_context_control-2.122.0}/tui/screens/pipe_view.py +0 -0
  506. {code_context_control-2.121.0 → code_context_control-2.122.0}/tui/screens/projects_view.py +0 -0
  507. {code_context_control-2.121.0 → code_context_control-2.122.0}/tui/screens/search_view.py +0 -0
  508. {code_context_control-2.121.0 → code_context_control-2.122.0}/tui/screens/session_view.py +0 -0
  509. {code_context_control-2.121.0 → code_context_control-2.122.0}/tui/screens/stats.py +0 -0
  510. {code_context_control-2.121.0 → code_context_control-2.122.0}/tui/screens/ui_view.py +0 -0
  511. {code_context_control-2.121.0 → code_context_control-2.122.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.121.0
3
+ Version: 2.122.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.121.0"
95
+ __version__ = "2.122.0"
96
96
 
97
97
 
98
98
  def _compress_file_cli(compressor, path, mode="smart", **kw):
@@ -72,7 +72,7 @@ def cmd_index(args, deps: CommandDeps):
72
72
  def cmd_compress(args, deps: CommandDeps):
73
73
  """Compress a file and show results."""
74
74
  config = deps.load_config()
75
- mode = args.mode or "smart"
75
+ mode = args.mode or "map"
76
76
 
77
77
  compressor = deps.CodeCompressor(str(Path(config.get("project_path", ".")) / ".c3/cache"))
78
78
  result = compressor.compress_file(args.file, mode)
@@ -91,7 +91,8 @@ def build_parser(version: str, parse_cli_ide_arg):
91
91
 
92
92
  p_compress = subparsers.add_parser("compress", help="Compress a file")
93
93
  p_compress.add_argument("file", help="File to compress")
94
- p_compress.add_argument("--mode", choices=["map", "dense_map", "smart", "diff"], default="smart")
94
+ p_compress.add_argument("--mode", choices=["map", "smart", "structure", "outline"], default="map",
95
+ help="map (default) is the canonical file map; the others are signature summaries")
95
96
  p_compress.add_argument("--output", "-o", action="store_true", help="Show compressed output")
96
97
 
97
98
  p_context = subparsers.add_parser("context", help="Get relevant context for a query")
@@ -0,0 +1,251 @@
1
+ """c3_compress — the canonical file map (services/file_map.render_map), one file or a batch.
2
+
3
+ There is one mode, `map`, and it is the same text c3_read(file_path) serves.
4
+ The modes that existed before 2.122.0 (dense_map, smart, diff, bug_scan,
5
+ ast, structure, outline) were called twice in 3,932 tool calls; a request
6
+ for one of them is answered with the map plus a one-line notice so an old
7
+ prompt keeps working while it says so (docs/file-map.md § Retired modes).
8
+ """
9
+
10
+ from concurrent.futures import ThreadPoolExecutor, as_completed
11
+ from pathlib import Path
12
+
13
+ from cli.tools import _grants
14
+ from cli.tools._helpers import finalize_with_tokens, show_token_ratios
15
+ from core import count_tokens
16
+ from services import access_guard
17
+
18
+ #: Every mode name c3_compress ever accepted, and what to say about it now.
19
+ RETIRED_MODES = {
20
+ "dense_map": "the map is dense now",
21
+ "smart": "the map carries full signatures",
22
+ "structure": "the map carries full signatures",
23
+ "outline": "the map carries full signatures",
24
+ "diff": "use `git diff` or the edit ledger (c3_edits)",
25
+ "bug_scan": "use c3_search(action='exact', query='except ') for handler hotspots",
26
+ "ast": "project architecture: codebase-memory-mcp `cli get_architecture`, or c3_status",
27
+ }
28
+ RETIRED_IN = "2.122.0"
29
+
30
+
31
+ def deprecation_line(requested: str) -> str:
32
+ hint = RETIRED_MODES.get(requested, "")
33
+ return (f"[compress:deprecated] mode '{requested}' retired in {RETIRED_IN} — "
34
+ f"map is the only mode ({hint}); see docs/file-map.md")
35
+
36
+
37
+ def map_detail(svc, rel: str, requested_mode: str, *, cache_hit: bool,
38
+ symbols: int = 0, fallback: str = "") -> dict:
39
+ """Telemetry `detail` for a map served from file_memory (C0, 2.120.0).
40
+
41
+ backend names the code path, parser the extractor that built the record
42
+ (tree_sitter | regex | generic, "" for a pre-2.120.0 record), cache_hit
43
+ whether the record was already fresh. `symbols` is how many the caller
44
+ asked for and `fallback` why a read served a map instead of source.
45
+ `deprecated_mode` (2.122.0) is set when a retired mode name was asked for.
46
+ Flat so telemetry.aggregate_tool_telemetry can fold it without a schema.
47
+ """
48
+ record = None
49
+ try:
50
+ record = svc.file_memory.get(rel)
51
+ except Exception:
52
+ record = None
53
+ if not isinstance(record, dict):
54
+ record = None
55
+ detail = {
56
+ "requested_mode": requested_mode,
57
+ "backend": "file_memory",
58
+ "parser": str((record or {}).get("parser") or ""),
59
+ "cache_hit": bool(cache_hit),
60
+ "sections": len((record or {}).get("sections") or []),
61
+ }
62
+ if symbols:
63
+ detail["symbols"] = int(symbols)
64
+ if fallback:
65
+ detail["fallback"] = fallback
66
+ if requested_mode not in ("map", "read"):
67
+ detail["deprecated_mode"] = requested_mode
68
+ return detail
69
+
70
+
71
+ def handle_compress(file_path: str, mode: str, svc,
72
+ finalize, maybe_facts) -> str:
73
+ requested = (mode or "map").strip() or "map"
74
+ if requested != "map" and requested not in RETIRED_MODES:
75
+ return finalize("c3_compress", {"file_path": file_path, "mode": requested},
76
+ f"[compress:error] Unknown mode '{requested}'. The only mode is 'map'.",
77
+ "error")
78
+ note = deprecation_line(requested) if requested != "map" else ""
79
+
80
+ # Batch dispatch: comma-separated paths
81
+ if "," in file_path:
82
+ paths = [p.strip() for p in file_path.split(",") if p.strip()]
83
+ return _compress_batch(paths, requested, note, svc, finalize)
84
+
85
+ return _compress_single(file_path, requested, note, svc, finalize)
86
+
87
+
88
+ def _build_map(svc, rel: str) -> str:
89
+ """The canonical map for `rel`, draining any queued watcher updates first."""
90
+ queued = svc.file_memory.drain_queue()
91
+ completed = []
92
+ failed = []
93
+ for qp in queued[:10]:
94
+ try:
95
+ if svc.file_memory.update(qp):
96
+ completed.append(qp)
97
+ else:
98
+ failed.append(qp)
99
+ except Exception:
100
+ failed.append(qp)
101
+ if completed:
102
+ svc.file_memory.complete_updates(completed)
103
+ if failed:
104
+ svc.file_memory.complete_updates(failed, failed=True)
105
+ return svc.file_memory.get_or_build_map(rel)
106
+
107
+
108
+ def _compress_single(file_path: str, requested: str, note: str, svc, finalize) -> str:
109
+ """Map a single file."""
110
+ # Access Guard: read verdict up front (docs/access-guard.md §3).
111
+ _verdict = access_guard.verdict(file_path, "read", svc.project_path)
112
+ if _verdict.denial and not _grants.allow(svc, _verdict.denial,
113
+ tool="c3_compress", op="read",
114
+ path=file_path):
115
+ return finalize("c3_compress", {"file_path": file_path, "mode": requested},
116
+ access_guard.refusal(_verdict.denial, file_path, "read"),
117
+ "access-denied")
118
+ # Mask Guard: the map is built through file_memory, which reads the RAW
119
+ # file — a masked path is served from its view instead
120
+ # (docs/mask-guard.md §6, row 7).
121
+ if _verdict.masked:
122
+ from services import mask_mirror
123
+ try:
124
+ view = mask_mirror.render_for_path(file_path, svc.project_path)
125
+ except mask_mirror.MaskUnavailable as exc:
126
+ return finalize("c3_compress",
127
+ {"file_path": file_path, "mode": requested},
128
+ f"{access_guard.TAG_MASK_UNSUPPORTED} {exc.message}",
129
+ "mask-unavailable")
130
+ return finalize("c3_compress", {"file_path": file_path, "mode": requested},
131
+ view.with_header(file_path), f"masked:{view.preset}")
132
+
133
+ full = Path(svc.project_path) / file_path
134
+ if not full.exists():
135
+ full = Path(file_path)
136
+ if not full.exists():
137
+ return ("[file_map:error] not found. To create a new file use "
138
+ "c3_edit(file_path=..., old_string='', new_string=<content>).")
139
+ rel = str(full.resolve().relative_to(Path(svc.project_path).resolve())).replace("\\", "/")
140
+ # C0 measurement: was the record already fresh before this call?
141
+ cache_hit = not svc.file_memory.needs_update(rel)
142
+ res = _build_map(svc, rel)
143
+ raw_tokens = None
144
+ map_tokens = 0
145
+ try:
146
+ raw_text = full.read_text(encoding="utf-8", errors="replace")
147
+ raw_tokens = count_tokens(raw_text)
148
+ map_tokens = count_tokens(res)
149
+ if map_tokens >= raw_tokens and not res.startswith("[file_map]"):
150
+ # A map that costs more than the file is worth nothing
151
+ # (docs/file-map.md § Small files).
152
+ res = f"[compress:{file_path}] whole file — smaller than its map\n" + raw_text
153
+ map_tokens = count_tokens(res)
154
+ summary = "map"
155
+ except Exception:
156
+ summary = "mapped"
157
+ if note:
158
+ res = note + "\n" + res
159
+ map_tokens = count_tokens(res)
160
+ return finalize_with_tokens(
161
+ finalize, svc, "c3_compress", {"file_path": file_path, "mode": requested},
162
+ res, summary,
163
+ raw_tokens=raw_tokens, optimized_tokens=map_tokens or None,
164
+ response_tokens=map_tokens,
165
+ detail=map_detail(svc, rel, requested, cache_hit=cache_hit))
166
+
167
+
168
+ def _compress_batch(paths: list, requested: str, note: str, svc, finalize) -> str:
169
+ """Map several files in parallel, return one combined report."""
170
+ max_files = 10
171
+ paths = paths[:max_files]
172
+
173
+ results = {}
174
+
175
+ def _do_one(fp):
176
+ """Returns (fp, map_text, raw_tokens, map_tokens, error)."""
177
+ try:
178
+ # Access Guard: per-member read verdict — the S1 refusal becomes
179
+ # this member's batch line; other members are still served.
180
+ _v = access_guard.verdict(fp, "read", svc.project_path)
181
+ if _v.denial:
182
+ return fp, None, None, None, access_guard.refusal(_v.denial, fp,
183
+ "read")
184
+ if _v.masked:
185
+ from services import mask_mirror
186
+ try:
187
+ view = mask_mirror.render_for_path(fp, svc.project_path)
188
+ except mask_mirror.MaskUnavailable as exc:
189
+ return fp, None, None, None, \
190
+ f"{access_guard.TAG_MASK_UNSUPPORTED} {exc.message}"
191
+ text = view.with_header(fp)
192
+ return fp, text, None, count_tokens(text), None
193
+ full = Path(svc.project_path) / fp
194
+ if not full.exists():
195
+ full = Path(fp)
196
+ if not full.exists():
197
+ return fp, None, None, None, "not found"
198
+ rel = str(full.resolve().relative_to(
199
+ Path(svc.project_path).resolve())).replace("\\", "/")
200
+ res = svc.file_memory.get_or_build_map(rel)
201
+ try:
202
+ raw_tok = count_tokens(full.read_text(encoding="utf-8", errors="replace"))
203
+ map_tok = count_tokens(res)
204
+ return fp, res, raw_tok, map_tok, None
205
+ except Exception:
206
+ return fp, res, None, None, None
207
+ except Exception as e:
208
+ return fp, None, None, None, str(e)
209
+
210
+ with ThreadPoolExecutor(max_workers=min(len(paths), 8)) as pool:
211
+ futures = {pool.submit(_do_one, fp): fp for fp in paths}
212
+ for fut in as_completed(futures):
213
+ fp, text, raw_tok, opt_tok, err = fut.result()
214
+ results[fp] = (text, raw_tok, opt_tok, err)
215
+
216
+ ratios = show_token_ratios(svc)
217
+ parts = []
218
+ total_ok = 0
219
+ total_raw = 0
220
+ total_opt = 0
221
+ measured = 0
222
+ for fp in paths:
223
+ text, raw_tok, opt_tok, err = results.get(fp, (None, None, None, "unknown"))
224
+ if text:
225
+ tag = ""
226
+ if raw_tok is not None and opt_tok is not None:
227
+ measured += 1
228
+ total_raw += raw_tok
229
+ total_opt += opt_tok
230
+ if ratios:
231
+ tag = f" ({raw_tok}->{opt_tok}tok)"
232
+ parts.append(f"## {fp}{tag}\n{text}")
233
+ total_ok += 1
234
+ else:
235
+ parts.append(f"## {fp} — ERROR: {err}")
236
+
237
+ header = f"[compress:batch] {total_ok}/{len(paths)} files (map)"
238
+ if note:
239
+ header = note + "\n" + header
240
+ body = header + "\n\n" + "\n\n".join(parts)
241
+ detail = {"requested_mode": requested, "backend": "batch",
242
+ "files": len(paths), "ok": total_ok}
243
+ if requested != "map":
244
+ detail["deprecated_mode"] = requested
245
+ return finalize_with_tokens(
246
+ finalize, svc, "c3_compress",
247
+ {"file_path": ",".join(paths), "mode": requested, "batch": True},
248
+ body, f"batch {total_ok}/{len(paths)}",
249
+ raw_tokens=total_raw if measured else None,
250
+ optimized_tokens=total_opt if measured else None,
251
+ detail=detail)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-context-control
3
- Version: 2.121.0
3
+ Version: 2.122.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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "code-context-control"
7
- version = "2.121.0"
7
+ version = "2.122.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"
@@ -2,10 +2,12 @@
2
2
  AST-based Code Compression Service
3
3
 
4
4
  Parses source files into AST and generates compressed summaries:
5
- - Function/class signatures only (skip bodies)
6
- - Structural outline mode
7
- - Smart truncation with context preservation
8
- - Diff-only mode for edits
5
+ - "map": the canonical file map (services/file_map) — what the tools serve
6
+ - "structure" / "outline" / "smart": signature-only summaries kept for
7
+ internal callers (delegate, Hub REST, context snapshots, benchmarks)
8
+ - "summary": an LLM summary through the router, when one is configured
9
+
10
+ "diff" and "bug_scan" were retired in 2.122.0 (docs/file-map.md).
9
11
  """
10
12
  import hashlib
11
13
  import json
@@ -145,6 +147,30 @@ class CodeCompressor:
145
147
  if protected_files:
146
148
  self._protected_files.update(self._normalize_rel_path(p) for p in protected_files)
147
149
  self.router = router
150
+ self._sweep_retired_caches()
151
+
152
+ #: Modes the compressor no longer implements, and where to go instead.
153
+ RETIRED_MODES = {
154
+ "diff": "use `git diff` or the edit ledger",
155
+ "bug_scan": "use c3_search(action='exact', query='except ')",
156
+ "dense_map": "use mode='map'",
157
+ }
158
+
159
+ def _sweep_retired_caches(self) -> int:
160
+ """Delete the pre-2.122.0 diff caches: one full copy of every file
161
+ ever diffed, keyed by BASENAME (so every __init__.py collided).
162
+ Cheap — only diff wrote `*.cache`; after one sweep there are none."""
163
+ removed = 0
164
+ try:
165
+ for f in self.cache_dir.glob("*.cache"):
166
+ try:
167
+ f.unlink()
168
+ removed += 1
169
+ except OSError:
170
+ continue
171
+ except Exception:
172
+ pass
173
+ return removed
148
174
 
149
175
  @staticmethod
150
176
  def _normalize_rel_path(path: str) -> str:
@@ -192,13 +218,17 @@ class CodeCompressor:
192
218
  Compress a source file.
193
219
 
194
220
  Modes:
221
+ - "map": the canonical file map (services/file_map.render_map)
195
222
  - "structure": Function/class signatures + imports (most compressed)
196
223
  - "outline": Structure + docstrings + key comments
197
224
  - "smart": Adaptive - more detail for small files, less for large
198
- - "diff": Only changes since last seen (requires prior state)
199
225
  - "summary": High-level LLM summary (requires router)
200
- - "bug_scan": Structure map + annotated exception-handling hotspots with line numbers
226
+ Retired (2.122.0): "diff", "bug_scan", "dense_map" -> error dict.
201
227
  """
228
+ if mode in self.RETIRED_MODES:
229
+ return {"error": f"mode '{mode}' retired in 2.122.0 — "
230
+ f"{self.RETIRED_MODES[mode]} (docs/file-map.md)",
231
+ "compressed": "", "retired": True}
202
232
  # Access Guard: read verdict before any cache or disk access — denied
203
233
  # paths raise AccessDenied (docs/access-guard.md §3). Callers that
204
234
  # need string returns catch it and surface exc.message. Checked
@@ -241,8 +271,9 @@ class CodeCompressor:
241
271
  content_hash = hashlib.md5(content.encode()).hexdigest()
242
272
  ext = filepath.suffix.lower()
243
273
 
244
- # Check persistent cache (except for diff/summary which have their own logic)
245
- if mode not in ("diff", "summary"):
274
+ # Check persistent cache (summary has its own logic; map is served
275
+ # from file_memory's own cache below)
276
+ if mode not in ("summary", "map"):
246
277
  cache_key = f"{content_hash}_{mode}{ext}.json"
247
278
  if mask_view is not None:
248
279
  cache_key = f"mask-{mask_view.view_hash}_{cache_key}"
@@ -271,7 +302,10 @@ class CodeCompressor:
271
302
  # entries (keyed on content hash) still win. diff/summary are exempt:
272
303
  # diff is the recommended targeted alternative and summary delegates
273
304
  # to the router.
274
- if mode not in ("diff", "summary"):
305
+ if mode == "map":
306
+ return self._canonical_map(filepath, content)
307
+
308
+ if mode != "summary":
275
309
  line_count = content.count("\n")
276
310
  if content and not content.endswith("\n"):
277
311
  line_count += 1
@@ -285,9 +319,6 @@ class CodeCompressor:
285
319
  filepath, content, content_hash, ext, mode,
286
320
  byte_size, line_count)
287
321
 
288
- if mode == "diff":
289
- return self._diff_compress(filepath, content)
290
-
291
322
  if mode == "summary":
292
323
  if not self.router:
293
324
  return {"error": "Summary mode requires a router", "compressed": ""}
@@ -296,31 +327,6 @@ class CodeCompressor:
296
327
  result = f"# {filepath.name} — SUMMARY\n{summary}"
297
328
  return {"compressed": result, "mode": "summary", **measure_savings(content, result)}
298
329
 
299
- if mode == "bug_scan":
300
- # Structure map + exception-handling annotation pass
301
- structure = self._extract_structure(content, ext, "outline")
302
- exception_section = self._scan_exception_handlers(content)
303
- compressed_parts = [structure]
304
- if exception_section:
305
- compressed_parts.append(exception_section)
306
- compressed = "\n".join(compressed_parts)
307
- header = f"# {filepath.name} ({filepath.suffix}) — {len(content.splitlines())} lines [bug_scan]\n"
308
- result = header + compressed
309
- savings = measure_savings(content, result)
310
- savings["compressed"] = result
311
- savings["mode"] = "bug_scan"
312
- savings["filepath"] = str(filepath)
313
- self._file_hashes[str(filepath)] = content_hash
314
- cache_key = f"{content_hash}_bug_scan{ext}.json"
315
- self._mem_cache[cache_key] = dict(savings)
316
- cache_file = self.cache_dir / cache_key
317
- try:
318
- with open(cache_file, "w", encoding="utf-8") as f:
319
- json.dump(savings, f, indent=2)
320
- except Exception:
321
- pass
322
- return savings
323
-
324
330
  if mode == "smart":
325
331
  tokens = count_tokens(content)
326
332
  if tokens < 80:
@@ -354,8 +360,8 @@ class CodeCompressor:
354
360
  # Cache hash for diff mode
355
361
  self._file_hashes[str(filepath)] = content_hash
356
362
 
357
- # Persist to cache (except diff which uses its own file format)
358
- if mode not in ("diff", "summary"):
363
+ # Persist to cache
364
+ if mode != "summary":
359
365
  cache_key = f"{content_hash}_{mode}{ext}.json"
360
366
  # Store in memory first (fast path for repeat access)
361
367
  if len(self._mem_cache) >= self._MEM_CACHE_MAX:
@@ -648,51 +654,6 @@ class CodeCompressor:
648
654
 
649
655
  return None
650
656
 
651
- def _scan_exception_handlers(self, content: str) -> str:
652
- """Scan for exception-handling hotspots and return an annotated section.
653
-
654
- Returns a formatted block listing every bare/broad except clause with:
655
- - line number
656
- - the except line itself
657
- - the immediately enclosing function name (if detectable)
658
-
659
- Returns an empty string if no exception handlers are found.
660
- """
661
- lines = content.splitlines()
662
- # Patterns ranked from most to least problematic
663
- _EXCEPT_PATTERNS = [
664
- (re.compile(r"^\s*except\s*:"), "bare-except"),
665
- (re.compile(r"^\s*except\s+Exception\s*:"), "broad-except"),
666
- (re.compile(r"^\s*except\s+Exception\s+as\s+\w+\s*:"), "broad-except"),
667
- (re.compile(r"^\s*except\s+\("), "multi-except"),
668
- ]
669
- _FUNC_DEF = re.compile(r"^\s*(?:async\s+)?def\s+(\w+)")
670
-
671
- hits: list[str] = []
672
- # Track the most recently seen function name for context
673
- current_func = "<module>"
674
- for idx, line in enumerate(lines, start=1):
675
- m = _FUNC_DEF.match(line)
676
- if m:
677
- current_func = m.group(1)
678
- for pattern, label in _EXCEPT_PATTERNS:
679
- if pattern.match(line):
680
- # Show up to 2 continuation lines (body of the except block)
681
- body_lines = []
682
- for j in range(idx, min(idx + 2, len(lines))):
683
- body = lines[j].strip()
684
- if body and not body.startswith("except") and not body.startswith("try"):
685
- body_lines.append(body)
686
- body_preview = " | ".join(body_lines[:2]) if body_lines else ""
687
- suffix = f" → {body_preview}" if body_preview else ""
688
- hits.append(f" L{idx} [{label}] in `{current_func}`: {line.strip()}{suffix}")
689
- break # one label per line
690
-
691
- if not hits:
692
- return ""
693
- header = f"\n# Exception-handling hotspots ({len(hits)} found):"
694
- return header + "\n" + "\n".join(hits)
695
-
696
657
  def _generic_compress(self, content: str, ext: str) -> str:
697
658
  """Fallback compression for unknown languages."""
698
659
  lines = content.split('\n')
@@ -712,49 +673,33 @@ class CodeCompressor:
712
673
  kept.append(stripped)
713
674
  return '\n'.join(kept)
714
675
 
715
- def _diff_compress(self, filepath: Path, current_content: str) -> dict:
716
- """Generate diff-based compression against cached version."""
717
- cache_file = self.cache_dir / f"{filepath.name}.cache"
718
- current_hash = hashlib.md5(current_content.encode()).hexdigest()
676
+ def _canonical_map(self, filepath: Path, content: str) -> dict:
677
+ """mode="map": the same text c3_read / c3_compress serve.
719
678
 
720
- if cache_file.exists():
721
- cached = cache_file.read_text(encoding="utf-8", errors="replace")
722
- cached_hash = hashlib.md5(cached.encode()).hexdigest()
723
-
724
- if cached_hash == current_hash:
725
- result = f"# {filepath.name} — NO CHANGES"
726
- return {"compressed": result, "mode": "diff-unchanged", **measure_savings(current_content, result)}
727
-
728
- # Generate contextual diff
729
- diff = self._contextual_diff(cached.split('\n'), current_content.split('\n'), filepath.name)
730
- savings = measure_savings(current_content, diff)
731
- savings["compressed"] = diff
732
- savings["mode"] = "diff"
733
- else:
734
- # No cache — fall back to structure mode
735
- compressed = self._extract_structure(current_content, filepath.suffix.lower(), "structure")
736
- header = f"# {filepath.name} (FIRST SEEN) — {len(current_content.splitlines())} lines\n"
737
- result = header + compressed
738
- savings = measure_savings(current_content, result)
739
- savings["compressed"] = result
740
- savings["mode"] = "diff-first"
741
-
742
- # Update cache
743
- cache_file.write_text(current_content, encoding="utf-8")
679
+ Built from a throwaway FileMemoryStore-style extraction so callers
680
+ that only hold a compressor (Hub REST, `c3 compress`, delegate)
681
+ get the canonical map rather than a structure-only summary.
682
+ """
683
+ from services.file_map import render_map
684
+ from services.file_memory import LANG_MAP, FileMemoryStore
685
+ ext = filepath.suffix.lower()
686
+ sections, parser = FileMemoryStore._extract_sections_with_parser(
687
+ FileMemoryStore.__new__(FileMemoryStore), filepath, content)
688
+ record = {
689
+ "path": self._relative_to_project(filepath),
690
+ "lines": len(content.splitlines()),
691
+ "language": LANG_MAP.get(ext, ext.lstrip(".")),
692
+ "parser": parser,
693
+ "sections": sections,
694
+ }
695
+ result = render_map(record)
696
+ savings = measure_savings(content, result)
697
+ savings["compressed"] = result
698
+ savings["mode"] = "map"
699
+ savings["parser"] = parser
700
+ savings["filepath"] = str(filepath)
744
701
  return savings
745
702
 
746
- def _contextual_diff(self, old_lines: list, new_lines: list, filename: str) -> str:
747
- """Generate a contextual diff with surrounding structure."""
748
- import difflib
749
- differ = difflib.unified_diff(old_lines, new_lines, lineterm='', n=1)
750
- diff_text = '\n'.join(differ)
751
-
752
- if not diff_text.strip():
753
- return f"# {filename} — NO CHANGES"
754
-
755
- header = f"# {filename} — CHANGES ONLY\n"
756
- return header + diff_text
757
-
758
703
  def compress_directory(self, dirpath: str, mode: str = "smart",
759
704
  extensions: Optional[list] = None,
760
705
  max_files: int = 50) -> dict:
@@ -208,17 +208,27 @@ class TestLargeFileFastPath(unittest.TestCase):
208
208
 
209
209
  # ── mode exemptions ─────────────────────────────────────────────────
210
210
 
211
- def test_diff_mode_not_intercepted(self):
212
- # diff is the documented alternative for large files — it must keep
213
- # its own path and never return the fast-path header.
211
+ def test_diff_mode_is_retired(self):
212
+ # diff was retired in 2.122.0: it cached full copies of every file
213
+ # keyed by basename. The answer is an error naming the replacement,
214
+ # never a fast-path header.
214
215
  content = _make_python_source(LARGE_FILE_LINE_THRESHOLD + 100, "dif")
215
216
  fpath = self._write("diffable.py", content)
216
217
 
217
218
  res = self.comp.compress_file(str(fpath), "diff")
218
219
 
220
+ self.assertTrue(res.get("retired"))
221
+ self.assertIn("retired in 2.122.0", res["error"])
219
222
  self.assertNotIn("fast_path", res)
220
- self.assertTrue(res["mode"].startswith("diff"))
221
- self.assertNotIn(LARGE_FILE_GUIDANCE, res["compressed"])
223
+
224
+ def test_map_mode_is_the_canonical_map_even_for_large_files(self):
225
+ content = _make_python_source(LARGE_FILE_LINE_THRESHOLD + 100, "mp")
226
+ fpath = self._write("mapbig.py", content)
227
+ res = self.comp.compress_file(str(fpath), "map")
228
+ self.assertEqual(res["mode"], "map")
229
+ self.assertNotIn("fast_path", res)
230
+ self.assertTrue(res["compressed"].startswith("# "))
231
+ self.assertIn("[L", res["compressed"])
222
232
 
223
233
  def test_smart_mode_takes_fast_path(self):
224
234
  content = _make_python_source(LARGE_FILE_LINE_THRESHOLD + 100, "smt")
@@ -140,18 +140,18 @@ class TestCompressDetail(unittest.TestCase):
140
140
  self.assertEqual(rows[0]["target"], "pkg/mod.py")
141
141
  self.assertGreater(rows[0]["raw_tokens"], rows[0]["optimized_tokens"])
142
142
 
143
- def test_compressor_mode_detail_and_cache_hit(self):
143
+ def test_retired_mode_detail(self):
144
144
  with tempfile.TemporaryDirectory() as tmp:
145
145
  svc = _project(tmp)
146
146
  fin = _finalize_via(svc.session_mgr)
147
- handle_compress("pkg/mod.py", "smart", svc, fin, _no_facts)
148
- handle_compress("pkg/mod.py", "smart", svc, fin, _no_facts)
147
+ out = handle_compress("pkg/mod.py", "smart", svc, fin, _no_facts)
148
+ self.assertTrue(out.startswith("[compress:deprecated] mode 'smart'"))
149
+ self.assertIn("C Thing [L", out)
149
150
  rows = [r["detail"] for r in _rows(tmp) if r["tool"] == "c3_compress"]
150
- self.assertEqual(rows[0]["backend"], "compressor")
151
+ self.assertEqual(rows[0]["backend"], "file_memory")
151
152
  self.assertEqual(rows[0]["requested_mode"], "smart")
152
- self.assertFalse(rows[0]["cache_hit"])
153
- self.assertTrue(rows[1]["cache_hit"])
154
- self.assertIn(rows[0]["actual_mode"], ("full", "outline", "structure", "smart"))
153
+ self.assertEqual(rows[0]["deprecated_mode"], "smart")
154
+ self.assertEqual(rows[0]["parser"], "tree_sitter")
155
155
 
156
156
  def test_batch_detail(self):
157
157
  with tempfile.TemporaryDirectory() as tmp: