code-finder 0.1.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.
- claude_context/__init__.py +33 -0
- claude_context/agentic_integration.py +309 -0
- claude_context/ast_chunker.py +646 -0
- claude_context/config.py +239 -0
- claude_context/context_manager.py +627 -0
- claude_context/embeddings.py +307 -0
- claude_context/embeddings_interface.py +226 -0
- claude_context/enhanced_ast_chunker.py +1129 -0
- claude_context/explorer.py +951 -0
- claude_context/explorer_with_context.py +1008 -0
- claude_context/indexer.py +893 -0
- claude_context/markdown_chunker.py +421 -0
- claude_context/mode_handler.py +1774 -0
- claude_context/query_metrics.py +164 -0
- claude_context/question_generator.py +800 -0
- claude_context/readme_extractor.py +485 -0
- claude_context/repository_adapter.py +399 -0
- claude_context/search.py +493 -0
- claude_context/skills/__init__.py +11 -0
- claude_context/skills/_cli_common.py +74 -0
- claude_context/skills/_index_manager.py +98 -0
- claude_context/skills/api_surface.py +219 -0
- claude_context/skills/evidence_retrieval.py +151 -0
- claude_context/skills/grounded_review.py +212 -0
- claude_context/synthesis/__init__.py +8 -0
- claude_context/synthesis/editor_agent.py +391 -0
- claude_context/synthesis/llm_synthesizer.py +153 -0
- claude_context/synthesis/logic_explainer.py +235 -0
- claude_context/synthesis/multi_review_pipeline.py +717 -0
- claude_context/synthesis/prompt_builder.py +439 -0
- claude_context/synthesis/providers.py +115 -0
- claude_context/synthesis/validators.py +458 -0
- code_finder-0.1.0.dist-info/METADATA +823 -0
- code_finder-0.1.0.dist-info/RECORD +37 -0
- code_finder-0.1.0.dist-info/WHEEL +5 -0
- code_finder-0.1.0.dist-info/entry_points.txt +4 -0
- code_finder-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Claude Context MCP Integration for Vibe2Doc
|
|
3
|
+
|
|
4
|
+
This module provides semantic code search and understanding capabilities
|
|
5
|
+
using Milvus Lite for vector storage and embeddings.
|
|
6
|
+
|
|
7
|
+
Philosophy: Fail fast, log clearly, no silent fallbacks.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from .config import ClaudeContextConfig, MilvusManager
|
|
11
|
+
from .embeddings import LocalEmbeddings, create_embeddings
|
|
12
|
+
from .indexer import RepositoryIndexer
|
|
13
|
+
from .search import HybridSearcher, SearchResult, create_hybrid_searcher
|
|
14
|
+
try:
|
|
15
|
+
# Expose synthesis module when available (Phase 3)
|
|
16
|
+
from .synthesis.llm_synthesizer import LLMSynthesizer # type: ignore
|
|
17
|
+
except Exception:
|
|
18
|
+
LLMSynthesizer = None # Optional until Phase 3 is fully wired
|
|
19
|
+
|
|
20
|
+
__version__ = "0.1.0"
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"ClaudeContextConfig",
|
|
24
|
+
"MilvusManager",
|
|
25
|
+
"LocalEmbeddings",
|
|
26
|
+
"create_embeddings",
|
|
27
|
+
"RepositoryIndexer",
|
|
28
|
+
"HybridSearcher",
|
|
29
|
+
"SearchResult",
|
|
30
|
+
"create_hybrid_searcher",
|
|
31
|
+
# Optional synthesis export
|
|
32
|
+
"LLMSynthesizer",
|
|
33
|
+
]
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Integration module for Claude Context modes with agentic_client_langgraph.py
|
|
3
|
+
|
|
4
|
+
This module bridges the new mode-based approach with the existing
|
|
5
|
+
LangGraph agentic workflow.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
import asyncio
|
|
10
|
+
from typing import Dict, Any, Optional, List
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
from .mode_handler import (
|
|
14
|
+
DocumentationModeHandler,
|
|
15
|
+
DocumentationMode,
|
|
16
|
+
ModeContext,
|
|
17
|
+
run_documentation_mode
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class AgenticModeIntegration:
|
|
24
|
+
"""
|
|
25
|
+
Integrates Claude Context modes with the existing agentic workflow.
|
|
26
|
+
|
|
27
|
+
This class provides methods that can be called from agentic_client_langgraph.py
|
|
28
|
+
to leverage the new mode-based documentation generation.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self):
|
|
32
|
+
"""Initialize the integration"""
|
|
33
|
+
self.handler = DocumentationModeHandler()
|
|
34
|
+
self.current_mode = DocumentationMode.AUTO # Default
|
|
35
|
+
self.current_context: Optional[ModeContext] = None
|
|
36
|
+
|
|
37
|
+
async def analyze_repository_with_mode(
|
|
38
|
+
self,
|
|
39
|
+
repository_path: str,
|
|
40
|
+
mode: str = "auto",
|
|
41
|
+
context_files: Optional[List[str]] = None,
|
|
42
|
+
jira_config: Optional[Dict] = None
|
|
43
|
+
) -> Dict[str, Any]:
|
|
44
|
+
"""
|
|
45
|
+
Analyze a repository using the specified mode.
|
|
46
|
+
|
|
47
|
+
This method replaces the standard repository analysis with
|
|
48
|
+
mode-aware analysis that includes indexing and context.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
repository_path: Path to the repository
|
|
52
|
+
mode: Documentation mode (auto/interactive/hybrid)
|
|
53
|
+
context_files: External context files
|
|
54
|
+
jira_config: Jira configuration
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Analysis results compatible with existing workflow
|
|
58
|
+
"""
|
|
59
|
+
logger.info(f"Analyzing repository with {mode} mode")
|
|
60
|
+
|
|
61
|
+
# Parse mode
|
|
62
|
+
try:
|
|
63
|
+
doc_mode = DocumentationMode(mode.lower())
|
|
64
|
+
except ValueError:
|
|
65
|
+
logger.warning(f"Invalid mode {mode}, defaulting to AUTO")
|
|
66
|
+
doc_mode = DocumentationMode.AUTO
|
|
67
|
+
|
|
68
|
+
# Initialize the mode
|
|
69
|
+
self.current_context = await self.handler.initialize_mode(
|
|
70
|
+
mode=doc_mode,
|
|
71
|
+
repository_path=repository_path,
|
|
72
|
+
context_files=context_files,
|
|
73
|
+
jira_config=jira_config
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# Build analysis result compatible with existing workflow
|
|
77
|
+
analysis = {
|
|
78
|
+
"repository_path": repository_path,
|
|
79
|
+
"mode": doc_mode.value,
|
|
80
|
+
"indexed": True,
|
|
81
|
+
"stats": {
|
|
82
|
+
"files_indexed": self.current_context.indexer.stats.get("files_indexed", 0)
|
|
83
|
+
if self.current_context.indexer else 0,
|
|
84
|
+
"total_chunks": self.current_context.indexer.stats.get("total_chunks", 0)
|
|
85
|
+
if self.current_context.indexer else 0,
|
|
86
|
+
"context_items": self.current_context.context_manager.total_items
|
|
87
|
+
if self.current_context.context_manager else 0
|
|
88
|
+
},
|
|
89
|
+
"has_context": doc_mode != DocumentationMode.AUTO,
|
|
90
|
+
"requires_interaction": doc_mode == DocumentationMode.INTERACTIVE
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
# For INTERACTIVE mode, we need to run the Q&A session
|
|
94
|
+
if doc_mode == DocumentationMode.INTERACTIVE:
|
|
95
|
+
logger.info("INTERACTIVE mode requires Q&A session")
|
|
96
|
+
analysis["interaction_required"] = True
|
|
97
|
+
analysis["explorer_ready"] = self.current_context.explorer is not None
|
|
98
|
+
|
|
99
|
+
return analysis
|
|
100
|
+
|
|
101
|
+
async def run_interactive_exploration(self) -> Dict[str, Any]:
|
|
102
|
+
"""
|
|
103
|
+
Run the interactive Q&A exploration session.
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
Exploration results including Q&A history
|
|
107
|
+
"""
|
|
108
|
+
if not self.current_context:
|
|
109
|
+
raise RuntimeError("No context initialized")
|
|
110
|
+
|
|
111
|
+
if self.current_context.mode != DocumentationMode.INTERACTIVE:
|
|
112
|
+
raise RuntimeError("Interactive exploration only available in INTERACTIVE mode")
|
|
113
|
+
|
|
114
|
+
# Run the interactive session
|
|
115
|
+
await self.handler._run_interactive_session(self.current_context)
|
|
116
|
+
|
|
117
|
+
# Return exploration results
|
|
118
|
+
return {
|
|
119
|
+
"exploration_complete": self.current_context.exploration_complete,
|
|
120
|
+
"qa_count": len(self.current_context.qa_history),
|
|
121
|
+
"qa_history": self.current_context.qa_history,
|
|
122
|
+
"context_used": self.current_context.context_manager.total_items
|
|
123
|
+
if self.current_context.context_manager else 0
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async def generate_documentation_with_mode(
|
|
127
|
+
self,
|
|
128
|
+
analysis_data: Dict[str, Any],
|
|
129
|
+
doc_type: str = "overview"
|
|
130
|
+
) -> str:
|
|
131
|
+
"""
|
|
132
|
+
Generate documentation using the current mode.
|
|
133
|
+
|
|
134
|
+
This method is called by the existing workflow to generate
|
|
135
|
+
individual documentation sections.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
analysis_data: Analysis data from the workflow
|
|
139
|
+
doc_type: Type of documentation to generate
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
Generated documentation content
|
|
143
|
+
"""
|
|
144
|
+
if not self.current_context:
|
|
145
|
+
logger.warning("No mode context, falling back to standard generation")
|
|
146
|
+
return f"# {doc_type.title()}\n\nNo mode context available."
|
|
147
|
+
|
|
148
|
+
# Generate based on mode
|
|
149
|
+
if self.current_context.mode == DocumentationMode.AUTO:
|
|
150
|
+
docs = await self.handler.run_auto_mode(self.current_context)
|
|
151
|
+
elif self.current_context.mode == DocumentationMode.HYBRID:
|
|
152
|
+
docs = await self.handler.run_hybrid_mode(self.current_context)
|
|
153
|
+
elif self.current_context.mode == DocumentationMode.INTERACTIVE:
|
|
154
|
+
docs = await self.handler.run_interactive_mode(self.current_context)
|
|
155
|
+
else:
|
|
156
|
+
return f"# {doc_type.title()}\n\nUnsupported mode."
|
|
157
|
+
|
|
158
|
+
# Map doc_type to our generated files
|
|
159
|
+
type_mapping = {
|
|
160
|
+
"overview": "README.md",
|
|
161
|
+
"architecture": "ARCHITECTURE.md",
|
|
162
|
+
"api": "API.md",
|
|
163
|
+
"setup": "README.md", # Part of README
|
|
164
|
+
"requirements": "REQUIREMENTS_TRACING.md",
|
|
165
|
+
"insights": "EXPLORATION_INSIGHTS.md"
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
filename = type_mapping.get(doc_type, "README.md")
|
|
169
|
+
return docs.get(filename, f"# {doc_type.title()}\n\nContent not available.")
|
|
170
|
+
|
|
171
|
+
async def search_code_with_context(
|
|
172
|
+
self,
|
|
173
|
+
query: str,
|
|
174
|
+
include_context: bool = True
|
|
175
|
+
) -> Dict[str, Any]:
|
|
176
|
+
"""
|
|
177
|
+
Search code and optionally external context.
|
|
178
|
+
|
|
179
|
+
This can be used by the existing workflow to find relevant
|
|
180
|
+
code and context for specific documentation sections.
|
|
181
|
+
|
|
182
|
+
Args:
|
|
183
|
+
query: Search query
|
|
184
|
+
include_context: Whether to search external context too
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
Search results from code and context
|
|
188
|
+
"""
|
|
189
|
+
if not self.current_context or not self.current_context.searcher:
|
|
190
|
+
return {"code_results": [], "context_results": []}
|
|
191
|
+
|
|
192
|
+
# Search code
|
|
193
|
+
code_results = self.current_context.searcher.search(query, limit=5)
|
|
194
|
+
|
|
195
|
+
# Search context if available and requested
|
|
196
|
+
context_results = []
|
|
197
|
+
if include_context and self.current_context.context_manager:
|
|
198
|
+
context_items = self.current_context.context_manager.search_context(query, limit=3)
|
|
199
|
+
context_results = [
|
|
200
|
+
{
|
|
201
|
+
"type": item.type,
|
|
202
|
+
"summary": item.get_summary(),
|
|
203
|
+
"source": item.source,
|
|
204
|
+
"relevance": score
|
|
205
|
+
}
|
|
206
|
+
for item, score in context_items
|
|
207
|
+
]
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
"code_results": [
|
|
211
|
+
{
|
|
212
|
+
"file": r.file_path,
|
|
213
|
+
"lines": f"{r.start_line}-{r.end_line}",
|
|
214
|
+
"content": r.content[:200],
|
|
215
|
+
"score": r.combined_score
|
|
216
|
+
}
|
|
217
|
+
for r in code_results
|
|
218
|
+
],
|
|
219
|
+
"context_results": context_results
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
def get_mode_status(self) -> Dict[str, Any]:
|
|
223
|
+
"""
|
|
224
|
+
Get the current status of the mode handler.
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
Status information
|
|
228
|
+
"""
|
|
229
|
+
if not self.current_context:
|
|
230
|
+
return {
|
|
231
|
+
"initialized": False,
|
|
232
|
+
"mode": None
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return {
|
|
236
|
+
"initialized": True,
|
|
237
|
+
"mode": self.current_context.mode.value,
|
|
238
|
+
"repository": self.current_context.repository_path,
|
|
239
|
+
"has_context": self.current_context.context_manager is not None,
|
|
240
|
+
"context_items": self.current_context.context_manager.total_items
|
|
241
|
+
if self.current_context.context_manager else 0,
|
|
242
|
+
"qa_count": len(self.current_context.qa_history),
|
|
243
|
+
"exploration_complete": self.current_context.exploration_complete,
|
|
244
|
+
"docs_generated": len(self.current_context.generated_docs)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
# Global instance for use by agentic_client_langgraph.py
|
|
249
|
+
_mode_integration = None
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def get_mode_integration() -> AgenticModeIntegration:
|
|
253
|
+
"""
|
|
254
|
+
Get or create the global mode integration instance.
|
|
255
|
+
|
|
256
|
+
Returns:
|
|
257
|
+
The mode integration instance
|
|
258
|
+
"""
|
|
259
|
+
global _mode_integration
|
|
260
|
+
if _mode_integration is None:
|
|
261
|
+
_mode_integration = AgenticModeIntegration()
|
|
262
|
+
return _mode_integration
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
async def analyze_with_mode(
|
|
266
|
+
repository_path: str,
|
|
267
|
+
mode: str = "auto",
|
|
268
|
+
**kwargs
|
|
269
|
+
) -> Dict[str, Any]:
|
|
270
|
+
"""
|
|
271
|
+
Convenience function for analyzing with a specific mode.
|
|
272
|
+
|
|
273
|
+
This can be called directly from agentic_client_langgraph.py.
|
|
274
|
+
|
|
275
|
+
Args:
|
|
276
|
+
repository_path: Path to repository
|
|
277
|
+
mode: Documentation mode
|
|
278
|
+
**kwargs: Additional arguments (context_files, jira_config)
|
|
279
|
+
|
|
280
|
+
Returns:
|
|
281
|
+
Analysis results
|
|
282
|
+
"""
|
|
283
|
+
integration = get_mode_integration()
|
|
284
|
+
return await integration.analyze_repository_with_mode(
|
|
285
|
+
repository_path=repository_path,
|
|
286
|
+
mode=mode,
|
|
287
|
+
**kwargs
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
async def generate_with_mode(
|
|
292
|
+
analysis_data: Dict[str, Any],
|
|
293
|
+
doc_type: str = "overview"
|
|
294
|
+
) -> str:
|
|
295
|
+
"""
|
|
296
|
+
Convenience function for generating documentation with current mode.
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
analysis_data: Analysis data
|
|
300
|
+
doc_type: Documentation type
|
|
301
|
+
|
|
302
|
+
Returns:
|
|
303
|
+
Generated documentation
|
|
304
|
+
"""
|
|
305
|
+
integration = get_mode_integration()
|
|
306
|
+
return await integration.generate_documentation_with_mode(
|
|
307
|
+
analysis_data=analysis_data,
|
|
308
|
+
doc_type=doc_type
|
|
309
|
+
)
|