code-context-control 2.75.0__tar.gz → 2.76.2__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 (417) hide show
  1. {code_context_control-2.75.0/code_context_control.egg-info → code_context_control-2.76.2}/PKG-INFO +1 -1
  2. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/c3.py +1 -1
  3. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hook_access_guard.py +62 -1
  4. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/edit.py +74 -9
  5. {code_context_control-2.75.0 → code_context_control-2.76.2/code_context_control.egg-info}/PKG-INFO +1 -1
  6. {code_context_control-2.75.0 → code_context_control-2.76.2}/code_context_control.egg-info/SOURCES.txt +4 -0
  7. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/oracle_server.py +7 -1
  8. code_context_control-2.76.2/oracle/services/chat_poll.py +397 -0
  9. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/mobile_api.py +597 -1
  10. {code_context_control-2.75.0 → code_context_control-2.76.2}/pyproject.toml +1 -1
  11. code_context_control-2.76.2/tests/test_chat_poll.py +570 -0
  12. code_context_control-2.76.2/tests/test_edit_ledger_deadline.py +166 -0
  13. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_hook_access_guard.py +68 -0
  14. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_mobile_api.py +3 -1
  15. code_context_control-2.76.2/tests/test_mobile_extras.py +736 -0
  16. {code_context_control-2.75.0 → code_context_control-2.76.2}/LICENSE +0 -0
  17. {code_context_control-2.75.0 → code_context_control-2.76.2}/README.md +0 -0
  18. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/__init__.py +0 -0
  19. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/_hook_utils.py +0 -0
  20. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/commands/__init__.py +0 -0
  21. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/commands/common.py +0 -0
  22. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/commands/parser.py +0 -0
  23. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/docs.html +0 -0
  24. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/edits.html +0 -0
  25. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/guide/access.html +0 -0
  26. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/guide/bitbucket.html +0 -0
  27. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/guide/credentials.html +0 -0
  28. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/guide/getting-started.html +0 -0
  29. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/guide/index.html +0 -0
  30. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/guide/masking.html +0 -0
  31. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/guide/oracle.html +0 -0
  32. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/guide/shared.css +0 -0
  33. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/guide/tools.html +0 -0
  34. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/guide/workflow.html +0 -0
  35. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hook_artifact.py +0 -0
  36. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hook_auto_snapshot.py +0 -0
  37. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hook_c3_signal.py +0 -0
  38. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hook_c3read.py +0 -0
  39. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hook_dispatch.py +0 -0
  40. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hook_edit_ledger.py +0 -0
  41. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hook_edit_unlock.py +0 -0
  42. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hook_filter.py +0 -0
  43. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hook_ghost_files.py +0 -0
  44. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hook_pretool_enforce.py +0 -0
  45. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hook_prompt_recall.py +0 -0
  46. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hook_read.py +0 -0
  47. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hook_session_stats.py +0 -0
  48. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hook_terse_advisor.py +0 -0
  49. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_server.py +0 -0
  50. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/app.js +0 -0
  51. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/add_project.js +0 -0
  52. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/config_editor.js +0 -0
  53. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/drill_artifacts.js +0 -0
  54. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/drill_health.js +0 -0
  55. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/drill_panel.js +0 -0
  56. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/drill_subprojects.js +0 -0
  57. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/drill_tasks.js +0 -0
  58. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/drill_views.js +0 -0
  59. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/global_search.js +0 -0
  60. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/hub_credentials.js +0 -0
  61. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/hub_enforcement.js +0 -0
  62. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/hub_locks.js +0 -0
  63. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/mcp_manager.js +0 -0
  64. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/modals.js +0 -0
  65. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/project_card.js +0 -0
  66. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/project_tree.js +0 -0
  67. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/session_drawer.js +0 -0
  68. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/settings_modal.js +0 -0
  69. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/sidebar.js +0 -0
  70. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/summary_bar.js +0 -0
  71. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/task_board.js +0 -0
  72. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/toasts.js +0 -0
  73. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/components/topbar.js +0 -0
  74. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui/state.js +0 -0
  75. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/hub_ui.html +0 -0
  76. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/mcp_proxy.py +0 -0
  77. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/mcp_server.py +0 -0
  78. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/progress.py +0 -0
  79. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/server.py +0 -0
  80. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/__init__.py +0 -0
  81. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/_grants.py +0 -0
  82. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/_helpers.py +0 -0
  83. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/agent.py +0 -0
  84. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/artifacts.py +0 -0
  85. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/bitbucket.py +0 -0
  86. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/compress.py +0 -0
  87. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/credentials.py +0 -0
  88. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/delegate.py +0 -0
  89. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/edit_verify.py +0 -0
  90. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/edits.py +0 -0
  91. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/federate.py +0 -0
  92. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/filter.py +0 -0
  93. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/impact.py +0 -0
  94. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/jira.py +0 -0
  95. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/locks.py +0 -0
  96. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/memory.py +0 -0
  97. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/override.py +0 -0
  98. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/project.py +0 -0
  99. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/read.py +0 -0
  100. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/search.py +0 -0
  101. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/session.py +0 -0
  102. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/shell.py +0 -0
  103. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/status.py +0 -0
  104. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/tasks.py +0 -0
  105. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/tools/validate.py +0 -0
  106. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/api.js +0 -0
  107. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/app.js +0 -0
  108. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/components/access.js +0 -0
  109. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/components/bitbucket.js +0 -0
  110. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/components/chat.js +0 -0
  111. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/components/credentials.js +0 -0
  112. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/components/dashboard.js +0 -0
  113. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/components/edits.js +0 -0
  114. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/components/enforcement.js +0 -0
  115. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/components/instructions.js +0 -0
  116. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/components/jira.js +0 -0
  117. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/components/memory.js +0 -0
  118. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/components/sessions.js +0 -0
  119. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/components/settings.js +0 -0
  120. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/components/sidebar.js +0 -0
  121. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/components/tasks.js +0 -0
  122. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/icons.js +0 -0
  123. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/pm_shared.js +0 -0
  124. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/shared.js +0 -0
  125. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui/theme.js +0 -0
  126. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui.html +0 -0
  127. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui_legacy.html +0 -0
  128. {code_context_control-2.75.0 → code_context_control-2.76.2}/cli/ui_nano.html +0 -0
  129. {code_context_control-2.75.0 → code_context_control-2.76.2}/code_context_control.egg-info/dependency_links.txt +0 -0
  130. {code_context_control-2.75.0 → code_context_control-2.76.2}/code_context_control.egg-info/entry_points.txt +0 -0
  131. {code_context_control-2.75.0 → code_context_control-2.76.2}/code_context_control.egg-info/requires.txt +0 -0
  132. {code_context_control-2.75.0 → code_context_control-2.76.2}/code_context_control.egg-info/top_level.txt +0 -0
  133. {code_context_control-2.75.0 → code_context_control-2.76.2}/core/__init__.py +0 -0
  134. {code_context_control-2.75.0 → code_context_control-2.76.2}/core/config.py +0 -0
  135. {code_context_control-2.75.0 → code_context_control-2.76.2}/core/ide.py +0 -0
  136. {code_context_control-2.75.0 → code_context_control-2.76.2}/core/mcp_toml.py +0 -0
  137. {code_context_control-2.75.0 → code_context_control-2.76.2}/core/web_security.py +0 -0
  138. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/__init__.py +0 -0
  139. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/config.py +0 -0
  140. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/mcp_oracle.py +0 -0
  141. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/oracle_ui.html +0 -0
  142. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/__init__.py +0 -0
  143. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/activity_reporter.py +0 -0
  144. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/api_auth.py +0 -0
  145. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/c3_bridge.py +0 -0
  146. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/chat_engine.py +0 -0
  147. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/chat_store.py +0 -0
  148. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/cross_memory.py +0 -0
  149. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/discovery_audit.py +0 -0
  150. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/federated_graph.py +0 -0
  151. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/health_checker.py +0 -0
  152. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/insight_engine.py +0 -0
  153. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/local_session.py +0 -0
  154. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/memory_reader.py +0 -0
  155. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/memory_writer.py +0 -0
  156. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/project_scanner.py +0 -0
  157. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/review_agent.py +0 -0
  158. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/tool_executor.py +0 -0
  159. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/services/tool_registry.py +0 -0
  160. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/activity.js +0 -0
  161. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/agents.js +0 -0
  162. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/app.js +0 -0
  163. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/busy.js +0 -0
  164. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/chat/conversations.js +0 -0
  165. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/chat/input.js +0 -0
  166. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/chat/markdown.js +0 -0
  167. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/chat/send.js +0 -0
  168. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/chat/stream_renderer.js +0 -0
  169. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/chat/toolbar.js +0 -0
  170. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/core.js +0 -0
  171. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/crossgraph.js +0 -0
  172. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/header.js +0 -0
  173. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/insights.js +0 -0
  174. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/projects.js +0 -0
  175. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/qrcode.js +0 -0
  176. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/settings.js +0 -0
  177. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/suggestions.js +0 -0
  178. {code_context_control-2.75.0 → code_context_control-2.76.2}/oracle/ui/theme_tabs.js +0 -0
  179. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/__init__.py +0 -0
  180. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/access_guard.py +0 -0
  181. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/access_telemetry.py +0 -0
  182. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/activity_log.py +0 -0
  183. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/agent_base.py +0 -0
  184. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/agent_locks.py +0 -0
  185. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/agents.py +0 -0
  186. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/artifact_defs.py +0 -0
  187. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/artifact_store.py +0 -0
  188. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/auto_memory.py +0 -0
  189. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/bench/__init__.py +0 -0
  190. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/bench/external/__init__.py +0 -0
  191. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/bench/external/aider_polyglot.py +0 -0
  192. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/bench/external/swe_bench.py +0 -0
  193. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/benchmark_dashboard.py +0 -0
  194. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/bitbucket_client.py +0 -0
  195. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/bitbucket_credentials.py +0 -0
  196. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/circuit_breaker.py +0 -0
  197. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/claude_md.py +0 -0
  198. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/compressor.py +0 -0
  199. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/context_snapshot.py +0 -0
  200. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/conversation_store.py +0 -0
  201. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/credential_store.py +0 -0
  202. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/doc_index.py +0 -0
  203. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/e2e_benchmark.py +0 -0
  204. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/e2e_evaluator.py +0 -0
  205. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/e2e_tasks.py +0 -0
  206. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/edit_ledger.py +0 -0
  207. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/embedding_index.py +0 -0
  208. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/enforcement_policy.py +0 -0
  209. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/error_reporting.py +0 -0
  210. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/file_memory.py +0 -0
  211. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/git_context.py +0 -0
  212. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/hub_service.py +0 -0
  213. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/indexer.py +0 -0
  214. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/jira_client.py +0 -0
  215. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/jira_cloud.py +0 -0
  216. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/jira_credentials.py +0 -0
  217. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/jira_data_center.py +0 -0
  218. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/jira_links.py +0 -0
  219. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/mask_activation.py +0 -0
  220. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/mask_mirror.py +0 -0
  221. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/mask_presets.py +0 -0
  222. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/memory.py +0 -0
  223. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/memory_consolidator.py +0 -0
  224. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/memory_distiller.py +0 -0
  225. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/memory_graph.py +0 -0
  226. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/memory_grounder.py +0 -0
  227. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/memory_queue.py +0 -0
  228. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/memory_scorer.py +0 -0
  229. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/metrics.py +0 -0
  230. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/notifications.py +0 -0
  231. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/ollama_bridge.py +0 -0
  232. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/ollama_client.py +0 -0
  233. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/ollama_credentials.py +0 -0
  234. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/output_filter.py +0 -0
  235. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/override_grants.py +0 -0
  236. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/override_policy.py +0 -0
  237. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/override_requests.py +0 -0
  238. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/override_wake.py +0 -0
  239. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/parser.py +0 -0
  240. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/project_manager.py +0 -0
  241. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/project_runtime.py +0 -0
  242. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/protocol.py +0 -0
  243. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/proxy_state.py +0 -0
  244. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/repo_map.py +0 -0
  245. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/retention.py +0 -0
  246. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/retrieval_broker.py +0 -0
  247. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/router.py +0 -0
  248. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/runtime.py +0 -0
  249. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/scanner.py +0 -0
  250. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/session_benchmark.py +0 -0
  251. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/session_manager.py +0 -0
  252. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/session_preloader.py +0 -0
  253. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/subprojects.py +0 -0
  254. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/task_store.py +0 -0
  255. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/telemetry.py +0 -0
  256. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/text_index.py +0 -0
  257. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/time_tracker.py +0 -0
  258. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/tool_classifier.py +0 -0
  259. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/transcript_index.py +0 -0
  260. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/validation_cache.py +0 -0
  261. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/vector_store.py +0 -0
  262. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/watcher.py +0 -0
  263. {code_context_control-2.75.0 → code_context_control-2.76.2}/services/win_subprocess.py +0 -0
  264. {code_context_control-2.75.0 → code_context_control-2.76.2}/setup.cfg +0 -0
  265. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_access_builtin_optout.py +0 -0
  266. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_access_guard.py +0 -0
  267. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_access_guard_meta.py +0 -0
  268. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_access_guard_shell_project.py +0 -0
  269. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_access_guard_surfaces.py +0 -0
  270. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_access_guard_wiring.py +0 -0
  271. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_activity_reporter.py +0 -0
  272. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_agent_locks.py +0 -0
  273. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_aider_polyglot.py +0 -0
  274. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_antigravity_transition.py +0 -0
  275. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_artifact_store.py +0 -0
  276. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_artifact_tool.py +0 -0
  277. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_bitbucket_cli_smoke.py +0 -0
  278. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_bitbucket_client.py +0 -0
  279. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_bitbucket_config_fallback.py +0 -0
  280. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_bitbucket_credentials.py +0 -0
  281. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_bitbucket_tool.py +0 -0
  282. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_c3_bridge_project_artifacts.py +0 -0
  283. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_c3_shell.py +0 -0
  284. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_circuit_breaker.py +0 -0
  285. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_claude_md_merge.py +0 -0
  286. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_cli_smoke.py +0 -0
  287. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_compressor_large_file.py +0 -0
  288. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_credential_store.py +0 -0
  289. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_credentials_routes.py +0 -0
  290. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_credentials_tool.py +0 -0
  291. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_creds_cli_smoke.py +0 -0
  292. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_delegate_cascade.py +0 -0
  293. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_delegate_version_probe.py +0 -0
  294. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_e2e_benchmark.py +0 -0
  295. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_edit_ledger_hook.py +0 -0
  296. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_edit_locking.py +0 -0
  297. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_edit_normalization.py +0 -0
  298. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_edit_verify.py +0 -0
  299. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_embedding_index_deadlock.py +0 -0
  300. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_enforcement_flip.py +0 -0
  301. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_enforcement_policy.py +0 -0
  302. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_enforcement_routes.py +0 -0
  303. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_federated_graph.py +0 -0
  304. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_filter_backoff.py +0 -0
  305. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_ghost_files.py +0 -0
  306. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_ghost_generation.py +0 -0
  307. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_git_branch_awareness.py +0 -0
  308. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_hook_dispatch.py +0 -0
  309. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_hook_pretool_enforce.py +0 -0
  310. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_hook_prompt_recall.py +0 -0
  311. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_hook_smoke.py +0 -0
  312. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_hook_state.py +0 -0
  313. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_hook_utf8_stdio.py +0 -0
  314. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_hub_credentials_route.py +0 -0
  315. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_hub_credentials_routes_write.py +0 -0
  316. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_hub_enforcement_routes.py +0 -0
  317. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_hub_inspect_api.py +0 -0
  318. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_hub_locks_routes.py +0 -0
  319. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_hub_server_smoke.py +0 -0
  320. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_hub_subproject_links.py +0 -0
  321. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_ide_workflow_adaptation.py +0 -0
  322. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_init_scan.py +0 -0
  323. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_install_mcp_entrypoint.py +0 -0
  324. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_jira_cli_smoke.py +0 -0
  325. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_jira_client.py +0 -0
  326. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_jira_config_fallback.py +0 -0
  327. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_jira_credentials.py +0 -0
  328. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_jira_links.py +0 -0
  329. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_jira_routes.py +0 -0
  330. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_jira_tool.py +0 -0
  331. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_lazy_store_init.py +0 -0
  332. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_mask_guard.py +0 -0
  333. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_mask_routes.py +0 -0
  334. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_mask_surfaces.py +0 -0
  335. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_mcp_host_guard.py +0 -0
  336. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_mcp_memory_timeout.py +0 -0
  337. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_mcp_server_smoke.py +0 -0
  338. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_mcp_toml.py +0 -0
  339. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_memory_distiller.py +0 -0
  340. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_memory_graph_api.py +0 -0
  341. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_memory_queue.py +0 -0
  342. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_memory_system.py +0 -0
  343. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_mobile_override_routes.py +0 -0
  344. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_mobile_security_api.py +0 -0
  345. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_no_stale_model_pins.py +0 -0
  346. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_notification_dedup.py +0 -0
  347. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_notification_discipline.py +0 -0
  348. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_ollama_credentials.py +0 -0
  349. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_oracle_api_auth.py +0 -0
  350. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_oracle_apikey_api.py +0 -0
  351. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_oracle_c3_bridge.py +0 -0
  352. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_oracle_chat_engine.py +0 -0
  353. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_oracle_chat_store.py +0 -0
  354. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_oracle_discovery_api.py +0 -0
  355. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_oracle_discovery_audit.py +0 -0
  356. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_oracle_local_auth.py +0 -0
  357. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_oracle_ollama_bridge.py +0 -0
  358. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_oracle_scanner_cache.py +0 -0
  359. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_oracle_security_fixes.py +0 -0
  360. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_oracle_session_bootstrap.py +0 -0
  361. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_oracle_subproject_awareness.py +0 -0
  362. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_oracle_ui_bundle.py +0 -0
  363. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_output_filter.py +0 -0
  364. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_override_grants.py +0 -0
  365. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_override_grants_mcp.py +0 -0
  366. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_override_requests.py +0 -0
  367. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_override_wake.py +0 -0
  368. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_permissions.py +0 -0
  369. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_pm_api.py +0 -0
  370. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_project_manager.py +0 -0
  371. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_project_manager_merge.py +0 -0
  372. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_project_tool.py +0 -0
  373. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_read_coercion.py +0 -0
  374. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_read_edit_parity.py +0 -0
  375. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_related_facts.py +0 -0
  376. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_repo_map.py +0 -0
  377. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_response_boilerplate.py +0 -0
  378. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_retention.py +0 -0
  379. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_review_digest.py +0 -0
  380. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_service_durability.py +0 -0
  381. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_session_benchmark.py +0 -0
  382. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_session_budget.py +0 -0
  383. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_shell_creds.py +0 -0
  384. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_shell_robustness.py +0 -0
  385. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_subproject_exclusion.py +0 -0
  386. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_subproject_federation.py +0 -0
  387. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_subprojects.py +0 -0
  388. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_swe_bench.py +0 -0
  389. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_task_store.py +0 -0
  390. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_task_tool.py +0 -0
  391. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_time_tracker.py +0 -0
  392. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_token_telemetry.py +0 -0
  393. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_tool_registry.py +0 -0
  394. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_upgrade_and_version.py +0 -0
  395. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_validate.py +0 -0
  396. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_vault_write_guard.py +0 -0
  397. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_version_sync.py +0 -0
  398. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_web_security.py +0 -0
  399. {code_context_control-2.75.0 → code_context_control-2.76.2}/tests/test_windows_reliability.py +0 -0
  400. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/__init__.py +0 -0
  401. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/backend.py +0 -0
  402. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/main.py +0 -0
  403. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/screens/__init__.py +0 -0
  404. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/screens/benchmark_view.py +0 -0
  405. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/screens/claudemd_view.py +0 -0
  406. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/screens/compress_view.py +0 -0
  407. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/screens/index_view.py +0 -0
  408. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/screens/init_view.py +0 -0
  409. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/screens/mcp_view.py +0 -0
  410. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/screens/optimize_view.py +0 -0
  411. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/screens/pipe_view.py +0 -0
  412. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/screens/projects_view.py +0 -0
  413. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/screens/search_view.py +0 -0
  414. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/screens/session_view.py +0 -0
  415. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/screens/stats.py +0 -0
  416. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/screens/ui_view.py +0 -0
  417. {code_context_control-2.75.0 → code_context_control-2.76.2}/tui/theme.tcss +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-context-control
3
- Version: 2.75.0
3
+ Version: 2.76.2
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.75.0"
95
+ __version__ = "2.76.2"
96
96
 
97
97
 
98
98
  def _compress_file_cli(compressor, path, mode="smart", **kw):
@@ -72,12 +72,59 @@ _IPV6_RE = re.compile(
72
72
  # so each became a hard deny on text that names no file at all.
73
73
  _SYNTAX_CHARS = frozenset("{}[]()<>\"'`|&*?")
74
74
 
75
+ # `pkg/mod.py::TestThing`, `ns::Type` — a pytest node id or a C++/Rust scope.
76
+ # NTFS spells a stream `file:name:$TYPE`, and the doubled-colon default-stream
77
+ # form `file::$DATA` is real, so "contains ::" is NOT safe on its own. What is
78
+ # safe is the type slot: stream types are `$`-prefixed system constants, so a
79
+ # `::` NOT followed by `$` cannot be a stream spelling.
80
+ _DOUBLE_COLON_RE = re.compile(r"::(?!\$)")
81
+
82
+ # `<rev>:<path>` — how git names a blob: `git show HEAD:setup.py`,
83
+ # `git cat-file -p origin/main:src/a.py`.
84
+ _GIT_REVSPEC_RE = re.compile(r"^(?P<rev>[^:\s]+):(?P<path>[^:\s]+)$")
85
+ _GIT_CMD_RE = re.compile(r"^\s*(?:[\w.\-]*[/\\])?git(?:\.exe)?\b", re.IGNORECASE)
86
+
75
87
 
76
88
  def _is_network_token(tok: str) -> bool:
77
89
  """True for URLs and IPv6 literals/CIDRs — never for an ADS spelling."""
78
90
  return bool(_SCHEME_RE.match(tok) or _IPV6_RE.match(tok))
79
91
 
80
92
 
93
+ def _is_scope_token(tok: str) -> bool:
94
+ """True for `a/b.py::Thing` and `ns::Type` — never an ADS spelling."""
95
+ return bool(_DOUBLE_COLON_RE.search(tok))
96
+
97
+
98
+ def _git_revspec_path(cmd: str, tok: str):
99
+ """The path half of a git ``<rev>:<path>`` token, or None.
100
+
101
+ Returned so the caller can check **the path** rather than the whole token,
102
+ which is the fix and a tightening at once. Today every git revspec is denied
103
+ by accident: ``<rev>:<path>`` canonicalizes to something with a residual
104
+ colon and trips ``<ads>``, so ``git show origin/main:pyproject.toml`` — an
105
+ everyday command naming nothing sensitive — is refused.
106
+
107
+ Whitelisting the shape outright would go too far the other way, because
108
+ ``git show HEAD:.env`` really does print a denied file's contents, and right
109
+ now the only thing stopping it is the false positive. Checking the path half
110
+ gets both right: `.env` is denied on its own rule, `pyproject.toml` is
111
+ allowed on its own merits, and neither answer depends on a rule misfiring.
112
+
113
+ Gated on the command actually being ``git``, since ``<word>:<word>`` means
114
+ something else almost everywhere else.
115
+ """
116
+ if not _GIT_CMD_RE.match(cmd or ""):
117
+ return None
118
+ if len(tok) > 1 and tok[1] == ":":
119
+ return None # a drive letter is not a revspec separator
120
+ m = _GIT_REVSPEC_RE.match(tok)
121
+ if not m:
122
+ return None
123
+ path = m.group("path")
124
+ # A `$`-prefixed suffix is a stream type, not a path. Do not reinterpret it.
125
+ return None if path.startswith("$") else path
126
+
127
+
81
128
  def _looks_like_a_path(tok: str) -> bool:
82
129
  """False for tokens that are shell syntax rather than a path argument.
83
130
 
@@ -167,6 +214,16 @@ def _scan_shell(cmd: str, base: str):
167
214
  # a path at all" — and the second is the one that generalizes.
168
215
  if not _looks_like_a_path(tok) or _is_network_token(tok):
169
216
  continue
217
+ # `tests/x.py::TestThing` is a node id, not a stream spelling.
218
+ if _is_scope_token(tok):
219
+ continue
220
+ # `git show <rev>:<path>` — judge the PATH, not the whole token. This
221
+ # is the one place the scan rewrites what it checks rather than skipping
222
+ # it, because skipping would let `git show HEAD:.env` through.
223
+ revspec_path = _git_revspec_path(cmd, tok)
224
+ from_revspec = revspec_path is not None
225
+ if from_revspec:
226
+ tok = revspec_path
170
227
  if re.match(r"^/[a-z]/", tok): # MSYS /c/foo → C:/foo
171
228
  tok = f"{tok[1]}:{tok[2:]}"
172
229
  denial = ag.check(tok, "read", base)
@@ -176,7 +233,11 @@ def _scan_shell(cmd: str, base: str):
176
233
  exists = (p if p.is_absolute() else Path(base) / p).exists()
177
234
  except OSError:
178
235
  exists = False
179
- if exists or denial.rule.startswith("<"):
236
+ # A revspec names a path in HISTORY, so the working tree is the
237
+ # wrong place to ask whether it is real. `git show HEAD~5:.env`
238
+ # reads a denied file whether or not that file exists today, and
239
+ # existence-gating it would be a hole this rewrite opened.
240
+ if exists or from_revspec or denial.rule.startswith("<"):
180
241
  return denial, tok
181
242
  return None, ""
182
243
 
@@ -387,10 +387,12 @@ def _edit_locked(path: Path, rel: str, file_path: str, old_string: str,
387
387
  tag_list = [t.strip() for t in tags.split(",") if t.strip()] if tags else None
388
388
  n_new = new_string.count("\n") + 1 if new_string else 0
389
389
  create_summary = summary or f"Created {rel} ({n_new}L)"
390
- _log_to_ledger(rel, create_summary, tag_list, svc,
391
- detail={"old_string": "", "new_string": new_string[:_DETAIL_CAP], "created": True})
390
+ deferred = _log_to_ledger(
391
+ rel, create_summary, tag_list, svc,
392
+ detail={"old_string": "", "new_string": new_string[:_DETAIL_CAP], "created": True})
392
393
  short = f"✓ {rel} [created, +{n_new}L]" + (f" — {summary}" if summary else "")
393
- return finalize("c3_edit", {"file": file_path}, short, f"{rel} created")
394
+ return finalize("c3_edit", {"file": file_path}, short + deferred,
395
+ f"{rel} created")
394
396
 
395
397
  # Parse tag list once
396
398
  tag_list = [t.strip() for t in tags.split(",") if t.strip()] if tags else None
@@ -477,6 +479,7 @@ def _edit_locked(path: Path, rel: str, file_path: str, old_string: str,
477
479
  f"Write error: {e}", "write error")
478
480
 
479
481
  # Log batch to ledger as one entry (store each patch's old/new for diff view)
482
+ deferred = ""
480
483
  if any_applied:
481
484
  batch_detail = {"patches": [
482
485
  {
@@ -486,7 +489,9 @@ def _edit_locked(path: Path, rel: str, file_path: str, old_string: str,
486
489
  }
487
490
  for p in edit_list if p.get("old_string") is not None
488
491
  ]}
489
- _log_to_ledger(rel, summary or f"Batch edit: {len(edit_list)} patches", tag_list, svc, detail=batch_detail)
492
+ deferred = _log_to_ledger(
493
+ rel, summary or f"Batch edit: {len(edit_list)} patches",
494
+ tag_list, svc, detail=batch_detail)
490
495
 
491
496
  # Classify from the structured status list, not by substring-scanning
492
497
  # the human-readable result lines — a patch *summary* containing words
@@ -499,7 +504,7 @@ def _edit_locked(path: Path, rel: str, file_path: str, old_string: str,
499
504
  short += "\n" + "\n".join(failed)
500
505
  if first_miss:
501
506
  short += first_miss
502
- return finalize("c3_edit", {"file": file_path}, short,
507
+ return finalize("c3_edit", {"file": file_path}, short + deferred,
503
508
  f"{rel} patched ({len(edit_list)} patches)")
504
509
 
505
510
  # ── Single-edit mode ──────────────────────────────────────────────────────
@@ -548,7 +553,8 @@ def _edit_locked(path: Path, rel: str, file_path: str, old_string: str,
548
553
  }
549
554
  if used_fallback:
550
555
  single_detail["unicode_normalized"] = True
551
- _log_to_ledger(rel, auto_summary, tag_list, svc, detail=single_detail)
556
+ deferred = _log_to_ledger(rel, auto_summary, tag_list, svc,
557
+ detail=single_detail)
552
558
 
553
559
  n_old = old_string.count("\n") + 1
554
560
  n_new = new_string.count("\n") + 1
@@ -556,14 +562,73 @@ def _edit_locked(path: Path, rel: str, file_path: str, old_string: str,
556
562
  occ = f" ({occurrences}x)" if occurrences > 1 else ""
557
563
  norm_tag = " [unicode-normalized]" if used_fallback else ""
558
564
  short = f"✓ {rel} [{delta}]{occ}{norm_tag}" + (f" — {summary}" if summary else "")
559
- return finalize("c3_edit", {"file": file_path}, short, f"{rel} patched")
565
+ return finalize("c3_edit", {"file": file_path}, short + deferred,
566
+ f"{rel} patched")
560
567
 
561
568
 
562
569
  _DETAIL_CAP = 2000 # chars stored per old/new string in the ledger
563
570
 
571
+ #: How long the post-write bookkeeping gets before the caller stops waiting on
572
+ #: it. Normal is milliseconds — a JSONL append and a git call that already caps
573
+ #: itself at 4s. Ten seconds is far outside normal and far inside the harness's
574
+ #: idle timeout, which is the number this exists to stay away from.
575
+ _LEDGER_DEADLINE_S = 10.0
576
+
577
+ _DEFERRED_NOTE = (
578
+ "\n [c3:ledger-deferred] The FILE WRITE SUCCEEDED. Recording it in the "
579
+ "ledger outran {sec:.0f}s and was left running in the background, so the "
580
+ "edit may be missing from c3_edits history and from "
581
+ "c3_edits(action='verify') corroboration.\n"
582
+ " Do not re-apply this edit on the strength of that absence — the file is "
583
+ "the evidence, and it already has the change."
584
+ )
585
+
586
+
587
+ def _log_to_ledger(rel: str, summary: str, tag_list, svc,
588
+ detail: dict = None) -> str:
589
+ """Record an edit in the ledger, activity log, and session manager.
590
+
591
+ Never raises, and — since #74 — never blocks the caller indefinitely.
592
+
593
+ The write has already happened by the time this runs. That ordering is what
594
+ makes a stall here so expensive: one logged `c3_edit` hung until the harness
595
+ aborted it at 1800s while the file on disk was already correct, so half an
596
+ hour bought a report of work that had finished in milliseconds.
597
+
598
+ The host-side cause of that stall is not C3's (see #74 — the box hits
599
+ commit-charge exhaustion in short unpredictable windows), and nothing here
600
+ prevents it. What this does prevent is *paying 1800s to find out*. The
601
+ bookkeeping runs on a daemon thread; if it outlives the deadline the caller
602
+ returns anyway, with the response saying plainly that the write landed and
603
+ the record may not have. The thread is left alone rather than killed — it
604
+ may well finish a moment later, and a half-written ledger entry would be
605
+ worse than a late one.
606
+
607
+ Returns "" normally, or a note to append to the response when the deadline
608
+ passed. Reporting a degraded record is the point; a silent one would make
609
+ this indistinguishable from a clean run, which is the failure class this
610
+ whole subsystem exists to remove.
611
+ """
612
+ if not svc.edit_ledger:
613
+ return ""
614
+ done = threading.Event()
615
+
616
+ def _record() -> None:
617
+ try:
618
+ _log_to_ledger_blocking(rel, summary, tag_list, svc, detail)
619
+ finally:
620
+ done.set()
621
+
622
+ threading.Thread(target=_record, name="c3-edit-ledger",
623
+ daemon=True).start()
624
+ if done.wait(_LEDGER_DEADLINE_S):
625
+ return ""
626
+ return _DEFERRED_NOTE.format(sec=_LEDGER_DEADLINE_S)
627
+
564
628
 
565
- def _log_to_ledger(rel: str, summary: str, tag_list, svc, detail: dict = None) -> None:
566
- """Log an edit to the ledger, activity log, and session manager. Never raises."""
629
+ def _log_to_ledger_blocking(rel: str, summary: str, tag_list, svc,
630
+ detail: dict = None) -> None:
631
+ """The bookkeeping itself. Never raises; may block. Always run on a thread."""
567
632
  if not svc.edit_ledger:
568
633
  return
569
634
  try:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-context-control
3
- Version: 2.75.0
3
+ Version: 2.76.2
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
@@ -136,6 +136,7 @@ oracle/services/activity_reporter.py
136
136
  oracle/services/api_auth.py
137
137
  oracle/services/c3_bridge.py
138
138
  oracle/services/chat_engine.py
139
+ oracle/services/chat_poll.py
139
140
  oracle/services/chat_store.py
140
141
  oracle/services/cross_memory.py
141
142
  oracle/services/discovery_audit.py
@@ -273,6 +274,7 @@ tests/test_bitbucket_credentials.py
273
274
  tests/test_bitbucket_tool.py
274
275
  tests/test_c3_bridge_project_artifacts.py
275
276
  tests/test_c3_shell.py
277
+ tests/test_chat_poll.py
276
278
  tests/test_circuit_breaker.py
277
279
  tests/test_claude_md_merge.py
278
280
  tests/test_cli_smoke.py
@@ -284,6 +286,7 @@ tests/test_creds_cli_smoke.py
284
286
  tests/test_delegate_cascade.py
285
287
  tests/test_delegate_version_probe.py
286
288
  tests/test_e2e_benchmark.py
289
+ tests/test_edit_ledger_deadline.py
287
290
  tests/test_edit_ledger_hook.py
288
291
  tests/test_edit_locking.py
289
292
  tests/test_edit_normalization.py
@@ -334,6 +337,7 @@ tests/test_memory_graph_api.py
334
337
  tests/test_memory_queue.py
335
338
  tests/test_memory_system.py
336
339
  tests/test_mobile_api.py
340
+ tests/test_mobile_extras.py
337
341
  tests/test_mobile_override_routes.py
338
342
  tests/test_mobile_security_api.py
339
343
  tests/test_no_stale_model_pins.py
@@ -248,11 +248,17 @@ def _local_write_guard():
248
248
 
249
249
  # ── Mobile gateway (companion app surface, /api/mobile/*) ─
250
250
  # Bearer required on every method, GETs included — see mobile_api docstring.
251
- from oracle.services import mobile_api # noqa: E402
251
+ from oracle.services import chat_poll, mobile_api # noqa: E402
252
252
 
253
253
  mobile_api.configure(get_cfg=lambda: _cfg, get_limiter=_rate_limiter)
254
254
  app.register_blueprint(mobile_api.bp)
255
255
 
256
+ # Poll-based chat transport (/api/mobile/chat/*) — phones cannot hold the SSE
257
+ # connection /api/chat serves. Same bearer token, same engine generator.
258
+ chat_poll.configure(get_engine=lambda: _chat_engine, get_store=lambda: _chat_store,
259
+ get_cfg=lambda: _cfg)
260
+ app.register_blueprint(chat_poll.bp)
261
+
256
262
 
257
263
  # ── Static ────────────────────────────────────────────────
258
264