code-context-control 2.138.0__tar.gz → 2.140.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 (560) hide show
  1. {code_context_control-2.138.0 → code_context_control-2.140.0}/PKG-INFO +1 -1
  2. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/c3.py +22 -2
  3. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/commands/parser.py +2 -1
  4. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/guide/tools.html +11 -2
  5. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_access_guard.py +71 -3
  6. code_context_control-2.140.0/cli/hook_agent_model.py +68 -0
  7. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_dispatch.py +11 -0
  8. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_server.py +7 -0
  9. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/mcp_server.py +33 -4
  10. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/delegate.py +286 -12
  11. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/status.py +15 -2
  12. {code_context_control-2.138.0 → code_context_control-2.140.0}/code_context_control.egg-info/PKG-INFO +1 -1
  13. {code_context_control-2.138.0 → code_context_control-2.140.0}/code_context_control.egg-info/SOURCES.txt +8 -0
  14. {code_context_control-2.138.0 → code_context_control-2.140.0}/core/config.py +13 -0
  15. {code_context_control-2.138.0 → code_context_control-2.140.0}/pyproject.toml +3 -1
  16. code_context_control-2.140.0/services/agent_downshift.py +220 -0
  17. code_context_control-2.140.0/services/bench/delegate_write_eval.py +370 -0
  18. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/claude_md.py +1 -1
  19. code_context_control-2.140.0/services/delegate_hints.py +199 -0
  20. code_context_control-2.140.0/services/delegate_write.py +243 -0
  21. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/telemetry.py +5 -1
  22. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_delegate_adoption_d4.py +9 -1
  23. code_context_control-2.140.0/tests/test_delegate_auto.py +362 -0
  24. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_delegate_telemetry_d0.py +18 -0
  25. code_context_control-2.140.0/tests/test_delegate_write.py +477 -0
  26. code_context_control-2.140.0/tests/test_delegate_write_eval.py +48 -0
  27. {code_context_control-2.138.0 → code_context_control-2.140.0}/LICENSE +0 -0
  28. {code_context_control-2.138.0 → code_context_control-2.140.0}/README.md +0 -0
  29. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/__init__.py +0 -0
  30. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/_hook_utils.py +0 -0
  31. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/_shell_writes.py +0 -0
  32. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/commands/__init__.py +0 -0
  33. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/commands/common.py +0 -0
  34. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/docs.html +0 -0
  35. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/edits.html +0 -0
  36. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/guide/access.html +0 -0
  37. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/guide/bitbucket.html +0 -0
  38. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/guide/credentials.html +0 -0
  39. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/guide/getting-started.html +0 -0
  40. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/guide/index.html +0 -0
  41. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/guide/masking.html +0 -0
  42. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/guide/oracle.html +0 -0
  43. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/guide/shared.css +0 -0
  44. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/guide/workflow.html +0 -0
  45. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_artifact.py +0 -0
  46. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_auto_snapshot.py +0 -0
  47. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_c3_signal.py +0 -0
  48. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_c3read.py +0 -0
  49. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_codex_lifecycle.py +0 -0
  50. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_edit_ledger.py +0 -0
  51. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_edit_unlock.py +0 -0
  52. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_filter.py +0 -0
  53. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_ghost_files.py +0 -0
  54. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_pretool_enforce.py +0 -0
  55. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_prompt_recall.py +0 -0
  56. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_read.py +0 -0
  57. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_session_end.py +0 -0
  58. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_session_open.py +0 -0
  59. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_session_stats.py +0 -0
  60. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hook_terse_advisor.py +0 -0
  61. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/app.js +0 -0
  62. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/add_project.js +0 -0
  63. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/config_editor.js +0 -0
  64. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
  65. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/drill_health.js +0 -0
  66. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/drill_panel.js +0 -0
  67. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
  68. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/drill_tasks.js +0 -0
  69. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/drill_views.js +0 -0
  70. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/global_search.js +0 -0
  71. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/hub_access.js +0 -0
  72. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/hub_ci.js +0 -0
  73. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/hub_cred_audit.js +0 -0
  74. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/hub_credentials.js +0 -0
  75. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
  76. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/hub_locks.js +0 -0
  77. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/hub_tokens.js +0 -0
  78. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/mcp_manager.js +0 -0
  79. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/modals.js +0 -0
  80. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/project_card.js +0 -0
  81. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/project_tree.js +0 -0
  82. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/session_drawer.js +0 -0
  83. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/settings_modal.js +0 -0
  84. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/sidebar.js +0 -0
  85. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/summary_bar.js +0 -0
  86. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/task_board.js +0 -0
  87. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/toasts.js +0 -0
  88. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/components/topbar.js +0 -0
  89. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui/state.js +0 -0
  90. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/hub_ui.html +0 -0
  91. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/mcp_proxy.py +0 -0
  92. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/progress.py +0 -0
  93. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/server.py +0 -0
  94. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/__init__.py +0 -0
  95. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/_grants.py +0 -0
  96. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/_helpers.py +0 -0
  97. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/agent.py +0 -0
  98. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/artifacts.py +0 -0
  99. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/bitbucket.py +0 -0
  100. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/ci.py +0 -0
  101. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/compress.py +0 -0
  102. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/credentials.py +0 -0
  103. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/edit.py +0 -0
  104. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/edit_verify.py +0 -0
  105. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/edits.py +0 -0
  106. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/federate.py +0 -0
  107. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/filter.py +0 -0
  108. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/impact.py +0 -0
  109. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/jira.py +0 -0
  110. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/locks.py +0 -0
  111. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/memory.py +0 -0
  112. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/override.py +0 -0
  113. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/project.py +0 -0
  114. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/read.py +0 -0
  115. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/search.py +0 -0
  116. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/session.py +0 -0
  117. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/shell.py +0 -0
  118. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/shell_job.py +0 -0
  119. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/shell_nudge.py +0 -0
  120. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/shell_parsers.py +0 -0
  121. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/shell_render.py +0 -0
  122. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/tasks.py +0 -0
  123. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/tools/validate.py +0 -0
  124. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/api.js +0 -0
  125. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/app.js +0 -0
  126. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/components/access.js +0 -0
  127. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/components/bitbucket.js +0 -0
  128. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/components/chat.js +0 -0
  129. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/components/credentials.js +0 -0
  130. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/components/dashboard.js +0 -0
  131. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/components/edits.js +0 -0
  132. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/components/enforcement.js +0 -0
  133. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/components/instructions.js +0 -0
  134. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/components/jira.js +0 -0
  135. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/components/memory.js +0 -0
  136. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/components/sessions.js +0 -0
  137. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/components/settings.js +0 -0
  138. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/components/sidebar.js +0 -0
  139. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/components/tasks.js +0 -0
  140. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/icons.js +0 -0
  141. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/pm_shared.js +0 -0
  142. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/shared.js +0 -0
  143. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui/theme.js +0 -0
  144. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui.html +0 -0
  145. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui_legacy.html +0 -0
  146. {code_context_control-2.138.0 → code_context_control-2.140.0}/cli/ui_nano.html +0 -0
  147. {code_context_control-2.138.0 → code_context_control-2.140.0}/code_context_control.egg-info/dependency_links.txt +0 -0
  148. {code_context_control-2.138.0 → code_context_control-2.140.0}/code_context_control.egg-info/entry_points.txt +0 -0
  149. {code_context_control-2.138.0 → code_context_control-2.140.0}/code_context_control.egg-info/requires.txt +0 -0
  150. {code_context_control-2.138.0 → code_context_control-2.140.0}/code_context_control.egg-info/top_level.txt +0 -0
  151. {code_context_control-2.138.0 → code_context_control-2.140.0}/core/__init__.py +0 -0
  152. {code_context_control-2.138.0 → code_context_control-2.140.0}/core/codex_patch.py +0 -0
  153. {code_context_control-2.138.0 → code_context_control-2.140.0}/core/grok_payload.py +0 -0
  154. {code_context_control-2.138.0 → code_context_control-2.140.0}/core/hook_command.py +0 -0
  155. {code_context_control-2.138.0 → code_context_control-2.140.0}/core/host.py +0 -0
  156. {code_context_control-2.138.0 → code_context_control-2.140.0}/core/ide.py +0 -0
  157. {code_context_control-2.138.0 → code_context_control-2.140.0}/core/mcp_toml.py +0 -0
  158. {code_context_control-2.138.0 → code_context_control-2.140.0}/core/web_security.py +0 -0
  159. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/__init__.py +0 -0
  160. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/config.py +0 -0
  161. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/listeners.py +0 -0
  162. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/mcp_oracle.py +0 -0
  163. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/oracle_server.py +0 -0
  164. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/oracle_ui.html +0 -0
  165. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/__init__.py +0 -0
  166. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/activity_reporter.py +0 -0
  167. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/api_auth.py +0 -0
  168. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/c3_bridge.py +0 -0
  169. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/chat_engine.py +0 -0
  170. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/chat_poll.py +0 -0
  171. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/chat_store.py +0 -0
  172. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/client_tokens.py +0 -0
  173. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/cross_memory.py +0 -0
  174. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/discovery_audit.py +0 -0
  175. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/federated_graph.py +0 -0
  176. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/health_checker.py +0 -0
  177. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/insight_engine.py +0 -0
  178. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/local_session.py +0 -0
  179. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/memory_reader.py +0 -0
  180. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/memory_writer.py +0 -0
  181. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/mobile_api.py +0 -0
  182. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/project_scanner.py +0 -0
  183. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/review_agent.py +0 -0
  184. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/tool_executor.py +0 -0
  185. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/services/tool_registry.py +0 -0
  186. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/activity.js +0 -0
  187. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/agents.js +0 -0
  188. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/app.js +0 -0
  189. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/busy.js +0 -0
  190. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/chat/conversations.js +0 -0
  191. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/chat/input.js +0 -0
  192. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/chat/markdown.js +0 -0
  193. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/chat/send.js +0 -0
  194. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/chat/stream_renderer.js +0 -0
  195. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/chat/toolbar.js +0 -0
  196. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/core.js +0 -0
  197. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/crossgraph.js +0 -0
  198. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/header.js +0 -0
  199. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/insights.js +0 -0
  200. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/projects.js +0 -0
  201. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/qrcode.js +0 -0
  202. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/settings.js +0 -0
  203. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/suggestions.js +0 -0
  204. {code_context_control-2.138.0 → code_context_control-2.140.0}/oracle/ui/theme_tabs.js +0 -0
  205. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/__init__.py +0 -0
  206. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/access_guard.py +0 -0
  207. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/access_telemetry.py +0 -0
  208. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/activity_log.py +0 -0
  209. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/agent_base.py +0 -0
  210. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/agent_locks.py +0 -0
  211. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/agents.py +0 -0
  212. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/agents_workflow.py +0 -0
  213. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/artifact_defs.py +0 -0
  214. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/artifact_store.py +0 -0
  215. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/atomic_json.py +0 -0
  216. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/auto_memory.py +0 -0
  217. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/background_service.py +0 -0
  218. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/bench/__init__.py +0 -0
  219. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/bench/delegate_eval.py +0 -0
  220. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/bench/external/__init__.py +0 -0
  221. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/bench/external/aider_polyglot.py +0 -0
  222. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/bench/external/swe_bench.py +0 -0
  223. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/bench/map_eval.py +0 -0
  224. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/bench/search_eval.py +0 -0
  225. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/bench/shell_eval.py +0 -0
  226. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/benchmark_dashboard.py +0 -0
  227. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/bitbucket_client.py +0 -0
  228. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/bitbucket_credentials.py +0 -0
  229. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/ci_act.py +0 -0
  230. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/ci_cache.py +0 -0
  231. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/ci_expr.py +0 -0
  232. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/ci_failures.py +0 -0
  233. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/ci_github.py +0 -0
  234. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/ci_impact.py +0 -0
  235. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/ci_intel.py +0 -0
  236. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/ci_runner.py +0 -0
  237. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/ci_workflow.py +0 -0
  238. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/circuit_breaker.py +0 -0
  239. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/codex_integration.py +0 -0
  240. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/codex_transcript.py +0 -0
  241. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/compressor.py +0 -0
  242. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/context_snapshot.py +0 -0
  243. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/conversation_store.py +0 -0
  244. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/cred_audit.py +0 -0
  245. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/cred_telemetry.py +0 -0
  246. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/credential_store.py +0 -0
  247. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/delegate_agents.py +0 -0
  248. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/dir_map.py +0 -0
  249. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/doc_index.py +0 -0
  250. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/e2e_benchmark.py +0 -0
  251. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/e2e_evaluator.py +0 -0
  252. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/e2e_tasks.py +0 -0
  253. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/edit_ledger.py +0 -0
  254. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/embedding_index.py +0 -0
  255. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/enforcement_policy.py +0 -0
  256. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/error_reporting.py +0 -0
  257. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/file_map.py +0 -0
  258. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/file_memory.py +0 -0
  259. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/git_context.py +0 -0
  260. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/grok_integration.py +0 -0
  261. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/grok_transcript.py +0 -0
  262. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/host_sessions.py +0 -0
  263. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/hub_service.py +0 -0
  264. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/index_store.py +0 -0
  265. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/indexer.py +0 -0
  266. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/jira_client.py +0 -0
  267. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/jira_cloud.py +0 -0
  268. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/jira_credentials.py +0 -0
  269. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/jira_data_center.py +0 -0
  270. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/jira_links.py +0 -0
  271. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/lexical_index.py +0 -0
  272. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/mask_activation.py +0 -0
  273. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/mask_mirror.py +0 -0
  274. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/mask_presets.py +0 -0
  275. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/memory.py +0 -0
  276. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/memory_consolidator.py +0 -0
  277. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/memory_distiller.py +0 -0
  278. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/memory_graph.py +0 -0
  279. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/memory_grounder.py +0 -0
  280. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/memory_queue.py +0 -0
  281. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/memory_scorer.py +0 -0
  282. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/metrics.py +0 -0
  283. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/notifications.py +0 -0
  284. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/ollama_bridge.py +0 -0
  285. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/ollama_client.py +0 -0
  286. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/ollama_credentials.py +0 -0
  287. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/oracle_service.py +0 -0
  288. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/output_filter.py +0 -0
  289. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/override_costs.py +0 -0
  290. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/override_grants.py +0 -0
  291. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/override_policy.py +0 -0
  292. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/override_requests.py +0 -0
  293. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/override_wake.py +0 -0
  294. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/parser.py +0 -0
  295. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/project_manager.py +0 -0
  296. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/project_runtime.py +0 -0
  297. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/protocol.py +0 -0
  298. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/proxy_state.py +0 -0
  299. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/repo_map.py +0 -0
  300. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/repo_shape.py +0 -0
  301. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/reranker.py +0 -0
  302. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/retention.py +0 -0
  303. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/retrieval.py +0 -0
  304. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/retrieval_broker.py +0 -0
  305. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/router.py +0 -0
  306. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/runtime.py +0 -0
  307. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/scanner.py +0 -0
  308. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/session_benchmark.py +0 -0
  309. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/session_live.py +0 -0
  310. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/session_manager.py +0 -0
  311. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/session_preloader.py +0 -0
  312. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/shell_jobs.py +0 -0
  313. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/shell_output.py +0 -0
  314. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/subprojects.py +0 -0
  315. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/task_store.py +0 -0
  316. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/text_index.py +0 -0
  317. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/time_tracker.py +0 -0
  318. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/tool_classifier.py +0 -0
  319. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/transcript_index.py +0 -0
  320. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/validation_cache.py +0 -0
  321. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/vector_store.py +0 -0
  322. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/watcher.py +0 -0
  323. {code_context_control-2.138.0 → code_context_control-2.140.0}/services/win_subprocess.py +0 -0
  324. {code_context_control-2.138.0 → code_context_control-2.140.0}/setup.cfg +0 -0
  325. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_access_builtin_optout.py +0 -0
  326. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_access_guard.py +0 -0
  327. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_access_guard_meta.py +0 -0
  328. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_access_guard_shell_project.py +0 -0
  329. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_access_guard_surfaces.py +0 -0
  330. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_access_guard_wiring.py +0 -0
  331. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_activity_log_find_last.py +0 -0
  332. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_activity_reporter.py +0 -0
  333. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_agent_locks.py +0 -0
  334. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_aider_polyglot.py +0 -0
  335. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_antigravity_transition.py +0 -0
  336. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_artifact_store.py +0 -0
  337. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_artifact_tool.py +0 -0
  338. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_atomic_json.py +0 -0
  339. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_background_service.py +0 -0
  340. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_bitbucket_cli_smoke.py +0 -0
  341. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_bitbucket_client.py +0 -0
  342. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_bitbucket_config_fallback.py +0 -0
  343. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_bitbucket_credentials.py +0 -0
  344. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_bitbucket_tool.py +0 -0
  345. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_builtin_modes.py +0 -0
  346. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
  347. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_c3_shell.py +0 -0
  348. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_chat_poll.py +0 -0
  349. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_ci_act.py +0 -0
  350. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_ci_cache.py +0 -0
  351. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_ci_dag_ownership.py +0 -0
  352. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_ci_expr.py +0 -0
  353. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_ci_impact.py +0 -0
  354. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_ci_intel.py +0 -0
  355. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_ci_runner.py +0 -0
  356. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_ci_workflow.py +0 -0
  357. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_circuit_breaker.py +0 -0
  358. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_claude_md_merge.py +0 -0
  359. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_claude_md_updater.py +0 -0
  360. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_cli_smoke.py +0 -0
  361. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_codex_mcp_transport.py +0 -0
  362. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_codex_native.py +0 -0
  363. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_compressor_large_file.py +0 -0
  364. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_confirm_guard.py +0 -0
  365. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_confirm_guard_wiring.py +0 -0
  366. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_cooccurrence_bounds.py +0 -0
  367. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_cred_audit.py +0 -0
  368. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_cred_telemetry.py +0 -0
  369. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_credential_login_kind.py +0 -0
  370. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_credential_store.py +0 -0
  371. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_credential_ui_parity.py +0 -0
  372. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_credentials_routes.py +0 -0
  373. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_credentials_tool.py +0 -0
  374. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_creds_cli_smoke.py +0 -0
  375. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_delegate_cascade.py +0 -0
  376. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_delegate_claude_d1.py +0 -0
  377. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_delegate_eval.py +0 -0
  378. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_delegate_grok.py +0 -0
  379. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_delegate_host_d2.py +0 -0
  380. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_delegate_scout_d3.py +0 -0
  381. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_delegate_thinking_cap.py +0 -0
  382. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_delegate_tuning.py +0 -0
  383. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_delegate_version_probe.py +0 -0
  384. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_dir_map_c3.py +0 -0
  385. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_e2e_benchmark.py +0 -0
  386. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_edit_ledger_deadline.py +0 -0
  387. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_edit_ledger_hook.py +0 -0
  388. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_edit_locking.py +0 -0
  389. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_edit_normalization.py +0 -0
  390. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_edit_verify.py +0 -0
  391. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_embedding_index_deadlock.py +0 -0
  392. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_enforcement_flip.py +0 -0
  393. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_enforcement_policy.py +0 -0
  394. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_enforcement_routes.py +0 -0
  395. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_env_parser.py +0 -0
  396. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_failed_calls_do_not_unlock.py +0 -0
  397. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_federated_graph.py +0 -0
  398. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_file_map_c1.py +0 -0
  399. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_filter_backoff.py +0 -0
  400. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_ghost_files.py +0 -0
  401. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_ghost_generation.py +0 -0
  402. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_git_branch_awareness.py +0 -0
  403. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_grok_native.py +0 -0
  404. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hook_access_guard.py +0 -0
  405. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hook_codex_compat.py +0 -0
  406. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hook_dispatch.py +0 -0
  407. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hook_grok_compat.py +0 -0
  408. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hook_pretool_enforce.py +0 -0
  409. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hook_prompt_recall.py +0 -0
  410. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hook_session_end.py +0 -0
  411. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hook_smoke.py +0 -0
  412. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hook_state.py +0 -0
  413. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hook_utf8_stdio.py +0 -0
  414. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hub_credentials_route.py +0 -0
  415. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hub_credentials_routes_write.py +0 -0
  416. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hub_enforcement_routes.py +0 -0
  417. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hub_hook_migration.py +0 -0
  418. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hub_inspect_api.py +0 -0
  419. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hub_locks_routes.py +0 -0
  420. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hub_oracle_service_routes.py +0 -0
  421. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hub_override_policy_routes.py +0 -0
  422. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hub_override_routes.py +0 -0
  423. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hub_server_smoke.py +0 -0
  424. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_hub_subproject_links.py +0 -0
  425. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_ide_workflow_adaptation.py +0 -0
  426. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_index_cap_not_hardcoded.py +0 -0
  427. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_init_clear_preserves_user_content.py +0 -0
  428. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_init_scan.py +0 -0
  429. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_install_mcp_entrypoint.py +0 -0
  430. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_jira_cli_smoke.py +0 -0
  431. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_jira_client.py +0 -0
  432. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_jira_config_fallback.py +0 -0
  433. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_jira_credentials.py +0 -0
  434. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_jira_links.py +0 -0
  435. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_jira_routes.py +0 -0
  436. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_jira_tool.py +0 -0
  437. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_large_files_c4.py +0 -0
  438. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_lazy_store_init.py +0 -0
  439. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_map_eval.py +0 -0
  440. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_map_telemetry_c0.py +0 -0
  441. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_mask_guard.py +0 -0
  442. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_mask_routes.py +0 -0
  443. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_mask_surfaces.py +0 -0
  444. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_mcp_host_guard.py +0 -0
  445. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_mcp_memory_timeout.py +0 -0
  446. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_mcp_server_smoke.py +0 -0
  447. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_mcp_toml.py +0 -0
  448. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_memory_distiller.py +0 -0
  449. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_memory_graph_api.py +0 -0
  450. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_memory_queue.py +0 -0
  451. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_memory_system.py +0 -0
  452. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_mobile_api.py +0 -0
  453. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_mobile_clients.py +0 -0
  454. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_mobile_extras.py +0 -0
  455. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_mobile_jobs_ci.py +0 -0
  456. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_mobile_override_costs.py +0 -0
  457. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_mobile_override_routes.py +0 -0
  458. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_mobile_security_api.py +0 -0
  459. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_no_stale_model_pins.py +0 -0
  460. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_notification_dedup.py +0 -0
  461. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_notification_discipline.py +0 -0
  462. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_notification_kinds.py +0 -0
  463. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_ollama_credentials.py +0 -0
  464. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_oracle_api_auth.py +0 -0
  465. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_oracle_apikey_api.py +0 -0
  466. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_oracle_c3_bridge.py +0 -0
  467. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_oracle_chat_engine.py +0 -0
  468. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_oracle_chat_store.py +0 -0
  469. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_oracle_discovery_api.py +0 -0
  470. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_oracle_discovery_audit.py +0 -0
  471. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_oracle_health_probe.py +0 -0
  472. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_oracle_local_auth.py +0 -0
  473. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_oracle_loopback.py +0 -0
  474. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_oracle_ollama_bridge.py +0 -0
  475. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_oracle_scanner_cache.py +0 -0
  476. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_oracle_security_fixes.py +0 -0
  477. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_oracle_session_bootstrap.py +0 -0
  478. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_oracle_subproject_awareness.py +0 -0
  479. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_oracle_ui_bundle.py +0 -0
  480. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_output_filter.py +0 -0
  481. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_override_costs.py +0 -0
  482. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_override_grants.py +0 -0
  483. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_override_grants_mcp.py +0 -0
  484. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_override_requests.py +0 -0
  485. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_override_wake.py +0 -0
  486. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_permissions.py +0 -0
  487. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_pm_api.py +0 -0
  488. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_project_manager.py +0 -0
  489. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_project_manager_merge.py +0 -0
  490. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_project_tool.py +0 -0
  491. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_read_coercion.py +0 -0
  492. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_read_edit_parity.py +0 -0
  493. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_read_outside_root.py +0 -0
  494. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_related_facts.py +0 -0
  495. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_repo_map.py +0 -0
  496. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_repo_shape.py +0 -0
  497. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_response_boilerplate.py +0 -0
  498. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_retention.py +0 -0
  499. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_review_digest.py +0 -0
  500. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_search_eval.py +0 -0
  501. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_search_p1.py +0 -0
  502. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_search_p2.py +0 -0
  503. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_search_p2b.py +0 -0
  504. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_search_p3.py +0 -0
  505. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_search_p4.py +0 -0
  506. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_search_p5.py +0 -0
  507. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_service_durability.py +0 -0
  508. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_session_benchmark.py +0 -0
  509. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_session_budget.py +0 -0
  510. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_session_live.py +0 -0
  511. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_shell_budget_s1.py +0 -0
  512. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_shell_creds.py +0 -0
  513. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_shell_eval.py +0 -0
  514. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_shell_jobs_s3.py +0 -0
  515. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_shell_nudge_s4.py +0 -0
  516. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_shell_output.py +0 -0
  517. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_shell_parsers_s2.py +0 -0
  518. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_shell_robustness.py +0 -0
  519. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_shell_telemetry_s0.py +0 -0
  520. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_shell_write_ledger.py +0 -0
  521. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_shell_writes.py +0 -0
  522. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_subproject_clear_scope.py +0 -0
  523. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_subproject_depth_consumers.py +0 -0
  524. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_subproject_exclusion.py +0 -0
  525. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_subproject_federation.py +0 -0
  526. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_subproject_linkage_api.py +0 -0
  527. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_subprojects.py +0 -0
  528. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_swe_bench.py +0 -0
  529. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_task_store.py +0 -0
  530. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_task_tool.py +0 -0
  531. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_time_tracker.py +0 -0
  532. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_token_telemetry.py +0 -0
  533. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_token_tracking.py +0 -0
  534. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_tool_registry.py +0 -0
  535. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_ui_jsx_syntax.py +0 -0
  536. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_upgrade_and_version.py +0 -0
  537. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_validate.py +0 -0
  538. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_vault_write_guard.py +0 -0
  539. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_version_sync.py +0 -0
  540. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_watcher_pruning.py +0 -0
  541. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_web_security.py +0 -0
  542. {code_context_control-2.138.0 → code_context_control-2.140.0}/tests/test_windows_reliability.py +0 -0
  543. {code_context_control-2.138.0 → code_context_control-2.140.0}/tui/__init__.py +0 -0
  544. {code_context_control-2.138.0 → code_context_control-2.140.0}/tui/backend.py +0 -0
  545. {code_context_control-2.138.0 → code_context_control-2.140.0}/tui/main.py +0 -0
  546. {code_context_control-2.138.0 → code_context_control-2.140.0}/tui/screens/__init__.py +0 -0
  547. {code_context_control-2.138.0 → code_context_control-2.140.0}/tui/screens/benchmark_view.py +0 -0
  548. {code_context_control-2.138.0 → code_context_control-2.140.0}/tui/screens/claudemd_view.py +0 -0
  549. {code_context_control-2.138.0 → code_context_control-2.140.0}/tui/screens/compress_view.py +0 -0
  550. {code_context_control-2.138.0 → code_context_control-2.140.0}/tui/screens/index_view.py +0 -0
  551. {code_context_control-2.138.0 → code_context_control-2.140.0}/tui/screens/init_view.py +0 -0
  552. {code_context_control-2.138.0 → code_context_control-2.140.0}/tui/screens/mcp_view.py +0 -0
  553. {code_context_control-2.138.0 → code_context_control-2.140.0}/tui/screens/optimize_view.py +0 -0
  554. {code_context_control-2.138.0 → code_context_control-2.140.0}/tui/screens/pipe_view.py +0 -0
  555. {code_context_control-2.138.0 → code_context_control-2.140.0}/tui/screens/projects_view.py +0 -0
  556. {code_context_control-2.138.0 → code_context_control-2.140.0}/tui/screens/search_view.py +0 -0
  557. {code_context_control-2.138.0 → code_context_control-2.140.0}/tui/screens/session_view.py +0 -0
  558. {code_context_control-2.138.0 → code_context_control-2.140.0}/tui/screens/stats.py +0 -0
  559. {code_context_control-2.138.0 → code_context_control-2.140.0}/tui/screens/ui_view.py +0 -0
  560. {code_context_control-2.138.0 → code_context_control-2.140.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.138.0
3
+ Version: 2.140.0
4
4
  Summary: Local MCP code-intelligence for AI coding tools: surgical search/read/edit, agent-config version history, path-level access + masking guards, and a multi-project hub.
5
5
  Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -91,7 +91,10 @@ console = Console() if HAS_RICH else None
91
91
  # Config
92
92
  CONFIG_DIR = ".c3"
93
93
  CONFIG_FILE = ".c3/config.json"
94
- __version__ = "2.138.0"
94
+ __version__ = "2.140.0"
95
+
96
+ # The PreToolUse matcher for native subagent calls (installer and hub migration).
97
+ AGENT_MATCHER = "Agent|Task"
95
98
 
96
99
 
97
100
  def _compress_file_cli(compressor, path, mode="smart", **kw):
@@ -1583,6 +1586,19 @@ def cmd_delegate_eval(args):
1583
1586
 
1584
1587
  targets = [t.strip() for t in (args.targets or "").split(",") if t.strip()]
1585
1588
  case_ids = [c.strip() for c in (args.cases or "").split(",") if c.strip()]
1589
+ if args.suite == "write":
1590
+ # Write mode (docs/delegate-write.md): graded on the files left behind.
1591
+ from services.bench import delegate_write_eval as dwe
1592
+ if not targets:
1593
+ raise RuntimeError("--suite write needs --targets (e.g. claude:small,claude:medium, or gold)")
1594
+ try:
1595
+ overrides = json.loads(args.config) if getattr(args, "config", None) else None
1596
+ report = dwe.run_write_suite(targets, case_ids=case_ids or None, record=args.record,
1597
+ delegate_overrides=overrides)
1598
+ except ValueError as e:
1599
+ raise RuntimeError(str(e))
1600
+ print(json.dumps(report, indent=2) if args.json else dwe.render(report))
1601
+ return
1586
1602
  overrides = json.loads(args.config) if getattr(args, "config", None) else None
1587
1603
  if overrides is not None and not isinstance(overrides, dict):
1588
1604
  raise RuntimeError("--config must be a JSON object")
@@ -5065,7 +5081,7 @@ back to native tools as the task progresses.
5065
5081
  - **Filter**: `c3_filter(text=...)` — for terminal output >10 lines
5066
5082
  - **Shell**: `c3_shell(cmd, timeout=60)` — structured shell exec (tests/git/build). Auto-filters output, logs git mutations to the ledger. Native Bash for interactive/TTY only
5067
5083
  - **Memory**: `c3_memory(action='recall')` — full recall. `index` + `fetch` for token-efficient two-step retrieval
5068
- - **Delegate**: `c3_delegate(task, task_type, context|file_path)` — your own provider one tier down (default `backend='host'`, `tier='small'`; Claude Code: Haiku) for bounded answers: summarize a diff/log, explain a function, triage a traceback. `scout=true` lets it look files up itself. Multi-step work: the `c3-scout` (haiku) / `c3-worker` (sonnet) subagents
5084
+ - **Delegate**: `c3_delegate(task, task_type, context|file_path)` — your own provider one tier down (default `backend='host'`, `tier='small'`; Claude Code: Haiku) for bounded answers: summarize a diff/log, explain a function, triage a traceback. `scout=true` lets it look files up itself; `write_paths='a.py,b.py'` has Sonnet make a change you specified in only those files and return the diff. Multi-step work: the `c3-scout` (haiku) / `c3-worker` (sonnet) subagents; an `Agent` call with no `model` runs one tier below you (pass `model=` to choose)
5069
5085
  - **Local CI** (v2.79.0+): `c3_ci(action='inspect|run|rerun|failures')` — run THIS repo's real `.github/workflows` here instead of pushing for feedback. `run` executes in `needs` order; `failures` gives {file,line,message}; `rerun` retries only what failed. Only `FULL_CI_PASS` means safe to push — `PARTIAL_PASS` means something did not run (other OS, unsupported action, or your selection).
5070
5086
  - **Bitbucket** (v2.30.0+, when `c3 bitbucket login` has run): `c3_bitbucket(action='list_prs|get_pr|merge_pr|...')` — self-hosted Bitbucket Data Center / Server. Token in OS keyring; mutating actions auto-log to the edit ledger.
5071
5087
  - **Cross-project** (v2.31.0+): `c3_project(action='list|scan|search|read|edit|...', project='<name|path>')` — discover and operate on OTHER c3-installed projects. Reads run freely; writes (edit/shell/memory) need `allow_write=true`.
@@ -5684,6 +5700,10 @@ def cmd_install_mcp(args):
5684
5700
  shell_matcher,
5685
5701
  "run_shell_command",
5686
5702
  ]
5703
+ # Native subagents (v2.140.0): a blank `model` is filled one tier below
5704
+ # the parent by hook_agent_model — without this matcher PreToolUse
5705
+ # never fires for Agent calls.
5706
+ _pre_matcher_names.append(AGENT_MATCHER)
5687
5707
  desired_pre_hooks = [
5688
5708
  {"matcher": m, "hooks": [{"type": "command", "command": hook_pretool_cmd}]}
5689
5709
  for m in _pre_matcher_names
@@ -92,7 +92,8 @@ def build_parser(version: str, parse_cli_ide_arg):
92
92
  p_delegate_eval = subparsers.add_parser(
93
93
  "delegate-eval", help="Grade c3_delegate answers per backend/tier (docs/delegate-eval.md)")
94
94
  p_delegate_eval.add_argument("--suite", default="gold",
95
- help="'gold' (bundled) or a .jsonl path")
95
+ help="'gold' (bundled), 'write' (write mode, docs/delegate-write.md) "
96
+ "or a .jsonl path")
96
97
  p_delegate_eval.add_argument("--targets", default="",
97
98
  help="Comma-separated backend[:tier] list, e.g. 'claude:small,claude:medium'")
98
99
  p_delegate_eval.add_argument("--cases", default="", help="Comma-separated case ids (default: all)")
@@ -954,6 +954,12 @@ c3_status(view=<span class="str">'sessions'</span>) <span class="com">#
954
954
  <td class="param-default">false</td>
955
955
  <td class="param-desc">Let the delegate Read/Grep/Glob the project itself, for lookups when you cannot name the files. Claude runs <code>--restricted</code> with Access Guard's read denies; Codex uses its read-only sandbox.</td>
956
956
  </tr>
957
+ <tr>
958
+ <td class="param-name">write_paths</td>
959
+ <td class="param-type">string</td>
960
+ <td class="param-default">""</td>
961
+ <td class="param-desc">Write mode (Claude only, defaults to Sonnet). Comma-separated project-relative globs the delegate may edit or create. You decide the change; it makes it with Read/Grep/Glob/Edit/Write, no commands. You get back the diff, and each change is in the edit ledger. Access Guard applies; confirm-held, locked, <code>.git/</code> and <code>.c3/</code> paths are refused. Review the diff and run the tests yourself.</td>
962
+ </tr>
957
963
  </tbody>
958
964
  </table>
959
965
 
@@ -965,12 +971,15 @@ c3_delegate(task=<span class="str">'Summarize this diff for a changelog in three
965
971
  c3_delegate(task=<span class="str">'What does resolve_host return inside a grok child?'</span>, file_path=<span class="str">'core/host.py'</span>, task_type=<span class="str">'explain'</span>, tier=<span class="str">'medium'</span>)
966
972
 
967
973
  <span class="com"># A lookup the delegate does itself</span>
968
- c3_delegate(task=<span class="str">'Which functions call charge_card, and where?'</span>, scout=<span class="kw">True</span>)</code></pre>
974
+ c3_delegate(task=<span class="str">'Which functions call charge_card, and where?'</span>, scout=<span class="kw">True</span>)
975
+
976
+ <span class="com"># A change you have decided, made by Sonnet inside a write set</span>
977
+ c3_delegate(task=<span class="str">'Rename calc_total to order_total in its definition and every use; no alias'</span>, write_paths=<span class="str">'inv/orders.py, inv/report.py, tests/test_orders.py'</span>)</code></pre>
969
978
 
970
979
  <div class="callout callout-info">
971
980
  <span class="callout-icon">ℹ️</span>
972
981
  <div class="callout-body">
973
- For multi-step work in Claude Code, <code>c3 install-mcp</code> also writes two subagents to <code>.claude/agents</code>: <code>c3-scout</code> (Haiku, read-only) and <code>c3-worker</code> (Sonnet). They run inside your session, so C3's hooks apply to them. Skip them with <code>--no-agents</code>. <code>c3 delegate-eval</code> measures pass rate and cost per backend and tier on your machine.
982
+ For multi-step work in Claude Code, <code>c3 install-mcp</code> also writes two subagents to <code>.claude/agents</code>: <code>c3-scout</code> (Haiku, read-only) and <code>c3-worker</code> (Sonnet). They run inside your session, so C3's hooks apply to them. Skip them with <code>--no-agents</code>. Any other <code>Agent</code> call that leaves <code>model</code> blank runs one tier below your session (Fable → Opus → Sonnet, never below Sonnet); set <code>delegate.agent_downshift</code> to <code>"off"</code> to keep the parent's model. When your own work looks delegable, a <code>[c3:delegate-hint]</code> line on the tool response names the call to make. <code>c3 delegate-eval</code> measures pass rate and cost per backend and tier on your machine.
974
983
  </div>
975
984
  </div>
976
985
  </div>
@@ -503,14 +503,77 @@ def run(payload: dict, project_path: Path | None = None,
503
503
  return None
504
504
 
505
505
 
506
+ def _worker_refusal(rel: str, why: str) -> dict:
507
+ return _deny(f"[c3-delegate:refused] {rel}: {why}. Do not write it another way; "
508
+ "leave it and say in your report what change it needed.")
509
+
510
+
511
+ def worker_run(payload: dict, project_path: Path, state_dir: Path) -> dict | None:
512
+ """PreToolUse for a ``c3_delegate`` write-mode worker (see services/delegate_write).
513
+
514
+ Reads go through ``run`` exactly as for a scout. A write must pass, in
515
+ order: canonicalization inside the project, never ``.git/`` or ``.c3/``,
516
+ never the credential vault, Access Guard with NO grants and NO filed
517
+ requests (a confirm hold is a refusal here — a headless worker cannot
518
+ wait for a human, and the caller can make that edit itself), the caller's
519
+ write set, and another agent's lock. Then the pre-image is saved before
520
+ the write is allowed. Raises on a broken spec; main() turns that into a
521
+ deny.
522
+ """
523
+ from services import delegate_write as dw
524
+
525
+ tool = normalize_tool_name(payload.get("tool_name", ""))
526
+ if tool not in _WRITE_TOOLS:
527
+ return run(payload, project_path)
528
+ spec = dw.load_spec(state_dir)
529
+ fp = _target(payload.get("tool_input", {}) or {})
530
+ if not fp:
531
+ return _deny("[c3-delegate:refused] a write with no target path")
532
+ base = str(project_path)
533
+ canon, rel, denial = ag.canonicalize(fp, base)
534
+ if denial:
535
+ return _worker_refusal(fp, f"path refused ({denial.reason})")
536
+ if not rel:
537
+ return _worker_refusal(fp, "outside the project")
538
+ if dw.forbidden(rel):
539
+ return _worker_refusal(rel, "under .git/ or .c3/, never delegate-writable")
540
+ try:
541
+ from services import credential_store as _cs
542
+ vault = _cs.vault_guard_reason(fp)
543
+ except Exception as exc: # fail closed: an unloadable vault check refuses
544
+ vault = f"vault check unavailable ({type(exc).__name__})"
545
+ if vault:
546
+ return _worker_refusal(rel, "credential vault file")
547
+ op = "write" if os.path.exists(fp) else "create"
548
+ denial = ag.check(fp, op, base)
549
+ if denial:
550
+ _record(denial, tool, op, fp, base, str(payload.get("session_id") or ""))
551
+ return _worker_refusal(rel, f"Access Guard {denial.kind} rule '{denial.rule}' "
552
+ f"({denial.scope})")
553
+ if not dw.in_write_set(rel, spec["write_paths"]):
554
+ return _worker_refusal(rel, "outside the write set the caller gave ("
555
+ + ", ".join(spec["write_paths"]) + ")")
556
+ try:
557
+ from services import agent_locks
558
+ holder = agent_locks.check(fp, base, str(spec.get("session_id") or ""))
559
+ except Exception:
560
+ holder = None
561
+ if holder:
562
+ return _worker_refusal(rel, f"locked by {holder.get('agent_id', 'another agent')}")
563
+ dw.snapshot(state_dir, fp, canon)
564
+ return None
565
+
566
+
506
567
  def main() -> None:
507
- """Standalone PreToolUse entry for a ``c3_delegate`` scout run.
568
+ """Standalone PreToolUse entry for a ``c3_delegate`` scout or worker run.
508
569
 
509
570
  A scout is ``claude -p --restricted`` with Read/Grep/Glob and no C3 MCP
510
571
  server, so the dispatcher's discipline hook (hook_pretool_enforce) would
511
572
  refuse every native read. Only the access guard runs here. It prints a
512
573
  deny and nothing else: grants and search footers are for an agent that
513
574
  can act on them. Any failure denies (fail closed).
575
+
576
+ ``--worker-state DIR``: a write-mode worker; see ``worker_run``.
514
577
  """
515
578
  import argparse
516
579
  import json
@@ -520,6 +583,7 @@ def main() -> None:
520
583
  ensure_utf8_stdio()
521
584
  parser = argparse.ArgumentParser()
522
585
  parser.add_argument("--project", required=True)
586
+ parser.add_argument("--worker-state", default="")
523
587
  args = parser.parse_args()
524
588
  try:
525
589
  raw = sys.stdin.read()
@@ -527,9 +591,13 @@ def main() -> None:
527
591
  if not isinstance(payload, dict):
528
592
  raise ValueError("hook payload must be a JSON object")
529
593
  # access_guard canonicalizes the base itself (no direct resolve here).
530
- out = run(payload, Path(args.project))
594
+ if args.worker_state:
595
+ out = worker_run(payload, Path(args.project), Path(args.worker_state))
596
+ else:
597
+ out = run(payload, Path(args.project))
531
598
  except Exception as exc:
532
- out = _deny(f"[c3-access:error] scout guard failed ({type(exc).__name__}: {exc}); "
599
+ who = "worker" if args.worker_state else "scout"
600
+ out = _deny(f"[c3-access:error] {who} guard failed ({type(exc).__name__}: {exc}); "
533
601
  "refusing the call")
534
602
  if isinstance(out, dict) and isinstance(out.get("hookSpecificOutput"), dict):
535
603
  print(json.dumps({"hookSpecificOutput": out["hookSpecificOutput"]}))
@@ -0,0 +1,68 @@
1
+ """PreToolUse sub-hook: a native subagent with no ``model`` gets one tier below its parent.
2
+
3
+ Routed by cli/hook_dispatch.py for ``Agent`` / ``Task`` on Claude Code only;
4
+ the policy lives in services/agent_downshift.py. Returns
5
+ ``hookSpecificOutput.updatedInput`` (the whole tool_input with ``model`` set),
6
+ or None to leave the call as it is. Every decision on a blank call — applied
7
+ or not, and why — is one ``agent_downshift`` telemetry row, so coverage is
8
+ measurable (how many calls fell through as ``parent_unknown``).
9
+
10
+ Opt out per project with ``delegate.agent_downshift: "off"``, or for a shell
11
+ with ``C3_AGENT_DOWNSHIFT=0``. Never raises into the tool call.
12
+ """
13
+ from __future__ import annotations
14
+
15
+ import os
16
+ import sys
17
+ from pathlib import Path
18
+
19
+ sys.path.insert(0, str(Path(__file__).parent.parent))
20
+
21
+ from cli._hook_utils import find_project, log_hook_error # noqa: E402
22
+
23
+
24
+ def run(payload: dict, project_path: Path | None = None):
25
+ try:
26
+ return _run(payload, project_path)
27
+ except Exception as exc: # a model choice is never worth a failed tool call
28
+ log_hook_error("hook_agent_model", exc)
29
+ return None
30
+
31
+
32
+ def _run(payload: dict, project_path):
33
+ from services import agent_downshift as ad
34
+
35
+ if str(payload.get("tool_name") or "") not in ad.SUBAGENT_TOOLS:
36
+ return None
37
+ tool_input = payload.get("tool_input")
38
+ if not isinstance(tool_input, dict):
39
+ return None
40
+ if str(tool_input.get("model") or "").strip():
41
+ return None # the caller chose
42
+ if os.environ.get("C3_AGENT_DOWNSHIFT", "").strip().lower() in ("0", "off", "false", "no"):
43
+ return None
44
+ project = find_project(payload, project_path)
45
+ if project is None:
46
+ return None
47
+ from core.config import load_delegate_config
48
+
49
+ cfg = load_delegate_config(str(project))
50
+ stype = str(tool_input.get("subagent_type") or "general-purpose")
51
+ if ":" in stype:
52
+ return None # plugin agent: its definition is not ours to second-guess
53
+ if ad.definition_sets_model(stype, project):
54
+ return None
55
+ parent, source = ad.parent_model(payload, project)
56
+ target, reason = ad.resolve(stype, parent, cfg)
57
+ try:
58
+ from services.telemetry import append_telemetry_record
59
+ append_telemetry_record(project, {"tool": "agent_downshift" if target else "agent_downshift_skip",
60
+ "detail": {
61
+ "subagent_type": stype, "parent_model": parent, "parent_source": source,
62
+ "model": target, "reason": reason, "applied": bool(target)}})
63
+ except Exception:
64
+ pass
65
+ if not target:
66
+ return None
67
+ return {"hookSpecificOutput": {"hookEventName": "PreToolUse",
68
+ "updatedInput": {**tool_input, "model": target}}}
@@ -136,6 +136,10 @@ def _routes(event: str, raw_tool: str, norm_tool: str, host: str = HOST_CLAUDE):
136
136
  yield "hook_access_guard"
137
137
  # hook_pretool_enforce self-filters via its _PREREQS table.
138
138
  yield "hook_pretool_enforce"
139
+ # A native subagent with no model inherits the parent's; this fills
140
+ # one in (services/agent_downshift.py). Claude Code only.
141
+ if raw_tool in ("Agent", "Task") and host == HOST_CLAUDE:
142
+ yield "hook_agent_model"
139
143
  elif event == "posttool":
140
144
  # hook_filter is the ONE sub-hook that reads the whole tool payload:
141
145
  # it tiktoken-encodes the entire Bash output to measure savings, a
@@ -402,6 +406,7 @@ def merge_outputs(outputs: list, warnings: list, is_gemini: bool = False,
402
406
  host = HOST_GEMINI if is_gemini else HOST_CLAUDE
403
407
 
404
408
  deny_hso = None
409
+ updated_input = None
405
410
  contexts: list = []
406
411
  texts: list = []
407
412
  tool_result = None
@@ -413,6 +418,8 @@ def merge_outputs(outputs: list, warnings: list, is_gemini: bool = False,
413
418
  if isinstance(hso, dict):
414
419
  if deny_hso is None and hso.get("permissionDecision") == "deny":
415
420
  deny_hso = hso
421
+ if updated_input is None and isinstance(hso.get("updatedInput"), dict):
422
+ updated_input = hso["updatedInput"]
416
423
  nested_ctx = hso.get("additionalContext")
417
424
  if nested_ctx and hso.get("permissionDecision") != "deny":
418
425
  contexts.append(str(nested_ctx))
@@ -435,6 +442,10 @@ def merge_outputs(outputs: list, warnings: list, is_gemini: bool = False,
435
442
  result: dict = {}
436
443
  if deny_hso is not None:
437
444
  result["hookSpecificOutput"] = deny_hso
445
+ elif updated_input is not None and host == HOST_CLAUDE and event == "pretool":
446
+ # A rewritten tool input (hook_agent_model) — never alongside a deny.
447
+ result["hookSpecificOutput"] = {"hookEventName": "PreToolUse",
448
+ "updatedInput": updated_input}
438
449
  if tool_result is not None:
439
450
  if is_gemini:
440
451
  # Gemini has no tool_result replacement — degrade to context,
@@ -4516,9 +4516,16 @@ def c3_hook_migrations(cli_dir: Path | None = None) -> list:
4516
4516
  "command": f"{dispatch} {arg}"}]},
4517
4517
  }
4518
4518
 
4519
+ # v2.140.0: native subagent calls reach the pretool dispatcher, where
4520
+ # hook_agent_model fills a blank model. Same literal as cli.c3.AGENT_MATCHER.
4521
+ agent_entry = {"matcher": "Agent|Task",
4522
+ "hooks": [{"type": "command", "command": f"{dispatch} pretool"}]}
4523
+
4519
4524
  return [
4520
4525
  {"settings": ".claude/settings.local.json", "event": "PostToolUse",
4521
4526
  "present": c3read_present, "entry": c3read_entry},
4527
+ {"settings": ".claude/settings.local.json", "event": "PreToolUse",
4528
+ "present": _has_matcher("Agent|Task"), "entry": agent_entry},
4522
4529
  {"settings": ".gemini/settings.json", "event": "AfterTool",
4523
4530
  "present": c3read_present, "entry": c3read_entry},
4524
4531
  # Claude only — Gemini has no session-lifecycle event to hang these on.
@@ -25,6 +25,7 @@ from fastmcp import Context, FastMCP
25
25
 
26
26
  from core.host import resolve_host
27
27
  from core.ide import get_profile
28
+ from services import delegate_hints
28
29
  from services.auto_memory import AutoMemory
29
30
  from services.context_snapshot import ContextSnapshot
30
31
  from services.runtime import C3Runtime, build_runtime, start_runtime, stop_runtime
@@ -515,6 +516,21 @@ _last_badge_count: int = 0 # delta-based: only show badge when count increases
515
516
  _finalize_lock = threading.Lock()
516
517
 
517
518
 
519
+ def _with_hint(resp, make_hint) -> str:
520
+ """``resp`` plus a delegation hint line (services/delegate_hints), when the
521
+ call succeeded and a hint is due. A hint is advice: it never fails a call."""
522
+ if not isinstance(resp, str):
523
+ return resp
524
+ try:
525
+ from cli._hook_utils import response_text_failed
526
+ if response_text_failed(resp):
527
+ return resp
528
+ hint = make_hint()
529
+ except Exception:
530
+ return resp
531
+ return f"{resp}\n{hint}" if hint else resp
532
+
533
+
518
534
  def _finalize_response(ctx: Context, tool_name: str, args: dict,
519
535
  response: str, summary: str = "",
520
536
  response_tokens: int = 0) -> str:
@@ -668,10 +684,11 @@ async def c3_search(query: str, action: str = "code", top_k: int = 3,
668
684
  def finalize(name, args, resp, summ, **kw):
669
685
  return _finalize_response(ctx, name, args, resp, summ, **kw)
670
686
 
671
- return await asyncio.to_thread(handle_search, query, action, top_k, max_tokens, svc,
687
+ resp = await asyncio.to_thread(handle_search, query, action, top_k, max_tokens, svc,
672
688
  finalize, maybe_related_facts, prefetch=prefetch,
673
689
  scope=scope, ignore_case=ignore_case,
674
690
  path=path, lang=lang, kind=kind)
691
+ return _with_hint(resp, lambda: delegate_hints.after_read(svc, ""))
675
692
 
676
693
 
677
694
  @mcp.tool()
@@ -746,7 +763,10 @@ async def c3_read(file_path: str, symbols: Any = None, lines: Any = None,
746
763
  def finalize(name, args, resp, summ, **kw):
747
764
  return _finalize_response(ctx, name, args, resp, summ, **kw)
748
765
 
749
- return await asyncio.to_thread(handle_read, file_path, symbols, lines, include_docstrings, svc, finalize)
766
+ resp = await asyncio.to_thread(handle_read, file_path, symbols, lines, include_docstrings, svc, finalize)
767
+ if not (symbols or lines):
768
+ return resp # a map is the cheap way to look; it does not count toward the hint
769
+ return _with_hint(resp, lambda: delegate_hints.after_read(svc, file_path.split(",")[0].strip()))
750
770
 
751
771
 
752
772
  # c3_compress left the MCP surface in 2.124.0: c3_read(file_path) serves the
@@ -806,11 +826,13 @@ async def c3_delegate(task: str, task_type: str = "ask", context: str = "",
806
826
  file_path: str = "", backend: str = "host",
807
827
  allow_write_delegation: bool = False,
808
828
  tier: str = "", model: str = "", scout: bool = False,
829
+ write_paths: str = "",
809
830
  ctx: Context = None) -> str:
810
831
  """OFFLOAD to another model — use when the subtask is local-model-sized or needs a different perspective.
811
832
  backend: host (default: your own provider, one tier down — Claude Code->claude, Codex->codex, Grok->grok, Antigravity->gemini) | claude|codex|gemini|grok|ollama|auto. task_type: auto, summarize, explain, review, ask, test, diagnose, ping (live auth check), available, codex_check, gemini_check, grok_check, codex_resume.
812
833
  tier: small (default; scout=true defaults to medium) | medium | large | default. claude: haiku/sonnet/opus; codex/grok: reasoning effort; gemini: flash-lite/flash/pro. model overrides the tier. Context + file_path are packed by C3 under Access Guard; a file over 8k tokens goes as its map, so for line-level questions on a big file paste the excerpt or use scout=true.
813
834
  scout=true: the delegate may Read/Grep/Glob the project itself (claude: read-only, guard-denied paths refused; codex: its read-only sandbox) — for lookups when you cannot name the files.
835
+ write_paths: comma-separated project-relative globs the delegate may edit or create (write mode; claude only, tier defaults to medium). You decide the change: say what to change, where, and the intended behaviour. It cannot run commands. You get back the diff (each change is in the edit ledger): review it and run the tests yourself. Access Guard applies; confirm-held, locked, .git/ and .c3/ paths are refused.
814
836
  grok runs read-only in a temp dir unless delegate.grok_allow_write=true (then --yolo in the project, loading its trusted .grok MCP servers and hooks).
815
837
  allow_write_delegation: explicit user opt-in for write-capable backends (gemini/grok write mode/codex_resume) while Access Guard rules are active; codex is pinned read-only instead."""
816
838
  svc = _svc(ctx)
@@ -825,10 +847,15 @@ async def c3_delegate(task: str, task_type: str = "ask", context: str = "",
825
847
  task.add_done_callback(lambda done: done.exception() if not done.cancelled() else None)
826
848
  loop.call_soon_threadsafe(schedule)
827
849
  svc._agent_progress_cb = _progress_cb
850
+ try:
851
+ delegate_hints.after_delegate(svc, write=bool(str(write_paths or "").strip()), scout=bool(scout))
852
+ except Exception:
853
+ pass
828
854
  try:
829
855
  return await asyncio.to_thread(handle_delegate, task, task_type, context,
830
856
  file_path, svc, finalize, backend,
831
- allow_write_delegation, tier, model, scout)
857
+ allow_write_delegation, tier, model, scout,
858
+ write_paths)
832
859
  finally:
833
860
  svc._agent_progress_cb = None
834
861
 
@@ -876,8 +903,10 @@ async def c3_edit(file_path: str, old_string: str = "", new_string: str = "",
876
903
  def finalize(name, args, resp, summ, **kw):
877
904
  return _finalize_response(ctx, name, args, resp, summ, **kw)
878
905
 
879
- return await asyncio.to_thread(handle_edit, file_path, old_string, new_string,
906
+ resp = await asyncio.to_thread(handle_edit, file_path, old_string, new_string,
880
907
  summary, tags, replace_all, svc, finalize, edits)
908
+ return _with_hint(resp, lambda: delegate_hints.after_edit(
909
+ svc, file_path, delegate_hints.edit_chars(new_string, edits)))
881
910
 
882
911
 
883
912
  @mcp.tool()