code-context-control 2.141.0__tar.gz → 2.142.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 (562) hide show
  1. {code_context_control-2.141.0 → code_context_control-2.142.0}/PKG-INFO +1 -1
  2. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/c3.py +1 -1
  3. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_server.py +178 -2
  4. {code_context_control-2.141.0 → code_context_control-2.142.0}/code_context_control.egg-info/PKG-INFO +1 -1
  5. {code_context_control-2.141.0 → code_context_control-2.142.0}/code_context_control.egg-info/SOURCES.txt +1 -0
  6. {code_context_control-2.141.0 → code_context_control-2.142.0}/pyproject.toml +1 -1
  7. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/access_guard.py +22 -0
  8. code_context_control-2.142.0/tests/test_hub_access_routes.py +230 -0
  9. {code_context_control-2.141.0 → code_context_control-2.142.0}/LICENSE +0 -0
  10. {code_context_control-2.141.0 → code_context_control-2.142.0}/README.md +0 -0
  11. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/__init__.py +0 -0
  12. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/_hook_utils.py +0 -0
  13. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/_shell_writes.py +0 -0
  14. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/commands/__init__.py +0 -0
  15. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/commands/common.py +0 -0
  16. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/commands/parser.py +0 -0
  17. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/docs.html +0 -0
  18. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/edits.html +0 -0
  19. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/guide/access.html +0 -0
  20. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/guide/bitbucket.html +0 -0
  21. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/guide/credentials.html +0 -0
  22. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/guide/getting-started.html +0 -0
  23. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/guide/index.html +0 -0
  24. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/guide/masking.html +0 -0
  25. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/guide/oracle.html +0 -0
  26. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/guide/shared.css +0 -0
  27. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/guide/tools.html +0 -0
  28. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/guide/workflow.html +0 -0
  29. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_access_guard.py +0 -0
  30. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_agent_model.py +0 -0
  31. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_artifact.py +0 -0
  32. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_auto_snapshot.py +0 -0
  33. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_c3_signal.py +0 -0
  34. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_c3read.py +0 -0
  35. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_codex_lifecycle.py +0 -0
  36. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_dispatch.py +0 -0
  37. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_edit_ledger.py +0 -0
  38. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_edit_unlock.py +0 -0
  39. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_filter.py +0 -0
  40. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_ghost_files.py +0 -0
  41. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_pretool_enforce.py +0 -0
  42. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_prompt_recall.py +0 -0
  43. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_read.py +0 -0
  44. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_session_end.py +0 -0
  45. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_session_open.py +0 -0
  46. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_session_stats.py +0 -0
  47. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hook_terse_advisor.py +0 -0
  48. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/app.js +0 -0
  49. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/add_project.js +0 -0
  50. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/config_editor.js +0 -0
  51. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
  52. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/drill_health.js +0 -0
  53. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/drill_panel.js +0 -0
  54. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
  55. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/drill_tasks.js +0 -0
  56. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/drill_views.js +0 -0
  57. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/global_search.js +0 -0
  58. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/hub_access.js +0 -0
  59. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/hub_ci.js +0 -0
  60. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/hub_cred_audit.js +0 -0
  61. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/hub_credentials.js +0 -0
  62. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
  63. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/hub_locks.js +0 -0
  64. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/hub_tokens.js +0 -0
  65. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/mcp_manager.js +0 -0
  66. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/modals.js +0 -0
  67. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/project_card.js +0 -0
  68. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/project_tree.js +0 -0
  69. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/session_drawer.js +0 -0
  70. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/settings_modal.js +0 -0
  71. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/sidebar.js +0 -0
  72. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/summary_bar.js +0 -0
  73. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/task_board.js +0 -0
  74. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/toasts.js +0 -0
  75. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/components/topbar.js +0 -0
  76. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui/state.js +0 -0
  77. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/hub_ui.html +0 -0
  78. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/mcp_proxy.py +0 -0
  79. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/mcp_server.py +0 -0
  80. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/progress.py +0 -0
  81. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/server.py +0 -0
  82. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/__init__.py +0 -0
  83. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/_grants.py +0 -0
  84. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/_helpers.py +0 -0
  85. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/agent.py +0 -0
  86. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/artifacts.py +0 -0
  87. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/bitbucket.py +0 -0
  88. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/ci.py +0 -0
  89. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/compress.py +0 -0
  90. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/credentials.py +0 -0
  91. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/delegate.py +0 -0
  92. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/edit.py +0 -0
  93. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/edit_verify.py +0 -0
  94. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/edits.py +0 -0
  95. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/federate.py +0 -0
  96. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/filter.py +0 -0
  97. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/impact.py +0 -0
  98. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/jira.py +0 -0
  99. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/locks.py +0 -0
  100. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/memory.py +0 -0
  101. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/override.py +0 -0
  102. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/project.py +0 -0
  103. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/read.py +0 -0
  104. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/search.py +0 -0
  105. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/session.py +0 -0
  106. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/shell.py +0 -0
  107. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/shell_job.py +0 -0
  108. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/shell_nudge.py +0 -0
  109. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/shell_parsers.py +0 -0
  110. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/shell_render.py +0 -0
  111. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/status.py +0 -0
  112. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/tasks.py +0 -0
  113. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/tools/validate.py +0 -0
  114. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/api.js +0 -0
  115. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/app.js +0 -0
  116. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/components/access.js +0 -0
  117. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/components/bitbucket.js +0 -0
  118. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/components/chat.js +0 -0
  119. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/components/credentials.js +0 -0
  120. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/components/dashboard.js +0 -0
  121. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/components/edits.js +0 -0
  122. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/components/enforcement.js +0 -0
  123. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/components/instructions.js +0 -0
  124. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/components/jira.js +0 -0
  125. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/components/memory.js +0 -0
  126. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/components/sessions.js +0 -0
  127. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/components/settings.js +0 -0
  128. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/components/sidebar.js +0 -0
  129. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/components/tasks.js +0 -0
  130. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/icons.js +0 -0
  131. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/pm_shared.js +0 -0
  132. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/shared.js +0 -0
  133. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui/theme.js +0 -0
  134. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui.html +0 -0
  135. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui_legacy.html +0 -0
  136. {code_context_control-2.141.0 → code_context_control-2.142.0}/cli/ui_nano.html +0 -0
  137. {code_context_control-2.141.0 → code_context_control-2.142.0}/code_context_control.egg-info/dependency_links.txt +0 -0
  138. {code_context_control-2.141.0 → code_context_control-2.142.0}/code_context_control.egg-info/entry_points.txt +0 -0
  139. {code_context_control-2.141.0 → code_context_control-2.142.0}/code_context_control.egg-info/requires.txt +0 -0
  140. {code_context_control-2.141.0 → code_context_control-2.142.0}/code_context_control.egg-info/top_level.txt +0 -0
  141. {code_context_control-2.141.0 → code_context_control-2.142.0}/core/__init__.py +0 -0
  142. {code_context_control-2.141.0 → code_context_control-2.142.0}/core/codex_patch.py +0 -0
  143. {code_context_control-2.141.0 → code_context_control-2.142.0}/core/config.py +0 -0
  144. {code_context_control-2.141.0 → code_context_control-2.142.0}/core/grok_payload.py +0 -0
  145. {code_context_control-2.141.0 → code_context_control-2.142.0}/core/hook_command.py +0 -0
  146. {code_context_control-2.141.0 → code_context_control-2.142.0}/core/host.py +0 -0
  147. {code_context_control-2.141.0 → code_context_control-2.142.0}/core/ide.py +0 -0
  148. {code_context_control-2.141.0 → code_context_control-2.142.0}/core/mcp_toml.py +0 -0
  149. {code_context_control-2.141.0 → code_context_control-2.142.0}/core/web_security.py +0 -0
  150. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/__init__.py +0 -0
  151. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/config.py +0 -0
  152. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/listeners.py +0 -0
  153. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/mcp_oracle.py +0 -0
  154. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/oracle_server.py +0 -0
  155. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/oracle_ui.html +0 -0
  156. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/__init__.py +0 -0
  157. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/activity_reporter.py +0 -0
  158. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/api_auth.py +0 -0
  159. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/c3_bridge.py +0 -0
  160. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/chat_engine.py +0 -0
  161. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/chat_poll.py +0 -0
  162. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/chat_store.py +0 -0
  163. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/client_tokens.py +0 -0
  164. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/cross_memory.py +0 -0
  165. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/discovery_audit.py +0 -0
  166. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/federated_graph.py +0 -0
  167. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/health_checker.py +0 -0
  168. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/insight_engine.py +0 -0
  169. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/local_session.py +0 -0
  170. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/memory_reader.py +0 -0
  171. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/memory_writer.py +0 -0
  172. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/mobile_api.py +0 -0
  173. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/project_scanner.py +0 -0
  174. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/review_agent.py +0 -0
  175. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/tool_executor.py +0 -0
  176. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/services/tool_registry.py +0 -0
  177. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/activity.js +0 -0
  178. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/agents.js +0 -0
  179. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/app.js +0 -0
  180. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/busy.js +0 -0
  181. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/chat/conversations.js +0 -0
  182. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/chat/input.js +0 -0
  183. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/chat/markdown.js +0 -0
  184. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/chat/send.js +0 -0
  185. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/chat/stream_renderer.js +0 -0
  186. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/chat/toolbar.js +0 -0
  187. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/core.js +0 -0
  188. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/crossgraph.js +0 -0
  189. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/header.js +0 -0
  190. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/insights.js +0 -0
  191. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/projects.js +0 -0
  192. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/qrcode.js +0 -0
  193. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/settings.js +0 -0
  194. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/suggestions.js +0 -0
  195. {code_context_control-2.141.0 → code_context_control-2.142.0}/oracle/ui/theme_tabs.js +0 -0
  196. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/__init__.py +0 -0
  197. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/access_telemetry.py +0 -0
  198. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/activity_log.py +0 -0
  199. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/agent_base.py +0 -0
  200. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/agent_downshift.py +0 -0
  201. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/agent_locks.py +0 -0
  202. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/agents.py +0 -0
  203. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/agents_workflow.py +0 -0
  204. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/artifact_defs.py +0 -0
  205. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/artifact_store.py +0 -0
  206. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/atomic_json.py +0 -0
  207. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/auto_memory.py +0 -0
  208. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/background_service.py +0 -0
  209. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/bench/__init__.py +0 -0
  210. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/bench/delegate_eval.py +0 -0
  211. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/bench/delegate_write_eval.py +0 -0
  212. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/bench/external/__init__.py +0 -0
  213. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/bench/external/aider_polyglot.py +0 -0
  214. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/bench/external/swe_bench.py +0 -0
  215. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/bench/map_eval.py +0 -0
  216. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/bench/search_eval.py +0 -0
  217. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/bench/shell_eval.py +0 -0
  218. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/benchmark_dashboard.py +0 -0
  219. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/bitbucket_client.py +0 -0
  220. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/bitbucket_credentials.py +0 -0
  221. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/ci_act.py +0 -0
  222. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/ci_cache.py +0 -0
  223. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/ci_expr.py +0 -0
  224. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/ci_failures.py +0 -0
  225. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/ci_github.py +0 -0
  226. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/ci_impact.py +0 -0
  227. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/ci_intel.py +0 -0
  228. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/ci_runner.py +0 -0
  229. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/ci_workflow.py +0 -0
  230. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/circuit_breaker.py +0 -0
  231. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/claude_md.py +0 -0
  232. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/codex_integration.py +0 -0
  233. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/codex_transcript.py +0 -0
  234. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/compressor.py +0 -0
  235. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/context_snapshot.py +0 -0
  236. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/conversation_store.py +0 -0
  237. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/cred_audit.py +0 -0
  238. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/cred_telemetry.py +0 -0
  239. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/credential_store.py +0 -0
  240. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/delegate_agents.py +0 -0
  241. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/delegate_hints.py +0 -0
  242. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/delegate_write.py +0 -0
  243. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/dir_map.py +0 -0
  244. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/doc_index.py +0 -0
  245. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/e2e_benchmark.py +0 -0
  246. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/e2e_evaluator.py +0 -0
  247. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/e2e_tasks.py +0 -0
  248. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/edit_ledger.py +0 -0
  249. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/embedding_index.py +0 -0
  250. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/enforcement_policy.py +0 -0
  251. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/error_reporting.py +0 -0
  252. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/file_map.py +0 -0
  253. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/file_memory.py +0 -0
  254. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/git_context.py +0 -0
  255. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/grok_integration.py +0 -0
  256. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/grok_transcript.py +0 -0
  257. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/host_sessions.py +0 -0
  258. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/hub_service.py +0 -0
  259. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/index_store.py +0 -0
  260. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/indexer.py +0 -0
  261. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/jira_client.py +0 -0
  262. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/jira_cloud.py +0 -0
  263. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/jira_credentials.py +0 -0
  264. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/jira_data_center.py +0 -0
  265. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/jira_links.py +0 -0
  266. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/lexical_index.py +0 -0
  267. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/mask_activation.py +0 -0
  268. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/mask_mirror.py +0 -0
  269. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/mask_presets.py +0 -0
  270. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/memory.py +0 -0
  271. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/memory_consolidator.py +0 -0
  272. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/memory_distiller.py +0 -0
  273. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/memory_graph.py +0 -0
  274. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/memory_grounder.py +0 -0
  275. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/memory_queue.py +0 -0
  276. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/memory_scorer.py +0 -0
  277. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/metrics.py +0 -0
  278. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/notifications.py +0 -0
  279. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/ollama_bridge.py +0 -0
  280. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/ollama_client.py +0 -0
  281. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/ollama_credentials.py +0 -0
  282. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/oracle_service.py +0 -0
  283. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/output_filter.py +0 -0
  284. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/override_costs.py +0 -0
  285. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/override_grants.py +0 -0
  286. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/override_policy.py +0 -0
  287. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/override_requests.py +0 -0
  288. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/override_wake.py +0 -0
  289. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/parser.py +0 -0
  290. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/project_manager.py +0 -0
  291. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/project_runtime.py +0 -0
  292. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/protocol.py +0 -0
  293. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/proxy_state.py +0 -0
  294. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/repo_map.py +0 -0
  295. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/repo_shape.py +0 -0
  296. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/reranker.py +0 -0
  297. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/retention.py +0 -0
  298. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/retrieval.py +0 -0
  299. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/retrieval_broker.py +0 -0
  300. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/router.py +0 -0
  301. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/runtime.py +0 -0
  302. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/scanner.py +0 -0
  303. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/session_benchmark.py +0 -0
  304. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/session_live.py +0 -0
  305. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/session_manager.py +0 -0
  306. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/session_preloader.py +0 -0
  307. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/shell_jobs.py +0 -0
  308. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/shell_output.py +0 -0
  309. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/subprojects.py +0 -0
  310. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/task_store.py +0 -0
  311. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/telemetry.py +0 -0
  312. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/text_index.py +0 -0
  313. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/time_tracker.py +0 -0
  314. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/tool_classifier.py +0 -0
  315. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/transcript_index.py +0 -0
  316. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/validation_cache.py +0 -0
  317. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/vector_store.py +0 -0
  318. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/watcher.py +0 -0
  319. {code_context_control-2.141.0 → code_context_control-2.142.0}/services/win_subprocess.py +0 -0
  320. {code_context_control-2.141.0 → code_context_control-2.142.0}/setup.cfg +0 -0
  321. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_access_builtin_optout.py +0 -0
  322. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_access_guard.py +0 -0
  323. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_access_guard_meta.py +0 -0
  324. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_access_guard_shell_project.py +0 -0
  325. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_access_guard_surfaces.py +0 -0
  326. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_access_guard_wiring.py +0 -0
  327. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_activity_log_find_last.py +0 -0
  328. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_activity_reporter.py +0 -0
  329. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_agent_locks.py +0 -0
  330. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_aider_polyglot.py +0 -0
  331. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_antigravity_transition.py +0 -0
  332. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_artifact_store.py +0 -0
  333. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_artifact_tool.py +0 -0
  334. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_atomic_json.py +0 -0
  335. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_background_service.py +0 -0
  336. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_bitbucket_cli_smoke.py +0 -0
  337. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_bitbucket_client.py +0 -0
  338. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_bitbucket_config_fallback.py +0 -0
  339. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_bitbucket_credentials.py +0 -0
  340. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_bitbucket_tool.py +0 -0
  341. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_builtin_modes.py +0 -0
  342. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
  343. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_c3_shell.py +0 -0
  344. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_chat_poll.py +0 -0
  345. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_ci_act.py +0 -0
  346. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_ci_cache.py +0 -0
  347. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_ci_dag_ownership.py +0 -0
  348. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_ci_expr.py +0 -0
  349. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_ci_impact.py +0 -0
  350. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_ci_intel.py +0 -0
  351. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_ci_runner.py +0 -0
  352. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_ci_workflow.py +0 -0
  353. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_circuit_breaker.py +0 -0
  354. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_claude_md_merge.py +0 -0
  355. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_claude_md_updater.py +0 -0
  356. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_cli_smoke.py +0 -0
  357. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_codex_mcp_transport.py +0 -0
  358. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_codex_native.py +0 -0
  359. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_compressor_large_file.py +0 -0
  360. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_confirm_guard.py +0 -0
  361. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_confirm_guard_wiring.py +0 -0
  362. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_cooccurrence_bounds.py +0 -0
  363. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_cred_audit.py +0 -0
  364. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_cred_telemetry.py +0 -0
  365. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_credential_login_kind.py +0 -0
  366. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_credential_store.py +0 -0
  367. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_credential_ui_parity.py +0 -0
  368. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_credentials_routes.py +0 -0
  369. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_credentials_tool.py +0 -0
  370. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_creds_cli_smoke.py +0 -0
  371. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_delegate_adoption_d4.py +0 -0
  372. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_delegate_auto.py +0 -0
  373. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_delegate_cascade.py +0 -0
  374. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_delegate_claude_d1.py +0 -0
  375. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_delegate_eval.py +0 -0
  376. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_delegate_grok.py +0 -0
  377. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_delegate_host_d2.py +0 -0
  378. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_delegate_scout_d3.py +0 -0
  379. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_delegate_telemetry_d0.py +0 -0
  380. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_delegate_thinking_cap.py +0 -0
  381. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_delegate_tuning.py +0 -0
  382. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_delegate_version_probe.py +0 -0
  383. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_delegate_write.py +0 -0
  384. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_delegate_write_eval.py +0 -0
  385. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_dir_map_c3.py +0 -0
  386. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_e2e_benchmark.py +0 -0
  387. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_edit_ledger_deadline.py +0 -0
  388. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_edit_ledger_hook.py +0 -0
  389. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_edit_locking.py +0 -0
  390. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_edit_normalization.py +0 -0
  391. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_edit_verify.py +0 -0
  392. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_embedding_index_deadlock.py +0 -0
  393. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_enforcement_flip.py +0 -0
  394. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_enforcement_policy.py +0 -0
  395. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_enforcement_routes.py +0 -0
  396. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_env_parser.py +0 -0
  397. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_failed_calls_do_not_unlock.py +0 -0
  398. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_federated_graph.py +0 -0
  399. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_file_map_c1.py +0 -0
  400. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_filter_backoff.py +0 -0
  401. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_ghost_files.py +0 -0
  402. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_ghost_generation.py +0 -0
  403. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_git_branch_awareness.py +0 -0
  404. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_grok_native.py +0 -0
  405. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hook_access_guard.py +0 -0
  406. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hook_codex_compat.py +0 -0
  407. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hook_dispatch.py +0 -0
  408. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hook_grok_compat.py +0 -0
  409. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hook_pretool_enforce.py +0 -0
  410. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hook_prompt_recall.py +0 -0
  411. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hook_session_end.py +0 -0
  412. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hook_smoke.py +0 -0
  413. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hook_state.py +0 -0
  414. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hook_utf8_stdio.py +0 -0
  415. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hub_credentials_route.py +0 -0
  416. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hub_credentials_routes_write.py +0 -0
  417. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hub_enforcement_routes.py +0 -0
  418. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hub_hook_migration.py +0 -0
  419. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hub_inspect_api.py +0 -0
  420. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hub_locks_routes.py +0 -0
  421. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hub_oracle_service_routes.py +0 -0
  422. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hub_override_policy_routes.py +0 -0
  423. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hub_override_routes.py +0 -0
  424. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hub_rules_routes.py +0 -0
  425. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hub_server_smoke.py +0 -0
  426. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_hub_subproject_links.py +0 -0
  427. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_ide_workflow_adaptation.py +0 -0
  428. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_index_cap_not_hardcoded.py +0 -0
  429. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_init_clear_preserves_user_content.py +0 -0
  430. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_init_scan.py +0 -0
  431. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_install_mcp_entrypoint.py +0 -0
  432. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_jira_cli_smoke.py +0 -0
  433. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_jira_client.py +0 -0
  434. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_jira_config_fallback.py +0 -0
  435. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_jira_credentials.py +0 -0
  436. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_jira_links.py +0 -0
  437. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_jira_routes.py +0 -0
  438. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_jira_tool.py +0 -0
  439. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_large_files_c4.py +0 -0
  440. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_lazy_store_init.py +0 -0
  441. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_map_eval.py +0 -0
  442. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_map_telemetry_c0.py +0 -0
  443. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_mask_guard.py +0 -0
  444. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_mask_routes.py +0 -0
  445. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_mask_surfaces.py +0 -0
  446. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_mcp_host_guard.py +0 -0
  447. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_mcp_memory_timeout.py +0 -0
  448. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_mcp_server_smoke.py +0 -0
  449. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_mcp_toml.py +0 -0
  450. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_memory_distiller.py +0 -0
  451. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_memory_graph_api.py +0 -0
  452. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_memory_queue.py +0 -0
  453. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_memory_system.py +0 -0
  454. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_mobile_api.py +0 -0
  455. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_mobile_clients.py +0 -0
  456. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_mobile_extras.py +0 -0
  457. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_mobile_jobs_ci.py +0 -0
  458. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_mobile_override_costs.py +0 -0
  459. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_mobile_override_routes.py +0 -0
  460. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_mobile_security_api.py +0 -0
  461. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_no_stale_model_pins.py +0 -0
  462. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_notification_dedup.py +0 -0
  463. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_notification_discipline.py +0 -0
  464. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_notification_kinds.py +0 -0
  465. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_ollama_credentials.py +0 -0
  466. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_oracle_api_auth.py +0 -0
  467. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_oracle_apikey_api.py +0 -0
  468. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_oracle_c3_bridge.py +0 -0
  469. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_oracle_chat_engine.py +0 -0
  470. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_oracle_chat_store.py +0 -0
  471. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_oracle_discovery_api.py +0 -0
  472. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_oracle_discovery_audit.py +0 -0
  473. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_oracle_health_probe.py +0 -0
  474. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_oracle_local_auth.py +0 -0
  475. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_oracle_loopback.py +0 -0
  476. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_oracle_ollama_bridge.py +0 -0
  477. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_oracle_scanner_cache.py +0 -0
  478. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_oracle_security_fixes.py +0 -0
  479. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_oracle_session_bootstrap.py +0 -0
  480. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_oracle_subproject_awareness.py +0 -0
  481. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_oracle_ui_bundle.py +0 -0
  482. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_output_filter.py +0 -0
  483. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_override_costs.py +0 -0
  484. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_override_grants.py +0 -0
  485. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_override_grants_mcp.py +0 -0
  486. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_override_requests.py +0 -0
  487. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_override_wake.py +0 -0
  488. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_permissions.py +0 -0
  489. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_pm_api.py +0 -0
  490. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_project_manager.py +0 -0
  491. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_project_manager_merge.py +0 -0
  492. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_project_tool.py +0 -0
  493. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_read_coercion.py +0 -0
  494. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_read_edit_parity.py +0 -0
  495. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_read_outside_root.py +0 -0
  496. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_related_facts.py +0 -0
  497. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_repo_map.py +0 -0
  498. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_repo_shape.py +0 -0
  499. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_response_boilerplate.py +0 -0
  500. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_retention.py +0 -0
  501. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_review_digest.py +0 -0
  502. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_search_eval.py +0 -0
  503. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_search_p1.py +0 -0
  504. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_search_p2.py +0 -0
  505. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_search_p2b.py +0 -0
  506. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_search_p3.py +0 -0
  507. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_search_p4.py +0 -0
  508. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_search_p5.py +0 -0
  509. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_service_durability.py +0 -0
  510. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_session_benchmark.py +0 -0
  511. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_session_budget.py +0 -0
  512. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_session_live.py +0 -0
  513. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_shell_budget_s1.py +0 -0
  514. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_shell_creds.py +0 -0
  515. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_shell_eval.py +0 -0
  516. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_shell_jobs_s3.py +0 -0
  517. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_shell_nudge_s4.py +0 -0
  518. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_shell_output.py +0 -0
  519. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_shell_parsers_s2.py +0 -0
  520. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_shell_robustness.py +0 -0
  521. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_shell_telemetry_s0.py +0 -0
  522. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_shell_write_ledger.py +0 -0
  523. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_shell_writes.py +0 -0
  524. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_subproject_clear_scope.py +0 -0
  525. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_subproject_depth_consumers.py +0 -0
  526. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_subproject_exclusion.py +0 -0
  527. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_subproject_federation.py +0 -0
  528. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_subproject_linkage_api.py +0 -0
  529. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_subprojects.py +0 -0
  530. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_swe_bench.py +0 -0
  531. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_task_store.py +0 -0
  532. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_task_tool.py +0 -0
  533. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_time_tracker.py +0 -0
  534. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_token_telemetry.py +0 -0
  535. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_token_tracking.py +0 -0
  536. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_tool_registry.py +0 -0
  537. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_ui_jsx_syntax.py +0 -0
  538. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_upgrade_and_version.py +0 -0
  539. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_validate.py +0 -0
  540. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_vault_write_guard.py +0 -0
  541. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_version_sync.py +0 -0
  542. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_watcher_pruning.py +0 -0
  543. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_web_security.py +0 -0
  544. {code_context_control-2.141.0 → code_context_control-2.142.0}/tests/test_windows_reliability.py +0 -0
  545. {code_context_control-2.141.0 → code_context_control-2.142.0}/tui/__init__.py +0 -0
  546. {code_context_control-2.141.0 → code_context_control-2.142.0}/tui/backend.py +0 -0
  547. {code_context_control-2.141.0 → code_context_control-2.142.0}/tui/main.py +0 -0
  548. {code_context_control-2.141.0 → code_context_control-2.142.0}/tui/screens/__init__.py +0 -0
  549. {code_context_control-2.141.0 → code_context_control-2.142.0}/tui/screens/benchmark_view.py +0 -0
  550. {code_context_control-2.141.0 → code_context_control-2.142.0}/tui/screens/claudemd_view.py +0 -0
  551. {code_context_control-2.141.0 → code_context_control-2.142.0}/tui/screens/compress_view.py +0 -0
  552. {code_context_control-2.141.0 → code_context_control-2.142.0}/tui/screens/index_view.py +0 -0
  553. {code_context_control-2.141.0 → code_context_control-2.142.0}/tui/screens/init_view.py +0 -0
  554. {code_context_control-2.141.0 → code_context_control-2.142.0}/tui/screens/mcp_view.py +0 -0
  555. {code_context_control-2.141.0 → code_context_control-2.142.0}/tui/screens/optimize_view.py +0 -0
  556. {code_context_control-2.141.0 → code_context_control-2.142.0}/tui/screens/pipe_view.py +0 -0
  557. {code_context_control-2.141.0 → code_context_control-2.142.0}/tui/screens/projects_view.py +0 -0
  558. {code_context_control-2.141.0 → code_context_control-2.142.0}/tui/screens/search_view.py +0 -0
  559. {code_context_control-2.141.0 → code_context_control-2.142.0}/tui/screens/session_view.py +0 -0
  560. {code_context_control-2.141.0 → code_context_control-2.142.0}/tui/screens/stats.py +0 -0
  561. {code_context_control-2.141.0 → code_context_control-2.142.0}/tui/screens/ui_view.py +0 -0
  562. {code_context_control-2.141.0 → code_context_control-2.142.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.141.0
3
+ Version: 2.142.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
@@ -91,7 +91,7 @@ console = Console() if HAS_RICH else None
91
91
  # Config
92
92
  CONFIG_DIR = ".c3"
93
93
  CONFIG_FILE = ".c3/config.json"
94
- __version__ = "2.141.0"
94
+ __version__ = "2.142.0"
95
95
 
96
96
  # The PreToolUse matcher for native subagent calls (installer and hub migration).
97
97
  AGENT_MATCHER = "Agent|Task"
@@ -3658,8 +3658,10 @@ def api_hub_access():
3658
3658
  """Effective Access Guard rules + override policy for one project.
3659
3659
 
3660
3660
  Read-only companion to the approvals list: the per-project mode matrix
3661
- the tab renders under the pending cards. Rule MUTATION stays on the
3662
- per-project server and the CLI — this route never writes.
3661
+ the tab renders under the pending cards. This route never writes; rule
3662
+ mutation from the Hub is ``/api/hub/access/rule`` (add) and
3663
+ ``/api/hub/access/rule/remove`` (v2.142.0), besides the per-project
3664
+ server and the CLI.
3663
3665
  """
3664
3666
  from services import access_guard
3665
3667
  from services import override_policy as opol
@@ -3679,6 +3681,180 @@ def api_hub_access():
3679
3681
  "policy": policy})
3680
3682
 
3681
3683
 
3684
+ # ── Access Guard by file type, across projects (v2.142.0) ─────────────────
3685
+ # The desktop surface for path rules. The phone's /api/mobile/access/rule
3686
+ # cannot carry a bulk edit — 12 security calls a minute and no global scope,
3687
+ # both on purpose for a device that leaves the building — and the per-project
3688
+ # server only runs while its project's UI is open. So the Hub, loopback and
3689
+ # human-only, gains the same two verbs with the same asymmetry: adding a rule
3690
+ # tightens and is one call; removing a deny rule, or ANY global-scope rule,
3691
+ # needs the glob retyped. Every write is audited on the target (a global
3692
+ # write in ~/.c3, since it has no single target project).
3693
+
3694
+ def _hub_access_audit(action: str, glob: str, kind: str, scope: str,
3695
+ project) -> None:
3696
+ """Globs only — never file content. Failure-safe. Mirrors the phone's
3697
+ ``_access_audit`` with ``via='hub'``."""
3698
+ detail = {"kind": "access", "action": action, "glob": glob,
3699
+ "rule_kind": kind, "scope": scope, "via": "hub"}
3700
+ if project is not None:
3701
+ try:
3702
+ from services.activity_log import ActivityLog as _AL
3703
+ _AL(str(project)).log("access_action", dict(detail))
3704
+ except Exception:
3705
+ pass
3706
+ try:
3707
+ from services.edit_ledger import EditLedger
3708
+ EditLedger(str(project)).log_edit(
3709
+ file=f"access://{glob}", change_type=f"access_{action}",
3710
+ summary=f"{action} {kind} rule {glob} ({scope}) via the Hub",
3711
+ tags=["access", action], detail=dict(detail))
3712
+ except Exception:
3713
+ pass
3714
+ if scope == "global":
3715
+ try:
3716
+ from services import credential_store as cred_store
3717
+ from services.activity_log import ActivityLog as _AL
3718
+ home = cred_store.global_base()
3719
+ if home is not None:
3720
+ _AL(str(home)).log("access_action", dict(detail))
3721
+ except Exception:
3722
+ pass
3723
+
3724
+
3725
+ def _hub_access_target(data: dict):
3726
+ """``(scope, project_path_or_None, error_response_or_None)``."""
3727
+ scope = str(data.get("scope") or "project").strip().lower()
3728
+ if scope not in ("project", "global"):
3729
+ return scope, None, (jsonify(
3730
+ {"error": "scope must be 'project' or 'global'"}), 400)
3731
+ if scope == "global":
3732
+ return scope, None, None
3733
+ raw = str(data.get("path") or "").strip()
3734
+ if not raw:
3735
+ return scope, None, (jsonify(
3736
+ {"error": "path is required for project scope"}), 400)
3737
+ try:
3738
+ resolved = _resolve_project_path(raw)
3739
+ except ValueError as e:
3740
+ return scope, None, (jsonify({"error": str(e)}), 404)
3741
+ # set_rule would create .c3/config.json in any directory it is handed;
3742
+ # a rule in a folder C3 does not manage protects nothing and says it does.
3743
+ if not (Path(resolved) / ".c3").is_dir():
3744
+ return scope, None, (jsonify(
3745
+ {"error": "not initialized for C3", "needs_init": True}), 409)
3746
+ return scope, str(resolved), None
3747
+
3748
+
3749
+ @app.route("/api/hub/access/overview", methods=["GET"])
3750
+ def api_hub_access_overview():
3751
+ """Every registered project's own path rules, plus global and builtin.
3752
+
3753
+ Per-row isolation like the enforcement and policy overviews: a project we
3754
+ could not read reports ``error`` rather than an empty rule list — "no
3755
+ rules" is a claim about a repo, and we would be making it blind. A corrupt
3756
+ scope is reported as corrupt: it evaluates deny-all until repaired by
3757
+ hand, which is the opposite of what an empty list would suggest.
3758
+ Builtin rules are read once, from the global realm; a project-scope
3759
+ builtin mode (set with the CLI) is not reflected per row.
3760
+ """
3761
+ empty = {"deny": [], "read_only": [], "confirm": [], "mask": 0,
3762
+ "corrupt": False}
3763
+ rows = []
3764
+ for p in _pm().list_projects():
3765
+ ppath = str(p.get("path") or "")
3766
+ row = {"name": p.get("name") or Path(ppath).name, "path": ppath,
3767
+ "initialized": True, "error": None, "rules": dict(empty)}
3768
+ try:
3769
+ if not (Path(ppath) / ".c3").is_dir():
3770
+ row["initialized"] = False
3771
+ else:
3772
+ row["rules"] = access_guard.scope_rules("project", ppath)
3773
+ except Exception as e:
3774
+ row["error"] = str(e)
3775
+ rows.append(row)
3776
+
3777
+ try:
3778
+ global_rules = {**access_guard.scope_rules("global"), "error": None}
3779
+ except Exception as e:
3780
+ global_rules = {**empty, "error": str(e)}
3781
+ try:
3782
+ home = access_guard._global_base()
3783
+ b = access_guard.list_rules(str(home) if home else ".")["builtin"]
3784
+ builtin = {"deny": list(b.get("deny") or []),
3785
+ "read_only": list(b.get("read_only") or []),
3786
+ "confirm": list(b.get("confirm") or []), "error": None}
3787
+ except Exception as e:
3788
+ builtin = {"deny": [], "read_only": [], "confirm": [], "error": str(e)}
3789
+
3790
+ return jsonify({
3791
+ "projects": rows,
3792
+ "global": global_rules,
3793
+ "builtin": builtin,
3794
+ # Strictest last. "allow" is the absence of a rule, not a kind.
3795
+ "kinds": ["confirm", "read_only", "deny"],
3796
+ "coverage_note": access_guard.COVERAGE_MATRIX,
3797
+ })
3798
+
3799
+
3800
+ @app.route("/api/hub/access/rule", methods=["POST"])
3801
+ def api_hub_access_rule_add():
3802
+ """Add one deny / read_only / confirm rule. Tightening — no confirmation.
3803
+
3804
+ Body: ``{path?, scope?, glob, kind}``. ``added: false`` when an equivalent
3805
+ glob is already there (a 200, not an error: the caller asked for the
3806
+ state it is in).
3807
+ """
3808
+ data = request.get_json(silent=True) or {}
3809
+ scope, project, err = _hub_access_target(data)
3810
+ if err:
3811
+ return err
3812
+ glob = str(data.get("glob") or "")
3813
+ kind = str(data.get("kind") or "").strip()
3814
+ try:
3815
+ result = access_guard.set_rule(glob, kind, scope, project or ".")
3816
+ except ValueError as exc:
3817
+ return jsonify({"error": str(exc)}), 400
3818
+ if result["added"]:
3819
+ _hub_access_audit("add", result["glob"], kind, scope, project)
3820
+ return jsonify({"rule": result})
3821
+
3822
+
3823
+ @app.route("/api/hub/access/rule/remove", methods=["POST"])
3824
+ def api_hub_access_rule_remove():
3825
+ """Remove one rule. Loosening.
3826
+
3827
+ Body: ``{path?, scope?, glob, kind, confirm?}``. A ``deny`` rule, and any
3828
+ rule in the GLOBAL scope (it governs every project on the machine), needs
3829
+ ``confirm`` equal to the glob — the CLI's "type the glob again". A
3830
+ read_only or confirm rule in one project does not: it downgrades writes
3831
+ to writable-or-ask, not to fully visible. POST rather than DELETE so the
3832
+ body survives every client.
3833
+ """
3834
+ data = request.get_json(silent=True) or {}
3835
+ scope, project, err = _hub_access_target(data)
3836
+ if err:
3837
+ return err
3838
+ glob = str(data.get("glob") or "")
3839
+ kind = str(data.get("kind") or "").strip()
3840
+ canon = access_guard._norm_glob(glob)
3841
+ if kind == "deny" or scope == "global":
3842
+ if access_guard._norm_glob(data.get("confirm")) != canon or not canon:
3843
+ return jsonify({
3844
+ "error": ("removing a deny rule weakens protection"
3845
+ if kind == "deny" else
3846
+ "removing a global rule weakens every project"),
3847
+ "needs_confirmation": True, "confirm_with": canon,
3848
+ }), 400
3849
+ try:
3850
+ result = access_guard.remove_rule(glob, kind, scope, project or ".")
3851
+ except ValueError as exc:
3852
+ return jsonify({"error": str(exc)}), 400
3853
+ if result["removed"]:
3854
+ _hub_access_audit("remove", result["glob"], kind, scope, project)
3855
+ return jsonify(result)
3856
+
3857
+
3682
3858
  # ── Project management: tasks / milestones / notes (v2.45.0) ──────────────
3683
3859
  # Direct TaskStore per request (reload-per-op store — no runtime build needed
3684
3860
  # for mutations); every write audited to the target project's activity log.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-context-control
3
- Version: 2.141.0
3
+ Version: 2.142.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
@@ -409,6 +409,7 @@ tests/test_hook_session_end.py
409
409
  tests/test_hook_smoke.py
410
410
  tests/test_hook_state.py
411
411
  tests/test_hook_utf8_stdio.py
412
+ tests/test_hub_access_routes.py
412
413
  tests/test_hub_credentials_route.py
413
414
  tests/test_hub_credentials_routes_write.py
414
415
  tests/test_hub_enforcement_routes.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "code-context-control"
7
- version = "2.141.0"
7
+ version = "2.142.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"
@@ -1439,6 +1439,28 @@ def list_rules(project_path: str = ".") -> dict:
1439
1439
  return out
1440
1440
 
1441
1441
 
1442
+ def scope_rules(scope: str, project_path: str = ".") -> dict:
1443
+ """One scope's OWN list rules, for a cross-project screen.
1444
+
1445
+ ``{"deny": [...], "read_only": [...], "confirm": [...], "mask": <count>,
1446
+ "corrupt": bool}``. Globs come back in the canonical storage form
1447
+ (:func:`_norm_glob`), which is what :func:`set_rule` writes and what
1448
+ :func:`remove_rule` compares against, so a caller can match a row to the
1449
+ rule it would remove without re-deriving the spelling. A missing file is
1450
+ an empty scope; an unreadable one is ``corrupt`` (it evaluates deny-all
1451
+ until repaired by hand). Unlike :func:`list_rules` this touches no
1452
+ keyring and computes no builtin modes, so it is cheap enough to run over
1453
+ every registered project in one request.
1454
+ """
1455
+ cfg = _scope_config_path(scope, project_path)
1456
+ section, corrupt = _raw_scope_section(cfg)
1457
+ out = {k: [_norm_glob(g) for g in _str_list(section.get(k))]
1458
+ for k in _LIST_KINDS}
1459
+ out[_KIND_MASK] = len(_mask_list(section.get(_KIND_MASK)))
1460
+ out["corrupt"] = corrupt
1461
+ return out
1462
+
1463
+
1442
1464
  def _load_config_for_write(cfg: Path) -> tuple:
1443
1465
  """(config_dict, access_section) for read-modify-write of one scope.
1444
1466
 
@@ -0,0 +1,230 @@
1
+ """Access Guard rules by file type, across projects, from the Hub (2.142.0).
2
+
3
+ WHY THE HUB. The phone's /api/mobile/access/rule cannot carry a bulk edit:
4
+ 12 security calls a minute and no global scope, both deliberate for a device
5
+ that leaves the building. The per-project server only runs while that
6
+ project's UI is open. C3 Desk needs one loopback surface that reads every
7
+ project's rules in one call and writes them one rule at a time.
8
+
9
+ WHAT THESE PIN.
10
+ 1. The overview never reports "no rules" for a project it could not read,
11
+ and flags a corrupt scope (which evaluates deny-all) as corrupt.
12
+ 2. Globs come back in the canonical storage form, so a client can match a
13
+ row to the rule remove_rule() will compare against.
14
+ 3. Adding tightens and needs nothing. Removing a deny rule, or any global
15
+ rule, needs the glob retyped; removing a project read_only/confirm rule
16
+ does not. A refused removal leaves the file untouched.
17
+ 4. Every real write is audited on the target; a no-op is not.
18
+ 5. A folder C3 does not manage gets a 409, not a fresh .c3/config.json.
19
+ """
20
+ from __future__ import annotations
21
+
22
+ import json
23
+ import sys
24
+ import tempfile
25
+ import unittest
26
+ from pathlib import Path
27
+ from unittest import mock
28
+
29
+ REPO_ROOT = Path(__file__).resolve().parent.parent
30
+ sys.path.insert(0, str(REPO_ROOT))
31
+
32
+ import cli.hub_server as hub_server # noqa: E402
33
+ from services import access_guard as ag # noqa: E402
34
+
35
+
36
+ class _StubPM:
37
+ def __init__(self, projects):
38
+ self._projects = projects
39
+
40
+ def list_projects(self):
41
+ return self._projects
42
+
43
+
44
+ def _cfg(path: Path) -> dict:
45
+ return json.loads((path / ".c3" / "config.json").read_text(encoding="utf-8"))
46
+
47
+
48
+ def _write_cfg(path: Path, data: dict) -> None:
49
+ (path / ".c3").mkdir(parents=True, exist_ok=True)
50
+ (path / ".c3" / "config.json").write_text(json.dumps(data), encoding="utf-8")
51
+
52
+
53
+ class _Base(unittest.TestCase):
54
+ def setUp(self):
55
+ self._tmp = tempfile.TemporaryDirectory()
56
+ root = Path(self._tmp.name)
57
+ self.proj = root / "proj"
58
+ _write_cfg(self.proj, {"access": {"deny": ["secrets\\**"],
59
+ "read_only": ["**/*.lock"]}})
60
+ self.other = root / "other"
61
+ _write_cfg(self.other, {})
62
+ self.bare = root / "bare"
63
+ self.bare.mkdir()
64
+ self.home = root / "home"
65
+ (self.home / ".c3").mkdir(parents=True)
66
+ self._gbase = mock.patch.object(ag, "_global_base", return_value=self.home)
67
+ self._gbase.start()
68
+
69
+ hub_server.app.config["TESTING"] = True
70
+ self.client = hub_server.app.test_client()
71
+ self._pm = mock.patch.object(hub_server, "_pm", return_value=_StubPM([
72
+ {"name": "proj", "path": str(self.proj)},
73
+ {"name": "other", "path": str(self.other)},
74
+ {"name": "bare", "path": str(self.bare)},
75
+ ]))
76
+ self._pm.start()
77
+ self._resolve = mock.patch.object(
78
+ hub_server, "_resolve_project_path", side_effect=lambda p: Path(p))
79
+ self._resolve.start()
80
+
81
+ def tearDown(self):
82
+ self._resolve.stop()
83
+ self._pm.stop()
84
+ self._gbase.stop()
85
+ self._tmp.cleanup()
86
+
87
+ def post(self, url, body):
88
+ resp = self.client.post(url, json=body)
89
+ return resp.status_code, resp.get_json()
90
+
91
+
92
+ class TestOverview(_Base):
93
+ def _overview(self):
94
+ resp = self.client.get("/api/hub/access/overview")
95
+ self.assertEqual(resp.status_code, 200)
96
+ return resp.get_json()
97
+
98
+ def _row(self, data, name):
99
+ return next(r for r in data["projects"] if r["name"] == name)
100
+
101
+ def test_rows_carry_each_projects_own_rules_in_storage_form(self):
102
+ row = self._row(self._overview(), "proj")
103
+ self.assertEqual(row["rules"]["deny"], ["secrets/**"])
104
+ self.assertEqual(row["rules"]["read_only"], ["**/*.lock"])
105
+ self.assertEqual(row["rules"]["confirm"], [])
106
+ self.assertFalse(row["rules"]["corrupt"])
107
+
108
+ def test_uninitialized_and_unreadable_rows_are_not_reported_as_no_rules(self):
109
+ real = ag.scope_rules
110
+
111
+ def flaky(scope, path="."):
112
+ if scope == "project" and Path(path) == self.other:
113
+ raise RuntimeError("boom")
114
+ return real(scope, path)
115
+
116
+ with mock.patch.object(ag, "scope_rules", side_effect=flaky):
117
+ data = self._overview()
118
+ self.assertFalse(self._row(data, "bare")["initialized"])
119
+ self.assertEqual(self._row(data, "other")["error"], "boom")
120
+ self.assertEqual(self._row(data, "proj")["rules"]["deny"], ["secrets/**"])
121
+
122
+ def test_a_corrupt_scope_is_flagged(self):
123
+ _write_cfg(self.other, {"access": {"allow": ["**"]}})
124
+ self.assertTrue(self._row(self._overview(), "other")["rules"]["corrupt"])
125
+
126
+ def test_global_and_builtin(self):
127
+ _write_cfg(self.home, {"access": {"confirm": ["**/*.sql"]}})
128
+ data = self._overview()
129
+ self.assertEqual(data["global"]["confirm"], ["**/*.sql"])
130
+ self.assertIn("**/.env*", data["builtin"]["deny"])
131
+ self.assertEqual(data["kinds"], ["confirm", "read_only", "deny"])
132
+ self.assertIn("NOT enforced", data["coverage_note"])
133
+
134
+
135
+ class TestAdd(_Base):
136
+ def test_add_writes_and_audits_on_the_target(self):
137
+ with mock.patch("services.activity_log.ActivityLog") as log:
138
+ status, body = self.post("/api/hub/access/rule", {
139
+ "path": str(self.other), "glob": "**\\*.pem", "kind": "deny"})
140
+ self.assertEqual(status, 200, body)
141
+ self.assertEqual(body["rule"], {"glob": "**/*.pem", "kind": "deny",
142
+ "scope": "project", "added": True})
143
+ self.assertEqual(_cfg(self.other)["access"]["deny"], ["**/*.pem"])
144
+ event, payload = log.return_value.log.call_args[0]
145
+ self.assertEqual((event, payload["action"], payload["via"]),
146
+ ("access_action", "add", "hub"))
147
+
148
+ def test_duplicate_is_a_noop_and_not_audited(self):
149
+ with mock.patch("services.activity_log.ActivityLog") as log:
150
+ status, body = self.post("/api/hub/access/rule", {
151
+ "path": str(self.proj), "glob": "SECRETS/**", "kind": "deny"})
152
+ self.assertEqual(status, 200)
153
+ self.assertFalse(body["rule"]["added"])
154
+ self.assertFalse(log.called)
155
+
156
+ def test_global_scope_needs_no_path(self):
157
+ status, body = self.post("/api/hub/access/rule", {
158
+ "scope": "global", "glob": "**/*.key", "kind": "read_only"})
159
+ self.assertEqual(status, 200, body)
160
+ self.assertEqual(_cfg(self.home)["access"]["read_only"], ["**/*.key"])
161
+
162
+ def test_refusals(self):
163
+ self.assertEqual(self.post("/api/hub/access/rule", {
164
+ "path": str(self.proj), "glob": "x/**", "kind": "allow"})[0], 400)
165
+ self.assertEqual(self.post("/api/hub/access/rule", {
166
+ "glob": "x/**", "kind": "deny"})[0], 400)
167
+ self.assertEqual(self.post("/api/hub/access/rule", {
168
+ "scope": "machine", "glob": "x/**", "kind": "deny"})[0], 400)
169
+ status, body = self.post("/api/hub/access/rule", {
170
+ "path": str(self.bare), "glob": "x/**", "kind": "deny"})
171
+ self.assertEqual(status, 409)
172
+ self.assertFalse((self.bare / ".c3").exists(), "it created .c3 anyway")
173
+
174
+
175
+ class TestRemove(_Base):
176
+ URL = "/api/hub/access/rule/remove"
177
+
178
+ def test_project_read_only_removal_needs_no_confirmation(self):
179
+ status, body = self.post(self.URL, {
180
+ "path": str(self.proj), "glob": "**/*.lock", "kind": "read_only"})
181
+ self.assertEqual(status, 200, body)
182
+ self.assertTrue(body["removed"])
183
+ self.assertEqual(_cfg(self.proj)["access"]["read_only"], [])
184
+
185
+ def test_deny_removal_needs_the_glob_retyped(self):
186
+ status, body = self.post(self.URL, {
187
+ "path": str(self.proj), "glob": "secrets/**", "kind": "deny"})
188
+ self.assertEqual(status, 400)
189
+ self.assertEqual((body["needs_confirmation"], body["confirm_with"]),
190
+ (True, "secrets/**"))
191
+ self.assertEqual(_cfg(self.proj)["access"]["deny"], ["secrets\\**"],
192
+ "it wrote despite refusing")
193
+ with mock.patch("services.activity_log.ActivityLog") as log:
194
+ status, body = self.post(self.URL, {
195
+ "path": str(self.proj), "glob": "secrets/**", "kind": "deny",
196
+ "confirm": "secrets\\**"})
197
+ self.assertEqual(status, 200, body)
198
+ self.assertTrue(body["removed"])
199
+ self.assertEqual(_cfg(self.proj)["access"]["deny"], [])
200
+ self.assertEqual(log.return_value.log.call_args[0][1]["action"], "remove")
201
+
202
+ def test_any_global_removal_needs_the_glob_retyped(self):
203
+ _write_cfg(self.home, {"access": {"confirm": ["**/*.sql"]}})
204
+ body = {"scope": "global", "glob": "**/*.sql", "kind": "confirm"}
205
+ self.assertEqual(self.post(self.URL, body)[0], 400)
206
+ status, res = self.post(self.URL, {**body, "confirm": "**/*.sql"})
207
+ self.assertEqual(status, 200, res)
208
+ self.assertEqual(_cfg(self.home)["access"]["confirm"], [])
209
+
210
+ def test_a_corrupt_scope_is_refused_not_rewritten(self):
211
+ _write_cfg(self.other, {"access": {"allow": ["**"], "read_only": ["a/**"]}})
212
+ status, _ = self.post(self.URL, {
213
+ "path": str(self.other), "glob": "a/**", "kind": "read_only"})
214
+ self.assertEqual(status, 400)
215
+ self.assertEqual(_cfg(self.other)["access"]["allow"], ["**"])
216
+
217
+
218
+ class TestRoutes(unittest.TestCase):
219
+ def test_each_route_resolves_to_its_own_endpoint(self):
220
+ adapter = hub_server.app.url_map.bind("localhost")
221
+ for url, method, endpoint in (
222
+ ("/api/hub/access/overview", "GET", "api_hub_access_overview"),
223
+ ("/api/hub/access/rule", "POST", "api_hub_access_rule_add"),
224
+ ("/api/hub/access/rule/remove", "POST",
225
+ "api_hub_access_rule_remove")):
226
+ self.assertEqual(adapter.match(url, method=method)[0], endpoint)
227
+
228
+
229
+ if __name__ == "__main__":
230
+ unittest.main()