code-context-control 2.28.0__py3-none-any.whl

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 (150) hide show
  1. cli/__init__.py +1 -0
  2. cli/_hook_utils.py +99 -0
  3. cli/c3.py +6152 -0
  4. cli/commands/__init__.py +1 -0
  5. cli/commands/common.py +312 -0
  6. cli/commands/parser.py +286 -0
  7. cli/docs.html +3178 -0
  8. cli/edits.html +878 -0
  9. cli/hook_auto_snapshot.py +142 -0
  10. cli/hook_c3_signal.py +61 -0
  11. cli/hook_c3read.py +116 -0
  12. cli/hook_edit_ledger.py +213 -0
  13. cli/hook_edit_unlock.py +170 -0
  14. cli/hook_filter.py +130 -0
  15. cli/hook_ghost_files.py +238 -0
  16. cli/hook_pretool_enforce.py +334 -0
  17. cli/hook_read.py +200 -0
  18. cli/hook_session_stats.py +62 -0
  19. cli/hook_terse_advisor.py +190 -0
  20. cli/hub.html +3764 -0
  21. cli/hub_server.py +1619 -0
  22. cli/mcp_proxy.py +428 -0
  23. cli/mcp_server.py +660 -0
  24. cli/server.py +2985 -0
  25. cli/tools/__init__.py +4 -0
  26. cli/tools/_helpers.py +65 -0
  27. cli/tools/agent.py +1165 -0
  28. cli/tools/compress.py +215 -0
  29. cli/tools/delegate.py +1184 -0
  30. cli/tools/edit.py +313 -0
  31. cli/tools/edits.py +118 -0
  32. cli/tools/filter.py +285 -0
  33. cli/tools/impact.py +163 -0
  34. cli/tools/memory.py +469 -0
  35. cli/tools/read.py +224 -0
  36. cli/tools/search.py +337 -0
  37. cli/tools/session.py +95 -0
  38. cli/tools/shell.py +193 -0
  39. cli/tools/status.py +306 -0
  40. cli/tools/validate.py +310 -0
  41. cli/ui/api.js +36 -0
  42. cli/ui/app.js +207 -0
  43. cli/ui/components/chat.js +758 -0
  44. cli/ui/components/dashboard.js +689 -0
  45. cli/ui/components/edits.js +220 -0
  46. cli/ui/components/instructions.js +481 -0
  47. cli/ui/components/memory.js +626 -0
  48. cli/ui/components/sessions.js +606 -0
  49. cli/ui/components/settings.js +1404 -0
  50. cli/ui/components/sidebar.js +156 -0
  51. cli/ui/icons.js +51 -0
  52. cli/ui/shared.js +119 -0
  53. cli/ui/theme.js +22 -0
  54. cli/ui.html +168 -0
  55. cli/ui_legacy.html +6797 -0
  56. cli/ui_nano.html +503 -0
  57. code_context_control-2.28.0.dist-info/METADATA +248 -0
  58. code_context_control-2.28.0.dist-info/RECORD +150 -0
  59. code_context_control-2.28.0.dist-info/WHEEL +5 -0
  60. code_context_control-2.28.0.dist-info/entry_points.txt +4 -0
  61. code_context_control-2.28.0.dist-info/licenses/LICENSE +201 -0
  62. code_context_control-2.28.0.dist-info/top_level.txt +5 -0
  63. core/__init__.py +75 -0
  64. core/config.py +269 -0
  65. core/ide.py +188 -0
  66. oracle/__init__.py +1 -0
  67. oracle/config.py +75 -0
  68. oracle/oracle.html +3900 -0
  69. oracle/oracle_server.py +663 -0
  70. oracle/services/__init__.py +1 -0
  71. oracle/services/c3_bridge.py +210 -0
  72. oracle/services/chat_engine.py +1103 -0
  73. oracle/services/chat_store.py +155 -0
  74. oracle/services/cross_memory.py +154 -0
  75. oracle/services/federated_graph.py +463 -0
  76. oracle/services/health_checker.py +117 -0
  77. oracle/services/insight_engine.py +307 -0
  78. oracle/services/memory_reader.py +106 -0
  79. oracle/services/memory_writer.py +182 -0
  80. oracle/services/ollama_bridge.py +332 -0
  81. oracle/services/project_scanner.py +87 -0
  82. oracle/services/review_agent.py +206 -0
  83. services/__init__.py +1 -0
  84. services/activity_log.py +93 -0
  85. services/agent_base.py +124 -0
  86. services/agents.py +1529 -0
  87. services/auto_memory.py +407 -0
  88. services/bench/__init__.py +6 -0
  89. services/bench/external/__init__.py +29 -0
  90. services/bench/external/aider_polyglot.py +405 -0
  91. services/bench/external/swe_bench.py +485 -0
  92. services/benchmark_dashboard.py +596 -0
  93. services/claude_md.py +785 -0
  94. services/compressor.py +592 -0
  95. services/context_snapshot.py +356 -0
  96. services/conversation_store.py +870 -0
  97. services/doc_index.py +537 -0
  98. services/e2e_benchmark.py +2884 -0
  99. services/e2e_evaluator.py +396 -0
  100. services/e2e_tasks.py +743 -0
  101. services/edit_ledger.py +459 -0
  102. services/embedding_index.py +341 -0
  103. services/error_reporting.py +123 -0
  104. services/file_memory.py +734 -0
  105. services/hub_service.py +585 -0
  106. services/indexer.py +712 -0
  107. services/memory.py +318 -0
  108. services/memory_consolidator.py +538 -0
  109. services/memory_graph.py +382 -0
  110. services/memory_grounder.py +304 -0
  111. services/memory_scorer.py +246 -0
  112. services/metrics.py +86 -0
  113. services/notifications.py +209 -0
  114. services/ollama_client.py +201 -0
  115. services/output_filter.py +488 -0
  116. services/parser.py +1238 -0
  117. services/project_manager.py +579 -0
  118. services/protocol.py +306 -0
  119. services/proxy_state.py +152 -0
  120. services/retrieval_broker.py +129 -0
  121. services/router.py +414 -0
  122. services/runtime.py +326 -0
  123. services/session_benchmark.py +1945 -0
  124. services/session_manager.py +1026 -0
  125. services/session_preloader.py +251 -0
  126. services/text_index.py +90 -0
  127. services/tool_classifier.py +176 -0
  128. services/transcript_index.py +340 -0
  129. services/validation_cache.py +155 -0
  130. services/vector_store.py +299 -0
  131. services/version_tracker.py +271 -0
  132. services/watcher.py +192 -0
  133. tui/__init__.py +0 -0
  134. tui/backend.py +59 -0
  135. tui/main.py +145 -0
  136. tui/screens/__init__.py +1 -0
  137. tui/screens/benchmark_view.py +109 -0
  138. tui/screens/claudemd_view.py +46 -0
  139. tui/screens/compress_view.py +52 -0
  140. tui/screens/index_view.py +74 -0
  141. tui/screens/init_view.py +82 -0
  142. tui/screens/mcp_view.py +73 -0
  143. tui/screens/optimize_view.py +41 -0
  144. tui/screens/pipe_view.py +46 -0
  145. tui/screens/projects_view.py +355 -0
  146. tui/screens/search_view.py +55 -0
  147. tui/screens/session_view.py +143 -0
  148. tui/screens/stats.py +158 -0
  149. tui/screens/ui_view.py +54 -0
  150. tui/theme.tcss +335 -0
services/runtime.py ADDED
@@ -0,0 +1,326 @@
1
+ """Shared C3 runtime/bootstrap helpers for UI and MCP entrypoints."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import re as _re
7
+ import time as _time
8
+ from dataclasses import dataclass, field
9
+ from pathlib import Path
10
+ from typing import Optional
11
+
12
+ from core.config import load_delegate_config, load_hybrid_config
13
+ from core.ide import get_profile, load_ide_config
14
+ from services.activity_log import ActivityLog
15
+ from services.agents import create_agents
16
+ from services.claude_md import ClaudeMdManager
17
+ from services.compressor import CodeCompressor
18
+ from services.context_snapshot import ContextSnapshot
19
+ from services.conversation_store import ConversationStore
20
+ from services.doc_index import DocIndex
21
+ from services.edit_ledger import EditLedger
22
+ from services.embedding_index import EmbeddingIndex
23
+ from services.file_memory import FileMemoryStore
24
+ from services.indexer import CodeIndex
25
+ from services.memory import MemoryStore
26
+ from services.memory_consolidator import MemoryConsolidator
27
+ from services.memory_graph import MemoryGraph
28
+ from services.memory_grounder import MemoryGrounder
29
+ from services.memory_scorer import MemoryScorer
30
+ from services.metrics import MetricsCollector
31
+ from services.notifications import NotificationStore
32
+ from services.ollama_client import OllamaClient
33
+ from services.output_filter import OutputFilter
34
+ from services.retrieval_broker import MemoryRetrievalBroker
35
+ from services.router import ModelRouter
36
+ from services.session_manager import SessionManager
37
+ from services.session_preloader import SessionPreloader
38
+ from services.validation_cache import ValidationCache
39
+ from services.vector_store import VectorStore
40
+ from services.version_tracker import VersionTracker
41
+ from services.watcher import CodeWatcher
42
+
43
+
44
+ @dataclass
45
+ class C3Runtime:
46
+ """Shared runtime container for C3 services."""
47
+
48
+ project_path: str
49
+ ide_name: str
50
+ ide_profile: object
51
+ indexer: CodeIndex
52
+ compressor: CodeCompressor
53
+ session_mgr: SessionManager
54
+ memory: MemoryStore
55
+ claude_md: ClaudeMdManager
56
+ activity_log: ActivityLog
57
+ notifications: NotificationStore
58
+ hybrid_config: dict
59
+ delegate_config: dict
60
+ vector_store: Optional[VectorStore] = None
61
+ output_filter: Optional[OutputFilter] = None
62
+ router: Optional[ModelRouter] = None
63
+ metrics: Optional[MetricsCollector] = None
64
+ watcher: Optional[CodeWatcher] = None
65
+ file_memory: Optional[FileMemoryStore] = None
66
+ version_tracker: Optional[VersionTracker] = None
67
+ ollama_client: Optional[OllamaClient] = None
68
+ ollama_available: bool = False
69
+ agents: list = field(default_factory=list)
70
+ transcript_index: Optional[object] = None
71
+ snapshots: Optional[object] = None
72
+ convo_store: Optional[object] = None
73
+ retrieval: Optional[object] = None
74
+ embedding_index: Optional[EmbeddingIndex] = None
75
+ doc_index: Optional[DocIndex] = None
76
+ preloader: Optional[SessionPreloader] = None
77
+ validation_cache: Optional[ValidationCache] = None
78
+ edit_ledger: Optional[EditLedger] = None
79
+ memory_scorer: Optional[MemoryScorer] = None
80
+ memory_graph: Optional[MemoryGraph] = None
81
+ memory_consolidator: Optional[MemoryConsolidator] = None
82
+ memory_grounder: Optional[MemoryGrounder] = None
83
+
84
+
85
+ def _load_agent_config(project_path: Path) -> dict:
86
+ config_path = project_path / ".c3" / "config.json"
87
+ if not config_path.exists():
88
+ return {}
89
+ try:
90
+ with open(config_path, encoding="utf-8") as f:
91
+ return json.load(f).get("agents", {})
92
+ except Exception:
93
+ return {}
94
+
95
+
96
+ _TMP_PATTERN = _re.compile(r"\.tmp\.\d+\.\d+$")
97
+ _TMP_MIN_AGE = 3600 # seconds — only sweep files older than 1h to avoid racing active atomic writes
98
+
99
+
100
+ def _cleanup_stale_tmp_files(project_path: Path) -> int:
101
+ """Remove orphaned .tmp.PID.TIMESTAMP files left by interrupted atomic writes.
102
+
103
+ Scoped to known hot directories so the sweep is O(small) on every startup.
104
+ """
105
+ count = 0
106
+ scan_roots = [
107
+ project_path,
108
+ project_path / "cli",
109
+ project_path / "cli" / "tools",
110
+ project_path / "services",
111
+ project_path / ".claude",
112
+ ]
113
+ now = _time.time()
114
+ for root in scan_roots:
115
+ if not root.exists() or not root.is_dir():
116
+ continue
117
+ try:
118
+ for p in root.iterdir():
119
+ if not p.is_file() or not _TMP_PATTERN.search(p.name):
120
+ continue
121
+ try:
122
+ if now - p.stat().st_mtime > _TMP_MIN_AGE:
123
+ p.unlink()
124
+ count += 1
125
+ except OSError:
126
+ pass
127
+ except OSError:
128
+ continue
129
+ return count
130
+
131
+
132
+ def build_runtime(project_path: str, ide_name: str | None = None) -> C3Runtime:
133
+ """Build the shared C3 runtime without starting background workers."""
134
+ project = Path(project_path).resolve()
135
+ _cleanup_stale_tmp_files(project)
136
+ c3_dir = project / ".c3"
137
+ resolved_ide = ide_name or load_ide_config(str(project))
138
+ ide_profile = get_profile(resolved_ide)
139
+ hybrid_config = load_hybrid_config(str(project))
140
+
141
+ indexer = CodeIndex(str(project), str(c3_dir / "index"))
142
+ compressor = CodeCompressor(str(c3_dir / "cache"), project_root=str(project))
143
+
144
+ ollama_client = OllamaClient(hybrid_config.get("ollama_base_url", "http://localhost:11434"))
145
+ session_mgr = SessionManager(str(project), str(c3_dir / "sessions"), ollama_client=ollama_client)
146
+
147
+ vector_store = None
148
+ if not hybrid_config.get("HYBRID_DISABLE_SLTM"):
149
+ try:
150
+ vector_store = VectorStore(str(project), hybrid_config)
151
+ except Exception:
152
+ pass
153
+
154
+ output_filter = None
155
+ if not hybrid_config.get("HYBRID_DISABLE_TIER1"):
156
+ output_filter = OutputFilter(hybrid_config)
157
+
158
+ router = None
159
+ if not hybrid_config.get("HYBRID_DISABLE_TIER2"):
160
+ router = ModelRouter(hybrid_config)
161
+
162
+ metrics = MetricsCollector(
163
+ output_filter=output_filter,
164
+ router=router,
165
+ vector_store=vector_store,
166
+ )
167
+ memory = MemoryStore(str(project), vector_store=vector_store)
168
+ session_mgr._memory_store = memory
169
+ convo_store = ConversationStore(str(project))
170
+ snapshots = ContextSnapshot(str(project))
171
+ watcher = CodeWatcher(str(project))
172
+ file_memory = FileMemoryStore(str(project))
173
+ validate_cfg = hybrid_config.get("validation_pipeline", {})
174
+ validation_cache = ValidationCache(str(project), validate_cfg) if validate_cfg.get("enabled", True) else None
175
+ watcher.set_backends(file_memory, compressor, validation_cache)
176
+ version_tracker = VersionTracker(str(project), ide_name=resolved_ide)
177
+ notifications = NotificationStore(str(project))
178
+ claude_md = ClaudeMdManager(
179
+ str(project),
180
+ session_mgr,
181
+ indexer,
182
+ memory,
183
+ instructions_file=ide_profile.instructions_file or "CLAUDE.md",
184
+ line_limit=ide_profile.instructions_line_limit or 200,
185
+ supports_hooks=ide_profile.supports_hooks,
186
+ supports_clear=ide_profile.supports_clear,
187
+ )
188
+ activity_log = ActivityLog(str(project))
189
+ delegate_config = load_delegate_config(str(project))
190
+ retrieval = MemoryRetrievalBroker(
191
+ str(project),
192
+ memory_store=memory,
193
+ conversation_store=convo_store,
194
+ file_memory=file_memory,
195
+ snapshots=snapshots,
196
+ )
197
+ memory.set_retrieval_broker(retrieval)
198
+
199
+ # Embedding index for semantic code search
200
+ embedding_index = None
201
+ if not hybrid_config.get("disable_embedding_index"):
202
+ try:
203
+ embed_model = hybrid_config.get("embed_model", "nomic-embed-text")
204
+ embedding_index = EmbeddingIndex(
205
+ str(project), ollama_client, embed_model=embed_model,
206
+ )
207
+ except Exception:
208
+ pass
209
+
210
+ # Doc index for Local RAG Pipeline
211
+ doc_index = None
212
+ rag_config = hybrid_config.get("rag", {})
213
+ if rag_config.get("enabled", True):
214
+ try:
215
+ doc_index = DocIndex(str(project), str(c3_dir / "doc_index"))
216
+ except Exception:
217
+ pass
218
+
219
+ # Session preloader for first-prompt auto-retrieval
220
+ preloader = None
221
+ if doc_index and rag_config.get("enabled", True):
222
+ preloader = SessionPreloader(
223
+ doc_index=doc_index,
224
+ embedding_index=embedding_index,
225
+ session_mgr=session_mgr,
226
+ memory_store=memory,
227
+ config=rag_config,
228
+ )
229
+
230
+ # Edit ledger for AI-tracked versioning
231
+ edit_ledger = EditLedger(str(project))
232
+
233
+ # Memory brain: scorer, graph, consolidator, grounder
234
+ memory_scorer = MemoryScorer()
235
+ memory_graph = MemoryGraph(str(project))
236
+ memory_consolidator = MemoryConsolidator(
237
+ memory_store=memory,
238
+ graph=memory_graph,
239
+ scorer=memory_scorer,
240
+ project_path=str(project),
241
+ )
242
+ memory_grounder = MemoryGrounder(
243
+ project_path=str(project),
244
+ memory_store=memory,
245
+ graph=memory_graph,
246
+ file_memory=file_memory,
247
+ )
248
+
249
+ # Ollama probe deferred to background — shaves ~2s off startup.
250
+ # Runtime starts with ollama_available=False; background thread updates it.
251
+ import threading as _t
252
+
253
+ def _bg_ollama_probe():
254
+ try:
255
+ runtime.ollama_available = ollama_client.is_available(timeout=2)
256
+ except Exception:
257
+ pass
258
+
259
+ runtime = C3Runtime(
260
+ project_path=str(project),
261
+ ide_name=resolved_ide,
262
+ ide_profile=ide_profile,
263
+ indexer=indexer,
264
+ compressor=compressor,
265
+ session_mgr=session_mgr,
266
+ memory=memory,
267
+ claude_md=claude_md,
268
+ activity_log=activity_log,
269
+ notifications=notifications,
270
+ hybrid_config=hybrid_config,
271
+ delegate_config=delegate_config,
272
+ vector_store=vector_store,
273
+ output_filter=output_filter,
274
+ router=router,
275
+ metrics=metrics,
276
+ watcher=watcher,
277
+ file_memory=file_memory,
278
+ version_tracker=version_tracker,
279
+ ollama_client=ollama_client,
280
+ ollama_available=False,
281
+ snapshots=snapshots,
282
+ convo_store=convo_store,
283
+ retrieval=retrieval,
284
+ embedding_index=embedding_index,
285
+ doc_index=doc_index,
286
+ preloader=preloader,
287
+ validation_cache=validation_cache,
288
+ edit_ledger=edit_ledger,
289
+ memory_scorer=memory_scorer,
290
+ memory_graph=memory_graph,
291
+ memory_consolidator=memory_consolidator,
292
+ memory_grounder=memory_grounder,
293
+ )
294
+ runtime.agents = create_agents(
295
+ runtime,
296
+ notifications,
297
+ _load_agent_config(project),
298
+ ollama=ollama_client,
299
+ )
300
+ # Start Ollama probe in background after runtime is constructed
301
+ _t.Thread(target=_bg_ollama_probe, daemon=True, name="c3-ollama-probe").start()
302
+ return runtime
303
+
304
+
305
+ def start_runtime(runtime: C3Runtime) -> None:
306
+ """Start watcher and agent background workers."""
307
+ if runtime.watcher:
308
+ runtime.watcher.start()
309
+ for agent in runtime.agents or []:
310
+ agent.start()
311
+
312
+
313
+ def stop_runtime(runtime: Optional[C3Runtime]) -> None:
314
+ """Stop watcher and agents for a runtime."""
315
+ if not runtime:
316
+ return
317
+ for agent in runtime.agents or []:
318
+ try:
319
+ agent.stop()
320
+ except Exception:
321
+ pass
322
+ if runtime.watcher:
323
+ try:
324
+ runtime.watcher.stop()
325
+ except Exception:
326
+ pass