code-context-control 2.92.4__tar.gz → 2.96.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 (465) hide show
  1. {code_context_control-2.92.4/code_context_control.egg-info → code_context_control-2.96.0}/PKG-INFO +4 -4
  2. {code_context_control-2.92.4 → code_context_control-2.96.0}/README.md +3 -3
  3. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/c3.py +313 -13
  4. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/commands/parser.py +40 -2
  5. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/credentials.html +115 -7
  6. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/tools.html +16 -1
  7. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/workflow.html +40 -10
  8. code_context_control-2.96.0/cli/hook_session_stats.py +154 -0
  9. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_server.py +465 -9
  10. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/app.js +2 -0
  11. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/drill_panel.js +6 -2
  12. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/drill_views.js +2 -1
  13. code_context_control-2.96.0/cli/hub_ui/components/hub_cred_audit.js +255 -0
  14. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/hub_credentials.js +782 -71
  15. code_context_control-2.96.0/cli/hub_ui/components/hub_tokens.js +384 -0
  16. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/modals.js +309 -16
  17. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/project_card.js +26 -24
  18. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/project_tree.js +44 -40
  19. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/topbar.js +1 -1
  20. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/state.js +46 -11
  21. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/mcp_server.py +22 -3
  22. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/server.py +112 -4
  23. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/credentials.py +69 -4
  24. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/federate.py +7 -3
  25. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/project.py +77 -20
  26. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/credentials.js +234 -38
  27. {code_context_control-2.92.4 → code_context_control-2.96.0/code_context_control.egg-info}/PKG-INFO +4 -4
  28. {code_context_control-2.92.4 → code_context_control-2.96.0}/code_context_control.egg-info/SOURCES.txt +8 -0
  29. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/c3_bridge.py +31 -5
  30. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/federated_graph.py +21 -2
  31. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/project_scanner.py +19 -9
  32. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/tool_registry.py +10 -5
  33. {code_context_control-2.92.4 → code_context_control-2.96.0}/pyproject.toml +1 -1
  34. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/claude_md.py +2 -2
  35. code_context_control-2.96.0/services/cred_audit.py +248 -0
  36. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/credential_store.py +441 -53
  37. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/project_manager.py +30 -2
  38. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/repo_map.py +6 -0
  39. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/session_manager.py +70 -2
  40. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/subprojects.py +426 -56
  41. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/telemetry.py +145 -1
  42. code_context_control-2.96.0/tests/test_cred_audit.py +229 -0
  43. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_credential_store.py +147 -0
  44. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_credentials_routes.py +120 -0
  45. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_credentials_tool.py +106 -0
  46. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_creds_cli_smoke.py +40 -0
  47. code_context_control-2.96.0/tests/test_env_parser.py +159 -0
  48. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hub_credentials_routes_write.py +160 -0
  49. code_context_control-2.96.0/tests/test_subproject_depth_consumers.py +205 -0
  50. code_context_control-2.96.0/tests/test_subproject_linkage_api.py +305 -0
  51. code_context_control-2.96.0/tests/test_subprojects.py +651 -0
  52. code_context_control-2.96.0/tests/test_token_tracking.py +321 -0
  53. code_context_control-2.96.0/tests/test_ui_jsx_syntax.py +149 -0
  54. code_context_control-2.92.4/cli/hook_session_stats.py +0 -69
  55. code_context_control-2.92.4/tests/test_subprojects.py +0 -294
  56. code_context_control-2.92.4/tests/test_ui_jsx_syntax.py +0 -68
  57. {code_context_control-2.92.4 → code_context_control-2.96.0}/LICENSE +0 -0
  58. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/__init__.py +0 -0
  59. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/_hook_utils.py +0 -0
  60. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/_shell_writes.py +0 -0
  61. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/commands/__init__.py +0 -0
  62. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/commands/common.py +0 -0
  63. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/docs.html +0 -0
  64. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/edits.html +0 -0
  65. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/access.html +0 -0
  66. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/bitbucket.html +0 -0
  67. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/getting-started.html +0 -0
  68. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/index.html +0 -0
  69. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/masking.html +0 -0
  70. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/oracle.html +0 -0
  71. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/shared.css +0 -0
  72. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_access_guard.py +0 -0
  73. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_artifact.py +0 -0
  74. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_auto_snapshot.py +0 -0
  75. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_c3_signal.py +0 -0
  76. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_c3read.py +0 -0
  77. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_dispatch.py +0 -0
  78. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_edit_ledger.py +0 -0
  79. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_edit_unlock.py +0 -0
  80. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_filter.py +0 -0
  81. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_ghost_files.py +0 -0
  82. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_pretool_enforce.py +0 -0
  83. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_prompt_recall.py +0 -0
  84. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_read.py +0 -0
  85. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_terse_advisor.py +0 -0
  86. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/add_project.js +0 -0
  87. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/config_editor.js +0 -0
  88. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
  89. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/drill_health.js +0 -0
  90. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
  91. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/drill_tasks.js +0 -0
  92. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/global_search.js +0 -0
  93. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/hub_ci.js +0 -0
  94. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
  95. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/hub_locks.js +0 -0
  96. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/mcp_manager.js +0 -0
  97. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/session_drawer.js +0 -0
  98. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/settings_modal.js +0 -0
  99. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/sidebar.js +0 -0
  100. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/summary_bar.js +0 -0
  101. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/task_board.js +0 -0
  102. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/toasts.js +0 -0
  103. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui.html +0 -0
  104. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/mcp_proxy.py +0 -0
  105. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/progress.py +0 -0
  106. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/__init__.py +0 -0
  107. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/_grants.py +0 -0
  108. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/_helpers.py +0 -0
  109. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/agent.py +0 -0
  110. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/artifacts.py +0 -0
  111. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/bitbucket.py +0 -0
  112. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/ci.py +0 -0
  113. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/compress.py +0 -0
  114. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/delegate.py +0 -0
  115. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/edit.py +0 -0
  116. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/edit_verify.py +0 -0
  117. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/edits.py +0 -0
  118. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/filter.py +0 -0
  119. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/impact.py +0 -0
  120. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/jira.py +0 -0
  121. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/locks.py +0 -0
  122. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/memory.py +0 -0
  123. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/override.py +0 -0
  124. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/read.py +0 -0
  125. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/search.py +0 -0
  126. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/session.py +0 -0
  127. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/shell.py +0 -0
  128. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/status.py +0 -0
  129. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/tasks.py +0 -0
  130. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/validate.py +0 -0
  131. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/api.js +0 -0
  132. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/app.js +0 -0
  133. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/access.js +0 -0
  134. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/bitbucket.js +0 -0
  135. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/chat.js +0 -0
  136. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/dashboard.js +0 -0
  137. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/edits.js +0 -0
  138. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/enforcement.js +0 -0
  139. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/instructions.js +0 -0
  140. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/jira.js +0 -0
  141. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/memory.js +0 -0
  142. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/sessions.js +0 -0
  143. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/settings.js +0 -0
  144. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/sidebar.js +0 -0
  145. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/tasks.js +0 -0
  146. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/icons.js +0 -0
  147. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/pm_shared.js +0 -0
  148. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/shared.js +0 -0
  149. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/theme.js +0 -0
  150. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui.html +0 -0
  151. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui_legacy.html +0 -0
  152. {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui_nano.html +0 -0
  153. {code_context_control-2.92.4 → code_context_control-2.96.0}/code_context_control.egg-info/dependency_links.txt +0 -0
  154. {code_context_control-2.92.4 → code_context_control-2.96.0}/code_context_control.egg-info/entry_points.txt +0 -0
  155. {code_context_control-2.92.4 → code_context_control-2.96.0}/code_context_control.egg-info/requires.txt +0 -0
  156. {code_context_control-2.92.4 → code_context_control-2.96.0}/code_context_control.egg-info/top_level.txt +0 -0
  157. {code_context_control-2.92.4 → code_context_control-2.96.0}/core/__init__.py +0 -0
  158. {code_context_control-2.92.4 → code_context_control-2.96.0}/core/config.py +0 -0
  159. {code_context_control-2.92.4 → code_context_control-2.96.0}/core/ide.py +0 -0
  160. {code_context_control-2.92.4 → code_context_control-2.96.0}/core/mcp_toml.py +0 -0
  161. {code_context_control-2.92.4 → code_context_control-2.96.0}/core/web_security.py +0 -0
  162. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/__init__.py +0 -0
  163. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/config.py +0 -0
  164. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/mcp_oracle.py +0 -0
  165. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/oracle_server.py +0 -0
  166. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/oracle_ui.html +0 -0
  167. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/__init__.py +0 -0
  168. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/activity_reporter.py +0 -0
  169. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/api_auth.py +0 -0
  170. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/chat_engine.py +0 -0
  171. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/chat_poll.py +0 -0
  172. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/chat_store.py +0 -0
  173. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/cross_memory.py +0 -0
  174. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/discovery_audit.py +0 -0
  175. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/health_checker.py +0 -0
  176. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/insight_engine.py +0 -0
  177. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/local_session.py +0 -0
  178. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/memory_reader.py +0 -0
  179. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/memory_writer.py +0 -0
  180. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/mobile_api.py +0 -0
  181. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/review_agent.py +0 -0
  182. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/tool_executor.py +0 -0
  183. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/activity.js +0 -0
  184. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/agents.js +0 -0
  185. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/app.js +0 -0
  186. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/busy.js +0 -0
  187. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/chat/conversations.js +0 -0
  188. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/chat/input.js +0 -0
  189. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/chat/markdown.js +0 -0
  190. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/chat/send.js +0 -0
  191. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/chat/stream_renderer.js +0 -0
  192. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/chat/toolbar.js +0 -0
  193. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/core.js +0 -0
  194. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/crossgraph.js +0 -0
  195. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/header.js +0 -0
  196. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/insights.js +0 -0
  197. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/projects.js +0 -0
  198. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/qrcode.js +0 -0
  199. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/settings.js +0 -0
  200. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/suggestions.js +0 -0
  201. {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/theme_tabs.js +0 -0
  202. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/__init__.py +0 -0
  203. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/access_guard.py +0 -0
  204. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/access_telemetry.py +0 -0
  205. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/activity_log.py +0 -0
  206. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/agent_base.py +0 -0
  207. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/agent_locks.py +0 -0
  208. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/agents.py +0 -0
  209. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/artifact_defs.py +0 -0
  210. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/artifact_store.py +0 -0
  211. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/auto_memory.py +0 -0
  212. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/background_service.py +0 -0
  213. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/bench/__init__.py +0 -0
  214. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/bench/external/__init__.py +0 -0
  215. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/bench/external/aider_polyglot.py +0 -0
  216. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/bench/external/swe_bench.py +0 -0
  217. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/benchmark_dashboard.py +0 -0
  218. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/bitbucket_client.py +0 -0
  219. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/bitbucket_credentials.py +0 -0
  220. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_act.py +0 -0
  221. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_cache.py +0 -0
  222. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_expr.py +0 -0
  223. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_failures.py +0 -0
  224. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_github.py +0 -0
  225. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_impact.py +0 -0
  226. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_intel.py +0 -0
  227. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_runner.py +0 -0
  228. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_workflow.py +0 -0
  229. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/circuit_breaker.py +0 -0
  230. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/compressor.py +0 -0
  231. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/context_snapshot.py +0 -0
  232. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/conversation_store.py +0 -0
  233. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/cred_telemetry.py +0 -0
  234. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/doc_index.py +0 -0
  235. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/e2e_benchmark.py +0 -0
  236. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/e2e_evaluator.py +0 -0
  237. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/e2e_tasks.py +0 -0
  238. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/edit_ledger.py +0 -0
  239. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/embedding_index.py +0 -0
  240. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/enforcement_policy.py +0 -0
  241. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/error_reporting.py +0 -0
  242. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/file_memory.py +0 -0
  243. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/git_context.py +0 -0
  244. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/hub_service.py +0 -0
  245. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/indexer.py +0 -0
  246. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/jira_client.py +0 -0
  247. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/jira_cloud.py +0 -0
  248. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/jira_credentials.py +0 -0
  249. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/jira_data_center.py +0 -0
  250. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/jira_links.py +0 -0
  251. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/mask_activation.py +0 -0
  252. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/mask_mirror.py +0 -0
  253. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/mask_presets.py +0 -0
  254. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/memory.py +0 -0
  255. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/memory_consolidator.py +0 -0
  256. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/memory_distiller.py +0 -0
  257. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/memory_graph.py +0 -0
  258. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/memory_grounder.py +0 -0
  259. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/memory_queue.py +0 -0
  260. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/memory_scorer.py +0 -0
  261. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/metrics.py +0 -0
  262. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/notifications.py +0 -0
  263. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ollama_bridge.py +0 -0
  264. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ollama_client.py +0 -0
  265. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ollama_credentials.py +0 -0
  266. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/oracle_service.py +0 -0
  267. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/output_filter.py +0 -0
  268. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/override_grants.py +0 -0
  269. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/override_policy.py +0 -0
  270. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/override_requests.py +0 -0
  271. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/override_wake.py +0 -0
  272. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/parser.py +0 -0
  273. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/project_runtime.py +0 -0
  274. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/protocol.py +0 -0
  275. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/proxy_state.py +0 -0
  276. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/repo_shape.py +0 -0
  277. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/retention.py +0 -0
  278. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/retrieval_broker.py +0 -0
  279. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/router.py +0 -0
  280. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/runtime.py +0 -0
  281. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/scanner.py +0 -0
  282. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/session_benchmark.py +0 -0
  283. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/session_preloader.py +0 -0
  284. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/task_store.py +0 -0
  285. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/text_index.py +0 -0
  286. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/time_tracker.py +0 -0
  287. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/tool_classifier.py +0 -0
  288. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/transcript_index.py +0 -0
  289. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/validation_cache.py +0 -0
  290. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/vector_store.py +0 -0
  291. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/watcher.py +0 -0
  292. {code_context_control-2.92.4 → code_context_control-2.96.0}/services/win_subprocess.py +0 -0
  293. {code_context_control-2.92.4 → code_context_control-2.96.0}/setup.cfg +0 -0
  294. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_access_builtin_optout.py +0 -0
  295. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_access_guard.py +0 -0
  296. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_access_guard_meta.py +0 -0
  297. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_access_guard_shell_project.py +0 -0
  298. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_access_guard_surfaces.py +0 -0
  299. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_access_guard_wiring.py +0 -0
  300. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_activity_reporter.py +0 -0
  301. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_agent_locks.py +0 -0
  302. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_aider_polyglot.py +0 -0
  303. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_antigravity_transition.py +0 -0
  304. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_artifact_store.py +0 -0
  305. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_artifact_tool.py +0 -0
  306. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_background_service.py +0 -0
  307. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_bitbucket_cli_smoke.py +0 -0
  308. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_bitbucket_client.py +0 -0
  309. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_bitbucket_config_fallback.py +0 -0
  310. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_bitbucket_credentials.py +0 -0
  311. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_bitbucket_tool.py +0 -0
  312. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
  313. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_c3_shell.py +0 -0
  314. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_chat_poll.py +0 -0
  315. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ci_act.py +0 -0
  316. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ci_cache.py +0 -0
  317. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ci_expr.py +0 -0
  318. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ci_impact.py +0 -0
  319. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ci_intel.py +0 -0
  320. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ci_runner.py +0 -0
  321. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ci_workflow.py +0 -0
  322. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_circuit_breaker.py +0 -0
  323. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_claude_md_merge.py +0 -0
  324. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_cli_smoke.py +0 -0
  325. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_compressor_large_file.py +0 -0
  326. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_cooccurrence_bounds.py +0 -0
  327. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_cred_telemetry.py +0 -0
  328. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_credential_login_kind.py +0 -0
  329. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_credential_ui_parity.py +0 -0
  330. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_delegate_cascade.py +0 -0
  331. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_delegate_version_probe.py +0 -0
  332. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_e2e_benchmark.py +0 -0
  333. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_edit_ledger_deadline.py +0 -0
  334. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_edit_ledger_hook.py +0 -0
  335. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_edit_locking.py +0 -0
  336. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_edit_normalization.py +0 -0
  337. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_edit_verify.py +0 -0
  338. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_embedding_index_deadlock.py +0 -0
  339. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_enforcement_flip.py +0 -0
  340. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_enforcement_policy.py +0 -0
  341. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_enforcement_routes.py +0 -0
  342. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_failed_calls_do_not_unlock.py +0 -0
  343. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_federated_graph.py +0 -0
  344. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_filter_backoff.py +0 -0
  345. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ghost_files.py +0 -0
  346. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ghost_generation.py +0 -0
  347. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_git_branch_awareness.py +0 -0
  348. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hook_access_guard.py +0 -0
  349. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hook_codex_compat.py +0 -0
  350. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hook_dispatch.py +0 -0
  351. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hook_pretool_enforce.py +0 -0
  352. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hook_prompt_recall.py +0 -0
  353. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hook_smoke.py +0 -0
  354. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hook_state.py +0 -0
  355. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hook_utf8_stdio.py +0 -0
  356. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hub_credentials_route.py +0 -0
  357. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hub_enforcement_routes.py +0 -0
  358. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hub_inspect_api.py +0 -0
  359. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hub_locks_routes.py +0 -0
  360. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hub_oracle_service_routes.py +0 -0
  361. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hub_server_smoke.py +0 -0
  362. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hub_subproject_links.py +0 -0
  363. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ide_workflow_adaptation.py +0 -0
  364. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_init_clear_preserves_user_content.py +0 -0
  365. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_init_scan.py +0 -0
  366. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_install_mcp_entrypoint.py +0 -0
  367. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_jira_cli_smoke.py +0 -0
  368. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_jira_client.py +0 -0
  369. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_jira_config_fallback.py +0 -0
  370. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_jira_credentials.py +0 -0
  371. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_jira_links.py +0 -0
  372. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_jira_routes.py +0 -0
  373. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_jira_tool.py +0 -0
  374. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_lazy_store_init.py +0 -0
  375. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mask_guard.py +0 -0
  376. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mask_routes.py +0 -0
  377. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mask_surfaces.py +0 -0
  378. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mcp_host_guard.py +0 -0
  379. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mcp_memory_timeout.py +0 -0
  380. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mcp_server_smoke.py +0 -0
  381. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mcp_toml.py +0 -0
  382. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_memory_distiller.py +0 -0
  383. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_memory_graph_api.py +0 -0
  384. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_memory_queue.py +0 -0
  385. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_memory_system.py +0 -0
  386. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mobile_api.py +0 -0
  387. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mobile_extras.py +0 -0
  388. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mobile_override_routes.py +0 -0
  389. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mobile_security_api.py +0 -0
  390. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_no_stale_model_pins.py +0 -0
  391. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_notification_dedup.py +0 -0
  392. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_notification_discipline.py +0 -0
  393. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ollama_credentials.py +0 -0
  394. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_api_auth.py +0 -0
  395. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_apikey_api.py +0 -0
  396. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_c3_bridge.py +0 -0
  397. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_chat_engine.py +0 -0
  398. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_chat_store.py +0 -0
  399. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_discovery_api.py +0 -0
  400. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_discovery_audit.py +0 -0
  401. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_health_probe.py +0 -0
  402. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_local_auth.py +0 -0
  403. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_ollama_bridge.py +0 -0
  404. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_scanner_cache.py +0 -0
  405. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_security_fixes.py +0 -0
  406. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_session_bootstrap.py +0 -0
  407. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_subproject_awareness.py +0 -0
  408. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_ui_bundle.py +0 -0
  409. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_output_filter.py +0 -0
  410. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_override_grants.py +0 -0
  411. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_override_grants_mcp.py +0 -0
  412. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_override_requests.py +0 -0
  413. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_override_wake.py +0 -0
  414. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_permissions.py +0 -0
  415. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_pm_api.py +0 -0
  416. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_project_manager.py +0 -0
  417. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_project_manager_merge.py +0 -0
  418. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_project_tool.py +0 -0
  419. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_read_coercion.py +0 -0
  420. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_read_edit_parity.py +0 -0
  421. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_related_facts.py +0 -0
  422. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_repo_map.py +0 -0
  423. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_repo_shape.py +0 -0
  424. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_response_boilerplate.py +0 -0
  425. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_retention.py +0 -0
  426. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_review_digest.py +0 -0
  427. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_service_durability.py +0 -0
  428. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_session_benchmark.py +0 -0
  429. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_session_budget.py +0 -0
  430. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_shell_creds.py +0 -0
  431. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_shell_robustness.py +0 -0
  432. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_shell_write_ledger.py +0 -0
  433. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_shell_writes.py +0 -0
  434. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_subproject_exclusion.py +0 -0
  435. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_subproject_federation.py +0 -0
  436. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_swe_bench.py +0 -0
  437. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_task_store.py +0 -0
  438. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_task_tool.py +0 -0
  439. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_time_tracker.py +0 -0
  440. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_token_telemetry.py +0 -0
  441. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_tool_registry.py +0 -0
  442. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_upgrade_and_version.py +0 -0
  443. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_validate.py +0 -0
  444. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_vault_write_guard.py +0 -0
  445. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_version_sync.py +0 -0
  446. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_web_security.py +0 -0
  447. {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_windows_reliability.py +0 -0
  448. {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/__init__.py +0 -0
  449. {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/backend.py +0 -0
  450. {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/main.py +0 -0
  451. {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/__init__.py +0 -0
  452. {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/benchmark_view.py +0 -0
  453. {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/claudemd_view.py +0 -0
  454. {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/compress_view.py +0 -0
  455. {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/index_view.py +0 -0
  456. {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/init_view.py +0 -0
  457. {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/mcp_view.py +0 -0
  458. {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/optimize_view.py +0 -0
  459. {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/pipe_view.py +0 -0
  460. {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/projects_view.py +0 -0
  461. {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/search_view.py +0 -0
  462. {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/session_view.py +0 -0
  463. {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/stats.py +0 -0
  464. {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/ui_view.py +0 -0
  465. {code_context_control-2.92.4 → code_context_control-2.96.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.92.4
3
+ Version: 2.96.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
@@ -149,7 +149,7 @@ Every C3-initialized project registers itself here on `c3 init`. Filter by activ
149
149
 
150
150
  Three top-level views — **Projects**, **Tasks** (a cross-project kanban), and **Credentials** — plus a drill-in panel per project covering Overview, Sub-projects, Tasks, Artifacts, Memory, Ledger, Sessions, Health, Budget, Credentials, Config, and MCP.
151
151
 
152
- **Sub-projects** make a nested repo a first-class child with its own `.c3`: the parent's index excludes the child's subtree, and `c3_search` / `c3_memory` fan out on demand (`scope='all'`, or one child by name). → [Sub-projects guide](https://github.com/drknowhow/code-context-control/blob/main/docs/sub-projects.md)
152
+ **Sub-projects** make one project a first-class child of another, with its own `.c3`. It can be a nested repo — the parent's index then excludes its subtree — or a project anywhere else on disk, linked by path. Hierarchies nest up to 8 levels, and `c3_search` / `c3_memory` fan out on demand (`scope='all'`, or one by name). → [Sub-projects guide](https://github.com/drknowhow/code-context-control/blob/main/docs/sub-projects.md)
153
153
 
154
154
  ### Per-project UI
155
155
 
@@ -208,10 +208,10 @@ C3 exposes **21 tools** as a native MCP server. Your IDE calls them directly:
208
208
  | `c3_edits` | Edit-ledger queries, version diffs, restore points, per-branch filter, `verify` (did a failed `c3_edit` still land?) |
209
209
  | `c3_task` | Per-project PM — tasks, dependencies, milestones, time tracking (v2.53.0) |
210
210
  | `c3_artifacts` | Agent-config version history, diff & restore (v2.46.0) |
211
- | `c3_credentials` | Named-secret vault; values never enter model context (v2.58.0) |
211
+ | `c3_credentials` | Named-secret vault; values never enter model context (v2.58.0). `import_env` bulk-imports a `.env` the agent still cannot read (v2.93.0) |
212
212
  | `c3_bitbucket` | Bitbucket Data Center — PRs, branches, builds, admin (v2.30.0) |
213
213
  | `c3_jira` | Jira Cloud + Data Center — JQL, issues, transitions (v2.56.0) |
214
- | `c3_project` | Cross-project discovery & operations; guarded writes (v2.31.0) |
214
+ | `c3_project` | Cross-project discovery & operations; sub-project hierarchy (link by path, inspect, multi-level tree); guarded writes (v2.31.0) |
215
215
 
216
216
  Every tool is **read-only safe in plan mode** except `c3_edit`, `c3_shell`, `c3_ci(action='run'|'rerun')`, `c3_artifacts(action='restore')`, `c3_delegate` with write delegation enabled, and write actions on `c3_bitbucket` / `c3_jira` / `c3_credentials` / `c3_project` / `c3_task` / `c3_locks`.
217
217
 
@@ -86,7 +86,7 @@ Every C3-initialized project registers itself here on `c3 init`. Filter by activ
86
86
 
87
87
  Three top-level views — **Projects**, **Tasks** (a cross-project kanban), and **Credentials** — plus a drill-in panel per project covering Overview, Sub-projects, Tasks, Artifacts, Memory, Ledger, Sessions, Health, Budget, Credentials, Config, and MCP.
88
88
 
89
- **Sub-projects** make a nested repo a first-class child with its own `.c3`: the parent's index excludes the child's subtree, and `c3_search` / `c3_memory` fan out on demand (`scope='all'`, or one child by name). → [Sub-projects guide](https://github.com/drknowhow/code-context-control/blob/main/docs/sub-projects.md)
89
+ **Sub-projects** make one project a first-class child of another, with its own `.c3`. It can be a nested repo — the parent's index then excludes its subtree — or a project anywhere else on disk, linked by path. Hierarchies nest up to 8 levels, and `c3_search` / `c3_memory` fan out on demand (`scope='all'`, or one by name). → [Sub-projects guide](https://github.com/drknowhow/code-context-control/blob/main/docs/sub-projects.md)
90
90
 
91
91
  ### Per-project UI
92
92
 
@@ -145,10 +145,10 @@ C3 exposes **21 tools** as a native MCP server. Your IDE calls them directly:
145
145
  | `c3_edits` | Edit-ledger queries, version diffs, restore points, per-branch filter, `verify` (did a failed `c3_edit` still land?) |
146
146
  | `c3_task` | Per-project PM — tasks, dependencies, milestones, time tracking (v2.53.0) |
147
147
  | `c3_artifacts` | Agent-config version history, diff & restore (v2.46.0) |
148
- | `c3_credentials` | Named-secret vault; values never enter model context (v2.58.0) |
148
+ | `c3_credentials` | Named-secret vault; values never enter model context (v2.58.0). `import_env` bulk-imports a `.env` the agent still cannot read (v2.93.0) |
149
149
  | `c3_bitbucket` | Bitbucket Data Center — PRs, branches, builds, admin (v2.30.0) |
150
150
  | `c3_jira` | Jira Cloud + Data Center — JQL, issues, transitions (v2.56.0) |
151
- | `c3_project` | Cross-project discovery & operations; guarded writes (v2.31.0) |
151
+ | `c3_project` | Cross-project discovery & operations; sub-project hierarchy (link by path, inspect, multi-level tree); guarded writes (v2.31.0) |
152
152
 
153
153
  Every tool is **read-only safe in plan mode** except `c3_edit`, `c3_shell`, `c3_ci(action='run'|'rerun')`, `c3_artifacts(action='restore')`, `c3_delegate` with write delegation enabled, and write actions on `c3_bitbucket` / `c3_jira` / `c3_credentials` / `c3_project` / `c3_task` / `c3_locks`.
154
154
 
@@ -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.92.4"
95
+ __version__ = "2.96.0"
96
96
 
97
97
 
98
98
  def _compress_file_cli(compressor, path, mode="smart", **kw):
@@ -6114,11 +6114,75 @@ def _bb_cmd_set_default(args, project_path: str) -> None:
6114
6114
  print(f"[OK] Default repo: {args.project}/{args.repo}")
6115
6115
 
6116
6116
 
6117
+ def cmd_tokens(args):
6118
+ """Print token usage from the two local measurement logs.
6119
+
6120
+ Reads only; writes nothing. Counts come from .c3/tool_telemetry.jsonl
6121
+ (what C3's tools returned) and .c3/session_stats.jsonl (what the whole
6122
+ conversation cost, per the transcript).
6123
+ """
6124
+ from services import telemetry
6125
+
6126
+ project_path = getattr(args, "project_path", ".") or "."
6127
+ days = max(0, int(getattr(args, "days", 30) or 0))
6128
+ limit = max(1, int(getattr(args, "limit", 15) or 15))
6129
+ tools = telemetry.aggregate_tool_telemetry(project_path, days=days)
6130
+ sess = telemetry.aggregate_session_stats(project_path, days=days)
6131
+
6132
+ if getattr(args, "json", False):
6133
+ print(json.dumps({"tools": tools, "sessions": sess}, indent=2))
6134
+ return
6135
+
6136
+ window = "all history" if days == 0 else f"last {days}d"
6137
+ print(f"\nToken usage — {window}")
6138
+ print(f" tool calls {tools['total_calls']:>14,}")
6139
+ print(f" tool tokens {tools['total_response_tokens']:>14,}")
6140
+ print(f" est. saved {tools['estimated_saved_vs_full_read']:>14,}"
6141
+ " (vs full-read baseline)")
6142
+ print(f" session tokens {sess['total_tokens']:>14,}"
6143
+ f" across {sess['session_count']} session(s)")
6144
+ if sess["rows_seen"] and sess["all_zero_rows"] == sess["rows_seen"]:
6145
+ # Do not let a log full of zeros read as "you used nothing".
6146
+ print(" note: every session row is zero — these predate the v2.95.0 "
6147
+ "Stop-hook fix; new sessions record real numbers.")
6148
+
6149
+ by = getattr(args, "by", "tool")
6150
+ if by == "tool":
6151
+ rows = sorted(({"name": k, **v} for k, v in tools["by_tool"].items()),
6152
+ key=lambda r: -r["response_tokens"])
6153
+ head, cols = "tool", ("calls", "tokens", "avg")
6154
+ elif by == "day":
6155
+ rows, head, cols = tools["by_day"][::-1], "day", ("calls", "tokens", "avg")
6156
+ elif by == "session":
6157
+ rows, head, cols = tools["by_session"], "session", ("calls", "tokens", "avg")
6158
+ else:
6159
+ rows, head, cols = tools["by_target"], "file", ("calls", "tokens", "avg")
6160
+
6161
+ if not rows:
6162
+ extra = (" (no file attribution recorded yet — targets are logged "
6163
+ "from v2.95.0 onward)" if by == "file" else " (nothing recorded)")
6164
+ print(f"\n{extra}")
6165
+ return
6166
+
6167
+ print(f"\n{head:<44}{cols[0]:>8}{cols[1]:>12}{cols[2]:>8}")
6168
+ print(" " + "-" * 70)
6169
+ for r in rows[:limit]:
6170
+ calls = r.get("calls", 0)
6171
+ toks = r.get("response_tokens", 0)
6172
+ name = str(r.get("name", ""))
6173
+ if len(name) > 43:
6174
+ name = "…" + name[-42:]
6175
+ print(f"{name:<44}{calls:>8}{toks:>12,}{toks // max(1, calls):>8}")
6176
+ if len(rows) > limit:
6177
+ print(f" … {len(rows) - limit} more (use --limit)")
6178
+ print()
6179
+
6180
+
6117
6181
  def cmd_creds(args):
6118
6182
  """Credential vault management (global + per-project scopes)."""
6119
6183
  sub = getattr(args, "creds_cmd", None)
6120
6184
  if not sub:
6121
- print("Usage: c3 creds {set,get,list,rm,import,usage} [args]")
6185
+ print("Usage: c3 creds {set,get,list,rm,import,usage,audit} [args]")
6122
6186
  return
6123
6187
 
6124
6188
  project_path = getattr(args, "project_path", ".") or "."
@@ -6135,6 +6199,8 @@ def cmd_creds(args):
6135
6199
  _creds_cmd_import(args, project_path)
6136
6200
  elif sub == "usage":
6137
6201
  _creds_cmd_usage(args, project_path)
6202
+ elif sub == "audit":
6203
+ _creds_cmd_audit(args, project_path)
6138
6204
  else:
6139
6205
  print(f"Unknown creds subcommand: {sub}")
6140
6206
 
@@ -6321,6 +6387,25 @@ def _creds_cmd_rm(args, project_path: str) -> None:
6321
6387
  print(f"[error] no credential named '{args.name}' in {scope} scope")
6322
6388
 
6323
6389
 
6390
+ def _creds_import_table(rows: list) -> None:
6391
+ """Print one line per parsed row: what it is, not what it holds.
6392
+
6393
+ Length and fingerprint are enough to tell two keys apart and to spot a
6394
+ truncated paste; a value prefix would be part of the secret, so there
6395
+ isn't one.
6396
+ """
6397
+ if not rows:
6398
+ print("Nothing to import — no KEY=VALUE lines found.")
6399
+ return
6400
+ width = max(len(str(r["name"])) for r in rows)
6401
+ print(f"{'NAME'.ljust(width)} LINE TYPE LEN FINGERPRINT STATUS")
6402
+ for r in rows:
6403
+ status = r["detail"] or r["action"]
6404
+ print(f"{str(r['name']).ljust(width)} {str(r['line']).rjust(4)} "
6405
+ f"{r['ctype']:<9} {str(r['value_len']).rjust(4)} "
6406
+ f"{(r['fingerprint'] or '-'):<11} {status}")
6407
+
6408
+
6324
6409
  def _creds_cmd_import(args, project_path: str) -> None:
6325
6410
  from services import credential_store as cred_store
6326
6411
 
@@ -6328,20 +6413,126 @@ def _creds_cmd_import(args, project_path: str) -> None:
6328
6413
  if not env_path.exists():
6329
6414
  print(f"[error] file not found: {env_path}")
6330
6415
  return
6416
+ only = [n.strip() for n in str(getattr(args, "only", "") or "").split(",")
6417
+ if n.strip()] or None
6418
+ dry_run = bool(getattr(args, "dry_run", False))
6331
6419
  try:
6332
- text = env_path.read_text(encoding="utf-8")
6420
+ text = cred_store.read_env_file(env_path)
6333
6421
  result = cred_store.import_env(
6334
6422
  text, scope=_creds_scope(args), project_path=project_path,
6335
6423
  overwrite=bool(getattr(args, "overwrite", False)),
6424
+ preview=dry_run, only=only,
6425
+ source=str(env_path.resolve()), compare=dry_run,
6336
6426
  )
6337
6427
  except (cred_store.CredentialError, RuntimeError) as exc:
6338
6428
  print(f"[error] {exc}")
6339
6429
  return
6430
+
6431
+ if dry_run:
6432
+ _creds_import_table(result["rows"])
6433
+ print(f"\n[dry-run] {len(result['created'])} would be imported, "
6434
+ f"{len(result['skipped'])} skipped. Nothing was written.")
6435
+ return
6436
+
6340
6437
  print(f"[OK] Imported {len(result['created'])} credential(s): "
6341
6438
  f"{', '.join(result['created']) or '-'}")
6342
6439
  if result["skipped"]:
6343
- print(f"Skipped {len(result['skipped'])}: {', '.join(result['skipped'])} "
6344
- "(use --overwrite to replace)")
6440
+ # Reasons come off the rows, which already carry human text — the old
6441
+ # output was a bare comma list that lumped four causes together.
6442
+ detail = {r["name"]: r["detail"] for r in result["rows"] if r["reason"]}
6443
+ print(f"Skipped {len(result['skipped'])}:")
6444
+ for name in result["skipped"]:
6445
+ print(f" {name} - {detail.get(name, 'skipped')}")
6446
+ notes = [r for r in result["rows"] if r["reason"] in ("no-assignment", "duplicate")]
6447
+ if notes:
6448
+ print(f"{len(notes)} line(s) ignored "
6449
+ "(no KEY=VALUE, or redefined later in the file).")
6450
+ if result["created"]:
6451
+ _creds_audit_import(project_path, _creds_scope(args), result["created"],
6452
+ env_path)
6453
+
6454
+
6455
+ def _creds_audit_import(project_path: str, scope: str, created: list,
6456
+ env_path) -> None:
6457
+ """The CLI import was the one credential mutation with no audit trail —
6458
+ both REST paths logged and this did not. Names only, never values."""
6459
+ try:
6460
+ from services.edit_ledger import EditLedger
6461
+ ledger = EditLedger(str(project_path))
6462
+ ledger.log_edit(
6463
+ file=f"cred://{len(created)} entries",
6464
+ change_type="cred_import",
6465
+ summary=f"import {len(created)} entries ({scope}) from "
6466
+ f"{Path(env_path).name} via c3 creds",
6467
+ tags=["creds", "import"],
6468
+ detail={"kind": "creds", "action": "import", "scope": scope,
6469
+ "names": list(created), "source": Path(env_path).name},
6470
+ )
6471
+ for name in created:
6472
+ ledger.log_edit(
6473
+ file=f"cred://{name}", change_type="cred_set",
6474
+ summary=f"set {name} ({scope}) via c3 creds import",
6475
+ tags=["creds", "set"],
6476
+ detail={"kind": "creds", "action": "set", "name": name,
6477
+ "scope": scope},
6478
+ )
6479
+ except Exception:
6480
+ pass
6481
+ try:
6482
+ from services.activity_log import ActivityLog
6483
+ log = ActivityLog(str(project_path))
6484
+ for name in created:
6485
+ log.log("cred_action", {"kind": "creds", "action": "set",
6486
+ "name": name, "scope": scope, "via": "cli"})
6487
+ except Exception:
6488
+ pass
6489
+
6490
+
6491
+ def _creds_cmd_audit(args, project_path):
6492
+ """One timeline of every credential change and use.
6493
+
6494
+ Reads only. Prints names and command TEMPLATES — the logs never hold a
6495
+ value, so there is nothing to redact on the way out.
6496
+ """
6497
+ from services import cred_audit
6498
+
6499
+ res = cred_audit.audit_events(
6500
+ project_path,
6501
+ name=getattr(args, "name", "") or "",
6502
+ kind=getattr(args, "kind", "") or "",
6503
+ action=getattr(args, "action", "") or "",
6504
+ surface=getattr(args, "surface", "") or "",
6505
+ q=getattr(args, "q", "") or "",
6506
+ since=getattr(args, "since", "") or "",
6507
+ limit=getattr(args, "limit", 40) or 40,
6508
+ )
6509
+ if getattr(args, "as_json", False):
6510
+ print(json.dumps(res, indent=2))
6511
+ return
6512
+
6513
+ counts = res["counts"]
6514
+ print(f"\nCredential audit — {res['matched']} event(s): "
6515
+ f"{counts['use']} use, {counts['change']} change"
6516
+ + (f", {counts['exposing']} exposing" if counts["exposing"] else ""))
6517
+ if not res["events"]:
6518
+ print(" (nothing recorded for these filters)\n")
6519
+ return
6520
+
6521
+ print(f"\n{'when':<20}{'kind':<8}{'action':<12}{'name':<24}{'where'}")
6522
+ print(" " + "-" * 84)
6523
+ for ev in res["events"]:
6524
+ when = str(ev["ts"])[:19].replace("T", " ")
6525
+ name = ev["name"] + (f".{ev['field']}" if ev["field"] else "")
6526
+ where = ev["surface"] or "?"
6527
+ if ev["scope"]:
6528
+ where += f" ({ev['scope']})"
6529
+ mark = " !" if ev["action"] in cred_audit.EXPOSING_ACTIONS else ""
6530
+ print(f"{when:<20}{ev['kind']:<8}{ev['action']:<12}{name[:23]:<24}{where}{mark}")
6531
+ if ev["cmd"]:
6532
+ print(f"{'':<20} cmd: {ev['cmd']}")
6533
+ if res["truncated"]:
6534
+ print(f" … {res['matched'] - res['returned']} more (use --limit)")
6535
+ print(f"\n {res['note']}\n")
6345
6536
 
6346
6537
 
6347
6538
  def _creds_cmd_usage(args, project_path: str) -> None:
@@ -7795,14 +7986,117 @@ def cmd_sub(args):
7795
7986
  print(f"No .c3 found in {parent}. Run 'c3 init' there first.")
7796
7987
  return
7797
7988
  # Import after the cheap guard — the registry module needs a resolvable home.
7798
- from services.subprojects import VALID_CASCADE_OPS, SubprojectManager
7989
+ from services.subprojects import (
7990
+ MAX_DEPTH,
7991
+ VALID_CASCADE_OPS,
7992
+ SubprojectManager,
7993
+ inspect_path,
7994
+ )
7799
7995
 
7800
7996
  sm = SubprojectManager(parent)
7801
7997
  sub = getattr(args, "sub_cmd", "list") or "list"
7802
7998
  target = getattr(args, "target", None)
7803
7999
  as_json = getattr(args, "json", False)
8000
+ depth = getattr(args, "depth", None) or MAX_DEPTH
8001
+
8002
+ if sub == "inspect":
8003
+ if not target:
8004
+ print("Usage: c3 sub inspect <path> [--json]")
8005
+ return
8006
+ rep = inspect_path(target, detect=not getattr(args, "no_detect", False))
8007
+ if as_json:
8008
+ print(json.dumps(rep, indent=2))
8009
+ return
8010
+ print(f"\n{rep['path']}")
8011
+ if not rep["is_dir"]:
8012
+ print(" not a folder")
8013
+ return
8014
+ proj = rep.get("project")
8015
+ if proj:
8016
+ reg = "registered" if rep["registered"] else "NOT registered"
8017
+ print(f" C3 project: {proj['name']} (v{proj.get('c3_version') or '?'}, "
8018
+ f"ide={proj.get('ide') or '?'}, {reg})")
8019
+ print(f" {proj['facts_count']} facts, {proj['sessions']} sessions, "
8020
+ f"{proj['edit_ledger_entries']} ledger entries, "
8021
+ f"{proj['notification_count']} alerts")
8022
+ else:
8023
+ print(" no .c3 — not a C3 project yet")
8024
+ if rep["ancestors"]:
8025
+ chain = " < ".join(a["name"] for a in rep["ancestors"])
8026
+ print(f" parent chain (depth {rep['depth']}): {chain}")
8027
+ else:
8028
+ print(" top-level (no parent)")
8029
+ if rep["children"]:
8030
+ print(f" {len(rep['children'])} sub-project(s):")
8031
+ for c in rep["children"]:
8032
+ print(f" - {c['name']:<22} [{c['link_kind']}/{c['status']}] {c['path']}")
8033
+ if rep["detected"]:
8034
+ print(f" {len(rep['detected'])} unlinked project(s) detected inside:")
8035
+ for d in rep["detected"]:
8036
+ print(f" ? {d['name']:<22} {d['path']}")
8037
+ print(" (suggestions only — link with `c3 sub link <path>`)")
8038
+ for w in rep["warnings"]:
8039
+ print(f" warning: {w}")
7804
8040
 
7805
- if sub == "add":
8041
+ elif sub == "tree":
8042
+ t = sm.tree(depth=depth)
8043
+ if as_json:
8044
+ print(json.dumps(t, indent=2))
8045
+ return
8046
+ r = t["rollup"]
8047
+ print(f"\n{t['parent']['name']} ({t['parent']['path']})")
8048
+
8049
+ def _render(rows, indent=" "):
8050
+ for row in rows:
8051
+ flag = "" if row["status"] == "ok" else f" [{row['status']}]"
8052
+ kind = "" if row["link_kind"] == "nested" else " (linked)"
8053
+ print(f"{indent}- {row['name']}{kind}{flag}")
8054
+ _render(row.get("children") or [], indent + " ")
8055
+
8056
+ _render(t["children"])
8057
+ if not t["children"]:
8058
+ print(" No sub-projects designated. Use `c3 sub link <path>`.")
8059
+ return
8060
+ line = f"\n{r['children']} descendant(s), {r['direct_children']} direct"
8061
+ if r["issues"]:
8062
+ line += f" -- {r['issues']} with issues (run `c3 sub check --fix`)"
8063
+ print(line)
8064
+
8065
+ elif sub == "link":
8066
+ if not target:
8067
+ print("Usage: c3 sub link <path> [--parent PATH] [--name NAME] [--init]")
8068
+ return
8069
+ # link is designation for a project that already exists anywhere on
8070
+ # disk; add is for a folder this parent should initialize.
8071
+ want_init = getattr(args, "init", False)
8072
+ candidate = target if Path(target).is_absolute() else str(Path(parent) / target)
8073
+ probe = inspect_path(candidate, detect=False)
8074
+ if probe["is_dir"] and not probe["has_c3"] and not want_init:
8075
+ err = (f"not a C3 project: {probe['path']} — "
8076
+ "pass --init to initialize it, or run `c3 init` there first")
8077
+ if as_json:
8078
+ print(json.dumps({"added": False, "error": err}, indent=2))
8079
+ else:
8080
+ print(f"Failed: {err}")
8081
+ return
8082
+ result = sm.add(
8083
+ target,
8084
+ name=getattr(args, "name", None),
8085
+ ide=getattr(args, "ide", None),
8086
+ run_init=want_init,
8087
+ reindex_parent=not getattr(args, "no_reindex_parent", False),
8088
+ )
8089
+ if as_json:
8090
+ print(json.dumps(result, indent=2))
8091
+ return
8092
+ if not result.get("added"):
8093
+ print(f"Failed: {result.get('error')}")
8094
+ return
8095
+ where = "by path" if result["link_kind"] == "external" else f"at {result['rel_path']}"
8096
+ print(f"\n[OK] Linked {result['name']} {where} (depth {result['depth']})")
8097
+ print(f" {result['path']}")
8098
+
8099
+ elif sub == "add":
7806
8100
  if not target:
7807
8101
  print("Usage: c3 sub add <folder> [--parent PATH] [--name NAME]")
7808
8102
  return
@@ -7835,16 +8129,19 @@ def cmd_sub(args):
7835
8129
  if not children:
7836
8130
  print("No sub-projects designated. Use `c3 sub add <folder>`.")
7837
8131
  return
7838
- fmt = "{:<22} {:<16} {:>6} {:>7} {}"
7839
- print(fmt.format("NAME", "STATUS", "FACTS", "ALERTS", "REL PATH"))
7840
- print("-" * 76)
8132
+ fmt = "{:<22} {:<16} {:<9} {:>6} {:>7} {}"
8133
+ print(fmt.format("NAME", "STATUS", "LINK", "FACTS", "ALERTS", "LOCATION"))
8134
+ print("-" * 90)
7841
8135
  for c in children:
8136
+ # An external child has no rel_path — show where it actually lives.
8137
+ location = c.get("rel_path") or c.get("path", "")
7842
8138
  print(fmt.format(
7843
8139
  (c.get("name") or "?")[:21],
7844
8140
  c.get("status", "?"),
8141
+ c.get("link_kind", "nested"),
7845
8142
  c.get("facts_count", 0),
7846
8143
  c.get("notification_count", 0),
7847
- c.get("rel_path", ""),
8144
+ location,
7848
8145
  ))
7849
8146
  issues = sum(1 for c in children if c["status"] != "ok")
7850
8147
  line = f"\n{len(children)} sub-project(s)"
@@ -7884,7 +8181,8 @@ def cmd_sub(args):
7884
8181
  return
7885
8182
  result = sm.cascade(target,
7886
8183
  include_parent=getattr(args, "include_parent", False),
7887
- mcp=getattr(args, "mcp", False))
8184
+ mcp=getattr(args, "mcp", False),
8185
+ depth=depth)
7888
8186
  if as_json:
7889
8187
  print(json.dumps(result, indent=2))
7890
8188
  return
@@ -7905,7 +8203,8 @@ def cmd_sub(args):
7905
8203
  print("No sub-projects designated.")
7906
8204
  return
7907
8205
  for c in result["children"]:
7908
- print(f" [{c['status']:<16}] {c.get('name') or '?':<22} {c.get('rel_path', '')}")
8206
+ location = c.get("rel_path") or c.get("path", "")
8207
+ print(f" [{c['status']:<16}] {c.get('name') or '?':<22} {location}")
7909
8208
  for o in result["orphans"]:
7910
8209
  print(f" [orphan_registry ] {o}")
7911
8210
  for f in result.get("fixed", []):
@@ -8769,6 +9068,7 @@ def main():
8769
9068
  "bitbucket": cmd_bitbucket,
8770
9069
  "jira": cmd_jira,
8771
9070
  "creds": cmd_creds,
9071
+ "tokens": cmd_tokens,
8772
9072
  "access": cmd_access,
8773
9073
  "enforce": cmd_enforce,
8774
9074
  "override": cmd_override,
@@ -152,7 +152,7 @@ def build_parser(version: str, parse_cli_ide_arg):
152
152
  p_sub.add_argument(
153
153
  "sub_cmd",
154
154
  nargs="?",
155
- choices=["add", "list", "remove", "run", "check"],
155
+ choices=["add", "link", "inspect", "list", "tree", "remove", "run", "check"],
156
156
  default="list",
157
157
  help="Sub-command (default: list)",
158
158
  )
@@ -160,7 +160,8 @@ def build_parser(version: str, parse_cli_ide_arg):
160
160
  "target",
161
161
  nargs="?",
162
162
  default=None,
163
- help="Folder (add), sub-project name/path (remove), or operation update|reindex|health (run)",
163
+ help="Folder (add), path to an existing project (link|inspect), "
164
+ "sub-project name/path (remove), or operation update|reindex|health (run)",
164
165
  )
165
166
  p_sub.add_argument("--parent", default=".", help="Parent project path (default: current directory)")
166
167
  p_sub.add_argument("--name", default=None, help="Display name for the sub-project (add)")
@@ -173,6 +174,12 @@ def build_parser(version: str, parse_cli_ide_arg):
173
174
  p_sub.add_argument("--mcp", action="store_true", help="Also reinstall MCP config on update (run update)")
174
175
  p_sub.add_argument("--fix", action="store_true", help="Repair links from the parent config (check)")
175
176
  p_sub.add_argument("--prune", action="store_true", help="With --fix: drop entries whose folder is gone (check)")
177
+ p_sub.add_argument("--depth", default=None, type=int,
178
+ help="Levels to descend (tree|run); default: the full hierarchy")
179
+ p_sub.add_argument("--init", action="store_true",
180
+ help="Initialize the folder if it is not a C3 project yet (link)")
181
+ p_sub.add_argument("--no-detect", action="store_true",
182
+ help="Skip the scan for unlinked nested projects (inspect)")
176
183
  p_sub.add_argument("--json", action="store_true", help="Emit JSON output")
177
184
 
178
185
  p_perms = subparsers.add_parser("permissions",
@@ -407,6 +414,21 @@ def build_parser(version: str, parse_cli_ide_arg):
407
414
  jr_default.add_argument("project_path", nargs="?", default=".")
408
415
 
409
416
  # ── Credential vault (v2.58.0) ──────────────────────────────────────
417
+ # ── Tokens ──────────────────────────────────────────────────────────
418
+ p_tokens = subparsers.add_parser(
419
+ "tokens",
420
+ help="Token usage — per tool, per day, per session, per file",
421
+ )
422
+ p_tokens.add_argument("--days", type=int, default=30,
423
+ help="Window in days; 0 = all recorded history (default: 30)")
424
+ p_tokens.add_argument("--by", default="tool",
425
+ choices=["tool", "day", "session", "file"],
426
+ help="Which breakdown to print (default: tool)")
427
+ p_tokens.add_argument("--limit", type=int, default=15,
428
+ help="Rows to show (default: 15)")
429
+ p_tokens.add_argument("--json", action="store_true",
430
+ help="Emit the full aggregate as JSON")
431
+
410
432
  p_creds = subparsers.add_parser(
411
433
  "creds",
412
434
  help="Credential vault — named secrets for agents (global + per-project)",
@@ -452,6 +474,8 @@ def build_parser(version: str, parse_cli_ide_arg):
452
474
  cr_import.add_argument("env_file", help="Path to the .env file")
453
475
  cr_import.add_argument("--global", dest="use_global", action="store_true", help="Import into the global scope")
454
476
  cr_import.add_argument("--overwrite", action="store_true", help="Replace entries already registered in the target scope")
477
+ cr_import.add_argument("--dry-run", dest="dry_run", action="store_true", help="Show what would be imported; write nothing")
478
+ cr_import.add_argument("--only", default="", help="Comma-separated names to import (default: all)")
455
479
  cr_import.add_argument("--path", dest="project_path", default=".", help="Project directory (default: current)")
456
480
 
457
481
  cr_usage = creds_subs.add_parser(
@@ -461,6 +485,20 @@ def build_parser(version: str, parse_cli_ide_arg):
461
485
  cr_usage.add_argument("--json", dest="as_json", action="store_true", help="Emit raw JSON")
462
486
  cr_usage.add_argument("--path", dest="project_path", default=".", help="Project directory (default: current)")
463
487
 
488
+ cr_audit = creds_subs.add_parser(
489
+ "audit", help="Audit trail — every change AND use, on one timeline")
490
+ cr_audit.add_argument("name", nargs="?", default="", help="Limit to one credential (default: all)")
491
+ cr_audit.add_argument("--kind", default="", choices=["", "use", "change"],
492
+ help="Show only uses or only changes (default: both)")
493
+ cr_audit.add_argument("--action", default="",
494
+ help="Exact action: inject_env, template, reveal, cli_show, set, update, delete, import…")
495
+ cr_audit.add_argument("--surface", default="", help="Exact surface: shell, cli, mcp, ui, hub")
496
+ cr_audit.add_argument("--since", default="", help="ISO timestamp lower bound, e.g. 2026-08-01")
497
+ cr_audit.add_argument("-q", dest="q", default="", help="Free-text over name/field/cmd/project")
498
+ cr_audit.add_argument("--limit", type=int, default=40, help="Events to show (default: 40)")
499
+ cr_audit.add_argument("--json", dest="as_json", action="store_true", help="Emit raw JSON")
500
+ cr_audit.add_argument("--path", dest="project_path", default=".", help="Project directory (default: current)")
501
+
464
502
  # ── Agent Locks (docs/agent-locks.md) ───────────────────────────────
465
503
  # force-release is human-only: it bumps the fencing counter so a holder
466
504
  # that comes back is stale by construction. Agents get c3_locks instead,