code-compass-cli 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.
@@ -0,0 +1,46 @@
1
+ Metadata-Version: 2.4
2
+ Name: code-compass-cli
3
+ Version: 0.1.0
4
+ Summary: A Python CLI tool for intelligent code analysis and navigation
5
+ Home-page: https://github.com/techwhiz/code-compass
6
+ Author: CodeCompass Team
7
+ Author-email: CodeCompass Team <support@codecompass.dev>
8
+ License: MIT
9
+ Project-URL: Homepage, https://github.com/techwhiz/code-compass
10
+ Project-URL: Documentation, https://github.com/techwhiz/code-compass#readme
11
+ Project-URL: Repository, https://github.com/techwhiz/code-compass
12
+ Project-URL: Bug Tracker, https://github.com/techwhiz/code-compass/issues
13
+ Keywords: code-analysis,code-navigation,code-quality,static-analysis,cli,python,security,performance
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Environment :: Console
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Natural Language :: English
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.7
22
+ Classifier: Programming Language :: Python :: 3.8
23
+ Classifier: Programming Language :: Python :: 3.9
24
+ Classifier: Programming Language :: Python :: 3.10
25
+ Classifier: Programming Language :: Python :: 3.11
26
+ Classifier: Programming Language :: Python :: 3.12
27
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
28
+ Classifier: Topic :: Utilities
29
+ Requires-Python: >=3.7
30
+ Description-Content-Type: text/markdown
31
+ Requires-Dist: click>=8.1.0
32
+ Requires-Dist: rich>=13.0.0
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest>=7.0; extra == "dev"
35
+ Requires-Dist: pytest-cov>=3.0; extra == "dev"
36
+ Requires-Dist: flake8>=4.0; extra == "dev"
37
+ Requires-Dist: black>=22.0; extra == "dev"
38
+ Requires-Dist: mypy>=0.950; extra == "dev"
39
+ Provides-Extra: docs
40
+ Requires-Dist: sphinx>=4.0; extra == "docs"
41
+ Requires-Dist: sphinx-rtd-theme>=1.0; extra == "docs"
42
+ Dynamic: author
43
+ Dynamic: home-page
44
+ Dynamic: requires-python
45
+
46
+ # code-compass
@@ -0,0 +1,31 @@
1
+ src/__init__.py,sha256=XGy3Yc6rmb-_q05j0fzZvBC2zJLuWr05slwkxDK9xTE,93
2
+ src/__pycache__/__init__.cpython-313.pyc,sha256=IEcu2pQZ2NHIHN7eWOKJmfLumdybVxZPTou_1BlYl3E,255
3
+ src/cli/__init__.py,sha256=TPerMu1FQSbvDIUN0aqKJCkVk4clbDrn3hT2SCDIbZU,34
4
+ src/cli/main.py,sha256=Z-KIQLImy1J8UbgQZtAPOib-QU0wmJXHIBGwCTnWb9Y,15050
5
+ src/cli/__pycache__/__init__.cpython-313.pyc,sha256=tbNWWnS7yq3BZGjpgM0KVPPn0hNW-Zo6MMLCGnA0JsM,194
6
+ src/cli/__pycache__/main.cpython-313.pyc,sha256=3J9aJ8Pcu0wYWyO5i-AzT8C0hbjnTsAgDzq9L2586YI,21573
7
+ src/docs/__init__.py,sha256=DJcV80OlqdVZe19OyYf7kIraz6UDlyQg9TG8SM8ZIzY,39
8
+ src/docs/doc_generator.py,sha256=d58SAMKhSKdvIRW4VFkeD9wVgPk30UVj8fIEUkFRiag,17826
9
+ src/docs/__pycache__/__init__.cpython-313.pyc,sha256=SlZxBpYc8zjPlQMb9jFS26hxOaQB53UFsaovx4xd6u0,200
10
+ src/docs/__pycache__/doc_generator.cpython-313.pyc,sha256=fG7xfZ0k6T2kzOvSRw9CN0_2XnJeO-xMNIQXlqFEa3Q,20455
11
+ src/quality/__init__.py,sha256=oC6QaaIgpAoh04g4dAtP97ryljAsHdYzqyYNLjg68Dc,36
12
+ src/quality/analyzer.py,sha256=fjkyOC0ATM3dn7QwYl2fNu8way0cvQVnpe31dwyQUjc,11682
13
+ src/quality/__pycache__/__init__.cpython-313.pyc,sha256=267KS5gJBtJCb8RJN_VAUQSGEqxiBbpuY_QfJnGdJ_0,200
14
+ src/quality/__pycache__/analyzer.cpython-313.pyc,sha256=9mvodhIVYCDlpxNJhdoQuHGtzlalN83ZlnO-R77w7XQ,11754
15
+ src/query/__init__.py,sha256=cBnG7wxPqcGh87L6WjnxIqtwpb5OA13s8XupH9EWnDU,38
16
+ src/query/copilot_query.py,sha256=knwMdTbG7QzqtY1bFyvAsP4M3iRvhFRSXmnAybazwt4,17990
17
+ src/query/__pycache__/__init__.cpython-313.pyc,sha256=dDHK6vyrTF68KTwdCeODALuKoiT0LYsMmH5l78Emk4g,200
18
+ src/query/__pycache__/copilot_query.cpython-313.pyc,sha256=5sK-4dUe5lWcSjetLpXTfYjLVQ4tLLnWRoYagWXK1Mo,20467
19
+ src/scanner/__init__.py,sha256=_F8EUHghATi8hiXGSoBZtuANrkebEOXuR320LmF7mhQ,34
20
+ src/scanner/repo_scanner.py,sha256=vOumUiKE0EmfkjgGelsUmJH7MziIMMHDFrA8g6iipCY,4402
21
+ src/scanner/__pycache__/__init__.cpython-313.pyc,sha256=5ta4-hZX4lgHb6RAJObKpR7nWu9X3AJWRsL_tLzx4bQ,198
22
+ src/scanner/__pycache__/repo_scanner.cpython-313.pyc,sha256=oSl-JuOMzfBTSYu0Tqjo1xCLkoy_mY1j-C-P-8nEKiw,6596
23
+ src/visualizer/__init__.py,sha256=JrDBHDMcq_hE7NCNrD25MFrEpjMCmGoxcNvv1iqPtq0,60
24
+ src/visualizer/flow_tracer.py,sha256=yviHzfXyzWAWWRYzx-W2jATDd_vHNRKAKcOAVjsuogk,9864
25
+ src/visualizer/__pycache__/__init__.cpython-313.pyc,sha256=4BfRJO1E8jCNTwROOJ2psmMCiYuQ0m0K6Ucu8ld-ToI,227
26
+ src/visualizer/__pycache__/flow_tracer.cpython-313.pyc,sha256=NKswmtaZ2JiT36AfEBToTVQMCnoSQFXIO0KQbxl90Ek,10662
27
+ code_compass_cli-0.1.0.dist-info/METADATA,sha256=ZtC1rOneto0s3Ztd3-ijupQ8tI_QRFuW42eMy-BpcM8,1929
28
+ code_compass_cli-0.1.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
29
+ code_compass_cli-0.1.0.dist-info/entry_points.txt,sha256=myMcO1H0BbBI4opXlmpaFWjgyPl4RyjGfPGSQxJpjCI,49
30
+ code_compass_cli-0.1.0.dist-info/top_level.txt,sha256=74rtVfumQlgAPzR5_2CgYN24MB0XARCg0t-gzk6gTrM,4
31
+ code_compass_cli-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ codecompass = src.cli.main:cli
@@ -0,0 +1 @@
1
+ src
src/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ """CodeCompass - Python CLI tool for code analysis and navigation."""
2
+
3
+ __version__ = "0.1.0"
Binary file
src/cli/__init__.py ADDED
@@ -0,0 +1 @@
1
+ """CLI module for CodeCompass."""
Binary file
src/cli/main.py ADDED
@@ -0,0 +1,431 @@
1
+ """Main CLI entry point for CodeCompass."""
2
+
3
+ import sys
4
+ from pathlib import Path
5
+
6
+ import click
7
+ from rich.console import Console
8
+ from rich.panel import Panel
9
+ from rich.syntax import Syntax
10
+ from rich.table import Table
11
+ from rich.tree import Tree
12
+
13
+ # Add parent directory to path for imports
14
+ sys.path.insert(0, str(Path(__file__).parent.parent.parent))
15
+
16
+ from src.scanner.repo_scanner import RepoScanner
17
+ from src.query.copilot_query import CopilotQuery
18
+ from src.visualizer.flow_tracer import FlowTracer
19
+ from src.quality.analyzer import CodeAnalyzer
20
+ from src.docs.doc_generator import DocumentationGenerator
21
+
22
+
23
+ console = Console()
24
+
25
+
26
+ @click.group()
27
+ @click.version_option()
28
+ def cli():
29
+ """CodeCompass - Navigate and analyze code with ease."""
30
+ pass
31
+
32
+
33
+ def _tree_to_rich(tree_node, max_files: int = 100) -> Tree:
34
+ """Convert TreeNode to rich Tree for display.
35
+
36
+ Args:
37
+ tree_node: The TreeNode to convert
38
+ max_files: Maximum number of files to display
39
+
40
+ Returns:
41
+ Rich Tree object
42
+ """
43
+ rich_tree = Tree(f"📁 {tree_node.name}")
44
+ _populate_rich_tree(tree_node, rich_tree, 0, max_files)
45
+ return rich_tree
46
+
47
+
48
+ def _populate_rich_tree(tree_node, rich_parent: Tree, depth: int, max_files: int, file_count: list = None) -> None:
49
+ """Recursively populate rich tree with nodes.
50
+
51
+ Args:
52
+ tree_node: Current TreeNode
53
+ rich_parent: Parent Rich Tree node
54
+ depth: Current recursion depth
55
+ max_files: Maximum files to display
56
+ file_count: List to track file count [current_count]
57
+ """
58
+ if file_count is None:
59
+ file_count = [0]
60
+
61
+ if depth > 10:
62
+ return
63
+
64
+ if file_count[0] >= max_files:
65
+ rich_parent.label += " [dim]...[/dim]"
66
+ return
67
+
68
+ for child in sorted(tree_node.children, key=lambda x: (not x.is_dir, x.name)):
69
+ if file_count[0] >= max_files:
70
+ break
71
+
72
+ file_count[0] += 1
73
+
74
+ if child.is_dir:
75
+ child_tree = rich_parent.add(f"📂 [bold]{child.name}[/bold]")
76
+ _populate_rich_tree(child, child_tree, depth + 1, max_files, file_count)
77
+ else:
78
+ # Add file with icon based on extension
79
+ icon = _get_file_icon(child.name)
80
+ rich_parent.add(f"{icon} [cyan]{child.name}[/cyan]")
81
+
82
+
83
+ def _get_file_icon(filename: str) -> str:
84
+ """Get appropriate icon for file type.
85
+
86
+ Args:
87
+ filename: The file name
88
+
89
+ Returns:
90
+ Icon string
91
+ """
92
+ ext = filename.split('.')[-1].lower() if '.' in filename else ''
93
+ icons = {
94
+ 'py': '🐍',
95
+ 'js': '📜',
96
+ 'ts': '📘',
97
+ 'json': '📋',
98
+ 'md': '📝',
99
+ 'txt': '📄',
100
+ 'yaml': '⚙️',
101
+ 'yml': '⚙️',
102
+ 'toml': '⚙️',
103
+ 'lock': '🔒',
104
+ 'git': '🔗',
105
+ 'env': '🔑',
106
+ }
107
+ return icons.get(ext, '📄')
108
+
109
+
110
+ @cli.command()
111
+ @click.argument('path', default='.', required=False)
112
+ def scan(path):
113
+ """Scan a repository for code structure."""
114
+ try:
115
+ scanner = RepoScanner(path)
116
+ result = scanner.scan()
117
+
118
+ console.print()
119
+ console.print(Panel("[bold cyan]CodeCompass Repository Scan[/bold cyan]", expand=False))
120
+ console.print(f"[bold]Path:[/bold] [yellow]{result['path']}[/yellow]")
121
+ console.print(f"[bold]Files found:[/bold] {len(result['files'])}")
122
+ console.print(f"[bold]Directories:[/bold] {len(result['directories'])}")
123
+ console.print()
124
+
125
+ # Display directory tree
126
+ rich_tree = _tree_to_rich(result['tree'], max_files=500)
127
+ console.print(rich_tree)
128
+ console.print()
129
+
130
+ console.print("[bold green]✓ Scan completed successfully[/bold green]")
131
+ except FileNotFoundError as e:
132
+ console.print(f"[bold red]✗ Error:[/bold red] {e}")
133
+ sys.exit(1)
134
+ except Exception as e:
135
+ console.print(f"[bold red]✗ Unexpected error:[/bold red] {e}")
136
+ sys.exit(1)
137
+
138
+
139
+
140
+ @cli.command()
141
+ @click.argument('query_text')
142
+ @click.argument('path', default='.', required=False)
143
+ def query(query_text, path):
144
+ """Query code with natural language."""
145
+ try:
146
+ copilot = CopilotQuery(path)
147
+
148
+ console.print()
149
+ console.print(Panel("[bold cyan]CodeCompass Query[/bold cyan]", expand=False))
150
+ console.print(f"[bold]Query:[/bold] {query_text}")
151
+ console.print(f"[dim]Path:[/dim] {path}")
152
+ console.print()
153
+
154
+ result = copilot.execute(query_text)
155
+
156
+ if result.get("results"):
157
+ console.print("[bold green]✓ Results found:[/bold green]")
158
+ console.print()
159
+
160
+ for idx, match in enumerate(result["results"], 1):
161
+ # Display file header
162
+ match_type = match.get("match_type", "Match")
163
+ file_path = match.get("file", "unknown")
164
+ console.print(f"[bold cyan][{idx}] {file_path}[/bold cyan] [dim]({match_type})[/dim]")
165
+
166
+ # Display keyword
167
+ if match.get("keyword"):
168
+ console.print(f" [yellow]Keyword:[/yellow] {match['keyword']}")
169
+
170
+ # Display content for filename/content matches
171
+ if match.get("content"):
172
+ console.print(" [bold]Code:[/bold]")
173
+ code_lines = match["content"].split("\n")
174
+ for line in code_lines[:15]: # Limit to 15 lines
175
+ console.print(f" [dim]|[/dim] {line}")
176
+ if len(code_lines) > 15:
177
+ console.print(f" [dim]... ({len(code_lines) - 15} more lines)[/dim]")
178
+
179
+ # Display definitions
180
+ if match.get("definitions"):
181
+ console.print(" [bold]Definitions:[/bold]")
182
+ for defn in match["definitions"][:3]: # Max 3 definitions
183
+ console.print(f" [green]{defn.get('type', 'definition')}[/green] at line {defn.get('line_num')}")
184
+ console.print(f" [cyan]{defn.get('name', 'unknown')}[/cyan]")
185
+ if defn.get("code"):
186
+ console.print(f" [dim]{defn['code'][:80]}[/dim]")
187
+ if defn.get("body"):
188
+ body_preview = defn['body'][:100].replace("\n", " ")
189
+ console.print(f" [dim]Body: {body_preview}...[/dim]")
190
+
191
+ # Display lines for keyword matches
192
+ if match.get("lines"):
193
+ console.print(" [bold]Matches:[/bold]")
194
+ for line_info in match["lines"][:2]: # Max 2 context blocks
195
+ console.print(f" Line {line_info.get('line_num')}:")
196
+ console.print(f" [yellow]{line_info.get('content', '')}[/yellow]")
197
+
198
+ # Display import statements
199
+ if match.get("content") and "import" in match.get("content", "").lower():
200
+ console.print(f" [bold]Import:[/bold] [dim]{match['content'][:100]}[/dim]")
201
+
202
+ console.print()
203
+
204
+ console.print(f"[dim]{result['summary']}[/dim]")
205
+ else:
206
+ console.print("[bold yellow]⚠ No results found[/bold yellow]")
207
+ console.print(f"[dim]Try searching with different keywords or longer file names[/dim]")
208
+
209
+ console.print()
210
+ except Exception as e:
211
+ console.print(f"[bold red]✗ Error:[/bold red] {e}")
212
+ sys.exit(1)
213
+
214
+
215
+
216
+ @cli.command()
217
+ @click.argument('symbol')
218
+ @click.argument('path', default='.', required=False)
219
+ def trace(symbol, path):
220
+ """Trace execution flow for a symbol."""
221
+ tracer = FlowTracer(path)
222
+
223
+ console.print()
224
+ console.print(Panel("[bold cyan]CodeCompass Flow Trace[/bold cyan]", expand=False))
225
+ console.print(f"[bold]Entry Point:[/bold] {symbol}")
226
+ console.print(f"[dim]Path:[/dim] {path}")
227
+ console.print()
228
+
229
+ result = tracer.trace(symbol)
230
+
231
+ if result["flow"]:
232
+ console.print("[bold green]✓ Execution flow traced:[/bold green]")
233
+ console.print()
234
+
235
+ # Build a rich tree for visualization
236
+ tree = Tree(f"[bold]{result['entry_point']}[/bold]")
237
+ _build_tree(tree, result["flow"])
238
+
239
+ console.print(tree)
240
+ console.print()
241
+ console.print(f"[dim]Total function calls: {result['total_calls']}[/dim]")
242
+ else:
243
+ console.print("[yellow]No execution flow found. Function not located in codebase.[/yellow]")
244
+
245
+
246
+ @cli.command()
247
+ @click.argument('path', default='.', required=False)
248
+ def analyze(path):
249
+ """Analyze code quality (security, performance, code smells)."""
250
+ analyzer = CodeAnalyzer(path)
251
+
252
+ console.print()
253
+ console.print(Panel("[bold cyan]CodeCompass Quality Analysis[/bold cyan]", expand=False))
254
+ console.print(f"[dim]Path:[/dim] {path}")
255
+ console.print()
256
+
257
+ result = analyzer.analyze()
258
+
259
+ # Display summary
260
+ total = result["total"]
261
+ critical_count = len(result["critical"])
262
+ warning_count = len(result["warning"])
263
+ info_count = len(result["info"])
264
+
265
+ console.print("[bold]Analysis Results:[/bold]")
266
+ console.print(f" [red]🔴 Critical:[/red] {critical_count}")
267
+ console.print(f" [yellow]🟡 Warnings:[/yellow] {warning_count}")
268
+ console.print(f" [blue]🔵 Info:[/blue] {info_count}")
269
+ console.print(f" [dim]Total Issues: {total}[/dim]")
270
+ console.print()
271
+
272
+ # Display critical issues
273
+ if critical_count:
274
+ console.print("[bold red]━ CRITICAL ISSUES ━[/bold red]")
275
+ for i, issue in enumerate(result["critical"], 1):
276
+ _display_issue(issue, i)
277
+
278
+ # Display warning issues
279
+ if warning_count:
280
+ console.print("[bold yellow]━ WARNINGS ━[/bold yellow]")
281
+ for i, issue in enumerate(result["warning"], 1):
282
+ _display_issue(issue, i)
283
+
284
+ # Display info issues
285
+ if info_count:
286
+ console.print("[bold blue]━ INFO ━[/bold blue]")
287
+ for i, issue in enumerate(result["info"][:5], 1): # Limit to first 5
288
+ _display_issue(issue, i)
289
+ if len(result["info"]) > 5:
290
+ console.print(f"[dim]... and {len(result['info']) - 5} more info messages[/dim]")
291
+
292
+ if total == 0:
293
+ console.print("[bold green]✓ No issues found! Code looks clean.[/bold green]")
294
+
295
+
296
+ def _display_issue(issue, index):
297
+ """Display a single issue.
298
+
299
+ Args:
300
+ issue: Issue object
301
+ index: Issue number
302
+ """
303
+ severity_color = {
304
+ "critical": "red",
305
+ "warning": "yellow",
306
+ "info": "blue",
307
+ }.get(issue.severity, "white")
308
+
309
+ console.print()
310
+ console.print(f" [{severity_color}]{index}. {issue.category.upper()}[/{severity_color}] "
311
+ f"[bold]{issue.message}[/bold]")
312
+ console.print(f" [dim]📄 {issue.file}:{issue.line}[/dim]")
313
+ console.print(f" [dim]{issue.code_snippet}[/dim]")
314
+ console.print(f" [cyan]💡 Suggestion:[/cyan] {issue.suggestion}")
315
+
316
+
317
+ def _build_tree(parent_tree, flow_node, depth=0):
318
+ """Build a rich Tree from flow data.
319
+
320
+ Args:
321
+ parent_tree: Parent Tree node
322
+ flow_node: Flow data dictionary
323
+ depth: Current depth
324
+ """
325
+ if not flow_node or depth > 5:
326
+ return
327
+
328
+ # Add definition info
329
+ if flow_node.get("file"):
330
+ label = f"[cyan]{flow_node['name']}[/cyan] [dim]({flow_node['type']})[/dim]"
331
+ label += f"\n[blue]📄 {flow_node['file']}:{flow_node['line']}[/blue]"
332
+ child = parent_tree.add(label)
333
+ else:
334
+ label = f"[dim]{flow_node['name']}[/dim] [yellow](not found)[/yellow]"
335
+ child = parent_tree.add(label)
336
+
337
+ # Add called functions
338
+ if flow_node.get("calls"):
339
+ for call in flow_node["calls"]:
340
+ call_label = f"[cyan]{call['name']}[/cyan]"
341
+ if call.get("called_from"):
342
+ call_label += f"\n[green]→ called from {call['called_from']['file']}:{call['called_from']['line']}[/green]"
343
+ sub_child = child.add(call_label)
344
+
345
+ # Recursively add children
346
+ if call.get("calls"):
347
+ for sub_call in call["calls"]:
348
+ _build_tree_node(sub_child, sub_call, depth + 1)
349
+
350
+
351
+ def _build_tree_node(parent_tree, flow_node, depth=0):
352
+ """Helper to build tree nodes recursively.
353
+
354
+ Args:
355
+ parent_tree: Parent Tree node
356
+ flow_node: Flow data dictionary
357
+ depth: Current depth
358
+ """
359
+ if not flow_node or depth > 5:
360
+ return
361
+
362
+ label = f"[cyan]{flow_node['name']}[/cyan]"
363
+ if flow_node.get("file"):
364
+ label += f" [blue]({flow_node['file']}:{flow_node['line']})[/blue]"
365
+ else:
366
+ label += " [yellow](not found)[/yellow]"
367
+
368
+ child = parent_tree.add(label)
369
+
370
+ if flow_node.get("calls"):
371
+ for call in flow_node["calls"]:
372
+ _build_tree_node(child, call, depth + 1)
373
+
374
+
375
+ @cli.command()
376
+ @click.argument('path', default='.', required=False)
377
+ def gendocs(path):
378
+ """Generate documentation for the project."""
379
+ generator = DocumentationGenerator(path)
380
+
381
+ console.print()
382
+ console.print(Panel("[bold cyan]CodeCompass Documentation Generator[/bold cyan]", expand=False))
383
+ console.print(f"[dim]Path:[/dim] {path}")
384
+ console.print()
385
+
386
+ console.print("[bold]Generating documentation...[/bold]")
387
+ console.print()
388
+
389
+ with console.status("[bold cyan]Analyzing project structure..."):
390
+ docs = generator.generate()
391
+
392
+ # Display results
393
+ console.print("[bold green]✓ Documentation generated successfully![/bold green]")
394
+ console.print()
395
+
396
+ # Show generated files
397
+ docs_path = Path(path) / "docs"
398
+ console.print("[bold]Generated Files:[/bold]")
399
+ for filename in sorted(docs.keys()):
400
+ filepath = docs_path / filename
401
+ if filepath.exists():
402
+ file_size = filepath.stat().st_size
403
+ console.print(f" [green]✓[/green] [cyan]{filename}[/cyan] ({file_size:,} bytes)")
404
+
405
+ console.print()
406
+ console.print(f"[dim]📁 Location: {docs_path.absolute()}[/dim]")
407
+ console.print()
408
+
409
+ # Display file descriptions
410
+ console.print("[bold]File Descriptions:[/bold]")
411
+ console.print()
412
+
413
+ descriptions = {
414
+ "README.md": "Project overview, features, and quick start guide",
415
+ "ARCHITECTURE.md": "Detailed architecture, module descriptions, and data flow diagrams",
416
+ "SETUP.md": "Installation instructions for different operating systems",
417
+ }
418
+
419
+ for filename, description in descriptions.items():
420
+ console.print(f" [yellow]•[/yellow] [bold]{filename}[/bold]")
421
+ console.print(f" [dim]{description}[/dim]")
422
+
423
+ console.print()
424
+ console.print("[bold cyan]Next Steps:[/bold cyan]")
425
+ console.print(f" • Review the generated documentation in: [cyan]{docs_path}[/cyan]")
426
+ console.print(" • Use the documentation for onboarding and reference")
427
+ console.print(" • Share with team members for project understanding")
428
+
429
+
430
+ if __name__ == '__main__':
431
+ cli()
src/docs/__init__.py ADDED
@@ -0,0 +1 @@
1
+ """Documentation generation module."""