codewiki-plus 5.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.
Files changed (134) hide show
  1. codewiki/__init__.py +13 -0
  2. codewiki/__main__.py +8 -0
  3. codewiki/cli/__init__.py +4 -0
  4. codewiki/cli/adapters/__init__.py +4 -0
  5. codewiki/cli/adapters/doc_generator.py +351 -0
  6. codewiki/cli/commands/__init__.py +4 -0
  7. codewiki/cli/commands/config.py +845 -0
  8. codewiki/cli/commands/generate.py +608 -0
  9. codewiki/cli/config_manager.py +333 -0
  10. codewiki/cli/git_manager.py +227 -0
  11. codewiki/cli/html_generator.py +286 -0
  12. codewiki/cli/main.py +78 -0
  13. codewiki/cli/models/__init__.py +4 -0
  14. codewiki/cli/models/config.py +280 -0
  15. codewiki/cli/models/job.py +156 -0
  16. codewiki/cli/utils/__init__.py +4 -0
  17. codewiki/cli/utils/api_errors.py +140 -0
  18. codewiki/cli/utils/errors.py +113 -0
  19. codewiki/cli/utils/fs.py +190 -0
  20. codewiki/cli/utils/instructions.py +179 -0
  21. codewiki/cli/utils/logging.py +85 -0
  22. codewiki/cli/utils/progress.py +222 -0
  23. codewiki/cli/utils/repo_validator.py +210 -0
  24. codewiki/cli/utils/validation.py +251 -0
  25. codewiki/mcp/__init__.py +6 -0
  26. codewiki/mcp/cache.py +1419 -0
  27. codewiki/mcp/cbm_client.py +356 -0
  28. codewiki/mcp/prompts.py +862 -0
  29. codewiki/mcp/registry.py +1463 -0
  30. codewiki/mcp/resources.py +266 -0
  31. codewiki/mcp/server.py +178 -0
  32. codewiki/mcp/session.py +197 -0
  33. codewiki/mcp/tools/__init__.py +6 -0
  34. codewiki/mcp/tools/agents_md.py +290 -0
  35. codewiki/mcp/tools/analysis.py +908 -0
  36. codewiki/mcp/tools/batch_ingest.py +135 -0
  37. codewiki/mcp/tools/cbm_integration.py +210 -0
  38. codewiki/mcp/tools/close_session.py +211 -0
  39. codewiki/mcp/tools/code_reader.py +72 -0
  40. codewiki/mcp/tools/component_list.py +161 -0
  41. codewiki/mcp/tools/cross_service.py +155 -0
  42. codewiki/mcp/tools/crosslink.py +222 -0
  43. codewiki/mcp/tools/doc_writer.py +1065 -0
  44. codewiki/mcp/tools/file_param.py +58 -0
  45. codewiki/mcp/tools/file_viewer.py +138 -0
  46. codewiki/mcp/tools/html_export.py +197 -0
  47. codewiki/mcp/tools/impact.py +244 -0
  48. codewiki/mcp/tools/issue_tracker.py +149 -0
  49. codewiki/mcp/tools/knowledge_loop.py +1211 -0
  50. codewiki/mcp/tools/legacy_tools.py +205 -0
  51. codewiki/mcp/tools/module_tree.py +194 -0
  52. codewiki/mcp/tools/page_router.py +292 -0
  53. codewiki/mcp/tools/prompt_server.py +905 -0
  54. codewiki/mcp/tools/reading_guide.py +130 -0
  55. codewiki/mcp/tools/schema_generator.py +330 -0
  56. codewiki/mcp/tools/source_ingest.py +350 -0
  57. codewiki/mcp/tools/wiki_index.py +405 -0
  58. codewiki/mcp/tools/wiki_lint.py +1002 -0
  59. codewiki/mcp/tools/wiki_search.py +338 -0
  60. codewiki/mcp/tools/workspace_analyzer.py +351 -0
  61. codewiki/mcp/tools/workspace_result.py +109 -0
  62. codewiki/mcp/workspace.py +151 -0
  63. codewiki/py.typed +2 -0
  64. codewiki/run_web_app.py +16 -0
  65. codewiki/src/__init__.py +2 -0
  66. codewiki/src/be/__init__.py +2 -0
  67. codewiki/src/be/agent_tools/__init__.py +2 -0
  68. codewiki/src/be/agent_tools/deps.py +17 -0
  69. codewiki/src/be/agent_tools/generate_sub_module_documentations.py +98 -0
  70. codewiki/src/be/agent_tools/read_code_components.py +22 -0
  71. codewiki/src/be/agent_tools/str_replace_editor.py +815 -0
  72. codewiki/src/be/backend.py +67 -0
  73. codewiki/src/be/caw_backend.py +325 -0
  74. codewiki/src/be/caw_toolkit.py +316 -0
  75. codewiki/src/be/cluster_modules.py +191 -0
  76. codewiki/src/be/dependency_analyzer/__init__.py +21 -0
  77. codewiki/src/be/dependency_analyzer/analysis/__init__.py +1 -0
  78. codewiki/src/be/dependency_analyzer/analysis/analysis_service.py +371 -0
  79. codewiki/src/be/dependency_analyzer/analysis/call_graph_analyzer.py +869 -0
  80. codewiki/src/be/dependency_analyzer/analysis/cloning.py +259 -0
  81. codewiki/src/be/dependency_analyzer/analysis/cross_service_matcher.py +241 -0
  82. codewiki/src/be/dependency_analyzer/analysis/infra_scanner.py +240 -0
  83. codewiki/src/be/dependency_analyzer/analysis/repo_analyzer.py +128 -0
  84. codewiki/src/be/dependency_analyzer/analysis/service_detector.py +581 -0
  85. codewiki/src/be/dependency_analyzer/analysis/topology_visualizer.py +123 -0
  86. codewiki/src/be/dependency_analyzer/analyzers/__init__.py +1 -0
  87. codewiki/src/be/dependency_analyzer/analyzers/c.py +215 -0
  88. codewiki/src/be/dependency_analyzer/analyzers/cpp.py +676 -0
  89. codewiki/src/be/dependency_analyzer/analyzers/csharp.py +297 -0
  90. codewiki/src/be/dependency_analyzer/analyzers/go.py +557 -0
  91. codewiki/src/be/dependency_analyzer/analyzers/java.py +538 -0
  92. codewiki/src/be/dependency_analyzer/analyzers/javascript.py +705 -0
  93. codewiki/src/be/dependency_analyzer/analyzers/kotlin.py +505 -0
  94. codewiki/src/be/dependency_analyzer/analyzers/php.py +598 -0
  95. codewiki/src/be/dependency_analyzer/analyzers/python.py +266 -0
  96. codewiki/src/be/dependency_analyzer/analyzers/typescript.py +981 -0
  97. codewiki/src/be/dependency_analyzer/ast_parser.py +177 -0
  98. codewiki/src/be/dependency_analyzer/dependency_graphs_builder.py +108 -0
  99. codewiki/src/be/dependency_analyzer/models/__init__.py +1 -0
  100. codewiki/src/be/dependency_analyzer/models/analysis.py +23 -0
  101. codewiki/src/be/dependency_analyzer/models/core.py +67 -0
  102. codewiki/src/be/dependency_analyzer/models/cross_service.py +64 -0
  103. codewiki/src/be/dependency_analyzer/topo_sort.py +597 -0
  104. codewiki/src/be/dependency_analyzer/utils/__init__.py +1 -0
  105. codewiki/src/be/dependency_analyzer/utils/external_symbols.py +393 -0
  106. codewiki/src/be/dependency_analyzer/utils/logging_config.py +143 -0
  107. codewiki/src/be/dependency_analyzer/utils/path_canonicalizer.py +61 -0
  108. codewiki/src/be/dependency_analyzer/utils/patterns.py +694 -0
  109. codewiki/src/be/dependency_analyzer/utils/security.py +83 -0
  110. codewiki/src/be/documentation_generator.py +383 -0
  111. codewiki/src/be/llm_services.py +290 -0
  112. codewiki/src/be/main.py +66 -0
  113. codewiki/src/be/prompt_template.py +670 -0
  114. codewiki/src/be/pydantic_ai_backend.py +128 -0
  115. codewiki/src/be/utils.py +281 -0
  116. codewiki/src/config.py +271 -0
  117. codewiki/src/fe/__init__.py +26 -0
  118. codewiki/src/fe/background_worker.py +256 -0
  119. codewiki/src/fe/cache_manager.py +119 -0
  120. codewiki/src/fe/config.py +51 -0
  121. codewiki/src/fe/github_processor.py +93 -0
  122. codewiki/src/fe/models.py +55 -0
  123. codewiki/src/fe/routes.py +300 -0
  124. codewiki/src/fe/template_utils.py +114 -0
  125. codewiki/src/fe/templates.py +680 -0
  126. codewiki/src/fe/visualise_docs.py +269 -0
  127. codewiki/src/fe/web_app.py +133 -0
  128. codewiki/src/utils.py +46 -0
  129. codewiki/templates/github_pages/viewer_template.html +643 -0
  130. codewiki_plus-5.1.0.dist-info/METADATA +887 -0
  131. codewiki_plus-5.1.0.dist-info/RECORD +134 -0
  132. codewiki_plus-5.1.0.dist-info/WHEEL +5 -0
  133. codewiki_plus-5.1.0.dist-info/entry_points.txt +2 -0
  134. codewiki_plus-5.1.0.dist-info/top_level.txt +1 -0
codewiki/__init__.py ADDED
@@ -0,0 +1,13 @@
1
+ """
2
+ CodeWiki: Transform codebases into comprehensive documentation using AI-powered analysis.
3
+
4
+ This package provides a CLI tool for generating documentation from code repositories,
5
+ and an MCP server for IDE-driven documentation generation.
6
+ """
7
+
8
+ __version__ = "5.1.0"
9
+ __author__ = "CodeWiki Contributors"
10
+ __license__ = "MIT"
11
+
12
+ __all__ = ["__version__"]
13
+
codewiki/__main__.py ADDED
@@ -0,0 +1,8 @@
1
+ """
2
+ Entry point for running codewiki as a module: python -m codewiki
3
+ """
4
+
5
+ from codewiki.cli.main import cli
6
+
7
+ if __name__ == "__main__":
8
+ cli()
@@ -0,0 +1,4 @@
1
+ """CLI module for CodeWiki."""
2
+
3
+ __all__ = []
4
+
@@ -0,0 +1,4 @@
1
+ """Adapters for integrating with backend modules."""
2
+
3
+ __all__ = []
4
+
@@ -0,0 +1,351 @@
1
+ """
2
+ CLI adapter for documentation generator backend.
3
+
4
+ This adapter wraps the existing backend documentation_generator.py
5
+ and provides CLI-specific functionality like progress reporting.
6
+ """
7
+
8
+ from pathlib import Path
9
+ from typing import Dict, Any
10
+ import time
11
+ import asyncio
12
+ import os
13
+ import logging
14
+ import sys
15
+
16
+
17
+ from codewiki.cli.utils.progress import ProgressTracker
18
+ from codewiki.cli.models.job import DocumentationJob, LLMConfig
19
+ from codewiki.cli.utils.errors import APIError
20
+
21
+ # Import backend modules
22
+ from codewiki.src.be.documentation_generator import DocumentationGenerator
23
+ from codewiki.src.config import Config as BackendConfig, set_cli_context
24
+
25
+
26
+ class CLIDocumentationGenerator:
27
+ """
28
+ CLI adapter for documentation generation with progress reporting.
29
+
30
+ This class wraps the backend documentation generator and adds
31
+ CLI-specific features like progress tracking and error handling.
32
+ """
33
+
34
+ def __init__(
35
+ self,
36
+ repo_path: Path,
37
+ output_dir: Path,
38
+ config: Dict[str, Any],
39
+ verbose: bool = False,
40
+ generate_html: bool = False,
41
+ commit_id: str = None,
42
+ ):
43
+ """
44
+ Initialize the CLI documentation generator.
45
+
46
+ Args:
47
+ repo_path: Repository path
48
+ output_dir: Output directory
49
+ config: LLM configuration
50
+ verbose: Enable verbose output
51
+ generate_html: Whether to generate HTML viewer
52
+ commit_id: Git commit SHA for incremental update tracking
53
+ """
54
+ self.repo_path = repo_path
55
+ self.output_dir = output_dir
56
+ self.config = config
57
+ self.verbose = verbose
58
+ self.generate_html = generate_html
59
+ self.commit_id = commit_id
60
+ self.progress_tracker = ProgressTracker(total_stages=5, verbose=verbose)
61
+ self.job = DocumentationJob()
62
+
63
+ # Setup job metadata
64
+ self.job.repository_path = str(repo_path)
65
+ self.job.repository_name = repo_path.name
66
+ self.job.output_directory = str(output_dir)
67
+ self.job.llm_config = LLMConfig(
68
+ main_model=config.get('main_model', ''),
69
+ cluster_model=config.get('cluster_model', ''),
70
+ base_url=config.get('base_url', '')
71
+ )
72
+
73
+ # Configure backend logging
74
+ self._configure_backend_logging()
75
+
76
+ def _configure_backend_logging(self):
77
+ """Configure backend logger for CLI use with colored output."""
78
+ from codewiki.src.be.dependency_analyzer.utils.logging_config import ColoredFormatter
79
+
80
+ # Get backend logger (parent of all backend modules)
81
+ backend_logger = logging.getLogger('codewiki.src.be')
82
+
83
+ # Remove existing handlers to avoid duplicates
84
+ backend_logger.handlers.clear()
85
+
86
+ if self.verbose:
87
+ # In verbose mode, show INFO and above
88
+ backend_logger.setLevel(logging.INFO)
89
+
90
+ # Create console handler with formatting
91
+ console_handler = logging.StreamHandler(sys.stdout)
92
+ console_handler.setLevel(logging.INFO)
93
+
94
+ # Use colored formatter for better readability
95
+ colored_formatter = ColoredFormatter()
96
+ console_handler.setFormatter(colored_formatter)
97
+
98
+ # Add handler to logger
99
+ backend_logger.addHandler(console_handler)
100
+ else:
101
+ # In non-verbose mode, suppress backend logs (use WARNING level to hide INFO/DEBUG)
102
+ backend_logger.setLevel(logging.WARNING)
103
+
104
+ # Create console handler for warnings and errors only
105
+ console_handler = logging.StreamHandler(sys.stderr)
106
+ console_handler.setLevel(logging.WARNING)
107
+
108
+ # Use colored formatter even for warnings/errors
109
+ colored_formatter = ColoredFormatter()
110
+ console_handler.setFormatter(colored_formatter)
111
+
112
+ backend_logger.addHandler(console_handler)
113
+
114
+ # Prevent propagation to root logger to avoid duplicate messages
115
+ backend_logger.propagate = False
116
+
117
+ def generate(self) -> DocumentationJob:
118
+ """
119
+ Generate documentation with progress tracking.
120
+
121
+ Returns:
122
+ Completed DocumentationJob
123
+
124
+ Raises:
125
+ APIError: If LLM API call fails
126
+ """
127
+ self.job.start()
128
+ start_time = time.time()
129
+
130
+ try:
131
+ # Set CLI context for backend
132
+ set_cli_context(True)
133
+
134
+ # Create backend config with CLI settings
135
+ backend_config = BackendConfig.from_cli(
136
+ repo_path=str(self.repo_path),
137
+ output_dir=str(self.output_dir),
138
+ llm_base_url=self.config.get('base_url'),
139
+ llm_api_key=self.config.get('api_key'),
140
+ main_model=self.config.get('main_model'),
141
+ cluster_model=self.config.get('cluster_model'),
142
+ fallback_model=self.config.get('fallback_model'),
143
+ provider=self.config.get('provider', 'openai-compatible'),
144
+ aws_region=self.config.get('aws_region', 'us-east-1'),
145
+ max_tokens=self.config.get('max_tokens', 32768),
146
+ max_token_per_module=self.config.get('max_token_per_module', 36369),
147
+ max_token_per_leaf_module=self.config.get('max_token_per_leaf_module', 16000),
148
+ max_depth=self.config.get('max_depth', 3),
149
+ agent_instructions=self.config.get('agent_instructions')
150
+ )
151
+
152
+ # Run backend documentation generation
153
+ asyncio.run(self._run_backend_generation(backend_config))
154
+
155
+ # Stage 4: HTML Generation (optional)
156
+ if self.generate_html:
157
+ self._run_html_generation()
158
+
159
+ # Stage 5: Finalization (metadata already created by backend)
160
+ self._finalize_job()
161
+
162
+ # Complete job
163
+ generation_time = time.time() - start_time
164
+ self.job.complete()
165
+
166
+ return self.job
167
+
168
+ except APIError as e:
169
+ self.job.fail(str(e))
170
+ raise
171
+ except Exception as e:
172
+ self.job.fail(str(e))
173
+ raise
174
+
175
+ async def _run_backend_generation(self, backend_config: BackendConfig):
176
+ """Run the backend documentation generation with progress tracking."""
177
+
178
+ # Stage 1: Dependency Analysis
179
+ self.progress_tracker.start_stage(1, "Dependency Analysis")
180
+ if self.verbose:
181
+ self.progress_tracker.update_stage(0.2, "Initializing dependency analyzer...")
182
+
183
+ # Create documentation generator
184
+ doc_generator = DocumentationGenerator(backend_config, commit_id=self.commit_id)
185
+
186
+ if self.verbose:
187
+ self.progress_tracker.update_stage(0.5, "Parsing source files...")
188
+
189
+ # Build dependency graph
190
+ try:
191
+ components, leaf_nodes, _routes = doc_generator.graph_builder.build_dependency_graph()
192
+ self.job.statistics.total_files_analyzed = len(components)
193
+ self.job.statistics.leaf_nodes = len(leaf_nodes)
194
+
195
+ if self.verbose:
196
+ self.progress_tracker.update_stage(0.8, f"Analyzed {len(components)} files, found {len(leaf_nodes)} leaf nodes")
197
+ # Log individual files analyzed
198
+ for comp_name in sorted(components.keys())[:20]:
199
+ self.progress_tracker.update_stage(0.9, f" File: {comp_name}")
200
+ if len(components) > 20:
201
+ self.progress_tracker.update_stage(0.9, f" ... and {len(components) - 20} more files")
202
+ except Exception as e:
203
+ raise APIError(f"Dependency analysis failed: {e}")
204
+
205
+ self.progress_tracker.complete_stage()
206
+
207
+ # Stage 2: Module Clustering
208
+ self.progress_tracker.start_stage(2, "Module Clustering")
209
+ if self.verbose:
210
+ self.progress_tracker.update_stage(0.5, "Clustering modules with LLM...")
211
+
212
+ # Import clustering function
213
+ from codewiki.src.be.cluster_modules import (
214
+ cluster_modules,
215
+ get_clustering_input_token_count,
216
+ )
217
+ from codewiki.src.utils import file_manager
218
+ from codewiki.src.config import FIRST_MODULE_TREE_FILENAME, MODULE_TREE_FILENAME, meta_resolve
219
+
220
+ working_dir = str(self.output_dir.absolute())
221
+ file_manager.ensure_directory(working_dir)
222
+ first_module_tree_path = meta_resolve(working_dir, FIRST_MODULE_TREE_FILENAME)
223
+ module_tree_path = meta_resolve(working_dir, MODULE_TREE_FILENAME)
224
+
225
+ try:
226
+ if os.path.exists(first_module_tree_path):
227
+ module_tree = file_manager.load_json(first_module_tree_path)
228
+ if self.verbose:
229
+ self.progress_tracker.update_stage(0.5, "Loaded cached module tree")
230
+ else:
231
+ if self.verbose:
232
+ clustering_tokens = get_clustering_input_token_count(
233
+ leaf_nodes, components
234
+ )
235
+ self.progress_tracker.update_stage(
236
+ 0.3,
237
+ (
238
+ f"Preparing {len(leaf_nodes)} leaf nodes for clustering "
239
+ f"({clustering_tokens} tokens, threshold "
240
+ f"{backend_config.max_token_per_module})"
241
+ ),
242
+ )
243
+ if clustering_tokens <= backend_config.max_token_per_module:
244
+ self.progress_tracker.update_stage(
245
+ 0.4,
246
+ "Skipping LLM clustering; selected leaf nodes fit within the module token threshold",
247
+ )
248
+ else:
249
+ self.progress_tracker.update_stage(
250
+ 0.4,
251
+ "Clustering modules with LLM...",
252
+ )
253
+ cluster_model = backend_config.cluster_model or None
254
+ module_tree = cluster_modules(
255
+ leaf_nodes,
256
+ components,
257
+ backend_config,
258
+ completer=lambda p: doc_generator.backend.complete(p, model=cluster_model),
259
+ )
260
+ file_manager.save_json(module_tree, first_module_tree_path)
261
+
262
+ file_manager.save_json(module_tree, module_tree_path)
263
+ self.job.module_count = len(module_tree)
264
+
265
+ if self.verbose:
266
+ if len(module_tree) == 0:
267
+ self.progress_tracker.update_stage(
268
+ 1.0,
269
+ "Created 0 modules; continuing in whole-repository documentation mode",
270
+ )
271
+ else:
272
+ self.progress_tracker.update_stage(
273
+ 1.0,
274
+ f"Created {len(module_tree)} modules",
275
+ )
276
+ for mod_name in sorted(module_tree.keys()):
277
+ file_count = len(module_tree[mod_name]) if isinstance(module_tree[mod_name], list) else "?"
278
+ self.progress_tracker.update_stage(1.0, f" Module: {mod_name} ({file_count} files)")
279
+ except Exception as e:
280
+ raise APIError(f"Module clustering failed: {e}")
281
+
282
+ self.progress_tracker.complete_stage()
283
+
284
+ # Stage 3: Documentation Generation
285
+ self.progress_tracker.start_stage(3, "Documentation Generation")
286
+ if self.verbose:
287
+ self.progress_tracker.update_stage(0.1, "Generating module documentation...")
288
+
289
+ try:
290
+ if self.verbose:
291
+ self.progress_tracker.update_stage(0.2, f"Generating documentation for {self.job.module_count} modules...")
292
+
293
+ # Run the actual documentation generation
294
+ await doc_generator.generate_module_documentation(components, leaf_nodes)
295
+
296
+ if self.verbose:
297
+ self.progress_tracker.update_stage(0.9, "Creating repository overview...")
298
+
299
+ # Create metadata
300
+ doc_generator.create_documentation_metadata(working_dir, components, len(leaf_nodes))
301
+
302
+ # Collect generated files
303
+ for file_path in os.listdir(working_dir):
304
+ if file_path.endswith('.md') or file_path.endswith('.json'):
305
+ self.job.files_generated.append(file_path)
306
+
307
+ except Exception as e:
308
+ raise APIError(f"Documentation generation failed: {e}")
309
+
310
+ self.progress_tracker.complete_stage()
311
+
312
+ def _run_html_generation(self):
313
+ """Run HTML generation stage."""
314
+ self.progress_tracker.start_stage(4, "HTML Generation")
315
+
316
+ from codewiki.cli.html_generator import HTMLGenerator
317
+
318
+ # Generate HTML
319
+ html_generator = HTMLGenerator()
320
+
321
+ if self.verbose:
322
+ self.progress_tracker.update_stage(0.3, "Loading module tree and metadata...")
323
+
324
+ repo_info = html_generator.detect_repository_info(self.repo_path)
325
+
326
+ # Generate HTML with auto-loading of module_tree and metadata from docs_dir
327
+ output_path = self.output_dir / "index.html"
328
+ html_generator.generate(
329
+ output_path=output_path,
330
+ title=repo_info['name'],
331
+ repository_url=repo_info['url'],
332
+ github_pages_url=repo_info['github_pages_url'],
333
+ docs_dir=self.output_dir # Auto-load module_tree and metadata from here
334
+ )
335
+
336
+ self.job.files_generated.append("index.html")
337
+
338
+ if self.verbose:
339
+ self.progress_tracker.update_stage(1.0, "Generated index.html")
340
+
341
+ self.progress_tracker.complete_stage()
342
+
343
+ def _finalize_job(self):
344
+ """Finalize the job (metadata already created by backend)."""
345
+ # Just verify metadata exists
346
+ from codewiki.src.config import meta_join
347
+ metadata_path = Path(meta_join(self.output_dir, "metadata.json"))
348
+ if not metadata_path.exists():
349
+ # Create our own if backend didn't
350
+ with open(metadata_path, 'w') as f:
351
+ f.write(self.job.to_json())
@@ -0,0 +1,4 @@
1
+ """CLI command implementations."""
2
+
3
+ __all__ = []
4
+