code-context-control 2.82.0__tar.gz → 2.86.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 (436) hide show
  1. {code_context_control-2.82.0/code_context_control.egg-info → code_context_control-2.86.0}/PKG-INFO +3 -2
  2. {code_context_control-2.82.0 → code_context_control-2.86.0}/README.md +2 -1
  3. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/c3.py +33 -2
  4. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/commands/parser.py +27 -0
  5. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hook_access_guard.py +25 -3
  6. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_server.py +14 -0
  7. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/mcp_server.py +23 -4
  8. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/server.py +14 -0
  9. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/ci.py +126 -3
  10. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/shell.py +56 -0
  11. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/tasks.py +22 -1
  12. {code_context_control-2.82.0 → code_context_control-2.86.0/code_context_control.egg-info}/PKG-INFO +3 -2
  13. {code_context_control-2.82.0 → code_context_control-2.86.0}/code_context_control.egg-info/SOURCES.txt +7 -0
  14. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/mobile_api.py +14 -0
  15. {code_context_control-2.82.0 → code_context_control-2.86.0}/pyproject.toml +1 -1
  16. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/access_guard.py +27 -0
  17. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/ci_act.py +36 -0
  18. code_context_control-2.86.0/services/ci_cache.py +345 -0
  19. code_context_control-2.86.0/services/ci_github.py +161 -0
  20. code_context_control-2.86.0/services/ci_impact.py +269 -0
  21. code_context_control-2.86.0/services/ci_intel.py +188 -0
  22. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/ci_runner.py +138 -5
  23. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/ci_workflow.py +1 -1
  24. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/scanner.py +35 -0
  25. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/task_store.py +63 -0
  26. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_access_guard.py +72 -0
  27. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_c3_shell.py +101 -0
  28. code_context_control-2.86.0/tests/test_ci_cache.py +205 -0
  29. code_context_control-2.86.0/tests/test_ci_impact.py +274 -0
  30. code_context_control-2.86.0/tests/test_ci_intel.py +179 -0
  31. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_hook_access_guard.py +30 -0
  32. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_init_scan.py +76 -0
  33. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_pm_api.py +25 -0
  34. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_task_store.py +45 -0
  35. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_task_tool.py +13 -0
  36. {code_context_control-2.82.0 → code_context_control-2.86.0}/LICENSE +0 -0
  37. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/__init__.py +0 -0
  38. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/_hook_utils.py +0 -0
  39. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/commands/__init__.py +0 -0
  40. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/commands/common.py +0 -0
  41. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/docs.html +0 -0
  42. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/edits.html +0 -0
  43. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/guide/access.html +0 -0
  44. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/guide/bitbucket.html +0 -0
  45. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/guide/credentials.html +0 -0
  46. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/guide/getting-started.html +0 -0
  47. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/guide/index.html +0 -0
  48. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/guide/masking.html +0 -0
  49. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/guide/oracle.html +0 -0
  50. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/guide/shared.css +0 -0
  51. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/guide/tools.html +0 -0
  52. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/guide/workflow.html +0 -0
  53. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hook_artifact.py +0 -0
  54. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hook_auto_snapshot.py +0 -0
  55. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hook_c3_signal.py +0 -0
  56. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hook_c3read.py +0 -0
  57. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hook_dispatch.py +0 -0
  58. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hook_edit_ledger.py +0 -0
  59. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hook_edit_unlock.py +0 -0
  60. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hook_filter.py +0 -0
  61. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hook_ghost_files.py +0 -0
  62. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hook_pretool_enforce.py +0 -0
  63. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hook_prompt_recall.py +0 -0
  64. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hook_read.py +0 -0
  65. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hook_session_stats.py +0 -0
  66. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hook_terse_advisor.py +0 -0
  67. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/app.js +0 -0
  68. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/add_project.js +0 -0
  69. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/config_editor.js +0 -0
  70. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
  71. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/drill_health.js +0 -0
  72. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/drill_panel.js +0 -0
  73. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
  74. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/drill_tasks.js +0 -0
  75. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/drill_views.js +0 -0
  76. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/global_search.js +0 -0
  77. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/hub_ci.js +0 -0
  78. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/hub_credentials.js +0 -0
  79. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
  80. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/hub_locks.js +0 -0
  81. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/mcp_manager.js +0 -0
  82. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/modals.js +0 -0
  83. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/project_card.js +0 -0
  84. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/project_tree.js +0 -0
  85. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/session_drawer.js +0 -0
  86. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/settings_modal.js +0 -0
  87. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/sidebar.js +0 -0
  88. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/summary_bar.js +0 -0
  89. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/task_board.js +0 -0
  90. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/toasts.js +0 -0
  91. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/components/topbar.js +0 -0
  92. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui/state.js +0 -0
  93. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/hub_ui.html +0 -0
  94. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/mcp_proxy.py +0 -0
  95. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/progress.py +0 -0
  96. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/__init__.py +0 -0
  97. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/_grants.py +0 -0
  98. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/_helpers.py +0 -0
  99. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/agent.py +0 -0
  100. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/artifacts.py +0 -0
  101. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/bitbucket.py +0 -0
  102. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/compress.py +0 -0
  103. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/credentials.py +0 -0
  104. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/delegate.py +0 -0
  105. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/edit.py +0 -0
  106. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/edit_verify.py +0 -0
  107. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/edits.py +0 -0
  108. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/federate.py +0 -0
  109. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/filter.py +0 -0
  110. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/impact.py +0 -0
  111. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/jira.py +0 -0
  112. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/locks.py +0 -0
  113. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/memory.py +0 -0
  114. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/override.py +0 -0
  115. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/project.py +0 -0
  116. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/read.py +0 -0
  117. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/search.py +0 -0
  118. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/session.py +0 -0
  119. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/status.py +0 -0
  120. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/tools/validate.py +0 -0
  121. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/api.js +0 -0
  122. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/app.js +0 -0
  123. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/components/access.js +0 -0
  124. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/components/bitbucket.js +0 -0
  125. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/components/chat.js +0 -0
  126. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/components/credentials.js +0 -0
  127. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/components/dashboard.js +0 -0
  128. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/components/edits.js +0 -0
  129. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/components/enforcement.js +0 -0
  130. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/components/instructions.js +0 -0
  131. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/components/jira.js +0 -0
  132. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/components/memory.js +0 -0
  133. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/components/sessions.js +0 -0
  134. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/components/settings.js +0 -0
  135. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/components/sidebar.js +0 -0
  136. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/components/tasks.js +0 -0
  137. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/icons.js +0 -0
  138. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/pm_shared.js +0 -0
  139. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/shared.js +0 -0
  140. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui/theme.js +0 -0
  141. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui.html +0 -0
  142. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui_legacy.html +0 -0
  143. {code_context_control-2.82.0 → code_context_control-2.86.0}/cli/ui_nano.html +0 -0
  144. {code_context_control-2.82.0 → code_context_control-2.86.0}/code_context_control.egg-info/dependency_links.txt +0 -0
  145. {code_context_control-2.82.0 → code_context_control-2.86.0}/code_context_control.egg-info/entry_points.txt +0 -0
  146. {code_context_control-2.82.0 → code_context_control-2.86.0}/code_context_control.egg-info/requires.txt +0 -0
  147. {code_context_control-2.82.0 → code_context_control-2.86.0}/code_context_control.egg-info/top_level.txt +0 -0
  148. {code_context_control-2.82.0 → code_context_control-2.86.0}/core/__init__.py +0 -0
  149. {code_context_control-2.82.0 → code_context_control-2.86.0}/core/config.py +0 -0
  150. {code_context_control-2.82.0 → code_context_control-2.86.0}/core/ide.py +0 -0
  151. {code_context_control-2.82.0 → code_context_control-2.86.0}/core/mcp_toml.py +0 -0
  152. {code_context_control-2.82.0 → code_context_control-2.86.0}/core/web_security.py +0 -0
  153. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/__init__.py +0 -0
  154. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/config.py +0 -0
  155. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/mcp_oracle.py +0 -0
  156. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/oracle_server.py +0 -0
  157. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/oracle_ui.html +0 -0
  158. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/__init__.py +0 -0
  159. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/activity_reporter.py +0 -0
  160. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/api_auth.py +0 -0
  161. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/c3_bridge.py +0 -0
  162. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/chat_engine.py +0 -0
  163. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/chat_poll.py +0 -0
  164. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/chat_store.py +0 -0
  165. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/cross_memory.py +0 -0
  166. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/discovery_audit.py +0 -0
  167. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/federated_graph.py +0 -0
  168. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/health_checker.py +0 -0
  169. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/insight_engine.py +0 -0
  170. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/local_session.py +0 -0
  171. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/memory_reader.py +0 -0
  172. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/memory_writer.py +0 -0
  173. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/project_scanner.py +0 -0
  174. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/review_agent.py +0 -0
  175. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/tool_executor.py +0 -0
  176. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/services/tool_registry.py +0 -0
  177. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/activity.js +0 -0
  178. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/agents.js +0 -0
  179. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/app.js +0 -0
  180. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/busy.js +0 -0
  181. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/chat/conversations.js +0 -0
  182. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/chat/input.js +0 -0
  183. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/chat/markdown.js +0 -0
  184. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/chat/send.js +0 -0
  185. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/chat/stream_renderer.js +0 -0
  186. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/chat/toolbar.js +0 -0
  187. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/core.js +0 -0
  188. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/crossgraph.js +0 -0
  189. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/header.js +0 -0
  190. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/insights.js +0 -0
  191. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/projects.js +0 -0
  192. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/qrcode.js +0 -0
  193. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/settings.js +0 -0
  194. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/suggestions.js +0 -0
  195. {code_context_control-2.82.0 → code_context_control-2.86.0}/oracle/ui/theme_tabs.js +0 -0
  196. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/__init__.py +0 -0
  197. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/access_telemetry.py +0 -0
  198. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/activity_log.py +0 -0
  199. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/agent_base.py +0 -0
  200. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/agent_locks.py +0 -0
  201. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/agents.py +0 -0
  202. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/artifact_defs.py +0 -0
  203. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/artifact_store.py +0 -0
  204. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/auto_memory.py +0 -0
  205. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/bench/__init__.py +0 -0
  206. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/bench/external/__init__.py +0 -0
  207. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/bench/external/aider_polyglot.py +0 -0
  208. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/bench/external/swe_bench.py +0 -0
  209. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/benchmark_dashboard.py +0 -0
  210. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/bitbucket_client.py +0 -0
  211. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/bitbucket_credentials.py +0 -0
  212. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/ci_expr.py +0 -0
  213. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/ci_failures.py +0 -0
  214. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/circuit_breaker.py +0 -0
  215. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/claude_md.py +0 -0
  216. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/compressor.py +0 -0
  217. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/context_snapshot.py +0 -0
  218. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/conversation_store.py +0 -0
  219. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/credential_store.py +0 -0
  220. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/doc_index.py +0 -0
  221. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/e2e_benchmark.py +0 -0
  222. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/e2e_evaluator.py +0 -0
  223. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/e2e_tasks.py +0 -0
  224. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/edit_ledger.py +0 -0
  225. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/embedding_index.py +0 -0
  226. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/enforcement_policy.py +0 -0
  227. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/error_reporting.py +0 -0
  228. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/file_memory.py +0 -0
  229. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/git_context.py +0 -0
  230. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/hub_service.py +0 -0
  231. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/indexer.py +0 -0
  232. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/jira_client.py +0 -0
  233. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/jira_cloud.py +0 -0
  234. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/jira_credentials.py +0 -0
  235. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/jira_data_center.py +0 -0
  236. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/jira_links.py +0 -0
  237. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/mask_activation.py +0 -0
  238. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/mask_mirror.py +0 -0
  239. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/mask_presets.py +0 -0
  240. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/memory.py +0 -0
  241. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/memory_consolidator.py +0 -0
  242. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/memory_distiller.py +0 -0
  243. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/memory_graph.py +0 -0
  244. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/memory_grounder.py +0 -0
  245. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/memory_queue.py +0 -0
  246. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/memory_scorer.py +0 -0
  247. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/metrics.py +0 -0
  248. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/notifications.py +0 -0
  249. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/ollama_bridge.py +0 -0
  250. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/ollama_client.py +0 -0
  251. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/ollama_credentials.py +0 -0
  252. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/output_filter.py +0 -0
  253. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/override_grants.py +0 -0
  254. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/override_policy.py +0 -0
  255. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/override_requests.py +0 -0
  256. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/override_wake.py +0 -0
  257. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/parser.py +0 -0
  258. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/project_manager.py +0 -0
  259. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/project_runtime.py +0 -0
  260. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/protocol.py +0 -0
  261. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/proxy_state.py +0 -0
  262. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/repo_map.py +0 -0
  263. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/retention.py +0 -0
  264. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/retrieval_broker.py +0 -0
  265. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/router.py +0 -0
  266. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/runtime.py +0 -0
  267. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/session_benchmark.py +0 -0
  268. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/session_manager.py +0 -0
  269. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/session_preloader.py +0 -0
  270. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/subprojects.py +0 -0
  271. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/telemetry.py +0 -0
  272. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/text_index.py +0 -0
  273. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/time_tracker.py +0 -0
  274. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/tool_classifier.py +0 -0
  275. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/transcript_index.py +0 -0
  276. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/validation_cache.py +0 -0
  277. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/vector_store.py +0 -0
  278. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/watcher.py +0 -0
  279. {code_context_control-2.82.0 → code_context_control-2.86.0}/services/win_subprocess.py +0 -0
  280. {code_context_control-2.82.0 → code_context_control-2.86.0}/setup.cfg +0 -0
  281. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_access_builtin_optout.py +0 -0
  282. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_access_guard_meta.py +0 -0
  283. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_access_guard_shell_project.py +0 -0
  284. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_access_guard_surfaces.py +0 -0
  285. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_access_guard_wiring.py +0 -0
  286. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_activity_reporter.py +0 -0
  287. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_agent_locks.py +0 -0
  288. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_aider_polyglot.py +0 -0
  289. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_antigravity_transition.py +0 -0
  290. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_artifact_store.py +0 -0
  291. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_artifact_tool.py +0 -0
  292. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_bitbucket_cli_smoke.py +0 -0
  293. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_bitbucket_client.py +0 -0
  294. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_bitbucket_config_fallback.py +0 -0
  295. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_bitbucket_credentials.py +0 -0
  296. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_bitbucket_tool.py +0 -0
  297. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
  298. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_chat_poll.py +0 -0
  299. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_ci_act.py +0 -0
  300. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_ci_expr.py +0 -0
  301. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_ci_runner.py +0 -0
  302. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_ci_workflow.py +0 -0
  303. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_circuit_breaker.py +0 -0
  304. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_claude_md_merge.py +0 -0
  305. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_cli_smoke.py +0 -0
  306. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_compressor_large_file.py +0 -0
  307. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_credential_store.py +0 -0
  308. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_credentials_routes.py +0 -0
  309. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_credentials_tool.py +0 -0
  310. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_creds_cli_smoke.py +0 -0
  311. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_delegate_cascade.py +0 -0
  312. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_delegate_version_probe.py +0 -0
  313. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_e2e_benchmark.py +0 -0
  314. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_edit_ledger_deadline.py +0 -0
  315. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_edit_ledger_hook.py +0 -0
  316. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_edit_locking.py +0 -0
  317. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_edit_normalization.py +0 -0
  318. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_edit_verify.py +0 -0
  319. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_embedding_index_deadlock.py +0 -0
  320. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_enforcement_flip.py +0 -0
  321. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_enforcement_policy.py +0 -0
  322. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_enforcement_routes.py +0 -0
  323. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_federated_graph.py +0 -0
  324. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_filter_backoff.py +0 -0
  325. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_ghost_files.py +0 -0
  326. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_ghost_generation.py +0 -0
  327. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_git_branch_awareness.py +0 -0
  328. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_hook_codex_compat.py +0 -0
  329. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_hook_dispatch.py +0 -0
  330. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_hook_pretool_enforce.py +0 -0
  331. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_hook_prompt_recall.py +0 -0
  332. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_hook_smoke.py +0 -0
  333. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_hook_state.py +0 -0
  334. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_hook_utf8_stdio.py +0 -0
  335. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_hub_credentials_route.py +0 -0
  336. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_hub_credentials_routes_write.py +0 -0
  337. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_hub_enforcement_routes.py +0 -0
  338. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_hub_inspect_api.py +0 -0
  339. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_hub_locks_routes.py +0 -0
  340. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_hub_server_smoke.py +0 -0
  341. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_hub_subproject_links.py +0 -0
  342. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_ide_workflow_adaptation.py +0 -0
  343. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_install_mcp_entrypoint.py +0 -0
  344. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_jira_cli_smoke.py +0 -0
  345. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_jira_client.py +0 -0
  346. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_jira_config_fallback.py +0 -0
  347. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_jira_credentials.py +0 -0
  348. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_jira_links.py +0 -0
  349. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_jira_routes.py +0 -0
  350. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_jira_tool.py +0 -0
  351. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_lazy_store_init.py +0 -0
  352. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_mask_guard.py +0 -0
  353. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_mask_routes.py +0 -0
  354. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_mask_surfaces.py +0 -0
  355. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_mcp_host_guard.py +0 -0
  356. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_mcp_memory_timeout.py +0 -0
  357. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_mcp_server_smoke.py +0 -0
  358. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_mcp_toml.py +0 -0
  359. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_memory_distiller.py +0 -0
  360. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_memory_graph_api.py +0 -0
  361. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_memory_queue.py +0 -0
  362. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_memory_system.py +0 -0
  363. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_mobile_api.py +0 -0
  364. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_mobile_extras.py +0 -0
  365. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_mobile_override_routes.py +0 -0
  366. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_mobile_security_api.py +0 -0
  367. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_no_stale_model_pins.py +0 -0
  368. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_notification_dedup.py +0 -0
  369. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_notification_discipline.py +0 -0
  370. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_ollama_credentials.py +0 -0
  371. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_oracle_api_auth.py +0 -0
  372. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_oracle_apikey_api.py +0 -0
  373. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_oracle_c3_bridge.py +0 -0
  374. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_oracle_chat_engine.py +0 -0
  375. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_oracle_chat_store.py +0 -0
  376. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_oracle_discovery_api.py +0 -0
  377. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_oracle_discovery_audit.py +0 -0
  378. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_oracle_local_auth.py +0 -0
  379. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_oracle_ollama_bridge.py +0 -0
  380. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_oracle_scanner_cache.py +0 -0
  381. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_oracle_security_fixes.py +0 -0
  382. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_oracle_session_bootstrap.py +0 -0
  383. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_oracle_subproject_awareness.py +0 -0
  384. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_oracle_ui_bundle.py +0 -0
  385. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_output_filter.py +0 -0
  386. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_override_grants.py +0 -0
  387. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_override_grants_mcp.py +0 -0
  388. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_override_requests.py +0 -0
  389. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_override_wake.py +0 -0
  390. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_permissions.py +0 -0
  391. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_project_manager.py +0 -0
  392. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_project_manager_merge.py +0 -0
  393. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_project_tool.py +0 -0
  394. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_read_coercion.py +0 -0
  395. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_read_edit_parity.py +0 -0
  396. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_related_facts.py +0 -0
  397. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_repo_map.py +0 -0
  398. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_response_boilerplate.py +0 -0
  399. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_retention.py +0 -0
  400. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_review_digest.py +0 -0
  401. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_service_durability.py +0 -0
  402. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_session_benchmark.py +0 -0
  403. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_session_budget.py +0 -0
  404. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_shell_creds.py +0 -0
  405. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_shell_robustness.py +0 -0
  406. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_subproject_exclusion.py +0 -0
  407. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_subproject_federation.py +0 -0
  408. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_subprojects.py +0 -0
  409. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_swe_bench.py +0 -0
  410. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_time_tracker.py +0 -0
  411. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_token_telemetry.py +0 -0
  412. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_tool_registry.py +0 -0
  413. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_upgrade_and_version.py +0 -0
  414. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_validate.py +0 -0
  415. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_vault_write_guard.py +0 -0
  416. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_version_sync.py +0 -0
  417. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_web_security.py +0 -0
  418. {code_context_control-2.82.0 → code_context_control-2.86.0}/tests/test_windows_reliability.py +0 -0
  419. {code_context_control-2.82.0 → code_context_control-2.86.0}/tui/__init__.py +0 -0
  420. {code_context_control-2.82.0 → code_context_control-2.86.0}/tui/backend.py +0 -0
  421. {code_context_control-2.82.0 → code_context_control-2.86.0}/tui/main.py +0 -0
  422. {code_context_control-2.82.0 → code_context_control-2.86.0}/tui/screens/__init__.py +0 -0
  423. {code_context_control-2.82.0 → code_context_control-2.86.0}/tui/screens/benchmark_view.py +0 -0
  424. {code_context_control-2.82.0 → code_context_control-2.86.0}/tui/screens/claudemd_view.py +0 -0
  425. {code_context_control-2.82.0 → code_context_control-2.86.0}/tui/screens/compress_view.py +0 -0
  426. {code_context_control-2.82.0 → code_context_control-2.86.0}/tui/screens/index_view.py +0 -0
  427. {code_context_control-2.82.0 → code_context_control-2.86.0}/tui/screens/init_view.py +0 -0
  428. {code_context_control-2.82.0 → code_context_control-2.86.0}/tui/screens/mcp_view.py +0 -0
  429. {code_context_control-2.82.0 → code_context_control-2.86.0}/tui/screens/optimize_view.py +0 -0
  430. {code_context_control-2.82.0 → code_context_control-2.86.0}/tui/screens/pipe_view.py +0 -0
  431. {code_context_control-2.82.0 → code_context_control-2.86.0}/tui/screens/projects_view.py +0 -0
  432. {code_context_control-2.82.0 → code_context_control-2.86.0}/tui/screens/search_view.py +0 -0
  433. {code_context_control-2.82.0 → code_context_control-2.86.0}/tui/screens/session_view.py +0 -0
  434. {code_context_control-2.82.0 → code_context_control-2.86.0}/tui/screens/stats.py +0 -0
  435. {code_context_control-2.82.0 → code_context_control-2.86.0}/tui/screens/ui_view.py +0 -0
  436. {code_context_control-2.82.0 → code_context_control-2.86.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.82.0
3
+ Version: 2.86.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
@@ -178,7 +178,7 @@ Twelve tabs. The dashboard above shows token savings, indexed files, the live se
178
178
  <img src="https://raw.githubusercontent.com/drknowhow/code-context-control/main/docs/screenshots/2026-07/ui_tasks.png" alt="C3 Tasks" width="900">
179
179
  </p>
180
180
 
181
- **Tasks** (v2.45.0, extended v2.53.0) is a durable per-project tracker — dependencies and subtasks, milestones, decision notes, full event history, health reports, and both automatic and manual time tracking. It rolls up into the Hub's cross-project board.
181
+ **Tasks** (v2.45.0, extended v2.53.0) is a durable per-project tracker — dependencies and subtasks, milestones, decision notes, full event history, health reports, and both automatic and manual time tracking. It rolls up into the Hub's cross-project board. Shipped milestones can be **completed** (v2.86.0) — they leave the board while their tasks keep the milestone link, unlike archiving, which detaches them.
182
182
 
183
183
  **Instructions** keeps your agent-facing docs in sync. C3-generated content sits inside a `<!-- C3:BEGIN … -->` block; anything you write outside it is preserved. Since v2.60.0 generated docs point at `.c3/MAP.md` — a machine-owned, byte-stable repo map C3 refreshes automatically — instead of embedding a tree that goes stale. `AGENTS.md` serves both Codex and Antigravity; `GEMINI.md` is read if present but no longer generated (the Gemini CLI profile was removed in v2.52).
184
184
 
@@ -243,6 +243,7 @@ c3 access mask activate # purge pre-mask artifacts, buil
243
243
  - **`deny` means deny-enumerate too** — denied paths never appear in search results, maps, or the vector index.
244
244
  - **Masked means read-only, always.** Cropped rows have no inverse, so an edit in transformed coordinates would corrupt the one file you protected.
245
245
  - **Four deterministic presets, no LLM in the read path:** `redact_secrets`, `redact_columns` (salted one-way pseudonyms — joins survive, no reverse dictionary), `sample_rows`, `signatures_only`.
246
+ - **Sensible defaults out of the box** (v2.86.0). A fresh install seeds `*.pem`, `id_rsa*`, and `*.key` as deny rules in global scope — visible in `c3 access list` and removable like any rule you wrote yourself. Delete one and it stays deleted.
246
247
  - **Rule changes are human-only** (UI tab or CLI) and ledger-logged. Agents have no mutation surface.
247
248
  - **Built-ins can be switched off when you need to** (v2.65.0). `**/.env*`, `**/.c3/**`, `**/.claude/settings*.json` and `**/.git/**` yield to `c3 access builtin disable <glob>`, which makes you retype the glob first. It takes **two keys** — a config entry *and* a keyring attestation — so an agent that manages to write `config.json` still cannot grant itself write access to your settings. The credential vault stays absolute.
248
249
  - **Honest coverage.** This guards *cooperative* agents against mistakes and prompt injection. It is not a sandbox — a raw shell outside C3's tools still sees the real bytes.
@@ -115,7 +115,7 @@ Twelve tabs. The dashboard above shows token savings, indexed files, the live se
115
115
  <img src="https://raw.githubusercontent.com/drknowhow/code-context-control/main/docs/screenshots/2026-07/ui_tasks.png" alt="C3 Tasks" width="900">
116
116
  </p>
117
117
 
118
- **Tasks** (v2.45.0, extended v2.53.0) is a durable per-project tracker — dependencies and subtasks, milestones, decision notes, full event history, health reports, and both automatic and manual time tracking. It rolls up into the Hub's cross-project board.
118
+ **Tasks** (v2.45.0, extended v2.53.0) is a durable per-project tracker — dependencies and subtasks, milestones, decision notes, full event history, health reports, and both automatic and manual time tracking. It rolls up into the Hub's cross-project board. Shipped milestones can be **completed** (v2.86.0) — they leave the board while their tasks keep the milestone link, unlike archiving, which detaches them.
119
119
 
120
120
  **Instructions** keeps your agent-facing docs in sync. C3-generated content sits inside a `<!-- C3:BEGIN … -->` block; anything you write outside it is preserved. Since v2.60.0 generated docs point at `.c3/MAP.md` — a machine-owned, byte-stable repo map C3 refreshes automatically — instead of embedding a tree that goes stale. `AGENTS.md` serves both Codex and Antigravity; `GEMINI.md` is read if present but no longer generated (the Gemini CLI profile was removed in v2.52).
121
121
 
@@ -180,6 +180,7 @@ c3 access mask activate # purge pre-mask artifacts, buil
180
180
  - **`deny` means deny-enumerate too** — denied paths never appear in search results, maps, or the vector index.
181
181
  - **Masked means read-only, always.** Cropped rows have no inverse, so an edit in transformed coordinates would corrupt the one file you protected.
182
182
  - **Four deterministic presets, no LLM in the read path:** `redact_secrets`, `redact_columns` (salted one-way pseudonyms — joins survive, no reverse dictionary), `sample_rows`, `signatures_only`.
183
+ - **Sensible defaults out of the box** (v2.86.0). A fresh install seeds `*.pem`, `id_rsa*`, and `*.key` as deny rules in global scope — visible in `c3 access list` and removable like any rule you wrote yourself. Delete one and it stays deleted.
183
184
  - **Rule changes are human-only** (UI tab or CLI) and ledger-logged. Agents have no mutation surface.
184
185
  - **Built-ins can be switched off when you need to** (v2.65.0). `**/.env*`, `**/.c3/**`, `**/.claude/settings*.json` and `**/.git/**` yield to `c3 access builtin disable <glob>`, which makes you retype the glob first. It takes **two keys** — a config entry *and* a keyring attestation — so an agent that manages to write `config.json` still cannot grant itself write access to your settings. The credential vault stays absolute.
185
186
  - **Honest coverage.** This guards *cooperative* agents against mistakes and prompt injection. It is not a sandbox — a raw shell outside C3's tools still sees the real bytes.
@@ -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.82.0"
95
+ __version__ = "2.86.0"
96
96
 
97
97
 
98
98
  def _compress_file_cli(compressor, path, mode="smart", **kw):
@@ -5535,6 +5535,14 @@ def cmd_install_mcp(args):
5535
5535
  except Exception as e:
5536
5536
  print(f"Warning: Could not update global CLAUDE.md: {e}")
5537
5537
 
5538
+ # ── Default Access Guard rules (first run only) ─────────────
5539
+ from services import access_guard
5540
+ seeded = access_guard.seed_default_global_rules()
5541
+ if seeded.get("seeded"):
5542
+ rules = ", ".join(seeded["rules"])
5543
+ print(f"Seeded default Access Guard deny rules into global scope: {rules}")
5544
+ print(" (remove with: c3 access remove <glob> --kind deny --global)")
5545
+
5538
5546
  # ── Install /terse skill for supported IDEs ──────────────────
5539
5547
  if profile.name in ("claude-code", "codex"):
5540
5548
  try:
@@ -6055,6 +6063,15 @@ def _ci_main(args) -> int:
6055
6063
  from cli.tools.ci import handle_ci
6056
6064
 
6057
6065
  sub = getattr(args, "ci_cmd", None) or "inspect"
6066
+ if sub == "publish":
6067
+ if getattr(args, "dry_run", False):
6068
+ args.job = "dry-run"
6069
+ if getattr(args, "force", False):
6070
+ args.allow_side_effects = True
6071
+ if sub == "cache" and getattr(args, "clear", False):
6072
+ # `--clear` is a flag on the CLI; the shared handler takes it
6073
+ # positionally so both surfaces route through one code path.
6074
+ args.job = "clear"
6058
6075
  project_path = getattr(args, "project_path", ".") or "."
6059
6076
  as_json = bool(getattr(args, "json", False))
6060
6077
 
@@ -6106,7 +6123,11 @@ def _ci_main(args) -> int:
6106
6123
  getattr(args, "event", "") or "",
6107
6124
  getattr(args, "engine", "auto") or "auto",
6108
6125
  bool(getattr(args, "allow_side_effects", False)),
6109
- getattr(args, "network", "") or "")
6126
+ getattr(args, "network", "") or "",
6127
+ "required" if getattr(args, "required", False) else "full",
6128
+ getattr(args, "base", "") or "",
6129
+ bool(getattr(args, "allow_host_mutation", False)),
6130
+ bool(getattr(args, "no_cache", False)))
6110
6131
  print(out)
6111
6132
  # Exit code is the finding: a non-full verdict must not read as success to
6112
6133
  # a shell script or a pre-push hook.
@@ -6590,6 +6611,16 @@ def _override_audit(grant: dict, project_path: str) -> None:
6590
6611
 
6591
6612
  def cmd_access(args):
6592
6613
  """Access Guard rule management — human-only mutation surface (spec §1)."""
6614
+ from services import access_guard
6615
+
6616
+ # First `c3 access` touch seeds the removable defaults (spec §1). A
6617
+ # no-op forever after: any existing access section, even an emptied
6618
+ # one, means the user has taken over the scope.
6619
+ seeded = access_guard.seed_default_global_rules()
6620
+ if seeded.get("seeded"):
6621
+ print(f"[seeded] default global deny rules: {', '.join(seeded['rules'])}")
6622
+ print(" Remove any of them: c3 access remove <glob> --kind deny --global\n")
6623
+
6593
6624
  sub = getattr(args, "access_cmd", None)
6594
6625
  if not sub:
6595
6626
  print("Usage: c3 access {list,add,remove,check,stats,mask,builtin} [args]")
@@ -507,6 +507,17 @@ def build_parser(version: str, parse_cli_ide_arg):
507
507
  ci_run.add_argument("--allow-side-effects", action="store_true",
508
508
  help="Let the act engine run jobs that look like they "
509
509
  "publish or deploy. Refused by default.")
510
+ ci_run.add_argument("--required", action="store_true",
511
+ help="Run only the jobs a change could have broken "
512
+ "(conservative; see `c3 ci plan`)")
513
+ ci_run.add_argument("--base", default="",
514
+ help="Diff against this ref instead of the working tree")
515
+ ci_run.add_argument("--allow-host-mutation", action="store_true",
516
+ help="Permit native steps that reconfigure this machine "
517
+ "(pip/npm -g/apt install). Refused by default.")
518
+ ci_run.add_argument("--no-cache", action="store_true",
519
+ help="Ignore cached results and execute every "
520
+ "selected job")
510
521
  ci_run.add_argument("--network", default="",
511
522
  help="Container network for the act engine (e.g. `none` "
512
523
  "to cut egress). Default: act's own.")
@@ -530,6 +541,22 @@ def build_parser(version: str, parse_cli_ide_arg):
530
541
  ci_logs.add_argument("--tail", type=int, default=200)
531
542
 
532
543
  _ci_common(ci_subs.add_parser("runs", help="Recent local CI runs"))
544
+ ci_plan = _ci_common(ci_subs.add_parser(
545
+ "plan", help="Show which jobs a change requires, and why"))
546
+ ci_plan.add_argument("--base", default="",
547
+ help="Diff against this ref instead of the working tree")
548
+ ci_pub = _ci_common(ci_subs.add_parser(
549
+ "publish", help="Post the last run as a GitHub commit status"))
550
+ ci_pub.add_argument("--run", dest="run_id", default="")
551
+ ci_pub.add_argument("--dry-run", action="store_true")
552
+ ci_pub.add_argument("--force", action="store_true",
553
+ help="Publish a PARTIAL result as `pending`")
554
+ _ci_common(ci_subs.add_parser(
555
+ "history", help="Per-job pass/fail history and flake detection"))
556
+ ci_cache_p = _ci_common(ci_subs.add_parser(
557
+ "cache", help="Cached-result store: size, or --clear it"))
558
+ ci_cache_p.add_argument("--clear", action="store_true",
559
+ help="Drop every cached result and dependency cache")
533
560
  _ci_common(ci_subs.add_parser(
534
561
  "doctor", help="Which execution engines are available on this machine"))
535
562
 
@@ -41,7 +41,24 @@ _MAX_TOKENS = 200
41
41
  # "NTFS alternate data stream". The ADS check stays strict for real path
42
42
  # arguments (_WRITE_TOOLS/_READ_TOOLS); here it only produced false denies on
43
43
  # commit messages, curl, and gh (#50).
44
- _SCHEME_RE = re.compile(r"^[a-z][a-z0-9+.\-]*://", re.IGNORECASE)
44
+ #
45
+ # UNANCHORED, and that is the fix rather than an oversight. `^…://` only ever
46
+ # recognised a token that BEGINS with a scheme, which is the same
47
+ # whitelist-a-shape mistake #50 made and this module's own header calls out —
48
+ # and the `_SYNTAX_CHARS` generalisation does not cover the gap, because a
49
+ # token can carry a URL and no syntax at all. Observed 2026-08-11: the single
50
+ # argument of
51
+ # printf '\n---\n\nhttps://claude.ai/code/session_01Hs28…\n' >> body.md
52
+ # strips to `\n---\n\nhttps://claude.ai/…`, which has a separator (`\` and
53
+ # `/`), no syntax characters, no `::`, and no leading scheme. It reached
54
+ # ag.check, canonicalised to a residual colon, and hard-denied a command whose
55
+ # only file argument was an ordinary markdown path. Third logged instance of
56
+ # this class in five days (two on 2026-08-07 were Windows paths inside Python
57
+ # string literals).
58
+ #
59
+ # A token containing `://` anywhere is a network literal, not an NTFS stream:
60
+ # a real stream is `file:name:$TYPE`, and no spelling of it contains `//`.
61
+ _SCHEME_RE = re.compile(r"[a-z][a-z0-9+.\-]*://", re.IGNORECASE)
45
62
  # IPv6 literal or CIDR: >=2 colons, hex groups only, optional [] and /prefix.
46
63
  # 'C:/x/f.txt:stream' has one colon and non-hex parts, so it never matches.
47
64
  _IPV6_RE = re.compile(
@@ -104,8 +121,13 @@ _CD_RE = re.compile(
104
121
 
105
122
 
106
123
  def _is_network_token(tok: str) -> bool:
107
- """True for URLs and IPv6 literals/CIDRs — never for an ADS spelling."""
108
- return bool(_SCHEME_RE.match(tok) or _IPV6_RE.match(tok))
124
+ """True for URLs and IPv6 literals/CIDRs — never for an ADS spelling.
125
+
126
+ ``search`` for the scheme (a URL anywhere in the token disqualifies it as
127
+ a path), ``match`` for IPv6 — that pattern is a whole-token shape and
128
+ anchoring is what keeps `C:/x/f.txt:stream` from matching it.
129
+ """
130
+ return bool(_SCHEME_RE.search(tok) or _IPV6_RE.match(tok))
109
131
 
110
132
 
111
133
  def _is_scope_token(tok: str) -> bool:
@@ -2740,6 +2740,20 @@ def api_pm_milestone():
2740
2740
  return jsonify({"error": "id is required"}), 400
2741
2741
 
2742
2742
  if request.method == "PUT":
2743
+ # {complete: true} / {reopen: true} switch lifecycle; tasks keep
2744
+ # their milestone link (unlike DELETE = archive + detach).
2745
+ if data.get("complete"):
2746
+ res = store.complete_milestone(ms_id)
2747
+ if "error" in res:
2748
+ return jsonify(res), 400
2749
+ _pm_audit(resolved, "milestone", "complete", res["id"])
2750
+ return jsonify({"completed": True, "milestone": res})
2751
+ if data.get("reopen"):
2752
+ res = store.reopen_milestone(ms_id)
2753
+ if "error" in res:
2754
+ return jsonify(res), 400
2755
+ _pm_audit(resolved, "milestone", "reopen", res["id"])
2756
+ return jsonify({"reopened": True, "milestone": res})
2743
2757
  res = store.update_milestone(ms_id, expected_rev=data.get("expected_rev"),
2744
2758
  **(data.get("fields") or {}))
2745
2759
  if "error" in res:
@@ -771,10 +771,25 @@ async def c3_ci(action: str = "inspect", job: str = "", run_id: str = "",
771
771
  allow_foreign: bool = False, workflow: str = "",
772
772
  tail: int = 200, timeout: int = 0, event: str = "",
773
773
  engine: str = "auto", allow_side_effects: bool = False,
774
- network: str = "", ctx: Context = None) -> str:
774
+ network: str = "", mode: str = "full", base: str = "",
775
+ allow_host_mutation: bool = False,
776
+ no_cache: bool = False, ctx: Context = None) -> str:
775
777
  """RUN THIS REPO'S REAL CI LOCALLY — before pushing, not after.
776
778
  Reads .github/workflows/*.yml as the source of truth (no second CI config).
777
- actions: inspect | run | rerun | status | failures | logs | runs | doctor.
779
+ actions: inspect | plan | run | rerun | status | failures | logs | runs |
780
+ cache | history | publish | doctor. publish posts the last run as a
781
+ GitHub COMMIT STATUS via your gh auth; it refuses a dirty tree, an
782
+ unpushed commit, and (unless forced) a PARTIAL result. history reports per-job fail rates and
783
+ flags FLAKY jobs — ones that both passed and failed on identical
784
+ inputs, so the code cannot be the cause. A job whose inputs are unchanged since it last passed
785
+ is reused (status `cached`, nothing executed); no_cache forces it.
786
+ mode: full (default) | required. required runs only the jobs a change
787
+ could have broken; it is CONSERVATIVE — anything unmapped runs. Use
788
+ action='plan' to see the decision and reason for every job first.
789
+ allow_host_mutation: the NATIVE engine refuses steps that would
790
+ reconfigure this machine (pip/npm -g/apt/brew install...). It has no
791
+ isolation; running this repo's own CI natively once uninstalled C3.
792
+ Prefer engine='act'.
778
793
  inspect: workflows, the job DAG, and which jobs are runnable on THIS host.
779
794
  run: execute in dependency order; job='lint' or 'test (ubuntu-latest, 3.12)'
780
795
  selects one (bare job name = all its matrix cells). A job whose dependency
@@ -798,7 +813,9 @@ async def c3_ci(action: str = "inspect", job: str = "", run_id: str = "",
798
813
  return await asyncio.to_thread(handle_ci, action, job, run_id,
799
814
  allow_foreign, workflow, tail, timeout,
800
815
  svc, finalize, event, engine,
801
- allow_side_effects, network)
816
+ allow_side_effects, network,
817
+ mode, base, allow_host_mutation,
818
+ no_cache)
802
819
 
803
820
 
804
821
  @mcp.tool()
@@ -1088,7 +1105,9 @@ async def c3_task(
1088
1105
  Time: time_add (minutes 1-1440 [+note/due_date=date/task_id]), time_update / time_delete (ref=entry id),
1089
1106
  time_list (manual entries + recent auto sessions), time_summary (today/7d/30d, auto vs manual).
1090
1107
  Auto-tracking: server startup + tool calls ping .c3/time; idle gaps >15min close a session.
1091
- Milestones: milestone_add (name [+target_date]), milestone_update, milestone_list (with progress %), milestone_archive.
1108
+ Milestones: milestone_add (name [+target_date]), milestone_update, milestone_list (with progress %),
1109
+ milestone_complete (close a shipped milestone; refuses while open tasks remain; tasks KEEP their link),
1110
+ milestone_reopen (undo complete), milestone_archive (removal: detaches tasks).
1092
1111
  Notes: note_add (note [+kind=decision] [+task_id]), note_list.
1093
1112
  History: history ([+task_id] [+limit]) — append-only event log (who/what/when, before->after), newest first.
1094
1113
  task_id accepts any unique id prefix (>=4 chars); milestone accepts id or unique name.
@@ -1295,6 +1295,20 @@ def api_pm_milestone():
1295
1295
  if not ms_id:
1296
1296
  return jsonify({"error": "id is required"}), 400
1297
1297
  if request.method == "PUT":
1298
+ # {complete: true} / {reopen: true} switch lifecycle; tasks keep
1299
+ # their milestone link (unlike DELETE = archive + detach).
1300
+ if data.get("complete"):
1301
+ res = store.complete_milestone(ms_id)
1302
+ if "error" in res:
1303
+ return jsonify(res), 400
1304
+ _pm_audit("milestone", "complete", res["id"])
1305
+ return jsonify({"completed": True, "milestone": res})
1306
+ if data.get("reopen"):
1307
+ res = store.reopen_milestone(ms_id)
1308
+ if "error" in res:
1309
+ return jsonify(res), 400
1310
+ _pm_audit("milestone", "reopen", res["id"])
1311
+ return jsonify({"reopened": True, "milestone": res})
1298
1312
  res = store.update_milestone(ms_id, expected_rev=data.get("expected_rev"),
1299
1313
  **(data.get("fields") or {}))
1300
1314
  if "error" in res:
@@ -12,13 +12,14 @@ That distinction is the product.
12
12
  """
13
13
  from __future__ import annotations
14
14
 
15
+ from services import ci_impact
15
16
  from services import ci_runner as cr
16
17
  from services.ci_workflow import inspect_project
17
18
 
18
19
  _MARK = {
19
20
  cr.PASSED: "PASS", cr.FAILED: "FAIL", cr.SKIPPED: "SKIP",
20
21
  cr.UNSUPPORTED: "UNSUP", cr.FOREIGN: "OTHER-OS", cr.TIMEOUT: "TIMEOUT",
21
- cr.DESELECTED: "-",
22
+ cr.DESELECTED: "-", cr.CACHED: "CACHED",
22
23
  }
23
24
 
24
25
  # Verdicts an agent may treat as "safe to push". Deliberately one item long.
@@ -81,7 +82,10 @@ def _failure_rows(jobs: list, limit: int = 25) -> list:
81
82
  def handle_ci(action: str, job: str, run_id: str, allow_foreign: bool,
82
83
  workflow: str, tail: int, timeout: int, svc, finalize,
83
84
  event: str = "", engine: str = "auto",
84
- allow_side_effects: bool = False, network: str = "") -> str:
85
+ allow_side_effects: bool = False, network: str = "",
86
+ mode: str = "full", base: str = "",
87
+ allow_host_mutation: bool = False,
88
+ no_cache: bool = False) -> str:
85
89
  """Route c3_ci actions."""
86
90
  project = str(svc.project_path)
87
91
  action = (action or "inspect").strip().lower()
@@ -152,6 +156,43 @@ def handle_ci(action: str, job: str, run_id: str, allow_foreign: bool,
152
156
  return finalize("c3_ci", args, "\n".join(lines),
153
157
  f"{len(data['jobs'])} jobs, {len(data['runnable'])} runnable")
154
158
 
159
+ # ── plan (required mode, no execution) ───────────────────────────────
160
+ if action == "plan":
161
+ from services.ci_workflow import (
162
+ build_dag,
163
+ discover_workflows,
164
+ git_context,
165
+ parse_workflow,
166
+ )
167
+ wfs = [parse_workflow(p) for p in discover_workflows(project)]
168
+ dag = build_dag([w for w in wfs if not w.error],
169
+ event=event, git=git_context(project))
170
+ try:
171
+ ordered = dag.topo_order()
172
+ except Exception:
173
+ ordered = dag.instances
174
+ plan = ci_impact.plan_required(project, ordered, wfs, base=base,
175
+ event=event)
176
+ lines = [
177
+ f"Required-mode plan ({len(plan.selected)} run / "
178
+ f"{len(plan.skipped)} skip) vs {base or 'the working tree'}",
179
+ f"changed files: {len(plan.changed)}",
180
+ ]
181
+ for path in plan.changed[:10]:
182
+ lines.append(f" {path}")
183
+ if len(plan.changed) > 10:
184
+ lines.append(f" ... and {len(plan.changed) - 10} more")
185
+ lines.append("")
186
+ for decision in plan.decisions:
187
+ mark = "RUN " if decision.decision == ci_impact.RUN else "skip"
188
+ lines.append(f" {mark} {decision.job}")
189
+ lines.append(f" {decision.reason}")
190
+ if plan.note:
191
+ lines.append(f"\n{plan.note}")
192
+ lines.append("\nRun it: c3_ci(action='run', mode='required')")
193
+ return finalize("c3_ci", args, "\n".join(lines),
194
+ f"{len(plan.selected)} required")
195
+
155
196
  # ── run / rerun ──────────────────────────────────────────────────────
156
197
  if action in ("run", "rerun"):
157
198
  only = None
@@ -172,7 +213,9 @@ def handle_ci(action: str, job: str, run_id: str, allow_foreign: bool,
172
213
  only=only, timeout=timeout or cr.DEFAULT_STEP_TIMEOUT,
173
214
  workflow=workflow, event=event, engine=engine,
174
215
  allow_side_effects=allow_side_effects,
175
- network=network)
216
+ network=network, mode=mode, base=base,
217
+ allow_host_mutation=allow_host_mutation,
218
+ no_cache=no_cache)
176
219
  run = result.to_dict()
177
220
  lines = [_verdict_line(run), f"run {run['run_id']} host={run['host_os']}"]
178
221
  fp = run.get("fingerprint") or {}
@@ -245,6 +288,86 @@ def handle_ci(action: str, job: str, run_id: str, allow_foreign: bool,
245
288
  f"{row.get('started_at', '')[:19]} {tally}")
246
289
  return finalize("c3_ci", args, "\n".join(lines), f"{len(rows)} runs")
247
290
 
291
+ # ── history / intelligence ───────────────────────────────────────────
292
+ if action in ("history", "intel", "flaky"):
293
+ from services import ci_intel
294
+ data = ci_intel.analyse(project)
295
+ if not data["runs_analysed"]:
296
+ return finalize("c3_ci", args, data["note"], "no history")
297
+ lines = [data["note"], ""]
298
+ if data["flaky"]:
299
+ lines.append("FLAKY — passed AND failed on identical inputs:")
300
+ for job in data["flaky"]:
301
+ lines.append(f" {job['key']} {job['failed']}/{job['executed']} failed")
302
+ lines.append(" same fingerprint gave both answers, so the "
303
+ "code did not change between them")
304
+ lines.append("")
305
+ lines.append(f"{'job':<40}{'exec':>5}{'fail':>6}{'rate':>7}{'avg':>8}")
306
+ for job in data["jobs"][:15]:
307
+ rate = f"{job['fail_rate']:.0%}" if job["executed"] else "-"
308
+ avg = f"{job['avg_ms'] / 1000:.1f}s" if job["avg_ms"] else "-"
309
+ mark = "" if job["confident"] else " (low n)"
310
+ lines.append(f" {job['key']:<38}{job['executed']:>5}"
311
+ f"{job['failed']:>6}{rate:>7}{avg:>8}{mark}")
312
+ if data["slowest"]:
313
+ lines.append("\nSlowest: " + ", ".join(
314
+ f"{j['key']} {j['avg_ms'] / 1000:.1f}s" for j in data["slowest"][:3]))
315
+ return finalize("c3_ci", args, "\n".join(lines),
316
+ f"{len(data['flaky'])} flaky")
317
+
318
+ # ── publish (GitHub commit status) ───────────────────────────────────
319
+ if action == "publish":
320
+ from services import ci_github
321
+ run = cr.load_run(project, run_id)
322
+ if not run:
323
+ return finalize("c3_ci", args, "No run to publish.", "no runs")
324
+ res = ci_github.publish(project, run,
325
+ force=allow_side_effects,
326
+ dry_run=(job or "").lower() == "dry-run")
327
+ if res.get("dry_run"):
328
+ body = "\n".join([
329
+ f"Would POST {res['endpoint']}",
330
+ f" state={res['state']}",
331
+ f" {res['description']}",
332
+ ])
333
+ return finalize("c3_ci", args, body, "dry run")
334
+ if not res.get("published"):
335
+ return finalize("c3_ci", args,
336
+ f"Not published: {res.get('reason')}", "refused")
337
+ body = (f"Published {res['state']} to {res['sha'][:8]} "
338
+ f"as {res['context']}.\n {res['description']}")
339
+ return finalize("c3_ci", args, body, res["state"])
340
+
341
+ # ── cache ────────────────────────────────────────────────────────────
342
+ if action == "cache":
343
+ from services import ci_cache
344
+ if (job or "").strip().lower() == "clear" or run_id == "clear":
345
+ freed = ci_cache.clear(project)
346
+ return finalize("c3_ci", args,
347
+ f"Cleared the CI cache ({freed / 1024:.0f} KB).",
348
+ "cache cleared")
349
+ info = ci_cache.stats(project)
350
+ rules = ci_impact.load_rules(project)
351
+ lines = [
352
+ f"Cached results: {info['results']}",
353
+ f"Dependency cache keys: {info['dependency_keys']}",
354
+ f"Location: {info['dir']}",
355
+ "",
356
+ "A job is reused when its definition, engine and inputs are all "
357
+ "unchanged since it last passed.",
358
+ ]
359
+ if rules:
360
+ lines.append(
361
+ f"{len(rules)} job(s) declare inputs via ci.required_map, so "
362
+ "only those paths invalidate them.")
363
+ else:
364
+ lines.append(
365
+ "No ci.required_map: every job is fingerprinted over the whole "
366
+ "tree, so any edit invalidates every cached result. Declaring "
367
+ "inputs is what makes the cache bite.")
368
+ return finalize("c3_ci", args, "\n".join(lines),
369
+ f"{info['results']} cached")
370
+
248
371
  # ── doctor ───────────────────────────────────────────────────────────
249
372
  if action == "doctor":
250
373
  from services import ci_act
@@ -69,6 +69,45 @@ _SOFT_WARN = re.compile(
69
69
 
70
70
  _DEFAULT_TIMEOUT = 60
71
71
  _MAX_TIMEOUT = 600
72
+
73
+ # The transport's own ceiling, and the reason _MAX_TIMEOUT alone is a lie.
74
+ #
75
+ # An MCP client kills a tool call at MCP_TOOL_TIMEOUT (Claude Code ships
76
+ # 120_000 ms and the value is set per-environment) — a limit this process does
77
+ # not choose and cannot raise. Until this existed, `c3_shell(timeout=600)` was
78
+ # accepted, clamped to 600, and then killed by the client at 120s with the
79
+ # subprocess still running: the caller saw the call "moved to background" and
80
+ # then fail, with no line anywhere naming the real limit or attributing the
81
+ # kill. The subprocess was NOT reaped by us, because our own deadline never
82
+ # arrived.
83
+ #
84
+ # The cost was not hypothetical. Two Higgsfield image generations (2-4 min
85
+ # each) were requested at timeout=420, killed at 120s, and the remote jobs
86
+ # completed and were BILLED while the local process died before downloading —
87
+ # one image landed, one was paid for and stranded.
88
+ #
89
+ # So: discover the client's ceiling, run just inside it, and SAY SO. Running
90
+ # inside it means OUR deadline fires first, which turns a phantom
91
+ # client-side kill into an ordinary `[c3_shell:TIMEOUT]` with stdout, a
92
+ # duration, and a process tree we actually killed.
93
+ _TRANSPORT_MARGIN_S = 5
94
+
95
+
96
+ def _transport_ceiling_s() -> int | None:
97
+ """Seconds this call may run before the MCP client kills it, if knowable.
98
+
99
+ None when the variable is unset or unparseable — then nothing is capped
100
+ and behaviour is exactly what it was, because a guess here would cap
101
+ legitimate work on a client with no such limit.
102
+ """
103
+ raw = (os.environ.get("MCP_TOOL_TIMEOUT") or "").strip()
104
+ if not raw:
105
+ return None
106
+ try:
107
+ ceiling = int(float(raw)) // 1000
108
+ except (TypeError, ValueError):
109
+ return None
110
+ return ceiling if ceiling > _TRANSPORT_MARGIN_S else None
72
111
  _FILTER_THRESHOLD_LINES = 30
73
112
  _JQ_INVOCATION = re.compile(r"(?:^|&&|\|\||[;|(])\s*jq(?:\s|$)", re.IGNORECASE)
74
113
 
@@ -468,6 +507,13 @@ async def handle_shell(cmd: str, cwd: str, timeout: int, filter_output: bool,
468
507
  )
469
508
 
470
509
  timeout = max(1, min(int(timeout or _DEFAULT_TIMEOUT), _MAX_TIMEOUT))
510
+ # Cap to what the transport will actually allow, and remember that we did
511
+ # so — the caller asked for a number, and a number quietly not honoured is
512
+ # the whole defect (see _transport_ceiling_s).
513
+ capped_from = 0
514
+ _ceiling = _transport_ceiling_s()
515
+ if _ceiling is not None and timeout > _ceiling - _TRANSPORT_MARGIN_S:
516
+ capped_from, timeout = timeout, _ceiling - _TRANSPORT_MARGIN_S
471
517
  work_cwd = cwd or svc.project_path
472
518
  work_cwd = str(Path(work_cwd).resolve())
473
519
 
@@ -601,6 +647,16 @@ async def handle_shell(cmd: str, cwd: str, timeout: int, filter_output: bool,
601
647
  warn = ""
602
648
  if _SOFT_WARN.search(cmd):
603
649
  warn = "[c3_shell:warn] destructive pattern detected — verify before re-running\n"
650
+ if capped_from:
651
+ # Named at the moment of the mistake, not in documentation nobody
652
+ # reads at the moment they need it. The alternative IS the escape
653
+ # hatch, so the line says which one.
654
+ warn += (
655
+ f"[c3_shell:capped] timeout={capped_from}s was requested but this "
656
+ f"MCP client kills a tool call at {_ceiling}s; ran with {timeout}s. "
657
+ f"For longer work use the native Bash tool with "
658
+ f"run_in_background, which is not bound by this limit.\n"
659
+ )
604
660
 
605
661
  if result["timed_out"]:
606
662
  status = "TIMEOUT"
@@ -5,7 +5,8 @@ READ_ACTIONS = {"list", "get", "board", "history", "report",
5
5
 
6
6
  _TASK_ACTIONS = ("add, update, done, list, get, board, history, report, archive, "
7
7
  "block, unblock, link, unlink, "
8
- "milestone_add, milestone_update, milestone_list, milestone_archive, "
8
+ "milestone_add, milestone_update, milestone_list, "
9
+ "milestone_complete, milestone_reopen, milestone_archive, "
9
10
  "note_add, note_list, "
10
11
  "time_add, time_update, time_delete, time_list, time_summary")
11
12
 
@@ -368,6 +369,26 @@ def handle_task(action, svc, finalize, *, title="", task_id="", status="",
368
369
  return done_resp(f"[task:error] {res['error']}", "error")
369
370
  return done_resp(f"[milestone:updated] {res['id'][:8]} \"{res['name']}\"", "updated")
370
371
 
372
+ if action == "milestone_complete":
373
+ if not milestone:
374
+ return done_resp("[task:error] milestone_complete requires milestone.", "error")
375
+ ms = store.resolve_milestone(milestone)
376
+ if ms is None:
377
+ return done_resp(f"[task:error] no milestone matches: {milestone}", "error")
378
+ res = store.complete_milestone(ms["id"])
379
+ if "error" in res:
380
+ return done_resp(f"[task:error] {res['error']}", "error")
381
+ return done_resp(f"[milestone:completed] \"{res['name']}\" "
382
+ f"(tasks keep their milestone link)", "completed")
383
+
384
+ if action == "milestone_reopen":
385
+ if not milestone:
386
+ return done_resp("[task:error] milestone_reopen requires milestone.", "error")
387
+ res = store.reopen_milestone(milestone)
388
+ if "error" in res:
389
+ return done_resp(f"[task:error] {res['error']}", "error")
390
+ return done_resp(f"[milestone:reopened] \"{res['name']}\"", "reopened")
391
+
371
392
  if action == "milestone_archive":
372
393
  if not milestone:
373
394
  return done_resp("[task:error] milestone_archive requires milestone.", "error")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-context-control
3
- Version: 2.82.0
3
+ Version: 2.86.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
@@ -178,7 +178,7 @@ Twelve tabs. The dashboard above shows token savings, indexed files, the live se
178
178
  <img src="https://raw.githubusercontent.com/drknowhow/code-context-control/main/docs/screenshots/2026-07/ui_tasks.png" alt="C3 Tasks" width="900">
179
179
  </p>
180
180
 
181
- **Tasks** (v2.45.0, extended v2.53.0) is a durable per-project tracker — dependencies and subtasks, milestones, decision notes, full event history, health reports, and both automatic and manual time tracking. It rolls up into the Hub's cross-project board.
181
+ **Tasks** (v2.45.0, extended v2.53.0) is a durable per-project tracker — dependencies and subtasks, milestones, decision notes, full event history, health reports, and both automatic and manual time tracking. It rolls up into the Hub's cross-project board. Shipped milestones can be **completed** (v2.86.0) — they leave the board while their tasks keep the milestone link, unlike archiving, which detaches them.
182
182
 
183
183
  **Instructions** keeps your agent-facing docs in sync. C3-generated content sits inside a `<!-- C3:BEGIN … -->` block; anything you write outside it is preserved. Since v2.60.0 generated docs point at `.c3/MAP.md` — a machine-owned, byte-stable repo map C3 refreshes automatically — instead of embedding a tree that goes stale. `AGENTS.md` serves both Codex and Antigravity; `GEMINI.md` is read if present but no longer generated (the Gemini CLI profile was removed in v2.52).
184
184
 
@@ -243,6 +243,7 @@ c3 access mask activate # purge pre-mask artifacts, buil
243
243
  - **`deny` means deny-enumerate too** — denied paths never appear in search results, maps, or the vector index.
244
244
  - **Masked means read-only, always.** Cropped rows have no inverse, so an edit in transformed coordinates would corrupt the one file you protected.
245
245
  - **Four deterministic presets, no LLM in the read path:** `redact_secrets`, `redact_columns` (salted one-way pseudonyms — joins survive, no reverse dictionary), `sample_rows`, `signatures_only`.
246
+ - **Sensible defaults out of the box** (v2.86.0). A fresh install seeds `*.pem`, `id_rsa*`, and `*.key` as deny rules in global scope — visible in `c3 access list` and removable like any rule you wrote yourself. Delete one and it stays deleted.
246
247
  - **Rule changes are human-only** (UI tab or CLI) and ledger-logged. Agents have no mutation surface.
247
248
  - **Built-ins can be switched off when you need to** (v2.65.0). `**/.env*`, `**/.c3/**`, `**/.claude/settings*.json` and `**/.git/**` yield to `c3 access builtin disable <glob>`, which makes you retype the glob first. It takes **two keys** — a config entry *and* a keyring attestation — so an agent that manages to write `config.json` still cannot grant itself write access to your settings. The credential vault stays absolute.
248
249
  - **Honest coverage.** This guards *cooperative* agents against mistakes and prompt injection. It is not a sandbox — a raw shell outside C3's tools still sees the real bytes.
@@ -186,8 +186,12 @@ services/benchmark_dashboard.py
186
186
  services/bitbucket_client.py
187
187
  services/bitbucket_credentials.py
188
188
  services/ci_act.py
189
+ services/ci_cache.py
189
190
  services/ci_expr.py
190
191
  services/ci_failures.py
192
+ services/ci_github.py
193
+ services/ci_impact.py
194
+ services/ci_intel.py
191
195
  services/ci_runner.py
192
196
  services/ci_workflow.py
193
197
  services/circuit_breaker.py
@@ -283,7 +287,10 @@ tests/test_c3_bridge_project_artifacts.py
283
287
  tests/test_c3_shell.py
284
288
  tests/test_chat_poll.py
285
289
  tests/test_ci_act.py
290
+ tests/test_ci_cache.py
286
291
  tests/test_ci_expr.py
292
+ tests/test_ci_impact.py
293
+ tests/test_ci_intel.py
287
294
  tests/test_ci_runner.py
288
295
  tests/test_ci_workflow.py
289
296
  tests/test_circuit_breaker.py