codexa 0.4.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 (189) hide show
  1. codexa-0.4.0.dist-info/METADATA +650 -0
  2. codexa-0.4.0.dist-info/RECORD +189 -0
  3. codexa-0.4.0.dist-info/WHEEL +5 -0
  4. codexa-0.4.0.dist-info/entry_points.txt +2 -0
  5. codexa-0.4.0.dist-info/licenses/LICENSE +21 -0
  6. codexa-0.4.0.dist-info/top_level.txt +1 -0
  7. semantic_code_intelligence/__init__.py +5 -0
  8. semantic_code_intelligence/analysis/__init__.py +21 -0
  9. semantic_code_intelligence/analysis/ai_features.py +351 -0
  10. semantic_code_intelligence/bridge/__init__.py +28 -0
  11. semantic_code_intelligence/bridge/context_provider.py +245 -0
  12. semantic_code_intelligence/bridge/protocol.py +167 -0
  13. semantic_code_intelligence/bridge/server.py +348 -0
  14. semantic_code_intelligence/bridge/vscode.py +271 -0
  15. semantic_code_intelligence/ci/__init__.py +13 -0
  16. semantic_code_intelligence/ci/hooks.py +98 -0
  17. semantic_code_intelligence/ci/hotspots.py +272 -0
  18. semantic_code_intelligence/ci/impact.py +246 -0
  19. semantic_code_intelligence/ci/metrics.py +591 -0
  20. semantic_code_intelligence/ci/pr.py +412 -0
  21. semantic_code_intelligence/ci/quality.py +557 -0
  22. semantic_code_intelligence/ci/templates.py +164 -0
  23. semantic_code_intelligence/ci/trace.py +224 -0
  24. semantic_code_intelligence/cli/__init__.py +0 -0
  25. semantic_code_intelligence/cli/commands/__init__.py +0 -0
  26. semantic_code_intelligence/cli/commands/ask_cmd.py +153 -0
  27. semantic_code_intelligence/cli/commands/benchmark_cmd.py +303 -0
  28. semantic_code_intelligence/cli/commands/chat_cmd.py +252 -0
  29. semantic_code_intelligence/cli/commands/ci_gen_cmd.py +74 -0
  30. semantic_code_intelligence/cli/commands/context_cmd.py +120 -0
  31. semantic_code_intelligence/cli/commands/cross_refactor_cmd.py +113 -0
  32. semantic_code_intelligence/cli/commands/deps_cmd.py +91 -0
  33. semantic_code_intelligence/cli/commands/docs_cmd.py +101 -0
  34. semantic_code_intelligence/cli/commands/doctor_cmd.py +147 -0
  35. semantic_code_intelligence/cli/commands/evolve_cmd.py +171 -0
  36. semantic_code_intelligence/cli/commands/explain_cmd.py +112 -0
  37. semantic_code_intelligence/cli/commands/gate_cmd.py +135 -0
  38. semantic_code_intelligence/cli/commands/grep_cmd.py +234 -0
  39. semantic_code_intelligence/cli/commands/hotspots_cmd.py +119 -0
  40. semantic_code_intelligence/cli/commands/impact_cmd.py +131 -0
  41. semantic_code_intelligence/cli/commands/index_cmd.py +138 -0
  42. semantic_code_intelligence/cli/commands/init_cmd.py +152 -0
  43. semantic_code_intelligence/cli/commands/investigate_cmd.py +163 -0
  44. semantic_code_intelligence/cli/commands/languages_cmd.py +101 -0
  45. semantic_code_intelligence/cli/commands/lsp_cmd.py +49 -0
  46. semantic_code_intelligence/cli/commands/mcp_cmd.py +50 -0
  47. semantic_code_intelligence/cli/commands/metrics_cmd.py +264 -0
  48. semantic_code_intelligence/cli/commands/models_cmd.py +157 -0
  49. semantic_code_intelligence/cli/commands/plugin_cmd.py +275 -0
  50. semantic_code_intelligence/cli/commands/pr_summary_cmd.py +178 -0
  51. semantic_code_intelligence/cli/commands/quality_cmd.py +208 -0
  52. semantic_code_intelligence/cli/commands/refactor_cmd.py +103 -0
  53. semantic_code_intelligence/cli/commands/review_cmd.py +88 -0
  54. semantic_code_intelligence/cli/commands/search_cmd.py +236 -0
  55. semantic_code_intelligence/cli/commands/serve_cmd.py +117 -0
  56. semantic_code_intelligence/cli/commands/suggest_cmd.py +100 -0
  57. semantic_code_intelligence/cli/commands/summary_cmd.py +78 -0
  58. semantic_code_intelligence/cli/commands/tool_cmd.py +282 -0
  59. semantic_code_intelligence/cli/commands/trace_cmd.py +123 -0
  60. semantic_code_intelligence/cli/commands/tui_cmd.py +58 -0
  61. semantic_code_intelligence/cli/commands/viz_cmd.py +127 -0
  62. semantic_code_intelligence/cli/commands/watch_cmd.py +72 -0
  63. semantic_code_intelligence/cli/commands/web_cmd.py +61 -0
  64. semantic_code_intelligence/cli/commands/workspace_cmd.py +250 -0
  65. semantic_code_intelligence/cli/main.py +65 -0
  66. semantic_code_intelligence/cli/router.py +92 -0
  67. semantic_code_intelligence/config/__init__.py +0 -0
  68. semantic_code_intelligence/config/settings.py +260 -0
  69. semantic_code_intelligence/context/__init__.py +19 -0
  70. semantic_code_intelligence/context/engine.py +429 -0
  71. semantic_code_intelligence/context/memory.py +253 -0
  72. semantic_code_intelligence/daemon/__init__.py +1 -0
  73. semantic_code_intelligence/daemon/watcher.py +515 -0
  74. semantic_code_intelligence/docs/__init__.py +1080 -0
  75. semantic_code_intelligence/embeddings/__init__.py +0 -0
  76. semantic_code_intelligence/embeddings/enhanced.py +131 -0
  77. semantic_code_intelligence/embeddings/generator.py +149 -0
  78. semantic_code_intelligence/embeddings/model_registry.py +100 -0
  79. semantic_code_intelligence/evolution/__init__.py +1 -0
  80. semantic_code_intelligence/evolution/budget_guard.py +111 -0
  81. semantic_code_intelligence/evolution/commit_manager.py +88 -0
  82. semantic_code_intelligence/evolution/context_builder.py +131 -0
  83. semantic_code_intelligence/evolution/engine.py +249 -0
  84. semantic_code_intelligence/evolution/patch_generator.py +229 -0
  85. semantic_code_intelligence/evolution/task_selector.py +214 -0
  86. semantic_code_intelligence/evolution/test_runner.py +111 -0
  87. semantic_code_intelligence/indexing/__init__.py +0 -0
  88. semantic_code_intelligence/indexing/chunker.py +174 -0
  89. semantic_code_intelligence/indexing/parallel.py +86 -0
  90. semantic_code_intelligence/indexing/scanner.py +146 -0
  91. semantic_code_intelligence/indexing/semantic_chunker.py +337 -0
  92. semantic_code_intelligence/llm/__init__.py +62 -0
  93. semantic_code_intelligence/llm/cache.py +219 -0
  94. semantic_code_intelligence/llm/cached_provider.py +145 -0
  95. semantic_code_intelligence/llm/conversation.py +190 -0
  96. semantic_code_intelligence/llm/cross_refactor.py +272 -0
  97. semantic_code_intelligence/llm/investigation.py +274 -0
  98. semantic_code_intelligence/llm/mock_provider.py +77 -0
  99. semantic_code_intelligence/llm/ollama_provider.py +122 -0
  100. semantic_code_intelligence/llm/openai_provider.py +100 -0
  101. semantic_code_intelligence/llm/provider.py +92 -0
  102. semantic_code_intelligence/llm/rate_limiter.py +164 -0
  103. semantic_code_intelligence/llm/reasoning.py +438 -0
  104. semantic_code_intelligence/llm/safety.py +110 -0
  105. semantic_code_intelligence/llm/streaming.py +251 -0
  106. semantic_code_intelligence/lsp/__init__.py +609 -0
  107. semantic_code_intelligence/mcp/__init__.py +393 -0
  108. semantic_code_intelligence/parsing/__init__.py +19 -0
  109. semantic_code_intelligence/parsing/parser.py +375 -0
  110. semantic_code_intelligence/plugins/__init__.py +255 -0
  111. semantic_code_intelligence/plugins/examples/__init__.py +1 -0
  112. semantic_code_intelligence/plugins/examples/code_quality.py +73 -0
  113. semantic_code_intelligence/plugins/examples/search_annotator.py +56 -0
  114. semantic_code_intelligence/scalability/__init__.py +205 -0
  115. semantic_code_intelligence/search/__init__.py +0 -0
  116. semantic_code_intelligence/search/formatter.py +123 -0
  117. semantic_code_intelligence/search/grep.py +361 -0
  118. semantic_code_intelligence/search/hybrid_search.py +170 -0
  119. semantic_code_intelligence/search/keyword_search.py +311 -0
  120. semantic_code_intelligence/search/section_expander.py +103 -0
  121. semantic_code_intelligence/services/__init__.py +0 -0
  122. semantic_code_intelligence/services/indexing_service.py +630 -0
  123. semantic_code_intelligence/services/search_service.py +269 -0
  124. semantic_code_intelligence/storage/__init__.py +0 -0
  125. semantic_code_intelligence/storage/chunk_hash_store.py +86 -0
  126. semantic_code_intelligence/storage/hash_store.py +66 -0
  127. semantic_code_intelligence/storage/index_manifest.py +85 -0
  128. semantic_code_intelligence/storage/index_stats.py +138 -0
  129. semantic_code_intelligence/storage/query_history.py +160 -0
  130. semantic_code_intelligence/storage/symbol_registry.py +209 -0
  131. semantic_code_intelligence/storage/vector_store.py +297 -0
  132. semantic_code_intelligence/tests/__init__.py +0 -0
  133. semantic_code_intelligence/tests/test_ai_features.py +351 -0
  134. semantic_code_intelligence/tests/test_chunker.py +119 -0
  135. semantic_code_intelligence/tests/test_cli.py +188 -0
  136. semantic_code_intelligence/tests/test_config.py +154 -0
  137. semantic_code_intelligence/tests/test_context.py +381 -0
  138. semantic_code_intelligence/tests/test_embeddings.py +73 -0
  139. semantic_code_intelligence/tests/test_endtoend.py +1142 -0
  140. semantic_code_intelligence/tests/test_enhanced_embeddings.py +92 -0
  141. semantic_code_intelligence/tests/test_hash_store.py +79 -0
  142. semantic_code_intelligence/tests/test_logging.py +55 -0
  143. semantic_code_intelligence/tests/test_new_cli.py +138 -0
  144. semantic_code_intelligence/tests/test_parser.py +495 -0
  145. semantic_code_intelligence/tests/test_phase10.py +355 -0
  146. semantic_code_intelligence/tests/test_phase11.py +593 -0
  147. semantic_code_intelligence/tests/test_phase12.py +375 -0
  148. semantic_code_intelligence/tests/test_phase13.py +663 -0
  149. semantic_code_intelligence/tests/test_phase14.py +568 -0
  150. semantic_code_intelligence/tests/test_phase15.py +814 -0
  151. semantic_code_intelligence/tests/test_phase16.py +792 -0
  152. semantic_code_intelligence/tests/test_phase17.py +815 -0
  153. semantic_code_intelligence/tests/test_phase18.py +934 -0
  154. semantic_code_intelligence/tests/test_phase19.py +986 -0
  155. semantic_code_intelligence/tests/test_phase20.py +2753 -0
  156. semantic_code_intelligence/tests/test_phase20b.py +2058 -0
  157. semantic_code_intelligence/tests/test_phase20c.py +962 -0
  158. semantic_code_intelligence/tests/test_phase21.py +428 -0
  159. semantic_code_intelligence/tests/test_phase22.py +799 -0
  160. semantic_code_intelligence/tests/test_phase23.py +783 -0
  161. semantic_code_intelligence/tests/test_phase24.py +715 -0
  162. semantic_code_intelligence/tests/test_phase25.py +496 -0
  163. semantic_code_intelligence/tests/test_phase26.py +251 -0
  164. semantic_code_intelligence/tests/test_phase27.py +531 -0
  165. semantic_code_intelligence/tests/test_phase8.py +592 -0
  166. semantic_code_intelligence/tests/test_phase9.py +643 -0
  167. semantic_code_intelligence/tests/test_plugins.py +293 -0
  168. semantic_code_intelligence/tests/test_priority_features.py +727 -0
  169. semantic_code_intelligence/tests/test_router.py +41 -0
  170. semantic_code_intelligence/tests/test_scalability.py +138 -0
  171. semantic_code_intelligence/tests/test_scanner.py +125 -0
  172. semantic_code_intelligence/tests/test_search.py +160 -0
  173. semantic_code_intelligence/tests/test_semantic_chunker.py +255 -0
  174. semantic_code_intelligence/tests/test_tools.py +182 -0
  175. semantic_code_intelligence/tests/test_vector_store.py +151 -0
  176. semantic_code_intelligence/tests/test_watcher.py +211 -0
  177. semantic_code_intelligence/tools/__init__.py +442 -0
  178. semantic_code_intelligence/tools/executor.py +232 -0
  179. semantic_code_intelligence/tools/protocol.py +200 -0
  180. semantic_code_intelligence/tui/__init__.py +454 -0
  181. semantic_code_intelligence/utils/__init__.py +0 -0
  182. semantic_code_intelligence/utils/logging.py +112 -0
  183. semantic_code_intelligence/version.py +3 -0
  184. semantic_code_intelligence/web/__init__.py +11 -0
  185. semantic_code_intelligence/web/api.py +289 -0
  186. semantic_code_intelligence/web/server.py +397 -0
  187. semantic_code_intelligence/web/ui.py +659 -0
  188. semantic_code_intelligence/web/visualize.py +226 -0
  189. semantic_code_intelligence/workspace/__init__.py +427 -0
@@ -0,0 +1,253 @@
1
+ """Context memory — workspace memory, session context, and multi-step reasoning.
2
+
3
+ Provides persistent and session-scoped memory so that the AI assistant can:
4
+ - Remember previous interactions within a session
5
+ - Cache insights across sessions (workspace memory)
6
+ - Maintain multi-step reasoning chains
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import json
12
+ import time
13
+ from dataclasses import dataclass, field
14
+ from pathlib import Path
15
+ from typing import Any
16
+
17
+ from semantic_code_intelligence.utils.logging import get_logger
18
+
19
+ logger = get_logger("context.memory")
20
+
21
+
22
+ # ---------------------------------------------------------------------------
23
+ # Data types
24
+ # ---------------------------------------------------------------------------
25
+
26
+ @dataclass
27
+ class MemoryEntry:
28
+ """A single memory entry (question/answer, insight, or reasoning step)."""
29
+
30
+ key: str
31
+ content: str
32
+ kind: str = "general" # general | qa | reasoning | insight
33
+ timestamp: float = field(default_factory=time.time)
34
+ metadata: dict[str, Any] = field(default_factory=dict)
35
+
36
+ def to_dict(self) -> dict[str, Any]:
37
+ """Serialize the memory entry to a plain dictionary."""
38
+ return {
39
+ "key": self.key,
40
+ "content": self.content,
41
+ "kind": self.kind,
42
+ "timestamp": self.timestamp,
43
+ "metadata": self.metadata,
44
+ }
45
+
46
+ @classmethod
47
+ def from_dict(cls, data: dict[str, Any]) -> "MemoryEntry":
48
+ """Create a MemoryEntry from a dictionary."""
49
+ return cls(
50
+ key=data["key"],
51
+ content=data["content"],
52
+ kind=data.get("kind", "general"),
53
+ timestamp=data.get("timestamp", time.time()),
54
+ metadata=data.get("metadata", {}),
55
+ )
56
+
57
+
58
+ @dataclass
59
+ class ReasoningStep:
60
+ """A single step in a multi-step reasoning chain."""
61
+
62
+ step_id: int
63
+ action: str # e.g. "search", "analyze", "ask_llm", "conclude"
64
+ input_text: str
65
+ output_text: str
66
+ timestamp: float = field(default_factory=time.time)
67
+
68
+ def to_dict(self) -> dict[str, Any]:
69
+ """Serialize the reasoning step to a plain dictionary."""
70
+ return {
71
+ "step_id": self.step_id,
72
+ "action": self.action,
73
+ "input": self.input_text,
74
+ "output": self.output_text,
75
+ "timestamp": self.timestamp,
76
+ }
77
+
78
+
79
+ # ---------------------------------------------------------------------------
80
+ # Session Memory (in-process, per-session)
81
+ # ---------------------------------------------------------------------------
82
+
83
+ class SessionMemory:
84
+ """In-process memory for the current session / conversation."""
85
+
86
+ def __init__(self, max_entries: int = 200) -> None:
87
+ self._entries: list[MemoryEntry] = []
88
+ self._reasoning_chains: dict[str, list[ReasoningStep]] = {}
89
+ self._max = max_entries
90
+
91
+ @property
92
+ def entries(self) -> list[MemoryEntry]:
93
+ """Return a shallow copy of all session memory entries."""
94
+ return list(self._entries)
95
+
96
+ def add(self, key: str, content: str, kind: str = "general", **metadata: Any) -> MemoryEntry:
97
+ """Add a memory entry to the session."""
98
+ entry = MemoryEntry(key=key, content=content, kind=kind, metadata=metadata)
99
+ self._entries.append(entry)
100
+ if len(self._entries) > self._max:
101
+ self._entries.pop(0)
102
+ return entry
103
+
104
+ def search(self, query: str, limit: int = 5) -> list[MemoryEntry]:
105
+ """Simple keyword search over session memory."""
106
+ query_lower = query.lower()
107
+ scored = []
108
+ for entry in self._entries:
109
+ text = f"{entry.key} {entry.content}".lower()
110
+ if query_lower in text:
111
+ scored.append(entry)
112
+ return scored[-limit:]
113
+
114
+ def get_recent(self, limit: int = 10) -> list[MemoryEntry]:
115
+ """Return the most recent entries."""
116
+ return self._entries[-limit:]
117
+
118
+ def clear(self) -> None:
119
+ """Clear all session memory."""
120
+ self._entries.clear()
121
+ self._reasoning_chains.clear()
122
+
123
+ # --- Reasoning chains ---
124
+
125
+ def start_chain(self, chain_id: str) -> None:
126
+ """Start a new reasoning chain."""
127
+ self._reasoning_chains[chain_id] = []
128
+
129
+ def add_step(
130
+ self,
131
+ chain_id: str,
132
+ action: str,
133
+ input_text: str,
134
+ output_text: str,
135
+ ) -> ReasoningStep:
136
+ """Add a step to an existing reasoning chain."""
137
+ chain = self._reasoning_chains.setdefault(chain_id, [])
138
+ step = ReasoningStep(
139
+ step_id=len(chain) + 1,
140
+ action=action,
141
+ input_text=input_text,
142
+ output_text=output_text,
143
+ )
144
+ chain.append(step)
145
+ return step
146
+
147
+ def get_chain(self, chain_id: str) -> list[ReasoningStep]:
148
+ """Retrieve all steps in a reasoning chain."""
149
+ return list(self._reasoning_chains.get(chain_id, []))
150
+
151
+ def to_dict(self) -> dict[str, Any]:
152
+ """Serialize all session memory and reasoning chains to a dictionary."""
153
+ return {
154
+ "entries": [e.to_dict() for e in self._entries],
155
+ "chains": {
156
+ cid: [s.to_dict() for s in steps]
157
+ for cid, steps in self._reasoning_chains.items()
158
+ },
159
+ }
160
+
161
+ def __repr__(self) -> str:
162
+ return (
163
+ f"SessionMemory(entries={len(self._entries)}, "
164
+ f"chains={len(self._reasoning_chains)})"
165
+ )
166
+
167
+
168
+ # ---------------------------------------------------------------------------
169
+ # Workspace Memory (persistent, stored in .codexa/)
170
+ # ---------------------------------------------------------------------------
171
+
172
+ MEMORY_FILE = "memory.json"
173
+
174
+
175
+ class WorkspaceMemory:
176
+ """Persistent memory stored in the project's .codexa/ directory.
177
+
178
+ Survives across sessions. Cached insights, frequently-asked questions,
179
+ and project-specific knowledge live here.
180
+ """
181
+
182
+ def __init__(self, project_root: Path) -> None:
183
+ from semantic_code_intelligence.config.settings import AppConfig
184
+
185
+ self._config_dir = AppConfig.config_dir(project_root)
186
+ self._path = self._config_dir / MEMORY_FILE
187
+ self._entries: dict[str, MemoryEntry] = {}
188
+ self._load()
189
+
190
+ def _load(self) -> None:
191
+ """Load memory from disk."""
192
+ if self._path.exists():
193
+ try:
194
+ data = json.loads(self._path.read_text(encoding="utf-8"))
195
+ for entry_data in data.get("entries", []):
196
+ entry = MemoryEntry.from_dict(entry_data)
197
+ self._entries[entry.key] = entry
198
+ logger.debug("Loaded %d workspace memory entries", len(self._entries))
199
+ except (json.JSONDecodeError, KeyError, TypeError):
200
+ logger.warning("Corrupt workspace memory file; starting fresh.")
201
+ self._entries = {}
202
+
203
+ def _save(self) -> None:
204
+ """Persist memory to disk."""
205
+ self._config_dir.mkdir(parents=True, exist_ok=True)
206
+ data = {"entries": [e.to_dict() for e in self._entries.values()]}
207
+ self._path.write_text(json.dumps(data, indent=2), encoding="utf-8")
208
+
209
+ @property
210
+ def entries(self) -> list[MemoryEntry]:
211
+ """Return a list of all persisted workspace memory entries."""
212
+ return list(self._entries.values())
213
+
214
+ def add(self, key: str, content: str, kind: str = "general", **metadata: Any) -> MemoryEntry:
215
+ """Add or update a memory entry."""
216
+ entry = MemoryEntry(key=key, content=content, kind=kind, metadata=metadata)
217
+ self._entries[key] = entry
218
+ self._save()
219
+ return entry
220
+
221
+ def get(self, key: str) -> MemoryEntry | None:
222
+ """Retrieve a specific memory entry by key."""
223
+ return self._entries.get(key)
224
+
225
+ def search(self, query: str, limit: int = 5) -> list[MemoryEntry]:
226
+ """Simple keyword search over workspace memory."""
227
+ query_lower = query.lower()
228
+ results = []
229
+ for entry in self._entries.values():
230
+ text = f"{entry.key} {entry.content}".lower()
231
+ if query_lower in text:
232
+ results.append(entry)
233
+ return results[:limit]
234
+
235
+ def remove(self, key: str) -> bool:
236
+ """Remove a memory entry."""
237
+ if key in self._entries:
238
+ del self._entries[key]
239
+ self._save()
240
+ return True
241
+ return False
242
+
243
+ def clear(self) -> None:
244
+ """Clear all workspace memory."""
245
+ self._entries.clear()
246
+ self._save()
247
+
248
+ def to_dict(self) -> dict[str, Any]:
249
+ """Serialize all workspace memory entries to a dictionary."""
250
+ return {"entries": [e.to_dict() for e in self._entries.values()]}
251
+
252
+ def __repr__(self) -> str:
253
+ return f"WorkspaceMemory(entries={len(self._entries)})"
@@ -0,0 +1 @@
1
+ """Daemon package — background intelligence subsystem."""