code-context-control 2.57.1__tar.gz → 2.59.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 (354) hide show
  1. {code_context_control-2.57.1 → code_context_control-2.59.0}/PKG-INFO +49 -2
  2. {code_context_control-2.57.1 → code_context_control-2.59.0}/README.md +48 -1
  3. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/c3.py +147 -2
  4. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/commands/parser.py +42 -0
  5. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/guide/tools.html +41 -0
  6. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_server.py +273 -2
  7. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/app.js +4 -2
  8. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/drill_panel.js +2 -0
  9. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/drill_views.js +7 -1
  10. code_context_control-2.59.0/cli/hub_ui/components/hub_credentials.js +516 -0
  11. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/topbar.js +1 -1
  12. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/mcp_server.py +59 -4
  13. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/server.py +147 -0
  14. code_context_control-2.59.0/cli/tools/credentials.py +239 -0
  15. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/project.py +5 -1
  16. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/shell.py +55 -5
  17. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui/app.js +4 -0
  18. code_context_control-2.59.0/cli/ui/components/credentials.js +365 -0
  19. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui/icons.js +2 -0
  20. {code_context_control-2.57.1 → code_context_control-2.59.0}/code_context_control.egg-info/PKG-INFO +49 -2
  21. {code_context_control-2.57.1 → code_context_control-2.59.0}/code_context_control.egg-info/SOURCES.txt +11 -0
  22. {code_context_control-2.57.1 → code_context_control-2.59.0}/pyproject.toml +1 -1
  23. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/claude_md.py +1 -0
  24. code_context_control-2.59.0/services/credential_store.py +643 -0
  25. code_context_control-2.59.0/tests/test_credential_store.py +270 -0
  26. code_context_control-2.59.0/tests/test_credentials_routes.py +175 -0
  27. code_context_control-2.59.0/tests/test_credentials_tool.py +202 -0
  28. code_context_control-2.59.0/tests/test_creds_cli_smoke.py +150 -0
  29. code_context_control-2.59.0/tests/test_hub_credentials_route.py +86 -0
  30. code_context_control-2.59.0/tests/test_hub_credentials_routes_write.py +364 -0
  31. code_context_control-2.59.0/tests/test_shell_creds.py +172 -0
  32. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_tool_registry.py +4 -1
  33. {code_context_control-2.57.1 → code_context_control-2.59.0}/LICENSE +0 -0
  34. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/__init__.py +0 -0
  35. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/_hook_utils.py +0 -0
  36. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/commands/__init__.py +0 -0
  37. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/commands/common.py +0 -0
  38. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/docs.html +0 -0
  39. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/edits.html +0 -0
  40. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/guide/bitbucket.html +0 -0
  41. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/guide/getting-started.html +0 -0
  42. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/guide/index.html +0 -0
  43. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/guide/oracle.html +0 -0
  44. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/guide/shared.css +0 -0
  45. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/guide/workflow.html +0 -0
  46. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hook_artifact.py +0 -0
  47. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hook_auto_snapshot.py +0 -0
  48. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hook_c3_signal.py +0 -0
  49. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hook_c3read.py +0 -0
  50. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hook_dispatch.py +0 -0
  51. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hook_edit_ledger.py +0 -0
  52. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hook_edit_unlock.py +0 -0
  53. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hook_filter.py +0 -0
  54. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hook_ghost_files.py +0 -0
  55. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hook_pretool_enforce.py +0 -0
  56. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hook_prompt_recall.py +0 -0
  57. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hook_read.py +0 -0
  58. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hook_session_stats.py +0 -0
  59. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hook_terse_advisor.py +0 -0
  60. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub.html +0 -0
  61. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/add_project.js +0 -0
  62. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/config_editor.js +0 -0
  63. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
  64. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/drill_health.js +0 -0
  65. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
  66. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/drill_tasks.js +0 -0
  67. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/global_search.js +0 -0
  68. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/mcp_manager.js +0 -0
  69. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/modals.js +0 -0
  70. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/project_card.js +0 -0
  71. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/project_tree.js +0 -0
  72. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/session_drawer.js +0 -0
  73. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/settings_modal.js +0 -0
  74. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/sidebar.js +0 -0
  75. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/summary_bar.js +0 -0
  76. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/task_board.js +0 -0
  77. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/components/toasts.js +0 -0
  78. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui/state.js +0 -0
  79. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/hub_ui.html +0 -0
  80. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/mcp_proxy.py +0 -0
  81. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/progress.py +0 -0
  82. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/__init__.py +0 -0
  83. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/_helpers.py +0 -0
  84. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/agent.py +0 -0
  85. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/artifacts.py +0 -0
  86. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/bitbucket.py +0 -0
  87. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/compress.py +0 -0
  88. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/delegate.py +0 -0
  89. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/edit.py +0 -0
  90. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/edits.py +0 -0
  91. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/federate.py +0 -0
  92. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/filter.py +0 -0
  93. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/impact.py +0 -0
  94. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/jira.py +0 -0
  95. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/memory.py +0 -0
  96. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/read.py +0 -0
  97. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/search.py +0 -0
  98. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/session.py +0 -0
  99. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/status.py +0 -0
  100. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/tasks.py +0 -0
  101. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/tools/validate.py +0 -0
  102. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui/api.js +0 -0
  103. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui/components/bitbucket.js +0 -0
  104. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui/components/chat.js +0 -0
  105. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui/components/dashboard.js +0 -0
  106. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui/components/edits.js +0 -0
  107. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui/components/instructions.js +0 -0
  108. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui/components/jira.js +0 -0
  109. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui/components/memory.js +0 -0
  110. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui/components/sessions.js +0 -0
  111. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui/components/settings.js +0 -0
  112. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui/components/sidebar.js +0 -0
  113. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui/components/tasks.js +0 -0
  114. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui/pm_shared.js +0 -0
  115. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui/shared.js +0 -0
  116. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui/theme.js +0 -0
  117. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui.html +0 -0
  118. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui_legacy.html +0 -0
  119. {code_context_control-2.57.1 → code_context_control-2.59.0}/cli/ui_nano.html +0 -0
  120. {code_context_control-2.57.1 → code_context_control-2.59.0}/code_context_control.egg-info/dependency_links.txt +0 -0
  121. {code_context_control-2.57.1 → code_context_control-2.59.0}/code_context_control.egg-info/entry_points.txt +0 -0
  122. {code_context_control-2.57.1 → code_context_control-2.59.0}/code_context_control.egg-info/requires.txt +0 -0
  123. {code_context_control-2.57.1 → code_context_control-2.59.0}/code_context_control.egg-info/top_level.txt +0 -0
  124. {code_context_control-2.57.1 → code_context_control-2.59.0}/core/__init__.py +0 -0
  125. {code_context_control-2.57.1 → code_context_control-2.59.0}/core/config.py +0 -0
  126. {code_context_control-2.57.1 → code_context_control-2.59.0}/core/ide.py +0 -0
  127. {code_context_control-2.57.1 → code_context_control-2.59.0}/core/mcp_toml.py +0 -0
  128. {code_context_control-2.57.1 → code_context_control-2.59.0}/core/web_security.py +0 -0
  129. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/__init__.py +0 -0
  130. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/config.py +0 -0
  131. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/mcp_oracle.py +0 -0
  132. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/oracle_server.py +0 -0
  133. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/oracle_ui.html +0 -0
  134. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/services/__init__.py +0 -0
  135. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/services/activity_reporter.py +0 -0
  136. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/services/api_auth.py +0 -0
  137. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/services/c3_bridge.py +0 -0
  138. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/services/chat_engine.py +0 -0
  139. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/services/chat_store.py +0 -0
  140. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/services/cross_memory.py +0 -0
  141. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/services/federated_graph.py +0 -0
  142. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/services/health_checker.py +0 -0
  143. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/services/insight_engine.py +0 -0
  144. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/services/local_session.py +0 -0
  145. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/services/memory_reader.py +0 -0
  146. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/services/memory_writer.py +0 -0
  147. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/services/project_scanner.py +0 -0
  148. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/services/review_agent.py +0 -0
  149. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/services/tool_executor.py +0 -0
  150. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/services/tool_registry.py +0 -0
  151. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/activity.js +0 -0
  152. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/agents.js +0 -0
  153. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/app.js +0 -0
  154. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/busy.js +0 -0
  155. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/chat/conversations.js +0 -0
  156. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/chat/input.js +0 -0
  157. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/chat/markdown.js +0 -0
  158. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/chat/send.js +0 -0
  159. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/chat/stream_renderer.js +0 -0
  160. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/chat/toolbar.js +0 -0
  161. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/core.js +0 -0
  162. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/crossgraph.js +0 -0
  163. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/header.js +0 -0
  164. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/insights.js +0 -0
  165. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/projects.js +0 -0
  166. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/settings.js +0 -0
  167. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/suggestions.js +0 -0
  168. {code_context_control-2.57.1 → code_context_control-2.59.0}/oracle/ui/theme_tabs.js +0 -0
  169. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/__init__.py +0 -0
  170. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/activity_log.py +0 -0
  171. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/agent_base.py +0 -0
  172. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/agents.py +0 -0
  173. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/artifact_defs.py +0 -0
  174. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/artifact_store.py +0 -0
  175. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/auto_memory.py +0 -0
  176. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/bench/__init__.py +0 -0
  177. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/bench/external/__init__.py +0 -0
  178. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/bench/external/aider_polyglot.py +0 -0
  179. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/bench/external/swe_bench.py +0 -0
  180. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/benchmark_dashboard.py +0 -0
  181. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/bitbucket_client.py +0 -0
  182. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/bitbucket_credentials.py +0 -0
  183. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/circuit_breaker.py +0 -0
  184. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/compressor.py +0 -0
  185. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/context_snapshot.py +0 -0
  186. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/conversation_store.py +0 -0
  187. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/doc_index.py +0 -0
  188. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/e2e_benchmark.py +0 -0
  189. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/e2e_evaluator.py +0 -0
  190. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/e2e_tasks.py +0 -0
  191. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/edit_ledger.py +0 -0
  192. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/embedding_index.py +0 -0
  193. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/error_reporting.py +0 -0
  194. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/file_memory.py +0 -0
  195. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/git_context.py +0 -0
  196. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/hub_service.py +0 -0
  197. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/indexer.py +0 -0
  198. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/jira_client.py +0 -0
  199. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/jira_cloud.py +0 -0
  200. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/jira_credentials.py +0 -0
  201. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/jira_data_center.py +0 -0
  202. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/jira_links.py +0 -0
  203. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/memory.py +0 -0
  204. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/memory_consolidator.py +0 -0
  205. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/memory_distiller.py +0 -0
  206. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/memory_graph.py +0 -0
  207. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/memory_grounder.py +0 -0
  208. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/memory_queue.py +0 -0
  209. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/memory_scorer.py +0 -0
  210. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/metrics.py +0 -0
  211. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/notifications.py +0 -0
  212. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/ollama_bridge.py +0 -0
  213. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/ollama_client.py +0 -0
  214. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/ollama_credentials.py +0 -0
  215. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/output_filter.py +0 -0
  216. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/parser.py +0 -0
  217. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/project_manager.py +0 -0
  218. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/project_runtime.py +0 -0
  219. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/protocol.py +0 -0
  220. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/proxy_state.py +0 -0
  221. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/retention.py +0 -0
  222. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/retrieval_broker.py +0 -0
  223. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/router.py +0 -0
  224. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/runtime.py +0 -0
  225. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/scanner.py +0 -0
  226. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/session_benchmark.py +0 -0
  227. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/session_manager.py +0 -0
  228. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/session_preloader.py +0 -0
  229. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/subprojects.py +0 -0
  230. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/task_store.py +0 -0
  231. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/telemetry.py +0 -0
  232. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/text_index.py +0 -0
  233. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/time_tracker.py +0 -0
  234. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/tool_classifier.py +0 -0
  235. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/transcript_index.py +0 -0
  236. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/validation_cache.py +0 -0
  237. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/vector_store.py +0 -0
  238. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/watcher.py +0 -0
  239. {code_context_control-2.57.1 → code_context_control-2.59.0}/services/win_subprocess.py +0 -0
  240. {code_context_control-2.57.1 → code_context_control-2.59.0}/setup.cfg +0 -0
  241. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_activity_reporter.py +0 -0
  242. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_aider_polyglot.py +0 -0
  243. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_antigravity_transition.py +0 -0
  244. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_artifact_store.py +0 -0
  245. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_artifact_tool.py +0 -0
  246. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_bitbucket_cli_smoke.py +0 -0
  247. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_bitbucket_client.py +0 -0
  248. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_bitbucket_config_fallback.py +0 -0
  249. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_bitbucket_credentials.py +0 -0
  250. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_bitbucket_tool.py +0 -0
  251. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
  252. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_c3_shell.py +0 -0
  253. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_circuit_breaker.py +0 -0
  254. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_claude_md_merge.py +0 -0
  255. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_cli_smoke.py +0 -0
  256. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_compressor_large_file.py +0 -0
  257. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_delegate_cascade.py +0 -0
  258. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_e2e_benchmark.py +0 -0
  259. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_edit_ledger_hook.py +0 -0
  260. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_edit_normalization.py +0 -0
  261. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_enforcement_flip.py +0 -0
  262. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_federated_graph.py +0 -0
  263. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_filter_backoff.py +0 -0
  264. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_ghost_files.py +0 -0
  265. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_ghost_generation.py +0 -0
  266. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_git_branch_awareness.py +0 -0
  267. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_hook_dispatch.py +0 -0
  268. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_hook_pretool_enforce.py +0 -0
  269. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_hook_prompt_recall.py +0 -0
  270. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_hook_smoke.py +0 -0
  271. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_hook_state.py +0 -0
  272. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_hook_utf8_stdio.py +0 -0
  273. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_hub_inspect_api.py +0 -0
  274. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_hub_server_smoke.py +0 -0
  275. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_hub_subproject_links.py +0 -0
  276. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_init_scan.py +0 -0
  277. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_install_mcp_entrypoint.py +0 -0
  278. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_jira_cli_smoke.py +0 -0
  279. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_jira_client.py +0 -0
  280. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_jira_config_fallback.py +0 -0
  281. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_jira_credentials.py +0 -0
  282. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_jira_links.py +0 -0
  283. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_jira_routes.py +0 -0
  284. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_jira_tool.py +0 -0
  285. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_lazy_store_init.py +0 -0
  286. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_mcp_host_guard.py +0 -0
  287. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_mcp_memory_timeout.py +0 -0
  288. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_mcp_server_smoke.py +0 -0
  289. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_mcp_toml.py +0 -0
  290. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_memory_distiller.py +0 -0
  291. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_memory_graph_api.py +0 -0
  292. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_memory_queue.py +0 -0
  293. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_memory_system.py +0 -0
  294. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_notification_dedup.py +0 -0
  295. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_notification_discipline.py +0 -0
  296. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_ollama_credentials.py +0 -0
  297. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_oracle_api_auth.py +0 -0
  298. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_oracle_apikey_api.py +0 -0
  299. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_oracle_c3_bridge.py +0 -0
  300. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_oracle_chat_engine.py +0 -0
  301. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_oracle_discovery_api.py +0 -0
  302. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_oracle_local_auth.py +0 -0
  303. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_oracle_ollama_bridge.py +0 -0
  304. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_oracle_scanner_cache.py +0 -0
  305. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_oracle_security_fixes.py +0 -0
  306. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_oracle_subproject_awareness.py +0 -0
  307. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_oracle_ui_bundle.py +0 -0
  308. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_output_filter.py +0 -0
  309. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_permissions.py +0 -0
  310. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_pm_api.py +0 -0
  311. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_project_manager.py +0 -0
  312. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_project_manager_merge.py +0 -0
  313. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_project_tool.py +0 -0
  314. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_read_coercion.py +0 -0
  315. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_read_edit_parity.py +0 -0
  316. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_related_facts.py +0 -0
  317. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_response_boilerplate.py +0 -0
  318. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_retention.py +0 -0
  319. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_review_digest.py +0 -0
  320. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_service_durability.py +0 -0
  321. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_session_benchmark.py +0 -0
  322. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_session_budget.py +0 -0
  323. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_shell_robustness.py +0 -0
  324. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_subproject_exclusion.py +0 -0
  325. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_subproject_federation.py +0 -0
  326. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_subprojects.py +0 -0
  327. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_swe_bench.py +0 -0
  328. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_task_store.py +0 -0
  329. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_task_tool.py +0 -0
  330. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_time_tracker.py +0 -0
  331. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_token_telemetry.py +0 -0
  332. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_upgrade_and_version.py +0 -0
  333. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_validate.py +0 -0
  334. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_version_sync.py +0 -0
  335. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_web_security.py +0 -0
  336. {code_context_control-2.57.1 → code_context_control-2.59.0}/tests/test_windows_reliability.py +0 -0
  337. {code_context_control-2.57.1 → code_context_control-2.59.0}/tui/__init__.py +0 -0
  338. {code_context_control-2.57.1 → code_context_control-2.59.0}/tui/backend.py +0 -0
  339. {code_context_control-2.57.1 → code_context_control-2.59.0}/tui/main.py +0 -0
  340. {code_context_control-2.57.1 → code_context_control-2.59.0}/tui/screens/__init__.py +0 -0
  341. {code_context_control-2.57.1 → code_context_control-2.59.0}/tui/screens/benchmark_view.py +0 -0
  342. {code_context_control-2.57.1 → code_context_control-2.59.0}/tui/screens/claudemd_view.py +0 -0
  343. {code_context_control-2.57.1 → code_context_control-2.59.0}/tui/screens/compress_view.py +0 -0
  344. {code_context_control-2.57.1 → code_context_control-2.59.0}/tui/screens/index_view.py +0 -0
  345. {code_context_control-2.57.1 → code_context_control-2.59.0}/tui/screens/init_view.py +0 -0
  346. {code_context_control-2.57.1 → code_context_control-2.59.0}/tui/screens/mcp_view.py +0 -0
  347. {code_context_control-2.57.1 → code_context_control-2.59.0}/tui/screens/optimize_view.py +0 -0
  348. {code_context_control-2.57.1 → code_context_control-2.59.0}/tui/screens/pipe_view.py +0 -0
  349. {code_context_control-2.57.1 → code_context_control-2.59.0}/tui/screens/projects_view.py +0 -0
  350. {code_context_control-2.57.1 → code_context_control-2.59.0}/tui/screens/search_view.py +0 -0
  351. {code_context_control-2.57.1 → code_context_control-2.59.0}/tui/screens/session_view.py +0 -0
  352. {code_context_control-2.57.1 → code_context_control-2.59.0}/tui/screens/stats.py +0 -0
  353. {code_context_control-2.57.1 → code_context_control-2.59.0}/tui/screens/ui_view.py +0 -0
  354. {code_context_control-2.57.1 → code_context_control-2.59.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.57.1
3
+ Version: 2.59.0
4
4
  Summary: Local code-intelligence layer for AI coding tools (Claude Code, Codex, Copilot, Cursor, Antigravity). Retrieve less, read less, edit safer — version the configs that shape your agent (CLAUDE.md, skills, hooks, MCP), and manage multi-project + sub-project hierarchies from a local hub.
5
5
  Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -283,6 +283,7 @@ C3 exposes 18 tools as a native MCP server. Your IDE calls them directly:
283
283
  | `c3_edits` | Edit-ledger queries + version diffs + restore points + per-branch filter |
284
284
  | `c3_bitbucket` | Bitbucket Data Center integration — PRs, branches, builds, repo admin (v2.30.0) |
285
285
  | `c3_jira` | Jira integration — Cloud + Data Center: JQL search, issues, transitions, My Work board (v2.56.0) |
286
+ | `c3_credentials` | Credential vault — named secrets (global + per-project), injection-first: agents use them by name, values never enter model context (v2.58.0) |
286
287
  | `c3_project` | Cross-project — discover & operate on other c3-installed projects; guarded writes (v2.31.0) |
287
288
  | `c3_task` | Durable per-project PM — tasks with dependencies & subtasks, milestones, decision notes, event history, health reports, and auto+manual time tracking (v2.53.0) |
288
289
  | `c3_artifacts` | Agent-config tracking — version history, diff & restore for CLAUDE.md, settings/hooks, MCP configs, skills (v2.46.0) |
@@ -291,7 +292,7 @@ On Windows, `c3_shell` uses Git Bash when available. Git Bash does not bundle
291
292
  optional utilities such as `jq`; use `python -m json.tool` for portable JSON
292
293
  formatting, or install `jq` separately when filter expressions are required.
293
294
 
294
- Every tool is **read-only safe in plan mode** (except `c3_edit`, `c3_shell`, `c3_artifacts(action='restore')`, and write actions on `c3_bitbucket` / `c3_jira` / `c3_project` / `c3_task`).
295
+ Every tool is **read-only safe in plan mode** (except `c3_edit`, `c3_shell`, `c3_artifacts(action='restore')`, and write actions on `c3_bitbucket` / `c3_jira` / `c3_credentials` / `c3_project` / `c3_task`).
295
296
 
296
297
  ### Bitbucket Data Center / Server (v2.30.0)
297
298
 
@@ -319,6 +320,52 @@ it has no active account C3 falls back to the global `~/.c3/config.json`. So a
319
320
  single `login --global` (or any login done from your home directory) is reusable
320
321
  across every C3 project — the PAT always lives in the OS keyring, never on disk.
321
322
 
323
+ ### Credential vault (v2.58.0)
324
+
325
+ `c3_credentials` gives agents a protected, user-managed place for API keys,
326
+ tokens, and `.env`-style values — **global** (`~/.c3`, every project) or
327
+ **per-project** (`.c3`, shadows the global name). Values live in the **OS
328
+ keyring** (large values in a Fernet-encrypted `.c3/secrets.enc` whose master
329
+ key lives in the keyring) — never in config files, and *never in the model's
330
+ context*: the agent addresses secrets by name and C3 decodes them only at the
331
+ subprocess boundary.
332
+
333
+ ```bash
334
+ # Store a secret for this project (value prompted, masked)
335
+ c3 creds set OPENAI_KEY --desc "OpenAI billing key"
336
+
337
+ # ...or globally for every C3 project
338
+ c3 creds set NPM_TOKEN --global
339
+
340
+ # Bulk-import an existing .env; list what the agent can see
341
+ c3 creds import .env
342
+ c3 creds list
343
+ ```
344
+
345
+ The agent then runs commands *with* the secret but without ever seeing it:
346
+
347
+ ```
348
+ c3_shell(cmd='npm publish', env_creds='NPM_TOKEN') # injected as env var
349
+ c3_shell(cmd='curl -H "Authorization: Bearer {{cred:OPENAI_KEY}}" …') # expanded server-side
350
+ ```
351
+
352
+ Echoed values are auto-redacted from output (`env` dumps come back as
353
+ `[cred:NAME]`), every use is ledger-logged by name, and `reveal` — the only
354
+ action that returns a value — is disabled per entry until you flip
355
+ `agent_readable` in the **Credentials UI tab** or via
356
+ `c3 creds set NAME --agent-readable`. A hostile repo config can't siphon your
357
+ global secrets (realm-atomic resolution, tested), cross-project shells run
358
+ with credentials disabled, and the vault is hard-excluded from the Oracle
359
+ Discovery API.
360
+
361
+ Since **v2.59.0** the Hub has a top-level **Credentials** view: manage the
362
+ global vault (`~/.c3`) and every registered project's entries from one place —
363
+ create / edit / delete / `.env` import / flag toggles, with shadowing shown
364
+ both ways ("shadows global" on project entries, "shadowed in N projects" on
365
+ globals). The write-only wire contract extends to the hub: values are
366
+ submitted inbound-only and **no hub route ever returns a stored value** (there
367
+ is no `reveal` on the hub at all).
368
+
322
369
  ### Jira — Cloud + Data Center (v2.56.0)
323
370
 
324
371
  `c3_jira` connects to Jira Cloud (REST v3, email + API token) or self-hosted
@@ -220,6 +220,7 @@ C3 exposes 18 tools as a native MCP server. Your IDE calls them directly:
220
220
  | `c3_edits` | Edit-ledger queries + version diffs + restore points + per-branch filter |
221
221
  | `c3_bitbucket` | Bitbucket Data Center integration — PRs, branches, builds, repo admin (v2.30.0) |
222
222
  | `c3_jira` | Jira integration — Cloud + Data Center: JQL search, issues, transitions, My Work board (v2.56.0) |
223
+ | `c3_credentials` | Credential vault — named secrets (global + per-project), injection-first: agents use them by name, values never enter model context (v2.58.0) |
223
224
  | `c3_project` | Cross-project — discover & operate on other c3-installed projects; guarded writes (v2.31.0) |
224
225
  | `c3_task` | Durable per-project PM — tasks with dependencies & subtasks, milestones, decision notes, event history, health reports, and auto+manual time tracking (v2.53.0) |
225
226
  | `c3_artifacts` | Agent-config tracking — version history, diff & restore for CLAUDE.md, settings/hooks, MCP configs, skills (v2.46.0) |
@@ -228,7 +229,7 @@ On Windows, `c3_shell` uses Git Bash when available. Git Bash does not bundle
228
229
  optional utilities such as `jq`; use `python -m json.tool` for portable JSON
229
230
  formatting, or install `jq` separately when filter expressions are required.
230
231
 
231
- Every tool is **read-only safe in plan mode** (except `c3_edit`, `c3_shell`, `c3_artifacts(action='restore')`, and write actions on `c3_bitbucket` / `c3_jira` / `c3_project` / `c3_task`).
232
+ Every tool is **read-only safe in plan mode** (except `c3_edit`, `c3_shell`, `c3_artifacts(action='restore')`, and write actions on `c3_bitbucket` / `c3_jira` / `c3_credentials` / `c3_project` / `c3_task`).
232
233
 
233
234
  ### Bitbucket Data Center / Server (v2.30.0)
234
235
 
@@ -256,6 +257,52 @@ it has no active account C3 falls back to the global `~/.c3/config.json`. So a
256
257
  single `login --global` (or any login done from your home directory) is reusable
257
258
  across every C3 project — the PAT always lives in the OS keyring, never on disk.
258
259
 
260
+ ### Credential vault (v2.58.0)
261
+
262
+ `c3_credentials` gives agents a protected, user-managed place for API keys,
263
+ tokens, and `.env`-style values — **global** (`~/.c3`, every project) or
264
+ **per-project** (`.c3`, shadows the global name). Values live in the **OS
265
+ keyring** (large values in a Fernet-encrypted `.c3/secrets.enc` whose master
266
+ key lives in the keyring) — never in config files, and *never in the model's
267
+ context*: the agent addresses secrets by name and C3 decodes them only at the
268
+ subprocess boundary.
269
+
270
+ ```bash
271
+ # Store a secret for this project (value prompted, masked)
272
+ c3 creds set OPENAI_KEY --desc "OpenAI billing key"
273
+
274
+ # ...or globally for every C3 project
275
+ c3 creds set NPM_TOKEN --global
276
+
277
+ # Bulk-import an existing .env; list what the agent can see
278
+ c3 creds import .env
279
+ c3 creds list
280
+ ```
281
+
282
+ The agent then runs commands *with* the secret but without ever seeing it:
283
+
284
+ ```
285
+ c3_shell(cmd='npm publish', env_creds='NPM_TOKEN') # injected as env var
286
+ c3_shell(cmd='curl -H "Authorization: Bearer {{cred:OPENAI_KEY}}" …') # expanded server-side
287
+ ```
288
+
289
+ Echoed values are auto-redacted from output (`env` dumps come back as
290
+ `[cred:NAME]`), every use is ledger-logged by name, and `reveal` — the only
291
+ action that returns a value — is disabled per entry until you flip
292
+ `agent_readable` in the **Credentials UI tab** or via
293
+ `c3 creds set NAME --agent-readable`. A hostile repo config can't siphon your
294
+ global secrets (realm-atomic resolution, tested), cross-project shells run
295
+ with credentials disabled, and the vault is hard-excluded from the Oracle
296
+ Discovery API.
297
+
298
+ Since **v2.59.0** the Hub has a top-level **Credentials** view: manage the
299
+ global vault (`~/.c3`) and every registered project's entries from one place —
300
+ create / edit / delete / `.env` import / flag toggles, with shadowing shown
301
+ both ways ("shadows global" on project entries, "shadowed in N projects" on
302
+ globals). The write-only wire contract extends to the hub: values are
303
+ submitted inbound-only and **no hub route ever returns a stored value** (there
304
+ is no `reveal` on the hub at all).
305
+
259
306
  ### Jira — Cloud + Data Center (v2.56.0)
260
307
 
261
308
  `c3_jira` connects to Jira Cloud (REST v3, email + API token) or self-hosted
@@ -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.57.1"
95
+ __version__ = "2.59.0"
96
96
 
97
97
 
98
98
  def _command_deps() -> CommandDeps:
@@ -248,7 +248,7 @@ _C3_MCP_ALLOW = [
248
248
  "mcp__c3__c3_memory", "mcp__c3__c3_validate", "mcp__c3__c3_edit",
249
249
  "mcp__c3__c3_agent", "mcp__c3__c3_delegate", "mcp__c3__c3_edits",
250
250
  "mcp__c3__c3_impact", "mcp__c3__c3_shell", "mcp__c3__c3_bitbucket",
251
- "mcp__c3__c3_jira",
251
+ "mcp__c3__c3_jira", "mcp__c3__c3_credentials",
252
252
  "mcp__c3__c3_project", "mcp__c3__c3_task", "mcp__c3__c3_artifacts",
253
253
  ]
254
254
 
@@ -5738,6 +5738,150 @@ def _bb_cmd_set_default(args, project_path: str) -> None:
5738
5738
  print(f"[OK] Default repo: {args.project}/{args.repo}")
5739
5739
 
5740
5740
 
5741
+ def cmd_creds(args):
5742
+ """Credential vault management (global + per-project scopes)."""
5743
+ sub = getattr(args, "creds_cmd", None)
5744
+ if not sub:
5745
+ print("Usage: c3 creds {set,get,list,rm,import} [args]")
5746
+ return
5747
+
5748
+ project_path = getattr(args, "project_path", ".") or "."
5749
+
5750
+ if sub == "set":
5751
+ _creds_cmd_set(args, project_path)
5752
+ elif sub == "get":
5753
+ _creds_cmd_get(args, project_path)
5754
+ elif sub == "list":
5755
+ _creds_cmd_list(args, project_path)
5756
+ elif sub == "rm":
5757
+ _creds_cmd_rm(args, project_path)
5758
+ elif sub == "import":
5759
+ _creds_cmd_import(args, project_path)
5760
+ else:
5761
+ print(f"Unknown creds subcommand: {sub}")
5762
+
5763
+
5764
+ def _creds_scope(args) -> str:
5765
+ return "global" if getattr(args, "use_global", False) else "project"
5766
+
5767
+
5768
+ def _creds_entry_line(name: str, entry: dict) -> str:
5769
+ flags = [f for f in ("inject", "agent_readable") if entry.get(f)]
5770
+ parts = [
5771
+ f"{name:<24} {entry.get('scope', '?'):<8} {entry.get('type', 'token'):<10}"
5772
+ f" len={entry.get('value_len', '?')}",
5773
+ ]
5774
+ if entry.get("env_var"):
5775
+ parts.append(f"env_var={entry['env_var']}")
5776
+ if flags:
5777
+ parts.append("[" + ",".join(flags) + "]")
5778
+ if entry.get("description"):
5779
+ parts.append(f"-- {entry['description']}")
5780
+ return " ".join(parts)
5781
+
5782
+
5783
+ def _creds_cmd_set(args, project_path: str) -> None:
5784
+ import getpass
5785
+
5786
+ from services import credential_store as cred_store
5787
+
5788
+ value = getattr(args, "value", "") or ""
5789
+ if getattr(args, "stdin", False):
5790
+ value = sys.stdin.read().rstrip("\n")
5791
+ if not value:
5792
+ value = getpass.getpass(f"Value for {args.name}: ")
5793
+ if not value:
5794
+ print("Cancelled -- value required.")
5795
+ return
5796
+ scope = _creds_scope(args)
5797
+ try:
5798
+ entry = cred_store.set_credential(
5799
+ args.name, value,
5800
+ scope=scope, project_path=project_path,
5801
+ description=getattr(args, "desc", "") or "",
5802
+ ctype=getattr(args, "ctype", "token") or "token",
5803
+ env_var=getattr(args, "env_var", "") or "",
5804
+ agent_readable=bool(getattr(args, "agent_readable", False)),
5805
+ inject=bool(getattr(args, "inject", False)),
5806
+ )
5807
+ except (cred_store.CredentialError, RuntimeError) as exc:
5808
+ print(f"[error] {exc}")
5809
+ return
5810
+ print(f"[OK] Stored credential '{args.name}' "
5811
+ f"(scope={scope}, storage={entry['storage']}, len={entry['value_len']})")
5812
+ if entry["agent_readable"]:
5813
+ print("[warn] agent_readable=true -- the agent can read this value "
5814
+ "into its context and transcripts.")
5815
+
5816
+
5817
+ def _creds_cmd_get(args, project_path: str) -> None:
5818
+ from services import credential_store as cred_store
5819
+
5820
+ entry = cred_store.get_entry(args.name, project_path=project_path)
5821
+ if not entry:
5822
+ print(f"[error] no credential named '{args.name}'")
5823
+ return
5824
+ print(_creds_entry_line(args.name, entry))
5825
+ print(f"storage={entry.get('storage', 'keyring')} "
5826
+ f"created={entry.get('created', '?')} updated={entry.get('updated', '?')}")
5827
+ fp = cred_store.fingerprint(args.name, project_path=project_path)
5828
+ print(f"fingerprint={fp or 'unresolvable'}")
5829
+ if getattr(args, "show", False):
5830
+ value = cred_store.get_value(args.name, project_path=project_path)
5831
+ print(value if value is not None else "[error] value missing from store")
5832
+
5833
+
5834
+ def _creds_cmd_list(args, project_path: str) -> None:
5835
+ from services import credential_store as cred_store
5836
+
5837
+ entries = cred_store.list_entries(project_path)
5838
+ if not entries:
5839
+ print("No credentials registered. Use `c3 creds set NAME` "
5840
+ "(add --global for all projects).")
5841
+ return
5842
+ print(f"{len(entries)} credential(s) — project scope shadows global:")
5843
+ for name, entry in entries.items():
5844
+ print(" " + _creds_entry_line(name, entry))
5845
+
5846
+
5847
+ def _creds_cmd_rm(args, project_path: str) -> None:
5848
+ from services import credential_store as cred_store
5849
+
5850
+ scope = _creds_scope(args)
5851
+ entry = cred_store.get_entry(args.name, project_path=project_path)
5852
+ if entry and entry["scope"] == "global" and scope == "project":
5853
+ print(f"[error] '{args.name}' is a global credential -- "
5854
+ "re-run with --global to delete it.")
5855
+ return
5856
+ if cred_store.delete_credential(args.name, scope=scope, project_path=project_path):
5857
+ print(f"[OK] Removed credential '{args.name}' (scope={scope})")
5858
+ else:
5859
+ print(f"[error] no credential named '{args.name}' in {scope} scope")
5860
+
5861
+
5862
+ def _creds_cmd_import(args, project_path: str) -> None:
5863
+ from services import credential_store as cred_store
5864
+
5865
+ env_path = Path(getattr(args, "env_file", ""))
5866
+ if not env_path.exists():
5867
+ print(f"[error] file not found: {env_path}")
5868
+ return
5869
+ try:
5870
+ text = env_path.read_text(encoding="utf-8")
5871
+ result = cred_store.import_env(
5872
+ text, scope=_creds_scope(args), project_path=project_path,
5873
+ overwrite=bool(getattr(args, "overwrite", False)),
5874
+ )
5875
+ except (cred_store.CredentialError, RuntimeError) as exc:
5876
+ print(f"[error] {exc}")
5877
+ return
5878
+ print(f"[OK] Imported {len(result['created'])} credential(s): "
5879
+ f"{', '.join(result['created']) or '-'}")
5880
+ if result["skipped"]:
5881
+ print(f"Skipped {len(result['skipped'])}: {', '.join(result['skipped'])} "
5882
+ "(use --overwrite to replace)")
5883
+
5884
+
5741
5885
  def cmd_jira(args):
5742
5886
  """Jira Cloud / Data Center credential + workspace management."""
5743
5887
  sub = getattr(args, "jira_cmd", None)
@@ -7036,6 +7180,7 @@ def main():
7036
7180
  "hub": cmd_hub,
7037
7181
  "bitbucket": cmd_bitbucket,
7038
7182
  "jira": cmd_jira,
7183
+ "creds": cmd_creds,
7039
7184
  "oracle": cmd_oracle,
7040
7185
  "upgrade": cmd_upgrade,
7041
7186
  }
@@ -401,6 +401,48 @@ def build_parser(version: str, parse_cli_ide_arg):
401
401
  jr_default.add_argument("--name", default="", help="Account name (defaults to the default account)")
402
402
  jr_default.add_argument("project_path", nargs="?", default=".")
403
403
 
404
+ # ── Credential vault (v2.58.0) ──────────────────────────────────────
405
+ p_creds = subparsers.add_parser(
406
+ "creds",
407
+ help="Credential vault — named secrets for agents (global + per-project)",
408
+ )
409
+ creds_subs = p_creds.add_subparsers(dest="creds_cmd")
410
+
411
+ cr_set = creds_subs.add_parser(
412
+ "set", help="Create or update a credential (value via hidden prompt)"
413
+ )
414
+ cr_set.add_argument("name", help="Entry name (env-var safe: [A-Za-z_][A-Za-z0-9_]*)")
415
+ cr_set.add_argument("--value", default="", help="Secret value (prompted via getpass if omitted — preferred)")
416
+ cr_set.add_argument("--stdin", action="store_true", help="Read the value from stdin (piped/multiline values)")
417
+ cr_set.add_argument("--type", dest="ctype", choices=["token", "env", "multiline"], default="token", help="Entry type")
418
+ cr_set.add_argument("--desc", default="", help="Human description shown in list/UI")
419
+ cr_set.add_argument("--env-var", default="", help="Env var name used at injection (default: entry name)")
420
+ cr_set.add_argument("--agent-readable", action="store_true", help="Allow the agent to reveal the decoded value into its context (default: injection-only)")
421
+ cr_set.add_argument("--inject", action="store_true", help="Auto-inject into every c3_shell run")
422
+ cr_set.add_argument("--global", dest="use_global", action="store_true", help="Store in the global scope (~/.c3) so every C3 project can use it")
423
+ # --path (not a trailing positional): a second positional after options
424
+ # breaks argparse on py<3.12 ("unrecognized arguments").
425
+ cr_set.add_argument("--path", dest="project_path", default=".", help="Project directory (default: current)")
426
+
427
+ cr_get = creds_subs.add_parser("get", help="Show entry metadata (masked; --show prints the value)")
428
+ cr_get.add_argument("name")
429
+ cr_get.add_argument("--show", action="store_true", help="Print the decoded value to the terminal")
430
+ cr_get.add_argument("--path", dest="project_path", default=".", help="Project directory (default: current)")
431
+
432
+ cr_list = creds_subs.add_parser("list", help="List credentials visible to this project")
433
+ cr_list.add_argument("--path", dest="project_path", default=".", help="Project directory (default: current)")
434
+
435
+ cr_rm = creds_subs.add_parser("rm", help="Delete a credential (value + registry entry)")
436
+ cr_rm.add_argument("name")
437
+ cr_rm.add_argument("--global", dest="use_global", action="store_true", help="Delete from the global scope")
438
+ cr_rm.add_argument("--path", dest="project_path", default=".", help="Project directory (default: current)")
439
+
440
+ cr_import = creds_subs.add_parser("import", help="Import KEY=VALUE lines from a .env file")
441
+ cr_import.add_argument("env_file", help="Path to the .env file")
442
+ cr_import.add_argument("--global", dest="use_global", action="store_true", help="Import into the global scope")
443
+ cr_import.add_argument("--overwrite", action="store_true", help="Replace entries already registered in the target scope")
444
+ cr_import.add_argument("--path", dest="project_path", default=".", help="Project directory (default: current)")
445
+
404
446
  # ── Oracle Discovery API (v2.32.0) ──────────────────────────────────
405
447
  p_oracle = subparsers.add_parser(
406
448
  "oracle",
@@ -125,6 +125,7 @@
125
125
  <div class="sidebar-label">SCM</div>
126
126
  <a href="#c3_task" class="sidebar-link"><span class="icon">✅</span> c3_task</a>
127
127
  <a href="#c3_bitbucket" class="sidebar-link"><span class="icon">🪣</span> c3_bitbucket</a>
128
+ <a href="#c3_credentials" class="sidebar-link"><span class="icon">🔐</span> c3_credentials</a>
128
129
  </div>
129
130
  <div class="sidebar-section">
130
131
  <div class="sidebar-label">Cross-project</div>
@@ -161,6 +162,7 @@
161
162
  <a href="#c3_task" class="toc-item">c3_task <span class="cat">PM</span></a>
162
163
  <a href="#c3_artifacts" class="toc-item">c3_artifacts <span class="cat">Config</span></a>
163
164
  <a href="#c3_bitbucket" class="toc-item">c3_bitbucket <span class="cat">SCM</span></a>
165
+ <a href="#c3_credentials" class="toc-item">c3_credentials <span class="cat">Secrets</span></a>
164
166
  <a href="#c3_project" class="toc-item">c3_project <span class="cat">Multi-project</span></a>
165
167
  </div>
166
168
  </div>
@@ -1239,6 +1241,45 @@ c3_bitbucket(action=<span class="str">'merge_pr'</span>, pr_id=<span class="num"
1239
1241
  <p class="tool-desc"><strong>Audit trail:</strong> mutating actions (<code>merge_pr</code>, <code>create_branch</code>, <code>delete_branch</code>, webhook writes, etc.) are appended to the C3 edit ledger so the local audit log covers platform-side state changes too.</p>
1240
1242
  </div>
1241
1243
  </div>
1244
+
1245
+ <!-- c3_credentials -->
1246
+ <div class="tool-card" id="c3_credentials">
1247
+ <div class="tool-card-header">
1248
+ <span class="tool-name">c3_credentials</span>
1249
+ <div class="tag-row">
1250
+ <span class="badge badge-purple">secrets</span>
1251
+ <span class="badge">v2.58.0</span>
1252
+ </div>
1253
+ <span class="tool-tagline">Credential vault — the agent uses secrets by name, never by value</span>
1254
+ </div>
1255
+ <div class="tool-card-body">
1256
+ <p class="tool-desc">A user-managed secret store, <strong>global</strong> (<code>~/.c3</code>, visible in every project) or <strong>per-project</strong> (<code>.c3</code>, shadows the same-named global). Values live in the OS keyring (service <code>c3-creds</code>; values over ~1KB in a Fernet-encrypted <code>.c3/secrets.enc</code> whose random master key is itself a keyring entry) — never in config files, and <em>never in the model's context</em>. <strong>Injection-first:</strong> the agent addresses secrets by name and C3 decodes them only at the subprocess boundary — <code>c3_shell(env_creds='A,B')</code> injects env vars, <code>{{cred:NAME}}</code> inside <code>cmd</code> expands server-side, and <code>inject</code>-flagged entries auto-inject into every shell run; echoed values are redacted back to <code>[cred:NAME]</code>. Resolution is <strong>realm-atomic</strong>: a project-registered name resolves in the project realm or not at all, so a hostile repo's committed config can never siphon your global values (tested).</p>
1257
+
1258
+ <h4>Actions</h4>
1259
+ <table class="params-table">
1260
+ <thead><tr><th>Action</th><th>Group</th><th>Description</th></tr></thead>
1261
+ <tbody>
1262
+ <tr><td class="param-name">list</td><td>Read</td><td class="param-desc">Merged registry (project shadows global) — names, scope, type, flags, usage. Never values</td></tr>
1263
+ <tr><td class="param-name">describe</td><td>Read</td><td class="param-desc">Metadata + storage + live fingerprint (first 8 hex of SHA-256, computed on demand, never persisted)</td></tr>
1264
+ <tr><td class="param-name">check</td><td>Read</td><td class="param-desc">Resolvability probe — does the stored value decode?</td></tr>
1265
+ <tr><td class="param-name">set</td><td>Write</td><td class="param-desc">Create/replace an entry. <code>agent_readable</code> may be set at creation only — raising it on an existing entry is user-only</td></tr>
1266
+ <tr><td class="param-name">delete</td><td>Write</td><td class="param-desc">Remove value + registry entry (owning scope inferred when omitted)</td></tr>
1267
+ <tr><td class="param-name">reveal</td><td>Gated</td><td class="param-desc">The only value-returning action — refused unless the user enabled <code>agent_readable</code> on that entry</td></tr>
1268
+ </tbody>
1269
+ </table>
1270
+
1271
+ <h4>Examples</h4>
1272
+ <pre><code><span class="com"># What can I use? (names and metadata only)</span>
1273
+ c3_credentials(action=<span class="str">'list'</span>)
1274
+ c3_credentials(action=<span class="str">'check'</span>, name=<span class="str">'NPM_TOKEN'</span>)
1275
+
1276
+ <span class="com"># USE a secret without ever seeing it</span>
1277
+ c3_shell(cmd=<span class="str">'npm publish'</span>, env_creds=<span class="str">'NPM_TOKEN'</span>)
1278
+ c3_shell(cmd=<span class="str">'curl -H "Authorization: Bearer {{cred:API_KEY}}" https://api.example.com'</span>)</code></pre>
1279
+
1280
+ <p class="tool-desc"><strong>Surfaces:</strong> the <code>c3 creds</code> CLI (<code>set</code> / <code>get</code> / <code>list</code> / <code>rm</code> / <code>import .env</code>, <code>--global</code> for the shared scope), a per-project dashboard <strong>Credentials</strong> tab, and — since v2.59.0 — a top-level <strong>Credentials</strong> view in the Hub: a Global-vault manager plus a per-project browser with shadowing shown both ways ("shadows global" on project entries, "shadowed in N projects" on globals); the Hub's per-project drill panel manages too. No HTTP route ever returns a stored value (write-only wire contract, endpoint-sweep tested), every mutation is ledger-logged by name, the vault is hard-excluded from the Oracle Discovery API, and cross-project (<code>c3_project</code>) shells run with credentials disabled.</p>
1281
+ </div>
1282
+ </div>
1242
1283
  </div>
1243
1284
 
1244
1285
  <!-- ═══════════════════════════════════════ CROSS-PROJECT ═════ -->