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.
- cli/__init__.py +1 -0
- cli/_hook_utils.py +99 -0
- cli/c3.py +6152 -0
- cli/commands/__init__.py +1 -0
- cli/commands/common.py +312 -0
- cli/commands/parser.py +286 -0
- cli/docs.html +3178 -0
- cli/edits.html +878 -0
- cli/hook_auto_snapshot.py +142 -0
- cli/hook_c3_signal.py +61 -0
- cli/hook_c3read.py +116 -0
- cli/hook_edit_ledger.py +213 -0
- cli/hook_edit_unlock.py +170 -0
- cli/hook_filter.py +130 -0
- cli/hook_ghost_files.py +238 -0
- cli/hook_pretool_enforce.py +334 -0
- cli/hook_read.py +200 -0
- cli/hook_session_stats.py +62 -0
- cli/hook_terse_advisor.py +190 -0
- cli/hub.html +3764 -0
- cli/hub_server.py +1619 -0
- cli/mcp_proxy.py +428 -0
- cli/mcp_server.py +660 -0
- cli/server.py +2985 -0
- cli/tools/__init__.py +4 -0
- cli/tools/_helpers.py +65 -0
- cli/tools/agent.py +1165 -0
- cli/tools/compress.py +215 -0
- cli/tools/delegate.py +1184 -0
- cli/tools/edit.py +313 -0
- cli/tools/edits.py +118 -0
- cli/tools/filter.py +285 -0
- cli/tools/impact.py +163 -0
- cli/tools/memory.py +469 -0
- cli/tools/read.py +224 -0
- cli/tools/search.py +337 -0
- cli/tools/session.py +95 -0
- cli/tools/shell.py +193 -0
- cli/tools/status.py +306 -0
- cli/tools/validate.py +310 -0
- cli/ui/api.js +36 -0
- cli/ui/app.js +207 -0
- cli/ui/components/chat.js +758 -0
- cli/ui/components/dashboard.js +689 -0
- cli/ui/components/edits.js +220 -0
- cli/ui/components/instructions.js +481 -0
- cli/ui/components/memory.js +626 -0
- cli/ui/components/sessions.js +606 -0
- cli/ui/components/settings.js +1404 -0
- cli/ui/components/sidebar.js +156 -0
- cli/ui/icons.js +51 -0
- cli/ui/shared.js +119 -0
- cli/ui/theme.js +22 -0
- cli/ui.html +168 -0
- cli/ui_legacy.html +6797 -0
- cli/ui_nano.html +503 -0
- code_context_control-2.28.0.dist-info/METADATA +248 -0
- code_context_control-2.28.0.dist-info/RECORD +150 -0
- code_context_control-2.28.0.dist-info/WHEEL +5 -0
- code_context_control-2.28.0.dist-info/entry_points.txt +4 -0
- code_context_control-2.28.0.dist-info/licenses/LICENSE +201 -0
- code_context_control-2.28.0.dist-info/top_level.txt +5 -0
- core/__init__.py +75 -0
- core/config.py +269 -0
- core/ide.py +188 -0
- oracle/__init__.py +1 -0
- oracle/config.py +75 -0
- oracle/oracle.html +3900 -0
- oracle/oracle_server.py +663 -0
- oracle/services/__init__.py +1 -0
- oracle/services/c3_bridge.py +210 -0
- oracle/services/chat_engine.py +1103 -0
- oracle/services/chat_store.py +155 -0
- oracle/services/cross_memory.py +154 -0
- oracle/services/federated_graph.py +463 -0
- oracle/services/health_checker.py +117 -0
- oracle/services/insight_engine.py +307 -0
- oracle/services/memory_reader.py +106 -0
- oracle/services/memory_writer.py +182 -0
- oracle/services/ollama_bridge.py +332 -0
- oracle/services/project_scanner.py +87 -0
- oracle/services/review_agent.py +206 -0
- services/__init__.py +1 -0
- services/activity_log.py +93 -0
- services/agent_base.py +124 -0
- services/agents.py +1529 -0
- services/auto_memory.py +407 -0
- services/bench/__init__.py +6 -0
- services/bench/external/__init__.py +29 -0
- services/bench/external/aider_polyglot.py +405 -0
- services/bench/external/swe_bench.py +485 -0
- services/benchmark_dashboard.py +596 -0
- services/claude_md.py +785 -0
- services/compressor.py +592 -0
- services/context_snapshot.py +356 -0
- services/conversation_store.py +870 -0
- services/doc_index.py +537 -0
- services/e2e_benchmark.py +2884 -0
- services/e2e_evaluator.py +396 -0
- services/e2e_tasks.py +743 -0
- services/edit_ledger.py +459 -0
- services/embedding_index.py +341 -0
- services/error_reporting.py +123 -0
- services/file_memory.py +734 -0
- services/hub_service.py +585 -0
- services/indexer.py +712 -0
- services/memory.py +318 -0
- services/memory_consolidator.py +538 -0
- services/memory_graph.py +382 -0
- services/memory_grounder.py +304 -0
- services/memory_scorer.py +246 -0
- services/metrics.py +86 -0
- services/notifications.py +209 -0
- services/ollama_client.py +201 -0
- services/output_filter.py +488 -0
- services/parser.py +1238 -0
- services/project_manager.py +579 -0
- services/protocol.py +306 -0
- services/proxy_state.py +152 -0
- services/retrieval_broker.py +129 -0
- services/router.py +414 -0
- services/runtime.py +326 -0
- services/session_benchmark.py +1945 -0
- services/session_manager.py +1026 -0
- services/session_preloader.py +251 -0
- services/text_index.py +90 -0
- services/tool_classifier.py +176 -0
- services/transcript_index.py +340 -0
- services/validation_cache.py +155 -0
- services/vector_store.py +299 -0
- services/version_tracker.py +271 -0
- services/watcher.py +192 -0
- tui/__init__.py +0 -0
- tui/backend.py +59 -0
- tui/main.py +145 -0
- tui/screens/__init__.py +1 -0
- tui/screens/benchmark_view.py +109 -0
- tui/screens/claudemd_view.py +46 -0
- tui/screens/compress_view.py +52 -0
- tui/screens/index_view.py +74 -0
- tui/screens/init_view.py +82 -0
- tui/screens/mcp_view.py +73 -0
- tui/screens/optimize_view.py +41 -0
- tui/screens/pipe_view.py +46 -0
- tui/screens/projects_view.py +355 -0
- tui/screens/search_view.py +55 -0
- tui/screens/session_view.py +143 -0
- tui/screens/stats.py +158 -0
- tui/screens/ui_view.py +54 -0
- 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
|