code-context-control 2.145.2__tar.gz → 2.146.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 (575) hide show
  1. {code_context_control-2.145.2 → code_context_control-2.146.0}/PKG-INFO +1 -1
  2. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/c3.py +3 -3
  3. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_server.py +28 -23
  4. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/app.js +4 -1
  5. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/hub_credentials.js +21 -14
  6. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/state.js +7 -3
  7. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui.html +1 -1
  8. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/server.py +4 -4
  9. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/credentials.py +1 -2
  10. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui.html +1 -1
  11. {code_context_control-2.145.2 → code_context_control-2.146.0}/code_context_control.egg-info/PKG-INFO +1 -1
  12. {code_context_control-2.145.2 → code_context_control-2.146.0}/pyproject.toml +1 -1
  13. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/activity_log.py +43 -15
  14. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/ci_act.py +22 -1
  15. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/ci_workflow.py +5 -2
  16. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/credential_backup.py +9 -3
  17. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/credential_store.py +72 -10
  18. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/project_manager.py +9 -0
  19. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/session_catalog.py +82 -34
  20. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_activity_log_find_last.py +29 -1
  21. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_ci_act.py +27 -0
  22. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_cred_audit.py +2 -2
  23. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_credential_store.py +50 -0
  24. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hub_access_routes.py +1 -1
  25. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hub_credentials_routes_write.py +1 -1
  26. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hub_enforcement_routes.py +1 -1
  27. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hub_locks_routes.py +1 -1
  28. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hub_rules_routes.py +1 -1
  29. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hub_sessions_routes.py +1 -1
  30. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_session_catalog.py +30 -0
  31. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_token_tracking.py +2 -2
  32. {code_context_control-2.145.2 → code_context_control-2.146.0}/LICENSE +0 -0
  33. {code_context_control-2.145.2 → code_context_control-2.146.0}/README.md +0 -0
  34. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/__init__.py +0 -0
  35. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/_hook_utils.py +0 -0
  36. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/_shell_writes.py +0 -0
  37. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/commands/__init__.py +0 -0
  38. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/commands/common.py +0 -0
  39. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/commands/parser.py +0 -0
  40. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/docs.html +0 -0
  41. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/edits.html +0 -0
  42. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/guide/access.html +0 -0
  43. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/guide/bitbucket.html +0 -0
  44. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/guide/ci.html +0 -0
  45. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/guide/credentials.html +0 -0
  46. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/guide/delegate.html +0 -0
  47. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/guide/getting-started.html +0 -0
  48. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/guide/index.html +0 -0
  49. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/guide/jira.html +0 -0
  50. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/guide/masking.html +0 -0
  51. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/guide/oracle.html +0 -0
  52. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/guide/sessions.html +0 -0
  53. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/guide/shared.css +0 -0
  54. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/guide/tools.html +0 -0
  55. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/guide/workflow.html +0 -0
  56. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_access_guard.py +0 -0
  57. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_agent_model.py +0 -0
  58. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_artifact.py +0 -0
  59. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_auto_snapshot.py +0 -0
  60. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_c3_signal.py +0 -0
  61. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_c3read.py +0 -0
  62. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_codex_lifecycle.py +0 -0
  63. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_dispatch.py +0 -0
  64. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_edit_ledger.py +0 -0
  65. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_edit_unlock.py +0 -0
  66. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_filter.py +0 -0
  67. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_ghost_files.py +0 -0
  68. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_pretool_enforce.py +0 -0
  69. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_prompt_recall.py +0 -0
  70. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_read.py +0 -0
  71. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_session_end.py +0 -0
  72. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_session_open.py +0 -0
  73. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_session_stats.py +0 -0
  74. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hook_terse_advisor.py +0 -0
  75. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/add_project.js +0 -0
  76. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/config_editor.js +0 -0
  77. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
  78. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/drill_health.js +0 -0
  79. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/drill_panel.js +0 -0
  80. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
  81. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/drill_tasks.js +0 -0
  82. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/drill_views.js +0 -0
  83. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/global_search.js +0 -0
  84. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/hub_access.js +0 -0
  85. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/hub_ci.js +0 -0
  86. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/hub_cred_audit.js +0 -0
  87. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
  88. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/hub_locks.js +0 -0
  89. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/hub_sessions.js +0 -0
  90. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/hub_tokens.js +0 -0
  91. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/mcp_manager.js +0 -0
  92. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/modals.js +0 -0
  93. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/project_card.js +0 -0
  94. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/project_tree.js +0 -0
  95. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/session_drawer.js +0 -0
  96. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/settings_modal.js +0 -0
  97. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/sidebar.js +0 -0
  98. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/summary_bar.js +0 -0
  99. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/task_board.js +0 -0
  100. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/toasts.js +0 -0
  101. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/hub_ui/components/topbar.js +0 -0
  102. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/mcp_proxy.py +0 -0
  103. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/mcp_server.py +0 -0
  104. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/progress.py +0 -0
  105. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/__init__.py +0 -0
  106. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/_grants.py +0 -0
  107. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/_helpers.py +0 -0
  108. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/agent.py +0 -0
  109. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/artifacts.py +0 -0
  110. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/bitbucket.py +0 -0
  111. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/ci.py +0 -0
  112. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/compress.py +0 -0
  113. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/delegate.py +0 -0
  114. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/edit.py +0 -0
  115. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/edit_verify.py +0 -0
  116. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/edits.py +0 -0
  117. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/federate.py +0 -0
  118. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/filter.py +0 -0
  119. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/impact.py +0 -0
  120. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/jira.py +0 -0
  121. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/locks.py +0 -0
  122. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/memory.py +0 -0
  123. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/override.py +0 -0
  124. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/project.py +0 -0
  125. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/read.py +0 -0
  126. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/search.py +0 -0
  127. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/session.py +0 -0
  128. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/shell.py +0 -0
  129. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/shell_job.py +0 -0
  130. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/shell_nudge.py +0 -0
  131. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/shell_parsers.py +0 -0
  132. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/shell_render.py +0 -0
  133. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/status.py +0 -0
  134. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/tasks.py +0 -0
  135. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/tools/validate.py +0 -0
  136. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/api.js +0 -0
  137. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/app.js +0 -0
  138. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/components/access.js +0 -0
  139. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/components/bitbucket.js +0 -0
  140. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/components/chat.js +0 -0
  141. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/components/credentials.js +0 -0
  142. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/components/dashboard.js +0 -0
  143. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/components/edits.js +0 -0
  144. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/components/enforcement.js +0 -0
  145. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/components/instructions.js +0 -0
  146. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/components/jira.js +0 -0
  147. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/components/memory.js +0 -0
  148. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/components/sessions.js +0 -0
  149. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/components/settings.js +0 -0
  150. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/components/sidebar.js +0 -0
  151. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/components/tasks.js +0 -0
  152. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/icons.js +0 -0
  153. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/pm_shared.js +0 -0
  154. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/shared.js +0 -0
  155. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui/theme.js +0 -0
  156. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui_legacy.html +0 -0
  157. {code_context_control-2.145.2 → code_context_control-2.146.0}/cli/ui_nano.html +0 -0
  158. {code_context_control-2.145.2 → code_context_control-2.146.0}/code_context_control.egg-info/SOURCES.txt +0 -0
  159. {code_context_control-2.145.2 → code_context_control-2.146.0}/code_context_control.egg-info/dependency_links.txt +0 -0
  160. {code_context_control-2.145.2 → code_context_control-2.146.0}/code_context_control.egg-info/entry_points.txt +0 -0
  161. {code_context_control-2.145.2 → code_context_control-2.146.0}/code_context_control.egg-info/requires.txt +0 -0
  162. {code_context_control-2.145.2 → code_context_control-2.146.0}/code_context_control.egg-info/top_level.txt +0 -0
  163. {code_context_control-2.145.2 → code_context_control-2.146.0}/core/__init__.py +0 -0
  164. {code_context_control-2.145.2 → code_context_control-2.146.0}/core/codex_patch.py +0 -0
  165. {code_context_control-2.145.2 → code_context_control-2.146.0}/core/config.py +0 -0
  166. {code_context_control-2.145.2 → code_context_control-2.146.0}/core/grok_payload.py +0 -0
  167. {code_context_control-2.145.2 → code_context_control-2.146.0}/core/hook_command.py +0 -0
  168. {code_context_control-2.145.2 → code_context_control-2.146.0}/core/host.py +0 -0
  169. {code_context_control-2.145.2 → code_context_control-2.146.0}/core/ide.py +0 -0
  170. {code_context_control-2.145.2 → code_context_control-2.146.0}/core/mcp_toml.py +0 -0
  171. {code_context_control-2.145.2 → code_context_control-2.146.0}/core/web_security.py +0 -0
  172. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/__init__.py +0 -0
  173. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/config.py +0 -0
  174. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/listeners.py +0 -0
  175. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/mcp_oracle.py +0 -0
  176. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/oracle_server.py +0 -0
  177. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/oracle_ui.html +0 -0
  178. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/__init__.py +0 -0
  179. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/activity_reporter.py +0 -0
  180. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/api_auth.py +0 -0
  181. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/c3_bridge.py +0 -0
  182. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/chat_engine.py +0 -0
  183. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/chat_poll.py +0 -0
  184. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/chat_store.py +0 -0
  185. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/client_tokens.py +0 -0
  186. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/cross_memory.py +0 -0
  187. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/discovery_audit.py +0 -0
  188. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/federated_graph.py +0 -0
  189. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/health_checker.py +0 -0
  190. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/insight_engine.py +0 -0
  191. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/local_session.py +0 -0
  192. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/memory_reader.py +0 -0
  193. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/memory_writer.py +0 -0
  194. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/mobile_api.py +0 -0
  195. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/project_scanner.py +0 -0
  196. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/review_agent.py +0 -0
  197. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/tool_executor.py +0 -0
  198. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/services/tool_registry.py +0 -0
  199. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/activity.js +0 -0
  200. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/agents.js +0 -0
  201. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/app.js +0 -0
  202. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/busy.js +0 -0
  203. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/chat/conversations.js +0 -0
  204. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/chat/input.js +0 -0
  205. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/chat/markdown.js +0 -0
  206. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/chat/send.js +0 -0
  207. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/chat/stream_renderer.js +0 -0
  208. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/chat/toolbar.js +0 -0
  209. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/core.js +0 -0
  210. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/crossgraph.js +0 -0
  211. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/header.js +0 -0
  212. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/insights.js +0 -0
  213. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/projects.js +0 -0
  214. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/qrcode.js +0 -0
  215. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/settings.js +0 -0
  216. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/suggestions.js +0 -0
  217. {code_context_control-2.145.2 → code_context_control-2.146.0}/oracle/ui/theme_tabs.js +0 -0
  218. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/__init__.py +0 -0
  219. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/access_guard.py +0 -0
  220. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/access_telemetry.py +0 -0
  221. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/agent_base.py +0 -0
  222. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/agent_downshift.py +0 -0
  223. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/agent_locks.py +0 -0
  224. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/agents.py +0 -0
  225. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/agents_workflow.py +0 -0
  226. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/artifact_defs.py +0 -0
  227. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/artifact_store.py +0 -0
  228. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/atomic_json.py +0 -0
  229. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/auto_memory.py +0 -0
  230. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/background_service.py +0 -0
  231. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/bench/__init__.py +0 -0
  232. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/bench/delegate_eval.py +0 -0
  233. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/bench/delegate_write_eval.py +0 -0
  234. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/bench/external/__init__.py +0 -0
  235. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/bench/external/aider_polyglot.py +0 -0
  236. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/bench/external/swe_bench.py +0 -0
  237. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/bench/map_eval.py +0 -0
  238. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/bench/search_eval.py +0 -0
  239. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/bench/shell_eval.py +0 -0
  240. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/benchmark_dashboard.py +0 -0
  241. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/bitbucket_client.py +0 -0
  242. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/bitbucket_credentials.py +0 -0
  243. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/ci_cache.py +0 -0
  244. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/ci_expr.py +0 -0
  245. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/ci_failures.py +0 -0
  246. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/ci_github.py +0 -0
  247. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/ci_impact.py +0 -0
  248. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/ci_intel.py +0 -0
  249. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/ci_runner.py +0 -0
  250. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/circuit_breaker.py +0 -0
  251. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/claude_md.py +0 -0
  252. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/codex_integration.py +0 -0
  253. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/codex_transcript.py +0 -0
  254. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/compressor.py +0 -0
  255. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/context_snapshot.py +0 -0
  256. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/conversation_store.py +0 -0
  257. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/cred_audit.py +0 -0
  258. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/cred_telemetry.py +0 -0
  259. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/delegate_agents.py +0 -0
  260. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/delegate_hints.py +0 -0
  261. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/delegate_write.py +0 -0
  262. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/dir_map.py +0 -0
  263. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/doc_index.py +0 -0
  264. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/e2e_benchmark.py +0 -0
  265. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/e2e_evaluator.py +0 -0
  266. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/e2e_tasks.py +0 -0
  267. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/edit_ledger.py +0 -0
  268. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/embedding_index.py +0 -0
  269. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/enforcement_policy.py +0 -0
  270. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/error_reporting.py +0 -0
  271. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/file_map.py +0 -0
  272. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/file_memory.py +0 -0
  273. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/git_context.py +0 -0
  274. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/grok_integration.py +0 -0
  275. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/grok_transcript.py +0 -0
  276. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/host_sessions.py +0 -0
  277. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/hub_service.py +0 -0
  278. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/index_store.py +0 -0
  279. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/indexer.py +0 -0
  280. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/jira_client.py +0 -0
  281. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/jira_cloud.py +0 -0
  282. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/jira_credentials.py +0 -0
  283. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/jira_data_center.py +0 -0
  284. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/jira_links.py +0 -0
  285. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/lexical_index.py +0 -0
  286. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/mask_activation.py +0 -0
  287. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/mask_mirror.py +0 -0
  288. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/mask_presets.py +0 -0
  289. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/memory.py +0 -0
  290. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/memory_consolidator.py +0 -0
  291. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/memory_distiller.py +0 -0
  292. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/memory_graph.py +0 -0
  293. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/memory_grounder.py +0 -0
  294. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/memory_queue.py +0 -0
  295. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/memory_scorer.py +0 -0
  296. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/metrics.py +0 -0
  297. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/notifications.py +0 -0
  298. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/ollama_bridge.py +0 -0
  299. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/ollama_client.py +0 -0
  300. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/ollama_credentials.py +0 -0
  301. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/oracle_service.py +0 -0
  302. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/output_filter.py +0 -0
  303. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/override_costs.py +0 -0
  304. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/override_grants.py +0 -0
  305. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/override_policy.py +0 -0
  306. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/override_requests.py +0 -0
  307. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/override_wake.py +0 -0
  308. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/parser.py +0 -0
  309. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/project_runtime.py +0 -0
  310. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/protocol.py +0 -0
  311. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/proxy_state.py +0 -0
  312. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/repo_map.py +0 -0
  313. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/repo_shape.py +0 -0
  314. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/reranker.py +0 -0
  315. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/retention.py +0 -0
  316. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/retrieval.py +0 -0
  317. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/retrieval_broker.py +0 -0
  318. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/router.py +0 -0
  319. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/runtime.py +0 -0
  320. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/scanner.py +0 -0
  321. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/session_benchmark.py +0 -0
  322. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/session_live.py +0 -0
  323. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/session_manager.py +0 -0
  324. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/session_preloader.py +0 -0
  325. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/shell_jobs.py +0 -0
  326. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/shell_output.py +0 -0
  327. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/subprojects.py +0 -0
  328. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/task_store.py +0 -0
  329. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/telemetry.py +0 -0
  330. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/terminal_launch.py +0 -0
  331. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/text_index.py +0 -0
  332. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/time_tracker.py +0 -0
  333. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/tool_classifier.py +0 -0
  334. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/transcript_index.py +0 -0
  335. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/validation_cache.py +0 -0
  336. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/vector_store.py +0 -0
  337. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/watcher.py +0 -0
  338. {code_context_control-2.145.2 → code_context_control-2.146.0}/services/win_subprocess.py +0 -0
  339. {code_context_control-2.145.2 → code_context_control-2.146.0}/setup.cfg +0 -0
  340. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_access_builtin_optout.py +0 -0
  341. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_access_guard.py +0 -0
  342. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_access_guard_meta.py +0 -0
  343. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_access_guard_shell_project.py +0 -0
  344. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_access_guard_surfaces.py +0 -0
  345. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_access_guard_wiring.py +0 -0
  346. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_activity_reporter.py +0 -0
  347. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_agent_locks.py +0 -0
  348. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_aider_polyglot.py +0 -0
  349. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_antigravity_transition.py +0 -0
  350. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_artifact_store.py +0 -0
  351. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_artifact_tool.py +0 -0
  352. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_atomic_json.py +0 -0
  353. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_background_service.py +0 -0
  354. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_bitbucket_cli_smoke.py +0 -0
  355. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_bitbucket_client.py +0 -0
  356. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_bitbucket_config_fallback.py +0 -0
  357. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_bitbucket_credentials.py +0 -0
  358. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_bitbucket_tool.py +0 -0
  359. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_builtin_modes.py +0 -0
  360. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
  361. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_c3_shell.py +0 -0
  362. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_chat_poll.py +0 -0
  363. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_ci_cache.py +0 -0
  364. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_ci_dag_ownership.py +0 -0
  365. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_ci_expr.py +0 -0
  366. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_ci_impact.py +0 -0
  367. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_ci_intel.py +0 -0
  368. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_ci_runner.py +0 -0
  369. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_ci_workflow.py +0 -0
  370. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_circuit_breaker.py +0 -0
  371. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_claude_md_merge.py +0 -0
  372. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_claude_md_updater.py +0 -0
  373. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_cli_smoke.py +0 -0
  374. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_codex_mcp_transport.py +0 -0
  375. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_codex_native.py +0 -0
  376. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_compressor_large_file.py +0 -0
  377. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_confirm_guard.py +0 -0
  378. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_confirm_guard_wiring.py +0 -0
  379. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_cooccurrence_bounds.py +0 -0
  380. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_cred_telemetry.py +0 -0
  381. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_credential_backup.py +0 -0
  382. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_credential_login_kind.py +0 -0
  383. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_credential_ui_parity.py +0 -0
  384. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_credentials_routes.py +0 -0
  385. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_credentials_tool.py +0 -0
  386. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_creds_cli_smoke.py +0 -0
  387. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_delegate_adoption_d4.py +0 -0
  388. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_delegate_auto.py +0 -0
  389. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_delegate_cascade.py +0 -0
  390. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_delegate_claude_d1.py +0 -0
  391. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_delegate_eval.py +0 -0
  392. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_delegate_grok.py +0 -0
  393. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_delegate_host_d2.py +0 -0
  394. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_delegate_scout_d3.py +0 -0
  395. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_delegate_telemetry_d0.py +0 -0
  396. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_delegate_thinking_cap.py +0 -0
  397. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_delegate_tuning.py +0 -0
  398. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_delegate_version_probe.py +0 -0
  399. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_delegate_write.py +0 -0
  400. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_delegate_write_eval.py +0 -0
  401. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_dir_map_c3.py +0 -0
  402. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_e2e_benchmark.py +0 -0
  403. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_edit_ledger_deadline.py +0 -0
  404. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_edit_ledger_hook.py +0 -0
  405. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_edit_locking.py +0 -0
  406. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_edit_normalization.py +0 -0
  407. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_edit_verify.py +0 -0
  408. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_embedding_index_corrupt_store.py +0 -0
  409. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_embedding_index_deadlock.py +0 -0
  410. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_enforcement_flip.py +0 -0
  411. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_enforcement_policy.py +0 -0
  412. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_enforcement_routes.py +0 -0
  413. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_env_parser.py +0 -0
  414. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_failed_calls_do_not_unlock.py +0 -0
  415. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_federated_graph.py +0 -0
  416. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_file_map_c1.py +0 -0
  417. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_filter_backoff.py +0 -0
  418. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_ghost_files.py +0 -0
  419. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_ghost_generation.py +0 -0
  420. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_git_branch_awareness.py +0 -0
  421. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_grok_native.py +0 -0
  422. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hook_access_guard.py +0 -0
  423. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hook_codex_compat.py +0 -0
  424. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hook_dispatch.py +0 -0
  425. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hook_grok_compat.py +0 -0
  426. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hook_pretool_enforce.py +0 -0
  427. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hook_prompt_recall.py +0 -0
  428. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hook_session_end.py +0 -0
  429. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hook_smoke.py +0 -0
  430. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hook_state.py +0 -0
  431. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hook_utf8_stdio.py +0 -0
  432. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hub_credentials_route.py +0 -0
  433. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hub_hook_migration.py +0 -0
  434. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hub_inspect_api.py +0 -0
  435. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hub_oracle_service_routes.py +0 -0
  436. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hub_override_policy_routes.py +0 -0
  437. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hub_override_routes.py +0 -0
  438. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hub_server_smoke.py +0 -0
  439. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_hub_subproject_links.py +0 -0
  440. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_ide_workflow_adaptation.py +0 -0
  441. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_index_cap_not_hardcoded.py +0 -0
  442. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_init_clear_preserves_user_content.py +0 -0
  443. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_init_scan.py +0 -0
  444. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_install_mcp_entrypoint.py +0 -0
  445. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_jira_cli_smoke.py +0 -0
  446. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_jira_client.py +0 -0
  447. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_jira_config_fallback.py +0 -0
  448. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_jira_credentials.py +0 -0
  449. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_jira_links.py +0 -0
  450. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_jira_routes.py +0 -0
  451. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_jira_tool.py +0 -0
  452. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_large_files_c4.py +0 -0
  453. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_lazy_store_init.py +0 -0
  454. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_map_eval.py +0 -0
  455. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_map_telemetry_c0.py +0 -0
  456. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_mask_guard.py +0 -0
  457. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_mask_routes.py +0 -0
  458. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_mask_surfaces.py +0 -0
  459. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_mcp_host_guard.py +0 -0
  460. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_mcp_memory_timeout.py +0 -0
  461. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_mcp_server_smoke.py +0 -0
  462. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_mcp_toml.py +0 -0
  463. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_memory_distiller.py +0 -0
  464. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_memory_graph_api.py +0 -0
  465. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_memory_queue.py +0 -0
  466. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_memory_system.py +0 -0
  467. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_mobile_api.py +0 -0
  468. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_mobile_clients.py +0 -0
  469. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_mobile_extras.py +0 -0
  470. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_mobile_jobs_ci.py +0 -0
  471. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_mobile_override_costs.py +0 -0
  472. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_mobile_override_routes.py +0 -0
  473. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_mobile_security_api.py +0 -0
  474. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_no_stale_model_pins.py +0 -0
  475. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_notification_dedup.py +0 -0
  476. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_notification_discipline.py +0 -0
  477. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_notification_kinds.py +0 -0
  478. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_ollama_credentials.py +0 -0
  479. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_oracle_api_auth.py +0 -0
  480. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_oracle_apikey_api.py +0 -0
  481. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_oracle_c3_bridge.py +0 -0
  482. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_oracle_chat_engine.py +0 -0
  483. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_oracle_chat_store.py +0 -0
  484. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_oracle_discovery_api.py +0 -0
  485. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_oracle_discovery_audit.py +0 -0
  486. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_oracle_health_probe.py +0 -0
  487. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_oracle_local_auth.py +0 -0
  488. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_oracle_loopback.py +0 -0
  489. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_oracle_ollama_bridge.py +0 -0
  490. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_oracle_scanner_cache.py +0 -0
  491. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_oracle_security_fixes.py +0 -0
  492. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_oracle_session_bootstrap.py +0 -0
  493. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_oracle_subproject_awareness.py +0 -0
  494. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_oracle_ui_bundle.py +0 -0
  495. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_output_filter.py +0 -0
  496. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_override_costs.py +0 -0
  497. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_override_grants.py +0 -0
  498. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_override_grants_mcp.py +0 -0
  499. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_override_requests.py +0 -0
  500. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_override_wake.py +0 -0
  501. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_permissions.py +0 -0
  502. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_pm_api.py +0 -0
  503. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_project_manager.py +0 -0
  504. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_project_manager_merge.py +0 -0
  505. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_project_tool.py +0 -0
  506. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_read_coercion.py +0 -0
  507. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_read_edit_parity.py +0 -0
  508. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_read_outside_root.py +0 -0
  509. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_related_facts.py +0 -0
  510. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_repo_map.py +0 -0
  511. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_repo_shape.py +0 -0
  512. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_response_boilerplate.py +0 -0
  513. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_retention.py +0 -0
  514. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_review_digest.py +0 -0
  515. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_search_eval.py +0 -0
  516. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_search_p1.py +0 -0
  517. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_search_p2.py +0 -0
  518. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_search_p2b.py +0 -0
  519. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_search_p3.py +0 -0
  520. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_search_p4.py +0 -0
  521. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_search_p5.py +0 -0
  522. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_service_durability.py +0 -0
  523. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_session_benchmark.py +0 -0
  524. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_session_budget.py +0 -0
  525. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_session_live.py +0 -0
  526. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_session_tool.py +0 -0
  527. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_shell_budget_s1.py +0 -0
  528. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_shell_creds.py +0 -0
  529. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_shell_eval.py +0 -0
  530. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_shell_jobs_s3.py +0 -0
  531. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_shell_nudge_s4.py +0 -0
  532. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_shell_output.py +0 -0
  533. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_shell_parsers_s2.py +0 -0
  534. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_shell_robustness.py +0 -0
  535. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_shell_telemetry_s0.py +0 -0
  536. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_shell_write_ledger.py +0 -0
  537. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_shell_writes.py +0 -0
  538. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_subproject_clear_scope.py +0 -0
  539. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_subproject_depth_consumers.py +0 -0
  540. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_subproject_exclusion.py +0 -0
  541. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_subproject_federation.py +0 -0
  542. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_subproject_linkage_api.py +0 -0
  543. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_subprojects.py +0 -0
  544. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_swe_bench.py +0 -0
  545. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_task_store.py +0 -0
  546. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_task_tool.py +0 -0
  547. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_time_tracker.py +0 -0
  548. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_token_telemetry.py +0 -0
  549. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_tool_registry.py +0 -0
  550. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_ui_jsx_syntax.py +0 -0
  551. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_upgrade_and_version.py +0 -0
  552. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_validate.py +0 -0
  553. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_vault_write_guard.py +0 -0
  554. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_version_sync.py +0 -0
  555. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_watcher_pruning.py +0 -0
  556. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_web_security.py +0 -0
  557. {code_context_control-2.145.2 → code_context_control-2.146.0}/tests/test_windows_reliability.py +0 -0
  558. {code_context_control-2.145.2 → code_context_control-2.146.0}/tui/__init__.py +0 -0
  559. {code_context_control-2.145.2 → code_context_control-2.146.0}/tui/backend.py +0 -0
  560. {code_context_control-2.145.2 → code_context_control-2.146.0}/tui/main.py +0 -0
  561. {code_context_control-2.145.2 → code_context_control-2.146.0}/tui/screens/__init__.py +0 -0
  562. {code_context_control-2.145.2 → code_context_control-2.146.0}/tui/screens/benchmark_view.py +0 -0
  563. {code_context_control-2.145.2 → code_context_control-2.146.0}/tui/screens/claudemd_view.py +0 -0
  564. {code_context_control-2.145.2 → code_context_control-2.146.0}/tui/screens/compress_view.py +0 -0
  565. {code_context_control-2.145.2 → code_context_control-2.146.0}/tui/screens/index_view.py +0 -0
  566. {code_context_control-2.145.2 → code_context_control-2.146.0}/tui/screens/init_view.py +0 -0
  567. {code_context_control-2.145.2 → code_context_control-2.146.0}/tui/screens/mcp_view.py +0 -0
  568. {code_context_control-2.145.2 → code_context_control-2.146.0}/tui/screens/optimize_view.py +0 -0
  569. {code_context_control-2.145.2 → code_context_control-2.146.0}/tui/screens/pipe_view.py +0 -0
  570. {code_context_control-2.145.2 → code_context_control-2.146.0}/tui/screens/projects_view.py +0 -0
  571. {code_context_control-2.145.2 → code_context_control-2.146.0}/tui/screens/search_view.py +0 -0
  572. {code_context_control-2.145.2 → code_context_control-2.146.0}/tui/screens/session_view.py +0 -0
  573. {code_context_control-2.145.2 → code_context_control-2.146.0}/tui/screens/stats.py +0 -0
  574. {code_context_control-2.145.2 → code_context_control-2.146.0}/tui/screens/ui_view.py +0 -0
  575. {code_context_control-2.145.2 → code_context_control-2.146.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.145.2
3
+ Version: 2.146.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.145.2"
94
+ __version__ = "2.146.0"
95
95
 
96
96
  # The PreToolUse matcher for native subagent calls (installer and hub migration).
97
97
  AGENT_MATCHER = "Agent|Task"
@@ -6685,10 +6685,10 @@ def _creds_cmd_list(args, project_path: str) -> None:
6685
6685
  "(add --global for all projects).")
6686
6686
  return
6687
6687
  print(f"{len(entries)} credential(s) — project scope shadows global:")
6688
+ present = cred_store.presence_for(entries, project_path)
6688
6689
  missing = 0
6689
6690
  for name, entry in entries.items():
6690
- gone = not cred_store.is_resolvable(
6691
- name, project_path=project_path, scope=entry["scope"])
6691
+ gone = not present[name]
6692
6692
  missing += gone
6693
6693
  print(" " + _creds_entry_line(name, entry, gone))
6694
6694
  if missing:
@@ -1804,7 +1804,7 @@ def api_projects_browse():
1804
1804
  return jsonify({"error": str(e)}), 400
1805
1805
  if not resolved.is_dir():
1806
1806
  return jsonify({"error": f"Not a directory: {resolved}"}), 404
1807
- registered = {os.path.normcase(p.get("path", "")) for p in _pm()._read_projects()}
1807
+ registered = {os.path.normcase(p.get("path", "")) for p in _pm().list_registered()}
1808
1808
  dirs = []
1809
1809
  try:
1810
1810
  for child in sorted(resolved.iterdir(), key=lambda c: c.name.lower()):
@@ -1913,7 +1913,7 @@ def api_search_global():
1913
1913
  if wanted else None)
1914
1914
 
1915
1915
  candidates, skipped = [], []
1916
- for p in _pm().list_projects():
1916
+ for p in _pm().list_registered():
1917
1917
  ppath = p.get("path") or ""
1918
1918
  if wanted_norm is not None and os.path.normcase(ppath) not in wanted_norm:
1919
1919
  continue
@@ -2138,14 +2138,15 @@ def api_projects_credentials():
2138
2138
  usage = cred_store.read_usage_state(str(resolved))
2139
2139
  home = cred_store.global_base()
2140
2140
  global_names = set(cred_store.list_entries(str(home))) if home else set()
2141
+ listed = cred_store.list_entries(str(resolved))
2142
+ present = cred_store.presence_for(listed, str(resolved))
2141
2143
  entries = []
2142
- for name, entry in cred_store.list_entries(str(resolved)).items():
2144
+ for name, entry in listed.items():
2143
2145
  entries.append(_cred_entry_public(
2144
2146
  name, entry, usage=usage,
2145
2147
  shadows_global=(entry.get("scope") == "project"
2146
2148
  and name in global_names),
2147
- value_ok=cred_store.is_resolvable(
2148
- name, project_path=str(resolved), scope=entry["scope"])))
2149
+ value_ok=present[name]))
2149
2150
  return jsonify({"path": str(resolved), "entries": entries})
2150
2151
 
2151
2152
 
@@ -2360,7 +2361,7 @@ def api_hub_credentials_audit():
2360
2361
  only_global = (request.args.get("scope") or "").strip().lower() == "global"
2361
2362
 
2362
2363
  events, errors = [], []
2363
- for p in ([] if only_global else _pm().list_projects()):
2364
+ for p in ([] if only_global else _pm().list_registered()):
2364
2365
  ppath = str(p.get("path") or "")
2365
2366
  if not (Path(ppath) / ".c3").is_dir():
2366
2367
  continue
@@ -2417,9 +2418,12 @@ def api_hub_credentials_overview():
2417
2418
  from services import credential_store as cred_store
2418
2419
  home = cred_store.global_base()
2419
2420
  global_entries = cred_store.list_entries(str(home)) if home else {}
2421
+ # realm -> {name: value decodes}, probed once per vault and shared with
2422
+ # the backup banner, which asks the same question of the same entries.
2423
+ present = {"global": cred_store.value_presence("global", str(home))} if home else {}
2420
2424
  shadowed_in = {name: [] for name in global_entries}
2421
2425
  projects_out = []
2422
- for p in _pm().list_projects():
2426
+ for p in _pm().list_registered():
2423
2427
  ppath = str(p.get("path") or "")
2424
2428
  row = {"name": p.get("name") or "", "path": ppath,
2425
2429
  "initialized": True, "error": None, "entries": []}
@@ -2428,14 +2432,15 @@ def api_hub_credentials_overview():
2428
2432
  row["initialized"] = False
2429
2433
  else:
2430
2434
  usage = cred_store.read_usage_state(ppath)
2435
+ ok = cred_store.value_presence("project", ppath)
2436
+ present[cred_store.realm("project", ppath)] = ok
2431
2437
  for name, entry in cred_store.list_entries(ppath).items():
2432
2438
  if entry.get("scope") != "project":
2433
2439
  continue
2434
2440
  row["entries"].append(_cred_entry_public(
2435
2441
  name, entry, usage=usage,
2436
2442
  shadows_global=name in global_entries,
2437
- value_ok=cred_store.is_resolvable(
2438
- name, project_path=ppath, scope="project")))
2443
+ value_ok=ok.get(name, False)))
2439
2444
  if name in shadowed_in:
2440
2445
  shadowed_in[name].append(
2441
2446
  {"name": row["name"], "path": ppath})
@@ -2446,21 +2451,21 @@ def api_hub_credentials_overview():
2446
2451
  global_out = [
2447
2452
  {**_cred_entry_public(
2448
2453
  name, entry, usage=global_usage,
2449
- value_ok=cred_store.is_resolvable(
2450
- name, project_path=str(home), scope="global")),
2454
+ value_ok=present.get("global", {}).get(name, False)),
2451
2455
  "shadowed_in": shadowed_in.get(name, [])}
2452
2456
  for name, entry in global_entries.items()
2453
2457
  ]
2454
2458
  return jsonify({"global": {"entries": global_out}, "projects": projects_out,
2455
2459
  "backup": _cred_backup_summary(
2456
- [row["path"] for row in projects_out if row["initialized"]])})
2460
+ [row["path"] for row in projects_out if row["initialized"]],
2461
+ present)})
2457
2462
 
2458
2463
 
2459
- def _cred_backup_summary(project_paths) -> dict:
2464
+ def _cred_backup_summary(project_paths, present) -> dict:
2460
2465
  """Backup state as counts for the Hub banner; a broken file reports its error."""
2461
2466
  from services import credential_backup
2462
2467
  try:
2463
- st = credential_backup.status(project_paths)
2468
+ st = credential_backup.status(project_paths, presence=present)
2464
2469
  except credential_backup.BackupError as exc:
2465
2470
  return {"enabled": True, "error": str(exc), "restorable": 0, "lost": 0}
2466
2471
  return {"enabled": st["enabled"], "restorable": len(st["restorable"]),
@@ -2612,7 +2617,7 @@ def api_hub_tokens_overview():
2612
2617
  days = _hub_tokens_days(request.args.get("days"))
2613
2618
  rows, totals = [], {"tool_calls": 0, "tool_tokens": 0,
2614
2619
  "session_tokens": 0, "saved": 0}
2615
- for p in _pm().list_projects():
2620
+ for p in _pm().list_registered():
2616
2621
  ppath = str(p.get("path") or "")
2617
2622
  row = {"name": p.get("name") or "", "path": ppath, "initialized": True,
2618
2623
  "error": None, "tool_calls": 0, "tool_tokens": 0,
@@ -2662,7 +2667,7 @@ def api_hub_locks_overview():
2662
2667
  from services import agent_locks as al
2663
2668
 
2664
2669
  rows, total = [], 0
2665
- for p in _pm().list_projects():
2670
+ for p in _pm().list_registered():
2666
2671
  ppath = str(p.get("path") or "")
2667
2672
  row = {"name": p.get("name") or "", "path": ppath, "initialized": True,
2668
2673
  "error": None, "enabled": True, "mode": "advisory",
@@ -2752,7 +2757,7 @@ def api_hub_enforcement_overview():
2752
2757
 
2753
2758
  rows = []
2754
2759
  totals = {"discipline": 0, "access": 0}
2755
- for p in _pm().list_projects():
2760
+ for p in _pm().list_registered():
2756
2761
  ppath = str(p.get("path") or "")
2757
2762
  row = {"name": p.get("name") or "", "path": ppath, "initialized": True,
2758
2763
  "error": None, "mode": None, "scope": "", "set_by": "",
@@ -3428,7 +3433,7 @@ def api_hub_override_policy_overview():
3428
3433
  from services import override_policy as opol
3429
3434
 
3430
3435
  rows = []
3431
- for p in _pm().list_projects():
3436
+ for p in _pm().list_registered():
3432
3437
  ppath = str(p.get("path") or "")
3433
3438
  row = {"name": p.get("name") or Path(ppath).name, "path": ppath,
3434
3439
  "initialized": True, "error": None, "policy": None,
@@ -3740,7 +3745,7 @@ def api_hub_access_overview():
3740
3745
  empty = {"deny": [], "read_only": [], "confirm": [], "mask": 0,
3741
3746
  "corrupt": False}
3742
3747
  rows = []
3743
- for p in _pm().list_projects():
3748
+ for p in _pm().list_registered():
3744
3749
  ppath = str(p.get("path") or "")
3745
3750
  row = {"name": p.get("name") or Path(ppath).name, "path": ppath,
3746
3751
  "initialized": True, "error": None, "rules": dict(empty)}
@@ -4268,7 +4273,7 @@ def api_pm_global():
4268
4273
  from services.task_store import TaskStore
4269
4274
 
4270
4275
  tasks, skipped, by_project = [], [], {}
4271
- entries = _pm()._read_projects()
4276
+ entries = _pm().list_registered()
4272
4277
  for p in entries:
4273
4278
  ppath = p.get("path") or ""
4274
4279
  if not Path(ppath).is_dir():
@@ -4808,7 +4813,7 @@ def _session_project(raw: str):
4808
4813
  if not raw:
4809
4814
  return None
4810
4815
  want = os.path.normcase(os.path.normpath(raw))
4811
- for p in _pm().list_projects():
4816
+ for p in _pm().list_registered():
4812
4817
  path = str(p.get("path") or "")
4813
4818
  if path and os.path.normcase(os.path.normpath(path)) == want:
4814
4819
  return {"name": str(p.get("name") or Path(path).name), "path": path}
@@ -4847,7 +4852,7 @@ def api_hub_sessions_overview():
4847
4852
  return row
4848
4853
 
4849
4854
  with ThreadPoolExecutor(max_workers=8) as pool:
4850
- rows = list(pool.map(one, _pm().list_projects()))
4855
+ rows = list(pool.map(one, _pm().list_registered()))
4851
4856
  rows.sort(key=lambda r: r.get("last_active") or "", reverse=True)
4852
4857
  return jsonify({"projects": rows, "features": _SESSIONS_FEATURES})
4853
4858
 
@@ -4876,7 +4881,7 @@ def api_hub_sessions_list():
4876
4881
  res["errors"] = []
4877
4882
  else:
4878
4883
  projects = [{"name": str(p.get("name") or ""), "path": str(p.get("path") or "")}
4879
- for p in _pm().list_projects()]
4884
+ for p in _pm().list_registered()]
4880
4885
  res = sc.list_many(projects, stale=stale, q=q, limit=limit, before=before)
4881
4886
  return jsonify(res)
4882
4887
  except Exception as e:
@@ -50,7 +50,10 @@ function App() {
50
50
  }, []);
51
51
 
52
52
  useEffect(() => { loadConfig(); loadProjects(); }, []);
53
- usePoll(loadProjects, 5000);
53
+ // Live status matters on the project list and in a drill-in. Elsewhere it
54
+ // only refreshes the sidebar and top-bar counts, which may lag 30 s, and
55
+ // each poll reads every project's activity log.
56
+ usePoll(loadProjects, mainView === 'projects' || drill ? 5000 : 30000);
54
57
 
55
58
  // Persisted preferences
56
59
  const toggleTheme = () => {
@@ -1381,7 +1381,10 @@ function CredSourcesStrip({ sources, onResync, busy }) {
1381
1381
 
1382
1382
  // path=null → the global vault (~/.c3): scope locked to 'global'.
1383
1383
  // path=string → that project's merged view (global entries + project shadows).
1384
- function CredsManager({ path, projectName, onChanged, bindSlash }) {
1384
+ // Global vault (path null): rows arrive as `globalEntries` (null while the
1385
+ // page's overview loads) and `onChanged` refills them; loading the overview
1386
+ // here as well fetched the whole cross-project index twice.
1387
+ function CredsManager({ path, projectName, onChanged, bindSlash, globalEntries }) {
1385
1388
  const isGlobal = !path;
1386
1389
  const [entries, setEntries] = useState([]);
1387
1390
  const [loading, setLoading] = useState(true);
@@ -1408,14 +1411,10 @@ function CredsManager({ path, projectName, onChanged, bindSlash }) {
1408
1411
  const withPath = (obj) => (path ? Object.assign({ path }, obj) : obj);
1409
1412
 
1410
1413
  const load = useCallback(async () => {
1414
+ if (!path) return;
1411
1415
  try {
1412
- if (path) {
1413
- const data = await api.get('/api/projects/credentials?path=' + encodeURIComponent(path));
1414
- setEntries((data && data.entries) || []);
1415
- } else {
1416
- const data = await api.get('/api/hub/credentials/overview');
1417
- setEntries((((data || {}).global) || {}).entries || []);
1418
- }
1416
+ const data = await credApi.listProject(path);
1417
+ setEntries((data && data.entries) || []);
1419
1418
  setError('');
1420
1419
  } catch (e) { setError(String(e)); }
1421
1420
  setLoading(false);
@@ -1426,6 +1425,14 @@ function CredsManager({ path, projectName, onChanged, bindSlash }) {
1426
1425
  load();
1427
1426
  }, [load]);
1428
1427
 
1428
+ useEffect(() => {
1429
+ if (path) return;
1430
+ setEntries(globalEntries || []);
1431
+ setLoading(globalEntries == null);
1432
+ }, [path, globalEntries]);
1433
+
1434
+ const refresh = () => { load(); if (onChanged) onChanged(); };
1435
+
1429
1436
  // `/` focuses the filter, as it does on every other hub board — but only
1430
1437
  // where nothing above already claims the key. The hub Credentials page owns
1431
1438
  // `/` for its cross-project search, so the manager binds it solely when
@@ -1447,7 +1454,7 @@ function CredsManager({ path, projectName, onChanged, bindSlash }) {
1447
1454
  return () => window.removeEventListener('keydown', onKey);
1448
1455
  }, [bindSlash, drawer, menu, confirm]);
1449
1456
 
1450
- const done = (msg) => { notify(msg); load(); if (onChanged) onChanged(); };
1457
+ const done = (msg) => { notify(msg); refresh(); };
1451
1458
 
1452
1459
  const saveForm = async () => {
1453
1460
  if (!form || !form.name.trim()) return;
@@ -1507,8 +1514,7 @@ function CredsManager({ path, projectName, onChanged, bindSlash }) {
1507
1514
  if (resp && resp.error) setError(resp.error);
1508
1515
  else {
1509
1516
  notify(`${field === 'inject' ? 'Auto-inject' : 'Agent access'} ${next ? 'enabled' : 'disabled'} for '${entry.name}'`);
1510
- load();
1511
- if (onChanged) onChanged();
1517
+ refresh();
1512
1518
  }
1513
1519
  } catch (e) { setError(apiErr(e)); }
1514
1520
  };
@@ -1619,7 +1625,7 @@ function CredsManager({ path, projectName, onChanged, bindSlash }) {
1619
1625
  } else {
1620
1626
  notify(`${label}: ${ok} ${ok === 1 ? 'entry' : 'entries'}`);
1621
1627
  }
1622
- if (action !== 'check') { exitSelect(); load(); if (onChanged) onChanged(); }
1628
+ if (action !== 'check') { exitSelect(); refresh(); }
1623
1629
  } catch (e) { notify(apiErr(e), 'err'); }
1624
1630
  setBulkBusy(false);
1625
1631
  };
@@ -2012,7 +2018,7 @@ function CredsManager({ path, projectName, onChanged, bindSlash }) {
2012
2018
  <CredDrawer entry={drawer} path={path} projectName={projectName}
2013
2019
  initialReplace={replaceOnOpen}
2014
2020
  onClose={() => { setDrawer(null); setReplaceOnOpen(false); }}
2015
- onChanged={() => { load(); if (onChanged) onChanged(); }} />
2021
+ onChanged={refresh} />
2016
2022
  )}
2017
2023
  {confirm && <CredConfirm spec={confirm} onClose={() => setConfirm(null)} />}
2018
2024
  </div>
@@ -2420,7 +2426,8 @@ function HubCredentials({ projects, onOpenDrill }) {
2420
2426
  <CredAuditView path={null} initialName={auditName}
2421
2427
  onOpenDrill={onOpenDrill} />
2422
2428
  ) : sub === 'global' ? (
2423
- <CredsManager path={null} onChanged={loadOverview} />
2429
+ <CredsManager path={null} onChanged={loadOverview}
2430
+ globalEntries={ov ? ((ov.global || {}).entries || []) : null} />
2424
2431
  ) : !ov ? (
2425
2432
  <div style={{ color: T.textMuted, fontSize: 13 }}>Loading…</div>
2426
2433
  ) : (ov.projects || []).length === 0 ? (
@@ -24,11 +24,15 @@ const IDE_OPTIONS = [
24
24
 
25
25
  const ideLabel = (ide) => IDE_LABELS[ide] || ide || 'unknown';
26
26
 
27
- // Repeating poll that pauses while the tab is hidden.
27
+ // Repeating poll that pauses while the tab is hidden and skips a tick while
28
+ // the previous call is still running, so a slow route never stacks requests.
28
29
  const usePoll = (fn, ms) => {
29
30
  React.useEffect(() => {
30
- const iv = setInterval(() => {
31
- if (!document.hidden) fn();
31
+ let running = false;
32
+ const iv = setInterval(async () => {
33
+ if (document.hidden || running) return;
34
+ running = true;
35
+ try { await fn(); } finally { running = false; }
32
36
  }, ms);
33
37
  return () => clearInterval(iv);
34
38
  }, [fn, ms]);
@@ -137,7 +137,7 @@
137
137
 
138
138
  <body>
139
139
  <div id="root"></div>
140
- <script type="text/babel">
140
+ <script type="text/babel" data-presets="react">
141
141
  /* __C3_HUB_SCRIPTS__ */
142
142
  </script>
143
143
  </body>
@@ -2764,12 +2764,12 @@ def api_credentials_list():
2764
2764
  from services import credential_store as cred_store
2765
2765
  pp = str(PROJECT_PATH)
2766
2766
  usage = cred_store.read_usage_state(pp)
2767
+ listed = cred_store.list_entries(pp)
2768
+ present = cred_store.presence_for(listed, pp)
2767
2769
  out = []
2768
- for name, entry in cred_store.list_entries(pp).items():
2770
+ for name, entry in listed.items():
2769
2771
  out.append(cred_store.public_entry(
2770
- name, entry, usage=usage,
2771
- value_ok=cred_store.is_resolvable(
2772
- name, project_path=pp, scope=entry["scope"])))
2772
+ name, entry, usage=usage, value_ok=present[name]))
2773
2773
  return jsonify({"entries": out})
2774
2774
 
2775
2775
 
@@ -98,8 +98,7 @@ def _act_list(project_path: str) -> str:
98
98
  "The user manages them via the Credentials UI tab or `c3 creds set`."
99
99
  )
100
100
  usage = cs.read_usage_state(project_path)
101
- missing = {n for n, e in entries.items() if not cs.is_resolvable(
102
- n, project_path=project_path, scope=e["scope"])}
101
+ missing = {n for n, ok in cs.presence_for(entries, project_path).items() if not ok}
103
102
  lines = [f"[creds] {len(entries)} entries (project scope shadows global):"]
104
103
  lines += [_format_entry_line(n, e, usage, n in missing)
105
104
  for n, e in entries.items()]
@@ -160,7 +160,7 @@
160
160
 
161
161
  <body>
162
162
  <div id="root"></div>
163
- <script type="text/babel">
163
+ <script type="text/babel" data-presets="react">
164
164
  /* __C3_UI_SCRIPTS__ */
165
165
  </script>
166
166
  </body>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-context-control
3
- Version: 2.145.2
3
+ Version: 2.146.0
4
4
  Summary: Local MCP code-intelligence for AI coding tools: surgical search/read/edit, agent-config version history, path-level access + masking guards, and a multi-project hub.
5
5
  Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "code-context-control"
7
- version = "2.145.2"
7
+ version = "2.146.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"
@@ -1,6 +1,6 @@
1
1
  """ActivityLog — Append-only JSONL activity log for C3 events."""
2
2
  import json
3
- from collections import Counter, deque
3
+ from collections import Counter
4
4
  from datetime import datetime, timezone
5
5
  from pathlib import Path
6
6
 
@@ -75,6 +75,9 @@ class ActivityLog:
75
75
  """
76
76
  if not self.log_file.exists():
77
77
  return []
78
+ # A row of this type holds its JSON-encoded name, so a chunk or line
79
+ # without those bytes cannot match and is skipped unparsed.
80
+ needle = json.dumps(event_type).encode("utf-8")
78
81
  events: list = []
79
82
  try:
80
83
  with open(self.log_file, "rb") as handle:
@@ -86,12 +89,19 @@ class ActivityLog:
86
89
  position -= step
87
90
  handle.seek(position)
88
91
  block = handle.read(step) + tail
89
- lines = block.split(b"\n")
90
- # The first element may be a partial line: keep it for the
91
- # next (earlier) chunk unless we are at the file start.
92
- tail = lines.pop(0) if position > 0 else b""
93
- for raw in reversed(lines):
94
- if not raw.strip():
92
+ # The first line may be partial: keep it for the next
93
+ # (earlier) chunk unless we are at the file start.
94
+ tail = b""
95
+ if position > 0:
96
+ cut = block.find(b"\n")
97
+ if cut < 0:
98
+ tail = block
99
+ continue
100
+ tail, block = block[:cut], block[cut + 1:]
101
+ if needle not in block:
102
+ continue
103
+ for raw in reversed(block.split(b"\n")):
104
+ if needle not in raw:
95
105
  continue
96
106
  try:
97
107
  entry = json.loads(raw.decode("utf-8", "replace"))
@@ -119,15 +129,13 @@ class ActivityLog:
119
129
  # far back in the log behind many tool_call entries. Use a larger scan
120
130
  # window so they aren't missed.
121
131
  scan_factor = 100 if event_type else 5
122
- tail = deque(maxlen=max(1, limit * scan_factor))
123
- with open(self.log_file, encoding="utf-8") as handle:
124
- for line in handle:
125
- if line.strip():
126
- tail.append(line)
127
- for line in reversed(tail):
132
+ needle = json.dumps(event_type).encode("utf-8") if event_type else b""
133
+ for raw in self._tail_lines(max(1, limit * scan_factor)):
134
+ if needle not in raw:
135
+ continue
128
136
  try:
129
- entry = json.loads(line)
130
- except json.JSONDecodeError:
137
+ entry = json.loads(raw)
138
+ except ValueError:
131
139
  continue
132
140
  if event_type and entry.get("type") != event_type:
133
141
  continue
@@ -141,6 +149,26 @@ class ActivityLog:
141
149
  break
142
150
  return events
143
151
 
152
+ def _tail_lines(self, count: int, chunk_bytes: int = 64 * 1024) -> list:
153
+ """The last ``count`` non-blank lines as bytes, newest first."""
154
+ lines: list = []
155
+ with open(self.log_file, "rb") as handle:
156
+ handle.seek(0, 2)
157
+ position = handle.tell()
158
+ tail = b""
159
+ while position > 0 and len(lines) < count:
160
+ step = min(chunk_bytes, position)
161
+ position -= step
162
+ handle.seek(position)
163
+ parts = (handle.read(step) + tail).split(b"\n")
164
+ tail = parts.pop(0) if position > 0 else b""
165
+ for raw in reversed(parts):
166
+ if raw.strip():
167
+ lines.append(raw)
168
+ if len(lines) >= count:
169
+ break
170
+ return lines
171
+
144
172
  def get_stats(self) -> dict:
145
173
  """Counts by event type, total events, time range."""
146
174
  if not self.log_file.exists():
@@ -88,12 +88,33 @@ def _probe(cmd: list, timeout: int = 30) -> tuple:
88
88
  return 127, f"{type(exc).__name__}: {exc}"
89
89
 
90
90
 
91
- def availability() -> dict:
91
+ #: How old an engine probe a display surface may reuse. The hub CI tab
92
+ #: re-inspects every 2-10 s, and each fresh probe spawns act and docker.
93
+ DISPLAY_PROBE_TTL_S = 30.0
94
+ _display_probe: tuple = (0.0, None)
95
+
96
+
97
+ def availability(max_age: float = 0.0) -> dict:
92
98
  """Can this engine run at all? Reports WHY not, never just False.
93
99
 
94
100
  Both halves are checked because they fail independently and a user with
95
101
  act installed but Docker stopped deserves to be told which one to fix.
102
+
103
+ ``max_age`` > 0 reuses a result at most that many seconds old from an
104
+ earlier call that also passed it; the default always probes, which is
105
+ what a run and ``doctor`` need.
96
106
  """
107
+ global _display_probe
108
+ if max_age <= 0:
109
+ return _probe_engine()
110
+ at, info = _display_probe
111
+ if info is None or time.monotonic() - at > max_age:
112
+ info = _probe_engine()
113
+ _display_probe = (time.monotonic(), info)
114
+ return dict(info)
115
+
116
+
117
+ def _probe_engine() -> dict:
97
118
  act = find_act()
98
119
  info: dict = {"ok": False, "act": act, "act_version": "",
99
120
  "docker": False, "docker_version": "", "reason": ""}
@@ -800,8 +800,11 @@ def inspect_project(project_path, event: str = "", engine: str = "auto") -> dict
800
800
  # Lazy: keeps parsing independent of the execution engines, and avoids
801
801
  # paying for a `docker version` probe on every import.
802
802
  from services import ci_act
803
- engines = ci_act.availability() if engine in ("auto", "act") else {
804
- "ok": False, "reason": "engine='native' — containers not considered"}
803
+ if engine in ("auto", "act"):
804
+ engines = ci_act.availability(max_age=ci_act.DISPLAY_PROBE_TTL_S)
805
+ else:
806
+ engines = {"ok": False,
807
+ "reason": "engine='native' — containers not considered"}
805
808
  act_ok = bool(engines.get("ok"))
806
809
 
807
810
  native, container, foreign, unsupported = [], [], [], []
@@ -310,20 +310,26 @@ def sync(project_paths=()) -> dict:
310
310
  return out
311
311
 
312
312
 
313
- def status(project_paths=()) -> dict:
313
+ def status(project_paths=(), presence=None) -> dict:
314
314
  """Counts only — never a value. ``not_backed_up`` lists registered entries
315
315
  with a live value but no sealed copy; ``restorable`` lists entries whose
316
- value is gone but whose copy is here."""
316
+ value is gone but whose copy is here.
317
+
318
+ ``presence`` maps realm to a ``credential_store.value_presence`` result
319
+ the caller already holds; any other vault is probed here, once."""
317
320
  data = _load()
318
321
  records = data.get("records", {}) if data else {}
319
322
  out: dict = {"enabled": bool(data), "path": str(backup_path() or ""),
320
323
  "created": data.get("created", "") if data else "",
321
324
  "backed_up": sum(len(r) for r in records.values()),
322
325
  "restorable": [], "lost": [], "not_backed_up": []}
326
+ known = dict(presence or {})
323
327
  for scope, pp, realm_s, name in _realm_entries(project_paths):
324
328
  label = name if scope == "global" else f"{name} ({pp})"
325
329
  has_copy = name in records.get(realm_s, {})
326
- if cs.is_resolvable(name, project_path=pp, scope=scope):
330
+ if realm_s not in known:
331
+ known[realm_s] = cs.value_presence(scope, pp)
332
+ if known[realm_s].get(name, False):
327
333
  if not has_copy:
328
334
  out["not_backed_up"].append(label)
329
335
  elif has_copy: