code-context-control 2.112.0__tar.gz → 2.114.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 (494) hide show
  1. {code_context_control-2.112.0 → code_context_control-2.114.0}/PKG-INFO +1 -1
  2. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/c3.py +3 -2
  3. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hook_dispatch.py +1 -1
  4. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/mcp_server.py +50 -3
  5. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/project.py +11 -0
  6. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/shell.py +143 -48
  7. code_context_control-2.114.0/cli/tools/shell_job.py +363 -0
  8. code_context_control-2.114.0/cli/tools/shell_parsers.py +683 -0
  9. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/shell_render.py +198 -68
  10. {code_context_control-2.112.0 → code_context_control-2.114.0}/code_context_control.egg-info/PKG-INFO +1 -1
  11. {code_context_control-2.112.0 → code_context_control-2.114.0}/code_context_control.egg-info/SOURCES.txt +5 -0
  12. {code_context_control-2.112.0 → code_context_control-2.114.0}/pyproject.toml +1 -1
  13. code_context_control-2.114.0/services/shell_jobs.py +1160 -0
  14. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/shell_output.py +11 -4
  15. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_c3_shell.py +24 -12
  16. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_shell_budget_s1.py +23 -6
  17. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_shell_eval.py +18 -10
  18. code_context_control-2.114.0/tests/test_shell_jobs_s3.py +488 -0
  19. code_context_control-2.114.0/tests/test_shell_parsers_s2.py +566 -0
  20. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_shell_telemetry_s0.py +12 -5
  21. {code_context_control-2.112.0 → code_context_control-2.114.0}/LICENSE +0 -0
  22. {code_context_control-2.112.0 → code_context_control-2.114.0}/README.md +0 -0
  23. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/__init__.py +0 -0
  24. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/_hook_utils.py +0 -0
  25. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/_shell_writes.py +0 -0
  26. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/commands/__init__.py +0 -0
  27. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/commands/common.py +0 -0
  28. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/commands/parser.py +0 -0
  29. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/docs.html +0 -0
  30. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/edits.html +0 -0
  31. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/guide/access.html +0 -0
  32. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/guide/bitbucket.html +0 -0
  33. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/guide/credentials.html +0 -0
  34. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/guide/getting-started.html +0 -0
  35. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/guide/index.html +0 -0
  36. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/guide/masking.html +0 -0
  37. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/guide/oracle.html +0 -0
  38. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/guide/shared.css +0 -0
  39. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/guide/tools.html +0 -0
  40. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/guide/workflow.html +0 -0
  41. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hook_access_guard.py +0 -0
  42. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hook_artifact.py +0 -0
  43. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hook_auto_snapshot.py +0 -0
  44. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hook_c3_signal.py +0 -0
  45. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hook_c3read.py +0 -0
  46. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hook_edit_ledger.py +0 -0
  47. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hook_edit_unlock.py +0 -0
  48. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hook_filter.py +0 -0
  49. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hook_ghost_files.py +0 -0
  50. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hook_pretool_enforce.py +0 -0
  51. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hook_prompt_recall.py +0 -0
  52. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hook_read.py +0 -0
  53. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hook_session_stats.py +0 -0
  54. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hook_terse_advisor.py +0 -0
  55. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_server.py +0 -0
  56. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/app.js +0 -0
  57. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/add_project.js +0 -0
  58. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/config_editor.js +0 -0
  59. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
  60. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/drill_health.js +0 -0
  61. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/drill_panel.js +0 -0
  62. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
  63. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/drill_tasks.js +0 -0
  64. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/drill_views.js +0 -0
  65. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/global_search.js +0 -0
  66. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/hub_access.js +0 -0
  67. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/hub_ci.js +0 -0
  68. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/hub_cred_audit.js +0 -0
  69. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/hub_credentials.js +0 -0
  70. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
  71. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/hub_locks.js +0 -0
  72. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/hub_tokens.js +0 -0
  73. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/mcp_manager.js +0 -0
  74. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/modals.js +0 -0
  75. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/project_card.js +0 -0
  76. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/project_tree.js +0 -0
  77. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/session_drawer.js +0 -0
  78. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/settings_modal.js +0 -0
  79. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/sidebar.js +0 -0
  80. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/summary_bar.js +0 -0
  81. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/task_board.js +0 -0
  82. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/toasts.js +0 -0
  83. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/components/topbar.js +0 -0
  84. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui/state.js +0 -0
  85. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/hub_ui.html +0 -0
  86. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/mcp_proxy.py +0 -0
  87. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/progress.py +0 -0
  88. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/server.py +0 -0
  89. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/__init__.py +0 -0
  90. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/_grants.py +0 -0
  91. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/_helpers.py +0 -0
  92. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/agent.py +0 -0
  93. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/artifacts.py +0 -0
  94. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/bitbucket.py +0 -0
  95. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/ci.py +0 -0
  96. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/compress.py +0 -0
  97. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/credentials.py +0 -0
  98. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/delegate.py +0 -0
  99. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/edit.py +0 -0
  100. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/edit_verify.py +0 -0
  101. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/edits.py +0 -0
  102. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/federate.py +0 -0
  103. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/filter.py +0 -0
  104. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/impact.py +0 -0
  105. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/jira.py +0 -0
  106. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/locks.py +0 -0
  107. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/memory.py +0 -0
  108. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/override.py +0 -0
  109. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/read.py +0 -0
  110. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/search.py +0 -0
  111. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/session.py +0 -0
  112. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/status.py +0 -0
  113. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/tasks.py +0 -0
  114. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/tools/validate.py +0 -0
  115. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/api.js +0 -0
  116. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/app.js +0 -0
  117. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/components/access.js +0 -0
  118. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/components/bitbucket.js +0 -0
  119. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/components/chat.js +0 -0
  120. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/components/credentials.js +0 -0
  121. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/components/dashboard.js +0 -0
  122. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/components/edits.js +0 -0
  123. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/components/enforcement.js +0 -0
  124. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/components/instructions.js +0 -0
  125. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/components/jira.js +0 -0
  126. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/components/memory.js +0 -0
  127. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/components/sessions.js +0 -0
  128. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/components/settings.js +0 -0
  129. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/components/sidebar.js +0 -0
  130. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/components/tasks.js +0 -0
  131. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/icons.js +0 -0
  132. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/pm_shared.js +0 -0
  133. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/shared.js +0 -0
  134. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui/theme.js +0 -0
  135. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui.html +0 -0
  136. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui_legacy.html +0 -0
  137. {code_context_control-2.112.0 → code_context_control-2.114.0}/cli/ui_nano.html +0 -0
  138. {code_context_control-2.112.0 → code_context_control-2.114.0}/code_context_control.egg-info/dependency_links.txt +0 -0
  139. {code_context_control-2.112.0 → code_context_control-2.114.0}/code_context_control.egg-info/entry_points.txt +0 -0
  140. {code_context_control-2.112.0 → code_context_control-2.114.0}/code_context_control.egg-info/requires.txt +0 -0
  141. {code_context_control-2.112.0 → code_context_control-2.114.0}/code_context_control.egg-info/top_level.txt +0 -0
  142. {code_context_control-2.112.0 → code_context_control-2.114.0}/core/__init__.py +0 -0
  143. {code_context_control-2.112.0 → code_context_control-2.114.0}/core/config.py +0 -0
  144. {code_context_control-2.112.0 → code_context_control-2.114.0}/core/ide.py +0 -0
  145. {code_context_control-2.112.0 → code_context_control-2.114.0}/core/mcp_toml.py +0 -0
  146. {code_context_control-2.112.0 → code_context_control-2.114.0}/core/web_security.py +0 -0
  147. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/__init__.py +0 -0
  148. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/config.py +0 -0
  149. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/mcp_oracle.py +0 -0
  150. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/oracle_server.py +0 -0
  151. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/oracle_ui.html +0 -0
  152. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/__init__.py +0 -0
  153. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/activity_reporter.py +0 -0
  154. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/api_auth.py +0 -0
  155. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/c3_bridge.py +0 -0
  156. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/chat_engine.py +0 -0
  157. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/chat_poll.py +0 -0
  158. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/chat_store.py +0 -0
  159. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/cross_memory.py +0 -0
  160. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/discovery_audit.py +0 -0
  161. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/federated_graph.py +0 -0
  162. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/health_checker.py +0 -0
  163. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/insight_engine.py +0 -0
  164. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/local_session.py +0 -0
  165. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/memory_reader.py +0 -0
  166. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/memory_writer.py +0 -0
  167. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/mobile_api.py +0 -0
  168. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/project_scanner.py +0 -0
  169. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/review_agent.py +0 -0
  170. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/tool_executor.py +0 -0
  171. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/services/tool_registry.py +0 -0
  172. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/activity.js +0 -0
  173. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/agents.js +0 -0
  174. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/app.js +0 -0
  175. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/busy.js +0 -0
  176. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/chat/conversations.js +0 -0
  177. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/chat/input.js +0 -0
  178. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/chat/markdown.js +0 -0
  179. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/chat/send.js +0 -0
  180. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/chat/stream_renderer.js +0 -0
  181. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/chat/toolbar.js +0 -0
  182. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/core.js +0 -0
  183. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/crossgraph.js +0 -0
  184. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/header.js +0 -0
  185. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/insights.js +0 -0
  186. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/projects.js +0 -0
  187. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/qrcode.js +0 -0
  188. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/settings.js +0 -0
  189. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/suggestions.js +0 -0
  190. {code_context_control-2.112.0 → code_context_control-2.114.0}/oracle/ui/theme_tabs.js +0 -0
  191. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/__init__.py +0 -0
  192. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/access_guard.py +0 -0
  193. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/access_telemetry.py +0 -0
  194. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/activity_log.py +0 -0
  195. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/agent_base.py +0 -0
  196. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/agent_locks.py +0 -0
  197. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/agents.py +0 -0
  198. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/artifact_defs.py +0 -0
  199. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/artifact_store.py +0 -0
  200. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/auto_memory.py +0 -0
  201. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/background_service.py +0 -0
  202. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/bench/__init__.py +0 -0
  203. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/bench/external/__init__.py +0 -0
  204. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/bench/external/aider_polyglot.py +0 -0
  205. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/bench/external/swe_bench.py +0 -0
  206. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/bench/search_eval.py +0 -0
  207. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/bench/shell_eval.py +0 -0
  208. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/benchmark_dashboard.py +0 -0
  209. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/bitbucket_client.py +0 -0
  210. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/bitbucket_credentials.py +0 -0
  211. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/ci_act.py +0 -0
  212. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/ci_cache.py +0 -0
  213. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/ci_expr.py +0 -0
  214. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/ci_failures.py +0 -0
  215. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/ci_github.py +0 -0
  216. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/ci_impact.py +0 -0
  217. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/ci_intel.py +0 -0
  218. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/ci_runner.py +0 -0
  219. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/ci_workflow.py +0 -0
  220. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/circuit_breaker.py +0 -0
  221. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/claude_md.py +0 -0
  222. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/compressor.py +0 -0
  223. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/context_snapshot.py +0 -0
  224. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/conversation_store.py +0 -0
  225. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/cred_audit.py +0 -0
  226. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/cred_telemetry.py +0 -0
  227. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/credential_store.py +0 -0
  228. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/doc_index.py +0 -0
  229. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/e2e_benchmark.py +0 -0
  230. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/e2e_evaluator.py +0 -0
  231. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/e2e_tasks.py +0 -0
  232. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/edit_ledger.py +0 -0
  233. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/embedding_index.py +0 -0
  234. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/enforcement_policy.py +0 -0
  235. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/error_reporting.py +0 -0
  236. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/file_memory.py +0 -0
  237. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/git_context.py +0 -0
  238. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/hub_service.py +0 -0
  239. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/index_store.py +0 -0
  240. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/indexer.py +0 -0
  241. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/jira_client.py +0 -0
  242. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/jira_cloud.py +0 -0
  243. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/jira_credentials.py +0 -0
  244. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/jira_data_center.py +0 -0
  245. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/jira_links.py +0 -0
  246. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/lexical_index.py +0 -0
  247. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/mask_activation.py +0 -0
  248. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/mask_mirror.py +0 -0
  249. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/mask_presets.py +0 -0
  250. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/memory.py +0 -0
  251. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/memory_consolidator.py +0 -0
  252. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/memory_distiller.py +0 -0
  253. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/memory_graph.py +0 -0
  254. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/memory_grounder.py +0 -0
  255. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/memory_queue.py +0 -0
  256. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/memory_scorer.py +0 -0
  257. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/metrics.py +0 -0
  258. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/notifications.py +0 -0
  259. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/ollama_bridge.py +0 -0
  260. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/ollama_client.py +0 -0
  261. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/ollama_credentials.py +0 -0
  262. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/oracle_service.py +0 -0
  263. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/output_filter.py +0 -0
  264. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/override_grants.py +0 -0
  265. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/override_policy.py +0 -0
  266. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/override_requests.py +0 -0
  267. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/override_wake.py +0 -0
  268. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/parser.py +0 -0
  269. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/project_manager.py +0 -0
  270. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/project_runtime.py +0 -0
  271. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/protocol.py +0 -0
  272. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/proxy_state.py +0 -0
  273. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/repo_map.py +0 -0
  274. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/repo_shape.py +0 -0
  275. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/reranker.py +0 -0
  276. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/retention.py +0 -0
  277. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/retrieval.py +0 -0
  278. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/retrieval_broker.py +0 -0
  279. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/router.py +0 -0
  280. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/runtime.py +0 -0
  281. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/scanner.py +0 -0
  282. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/session_benchmark.py +0 -0
  283. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/session_manager.py +0 -0
  284. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/session_preloader.py +0 -0
  285. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/subprojects.py +0 -0
  286. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/task_store.py +0 -0
  287. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/telemetry.py +0 -0
  288. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/text_index.py +0 -0
  289. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/time_tracker.py +0 -0
  290. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/tool_classifier.py +0 -0
  291. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/transcript_index.py +0 -0
  292. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/validation_cache.py +0 -0
  293. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/vector_store.py +0 -0
  294. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/watcher.py +0 -0
  295. {code_context_control-2.112.0 → code_context_control-2.114.0}/services/win_subprocess.py +0 -0
  296. {code_context_control-2.112.0 → code_context_control-2.114.0}/setup.cfg +0 -0
  297. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_access_builtin_optout.py +0 -0
  298. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_access_guard.py +0 -0
  299. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_access_guard_meta.py +0 -0
  300. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_access_guard_shell_project.py +0 -0
  301. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_access_guard_surfaces.py +0 -0
  302. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_access_guard_wiring.py +0 -0
  303. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_activity_reporter.py +0 -0
  304. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_agent_locks.py +0 -0
  305. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_aider_polyglot.py +0 -0
  306. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_antigravity_transition.py +0 -0
  307. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_artifact_store.py +0 -0
  308. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_artifact_tool.py +0 -0
  309. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_background_service.py +0 -0
  310. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_bitbucket_cli_smoke.py +0 -0
  311. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_bitbucket_client.py +0 -0
  312. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_bitbucket_config_fallback.py +0 -0
  313. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_bitbucket_credentials.py +0 -0
  314. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_bitbucket_tool.py +0 -0
  315. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_builtin_modes.py +0 -0
  316. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
  317. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_chat_poll.py +0 -0
  318. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_ci_act.py +0 -0
  319. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_ci_cache.py +0 -0
  320. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_ci_expr.py +0 -0
  321. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_ci_impact.py +0 -0
  322. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_ci_intel.py +0 -0
  323. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_ci_runner.py +0 -0
  324. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_ci_workflow.py +0 -0
  325. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_circuit_breaker.py +0 -0
  326. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_claude_md_merge.py +0 -0
  327. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_claude_md_updater.py +0 -0
  328. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_cli_smoke.py +0 -0
  329. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_compressor_large_file.py +0 -0
  330. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_confirm_guard.py +0 -0
  331. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_confirm_guard_wiring.py +0 -0
  332. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_cooccurrence_bounds.py +0 -0
  333. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_cred_audit.py +0 -0
  334. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_cred_telemetry.py +0 -0
  335. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_credential_login_kind.py +0 -0
  336. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_credential_store.py +0 -0
  337. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_credential_ui_parity.py +0 -0
  338. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_credentials_routes.py +0 -0
  339. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_credentials_tool.py +0 -0
  340. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_creds_cli_smoke.py +0 -0
  341. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_delegate_cascade.py +0 -0
  342. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_delegate_version_probe.py +0 -0
  343. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_e2e_benchmark.py +0 -0
  344. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_edit_ledger_deadline.py +0 -0
  345. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_edit_ledger_hook.py +0 -0
  346. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_edit_locking.py +0 -0
  347. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_edit_normalization.py +0 -0
  348. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_edit_verify.py +0 -0
  349. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_embedding_index_deadlock.py +0 -0
  350. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_enforcement_flip.py +0 -0
  351. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_enforcement_policy.py +0 -0
  352. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_enforcement_routes.py +0 -0
  353. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_env_parser.py +0 -0
  354. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_failed_calls_do_not_unlock.py +0 -0
  355. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_federated_graph.py +0 -0
  356. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_filter_backoff.py +0 -0
  357. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_ghost_files.py +0 -0
  358. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_ghost_generation.py +0 -0
  359. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_git_branch_awareness.py +0 -0
  360. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_hook_access_guard.py +0 -0
  361. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_hook_codex_compat.py +0 -0
  362. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_hook_dispatch.py +0 -0
  363. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_hook_pretool_enforce.py +0 -0
  364. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_hook_prompt_recall.py +0 -0
  365. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_hook_smoke.py +0 -0
  366. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_hook_state.py +0 -0
  367. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_hook_utf8_stdio.py +0 -0
  368. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_hub_credentials_route.py +0 -0
  369. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_hub_credentials_routes_write.py +0 -0
  370. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_hub_enforcement_routes.py +0 -0
  371. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_hub_inspect_api.py +0 -0
  372. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_hub_locks_routes.py +0 -0
  373. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_hub_oracle_service_routes.py +0 -0
  374. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_hub_override_routes.py +0 -0
  375. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_hub_server_smoke.py +0 -0
  376. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_hub_subproject_links.py +0 -0
  377. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_ide_workflow_adaptation.py +0 -0
  378. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_index_cap_not_hardcoded.py +0 -0
  379. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_init_clear_preserves_user_content.py +0 -0
  380. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_init_scan.py +0 -0
  381. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_install_mcp_entrypoint.py +0 -0
  382. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_jira_cli_smoke.py +0 -0
  383. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_jira_client.py +0 -0
  384. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_jira_config_fallback.py +0 -0
  385. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_jira_credentials.py +0 -0
  386. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_jira_links.py +0 -0
  387. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_jira_routes.py +0 -0
  388. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_jira_tool.py +0 -0
  389. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_lazy_store_init.py +0 -0
  390. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_mask_guard.py +0 -0
  391. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_mask_routes.py +0 -0
  392. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_mask_surfaces.py +0 -0
  393. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_mcp_host_guard.py +0 -0
  394. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_mcp_memory_timeout.py +0 -0
  395. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_mcp_server_smoke.py +0 -0
  396. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_mcp_toml.py +0 -0
  397. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_memory_distiller.py +0 -0
  398. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_memory_graph_api.py +0 -0
  399. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_memory_queue.py +0 -0
  400. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_memory_system.py +0 -0
  401. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_mobile_api.py +0 -0
  402. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_mobile_extras.py +0 -0
  403. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_mobile_override_routes.py +0 -0
  404. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_mobile_security_api.py +0 -0
  405. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_no_stale_model_pins.py +0 -0
  406. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_notification_dedup.py +0 -0
  407. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_notification_discipline.py +0 -0
  408. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_ollama_credentials.py +0 -0
  409. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_oracle_api_auth.py +0 -0
  410. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_oracle_apikey_api.py +0 -0
  411. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_oracle_c3_bridge.py +0 -0
  412. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_oracle_chat_engine.py +0 -0
  413. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_oracle_chat_store.py +0 -0
  414. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_oracle_discovery_api.py +0 -0
  415. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_oracle_discovery_audit.py +0 -0
  416. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_oracle_health_probe.py +0 -0
  417. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_oracle_local_auth.py +0 -0
  418. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_oracle_ollama_bridge.py +0 -0
  419. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_oracle_scanner_cache.py +0 -0
  420. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_oracle_security_fixes.py +0 -0
  421. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_oracle_session_bootstrap.py +0 -0
  422. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_oracle_subproject_awareness.py +0 -0
  423. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_oracle_ui_bundle.py +0 -0
  424. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_output_filter.py +0 -0
  425. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_override_grants.py +0 -0
  426. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_override_grants_mcp.py +0 -0
  427. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_override_requests.py +0 -0
  428. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_override_wake.py +0 -0
  429. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_permissions.py +0 -0
  430. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_pm_api.py +0 -0
  431. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_project_manager.py +0 -0
  432. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_project_manager_merge.py +0 -0
  433. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_project_tool.py +0 -0
  434. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_read_coercion.py +0 -0
  435. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_read_edit_parity.py +0 -0
  436. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_related_facts.py +0 -0
  437. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_repo_map.py +0 -0
  438. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_repo_shape.py +0 -0
  439. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_response_boilerplate.py +0 -0
  440. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_retention.py +0 -0
  441. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_review_digest.py +0 -0
  442. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_search_eval.py +0 -0
  443. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_search_p1.py +0 -0
  444. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_search_p2.py +0 -0
  445. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_search_p2b.py +0 -0
  446. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_search_p3.py +0 -0
  447. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_search_p4.py +0 -0
  448. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_search_p5.py +0 -0
  449. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_service_durability.py +0 -0
  450. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_session_benchmark.py +0 -0
  451. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_session_budget.py +0 -0
  452. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_shell_creds.py +0 -0
  453. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_shell_output.py +0 -0
  454. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_shell_robustness.py +0 -0
  455. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_shell_write_ledger.py +0 -0
  456. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_shell_writes.py +0 -0
  457. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_subproject_clear_scope.py +0 -0
  458. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_subproject_depth_consumers.py +0 -0
  459. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_subproject_exclusion.py +0 -0
  460. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_subproject_federation.py +0 -0
  461. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_subproject_linkage_api.py +0 -0
  462. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_subprojects.py +0 -0
  463. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_swe_bench.py +0 -0
  464. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_task_store.py +0 -0
  465. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_task_tool.py +0 -0
  466. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_time_tracker.py +0 -0
  467. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_token_telemetry.py +0 -0
  468. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_token_tracking.py +0 -0
  469. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_tool_registry.py +0 -0
  470. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_ui_jsx_syntax.py +0 -0
  471. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_upgrade_and_version.py +0 -0
  472. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_validate.py +0 -0
  473. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_vault_write_guard.py +0 -0
  474. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_version_sync.py +0 -0
  475. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_web_security.py +0 -0
  476. {code_context_control-2.112.0 → code_context_control-2.114.0}/tests/test_windows_reliability.py +0 -0
  477. {code_context_control-2.112.0 → code_context_control-2.114.0}/tui/__init__.py +0 -0
  478. {code_context_control-2.112.0 → code_context_control-2.114.0}/tui/backend.py +0 -0
  479. {code_context_control-2.112.0 → code_context_control-2.114.0}/tui/main.py +0 -0
  480. {code_context_control-2.112.0 → code_context_control-2.114.0}/tui/screens/__init__.py +0 -0
  481. {code_context_control-2.112.0 → code_context_control-2.114.0}/tui/screens/benchmark_view.py +0 -0
  482. {code_context_control-2.112.0 → code_context_control-2.114.0}/tui/screens/claudemd_view.py +0 -0
  483. {code_context_control-2.112.0 → code_context_control-2.114.0}/tui/screens/compress_view.py +0 -0
  484. {code_context_control-2.112.0 → code_context_control-2.114.0}/tui/screens/index_view.py +0 -0
  485. {code_context_control-2.112.0 → code_context_control-2.114.0}/tui/screens/init_view.py +0 -0
  486. {code_context_control-2.112.0 → code_context_control-2.114.0}/tui/screens/mcp_view.py +0 -0
  487. {code_context_control-2.112.0 → code_context_control-2.114.0}/tui/screens/optimize_view.py +0 -0
  488. {code_context_control-2.112.0 → code_context_control-2.114.0}/tui/screens/pipe_view.py +0 -0
  489. {code_context_control-2.112.0 → code_context_control-2.114.0}/tui/screens/projects_view.py +0 -0
  490. {code_context_control-2.112.0 → code_context_control-2.114.0}/tui/screens/search_view.py +0 -0
  491. {code_context_control-2.112.0 → code_context_control-2.114.0}/tui/screens/session_view.py +0 -0
  492. {code_context_control-2.112.0 → code_context_control-2.114.0}/tui/screens/stats.py +0 -0
  493. {code_context_control-2.112.0 → code_context_control-2.114.0}/tui/screens/ui_view.py +0 -0
  494. {code_context_control-2.112.0 → code_context_control-2.114.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.112.0
3
+ Version: 2.114.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
@@ -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.112.0"
95
+ __version__ = "2.114.0"
96
96
 
97
97
 
98
98
  def _compress_file_cli(compressor, path, mode="smart", **kw):
@@ -261,7 +261,7 @@ _C3_MCP_ALLOW = [
261
261
  "mcp__c3__c3_bitbucket",
262
262
  "mcp__c3__c3_jira", "mcp__c3__c3_credentials",
263
263
  "mcp__c3__c3_project", "mcp__c3__c3_task", "mcp__c3__c3_artifacts",
264
- "mcp__c3__c3_override", "mcp__c3__c3_ci",
264
+ "mcp__c3__c3_override", "mcp__c3__c3_ci", "mcp__c3__c3_shell_job",
265
265
  ]
266
266
 
267
267
  # Obsolete MCP tool names from earlier C3 versions. `c3 permissions clean`
@@ -5639,6 +5639,7 @@ def cmd_install_mcp(args):
5639
5639
  "mcp__c3__c3_delegate",
5640
5640
  "mcp__c3__c3_session",
5641
5641
  "mcp__c3__c3_agent",
5642
+ "mcp__c3__c3_shell_job",
5642
5643
  edit_matcher,
5643
5644
  write_matcher,
5644
5645
  *extra_edit_matchers,
@@ -97,7 +97,7 @@ _SIGNAL_TOOLS = {
97
97
  "mcp__c3__c3_compress", "mcp__c3__c3_filter", "mcp__c3__c3_memory",
98
98
  "mcp__c3__c3_validate", "mcp__c3__c3_edit", "mcp__c3__c3_edits",
99
99
  "mcp__c3__c3_impact", "mcp__c3__c3_status", "mcp__c3__c3_delegate",
100
- "mcp__c3__c3_session", "mcp__c3__c3_agent",
100
+ "mcp__c3__c3_session", "mcp__c3__c3_agent", "mcp__c3__c3_shell_job",
101
101
  }
102
102
 
103
103
  # hook_edit_unlock was registered only for c3_compress and c3_agent
@@ -899,8 +899,16 @@ async def c3_shell(cmd: str = "", cwd: str = "", timeout: int = 60,
899
899
  (pattern=regex), 'tail' (lines='80') or 'delete', stream='stdout'|'stderr'; an id
900
900
  resolves only for this project and this session under the current access rules.
901
901
  The echoed command is its first line; a multi-line command shows (N lines, M chars,
902
- sha256). Auto-filters stdout >30 lines when it fits; auto-logs git mutations to
903
- the edit ledger.
902
+ sha256). Under budget the output is complete: ANSI/control sequences stripped, each
903
+ line's \\r progress rewrites reduced to their final state, runs of 3+ identical
904
+ consecutive lines folded to one plus ` [x N]` (the header says `[collapsed …]` and the
905
+ raw streams are kept by id). Over budget, pytest/unittest/cargo/tsc/jest/vitest
906
+ failure blocks, error lines and totals are kept first (each announced by `[La-b: why]`),
907
+ then a bounded head/tail; a recognised runner past 30 lines gets a `--- summary ---`
908
+ (totals + one line per failing test). filter_output=False skips the two collapses so
909
+ every line comes through as written — escapes are still stripped, summaries and
910
+ priority regions still apply, and the cap is never lifted. Auto-logs git mutations
911
+ to the edit ledger.
904
912
  Credentials: env_creds='NAME1,NAME2' injects vault entries as env vars, and
905
913
  {{cred:NAME}} inside cmd expands server-side — decoded values never enter
906
914
  model context (see c3_credentials; echoed values are auto-redacted, in the
@@ -909,7 +917,10 @@ async def c3_shell(cmd: str = "", cwd: str = "", timeout: int = 60,
909
917
  $HOME/~; fork bombs; whole-drive wipes) — a guard, NOT a sandbox. Soft-warns on
910
918
  --force, --no-verify, reset --hard.
911
919
  Git Bash may not include optional tools such as jq; use `python -m json.tool`
912
- for portable JSON formatting. Native Bash remains the fallback for interactive/TTY commands."""
920
+ for portable JSON formatting. Native Bash remains the fallback for interactive/TTY commands.
921
+ Work longer than this client's tool-call ceiling (full test suites, builds, device
922
+ commands) belongs in c3_shell_job, which runs it in a detached supervisor for up to 6 h
923
+ and keeps its output in the same store — a timeout here is never converted into a job."""
913
924
  svc = _svc(ctx)
914
925
 
915
926
  def finalize(name, args, resp, summ, **kw):
@@ -922,6 +933,42 @@ async def c3_shell(cmd: str = "", cwd: str = "", timeout: int = 60,
922
933
  max_bytes=max_bytes or None)
923
934
 
924
935
 
936
+ @mcp.tool()
937
+ async def c3_shell_job(action: str, cmd: str = "", cwd: str = "", timeout: int = 1800,
938
+ env_creds: str = "", job_id: str = "", stream: str = "stdout",
939
+ lines: str = "", max_bytes: int = 0,
940
+ ctx: Context = None) -> str:
941
+ """BACKGROUND shell job — start | status | tail | cancel | list. For work that outlives a
942
+ tool call: full test suites, long builds, device/emulator commands, anything over the
943
+ client's ~2 min ceiling on c3_shell. Prefer c3_ci for a repository's own workflows.
944
+ start: cmd (+cwd, env_creds, timeout in seconds — default 1800, ceiling 21600 = 6 h)
945
+ runs c3_shell's full pre-flight (blocklist, access-guard cwd deny, advisory read scan,
946
+ write scan with confirm holds, credential expansion) and then hands the command to a
947
+ DETACHED supervisor process that survives this server; replies with a job_id='j-…'
948
+ at once. Nothing here waits on the job, and a c3_shell timeout is never turned into one.
949
+ status: one line — queued|running|done|failed|timeout|cancelled|lost, exit code,
950
+ duration, and the output_id once finished. tail: the last `lines` (default 50) of
951
+ stream='stdout'|'stderr' — the GROWING output while running, the kept output after —
952
+ under the same byte budget as c3_shell (max_bytes may only lower it). cancel: kills the
953
+ child process tree ONLY if the recorded pid still has the creation time recorded at
954
+ spawn (a reused pid is never signalled) and records 'cancelled'. list: this project +
955
+ session's jobs.
956
+ Output lands in the same spill store as c3_shell, ALWAYS kept for 3 days: page it with
957
+ c3_shell(output_id='o-…', output_action='read'|'search'|'tail'). Jobs and their output
958
+ are per project AND per session, resolved under the current access rules; another
959
+ project or session sees 'not found'. Credentials are redacted in the kept output and
960
+ never touch the command line, the environment of the supervisor, or disk."""
961
+ svc = _svc(ctx)
962
+
963
+ def finalize(name, args, resp, summ, **kw):
964
+ return _finalize_response(ctx, name, args, resp, summ, **kw)
965
+
966
+ from cli.tools.shell_job import handle_shell_job
967
+ return await asyncio.to_thread(handle_shell_job, action, cmd, cwd, timeout, env_creds,
968
+ job_id, stream, lines or None, max_bytes or None,
969
+ svc, finalize)
970
+
971
+
925
972
  @mcp.tool()
926
973
  async def c3_bitbucket(
927
974
  action: str,
@@ -467,6 +467,17 @@ def handle_project(action, svc, finalize, *, project="", query="", file_path="",
467
467
  from_project=str(getattr(svc, "project_path", ""))),
468
468
  action)
469
469
 
470
+ if action in ("shell_job", "job", "jobs"):
471
+ # S3: a background job is bound to the project AND session that
472
+ # started it (services/shell_jobs.py); proxying one would either run
473
+ # it under the caller's identity or hand another project's session a
474
+ # handle it must not have. Not offered cross-project.
475
+ return done(
476
+ "[c3_project:error] c3_shell_job is not proxied across projects — "
477
+ "start, poll and cancel background jobs from the target project's "
478
+ "own session.",
479
+ "error")
480
+
470
481
  if action not in _READ_OPS and action not in _WRITE_OPS:
471
482
  return done(
472
483
  f"[c3_project:error] Unknown action '{action}'. "
@@ -2,8 +2,10 @@
2
2
 
3
3
  Wraps subprocess.Popen with the Windows-safe pattern from
4
4
  services/edit_ledger.py::_git_combined (Popen + taskkill /F /T + stdin=DEVNULL).
5
- Auto-filters long stdout via handle_filter, auto-logs git mutations
6
- to the edit ledger, and accounts stdout tokens against session budget.
5
+ Budgets and shapes the response (cli/tools/shell_render.py + shell_parsers.py:
6
+ normalised streams, runner-aware priority regions, omission only over budget),
7
+ auto-logs git mutations to the edit ledger, and accounts stdout tokens against
8
+ session budget.
7
9
 
8
10
  Shell selection: on Windows, commands are run through Git Bash (bash.exe) when
9
11
  it is available, so c3_shell speaks the same POSIX dialect as the native Bash
@@ -28,7 +30,13 @@ from pathlib import Path
28
30
  from cli._shell_writes import shell_write_targets
29
31
  from cli.tools import _grants
30
32
  from cli.tools._helpers import finalize_with_tokens
31
- from cli.tools.filter import handle_filter
33
+ from cli.tools.shell_parsers import (
34
+ SUMMARY_MIN_LINES,
35
+ detect_runner,
36
+ normalize_stream,
37
+ priority_regions,
38
+ structured_tail,
39
+ )
32
40
  from cli.tools.shell_render import (
33
41
  allocate,
34
42
  cmd_display,
@@ -36,6 +44,8 @@ from cli.tools.shell_render import (
36
44
  grep_pattern,
37
45
  human_bytes,
38
46
  shape_stream,
47
+ split_lines,
48
+ split_preview,
39
49
  )
40
50
  from core import count_tokens
41
51
  from services import access_guard
@@ -477,6 +487,39 @@ def _stream_facts(result: dict, stream: str) -> dict:
477
487
  "longest": _longest_line(text)}
478
488
 
479
489
 
490
+ _ZERO_NORM = {"ansi_stripped": 0, "cr_collapsed": 0, "dup_collapsed": 0}
491
+
492
+
493
+ def _normalised(facts: dict, *, collapse: bool, fuzzy: bool) -> dict:
494
+ """One stream after ``normalize_stream``: the text (or previews), its
495
+ logical lines in the index space ``shape_stream`` uses, the raw line
496
+ numbers of those lines when folding shifted them, and the counters."""
497
+ info = dict(_ZERO_NORM)
498
+ if facts["text"] is not None:
499
+ text, ni = normalize_stream(facts["text"], collapse=collapse, fuzzy_dups=fuzzy)
500
+ for k in _ZERO_NORM:
501
+ info[k] = ni[k]
502
+ return {"text": text, "head": "", "tail": "", "lines": split_lines(text),
503
+ "bytes": len(text.encode("utf-8", errors="replace")),
504
+ "total_lines": facts["lines"], "numbers": ni["line_numbers"],
505
+ "tail_numbers": None, "info": info}
506
+ head, hi = normalize_stream(facts["head"], collapse=collapse, fuzzy_dups=fuzzy)
507
+ tail, ti = normalize_stream(facts["tail"], collapse=collapse, fuzzy_dups=fuzzy)
508
+ for k in _ZERO_NORM:
509
+ info[k] = hi[k] + ti[k]
510
+ h_lines, t_lines, _torn = split_preview(head, tail)
511
+ return {"text": None, "head": head, "tail": tail, "lines": h_lines + t_lines,
512
+ "bytes": facts["bytes"], "total_lines": facts["lines"],
513
+ "numbers": hi["line_numbers"], "tail_numbers": ti["line_numbers"], "info": info}
514
+
515
+
516
+ def _region_line_count(regions) -> int:
517
+ seen: set[int] = set()
518
+ for a, b, _why in regions:
519
+ seen.update(range(a, b + 1))
520
+ return len(seen)
521
+
522
+
480
523
  def render_shell_response(cmd: str, result: dict, svc, *,
481
524
  filter_output: bool = True, warn: str = "",
482
525
  capped_note: str = "", touched_files=(),
@@ -494,21 +537,46 @@ def render_shell_response(cmd: str, result: dict, svc, *,
494
537
  Budget (2.112.0, cli/tools/shell_render.py): the rendered body never
495
538
  exceeds ``effective_budget()`` bytes — 18 KiB by default, 22 KiB ceiling,
496
539
  ``max_bytes`` and ``hybrid.shell_budget_bytes`` may only lower it,
497
- ``filter_output=False`` never lifts it. A stream that fits its share
498
- passes through untouched (and, when it has more than
499
- _FILTER_THRESHOLD_LINES newlines and is not a git diagnostic, through the
500
- same auto-filter as before); a stream that does not is clipped line by
501
- line and windowed head/tail with an omission note naming the output id.
502
- Whenever anything was dropped — clipped, windowed or filtered — the raw
503
- streams are kept in the spill store and ``stats["needs_spill"]`` tells
504
- handle_shell to promote them.
540
+ ``filter_output=False`` never lifts it.
541
+
542
+ Shaping (2.113.0, S2, cli/tools/shell_parsers.py) the Cod rule: strip
543
+ ANSI and collapse ``\\r`` rewrites always, otherwise preserve complete
544
+ under-budget output, run the parsers always but omit only over budget:
545
+
546
+ 1. Both streams are normalised: ``\\r\\n`` ``\\n``, ANSI escape and
547
+ control sequences stripped (not a loss), each line's ``\\r``
548
+ progress rewrites collapsed to the final state, runs of three or
549
+ more identical consecutive lines folded to the first plus
550
+ `` [x N]``. The last two are a loss: the header says
551
+ ``[collapsed …]``, ``stats["filtered"]`` is set and the raw streams
552
+ are spilled. ``filter_output=False`` skips the two collapses (ANSI
553
+ is always stripped) and, as before, never lifts the byte cap.
554
+ 2. The runner is detected (pytest, unittest, cargo/rustc, tsc, jest,
555
+ vitest) and its priority regions computed on every call; a stream
556
+ that fits its allocation passes through whole regardless. A stream
557
+ that does not is re-normalised with the duplicate test widened to
558
+ lines differing only in digits / hex / timestamps, then shaped:
559
+ priority regions first (each announced by ``[La-b: why]`` when not
560
+ contiguous), head/tail with the rest, one omission note naming the
561
+ output id. Unrecognised output uses generic error anchors, capped at
562
+ 60% of the allocation so head and tail always keep something.
563
+ 3. For a recognised runner with more than SUMMARY_MIN_LINES lines a
564
+ ``--- summary ---`` section (totals + one line per failing test,
565
+ cap 20) is appended and counted inside the budget.
566
+
567
+ The legacy ``>30 newlines → handle_filter`` path is gone from this
568
+ function (``c3_filter`` the tool is untouched). Whenever anything was
569
+ dropped — collapsed, clipped or windowed — ``stats["needs_spill"]``
570
+ tells handle_shell to keep the raw streams.
505
571
 
506
572
  ``stats`` is what telemetry records about the call (see
507
573
  SessionManager.record_tool_tokens ``detail``): stdout_bytes and
508
- stderr_bytes are measured BEFORE filtering; longest_line is the tell for
509
- the single-line monsters (minified bundles, JSONL) that a newline-count
510
- trigger never sees; filtered/spilled/output_id describe what this
511
- renderer did.
574
+ stderr_bytes are measured on the RAW streams; longest_line is the tell
575
+ for the single-line monsters (minified bundles, JSONL) that a
576
+ newline-count trigger never sees; filtered (a lossy collapse happened),
577
+ spilled, output_id, runner, ansi_stripped, cr_collapsed, dup_collapsed
578
+ and priority_lines (lines the parsers marked, both streams) describe
579
+ what this renderer did.
512
580
  """
513
581
  out = _stream_facts(result, "stdout")
514
582
  err = _stream_facts(result, "stderr")
@@ -524,6 +592,11 @@ def render_shell_response(cmd: str, result: dict, svc, *,
524
592
  "output_id": None,
525
593
  "cmd_class": _cmd_class(cmd),
526
594
  "needs_spill": False,
595
+ "runner": None,
596
+ "ansi_stripped": 0,
597
+ "cr_collapsed": 0,
598
+ "dup_collapsed": 0,
599
+ "priority_lines": 0,
527
600
  }
528
601
 
529
602
  config_default = None
@@ -532,45 +605,56 @@ def render_shell_response(cmd: str, result: dict, svc, *,
532
605
  except Exception:
533
606
  config_default = None
534
607
  budget = effective_budget(max_bytes, config_default=config_default)
535
- out_alloc, err_alloc = allocate(budget, out["bytes"], err["bytes"])
536
608
  stats["budget_bytes"] = budget
537
609
  output_id = getattr(capture, "output_id", None) if capture is not None else None
538
610
  focus = grep_pattern(cmd)
539
-
540
- # Legacy auto-filter: only on stdout, only when the whole text is at hand
541
- # (a stream over TEXT_MAX_BYTES has previews only and goes straight to
542
- # deterministic shaping), more than _FILTER_THRESHOLD_LINES newlines,
543
- # never a git diagnostic — exactly the trigger 2.111.0 had, so the token
544
- # profile of a filtered test or build run does not move in S1; what
545
- # moves is that the dropped text is now recoverable. S2 replaces this.
546
- stdout_text = out["text"]
547
- filtered_note = ""
548
- if (filter_output and stdout_text is not None
549
- and stdout_text.count("\n") > _FILTER_THRESHOLD_LINES
550
- and not _GIT_DIAGNOSTIC.search(cmd)):
551
- try:
552
- stdout_text = handle_filter(
553
- "", stdout_text, "", 50, "smart", True,
554
- svc, lambda *a, **kw: a[2],
555
- )
556
- filtered_note = " [stdout filtered]"
557
- stats["filtered"] = True
558
- except Exception:
559
- stdout_text = out["text"]
611
+ collapse = bool(filter_output)
612
+
613
+ # 1. Normalise. A stream with previews only (over TEXT_MAX_BYTES) is over
614
+ # budget by definition, so it gets the widened duplicate test at once.
615
+ norm_out = _normalised(out, collapse=collapse, fuzzy=out["text"] is None)
616
+ norm_err = _normalised(err, collapse=collapse, fuzzy=err["text"] is None)
617
+
618
+ # 2. Runner, summary, allocation. The summary is measured first so the
619
+ # streams are allocated what is left of the budget.
620
+ runner = detect_runner(cmd, norm_out["text"] or norm_out["head"] + norm_out["tail"],
621
+ norm_err["text"] or norm_err["head"] + norm_err["tail"])
622
+ stats["runner"] = runner
623
+ summary = ""
624
+ if runner and (out["lines"] + err["lines"]) > SUMMARY_MIN_LINES:
625
+ summary = structured_tail(runner, norm_out["lines"] + norm_err["lines"], result.get("exit_code"))
626
+ summary_bytes = len(summary.encode("utf-8", errors="replace"))
627
+ out_alloc, err_alloc = allocate(budget - summary_bytes, norm_out["bytes"], norm_err["bytes"])
628
+
629
+ # 3. A stream that does not fit is re-normalised with fuzzy duplicates,
630
+ # then shaped around its priority regions.
631
+ if collapse and norm_out["text"] is not None and norm_out["bytes"] > out_alloc:
632
+ norm_out = _normalised(out, collapse=True, fuzzy=True)
633
+ if collapse and norm_err["text"] is not None and norm_err["bytes"] > err_alloc:
634
+ norm_err = _normalised(err, collapse=True, fuzzy=True)
635
+ for key in ("ansi_stripped", "cr_collapsed", "dup_collapsed"):
636
+ stats[key] = norm_out["info"][key] + norm_err["info"][key]
637
+ stats["filtered"] = bool(stats["cr_collapsed"] or stats["dup_collapsed"])
638
+
639
+ prio_out = priority_regions(runner, norm_out["lines"]) if norm_out["lines"] else []
640
+ prio_err = priority_regions(runner, norm_err["lines"]) if norm_err["lines"] else []
641
+ stats["priority_lines"] = _region_line_count(prio_out) + _region_line_count(prio_err)
642
+ share = 1.0 if runner else 0.6
560
643
 
561
644
  shaped_out, info_out = shape_stream(
562
- full_text=stdout_text, head=out["head"], tail=out["tail"],
563
- total_bytes=out["bytes"], total_lines=out["lines"], alloc=out_alloc,
564
- output_id=output_id, focus=focus,
565
- number_lines=not stats["filtered"]) # filtered text no longer maps to raw line numbers
645
+ full_text=norm_out["text"], head=norm_out["head"], tail=norm_out["tail"],
646
+ total_bytes=norm_out["bytes"], total_lines=norm_out["total_lines"], alloc=out_alloc,
647
+ output_id=output_id, focus=focus, priority=prio_out, priority_share=share,
648
+ line_numbers=norm_out["numbers"], tail_line_numbers=norm_out["tail_numbers"])
566
649
  if err["bytes"] > 0 or (err["text"] or "").strip():
567
650
  shaped_err, info_err = shape_stream(
568
- full_text=err["text"], head=err["head"], tail=err["tail"],
569
- total_bytes=err["bytes"], total_lines=err["lines"], alloc=err_alloc,
570
- output_id=output_id, focus=focus)
651
+ full_text=norm_err["text"], head=norm_err["head"], tail=norm_err["tail"],
652
+ total_bytes=norm_err["bytes"], total_lines=norm_err["total_lines"], alloc=err_alloc,
653
+ output_id=output_id, focus=focus, priority=prio_err, priority_share=share,
654
+ line_numbers=norm_err["numbers"], tail_line_numbers=norm_err["tail_numbers"])
571
655
  else:
572
656
  shaped_err, info_err = "", {"cut": False, "omitted_lines": 0, "omitted_bytes": 0,
573
- "clipped_lines": 0, "rendered_bytes": 0}
657
+ "clipped_lines": 0, "rendered_bytes": 0, "priority_kept": 0}
574
658
 
575
659
  cut = bool(info_out["cut"] or info_err["cut"])
576
660
  stats["needs_spill"] = bool(stats["filtered"] or cut)
@@ -586,6 +670,14 @@ def render_shell_response(cmd: str, result: dict, svc, *,
586
670
  else:
587
671
  status = f"FAIL({result.get('exit_code')})"
588
672
 
673
+ collapsed_note = ""
674
+ if stats["filtered"]:
675
+ parts = []
676
+ if stats["cr_collapsed"]:
677
+ parts.append(f"{stats['cr_collapsed']} cr rewrites")
678
+ if stats["dup_collapsed"]:
679
+ parts.append(f"{stats['dup_collapsed']} dup lines")
680
+ collapsed_note = f" [collapsed {', '.join(parts)}]"
589
681
  size_note = ""
590
682
  if cut or stats["spilled"]:
591
683
  size_note = (f" (stdout {human_bytes(out['bytes'])}/{out['lines']} lines,"
@@ -594,12 +686,14 @@ def render_shell_response(cmd: str, result: dict, svc, *,
594
686
 
595
687
  body = (
596
688
  f"{warn}{capped_note}"
597
- f"[c3_shell:{status}] {result.get('duration_ms', 0)}ms{filtered_note}{size_note}\n"
689
+ f"[c3_shell:{status}] {result.get('duration_ms', 0)}ms{collapsed_note}{size_note}\n"
598
690
  f"$ {cmd_display(cmd)}\n"
599
691
  f"--- stdout ---\n{shaped_out.rstrip()}\n"
600
692
  )
601
693
  if shaped_err.strip():
602
694
  body += f"--- stderr ---\n{shaped_err.rstrip()}\n"
695
+ if summary:
696
+ body += summary
603
697
  dependency_hint = _dependency_hint(cmd, result)
604
698
  if dependency_hint:
605
699
  body += f"--- hint ---\n{dependency_hint}\n"
@@ -1140,8 +1234,9 @@ async def handle_shell(cmd: str, cwd: str, timeout: int, filter_output: bool,
1140
1234
  capped_note = (
1141
1235
  f"[c3_shell:capped] timeout={capped_from}s was requested but this "
1142
1236
  f"MCP client kills a tool call at {_ceiling}s; ran with {timeout}s. "
1143
- f"For longer work use the native Bash tool with "
1144
- f"run_in_background, which is not bound by this limit.\n"
1237
+ f"For longer work use c3_shell_job(action='start', cmd=..., timeout=...), "
1238
+ f"which runs detached (up to 6 h), keeps the ledger and telemetry, and "
1239
+ f"pages its output back by id.\n"
1145
1240
  )
1146
1241
 
1147
1242
  try: