code-context-control 2.59.0__tar.gz → 2.60.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 (357) hide show
  1. {code_context_control-2.59.0 → code_context_control-2.60.0}/PKG-INFO +3 -1
  2. {code_context_control-2.59.0 → code_context_control-2.60.0}/README.md +2 -0
  3. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/c3.py +8 -1
  4. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/commands/common.py +51 -0
  5. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/commands/parser.py +4 -0
  6. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/guide/tools.html +53 -0
  7. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/guide/workflow.html +48 -0
  8. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hook_edit_ledger.py +9 -0
  9. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/mcp_server.py +27 -1
  10. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/agent.py +4 -4
  11. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/delegate.py +35 -20
  12. {code_context_control-2.59.0 → code_context_control-2.60.0}/code_context_control.egg-info/PKG-INFO +3 -1
  13. {code_context_control-2.59.0 → code_context_control-2.60.0}/code_context_control.egg-info/SOURCES.txt +3 -0
  14. {code_context_control-2.59.0 → code_context_control-2.60.0}/pyproject.toml +1 -1
  15. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/agents.py +1 -1
  16. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/claude_md.py +44 -14
  17. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/edit_ledger.py +7 -0
  18. code_context_control-2.60.0/services/repo_map.py +584 -0
  19. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/session_manager.py +29 -13
  20. code_context_control-2.60.0/tests/test_no_stale_model_pins.py +60 -0
  21. code_context_control-2.60.0/tests/test_repo_map.py +365 -0
  22. {code_context_control-2.59.0 → code_context_control-2.60.0}/LICENSE +0 -0
  23. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/__init__.py +0 -0
  24. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/_hook_utils.py +0 -0
  25. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/commands/__init__.py +0 -0
  26. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/docs.html +0 -0
  27. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/edits.html +0 -0
  28. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/guide/bitbucket.html +0 -0
  29. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/guide/getting-started.html +0 -0
  30. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/guide/index.html +0 -0
  31. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/guide/oracle.html +0 -0
  32. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/guide/shared.css +0 -0
  33. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hook_artifact.py +0 -0
  34. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hook_auto_snapshot.py +0 -0
  35. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hook_c3_signal.py +0 -0
  36. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hook_c3read.py +0 -0
  37. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hook_dispatch.py +0 -0
  38. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hook_edit_unlock.py +0 -0
  39. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hook_filter.py +0 -0
  40. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hook_ghost_files.py +0 -0
  41. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hook_pretool_enforce.py +0 -0
  42. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hook_prompt_recall.py +0 -0
  43. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hook_read.py +0 -0
  44. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hook_session_stats.py +0 -0
  45. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hook_terse_advisor.py +0 -0
  46. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub.html +0 -0
  47. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_server.py +0 -0
  48. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/app.js +0 -0
  49. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/add_project.js +0 -0
  50. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/config_editor.js +0 -0
  51. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
  52. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/drill_health.js +0 -0
  53. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/drill_panel.js +0 -0
  54. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
  55. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/drill_tasks.js +0 -0
  56. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/drill_views.js +0 -0
  57. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/global_search.js +0 -0
  58. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/hub_credentials.js +0 -0
  59. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/mcp_manager.js +0 -0
  60. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/modals.js +0 -0
  61. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/project_card.js +0 -0
  62. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/project_tree.js +0 -0
  63. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/session_drawer.js +0 -0
  64. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/settings_modal.js +0 -0
  65. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/sidebar.js +0 -0
  66. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/summary_bar.js +0 -0
  67. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/task_board.js +0 -0
  68. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/toasts.js +0 -0
  69. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/components/topbar.js +0 -0
  70. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui/state.js +0 -0
  71. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/hub_ui.html +0 -0
  72. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/mcp_proxy.py +0 -0
  73. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/progress.py +0 -0
  74. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/server.py +0 -0
  75. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/__init__.py +0 -0
  76. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/_helpers.py +0 -0
  77. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/artifacts.py +0 -0
  78. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/bitbucket.py +0 -0
  79. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/compress.py +0 -0
  80. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/credentials.py +0 -0
  81. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/edit.py +0 -0
  82. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/edits.py +0 -0
  83. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/federate.py +0 -0
  84. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/filter.py +0 -0
  85. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/impact.py +0 -0
  86. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/jira.py +0 -0
  87. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/memory.py +0 -0
  88. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/project.py +0 -0
  89. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/read.py +0 -0
  90. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/search.py +0 -0
  91. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/session.py +0 -0
  92. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/shell.py +0 -0
  93. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/status.py +0 -0
  94. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/tasks.py +0 -0
  95. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/tools/validate.py +0 -0
  96. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/api.js +0 -0
  97. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/app.js +0 -0
  98. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/components/bitbucket.js +0 -0
  99. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/components/chat.js +0 -0
  100. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/components/credentials.js +0 -0
  101. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/components/dashboard.js +0 -0
  102. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/components/edits.js +0 -0
  103. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/components/instructions.js +0 -0
  104. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/components/jira.js +0 -0
  105. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/components/memory.js +0 -0
  106. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/components/sessions.js +0 -0
  107. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/components/settings.js +0 -0
  108. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/components/sidebar.js +0 -0
  109. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/components/tasks.js +0 -0
  110. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/icons.js +0 -0
  111. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/pm_shared.js +0 -0
  112. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/shared.js +0 -0
  113. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui/theme.js +0 -0
  114. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui.html +0 -0
  115. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui_legacy.html +0 -0
  116. {code_context_control-2.59.0 → code_context_control-2.60.0}/cli/ui_nano.html +0 -0
  117. {code_context_control-2.59.0 → code_context_control-2.60.0}/code_context_control.egg-info/dependency_links.txt +0 -0
  118. {code_context_control-2.59.0 → code_context_control-2.60.0}/code_context_control.egg-info/entry_points.txt +0 -0
  119. {code_context_control-2.59.0 → code_context_control-2.60.0}/code_context_control.egg-info/requires.txt +0 -0
  120. {code_context_control-2.59.0 → code_context_control-2.60.0}/code_context_control.egg-info/top_level.txt +0 -0
  121. {code_context_control-2.59.0 → code_context_control-2.60.0}/core/__init__.py +0 -0
  122. {code_context_control-2.59.0 → code_context_control-2.60.0}/core/config.py +0 -0
  123. {code_context_control-2.59.0 → code_context_control-2.60.0}/core/ide.py +0 -0
  124. {code_context_control-2.59.0 → code_context_control-2.60.0}/core/mcp_toml.py +0 -0
  125. {code_context_control-2.59.0 → code_context_control-2.60.0}/core/web_security.py +0 -0
  126. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/__init__.py +0 -0
  127. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/config.py +0 -0
  128. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/mcp_oracle.py +0 -0
  129. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/oracle_server.py +0 -0
  130. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/oracle_ui.html +0 -0
  131. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/services/__init__.py +0 -0
  132. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/services/activity_reporter.py +0 -0
  133. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/services/api_auth.py +0 -0
  134. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/services/c3_bridge.py +0 -0
  135. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/services/chat_engine.py +0 -0
  136. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/services/chat_store.py +0 -0
  137. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/services/cross_memory.py +0 -0
  138. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/services/federated_graph.py +0 -0
  139. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/services/health_checker.py +0 -0
  140. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/services/insight_engine.py +0 -0
  141. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/services/local_session.py +0 -0
  142. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/services/memory_reader.py +0 -0
  143. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/services/memory_writer.py +0 -0
  144. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/services/project_scanner.py +0 -0
  145. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/services/review_agent.py +0 -0
  146. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/services/tool_executor.py +0 -0
  147. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/services/tool_registry.py +0 -0
  148. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/activity.js +0 -0
  149. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/agents.js +0 -0
  150. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/app.js +0 -0
  151. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/busy.js +0 -0
  152. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/chat/conversations.js +0 -0
  153. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/chat/input.js +0 -0
  154. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/chat/markdown.js +0 -0
  155. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/chat/send.js +0 -0
  156. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/chat/stream_renderer.js +0 -0
  157. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/chat/toolbar.js +0 -0
  158. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/core.js +0 -0
  159. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/crossgraph.js +0 -0
  160. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/header.js +0 -0
  161. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/insights.js +0 -0
  162. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/projects.js +0 -0
  163. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/settings.js +0 -0
  164. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/suggestions.js +0 -0
  165. {code_context_control-2.59.0 → code_context_control-2.60.0}/oracle/ui/theme_tabs.js +0 -0
  166. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/__init__.py +0 -0
  167. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/activity_log.py +0 -0
  168. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/agent_base.py +0 -0
  169. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/artifact_defs.py +0 -0
  170. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/artifact_store.py +0 -0
  171. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/auto_memory.py +0 -0
  172. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/bench/__init__.py +0 -0
  173. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/bench/external/__init__.py +0 -0
  174. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/bench/external/aider_polyglot.py +0 -0
  175. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/bench/external/swe_bench.py +0 -0
  176. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/benchmark_dashboard.py +0 -0
  177. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/bitbucket_client.py +0 -0
  178. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/bitbucket_credentials.py +0 -0
  179. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/circuit_breaker.py +0 -0
  180. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/compressor.py +0 -0
  181. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/context_snapshot.py +0 -0
  182. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/conversation_store.py +0 -0
  183. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/credential_store.py +0 -0
  184. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/doc_index.py +0 -0
  185. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/e2e_benchmark.py +0 -0
  186. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/e2e_evaluator.py +0 -0
  187. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/e2e_tasks.py +0 -0
  188. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/embedding_index.py +0 -0
  189. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/error_reporting.py +0 -0
  190. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/file_memory.py +0 -0
  191. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/git_context.py +0 -0
  192. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/hub_service.py +0 -0
  193. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/indexer.py +0 -0
  194. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/jira_client.py +0 -0
  195. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/jira_cloud.py +0 -0
  196. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/jira_credentials.py +0 -0
  197. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/jira_data_center.py +0 -0
  198. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/jira_links.py +0 -0
  199. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/memory.py +0 -0
  200. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/memory_consolidator.py +0 -0
  201. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/memory_distiller.py +0 -0
  202. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/memory_graph.py +0 -0
  203. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/memory_grounder.py +0 -0
  204. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/memory_queue.py +0 -0
  205. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/memory_scorer.py +0 -0
  206. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/metrics.py +0 -0
  207. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/notifications.py +0 -0
  208. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/ollama_bridge.py +0 -0
  209. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/ollama_client.py +0 -0
  210. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/ollama_credentials.py +0 -0
  211. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/output_filter.py +0 -0
  212. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/parser.py +0 -0
  213. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/project_manager.py +0 -0
  214. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/project_runtime.py +0 -0
  215. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/protocol.py +0 -0
  216. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/proxy_state.py +0 -0
  217. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/retention.py +0 -0
  218. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/retrieval_broker.py +0 -0
  219. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/router.py +0 -0
  220. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/runtime.py +0 -0
  221. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/scanner.py +0 -0
  222. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/session_benchmark.py +0 -0
  223. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/session_preloader.py +0 -0
  224. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/subprojects.py +0 -0
  225. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/task_store.py +0 -0
  226. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/telemetry.py +0 -0
  227. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/text_index.py +0 -0
  228. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/time_tracker.py +0 -0
  229. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/tool_classifier.py +0 -0
  230. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/transcript_index.py +0 -0
  231. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/validation_cache.py +0 -0
  232. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/vector_store.py +0 -0
  233. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/watcher.py +0 -0
  234. {code_context_control-2.59.0 → code_context_control-2.60.0}/services/win_subprocess.py +0 -0
  235. {code_context_control-2.59.0 → code_context_control-2.60.0}/setup.cfg +0 -0
  236. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_activity_reporter.py +0 -0
  237. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_aider_polyglot.py +0 -0
  238. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_antigravity_transition.py +0 -0
  239. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_artifact_store.py +0 -0
  240. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_artifact_tool.py +0 -0
  241. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_bitbucket_cli_smoke.py +0 -0
  242. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_bitbucket_client.py +0 -0
  243. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_bitbucket_config_fallback.py +0 -0
  244. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_bitbucket_credentials.py +0 -0
  245. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_bitbucket_tool.py +0 -0
  246. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
  247. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_c3_shell.py +0 -0
  248. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_circuit_breaker.py +0 -0
  249. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_claude_md_merge.py +0 -0
  250. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_cli_smoke.py +0 -0
  251. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_compressor_large_file.py +0 -0
  252. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_credential_store.py +0 -0
  253. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_credentials_routes.py +0 -0
  254. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_credentials_tool.py +0 -0
  255. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_creds_cli_smoke.py +0 -0
  256. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_delegate_cascade.py +0 -0
  257. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_e2e_benchmark.py +0 -0
  258. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_edit_ledger_hook.py +0 -0
  259. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_edit_normalization.py +0 -0
  260. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_enforcement_flip.py +0 -0
  261. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_federated_graph.py +0 -0
  262. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_filter_backoff.py +0 -0
  263. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_ghost_files.py +0 -0
  264. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_ghost_generation.py +0 -0
  265. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_git_branch_awareness.py +0 -0
  266. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_hook_dispatch.py +0 -0
  267. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_hook_pretool_enforce.py +0 -0
  268. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_hook_prompt_recall.py +0 -0
  269. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_hook_smoke.py +0 -0
  270. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_hook_state.py +0 -0
  271. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_hook_utf8_stdio.py +0 -0
  272. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_hub_credentials_route.py +0 -0
  273. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_hub_credentials_routes_write.py +0 -0
  274. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_hub_inspect_api.py +0 -0
  275. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_hub_server_smoke.py +0 -0
  276. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_hub_subproject_links.py +0 -0
  277. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_init_scan.py +0 -0
  278. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_install_mcp_entrypoint.py +0 -0
  279. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_jira_cli_smoke.py +0 -0
  280. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_jira_client.py +0 -0
  281. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_jira_config_fallback.py +0 -0
  282. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_jira_credentials.py +0 -0
  283. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_jira_links.py +0 -0
  284. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_jira_routes.py +0 -0
  285. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_jira_tool.py +0 -0
  286. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_lazy_store_init.py +0 -0
  287. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_mcp_host_guard.py +0 -0
  288. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_mcp_memory_timeout.py +0 -0
  289. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_mcp_server_smoke.py +0 -0
  290. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_mcp_toml.py +0 -0
  291. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_memory_distiller.py +0 -0
  292. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_memory_graph_api.py +0 -0
  293. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_memory_queue.py +0 -0
  294. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_memory_system.py +0 -0
  295. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_notification_dedup.py +0 -0
  296. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_notification_discipline.py +0 -0
  297. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_ollama_credentials.py +0 -0
  298. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_oracle_api_auth.py +0 -0
  299. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_oracle_apikey_api.py +0 -0
  300. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_oracle_c3_bridge.py +0 -0
  301. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_oracle_chat_engine.py +0 -0
  302. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_oracle_discovery_api.py +0 -0
  303. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_oracle_local_auth.py +0 -0
  304. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_oracle_ollama_bridge.py +0 -0
  305. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_oracle_scanner_cache.py +0 -0
  306. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_oracle_security_fixes.py +0 -0
  307. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_oracle_subproject_awareness.py +0 -0
  308. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_oracle_ui_bundle.py +0 -0
  309. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_output_filter.py +0 -0
  310. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_permissions.py +0 -0
  311. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_pm_api.py +0 -0
  312. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_project_manager.py +0 -0
  313. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_project_manager_merge.py +0 -0
  314. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_project_tool.py +0 -0
  315. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_read_coercion.py +0 -0
  316. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_read_edit_parity.py +0 -0
  317. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_related_facts.py +0 -0
  318. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_response_boilerplate.py +0 -0
  319. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_retention.py +0 -0
  320. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_review_digest.py +0 -0
  321. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_service_durability.py +0 -0
  322. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_session_benchmark.py +0 -0
  323. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_session_budget.py +0 -0
  324. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_shell_creds.py +0 -0
  325. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_shell_robustness.py +0 -0
  326. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_subproject_exclusion.py +0 -0
  327. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_subproject_federation.py +0 -0
  328. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_subprojects.py +0 -0
  329. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_swe_bench.py +0 -0
  330. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_task_store.py +0 -0
  331. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_task_tool.py +0 -0
  332. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_time_tracker.py +0 -0
  333. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_token_telemetry.py +0 -0
  334. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_tool_registry.py +0 -0
  335. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_upgrade_and_version.py +0 -0
  336. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_validate.py +0 -0
  337. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_version_sync.py +0 -0
  338. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_web_security.py +0 -0
  339. {code_context_control-2.59.0 → code_context_control-2.60.0}/tests/test_windows_reliability.py +0 -0
  340. {code_context_control-2.59.0 → code_context_control-2.60.0}/tui/__init__.py +0 -0
  341. {code_context_control-2.59.0 → code_context_control-2.60.0}/tui/backend.py +0 -0
  342. {code_context_control-2.59.0 → code_context_control-2.60.0}/tui/main.py +0 -0
  343. {code_context_control-2.59.0 → code_context_control-2.60.0}/tui/screens/__init__.py +0 -0
  344. {code_context_control-2.59.0 → code_context_control-2.60.0}/tui/screens/benchmark_view.py +0 -0
  345. {code_context_control-2.59.0 → code_context_control-2.60.0}/tui/screens/claudemd_view.py +0 -0
  346. {code_context_control-2.59.0 → code_context_control-2.60.0}/tui/screens/compress_view.py +0 -0
  347. {code_context_control-2.59.0 → code_context_control-2.60.0}/tui/screens/index_view.py +0 -0
  348. {code_context_control-2.59.0 → code_context_control-2.60.0}/tui/screens/init_view.py +0 -0
  349. {code_context_control-2.59.0 → code_context_control-2.60.0}/tui/screens/mcp_view.py +0 -0
  350. {code_context_control-2.59.0 → code_context_control-2.60.0}/tui/screens/optimize_view.py +0 -0
  351. {code_context_control-2.59.0 → code_context_control-2.60.0}/tui/screens/pipe_view.py +0 -0
  352. {code_context_control-2.59.0 → code_context_control-2.60.0}/tui/screens/projects_view.py +0 -0
  353. {code_context_control-2.59.0 → code_context_control-2.60.0}/tui/screens/search_view.py +0 -0
  354. {code_context_control-2.59.0 → code_context_control-2.60.0}/tui/screens/session_view.py +0 -0
  355. {code_context_control-2.59.0 → code_context_control-2.60.0}/tui/screens/stats.py +0 -0
  356. {code_context_control-2.59.0 → code_context_control-2.60.0}/tui/screens/ui_view.py +0 -0
  357. {code_context_control-2.59.0 → code_context_control-2.60.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.59.0
3
+ Version: 2.60.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
@@ -243,6 +243,8 @@ Manage `CLAUDE.md`, `AGENTS.md` (Codex), `GEMINI.md`, and `.github/copilot-instr
243
243
 
244
244
  C3-generated content is wrapped in a `<!-- C3:BEGIN … -->` / `<!-- C3:END -->` block. Regenerating (or `Compact`) only rewrites that block — **anything you write outside it is preserved**, so it's safe to keep your own notes in the same file.
245
245
 
246
+ **Live repo map (v2.60.0):** generated docs no longer embed a frozen project tree. They carry a stable pointer to `.c3/MAP.md` — a machine-owned, byte-stable map (commands, entry points, module one-liners, tree) that C3 refreshes automatically via edit hooks and a first-tool-call freshness check. Manage it with `c3 map status|ensure|refresh`; set `map.enabled=false` in `.c3/config.json` to restore the embedded tree.
247
+
246
248
  ### 7. Chat — browse prior AI conversations
247
249
 
248
250
  <p align="center">
@@ -180,6 +180,8 @@ Manage `CLAUDE.md`, `AGENTS.md` (Codex), `GEMINI.md`, and `.github/copilot-instr
180
180
 
181
181
  C3-generated content is wrapped in a `<!-- C3:BEGIN … -->` / `<!-- C3:END -->` block. Regenerating (or `Compact`) only rewrites that block — **anything you write outside it is preserved**, so it's safe to keep your own notes in the same file.
182
182
 
183
+ **Live repo map (v2.60.0):** generated docs no longer embed a frozen project tree. They carry a stable pointer to `.c3/MAP.md` — a machine-owned, byte-stable map (commands, entry points, module one-liners, tree) that C3 refreshes automatically via edit hooks and a first-tool-call freshness check. Manage it with `c3 map status|ensure|refresh`; set `map.enabled=false` in `.c3/config.json` to restore the embedded tree.
184
+
183
185
  ### 7. Chat — browse prior AI conversations
184
186
 
185
187
  <p align="center">
@@ -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.59.0"
95
+ __version__ = "2.60.0"
96
96
 
97
97
 
98
98
  def _command_deps() -> CommandDeps:
@@ -1313,6 +1313,12 @@ def cmd_claudemd(args):
1313
1313
  return common_cmd_claudemd(args, _command_deps())
1314
1314
 
1315
1315
 
1316
+ def cmd_map(args):
1317
+ """Live repo map (.c3/MAP.md) commands."""
1318
+ from cli.commands.common import cmd_map as common_cmd_map
1319
+ return common_cmd_map(args, _command_deps())
1320
+
1321
+
1316
1322
  def cmd_stats(args):
1317
1323
  """Show comprehensive stats."""
1318
1324
  return common_cmd_stats(args, _command_deps())
@@ -7162,6 +7168,7 @@ def main():
7162
7168
  "decode": cmd_decode,
7163
7169
  "session": cmd_session,
7164
7170
  "claudemd": cmd_claudemd,
7171
+ "map": cmd_map,
7165
7172
  "stats": cmd_stats,
7166
7173
  "benchmark": cmd_benchmark,
7167
7174
  "session-benchmark": cmd_session_benchmark,
@@ -159,6 +159,57 @@ def cmd_session(args, deps: CommandDeps):
159
159
  print(context)
160
160
 
161
161
 
162
+ def cmd_map(args, deps: CommandDeps):
163
+ """Live repo map (.c3/MAP.md): status | ensure | refresh."""
164
+ config = deps.load_config()
165
+ project_path = config.get("project_path", ".")
166
+
167
+ from services.repo_map import RepoMapService
168
+
169
+ sm = deps.SessionManager(project_path)
170
+ svc = RepoMapService(project_path, session_mgr=sm)
171
+
172
+ if args.map_cmd == "status":
173
+ result = svc.status()
174
+ elif args.map_cmd == "ensure":
175
+ result = svc.ensure()
176
+ else:
177
+ result = svc.refresh()
178
+
179
+ if getattr(args, "json", False):
180
+ print(json.dumps(result, indent=2))
181
+ return
182
+
183
+ if args.map_cmd == "status":
184
+ state = "STALE" if result["stale"] else ("FRESH" if result["exists"] else "MISSING")
185
+ deps.print_header(f"Repo Map — {state}")
186
+ print(f" Path: {svc.map_path}")
187
+ if result.get("generated_at"):
188
+ print(f" Generated: {result['generated_at']}")
189
+ if result.get("tokens"):
190
+ print(f" Tokens: {result['tokens']}")
191
+ if result.get("reasons"):
192
+ print(f" Stale reasons: {', '.join(result['reasons'])}")
193
+ if result.get("truncated"):
194
+ print(" [WARN] Map is truncated (file cap or token budget hit)")
195
+ else:
196
+ action = result.get("action", "?")
197
+ label = {
198
+ "regenerated": "Map regenerated",
199
+ "meta_only": "Content unchanged (meta refreshed)",
200
+ "fresh": "Already fresh — nothing to do",
201
+ "locked": "Another process is regenerating — skipped",
202
+ "disabled": "Repo map disabled (map.enabled=false in .c3/config.json)",
203
+ }.get(action, action)
204
+ deps.print_header(f"Repo Map — {label}")
205
+ if result.get("tokens"):
206
+ print(f" Tokens: {result['tokens']}, duration: {result.get('duration_ms', '?')}ms")
207
+ if result.get("reasons"):
208
+ print(f" Triggered by: {', '.join(result['reasons'])}")
209
+ if result.get("truncated"):
210
+ print(" [WARN] Map is truncated (file cap or token budget hit)")
211
+
212
+
162
213
  def cmd_claudemd(args, deps: CommandDeps):
163
214
  """Instructions file generation commands."""
164
215
  config = deps.load_config()
@@ -61,6 +61,10 @@ def build_parser(version: str, parse_cli_ide_arg):
61
61
  p_claudemd.add_argument("claudemd_cmd", choices=["generate", "save", "check"])
62
62
  p_claudemd.add_argument("--nano", action="store_true", help="Generate nano mode (~250 tokens) instead of full compact mode")
63
63
 
64
+ p_map = subparsers.add_parser("map", help="Live repo map (.c3/MAP.md) management")
65
+ p_map.add_argument("map_cmd", choices=["status", "ensure", "refresh"])
66
+ p_map.add_argument("--json", action="store_true", help="Emit JSON result")
67
+
64
68
  subparsers.add_parser("stats", help="Show statistics")
65
69
 
66
70
  p_benchmark = subparsers.add_parser("benchmark", help="Run with/without-C3 workflow benchmark")
@@ -126,6 +126,7 @@
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
128
  <a href="#c3_credentials" class="sidebar-link"><span class="icon">🔐</span> c3_credentials</a>
129
+ <a href="#c3_jira" class="sidebar-link"><span class="icon">🎫</span> c3_jira</a>
129
130
  </div>
130
131
  <div class="sidebar-section">
131
132
  <div class="sidebar-label">Cross-project</div>
@@ -163,6 +164,7 @@
163
164
  <a href="#c3_artifacts" class="toc-item">c3_artifacts <span class="cat">Config</span></a>
164
165
  <a href="#c3_bitbucket" class="toc-item">c3_bitbucket <span class="cat">SCM</span></a>
165
166
  <a href="#c3_credentials" class="toc-item">c3_credentials <span class="cat">Secrets</span></a>
167
+ <a href="#c3_jira" class="toc-item">c3_jira <span class="cat">Issues</span></a>
166
168
  <a href="#c3_project" class="toc-item">c3_project <span class="cat">Multi-project</span></a>
167
169
  </div>
168
170
  </div>
@@ -1280,6 +1282,57 @@ c3_shell(cmd=<span class="str">'curl -H "Authorization: Bearer {{cred:API_KEY}}"
1280
1282
  <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
1283
  </div>
1282
1284
  </div>
1285
+
1286
+ <!-- c3_jira -->
1287
+ <div class="tool-card" id="c3_jira">
1288
+ <div class="tool-card-header">
1289
+ <span class="tool-name">c3_jira</span>
1290
+ <div class="tag-row">
1291
+ <span class="badge badge-purple">issue tracking</span>
1292
+ <span class="badge">v2.56.0</span>
1293
+ </div>
1294
+ <span class="tool-tagline">Jira Cloud + Data Center — search, create, transition, comment through one tool</span>
1295
+ </div>
1296
+ <div class="tool-card-body">
1297
+ <p class="tool-desc">One tool for both Jira deployments: <strong>Cloud</strong> (REST v3, email + API token, ADF bodies handled transparently) and self-hosted <strong>Data Center / Server</strong> (REST v2, PAT Bearer, plain-text bodies) — normalized to a single DTO surface with an opaque pagination cursor. Transport is stdlib <code>urllib</code> (no new dependencies); reads get one bounded 429 retry honoring <code>Retry-After</code>, mutations are <em>never</em> auto-retried. Tokens live in the OS keyring keyed by <code>(base_url, username)</code>; the <code>jira</code> config section resolves project → home <strong>wholesale from a single file</strong>, so a repository's committed config can never field-override a home account's URL or TLS settings (credential-redirect hardening). HTTPS-only.</p>
1298
+
1299
+ <p class="tool-desc"><strong>Setup:</strong> <code>c3 jira login --url https://yoursite.atlassian.net</code> (Cloud inferred for <code>*.atlassian.net</code>; add <code>--deployment data_center</code> for self-hosted, <code>--ca-bundle</code> for enterprise certs, <code>--global</code> for a home config reusable across projects), then <code>c3 jira set-default --project PROJ</code>. Manage accounts with <code>c3 jira status / use / logout</code>.</p>
1300
+
1301
+ <h4>Actions</h4>
1302
+ <table class="params-table">
1303
+ <thead><tr><th>Action</th><th>Group</th><th>Description</th></tr></thead>
1304
+ <tbody>
1305
+ <tr><td class="param-name">status, whoami</td><td>Read</td><td class="param-desc">Active account, deployment, defaults, server probe / authenticated user</td></tr>
1306
+ <tr><td class="param-name">search</td><td>Read</td><td class="param-desc">Raw JQL, paginated (helper-built JQL elsewhere is always quoted)</td></tr>
1307
+ <tr><td class="param-name">my_issues</td><td>Read</td><td class="param-desc">Open issues assigned to the token's user (statusCategory-aware)</td></tr>
1308
+ <tr><td class="param-name">get_issue, list_projects, list_transitions</td><td>Read</td><td class="param-desc">Issue detail with comments / project discovery / legal transitions for an issue</td></tr>
1309
+ <tr><td class="param-name">get_create_metadata, search_users</td><td>Read</td><td class="param-desc">Required + allowed fields per project/type; user lookup for assignment</td></tr>
1310
+ <tr><td class="param-name">create_issue</td><td>Write</td><td class="param-desc">Pre-validates against create metadata and returns machine-readable missing required fields instead of guessing defaults</td></tr>
1311
+ <tr><td class="param-name">comment, transition, assign</td><td>Write</td><td class="param-desc">Comment on / move (accepts transition id <em>or</em> name) / assign an issue</td></tr>
1312
+ </tbody>
1313
+ </table>
1314
+
1315
+ <h4>Examples</h4>
1316
+ <pre><code><span class="com"># Connection + account probe, then my open work</span>
1317
+ c3_jira(action=<span class="str">'status'</span>)
1318
+ c3_jira(action=<span class="str">'my_issues'</span>)
1319
+
1320
+ <span class="com"># Raw JQL search</span>
1321
+ c3_jira(action=<span class="str">'search'</span>, jql=<span class="str">'project = PROJ AND status != Done ORDER BY updated DESC'</span>)
1322
+
1323
+ <span class="com"># Create — required fields come from metadata, not guesses</span>
1324
+ c3_jira(action=<span class="str">'get_create_metadata'</span>, project=<span class="str">'PROJ'</span>, issue_type=<span class="str">'Task'</span>)
1325
+ c3_jira(action=<span class="str">'create_issue'</span>, project=<span class="str">'PROJ'</span>, issue_type=<span class="str">'Task'</span>,
1326
+ summary=<span class="str">'Fix login flow'</span>, description=<span class="str">'Steps in thread'</span>)
1327
+
1328
+ <span class="com"># Move it along — id or name both work</span>
1329
+ c3_jira(action=<span class="str">'list_transitions'</span>, issue=<span class="str">'PROJ-123'</span>)
1330
+ c3_jira(action=<span class="str">'transition'</span>, issue=<span class="str">'PROJ-123'</span>, transition=<span class="str">'In Progress'</span>)
1331
+ c3_jira(action=<span class="str">'comment'</span>, issue=<span class="str">'PROJ-123'</span>, body=<span class="str">'Deployed to staging'</span>)</code></pre>
1332
+
1333
+ <p class="tool-desc"><strong>Surfaces &amp; audit:</strong> the per-project dashboard gets a <strong>Jira tab</strong> (My Work board grouped by statusCategory, JQL search, an issue drawer with transition buttons + comments, and an Activity view) backed by <code>/api/jira/*</code> routes. Issue keys like <code>PROJ-123</code> are auto-linked from branch names and edit-ledger entries (acronym denylist, so UTF-8 / SHA-256 / CVE-2024 never match), and the issue drawer shows the local ledger activity for the open issue — that Activity view works with no account configured. Mutations (<code>create_issue</code>, <code>comment</code>, <code>transition</code>, <code>assign</code>) are edit-ledger-logged with identifiers only — bodies are never logged. Read actions are safe in plan mode.</p>
1334
+ </div>
1335
+ </div>
1283
1336
  </div>
1284
1337
 
1285
1338
  <!-- ═══════════════════════════════════════ CROSS-PROJECT ═════ -->
@@ -250,6 +250,7 @@
250
250
  <a href="#session-restart" class="sidebar-link"><span class="icon">🔄</span> Session Restart</a>
251
251
  <a href="#terse-skill" class="sidebar-link"><span class="icon">⚡</span> /terse Skill</a>
252
252
  <a href="#subprojects" class="sidebar-link"><span class="icon">🌳</span> Sub-projects</a>
253
+ <a href="#repo-map" class="sidebar-link"><span class="icon">🗺️</span> Live Repo Map</a>
253
254
  <a href="#native-fallback" class="sidebar-link"><span class="icon">⚠️</span> Native Fallback</a>
254
255
  </div>
255
256
  </aside>
@@ -984,6 +985,53 @@ c3_memory(action=<span class="str">'recall'</span>, query=<span class="str">'pay
984
985
 
985
986
  <hr class="divider">
986
987
 
988
+ <!-- Live repo map -->
989
+ <section class="section" id="repo-map">
990
+ <div class="section-title"><span class="icon">🗺️</span> Live Repo Map (v2.60.0)</div>
991
+
992
+ <p>Instruction docs (CLAUDE.md / AGENTS.md) no longer embed a frozen project tree. They carry a stable pointer to <code>.c3/MAP.md</code> — a machine-owned map C3 keeps fresh automatically. One map serves every consumer: Claude Code, Codex, Antigravity.</p>
993
+
994
+ <p>The map contains, in priority order: build/test commands, entry points, module one-liners, the depth-2 tree, and key files — under a token budget (default 1000). Sub-projects appear as boundaries and are never expanded into the parent map.</p>
995
+
996
+ <h4>How it stays fresh</h4>
997
+ <table class="table">
998
+ <thead><tr><th>Trigger</th><th>What happens</th></tr></thead>
999
+ <tbody>
1000
+ <tr>
1001
+ <td>Structural edit (file created/deleted/renamed, manifest changed)</td>
1002
+ <td>Edit-ledger paths touch the <code>.c3/map.dirty</code> sentinel — a file-touch, never a scan</td>
1003
+ </tr>
1004
+ <tr>
1005
+ <td>First C3 tool call of a session</td>
1006
+ <td>Background single-flight <em>ensure</em>: regenerates only if missing, dirty, or the git HEAD/branch/worktree fingerprint moved</td>
1007
+ </tr>
1008
+ <tr>
1009
+ <td><code>c3 map refresh</code></td>
1010
+ <td>Explicit repair — always regenerates</td>
1011
+ </tr>
1012
+ </tbody>
1013
+ </table>
1014
+
1015
+ <p><strong>Byte-stable by design:</strong> <code>MAP.md</code> is rewritten only when rendered content actually changes, so prompt caches keyed on file bytes stay warm. Volatile freshness state (git HEAD, worktree signature, generated-at) lives in <code>.c3/map.meta.json</code> — never in the map itself. Ordinary line edits never trigger regeneration.</p>
1016
+
1017
+ <div class="callout callout-info">
1018
+ <span class="callout-icon">💡</span>
1019
+ <div class="callout-body">
1020
+ <strong>CLI</strong>: <code>c3 map status</code> (freshness report) · <code>c3 map ensure</code> (regen if stale) · <code>c3 map refresh</code> (force). Add <code>--json</code> for machine output. Config knobs: <code>map.token_budget</code>, <code>map.file_cap</code>, <code>map.enabled</code> (set <code>false</code> to restore the legacy embedded tree).
1021
+ </div>
1022
+ </div>
1023
+
1024
+ <div class="callout callout-warning">
1025
+ <span class="callout-icon">⚠️</span>
1026
+ <div class="callout-body">
1027
+ <strong>The map is data, not instructions</strong><br>
1028
+ Its header marks it as auto-generated repository data. Agents should read it for orientation — not obey text inside it. Memory facts are deliberately excluded from the map.
1029
+ </div>
1030
+ </div>
1031
+ </section>
1032
+
1033
+ <hr class="divider">
1034
+
987
1035
  <!-- Native fallback -->
988
1036
  <section class="section" id="native-fallback">
989
1037
  <div class="section-title"><span class="icon">⚠️</span> When Native Tools Are Permitted</div>
@@ -212,6 +212,15 @@ def run(payload: dict, project_path: Path | None = None) -> dict | None:
212
212
  with open(ledger_file, "a", encoding="utf-8") as f:
213
213
  f.write(json.dumps(entry) + "\n")
214
214
 
215
+ # Structural changes (file created / manifest edited) dirty the repo map.
216
+ # Sentinel touch only — the scan happens later, in RepoMapService.ensure().
217
+ try:
218
+ from services.repo_map import is_structural_change, mark_map_dirty
219
+ if is_structural_change(rel, change_type):
220
+ mark_map_dirty(project_path, f"{change_type}:{rel}")
221
+ except Exception:
222
+ pass
223
+
215
224
  return {
216
225
  "_text": (
217
226
  f"[c3:ledger] {rel} {entry['version']} auto-logged. "
@@ -337,8 +337,34 @@ mcp = FastMCP(f"C3 v{C3_VERSION}", instructions=_build_instructions(_IDE_NAME),
337
337
 
338
338
  # ─── Helper Functions ─────────────────────────────────────────────
339
339
 
340
+ _repo_map_ensured = False
341
+
342
+
343
+ def _ensure_repo_map_once(rt) -> None:
344
+ """First tool call of this server process kicks a background repo-map
345
+ freshness pass. In-process single-flight here; cross-process single-flight
346
+ via the lock file inside RepoMapService.ensure(). Never blocks the tool
347
+ call that triggered it."""
348
+ global _repo_map_ensured
349
+ if _repo_map_ensured:
350
+ return
351
+ _repo_map_ensured = True
352
+
353
+ def _bg():
354
+ try:
355
+ from services.repo_map import RepoMapService
356
+ RepoMapService(rt.project_path,
357
+ session_mgr=getattr(rt, "session_mgr", None)).ensure()
358
+ except Exception:
359
+ pass
360
+
361
+ threading.Thread(target=_bg, daemon=True, name="repo-map-ensure").start()
362
+
363
+
340
364
  def _svc(ctx: Context) -> C3Runtime:
341
- return ctx.request_context.lifespan_context
365
+ rt = ctx.request_context.lifespan_context
366
+ _ensure_repo_map_once(rt)
367
+ return rt
342
368
 
343
369
 
344
370
  _last_tool_call_time: float = 0.0
@@ -530,7 +530,7 @@ def _wf_codex_test_gen(scope, context, svc, steps_log):
530
530
  if context:
531
531
  gen_context += f"\n\nAdditional context: {context}"
532
532
 
533
- model = dcfg.get("codex_default_model", "gpt-5.3-codex-spark")
533
+ model = dcfg.get("codex_default_model", "")
534
534
  timeout = int(dcfg.get("codex_timeout", 180))
535
535
 
536
536
  steps_log.append("codex_generate")
@@ -544,7 +544,7 @@ def _wf_codex_test_gen(scope, context, svc, steps_log):
544
544
  parts = [f"--- Test generation for {len(files)} file(s) ---"]
545
545
  parts.append(f"Files: {file_list}")
546
546
  parts.append("Sandbox: workspace-write")
547
- parts.append(f"Model: {model}")
547
+ parts.append(f"Model: {model or 'cli-default'}")
548
548
  if ok:
549
549
  parts.append(f"\n--- Codex output ---\n{output}")
550
550
  else:
@@ -1005,7 +1005,7 @@ def _try_delegate(svc, task_type: str, task: str, context: str, steps_log: list,
1005
1005
  steps_log.append("codex(skipped:health_check_failed)")
1006
1006
  return ""
1007
1007
  cdef = CODEX_MODELS.get(task_type, CODEX_MODELS.get("ask", {}))
1008
- model = dcfg.get("codex_default_model") or cdef.get("model", "gpt-5.3-codex-spark")
1008
+ model = dcfg.get("codex_default_model") or cdef.get("model", "")
1009
1009
  sandbox = dcfg.get("codex_default_sandbox") or cdef.get("sandbox", "read-only")
1010
1010
  reasoning = dcfg.get("codex_reasoning_effort") or cdef.get("reasoning", "high")
1011
1011
  timeout = int(dcfg.get("codex_timeout", 90))
@@ -1109,7 +1109,7 @@ def _try_delegate(svc, task_type: str, task: str, context: str, steps_log: list,
1109
1109
  )
1110
1110
  if _codex_ok and _dm_auto._codex_available is not False:
1111
1111
  cdef = CODEX_MODELS.get(task_type, CODEX_MODELS.get("ask", {}))
1112
- c_model = dcfg.get("codex_default_model") or cdef.get("model", "gpt-5.3-codex-spark")
1112
+ c_model = dcfg.get("codex_default_model") or cdef.get("model", "")
1113
1113
  c_sandbox = dcfg.get("codex_default_sandbox") or cdef.get("sandbox", "read-only")
1114
1114
  c_reason = dcfg.get("codex_reasoning_effort") or cdef.get("reasoning", "high")
1115
1115
  c_timeout = int(dcfg.get("codex_timeout", 90))
@@ -115,15 +115,19 @@ def _popen_kwargs():
115
115
  # Codex CLI backend
116
116
  # ---------------------------------------------------------------------------
117
117
 
118
+ # No "model" keys here on purpose: a pinned model name goes stale and breaks
119
+ # accounts that don't support it (ChatGPT-plan logins reject retired models
120
+ # outright). Resolution order: .c3 config codex_default_model → the user's own
121
+ # Codex CLI default (~/.codex/config.toml). Empty model = omit -m entirely.
118
122
  CODEX_MODELS = {
119
- "review": {"model": "gpt-5.3-codex-spark", "sandbox": "read-only", "reasoning": "high"},
120
- "explain": {"model": "gpt-5.3-codex-spark", "sandbox": "read-only", "reasoning": "medium"},
121
- "improve": {"model": "gpt-5.4", "sandbox": "read-only", "reasoning": "high"},
122
- "diagnose": {"model": "gpt-5.3-codex", "sandbox": "read-only", "reasoning": "high"},
123
- "test": {"model": "gpt-5.3-codex-spark", "sandbox": "workspace-write", "reasoning": "medium"},
124
- "summarize":{"model": "gpt-5.3-codex-spark", "sandbox": "read-only", "reasoning": "low"},
125
- "docstring":{"model": "gpt-5.3-codex-spark", "sandbox": "read-only", "reasoning": "low"},
126
- "ask": {"model": "gpt-5.3-codex-spark", "sandbox": "read-only", "reasoning": "medium"},
123
+ "review": {"sandbox": "read-only", "reasoning": "high"},
124
+ "explain": {"sandbox": "read-only", "reasoning": "medium"},
125
+ "improve": {"sandbox": "read-only", "reasoning": "high"},
126
+ "diagnose": {"sandbox": "read-only", "reasoning": "high"},
127
+ "test": {"sandbox": "workspace-write", "reasoning": "medium"},
128
+ "summarize":{"sandbox": "read-only", "reasoning": "low"},
129
+ "docstring":{"sandbox": "read-only", "reasoning": "low"},
130
+ "ask": {"sandbox": "read-only", "reasoning": "medium"},
127
131
  }
128
132
 
129
133
  _codex_available: bool | None = None # cached after first check
@@ -560,6 +564,26 @@ def check_codex() -> dict:
560
564
  return {"status": "error", "detail": str(e)}
561
565
 
562
566
 
567
+ def _codex_cmd(prompt: str, model: str, sandbox: str, reasoning: str) -> list:
568
+ """Build the codex exec argv.
569
+
570
+ An empty/falsy model omits ``-m`` so the user's own Codex CLI default
571
+ (~/.codex/config.toml) applies — never pin a fallback model name here.
572
+ """
573
+ codex_exe = _which("codex") or "codex"
574
+ cmd = [codex_exe, "exec"]
575
+ if model:
576
+ cmd += ["-m", model]
577
+ cmd += [
578
+ "--config", f"model_reasoning_effort={reasoning}",
579
+ "--sandbox", sandbox,
580
+ "--full-auto",
581
+ "--skip-git-repo-check",
582
+ prompt,
583
+ ]
584
+ return cmd
585
+
586
+
563
587
  def _run_codex(task: str, context: str, model: str, sandbox: str,
564
588
  reasoning: str = "high", timeout: int = 120,
565
589
  idle_timeout: int = 20,
@@ -570,16 +594,7 @@ def _run_codex(task: str, context: str, model: str, sandbox: str,
570
594
  seconds (catches MCP startup hangs). Also enforces total timeout.
571
595
  """
572
596
  prompt = f"{task}\n\nContext:\n{context}" if context else task
573
- codex_exe = _which("codex") or "codex"
574
- cmd = [
575
- codex_exe, "exec",
576
- "-m", model,
577
- "--config", f"model_reasoning_effort={reasoning}",
578
- "--sandbox", sandbox,
579
- "--full-auto",
580
- "--skip-git-repo-check",
581
- prompt,
582
- ]
597
+ cmd = _codex_cmd(prompt, model, sandbox, reasoning)
583
598
  try:
584
599
  proc = subprocess.Popen(
585
600
  harden_win_argv(cmd),
@@ -897,7 +912,7 @@ def _handle_codex_delegate(task: str, task_type: str, context: str,
897
912
 
898
913
  # Resolve model/sandbox/reasoning from config or defaults
899
914
  cdef = CODEX_MODELS.get(task_type, CODEX_MODELS.get("ask", {}))
900
- model = dcfg.get("codex_default_model") or cdef.get("model", "gpt-5.3-codex-spark")
915
+ model = dcfg.get("codex_default_model") or cdef.get("model", "")
901
916
  sandbox = dcfg.get("codex_default_sandbox") or cdef.get("sandbox", "read-only")
902
917
  reasoning = dcfg.get("codex_reasoning_effort") or cdef.get("reasoning", "high")
903
918
  timeout = int(dcfg.get("codex_timeout", 120))
@@ -926,7 +941,7 @@ def _handle_codex_delegate(task: str, task_type: str, context: str,
926
941
  cached_resp, "cached")
927
942
 
928
943
  # Run Codex
929
- _log_progress(svc, f"[delegate] Codex {model} ({sandbox}, reasoning={reasoning})...")
944
+ _log_progress(svc, f"[delegate] Codex {model or 'cli-default'} ({sandbox}, reasoning={reasoning})...")
930
945
  t0 = time.monotonic()
931
946
  output, ok = _run_codex(
932
947
  task=task, context=enriched,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-context-control
3
- Version: 2.59.0
3
+ Version: 2.60.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
@@ -243,6 +243,8 @@ Manage `CLAUDE.md`, `AGENTS.md` (Codex), `GEMINI.md`, and `.github/copilot-instr
243
243
 
244
244
  C3-generated content is wrapped in a `<!-- C3:BEGIN … -->` / `<!-- C3:END -->` block. Regenerating (or `Compact`) only rewrites that block — **anything you write outside it is preserved**, so it's safe to keep your own notes in the same file.
245
245
 
246
+ **Live repo map (v2.60.0):** generated docs no longer embed a frozen project tree. They carry a stable pointer to `.c3/MAP.md` — a machine-owned, byte-stable map (commands, entry points, module one-liners, tree) that C3 refreshes automatically via edit hooks and a first-tool-call freshness check. Manage it with `c3 map status|ensure|refresh`; set `map.enabled=false` in `.c3/config.json` to restore the embedded tree.
247
+
246
248
  ### 7. Chat — browse prior AI conversations
247
249
 
248
250
  <p align="center">
@@ -205,6 +205,7 @@ services/project_manager.py
205
205
  services/project_runtime.py
206
206
  services/protocol.py
207
207
  services/proxy_state.py
208
+ services/repo_map.py
208
209
  services/retention.py
209
210
  services/retrieval_broker.py
210
211
  services/router.py
@@ -287,6 +288,7 @@ tests/test_memory_distiller.py
287
288
  tests/test_memory_graph_api.py
288
289
  tests/test_memory_queue.py
289
290
  tests/test_memory_system.py
291
+ tests/test_no_stale_model_pins.py
290
292
  tests/test_notification_dedup.py
291
293
  tests/test_notification_discipline.py
292
294
  tests/test_ollama_credentials.py
@@ -310,6 +312,7 @@ tests/test_project_tool.py
310
312
  tests/test_read_coercion.py
311
313
  tests/test_read_edit_parity.py
312
314
  tests/test_related_facts.py
315
+ tests/test_repo_map.py
313
316
  tests/test_response_boilerplate.py
314
317
  tests/test_retention.py
315
318
  tests/test_review_digest.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "code-context-control"
7
- version = "2.59.0"
7
+ version = "2.60.0"
8
8
  description = "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."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -1554,7 +1554,7 @@ class EditLedgerEnricherAgent(BackgroundAgent):
1554
1554
  f"--- {f} ---\n{d}" for _, f, d in batch
1555
1555
  )
1556
1556
  task = "Review these recent edits for regressions, bugs, or issues. Be concise — only flag real problems."
1557
- model = self.delegate_config.get("codex_default_model", "gpt-5.3-codex-spark")
1557
+ model = self.delegate_config.get("codex_default_model", "")
1558
1558
  timeout = int(self.delegate_config.get("codex_timeout", 120))
1559
1559
 
1560
1560
  output, ok = _run_codex(
@@ -55,6 +55,16 @@ In plan mode, all c3_* read tools (search, read, compress, filter, validate, sta
55
55
  - Reading entire files when c3_compress + c3_read would be more surgical
56
56
  - Skipping c3_validate after making edits"""
57
57
 
58
+ # Pointer that replaces the embedded Project Context tree (v2.60.0).
59
+ # The live map is machine-owned and auto-refreshed; instruction docs carry
60
+ # only this stable pointer so they never go stale and never fight the
61
+ # line budget. Works for every consumer (Claude Code, Codex, Antigravity).
62
+ MAP_POINTER_BLOCK = """\
63
+ Live repo map: `.c3/MAP.md` — tree, commands, entry points, module
64
+ one-liners. Read it BEFORE any file discovery. C3 refreshes it
65
+ automatically (edit hooks + first tool call); if it is missing or looks
66
+ stale, run `c3 map refresh`. Freshness state: `.c3/map.meta.json`."""
67
+
58
68
  # Ultra-compact workflow for nano mode (~250 tokens vs ~800 for full)
59
69
  C3_NANO_WORKFLOW = """\
60
70
  ## C3 Tools — MANDATORY
@@ -230,6 +240,17 @@ class ClaudeMdManager:
230
240
 
231
241
  return workflow
232
242
 
243
+ def _repo_map_enabled(self) -> bool:
244
+ """Live repo map is default-on; map.enabled=false in .c3/config.json
245
+ restores the legacy embedded tree."""
246
+ try:
247
+ with open(self.project_path / ".c3" / "config.json",
248
+ encoding="utf-8") as f:
249
+ cfg = json.load(f) or {}
250
+ return bool(cfg.get("map", {}).get("enabled", True))
251
+ except (OSError, ValueError):
252
+ return True
253
+
233
254
  def generate(self, include_sessions: bool = True, mode: str = "compact") -> dict:
234
255
  """Generate token-efficient CLAUDE.md from live project data.
235
256
 
@@ -264,20 +285,29 @@ class ClaudeMdManager:
264
285
  # C3 workflow instructions (compact)
265
286
  parts.append(self._build_c3_workflow(nano=False))
266
287
 
267
- # Project structure
268
- parts.append("\n# Project Context\n")
269
- parts.append(self.session_mgr._scan_project_structure())
270
-
271
- # Tech stack
272
- parts.append("\n## Tech Stack\n")
273
- parts.append(self.session_mgr._detect_tech_stack())
274
-
275
- # Key files (compact)
276
- key_files = self._detect_key_files()
277
- if key_files:
278
- parts.append("\n## Key Files\n")
279
- for kf in key_files[:5]:
280
- parts.append(f"- `{kf['file']}` — {kf['reason']}")
288
+ # Project context: pointer to the live repo map when enabled
289
+ # (v2.60.0), legacy embedded tree otherwise. The map is regenerated
290
+ # automatically (hooks + first-tool-call ensure), so the pointer
291
+ # never goes stale the way an embedded tree did.
292
+ map_enabled = self._repo_map_enabled()
293
+ if map_enabled:
294
+ parts.append("\n# Project Context\n")
295
+ parts.append(MAP_POINTER_BLOCK)
296
+ else:
297
+ # Project structure
298
+ parts.append("\n# Project Context\n")
299
+ parts.append(self.session_mgr._scan_project_structure())
300
+
301
+ # Tech stack
302
+ parts.append("\n## Tech Stack\n")
303
+ parts.append(self.session_mgr._detect_tech_stack())
304
+
305
+ # Key files (compact)
306
+ key_files = self._detect_key_files()
307
+ if key_files:
308
+ parts.append("\n## Key Files\n")
309
+ for kf in key_files[:5]:
310
+ parts.append(f"- `{kf['file']}` — {kf['reason']}")
281
311
 
282
312
  # Top learned facts only (rest available via c3_memory recall)
283
313
  promoted_facts = [
@@ -133,6 +133,13 @@ class EditLedger:
133
133
  f.write(json.dumps(entry) + "\n")
134
134
  if self._total_count is not None:
135
135
  self._total_count += 1
136
+ # Structural changes dirty the repo map (sentinel touch, never raises).
137
+ try:
138
+ from services.repo_map import is_structural_change, mark_map_dirty
139
+ if is_structural_change(rel, change_type):
140
+ mark_map_dirty(self.project_path, f"{change_type}:{rel}")
141
+ except Exception:
142
+ pass
136
143
  return entry
137
144
 
138
145
  def get_history(self, file: str = None, limit: int = 50,