code-context-control 2.89.0__tar.gz → 2.91.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 (446) hide show
  1. {code_context_control-2.89.0/code_context_control.egg-info → code_context_control-2.91.0}/PKG-INFO +2 -2
  2. {code_context_control-2.89.0 → code_context_control-2.91.0}/README.md +1 -1
  3. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/c3.py +48 -8
  4. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/commands/parser.py +9 -2
  5. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/guide/credentials.html +22 -5
  6. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/guide/oracle.html +18 -3
  7. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_server.py +57 -0
  8. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/app.js +2 -1
  9. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/hub_credentials.js +26 -3
  10. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/settings_modal.js +148 -33
  11. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/mcp_server.py +9 -5
  12. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/credentials.py +9 -1
  13. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/components/credentials.js +26 -3
  14. {code_context_control-2.89.0 → code_context_control-2.91.0/code_context_control.egg-info}/PKG-INFO +2 -2
  15. {code_context_control-2.89.0 → code_context_control-2.91.0}/code_context_control.egg-info/SOURCES.txt +7 -0
  16. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/oracle_server.py +17 -9
  17. {code_context_control-2.89.0 → code_context_control-2.91.0}/pyproject.toml +1 -1
  18. code_context_control-2.91.0/services/background_service.py +662 -0
  19. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/claude_md.py +1 -1
  20. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/credential_store.py +83 -3
  21. code_context_control-2.91.0/services/hub_service.py +78 -0
  22. code_context_control-2.91.0/services/oracle_service.py +141 -0
  23. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/parser.py +11 -1
  24. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/project_manager.py +3 -1
  25. code_context_control-2.91.0/tests/test_background_service.py +445 -0
  26. code_context_control-2.91.0/tests/test_credential_login_kind.py +191 -0
  27. code_context_control-2.91.0/tests/test_credential_ui_parity.py +146 -0
  28. code_context_control-2.91.0/tests/test_hub_oracle_service_routes.py +146 -0
  29. code_context_control-2.91.0/tests/test_oracle_health_probe.py +73 -0
  30. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_project_manager_merge.py +68 -0
  31. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_validate.py +28 -0
  32. code_context_control-2.89.0/services/hub_service.py +0 -585
  33. {code_context_control-2.89.0 → code_context_control-2.91.0}/LICENSE +0 -0
  34. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/__init__.py +0 -0
  35. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/_hook_utils.py +0 -0
  36. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/commands/__init__.py +0 -0
  37. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/commands/common.py +0 -0
  38. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/docs.html +0 -0
  39. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/edits.html +0 -0
  40. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/guide/access.html +0 -0
  41. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/guide/bitbucket.html +0 -0
  42. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/guide/getting-started.html +0 -0
  43. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/guide/index.html +0 -0
  44. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/guide/masking.html +0 -0
  45. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/guide/shared.css +0 -0
  46. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/guide/tools.html +0 -0
  47. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/guide/workflow.html +0 -0
  48. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hook_access_guard.py +0 -0
  49. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hook_artifact.py +0 -0
  50. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hook_auto_snapshot.py +0 -0
  51. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hook_c3_signal.py +0 -0
  52. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hook_c3read.py +0 -0
  53. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hook_dispatch.py +0 -0
  54. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hook_edit_ledger.py +0 -0
  55. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hook_edit_unlock.py +0 -0
  56. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hook_filter.py +0 -0
  57. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hook_ghost_files.py +0 -0
  58. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hook_pretool_enforce.py +0 -0
  59. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hook_prompt_recall.py +0 -0
  60. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hook_read.py +0 -0
  61. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hook_session_stats.py +0 -0
  62. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hook_terse_advisor.py +0 -0
  63. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/add_project.js +0 -0
  64. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/config_editor.js +0 -0
  65. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
  66. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/drill_health.js +0 -0
  67. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/drill_panel.js +0 -0
  68. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
  69. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/drill_tasks.js +0 -0
  70. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/drill_views.js +0 -0
  71. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/global_search.js +0 -0
  72. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/hub_ci.js +0 -0
  73. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
  74. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/hub_locks.js +0 -0
  75. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/mcp_manager.js +0 -0
  76. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/modals.js +0 -0
  77. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/project_card.js +0 -0
  78. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/project_tree.js +0 -0
  79. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/session_drawer.js +0 -0
  80. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/sidebar.js +0 -0
  81. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/summary_bar.js +0 -0
  82. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/task_board.js +0 -0
  83. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/toasts.js +0 -0
  84. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/components/topbar.js +0 -0
  85. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui/state.js +0 -0
  86. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/hub_ui.html +0 -0
  87. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/mcp_proxy.py +0 -0
  88. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/progress.py +0 -0
  89. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/server.py +0 -0
  90. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/__init__.py +0 -0
  91. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/_grants.py +0 -0
  92. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/_helpers.py +0 -0
  93. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/agent.py +0 -0
  94. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/artifacts.py +0 -0
  95. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/bitbucket.py +0 -0
  96. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/ci.py +0 -0
  97. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/compress.py +0 -0
  98. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/delegate.py +0 -0
  99. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/edit.py +0 -0
  100. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/edit_verify.py +0 -0
  101. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/edits.py +0 -0
  102. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/federate.py +0 -0
  103. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/filter.py +0 -0
  104. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/impact.py +0 -0
  105. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/jira.py +0 -0
  106. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/locks.py +0 -0
  107. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/memory.py +0 -0
  108. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/override.py +0 -0
  109. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/project.py +0 -0
  110. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/read.py +0 -0
  111. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/search.py +0 -0
  112. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/session.py +0 -0
  113. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/shell.py +0 -0
  114. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/status.py +0 -0
  115. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/tasks.py +0 -0
  116. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/tools/validate.py +0 -0
  117. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/api.js +0 -0
  118. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/app.js +0 -0
  119. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/components/access.js +0 -0
  120. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/components/bitbucket.js +0 -0
  121. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/components/chat.js +0 -0
  122. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/components/dashboard.js +0 -0
  123. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/components/edits.js +0 -0
  124. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/components/enforcement.js +0 -0
  125. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/components/instructions.js +0 -0
  126. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/components/jira.js +0 -0
  127. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/components/memory.js +0 -0
  128. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/components/sessions.js +0 -0
  129. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/components/settings.js +0 -0
  130. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/components/sidebar.js +0 -0
  131. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/components/tasks.js +0 -0
  132. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/icons.js +0 -0
  133. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/pm_shared.js +0 -0
  134. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/shared.js +0 -0
  135. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui/theme.js +0 -0
  136. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui.html +0 -0
  137. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui_legacy.html +0 -0
  138. {code_context_control-2.89.0 → code_context_control-2.91.0}/cli/ui_nano.html +0 -0
  139. {code_context_control-2.89.0 → code_context_control-2.91.0}/code_context_control.egg-info/dependency_links.txt +0 -0
  140. {code_context_control-2.89.0 → code_context_control-2.91.0}/code_context_control.egg-info/entry_points.txt +0 -0
  141. {code_context_control-2.89.0 → code_context_control-2.91.0}/code_context_control.egg-info/requires.txt +0 -0
  142. {code_context_control-2.89.0 → code_context_control-2.91.0}/code_context_control.egg-info/top_level.txt +0 -0
  143. {code_context_control-2.89.0 → code_context_control-2.91.0}/core/__init__.py +0 -0
  144. {code_context_control-2.89.0 → code_context_control-2.91.0}/core/config.py +0 -0
  145. {code_context_control-2.89.0 → code_context_control-2.91.0}/core/ide.py +0 -0
  146. {code_context_control-2.89.0 → code_context_control-2.91.0}/core/mcp_toml.py +0 -0
  147. {code_context_control-2.89.0 → code_context_control-2.91.0}/core/web_security.py +0 -0
  148. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/__init__.py +0 -0
  149. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/config.py +0 -0
  150. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/mcp_oracle.py +0 -0
  151. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/oracle_ui.html +0 -0
  152. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/__init__.py +0 -0
  153. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/activity_reporter.py +0 -0
  154. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/api_auth.py +0 -0
  155. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/c3_bridge.py +0 -0
  156. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/chat_engine.py +0 -0
  157. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/chat_poll.py +0 -0
  158. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/chat_store.py +0 -0
  159. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/cross_memory.py +0 -0
  160. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/discovery_audit.py +0 -0
  161. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/federated_graph.py +0 -0
  162. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/health_checker.py +0 -0
  163. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/insight_engine.py +0 -0
  164. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/local_session.py +0 -0
  165. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/memory_reader.py +0 -0
  166. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/memory_writer.py +0 -0
  167. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/mobile_api.py +0 -0
  168. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/project_scanner.py +0 -0
  169. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/review_agent.py +0 -0
  170. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/tool_executor.py +0 -0
  171. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/services/tool_registry.py +0 -0
  172. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/activity.js +0 -0
  173. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/agents.js +0 -0
  174. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/app.js +0 -0
  175. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/busy.js +0 -0
  176. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/chat/conversations.js +0 -0
  177. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/chat/input.js +0 -0
  178. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/chat/markdown.js +0 -0
  179. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/chat/send.js +0 -0
  180. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/chat/stream_renderer.js +0 -0
  181. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/chat/toolbar.js +0 -0
  182. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/core.js +0 -0
  183. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/crossgraph.js +0 -0
  184. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/header.js +0 -0
  185. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/insights.js +0 -0
  186. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/projects.js +0 -0
  187. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/qrcode.js +0 -0
  188. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/settings.js +0 -0
  189. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/suggestions.js +0 -0
  190. {code_context_control-2.89.0 → code_context_control-2.91.0}/oracle/ui/theme_tabs.js +0 -0
  191. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/__init__.py +0 -0
  192. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/access_guard.py +0 -0
  193. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/access_telemetry.py +0 -0
  194. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/activity_log.py +0 -0
  195. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/agent_base.py +0 -0
  196. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/agent_locks.py +0 -0
  197. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/agents.py +0 -0
  198. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/artifact_defs.py +0 -0
  199. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/artifact_store.py +0 -0
  200. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/auto_memory.py +0 -0
  201. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/bench/__init__.py +0 -0
  202. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/bench/external/__init__.py +0 -0
  203. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/bench/external/aider_polyglot.py +0 -0
  204. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/bench/external/swe_bench.py +0 -0
  205. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/benchmark_dashboard.py +0 -0
  206. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/bitbucket_client.py +0 -0
  207. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/bitbucket_credentials.py +0 -0
  208. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/ci_act.py +0 -0
  209. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/ci_cache.py +0 -0
  210. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/ci_expr.py +0 -0
  211. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/ci_failures.py +0 -0
  212. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/ci_github.py +0 -0
  213. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/ci_impact.py +0 -0
  214. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/ci_intel.py +0 -0
  215. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/ci_runner.py +0 -0
  216. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/ci_workflow.py +0 -0
  217. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/circuit_breaker.py +0 -0
  218. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/compressor.py +0 -0
  219. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/context_snapshot.py +0 -0
  220. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/conversation_store.py +0 -0
  221. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/cred_telemetry.py +0 -0
  222. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/doc_index.py +0 -0
  223. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/e2e_benchmark.py +0 -0
  224. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/e2e_evaluator.py +0 -0
  225. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/e2e_tasks.py +0 -0
  226. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/edit_ledger.py +0 -0
  227. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/embedding_index.py +0 -0
  228. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/enforcement_policy.py +0 -0
  229. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/error_reporting.py +0 -0
  230. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/file_memory.py +0 -0
  231. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/git_context.py +0 -0
  232. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/indexer.py +0 -0
  233. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/jira_client.py +0 -0
  234. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/jira_cloud.py +0 -0
  235. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/jira_credentials.py +0 -0
  236. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/jira_data_center.py +0 -0
  237. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/jira_links.py +0 -0
  238. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/mask_activation.py +0 -0
  239. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/mask_mirror.py +0 -0
  240. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/mask_presets.py +0 -0
  241. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/memory.py +0 -0
  242. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/memory_consolidator.py +0 -0
  243. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/memory_distiller.py +0 -0
  244. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/memory_graph.py +0 -0
  245. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/memory_grounder.py +0 -0
  246. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/memory_queue.py +0 -0
  247. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/memory_scorer.py +0 -0
  248. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/metrics.py +0 -0
  249. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/notifications.py +0 -0
  250. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/ollama_bridge.py +0 -0
  251. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/ollama_client.py +0 -0
  252. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/ollama_credentials.py +0 -0
  253. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/output_filter.py +0 -0
  254. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/override_grants.py +0 -0
  255. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/override_policy.py +0 -0
  256. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/override_requests.py +0 -0
  257. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/override_wake.py +0 -0
  258. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/project_runtime.py +0 -0
  259. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/protocol.py +0 -0
  260. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/proxy_state.py +0 -0
  261. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/repo_map.py +0 -0
  262. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/retention.py +0 -0
  263. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/retrieval_broker.py +0 -0
  264. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/router.py +0 -0
  265. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/runtime.py +0 -0
  266. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/scanner.py +0 -0
  267. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/session_benchmark.py +0 -0
  268. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/session_manager.py +0 -0
  269. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/session_preloader.py +0 -0
  270. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/subprojects.py +0 -0
  271. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/task_store.py +0 -0
  272. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/telemetry.py +0 -0
  273. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/text_index.py +0 -0
  274. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/time_tracker.py +0 -0
  275. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/tool_classifier.py +0 -0
  276. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/transcript_index.py +0 -0
  277. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/validation_cache.py +0 -0
  278. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/vector_store.py +0 -0
  279. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/watcher.py +0 -0
  280. {code_context_control-2.89.0 → code_context_control-2.91.0}/services/win_subprocess.py +0 -0
  281. {code_context_control-2.89.0 → code_context_control-2.91.0}/setup.cfg +0 -0
  282. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_access_builtin_optout.py +0 -0
  283. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_access_guard.py +0 -0
  284. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_access_guard_meta.py +0 -0
  285. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_access_guard_shell_project.py +0 -0
  286. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_access_guard_surfaces.py +0 -0
  287. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_access_guard_wiring.py +0 -0
  288. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_activity_reporter.py +0 -0
  289. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_agent_locks.py +0 -0
  290. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_aider_polyglot.py +0 -0
  291. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_antigravity_transition.py +0 -0
  292. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_artifact_store.py +0 -0
  293. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_artifact_tool.py +0 -0
  294. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_bitbucket_cli_smoke.py +0 -0
  295. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_bitbucket_client.py +0 -0
  296. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_bitbucket_config_fallback.py +0 -0
  297. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_bitbucket_credentials.py +0 -0
  298. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_bitbucket_tool.py +0 -0
  299. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
  300. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_c3_shell.py +0 -0
  301. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_chat_poll.py +0 -0
  302. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_ci_act.py +0 -0
  303. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_ci_cache.py +0 -0
  304. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_ci_expr.py +0 -0
  305. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_ci_impact.py +0 -0
  306. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_ci_intel.py +0 -0
  307. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_ci_runner.py +0 -0
  308. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_ci_workflow.py +0 -0
  309. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_circuit_breaker.py +0 -0
  310. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_claude_md_merge.py +0 -0
  311. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_cli_smoke.py +0 -0
  312. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_compressor_large_file.py +0 -0
  313. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_cred_telemetry.py +0 -0
  314. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_credential_store.py +0 -0
  315. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_credentials_routes.py +0 -0
  316. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_credentials_tool.py +0 -0
  317. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_creds_cli_smoke.py +0 -0
  318. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_delegate_cascade.py +0 -0
  319. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_delegate_version_probe.py +0 -0
  320. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_e2e_benchmark.py +0 -0
  321. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_edit_ledger_deadline.py +0 -0
  322. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_edit_ledger_hook.py +0 -0
  323. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_edit_locking.py +0 -0
  324. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_edit_normalization.py +0 -0
  325. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_edit_verify.py +0 -0
  326. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_embedding_index_deadlock.py +0 -0
  327. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_enforcement_flip.py +0 -0
  328. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_enforcement_policy.py +0 -0
  329. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_enforcement_routes.py +0 -0
  330. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_federated_graph.py +0 -0
  331. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_filter_backoff.py +0 -0
  332. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_ghost_files.py +0 -0
  333. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_ghost_generation.py +0 -0
  334. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_git_branch_awareness.py +0 -0
  335. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_hook_access_guard.py +0 -0
  336. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_hook_codex_compat.py +0 -0
  337. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_hook_dispatch.py +0 -0
  338. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_hook_pretool_enforce.py +0 -0
  339. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_hook_prompt_recall.py +0 -0
  340. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_hook_smoke.py +0 -0
  341. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_hook_state.py +0 -0
  342. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_hook_utf8_stdio.py +0 -0
  343. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_hub_credentials_route.py +0 -0
  344. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_hub_credentials_routes_write.py +0 -0
  345. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_hub_enforcement_routes.py +0 -0
  346. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_hub_inspect_api.py +0 -0
  347. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_hub_locks_routes.py +0 -0
  348. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_hub_server_smoke.py +0 -0
  349. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_hub_subproject_links.py +0 -0
  350. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_ide_workflow_adaptation.py +0 -0
  351. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_init_scan.py +0 -0
  352. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_install_mcp_entrypoint.py +0 -0
  353. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_jira_cli_smoke.py +0 -0
  354. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_jira_client.py +0 -0
  355. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_jira_config_fallback.py +0 -0
  356. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_jira_credentials.py +0 -0
  357. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_jira_links.py +0 -0
  358. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_jira_routes.py +0 -0
  359. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_jira_tool.py +0 -0
  360. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_lazy_store_init.py +0 -0
  361. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_mask_guard.py +0 -0
  362. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_mask_routes.py +0 -0
  363. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_mask_surfaces.py +0 -0
  364. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_mcp_host_guard.py +0 -0
  365. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_mcp_memory_timeout.py +0 -0
  366. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_mcp_server_smoke.py +0 -0
  367. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_mcp_toml.py +0 -0
  368. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_memory_distiller.py +0 -0
  369. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_memory_graph_api.py +0 -0
  370. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_memory_queue.py +0 -0
  371. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_memory_system.py +0 -0
  372. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_mobile_api.py +0 -0
  373. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_mobile_extras.py +0 -0
  374. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_mobile_override_routes.py +0 -0
  375. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_mobile_security_api.py +0 -0
  376. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_no_stale_model_pins.py +0 -0
  377. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_notification_dedup.py +0 -0
  378. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_notification_discipline.py +0 -0
  379. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_ollama_credentials.py +0 -0
  380. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_oracle_api_auth.py +0 -0
  381. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_oracle_apikey_api.py +0 -0
  382. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_oracle_c3_bridge.py +0 -0
  383. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_oracle_chat_engine.py +0 -0
  384. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_oracle_chat_store.py +0 -0
  385. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_oracle_discovery_api.py +0 -0
  386. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_oracle_discovery_audit.py +0 -0
  387. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_oracle_local_auth.py +0 -0
  388. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_oracle_ollama_bridge.py +0 -0
  389. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_oracle_scanner_cache.py +0 -0
  390. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_oracle_security_fixes.py +0 -0
  391. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_oracle_session_bootstrap.py +0 -0
  392. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_oracle_subproject_awareness.py +0 -0
  393. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_oracle_ui_bundle.py +0 -0
  394. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_output_filter.py +0 -0
  395. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_override_grants.py +0 -0
  396. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_override_grants_mcp.py +0 -0
  397. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_override_requests.py +0 -0
  398. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_override_wake.py +0 -0
  399. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_permissions.py +0 -0
  400. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_pm_api.py +0 -0
  401. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_project_manager.py +0 -0
  402. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_project_tool.py +0 -0
  403. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_read_coercion.py +0 -0
  404. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_read_edit_parity.py +0 -0
  405. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_related_facts.py +0 -0
  406. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_repo_map.py +0 -0
  407. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_response_boilerplate.py +0 -0
  408. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_retention.py +0 -0
  409. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_review_digest.py +0 -0
  410. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_service_durability.py +0 -0
  411. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_session_benchmark.py +0 -0
  412. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_session_budget.py +0 -0
  413. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_shell_creds.py +0 -0
  414. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_shell_robustness.py +0 -0
  415. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_subproject_exclusion.py +0 -0
  416. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_subproject_federation.py +0 -0
  417. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_subprojects.py +0 -0
  418. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_swe_bench.py +0 -0
  419. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_task_store.py +0 -0
  420. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_task_tool.py +0 -0
  421. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_time_tracker.py +0 -0
  422. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_token_telemetry.py +0 -0
  423. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_tool_registry.py +0 -0
  424. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_upgrade_and_version.py +0 -0
  425. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_vault_write_guard.py +0 -0
  426. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_version_sync.py +0 -0
  427. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_web_security.py +0 -0
  428. {code_context_control-2.89.0 → code_context_control-2.91.0}/tests/test_windows_reliability.py +0 -0
  429. {code_context_control-2.89.0 → code_context_control-2.91.0}/tui/__init__.py +0 -0
  430. {code_context_control-2.89.0 → code_context_control-2.91.0}/tui/backend.py +0 -0
  431. {code_context_control-2.89.0 → code_context_control-2.91.0}/tui/main.py +0 -0
  432. {code_context_control-2.89.0 → code_context_control-2.91.0}/tui/screens/__init__.py +0 -0
  433. {code_context_control-2.89.0 → code_context_control-2.91.0}/tui/screens/benchmark_view.py +0 -0
  434. {code_context_control-2.89.0 → code_context_control-2.91.0}/tui/screens/claudemd_view.py +0 -0
  435. {code_context_control-2.89.0 → code_context_control-2.91.0}/tui/screens/compress_view.py +0 -0
  436. {code_context_control-2.89.0 → code_context_control-2.91.0}/tui/screens/index_view.py +0 -0
  437. {code_context_control-2.89.0 → code_context_control-2.91.0}/tui/screens/init_view.py +0 -0
  438. {code_context_control-2.89.0 → code_context_control-2.91.0}/tui/screens/mcp_view.py +0 -0
  439. {code_context_control-2.89.0 → code_context_control-2.91.0}/tui/screens/optimize_view.py +0 -0
  440. {code_context_control-2.89.0 → code_context_control-2.91.0}/tui/screens/pipe_view.py +0 -0
  441. {code_context_control-2.89.0 → code_context_control-2.91.0}/tui/screens/projects_view.py +0 -0
  442. {code_context_control-2.89.0 → code_context_control-2.91.0}/tui/screens/search_view.py +0 -0
  443. {code_context_control-2.89.0 → code_context_control-2.91.0}/tui/screens/session_view.py +0 -0
  444. {code_context_control-2.89.0 → code_context_control-2.91.0}/tui/screens/stats.py +0 -0
  445. {code_context_control-2.89.0 → code_context_control-2.91.0}/tui/screens/ui_view.py +0 -0
  446. {code_context_control-2.89.0 → code_context_control-2.91.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.89.0
3
+ Version: 2.91.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
@@ -137,7 +137,7 @@ Full notes: [Upgrading](https://github.com/drknowhow/code-context-control/blob/m
137
137
 
138
138
  ## The UI
139
139
 
140
- Three local web apps, no Electron — pure Flask + vanilla JS: the **Hub** (`c3 hub`, port 3330), the **per-project UI** (`c3 ui`), and the optional **Oracle** (`c3 oracle serve`).
140
+ Three local web apps, no Electron — pure Flask + vanilla JS: the **Hub** (`c3 hub`, port 3330), the **per-project UI** (`c3 ui`), and the optional **Oracle** (`c3 oracle serve`). Both servers can run as windowless login services — `c3 hub --install`, `c3 oracle serve --install`, or the buttons in Hub → Settings.
141
141
 
142
142
  ### Project Hub — multi-project mission control
143
143
 
@@ -74,7 +74,7 @@ Full notes: [Upgrading](https://github.com/drknowhow/code-context-control/blob/m
74
74
 
75
75
  ## The UI
76
76
 
77
- Three local web apps, no Electron — pure Flask + vanilla JS: the **Hub** (`c3 hub`, port 3330), the **per-project UI** (`c3 ui`), and the optional **Oracle** (`c3 oracle serve`).
77
+ Three local web apps, no Electron — pure Flask + vanilla JS: the **Hub** (`c3 hub`, port 3330), the **per-project UI** (`c3 ui`), and the optional **Oracle** (`c3 oracle serve`). Both servers can run as windowless login services — `c3 hub --install`, `c3 oracle serve --install`, or the buttons in Hub → Settings.
78
78
 
79
79
  ### Project Hub — multi-project mission control
80
80
 
@@ -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.89.0"
95
+ __version__ = "2.91.0"
96
96
 
97
97
 
98
98
  def _compress_file_cli(compressor, path, mode="smart", **kw):
@@ -4555,14 +4555,22 @@ def _ensure_global_session_fallbacks(server_script: str, c3_mcp_exe: str | None
4555
4555
  print(f"Warning: Could not update {antigravity_path} (global fallback skipped)")
4556
4556
 
4557
4557
 
4558
- def _uninstall_mcp_all(project_path: str):
4559
- """Remove C3 MCP server configurations from all supported IDEs."""
4558
+ def _uninstall_mcp_all(project_path: str, include_global: bool = True):
4559
+ """Remove C3 MCP server configurations from all supported IDEs.
4560
+
4561
+ ``include_global=False`` restricts removal to PROJECT-scoped config files
4562
+ (the project's .mcp.json, .codex/config.toml, settings/hooks). Home-level
4563
+ configs (~/.codex, Antigravity's mcp_config.json) are machine-wide and
4564
+ shared by every C3 project, so per-project cleanup — the merge action's
4565
+ ``cleanup='clear'`` — must never touch them; only a real machine
4566
+ uninstall (the default) may."""
4560
4567
  import shutil
4561
4568
  from pathlib import Path
4562
4569
 
4563
4570
  from core.ide import PROFILES
4564
4571
 
4565
- print("\nRemoving C3 MCP server configurations...")
4572
+ scope = "" if include_global else " (project-scoped only)"
4573
+ print(f"\nRemoving C3 MCP server configurations...{scope}")
4566
4574
  target = Path(project_path).resolve()
4567
4575
 
4568
4576
  # Remove .mcp.json if it exists (standard MCP config file)
@@ -4587,11 +4595,12 @@ def _uninstall_mcp_all(project_path: str):
4587
4595
  # MCP Config paths to check
4588
4596
  config_paths = []
4589
4597
  if profile.config_path_global:
4590
- config_paths.append(Path.home() / profile.config_path)
4598
+ if include_global:
4599
+ config_paths.append(Path.home() / profile.config_path)
4591
4600
  else:
4592
4601
  config_paths.append(target / profile.config_path)
4593
4602
  # For Codex, also check the global fallback in home dir
4594
- if ide_name == "codex":
4603
+ if ide_name == "codex" and include_global:
4595
4604
  config_paths.append(Path.home() / profile.config_path)
4596
4605
 
4597
4606
  for mcp_config_path in config_paths:
@@ -4714,8 +4723,10 @@ def _uninstall_mcp_all(project_path: str):
4714
4723
  print(f" Warning: Could not update {vscode_settings_path}: {e}")
4715
4724
 
4716
4725
  # Legacy Gemini CLI configs (profile removed in v2.52) — still strip the c3 entry.
4717
- for legacy_cfg in (target / ".gemini" / "settings.json",
4718
- Path.home() / ".gemini" / "settings.json"):
4726
+ legacy_cfgs = [target / ".gemini" / "settings.json"]
4727
+ if include_global:
4728
+ legacy_cfgs.append(Path.home() / ".gemini" / "settings.json")
4729
+ for legacy_cfg in legacy_cfgs:
4719
4730
  if not legacy_cfg.exists():
4720
4731
  continue
4721
4732
  try:
@@ -7415,10 +7426,39 @@ def _oracle_open(args):
7415
7426
  webbrowser.open(url)
7416
7427
 
7417
7428
 
7429
+ def _oracle_service_cmd(args):
7430
+ """`c3 oracle serve --install | --uninstall | --status` — mirrors `c3 hub`."""
7431
+ from services.oracle_service import OracleService
7432
+ svc = OracleService()
7433
+ port = getattr(args, "port", None) or svc.default_port()
7434
+
7435
+ if getattr(args, "install", False):
7436
+ res = svc.install(port)
7437
+ print(res.get("output", "Service installed."))
7438
+ if res.get("success"):
7439
+ print(f"Oracle will start at login (no terminal window); log: {svc.LOG_FILE}")
7440
+ return
7441
+ if getattr(args, "uninstall", False):
7442
+ res = svc.uninstall()
7443
+ print(res.get("output", "Service uninstalled."))
7444
+ return
7445
+ res = svc.status()
7446
+ print(f"Oracle Service Status ({res.get('platform', 'unknown')}):")
7447
+ print(f" Installed: {res.get('installed')}")
7448
+ print(f" Running : {res.get('running')}")
7449
+ print(f" Port : {res.get('port')} (bind {res.get('bind_host')}, MCP {res.get('mcp_port')})")
7450
+ print(f" URL : {res.get('url')}")
7451
+ print(f" Method : {res.get('method')}")
7452
+ print(f" Log : {res.get('log_path')}")
7453
+
7454
+
7418
7455
  def cmd_oracle(args):
7419
7456
  """Oracle dashboard server + Discovery API key management."""
7420
7457
  sub = getattr(args, "oracle_cmd", None)
7421
7458
  if sub in ("serve", "start"):
7459
+ if any(getattr(args, f, False) for f in ("install", "uninstall", "status")):
7460
+ _oracle_service_cmd(args)
7461
+ return
7422
7462
  # Lazy import: run_oracle builds all Oracle services (matches
7423
7463
  # cmd_hub's deferred-import style so bare `c3` stays fast).
7424
7464
  from oracle.oracle_server import run_oracle
@@ -421,9 +421,9 @@ def build_parser(version: str, parse_cli_ide_arg):
421
421
  cr_set.add_argument("--stdin", action="store_true", help="Read the value from stdin (piped/multiline values)")
422
422
  cr_set.add_argument("--type", dest="ctype",
423
423
  choices=["token", "env", "multiline",
424
- "address", "identity", "card"],
424
+ "address", "identity", "card", "login"],
425
425
  default="token",
426
- help="Entry type; address/identity/card are structured "
426
+ help="Entry type; address/identity/card/login are structured "
427
427
  "(field payload, inject-only, never revealable to the agent)")
428
428
  cr_set.add_argument("--desc", default="", help="Human description shown in list/UI")
429
429
  cr_set.add_argument("--env-var", default="", help="Env var name used at injection (default: entry name)")
@@ -824,6 +824,13 @@ def build_parser(version: str, parse_cli_ide_arg):
824
824
  help="Server port (default: config 'port', 3331)")
825
825
  or_serve.add_argument("--no-browser", action="store_true",
826
826
  help="Don't open the browser")
827
+ or_serve.add_argument("--install", action="store_true",
828
+ help="Register the Oracle as a login/startup service "
829
+ "(no terminal window) and start it now")
830
+ or_serve.add_argument("--uninstall", action="store_true",
831
+ help="Remove the Oracle's startup service registration")
832
+ or_serve.add_argument("--status", action="store_true",
833
+ help="Show the Oracle's startup service status")
827
834
  or_open = or_subs.add_parser(
828
835
  "open",
829
836
  help="Sign in to a running dashboard via a single-use URL",
@@ -297,12 +297,14 @@ c3_shell(cmd=<span class="str">'terraform apply'</span>, env_creds=<span class="
297
297
 
298
298
  <!-- ═══════════════════════════════════ STRUCTURED ═══ -->
299
299
  <section id="structured" class="tool-section">
300
- <h2>Structured kinds — cards, addresses, identity (v2.87.0)</h2>
300
+ <h2>Structured kinds — cards, addresses, identity, logins (v2.87.0)</h2>
301
301
 
302
- <p>Three entry types hold <strong>named fields</strong> instead of one opaque value:
302
+ <p>Four entry types hold <strong>named fields</strong> instead of one opaque value:
303
303
  <code>card</code> (cardholder, number, expiry, optional cvc/billing_zip — Luhn-checked),
304
- <code>address</code> (street1, city, state, zip, optional recipient/street2/country/phone) and
305
- <code>identity</code> (full_name, optional dob/ssn/phone/email). The payload is stored as one
304
+ <code>address</code> (street1, city, state, zip, optional recipient/street2/country/phone),
305
+ <code>identity</code> (full_name, optional dob/ssn/phone/email) and
306
+ <code>login</code> (site_id, canonical_origin, username, password, optional totp_secret —
307
+ v2.90.0). The payload is stored as one
306
308
  canonical JSON object through the same keyring / encrypted-sidecar path as any other value.</p>
307
309
 
308
310
  <p>They are <strong>inject-only by construction</strong>, which is stricter than a normal secret:</p>
@@ -315,7 +317,10 @@ c3_shell(cmd=<span class="str">'terraform apply'</span>, env_creds=<span class="
315
317
  the field list rather than expanding the whole payload.</li>
316
318
  <li><strong>The registry shows a projection, not the data.</strong> Lists and the UI display
317
319
  <code>visa ••••4242</code> for a card (brand + last4, deliberately <em>not</em> expiry),
318
- city/state for an address, the name for an identity. Field <em>names</em> are public;
320
+ city/state for an address, the name for an identity, and
321
+ <code>github · https://github.com · 2FA</code> for a login — site, origin and a 2FA
322
+ boolean, with the <em>username withheld on purpose</em>, because username + origin is
323
+ half the credential. Field <em>names</em> are public;
319
324
  field <em>values</em> never transit any HTTP response — a sweep test enforces this.</li>
320
325
  <li><strong>Echoes redact per field</strong> to <code>[cred:NAME.field]</code>. Caveat: the
321
326
  redactor only tracks values of 4+ characters, so a 3-digit CVC or 2-letter state that a
@@ -333,6 +338,18 @@ c3_shell(cmd=<span class="str">'terraform apply'</span>, env_creds=<span class="
333
338
  <code>c3 creds get NAME --show</code> (all fields) or <code>--show --field number</code> —
334
339
  the browser and the mobile gateway never carry the values, and mobile cannot create
335
340
  structured entries at all.</p>
341
+
342
+ <p><strong><code>login</code> is storage only, and that is a design constraint, not a
343
+ gap.</strong> C3 has no browser surface and must not grow one: a login runner in which the
344
+ <em>agent</em> picks the destination URL turns page-content prompt injection into credential
345
+ exfiltration, and a check written into a script that already holds the plaintext in its own
346
+ environment is not a boundary — the script can simply not call it. That is what
347
+ <code>canonical_origin</code> is for: https-only, stored normalized
348
+ (<code>scheme://host[:port]</code>, no path/query/fragment/userinfo, host lowercased), so a
349
+ separate <em>out-of-process</em> runner that the agent does not author can pin a credential to
350
+ exactly one origin and check the live top-level frame before typing. That runner is
351
+ deliberately not shipped in this package. <code>totp_secret</code> must be base32 — a
352
+ malformed seed produces wrong codes that look exactly like a wrong password.</p>
336
353
  </section>
337
354
 
338
355
  <hr class="divider">
@@ -168,9 +168,10 @@
168
168
  <div class="step-grid">
169
169
  <div class="step-card">
170
170
  <span class="step-num">1</span><h4>Start the Oracle</h4>
171
- <pre><code>python oracle/oracle_server.py \
172
- --no-browser</code></pre>
173
- <p style="font-size: 12px; color: var(--text-dim); margin: 8px 0 0;">Prints the REST + MCP URLs and ensures an API key exists. The MCP server starts in a background thread.</p>
171
+ <pre><code>c3 oracle serve --no-browser
172
+ <span class="com"># or: run it at login, no terminal window</span>
173
+ c3 oracle serve --install</code></pre>
174
+ <p style="font-size: 12px; color: var(--text-dim); margin: 8px 0 0;">Prints the REST + MCP URLs and ensures an API key exists. The MCP server starts in a background thread. <code>--install</code> registers a windowless background service (Task Scheduler / launchd / systemd) and starts it now — the same buttons live in <strong>Hub → Settings → Oracle service</strong>.</p>
174
175
  </div>
175
176
  <div class="step-card">
176
177
  <span class="step-num">2</span><h4>Get the token</h4>
@@ -325,8 +326,14 @@ curl -X POST \
325
326
  <tr><td><code>c3 oracle api key</code></td> <td>Print just the token (generating one if needed)</td></tr>
326
327
  <tr><td><code>c3 oracle api rotate</code></td> <td>Replace the token with a fresh one</td></tr>
327
328
  <tr><td><code>c3 oracle api clear</code></td> <td>Delete the stored token from the keyring</td></tr>
329
+ <tr><td><code>c3 oracle serve</code></td> <td>Run the dashboard + discovery endpoints in this terminal (<code>--no-browser</code>, <code>--port</code>)</td></tr>
330
+ <tr><td><code>c3 oracle serve --install</code></td> <td>Register the Oracle as a login/startup service — no terminal window — and start it now. Windows: Task Scheduler (Run-key fallback); macOS: launchd; Linux: systemd user unit</td></tr>
331
+ <tr><td><code>c3 oracle serve --uninstall</code></td> <td>Remove the startup registration (a running Oracle keeps running)</td></tr>
332
+ <tr><td><code>c3 oracle serve --status</code></td> <td>Installed? Running? Port, bind host, URL, and the launcher log path</td></tr>
333
+ <tr><td><code>c3 oracle open</code></td> <td>Sign in to a running dashboard via a single-use URL</td></tr>
328
334
  </tbody>
329
335
  </table>
336
+ <p style="font-size: 12px; color: var(--text-dim); margin: 8px 0 0;">The Hub exposes the same controls under <strong>Settings → Oracle service</strong> (Install / Uninstall / Start / Stop / Open). Starting the Oracle from there also fills in the Hub's <em>Oracle URL</em> when it is empty, so the Open Oracle button appears in the top bar.</p>
330
337
  </section>
331
338
 
332
339
  <hr class="divider">
@@ -373,6 +380,14 @@ curl -X POST \
373
380
  <td><code>The 'keyring' package is required</code></td>
374
381
  <td><code>pip install keyring</code> — a C3 dependency that may be missing if you upgraded without re-installing.</td>
375
382
  </tr>
383
+ <tr>
384
+ <td>Oracle is down after a reboot</td>
385
+ <td>Nothing restarts a terminal-launched Oracle. Register it once with <code>c3 oracle serve --install</code> (or Hub → Settings → Oracle service → Install); it then starts at login with no window. Startup problems land in <code>~/.c3/oracle/service.log</code> (the launcher) and <code>~/.c3/oracle/oracle.log</code> (the server).</td>
386
+ </tr>
387
+ <tr>
388
+ <td>Installed, but "stopped" right after login</td>
389
+ <td>If <code>bind_host</code> is a LAN/VPN address, the launcher waits up to 120 s for that address to come up before binding, and Task Scheduler retries a failed start three times a minute apart. Check <code>service.log</code> for <em>waiting for bind host</em>; if the address never appears, the Oracle starts anyway and fails to bind — fix the interface or set <code>bind_host</code> to <code>0.0.0.0</code>.</td>
390
+ </tr>
376
391
  </tbody>
377
392
  </table>
378
393
  </section>
@@ -3407,6 +3407,63 @@ def api_hub_restart():
3407
3407
  return jsonify({"restarting": True})
3408
3408
 
3409
3409
 
3410
+ # ─── Routes: oracle service (background daemon for `c3 oracle serve`) ───────
3411
+ #
3412
+ # Same shape as the hub's own service routes above. Port and bind host come
3413
+ # from ~/.c3/oracle/config.json, not from the hub config. A successful
3414
+ # install/start fills an EMPTY hub `oracle_url` with the Oracle's address so
3415
+ # the top bar's Open Oracle link appears without a second trip to settings.
3416
+
3417
+ def _oracle_service():
3418
+ from services.oracle_service import OracleService
3419
+ return OracleService()
3420
+
3421
+
3422
+ def _adopt_oracle_url(svc, result: dict) -> dict:
3423
+ result = dict(result or {})
3424
+ if not result.get("success"):
3425
+ return result
3426
+ cfg = _read_hub_config()
3427
+ if not (cfg.get("oracle_url") or "").strip():
3428
+ cfg["oracle_url"] = svc.url()
3429
+ _write_hub_config(cfg)
3430
+ result["oracle_url_set"] = True
3431
+ result["oracle_url"] = cfg["oracle_url"]
3432
+ return result
3433
+
3434
+
3435
+ @app.route("/api/oracle/service", methods=["GET"])
3436
+ def api_oracle_service_status():
3437
+ """Whether the Oracle is registered as a startup service / currently up."""
3438
+ return jsonify(_oracle_service().status())
3439
+
3440
+
3441
+ @app.route("/api/oracle/service/install", methods=["POST"])
3442
+ def api_oracle_service_install():
3443
+ """Register the Oracle to start at login (windowless) and start it now."""
3444
+ svc = _oracle_service()
3445
+ return jsonify(_adopt_oracle_url(svc, svc.install()))
3446
+
3447
+
3448
+ @app.route("/api/oracle/service/uninstall", methods=["POST"])
3449
+ def api_oracle_service_uninstall():
3450
+ """Remove the Oracle's startup registration (does not stop a running one)."""
3451
+ return jsonify(_oracle_service().uninstall())
3452
+
3453
+
3454
+ @app.route("/api/oracle/service/start", methods=["POST"])
3455
+ def api_oracle_service_start():
3456
+ """Start the Oracle as a detached background process (no terminal)."""
3457
+ svc = _oracle_service()
3458
+ return jsonify(_adopt_oracle_url(svc, svc.start()))
3459
+
3460
+
3461
+ @app.route("/api/oracle/service/stop", methods=["POST"])
3462
+ def api_oracle_service_stop():
3463
+ """Kill the Oracle process listening on its configured port."""
3464
+ return jsonify(_oracle_service().stop())
3465
+
3466
+
3410
3467
  # ─── Routes: sessions ────────────────────────────────────────────────────────
3411
3468
 
3412
3469
  @app.route("/api/sessions/start", methods=["POST"])
@@ -142,7 +142,8 @@ function App() {
142
142
  onOpenProject={(p, tab) => { setSearchOpen(false); openDrill(p, tab || 'overview'); }} />
143
143
  {modal &&
144
144
  <HubModals modal={modal} projects={projects}
145
- onClose={() => setModal(null)} onChanged={loadProjects} />}
145
+ onClose={() => setModal(null)}
146
+ onChanged={() => { loadConfig(); loadProjects(); }} />}
146
147
  <ToastHost />
147
148
  </div>
148
149
  );
@@ -15,10 +15,14 @@ const HUB_CREDS_EMPTY_FORM = {
15
15
  fields: {},
16
16
  };
17
17
 
18
- // Structured kinds (v2.87.0): per-type field sets composed into a JSON
19
- // object client-side. `hidden` fields render as password inputs. These
20
- // entries are inject-only — the server refuses agent_readable/inject and
18
+ // Structured kinds (v2.87.0; `login` v2.90.0): per-type field sets composed
19
+ // into a JSON object client-side. `hidden` fields render as password inputs.
20
+ // These entries are inject-only — the server refuses agent_readable/inject and
21
21
  // there is no reveal path anywhere.
22
+ // This table MUST mirror services/credential_store._SCHEMAS — a kind the store
23
+ // accepts and this table omits is unreachable from the browser and, worse,
24
+ // renders as a plain secret with exposure toggles the server will refuse.
25
+ // tests/test_credential_ui_parity.py asserts the two stay in step.
22
26
  const CREDS_STRUCTURED = {
23
27
  card: { required: ['cardholder', 'number', 'expiry'],
24
28
  optional: ['cvc', 'billing_zip'], hidden: ['number', 'cvc'] },
@@ -26,11 +30,20 @@ const CREDS_STRUCTURED = {
26
30
  optional: ['recipient', 'street2', 'country', 'phone'], hidden: [] },
27
31
  identity: { required: ['full_name'],
28
32
  optional: ['dob', 'ssn', 'phone', 'email'], hidden: ['ssn', 'dob'] },
33
+ login: { required: ['site_id', 'canonical_origin', 'username', 'password'],
34
+ optional: ['totp_secret'], hidden: ['password', 'totp_secret'] },
29
35
  };
30
36
 
31
37
  const credsDisplayText = (entry) => {
32
38
  const d = entry.display || {};
33
39
  if (entry.type === 'card') return `${d.brand || 'card'} ••••${d.last4 || '????'}`;
40
+ // login's projection carries has_totp as a BOOLEAN — the generic join below
41
+ // would render it as the word "true". Username is absent by design.
42
+ if (entry.type === 'login') {
43
+ const bits = [d.site_id, d.origin].filter(Boolean);
44
+ if (d.has_totp) bits.push('2FA');
45
+ return bits.join(' · ');
46
+ }
34
47
  const vals = Object.values(d).filter(Boolean);
35
48
  return vals.length ? vals.join(', ') : '';
36
49
  };
@@ -1168,6 +1181,7 @@ function CredsManager({ path, projectName, onChanged }) {
1168
1181
  <option value="card">card — credit/debit card (inject-only)</option>
1169
1182
  <option value="address">address — postal address (inject-only)</option>
1170
1183
  <option value="identity">identity — personal info (inject-only)</option>
1184
+ <option value="login">login — website login (inject-only, storage only)</option>
1171
1185
  </select>
1172
1186
  </div>
1173
1187
  <div>
@@ -1192,6 +1206,15 @@ function CredsManager({ path, projectName, onChanged }) {
1192
1206
  (<span className="mono">{'{{cred:NAME.field}}'}</span> /{' '}
1193
1207
  <span className="mono">env_creds='NAME.field'</span>) but can never
1194
1208
  reveal them, and they never auto-inject.
1209
+ {form.type === 'login' && (
1210
+ <div style={{ marginTop: 4 }}>
1211
+ Storage only — C3 has no browser and does not log in to anything.{' '}
1212
+ <span className="mono">canonical_origin</span> is https-only and
1213
+ stored normalized so a separate out-of-process runner can pin this
1214
+ credential to exactly one origin before typing it.{' '}
1215
+ <span className="mono">totp_secret</span> is base32.
1216
+ </div>
1217
+ )}
1195
1218
  </div>
1196
1219
  ) : (
1197
1220
  <div style={{ display: 'flex', gap: 18, marginTop: 10, fontSize: 12, color: T.text }}>