ai-coding-assistant 0.5.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 (89) hide show
  1. ai_coding_assistant-0.5.0.dist-info/METADATA +226 -0
  2. ai_coding_assistant-0.5.0.dist-info/RECORD +89 -0
  3. ai_coding_assistant-0.5.0.dist-info/WHEEL +4 -0
  4. ai_coding_assistant-0.5.0.dist-info/entry_points.txt +3 -0
  5. ai_coding_assistant-0.5.0.dist-info/licenses/LICENSE +21 -0
  6. coding_assistant/__init__.py +3 -0
  7. coding_assistant/__main__.py +19 -0
  8. coding_assistant/cli/__init__.py +1 -0
  9. coding_assistant/cli/app.py +158 -0
  10. coding_assistant/cli/commands/__init__.py +19 -0
  11. coding_assistant/cli/commands/ask.py +178 -0
  12. coding_assistant/cli/commands/config.py +438 -0
  13. coding_assistant/cli/commands/diagram.py +267 -0
  14. coding_assistant/cli/commands/document.py +410 -0
  15. coding_assistant/cli/commands/explain.py +192 -0
  16. coding_assistant/cli/commands/fix.py +249 -0
  17. coding_assistant/cli/commands/index.py +162 -0
  18. coding_assistant/cli/commands/refactor.py +245 -0
  19. coding_assistant/cli/commands/search.py +182 -0
  20. coding_assistant/cli/commands/serve_docs.py +128 -0
  21. coding_assistant/cli/repl.py +381 -0
  22. coding_assistant/cli/theme.py +90 -0
  23. coding_assistant/codebase/__init__.py +1 -0
  24. coding_assistant/codebase/crawler.py +93 -0
  25. coding_assistant/codebase/parser.py +266 -0
  26. coding_assistant/config/__init__.py +25 -0
  27. coding_assistant/config/config_manager.py +615 -0
  28. coding_assistant/config/settings.py +82 -0
  29. coding_assistant/context/__init__.py +19 -0
  30. coding_assistant/context/chunker.py +443 -0
  31. coding_assistant/context/enhanced_retriever.py +322 -0
  32. coding_assistant/context/hybrid_search.py +311 -0
  33. coding_assistant/context/ranker.py +355 -0
  34. coding_assistant/context/retriever.py +119 -0
  35. coding_assistant/context/window.py +362 -0
  36. coding_assistant/documentation/__init__.py +23 -0
  37. coding_assistant/documentation/agents/__init__.py +27 -0
  38. coding_assistant/documentation/agents/coordinator.py +510 -0
  39. coding_assistant/documentation/agents/module_documenter.py +111 -0
  40. coding_assistant/documentation/agents/synthesizer.py +139 -0
  41. coding_assistant/documentation/agents/task_delegator.py +100 -0
  42. coding_assistant/documentation/decomposition/__init__.py +21 -0
  43. coding_assistant/documentation/decomposition/context_preserver.py +477 -0
  44. coding_assistant/documentation/decomposition/module_detector.py +302 -0
  45. coding_assistant/documentation/decomposition/partitioner.py +621 -0
  46. coding_assistant/documentation/generators/__init__.py +14 -0
  47. coding_assistant/documentation/generators/dataflow_generator.py +440 -0
  48. coding_assistant/documentation/generators/diagram_generator.py +511 -0
  49. coding_assistant/documentation/graph/__init__.py +13 -0
  50. coding_assistant/documentation/graph/dependency_builder.py +468 -0
  51. coding_assistant/documentation/graph/module_analyzer.py +475 -0
  52. coding_assistant/documentation/writers/__init__.py +11 -0
  53. coding_assistant/documentation/writers/markdown_writer.py +322 -0
  54. coding_assistant/embeddings/__init__.py +0 -0
  55. coding_assistant/embeddings/generator.py +89 -0
  56. coding_assistant/embeddings/store.py +187 -0
  57. coding_assistant/exceptions/__init__.py +50 -0
  58. coding_assistant/exceptions/base.py +110 -0
  59. coding_assistant/exceptions/llm.py +249 -0
  60. coding_assistant/exceptions/recovery.py +263 -0
  61. coding_assistant/exceptions/storage.py +213 -0
  62. coding_assistant/exceptions/validation.py +230 -0
  63. coding_assistant/llm/__init__.py +1 -0
  64. coding_assistant/llm/client.py +277 -0
  65. coding_assistant/llm/gemini_client.py +181 -0
  66. coding_assistant/llm/groq_client.py +160 -0
  67. coding_assistant/llm/prompts.py +98 -0
  68. coding_assistant/llm/together_client.py +160 -0
  69. coding_assistant/operations/__init__.py +13 -0
  70. coding_assistant/operations/differ.py +369 -0
  71. coding_assistant/operations/generator.py +347 -0
  72. coding_assistant/operations/linter.py +430 -0
  73. coding_assistant/operations/validator.py +406 -0
  74. coding_assistant/storage/__init__.py +9 -0
  75. coding_assistant/storage/database.py +363 -0
  76. coding_assistant/storage/session.py +231 -0
  77. coding_assistant/utils/__init__.py +31 -0
  78. coding_assistant/utils/cache.py +477 -0
  79. coding_assistant/utils/hardware.py +132 -0
  80. coding_assistant/utils/keystore.py +206 -0
  81. coding_assistant/utils/logger.py +32 -0
  82. coding_assistant/utils/progress.py +311 -0
  83. coding_assistant/validation/__init__.py +13 -0
  84. coding_assistant/validation/files.py +305 -0
  85. coding_assistant/validation/inputs.py +335 -0
  86. coding_assistant/validation/params.py +280 -0
  87. coding_assistant/validation/sanitizers.py +243 -0
  88. coding_assistant/vcs/__init__.py +5 -0
  89. coding_assistant/vcs/git.py +269 -0
@@ -0,0 +1,267 @@
1
+ """Diagram generation command.
2
+
3
+ This module provides CLI commands for generating visual diagrams
4
+ of code structure, dependencies, and data flow.
5
+ """
6
+
7
+ from pathlib import Path
8
+ from typing import Optional
9
+ import typer
10
+ from rich.console import Console
11
+ from rich.progress import Progress, SpinnerColumn, TextColumn
12
+ from rich.panel import Panel
13
+ from rich.table import Table
14
+
15
+ from coding_assistant.documentation.graph.dependency_builder import DependencyGraphBuilder
16
+ from coding_assistant.documentation.graph.module_analyzer import ModuleAnalyzer
17
+ from coding_assistant.documentation.decomposition.partitioner import HierarchicalPartitioner
18
+ from coding_assistant.documentation.generators.diagram_generator import MermaidDiagramGenerator
19
+ from coding_assistant.documentation.generators.dataflow_generator import DataFlowGenerator
20
+ from coding_assistant.codebase.parser import CodeParser
21
+ from coding_assistant.utils.logger import get_logger
22
+
23
+ logger = get_logger(__name__)
24
+ console = Console()
25
+
26
+ # Create Typer app for diagram subcommands
27
+ diagram_app = typer.Typer(
28
+ name="diagram",
29
+ help="Generate visual diagrams of code structure",
30
+ no_args_is_help=True
31
+ )
32
+
33
+
34
+ @diagram_app.command("generate")
35
+ def generate_diagram_command(
36
+ diagram_type: str = typer.Argument(
37
+ ...,
38
+ help="Diagram type: architecture, dependency, class, dataflow"
39
+ ),
40
+ output: Optional[Path] = typer.Option(
41
+ None,
42
+ "--output",
43
+ "-o",
44
+ help="Output file (default: <type>.mmd)"
45
+ ),
46
+ codebase_path: Optional[Path] = typer.Option(
47
+ None,
48
+ "--path",
49
+ "-p",
50
+ help="Path to codebase (default: current directory)"
51
+ ),
52
+ max_nodes: int = typer.Option(
53
+ 40,
54
+ "--max-nodes",
55
+ help="Maximum nodes in graph diagrams"
56
+ ),
57
+ direction: str = typer.Option(
58
+ "TB",
59
+ "--direction",
60
+ "-d",
61
+ help="Graph direction (TB, LR, RL, BT)"
62
+ ),
63
+ ):
64
+ """
65
+ Generate a single diagram of the codebase.
66
+
67
+ Supported diagram types:
68
+ - architecture: High-level module structure
69
+ - dependency: File/module dependencies
70
+ - class: OOP structure with inheritance
71
+ - dataflow: Data movement through system
72
+
73
+ Examples:
74
+ assistant diagram generate architecture
75
+ assistant diagram generate dependency --max-nodes 30
76
+ assistant diagram generate class --output classes.mmd
77
+ """
78
+ codebase = codebase_path or Path.cwd()
79
+
80
+ console.print(Panel.fit(
81
+ f"[bold cyan]Generating {diagram_type} Diagram[/bold cyan]\\n"
82
+ f"Analyzing: {codebase}",
83
+ border_style="cyan"
84
+ ))
85
+
86
+ try:
87
+ # Build dependency graph
88
+ with Progress(
89
+ SpinnerColumn(),
90
+ TextColumn("[progress.description]{task.description}"),
91
+ console=console
92
+ ) as progress:
93
+
94
+ task1 = progress.add_task("[cyan]Building dependency graph...", total=None)
95
+ builder = DependencyGraphBuilder(codebase)
96
+ file_graph = builder.build_file_graph()
97
+ progress.update(task1, completed=True)
98
+
99
+ diagram_gen = MermaidDiagramGenerator()
100
+ dataflow_gen = DataFlowGenerator()
101
+
102
+ # Generate requested diagram type
103
+ diagram_code = None
104
+
105
+ if diagram_type == "architecture":
106
+ task2 = progress.add_task("[cyan]Detecting modules...", total=None)
107
+ analyzer = ModuleAnalyzer(file_graph)
108
+ modules = analyzer.detect_modules()
109
+ progress.update(task2, completed=True)
110
+
111
+ task3 = progress.add_task("[cyan]Creating partitions...", total=None)
112
+ file_sizes = {
113
+ node: file_graph.nodes[node].get('line_count', 0)
114
+ for node in file_graph.nodes()
115
+ }
116
+ partitioner = HierarchicalPartitioner()
117
+ partitions = partitioner.partition(file_graph, file_sizes, modules)
118
+ progress.update(task3, completed=True)
119
+
120
+ task4 = progress.add_task("[cyan]Generating architecture diagram...", total=None)
121
+ diagram_code = diagram_gen.generate_architecture_diagram(
122
+ partitions,
123
+ file_graph,
124
+ direction=direction
125
+ )
126
+ progress.update(task4, completed=True)
127
+
128
+ elif diagram_type == "dependency":
129
+ task2 = progress.add_task("[cyan]Generating dependency graph...", total=None)
130
+ diagram_code = diagram_gen.generate_dependency_graph(
131
+ file_graph,
132
+ max_nodes=max_nodes,
133
+ show_files=True
134
+ )
135
+ progress.update(task2, completed=True)
136
+
137
+ elif diagram_type == "class":
138
+ task2 = progress.add_task("[cyan]Parsing files...", total=None)
139
+ parser = CodeParser()
140
+ parsed_files = {}
141
+
142
+ sample_files = list(file_graph.nodes())[:30]
143
+ for file_path in sample_files:
144
+ try:
145
+ parsed = parser.parse_file(file_path)
146
+ parsed_files[file_path] = parsed
147
+ except Exception:
148
+ pass
149
+
150
+ progress.update(task2, completed=True)
151
+
152
+ task3 = progress.add_task("[cyan]Generating class diagram...", total=None)
153
+ diagram_code = diagram_gen.generate_class_diagram(
154
+ parsed_files,
155
+ max_classes=25
156
+ )
157
+ progress.update(task3, completed=True)
158
+
159
+ elif diagram_type == "dataflow":
160
+ task2 = progress.add_task("[cyan]Parsing files...", total=None)
161
+ parser = CodeParser()
162
+ parsed_files = {}
163
+
164
+ sample_files = list(file_graph.nodes())[:30]
165
+ for file_path in sample_files:
166
+ try:
167
+ parsed = parser.parse_file(file_path)
168
+ parsed_files[file_path] = parsed
169
+ except Exception:
170
+ pass
171
+
172
+ progress.update(task2, completed=True)
173
+
174
+ task3 = progress.add_task("[cyan]Extracting data flow...", total=None)
175
+ dataflow_info = dataflow_gen.extract_dataflow_from_parsed_files(
176
+ parsed_files,
177
+ max_entities=35
178
+ )
179
+ progress.update(task3, completed=True)
180
+
181
+ task4 = progress.add_task("[cyan]Generating dataflow diagram...", total=None)
182
+ diagram_code = dataflow_gen.generate_dataflow_diagram(
183
+ dataflow_info['entities'],
184
+ dataflow_info['transformations'],
185
+ dataflow_info['external_systems']
186
+ )
187
+ progress.update(task4, completed=True)
188
+
189
+ else:
190
+ console.print(f"[red]Error:[/red] Unknown diagram type: {diagram_type}")
191
+ console.print("[yellow]Supported types:[/yellow] architecture, dependency, class, dataflow")
192
+ raise typer.Exit(1)
193
+
194
+ # Determine output path
195
+ if output is None:
196
+ output = Path(f"{diagram_type}.mmd")
197
+
198
+ # Write diagram
199
+ output.write_text(diagram_code)
200
+
201
+ # Success message
202
+ console.print(f"\\n[green]✓[/green] Diagram generated: {output}")
203
+ console.print(f"[dim]Lines:[/dim] {len(diagram_code.splitlines())}")
204
+ console.print(f"[dim]Size:[/dim] {len(diagram_code)} chars")
205
+
206
+ # Viewing instructions
207
+ console.print("\\n[cyan]How to view:[/cyan]")
208
+ console.print(" 1. Visit https://mermaid.live")
209
+ console.print(f" 2. Copy contents of {output}")
210
+ console.print(" 3. Paste and view rendered diagram")
211
+ console.print("")
212
+
213
+ except Exception as e:
214
+ console.print(f"\\n[bold red]Error:[/bold red] {e}")
215
+ logger.exception("Diagram generation failed")
216
+ raise typer.Exit(1)
217
+
218
+
219
+ @diagram_app.command("list")
220
+ def list_diagrams_command():
221
+ """
222
+ List available diagram types and their descriptions.
223
+
224
+ Examples:
225
+ assistant diagram list
226
+ """
227
+ console.print("[bold cyan]Available Diagram Types[/bold cyan]\\n")
228
+
229
+ table = Table(show_header=True, header_style="bold magenta")
230
+ table.add_column("Type")
231
+ table.add_column("Description")
232
+ table.add_column("Best For")
233
+
234
+ table.add_row(
235
+ "architecture",
236
+ "High-level module structure",
237
+ "Understanding overall system design"
238
+ )
239
+
240
+ table.add_row(
241
+ "dependency",
242
+ "File/module dependencies",
243
+ "Finding tightly coupled components"
244
+ )
245
+
246
+ table.add_row(
247
+ "class",
248
+ "OOP structure with inheritance",
249
+ "Understanding class relationships"
250
+ )
251
+
252
+ table.add_row(
253
+ "dataflow",
254
+ "Data movement through system",
255
+ "Tracing data transformations"
256
+ )
257
+
258
+ console.print(table)
259
+
260
+ console.print("\\n[cyan]Example usage:[/cyan]")
261
+ console.print(" assistant diagram generate architecture")
262
+ console.print(" assistant diagram generate dependency --max-nodes 50")
263
+ console.print("")
264
+
265
+
266
+ # Export the Typer app
267
+ __all__ = ['diagram_app']
@@ -0,0 +1,410 @@
1
+ """Documentation generation command.
2
+
3
+ This module provides the main CLI command for generating comprehensive
4
+ repository documentation using the CodeWiki integration.
5
+ """
6
+
7
+ import asyncio
8
+ from pathlib import Path
9
+ from typing import Optional, Dict
10
+ import typer
11
+ from rich.console import Console
12
+ from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn
13
+ from rich.panel import Panel
14
+ from rich.table import Table
15
+
16
+ from coding_assistant.documentation.graph.dependency_builder import DependencyGraphBuilder
17
+ from coding_assistant.documentation.graph.module_analyzer import ModuleAnalyzer
18
+ from coding_assistant.documentation.decomposition.partitioner import HierarchicalPartitioner
19
+ from coding_assistant.documentation.decomposition.context_preserver import ContextPreserver
20
+ from coding_assistant.documentation.agents.coordinator import MultiAgentCoordinator
21
+ from coding_assistant.documentation.agents.synthesizer import DocumentationSynthesizer
22
+ from coding_assistant.documentation.generators.diagram_generator import MermaidDiagramGenerator
23
+ from coding_assistant.documentation.generators.dataflow_generator import DataFlowGenerator
24
+ from coding_assistant.codebase.parser import CodeParser
25
+ from coding_assistant.utils.logger import get_logger
26
+
27
+ logger = get_logger(__name__)
28
+ console = Console()
29
+
30
+ # Create Typer app for document subcommands
31
+ document_app = typer.Typer(
32
+ name="document",
33
+ help="Generate comprehensive documentation for the codebase",
34
+ no_args_is_help=True
35
+ )
36
+
37
+
38
+ @document_app.command("generate")
39
+ def generate_command(
40
+ output_dir: Path = typer.Option(
41
+ "./docs/generated",
42
+ "--output",
43
+ "-o",
44
+ help="Output directory for documentation"
45
+ ),
46
+ codebase_path: Optional[Path] = typer.Option(
47
+ None,
48
+ "--path",
49
+ "-p",
50
+ help="Path to codebase (default: current directory)"
51
+ ),
52
+ include_diagrams: bool = typer.Option(
53
+ True,
54
+ "--diagrams/--no-diagrams",
55
+ help="Include visual diagrams"
56
+ ),
57
+ max_agents: int = typer.Option(
58
+ 3,
59
+ "--agents",
60
+ "-a",
61
+ help="Maximum concurrent documentation agents"
62
+ ),
63
+ format_type: str = typer.Option(
64
+ "markdown",
65
+ "--format",
66
+ "-f",
67
+ help="Output format (markdown, html)"
68
+ ),
69
+ ):
70
+ """
71
+ Generate comprehensive documentation for the codebase.
72
+
73
+ This command uses the CodeWiki integration to:
74
+ - Analyze code structure and dependencies
75
+ - Partition repository into logical modules
76
+ - Generate documentation using parallel LLM agents
77
+ - Create visual diagrams (architecture, dependencies, etc.)
78
+ - Synthesize repository overview
79
+
80
+ Examples:
81
+ assistant document generate
82
+ assistant document generate --output ./docs
83
+ assistant document generate --agents 5 --no-diagrams
84
+ """
85
+ asyncio.run(_generate_documentation_async(
86
+ output_dir=output_dir,
87
+ codebase_path=codebase_path or Path.cwd(),
88
+ include_diagrams=include_diagrams,
89
+ max_agents=max_agents,
90
+ format_type=format_type
91
+ ))
92
+
93
+
94
+ async def _generate_documentation_async(
95
+ output_dir: Path,
96
+ codebase_path: Path,
97
+ include_diagrams: bool,
98
+ max_agents: int,
99
+ format_type: str
100
+ ):
101
+ """Generate documentation asynchronously."""
102
+
103
+ console.print(Panel.fit(
104
+ "[bold cyan]CodeWiki Documentation Generation[/bold cyan]\\n"
105
+ f"Analyzing: {codebase_path}",
106
+ border_style="cyan"
107
+ ))
108
+
109
+ try:
110
+ # Phase 1: Build dependency graph
111
+ console.print("\\n[bold]Phase 1: Code Analysis[/bold]")
112
+
113
+ with Progress(
114
+ SpinnerColumn(),
115
+ TextColumn("[progress.description]{task.description}"),
116
+ console=console
117
+ ) as progress:
118
+
119
+ task1 = progress.add_task("[cyan]Building dependency graph...", total=None)
120
+ builder = DependencyGraphBuilder(codebase_path)
121
+ file_graph = builder.build_file_graph()
122
+ module_graph = builder.build_module_graph(file_graph)
123
+ progress.update(task1, completed=True)
124
+
125
+ task2 = progress.add_task("[cyan]Detecting modules...", total=None)
126
+ analyzer = ModuleAnalyzer(file_graph)
127
+ modules = analyzer.detect_modules()
128
+ progress.update(task2, completed=True)
129
+
130
+ task3 = progress.add_task("[cyan]Computing metrics...", total=None)
131
+ metrics = builder.compute_metrics(file_graph)
132
+ progress.update(task3, completed=True)
133
+
134
+ console.print(f"[green]✓[/green] Analyzed {file_graph.number_of_nodes()} files, "
135
+ f"detected {len(modules)} modules\\n")
136
+
137
+ # Phase 2: Partition repository
138
+ console.print("[bold]Phase 2: Repository Partitioning[/bold]")
139
+
140
+ with Progress(
141
+ SpinnerColumn(),
142
+ TextColumn("[progress.description]{task.description}"),
143
+ console=console
144
+ ) as progress:
145
+
146
+ task1 = progress.add_task("[cyan]Partitioning repository...", total=None)
147
+
148
+ file_sizes = {
149
+ node: file_graph.nodes[node].get('line_count', 0)
150
+ for node in file_graph.nodes()
151
+ }
152
+
153
+ partitioner = HierarchicalPartitioner(
154
+ max_partition_size=2000,
155
+ min_partition_size=100,
156
+ min_cohesion=0.3
157
+ )
158
+
159
+ partitions = partitioner.partition(file_graph, file_sizes, modules)
160
+ progress.update(task1, completed=True)
161
+
162
+ task2 = progress.add_task("[cyan]Extracting context...", total=None)
163
+
164
+ preserver = ContextPreserver()
165
+ contexts = {}
166
+
167
+ for partition in partitions:
168
+ context = preserver.extract_context(partition, partitions, file_graph)
169
+ contexts[partition.name] = context
170
+
171
+ progress.update(task2, completed=True)
172
+
173
+ console.print(f"[green]✓[/green] Created {len(partitions)} partitions with architectural context\\n")
174
+
175
+ # Phase 3: Generate documentation
176
+ console.print("[bold]Phase 3: Documentation Generation[/bold]")
177
+
178
+ coordinator = MultiAgentCoordinator(
179
+ max_concurrent_agents=max_agents,
180
+ use_async=True
181
+ )
182
+
183
+ with Progress(
184
+ SpinnerColumn(),
185
+ TextColumn("[progress.description]{task.description}"),
186
+ BarColumn(),
187
+ TextColumn("[progress.percentage]{task.percentage:>3.0f}%"),
188
+ console=console
189
+ ) as progress:
190
+
191
+ task = progress.add_task(
192
+ "[cyan]Generating module documentation...",
193
+ total=len(partitions)
194
+ )
195
+
196
+ # Parse files for detailed documentation
197
+ parser = CodeParser()
198
+ parsed_files = {}
199
+
200
+ for partition in partitions:
201
+ for file_path in partition.files[:10]: # Limit files per partition
202
+ try:
203
+ parsed = parser.parse_file(file_path)
204
+ parsed_files[file_path] = parsed
205
+ except Exception as e:
206
+ logger.debug(f"Failed to parse {file_path}: {e}")
207
+
208
+ # Generate module documentation
209
+ module_docs = await coordinator.generate_documentation(
210
+ partitions,
211
+ contexts,
212
+ parsed_files
213
+ )
214
+
215
+ progress.update(task, completed=len(partitions))
216
+
217
+ stats = coordinator.get_completion_stats()
218
+ console.print(f"[green]✓[/green] Generated documentation for {stats['completed']}/{stats['total']} modules "
219
+ f"({stats['completion_rate']:.0%} success rate)\\n")
220
+
221
+ # Phase 4: Generate diagrams
222
+ diagrams = {}
223
+
224
+ if include_diagrams:
225
+ console.print("[bold]Phase 4: Diagram Generation[/bold]")
226
+
227
+ diagram_gen = MermaidDiagramGenerator()
228
+ dataflow_gen = DataFlowGenerator()
229
+
230
+ with Progress(
231
+ SpinnerColumn(),
232
+ TextColumn("[progress.description]{task.description}"),
233
+ console=console
234
+ ) as progress:
235
+
236
+ task1 = progress.add_task("[cyan]Generating architecture diagram...", total=None)
237
+ diagrams['architecture'] = diagram_gen.generate_architecture_diagram(
238
+ partitions,
239
+ file_graph,
240
+ direction="TB"
241
+ )
242
+ progress.update(task1, completed=True)
243
+
244
+ task2 = progress.add_task("[cyan]Generating dependency graph...", total=None)
245
+ diagrams['dependencies'] = diagram_gen.generate_dependency_graph(
246
+ file_graph,
247
+ max_nodes=40,
248
+ show_files=True
249
+ )
250
+ progress.update(task2, completed=True)
251
+
252
+ if parsed_files:
253
+ task3 = progress.add_task("[cyan]Generating class diagram...", total=None)
254
+ diagrams['classes'] = diagram_gen.generate_class_diagram(
255
+ parsed_files,
256
+ max_classes=20
257
+ )
258
+ progress.update(task3, completed=True)
259
+
260
+ task4 = progress.add_task("[cyan]Generating data flow diagram...", total=None)
261
+ dataflow_info = dataflow_gen.extract_dataflow_from_parsed_files(
262
+ parsed_files,
263
+ max_entities=30
264
+ )
265
+
266
+ if dataflow_info['entities'] or dataflow_info['transformations']:
267
+ diagrams['dataflow'] = dataflow_gen.generate_dataflow_diagram(
268
+ dataflow_info['entities'],
269
+ dataflow_info['transformations'],
270
+ dataflow_info['external_systems']
271
+ )
272
+ progress.update(task4, completed=True)
273
+
274
+ console.print(f"[green]✓[/green] Generated {len(diagrams)} diagrams\\n")
275
+
276
+ # Phase 5: Synthesize overview
277
+ console.print("[bold]Phase 5: Repository Overview[/bold]")
278
+
279
+ with Progress(
280
+ SpinnerColumn(),
281
+ TextColumn("[progress.description]{task.description}"),
282
+ console=console
283
+ ) as progress:
284
+
285
+ task = progress.add_task("[cyan]Synthesizing repository overview...", total=None)
286
+
287
+ synthesizer = DocumentationSynthesizer()
288
+
289
+ repo_metadata = {
290
+ 'name': codebase_path.name,
291
+ 'path': str(codebase_path),
292
+ 'total_files': file_graph.number_of_nodes(),
293
+ 'total_modules': len(modules),
294
+ 'total_partitions': len(partitions)
295
+ }
296
+
297
+ overview = await synthesizer.synthesize_overview(
298
+ module_docs,
299
+ partitions,
300
+ repo_metadata
301
+ )
302
+
303
+ progress.update(task, completed=True)
304
+
305
+ console.print(f"[green]✓[/green] Repository overview synthesized\\n")
306
+
307
+ # Phase 6: Write output
308
+ console.print("[bold]Phase 6: Writing Documentation[/bold]")
309
+
310
+ with Progress(
311
+ SpinnerColumn(),
312
+ TextColumn("[progress.description]{task.description}"),
313
+ console=console
314
+ ) as progress:
315
+
316
+ task = progress.add_task("[cyan]Writing documentation files...", total=None)
317
+
318
+ from coding_assistant.documentation.writers.markdown_writer import MarkdownWriter
319
+
320
+ writer = MarkdownWriter(output_dir)
321
+
322
+ written_files = writer.write_documentation(
323
+ overview=overview,
324
+ module_docs=module_docs,
325
+ diagrams=diagrams,
326
+ partitions=partitions,
327
+ repo_metadata=repo_metadata
328
+ )
329
+
330
+ progress.update(task, completed=True)
331
+
332
+ console.print(f"[green]✓[/green] Wrote {len(written_files)} documentation files\\n")
333
+
334
+ # Success summary
335
+ console.print("\\n" + "=" * 70)
336
+ console.print("[bold green]Documentation Generation Complete![/bold green]")
337
+ console.print("=" * 70)
338
+
339
+ summary_table = Table(show_header=False, box=None, padding=(0, 2))
340
+ summary_table.add_column("Metric", style="cyan")
341
+ summary_table.add_column("Value", style="green")
342
+
343
+ summary_table.add_row("Output Directory", str(output_dir))
344
+ summary_table.add_row("Files Analyzed", str(file_graph.number_of_nodes()))
345
+ summary_table.add_row("Modules Detected", str(len(modules)))
346
+ summary_table.add_row("Partitions Created", str(len(partitions)))
347
+ summary_table.add_row("Module Docs Generated", f"{stats['completed']}/{stats['total']}")
348
+ summary_table.add_row("Diagrams Generated", str(len(diagrams)))
349
+ summary_table.add_row("Documentation Files", str(len(written_files)))
350
+
351
+ console.print("\\n")
352
+ console.print(summary_table)
353
+
354
+ console.print(f"\\n[cyan]View documentation:[/cyan] {output_dir}/README.md")
355
+ console.print(f"[dim]Or run:[/dim] [yellow]assistant serve-docs --dir {output_dir}[/yellow]\\n")
356
+
357
+ except Exception as e:
358
+ console.print(f"\\n[bold red]Error:[/bold red] {e}")
359
+ logger.exception("Documentation generation failed")
360
+ raise typer.Exit(1)
361
+
362
+
363
+ @document_app.command("status")
364
+ def status_command(
365
+ output_dir: Path = typer.Option(
366
+ "./docs/generated",
367
+ "--output",
368
+ "-o",
369
+ help="Documentation output directory"
370
+ ),
371
+ ):
372
+ """
373
+ Show status of generated documentation.
374
+
375
+ Examples:
376
+ assistant document status
377
+ assistant document status --output ./docs
378
+ """
379
+ console.print(f"[bold cyan]Documentation Status[/bold cyan]\\n")
380
+
381
+ if not output_dir.exists():
382
+ console.print(f"[yellow]⚠[/yellow] Documentation directory does not exist: {output_dir}")
383
+ console.print(f"[dim]Run:[/dim] [cyan]assistant document generate[/cyan] to create documentation\\n")
384
+ return
385
+
386
+ # Count documentation files
387
+ md_files = list(output_dir.glob("**/*.md"))
388
+ diagram_files = list(output_dir.glob("**/*.mmd"))
389
+
390
+ status_table = Table(show_header=True, header_style="bold magenta")
391
+ status_table.add_column("Item")
392
+ status_table.add_column("Count", justify="right")
393
+
394
+ status_table.add_row("Markdown Files", str(len(md_files)))
395
+ status_table.add_row("Diagram Files", str(len(diagram_files)))
396
+ status_table.add_row("Total Files", str(len(md_files) + len(diagram_files)))
397
+
398
+ console.print(status_table)
399
+
400
+ console.print(f"\\n[cyan]Location:[/cyan] {output_dir}")
401
+
402
+ if (output_dir / "README.md").exists():
403
+ console.print(f"[green]✓[/green] Repository overview available")
404
+ console.print(f"[dim]View:[/dim] {output_dir}/README.md\\n")
405
+ else:
406
+ console.print(f"[yellow]⚠[/yellow] README.md not found\\n")
407
+
408
+
409
+ # Export the Typer app
410
+ __all__ = ['document_app']