brieflook 0.1.0__tar.gz

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 (37) hide show
  1. brieflook-0.1.0/.gitignore +40 -0
  2. brieflook-0.1.0/LICENSE +22 -0
  3. brieflook-0.1.0/PKG-INFO +69 -0
  4. brieflook-0.1.0/README.md +47 -0
  5. brieflook-0.1.0/pyproject.toml +48 -0
  6. brieflook-0.1.0/src/brieflook/__init__.py +0 -0
  7. brieflook-0.1.0/src/brieflook/__main__.py +7 -0
  8. brieflook-0.1.0/src/brieflook/cli/__init__.py +0 -0
  9. brieflook-0.1.0/src/brieflook/cli/main.py +140 -0
  10. brieflook-0.1.0/src/brieflook/core/__init__.py +0 -0
  11. brieflook-0.1.0/src/brieflook/core/index.py +41 -0
  12. brieflook-0.1.0/src/brieflook/core/index_builder.py +68 -0
  13. brieflook-0.1.0/src/brieflook/core/repository.py +38 -0
  14. brieflook-0.1.0/src/brieflook/entrypoints/__init__.py +2 -0
  15. brieflook-0.1.0/src/brieflook/entrypoints/detector.py +137 -0
  16. brieflook-0.1.0/src/brieflook/entrypoints/models.py +16 -0
  17. brieflook-0.1.0/src/brieflook/git/__init__.py +0 -0
  18. brieflook-0.1.0/src/brieflook/guide/__init__.py +0 -0
  19. brieflook-0.1.0/src/brieflook/guide/detector.py +69 -0
  20. brieflook-0.1.0/src/brieflook/guide/models.py +16 -0
  21. brieflook-0.1.0/src/brieflook/guide/rules.py +42 -0
  22. brieflook-0.1.0/src/brieflook/project/__init__.py +0 -0
  23. brieflook-0.1.0/src/brieflook/project/detector.py +233 -0
  24. brieflook-0.1.0/src/brieflook/project/models.py +36 -0
  25. brieflook-0.1.0/src/brieflook/readme/detector.py +31 -0
  26. brieflook-0.1.0/src/brieflook/readme/models.py +16 -0
  27. brieflook-0.1.0/src/brieflook/run/__init__.py +2 -0
  28. brieflook-0.1.0/src/brieflook/run/detector.py +124 -0
  29. brieflook-0.1.0/src/brieflook/run/models.py +17 -0
  30. brieflook-0.1.0/src/brieflook/structure/__init__.py +2 -0
  31. brieflook-0.1.0/src/brieflook/structure/detector.py +65 -0
  32. brieflook-0.1.0/src/brieflook/structure/models.py +17 -0
  33. brieflook-0.1.0/src/brieflook/summary/detector.py +32 -0
  34. brieflook-0.1.0/src/brieflook/summary/models.py +14 -0
  35. brieflook-0.1.0/tests/test_project_detector.py +31 -0
  36. brieflook-0.1.0/tests/test_scanner.py +14 -0
  37. brieflook-0.1.0/uv.lock +184 -0
@@ -0,0 +1,40 @@
1
+ # ----------------------------
2
+ # Python
3
+ # ----------------------------
4
+ __pycache__/
5
+ *.py[cod]
6
+ *.pyc
7
+
8
+ # ----------------------------
9
+ # Virtual environments
10
+ # ----------------------------
11
+ .venv/
12
+ venv/
13
+
14
+ # ----------------------------
15
+ # Environment variables
16
+ # ----------------------------
17
+ .env
18
+ .env.*
19
+ !.env.example
20
+
21
+ # ----------------------------
22
+ # Test & quality tool caches
23
+ # ----------------------------
24
+ .pytest_cache/
25
+ .mypy_cache/
26
+ .ruff_cache/
27
+ .coverage
28
+ htmlcov/
29
+
30
+ # ----------------------------
31
+ # IDEs
32
+ # ----------------------------
33
+ .vscode/
34
+ .idea/
35
+
36
+ # ----------------------------
37
+ # OS
38
+ # ----------------------------
39
+ .DS_Store
40
+ Thumbs.db
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nabil Khan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,69 @@
1
+ Metadata-Version: 2.4
2
+ Name: brieflook
3
+ Version: 0.1.0
4
+ Summary: Understand any repository in minutes.
5
+ Project-URL: Homepage, https://github.com/nabilkhan-01/brieflook
6
+ Project-URL: Repository, https://github.com/nabilkhan-01/brieflook
7
+ Project-URL: Issues, https://github.com/nabilkhan-01/brieflook/issues
8
+ License: MIT
9
+ License-File: LICENSE
10
+ Keywords: cli,codebase,developer-tools,onboarding,repository
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Software Development
18
+ Requires-Python: >=3.11
19
+ Requires-Dist: rich>=14.1.0
20
+ Requires-Dist: typer>=0.17.4
21
+ Description-Content-Type: text/markdown
22
+
23
+ # brieflook
24
+
25
+ > **Understand any repository in minutes.**
26
+
27
+ brieflook is an open-source developer tool that helps you understand unfamiliar codebases faster.
28
+
29
+ Instead of spending hours exploring folders, opening random files, and guessing where to start, brieflook analyzes a repository and provides a clear overview of its technologies, structure, and important entry points.
30
+
31
+ Our goal is simple:
32
+
33
+ > **Reduce repository onboarding from hours to minutes.**
34
+
35
+ ---
36
+
37
+ ## Status
38
+
39
+ 🚧 Early Development
40
+
41
+ brieflook is under active development. The current focus is building a fast, reliable repository understanding engine before expanding into deeper repository analysis.
42
+
43
+ ---
44
+
45
+ ## Vision
46
+
47
+ Every developer has experienced this moment:
48
+
49
+ - You clone a new repository.
50
+ - Hundreds of files appear.
51
+ - You don't know where to begin.
52
+ - You don't know which files matter.
53
+ - You don't know how everything fits together.
54
+
55
+ brieflook exists to remove that uncertainty.
56
+
57
+ ---
58
+
59
+ ## Project
60
+
61
+ **Name:** brieflook
62
+
63
+ **Tagline:** *Understand any repository in minutes.*
64
+
65
+ **Started:** 2 August 2026
66
+
67
+ ---
68
+
69
+ If brieflook saves you time understanding a repository, then it's doing exactly what it was built for.
@@ -0,0 +1,47 @@
1
+ # brieflook
2
+
3
+ > **Understand any repository in minutes.**
4
+
5
+ brieflook is an open-source developer tool that helps you understand unfamiliar codebases faster.
6
+
7
+ Instead of spending hours exploring folders, opening random files, and guessing where to start, brieflook analyzes a repository and provides a clear overview of its technologies, structure, and important entry points.
8
+
9
+ Our goal is simple:
10
+
11
+ > **Reduce repository onboarding from hours to minutes.**
12
+
13
+ ---
14
+
15
+ ## Status
16
+
17
+ 🚧 Early Development
18
+
19
+ brieflook is under active development. The current focus is building a fast, reliable repository understanding engine before expanding into deeper repository analysis.
20
+
21
+ ---
22
+
23
+ ## Vision
24
+
25
+ Every developer has experienced this moment:
26
+
27
+ - You clone a new repository.
28
+ - Hundreds of files appear.
29
+ - You don't know where to begin.
30
+ - You don't know which files matter.
31
+ - You don't know how everything fits together.
32
+
33
+ brieflook exists to remove that uncertainty.
34
+
35
+ ---
36
+
37
+ ## Project
38
+
39
+ **Name:** brieflook
40
+
41
+ **Tagline:** *Understand any repository in minutes.*
42
+
43
+ **Started:** 2 August 2026
44
+
45
+ ---
46
+
47
+ If brieflook saves you time understanding a repository, then it's doing exactly what it was built for.
@@ -0,0 +1,48 @@
1
+ [project]
2
+ name = "brieflook"
3
+ version = "0.1.0"
4
+ description = "Understand any repository in minutes."
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ license = { text = "MIT" }
8
+
9
+ keywords = [
10
+ "cli",
11
+ "repository",
12
+ "developer-tools",
13
+ "onboarding",
14
+ "codebase",
15
+ ]
16
+
17
+ classifiers = [
18
+ "Development Status :: 3 - Alpha",
19
+ "Intended Audience :: Developers",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Topic :: Software Development",
24
+ "Environment :: Console",
25
+ ]
26
+
27
+ dependencies = [
28
+ "rich>=14.1.0",
29
+ "typer>=0.17.4",
30
+ ]
31
+
32
+ [project.urls]
33
+ Homepage = "https://github.com/nabilkhan-01/brieflook"
34
+ Repository = "https://github.com/nabilkhan-01/brieflook"
35
+ Issues = "https://github.com/nabilkhan-01/brieflook/issues"
36
+
37
+ [project.scripts]
38
+ brieflook = "brieflook.cli.main:app"
39
+
40
+ [dependency-groups]
41
+ dev = [
42
+ "pytest>=8.4.1",
43
+ "ruff>=0.12.8",
44
+ ]
45
+
46
+ [build-system]
47
+ requires = ["hatchling"]
48
+ build-backend = "hatchling.build"
File without changes
@@ -0,0 +1,7 @@
1
+ """
2
+ Application entry point.
3
+ """
4
+
5
+ from brieflook.cli.main import app
6
+
7
+ app()
File without changes
@@ -0,0 +1,140 @@
1
+ """
2
+ CLI entry point for brieflook.
3
+
4
+ Responsibilities:
5
+ - Parse command-line arguments.
6
+ - Invoke the appropriate application services.
7
+ - Format and display results to the terminal.
8
+
9
+ This module should never contain business logic.
10
+ Repository analysis belongs in the core and project modules.
11
+ """
12
+
13
+ from pathlib import Path
14
+
15
+ import typer
16
+ from rich.console import Console
17
+ from rich.table import Table
18
+
19
+ from brieflook.project.detector import ProjectDetector
20
+ from brieflook.guide.detector import GuideDetector
21
+ from brieflook.entrypoints.detector import EntryPointDetector
22
+ from brieflook.run.detector import RunGuideDetector
23
+ from brieflook.structure.detector import ProjectStructureDetector
24
+ from brieflook.core.index_builder import RepositoryIndexBuilder
25
+
26
+ app = typer.Typer(
27
+ no_args_is_help=True,
28
+ help="Understand any repository in minutes.",
29
+ )
30
+
31
+ console = Console()
32
+
33
+
34
+ @app.command()
35
+ def scan(
36
+ path: Path = typer.Argument(
37
+ Path("."),
38
+ exists=True,
39
+ file_okay=False,
40
+ dir_okay=True,
41
+ resolve_path=True,
42
+ help="Path to the repository.",
43
+ ),
44
+ ) -> None:
45
+ """
46
+ Scan a repository.
47
+ """
48
+
49
+ detector = ProjectDetector()
50
+ project = detector.detect(path)
51
+
52
+ index = RepositoryIndexBuilder().build(path)
53
+
54
+ guide = GuideDetector().detect(index, project)
55
+
56
+ table = Table(title="Repository")
57
+
58
+ table.add_column("Property", style="cyan")
59
+ table.add_column("Value", style="green")
60
+
61
+ table.add_row("Name", path.name)
62
+ table.add_row("Language", project.language)
63
+ table.add_row("Framework", project.framework or "Unknown")
64
+ table.add_row("Package Manager", project.package_manager or "Unknown")
65
+ table.add_row("Project Type", project.project_type or "Unknown")
66
+
67
+ console.print(table)
68
+
69
+ console.print()
70
+
71
+ guide_table = Table(title="Start Here")
72
+
73
+ guide_table.add_column("#", style="cyan", justify="right")
74
+ guide_table.add_column("Path", style="green")
75
+ guide_table.add_column("Reason")
76
+
77
+ for i, item in enumerate(guide, start=1):
78
+ guide_table.add_row(
79
+ str(i),
80
+ item.path,
81
+ item.reason,
82
+ )
83
+
84
+ console.print(guide_table)
85
+
86
+ console.print()
87
+
88
+ entry_points = EntryPointDetector().detect(index)
89
+
90
+ entry_table = Table(title="Entry Points")
91
+
92
+ entry_table.add_column("#", style="cyan", justify="right")
93
+ entry_table.add_column("Path", style="green")
94
+ entry_table.add_column("Reason")
95
+
96
+ for i, ep in enumerate(entry_points, start=1):
97
+ entry_table.add_row(
98
+ str(i),
99
+ ep.path,
100
+ ep.reason,
101
+ )
102
+
103
+ console.print(entry_table)
104
+
105
+ console.print()
106
+
107
+ run_guide = RunGuideDetector().detect(project, index)
108
+
109
+ run_table = Table(title="Run Guide")
110
+
111
+ run_table.add_column("Step", style="cyan")
112
+ run_table.add_column("Command", style="green")
113
+
114
+ if run_guide.install_command:
115
+ run_table.add_row("Install", run_guide.install_command)
116
+ if run_guide.run_command:
117
+ run_table.add_row("Run", run_guide.run_command)
118
+ if run_guide.test_command:
119
+ run_table.add_row("Test", run_guide.test_command)
120
+
121
+ console.print(run_table)
122
+
123
+ console.print()
124
+
125
+ structure = ProjectStructureDetector().detect(index)
126
+
127
+ structure_table = Table(title="Project Structure")
128
+
129
+ structure_table.add_column("#", style="cyan", justify="right")
130
+ structure_table.add_column("Directory", style="green")
131
+ structure_table.add_column("Purpose")
132
+
133
+ for i, d in enumerate(structure, start=1):
134
+ structure_table.add_row(
135
+ str(i),
136
+ d.path,
137
+ d.reason,
138
+ )
139
+
140
+ console.print(structure_table)
File without changes
@@ -0,0 +1,41 @@
1
+ """
2
+ Repository index.
3
+
4
+ Responsibilities:
5
+ - Store an in-memory representation of a repository.
6
+ - Provide fast filesystem lookups.
7
+ - Avoid repeated filesystem traversal.
8
+
9
+ This module should never:
10
+ - Detect technologies.
11
+ - Generate terminal output.
12
+ - Contain business rules.
13
+ """
14
+
15
+ from dataclasses import dataclass
16
+ from pathlib import Path
17
+
18
+
19
+ @dataclass(slots=True)
20
+ class RepositoryIndex:
21
+ """
22
+ Fast lookup structure for repository contents.
23
+ """
24
+
25
+ root: Path
26
+
27
+ files: dict[str, list[Path]]
28
+ directories: dict[str, list[Path]]
29
+ extensions: dict[str, list[Path]]
30
+
31
+ def find_file(self, filename: str) -> list[Path]:
32
+ """
33
+ Return every file with the given filename.
34
+ """
35
+ return self.files.get(filename, [])
36
+
37
+ def has_file(self, filename: str) -> bool:
38
+ """
39
+ Return True if the repository contains the file.
40
+ """
41
+ return filename in self.files
@@ -0,0 +1,68 @@
1
+ """
2
+ Repository index builder.
3
+
4
+ Responsibilities:
5
+ - Traverse the repository once.
6
+ - Build a RepositoryIndex.
7
+ - Normalize filesystem information.
8
+
9
+ This module should never:
10
+ - Detect technologies.
11
+ - Rank files.
12
+ - Produce CLI output.
13
+ """
14
+
15
+ from collections import defaultdict
16
+ from pathlib import Path
17
+
18
+ from brieflook.core.index import RepositoryIndex
19
+
20
+
21
+ IGNORED_DIRECTORIES = {
22
+ ".git",
23
+ ".venv",
24
+ "__pycache__",
25
+ ".pytest_cache",
26
+ ".ruff_cache",
27
+ ".mypy_cache",
28
+ ".idea",
29
+ ".vscode",
30
+ "node_modules",
31
+ "dist",
32
+ "build",
33
+ }
34
+
35
+
36
+ class RepositoryIndexBuilder:
37
+ """
38
+ Builds a RepositoryIndex by traversing the repository once.
39
+ """
40
+
41
+ def build(self, root: Path) -> RepositoryIndex:
42
+
43
+ files: dict[str, list[Path]] = defaultdict(list)
44
+ directories: dict[str, list[Path]] = defaultdict(list)
45
+ extensions: dict[str, list[Path]] = defaultdict(list)
46
+
47
+ for item in root.rglob("*"):
48
+
49
+ if any(part in IGNORED_DIRECTORIES for part in item.parts):
50
+ continue
51
+
52
+ if item.is_file():
53
+
54
+ files[item.name].append(item)
55
+
56
+ if item.suffix:
57
+ extensions[item.suffix].append(item)
58
+
59
+ elif item.is_dir():
60
+
61
+ directories[item.name].append(item)
62
+
63
+ return RepositoryIndex(
64
+ root=root,
65
+ files=dict(files),
66
+ directories=dict(directories),
67
+ extensions=dict(extensions),
68
+ )
@@ -0,0 +1,38 @@
1
+ """
2
+ Repository domain models.
3
+
4
+ This module defines the core data structures shared across brieflook.
5
+
6
+ These models represent facts about a repository without making
7
+ assumptions or interpretations.
8
+ """
9
+
10
+ from dataclasses import dataclass
11
+ from pathlib import Path
12
+
13
+
14
+ @dataclass(slots=True)
15
+ class RepositoryFacts:
16
+ """
17
+ Raw facts collected from a repository.
18
+
19
+ Responsibilities:
20
+ - Store filesystem facts.
21
+ - Represent the current state of a repository.
22
+ - Serve as input for higher-level analysis.
23
+
24
+ This class should never:
25
+ - Detect frameworks.
26
+ - Infer project types.
27
+ - Perform filesystem scanning.
28
+ - Contain business logic.
29
+ """
30
+
31
+ name: str
32
+ root: Path
33
+
34
+ file_count: int
35
+ directory_count: int
36
+
37
+ has_git: bool
38
+ has_readme: bool
@@ -0,0 +1,137 @@
1
+ """
2
+ Application entry point detection.
3
+
4
+ Responsibilities:
5
+ - Identify real application entry points from the repository index.
6
+ - Provide a reason for each detected entry point.
7
+
8
+ This module should never:
9
+ - Traverse the filesystem.
10
+ - Generate terminal output.
11
+ """
12
+
13
+ from dataclasses import dataclass
14
+ from pathlib import Path
15
+
16
+ from brieflook.core.index import RepositoryIndex
17
+ from brieflook.entrypoints.models import EntryPoint
18
+
19
+
20
+ @dataclass(frozen=True, slots=True)
21
+ class _Rule:
22
+ filename: str
23
+ reason: str
24
+ root_only: bool = False
25
+
26
+
27
+ _RULES: list[_Rule] = [
28
+ # Python
29
+ _Rule("__main__.py", "Python package entry point."),
30
+ _Rule("main.py", "Python application entry point.", root_only=True),
31
+ _Rule("manage.py", "Django management entry point."),
32
+ _Rule("app.py", "Python application entry point.", root_only=True),
33
+ _Rule("wsgi.py", "WSGI application entry point."),
34
+ _Rule("asgi.py", "ASGI application entry point."),
35
+
36
+ # JavaScript / TypeScript
37
+ _Rule("server.js", "Node.js server entry point."),
38
+ _Rule("index.js", "JavaScript application entry point."),
39
+ _Rule("main.js", "JavaScript application entry point."),
40
+
41
+ # Next.js
42
+ _Rule("page.tsx", "Next.js application entry point."),
43
+
44
+ # Rust
45
+ _Rule("main.rs", "Rust application entry point."),
46
+
47
+ # Java
48
+ _Rule("Application.java", "Java application entry point."),
49
+ _Rule("Main.java", "Java application entry point."),
50
+ ]
51
+
52
+ # JS/TS files that are only valid inside a src/ directory.
53
+ _SRC_ONLY = {"main.ts", "main.tsx", "index.ts", "index.tsx", "main.js", "main.jsx", "index.js", "index.jsx"}
54
+
55
+ # Next.js page files and the directories they must live under.
56
+ _NEXTJS_DIRS = {"page.tsx": {"app", "pages"}}
57
+
58
+ # Next.js pages/index.tsx pattern.
59
+ _PAGES_INDEX = "index.tsx"
60
+
61
+ # Go entry point pattern: main.go inside a cmd/ tree.
62
+ _GO_ENTRY = "main.go"
63
+
64
+
65
+ class EntryPointDetector:
66
+ """
67
+ Detect application entry points from a RepositoryIndex.
68
+ """
69
+
70
+ def detect(self, index: RepositoryIndex) -> list[EntryPoint]:
71
+ results: list[EntryPoint] = []
72
+
73
+ for rule in _RULES:
74
+ matches = index.find_file(rule.filename)
75
+ for file_path in matches:
76
+ if self._matches_rule(rule, file_path, index.root):
77
+ rel = file_path.relative_to(index.root).as_posix()
78
+ results.append(EntryPoint(path=rel, reason=rule.reason))
79
+
80
+ # src-only JS/TS files
81
+ for filename in sorted(_SRC_ONLY):
82
+ for file_path in index.find_file(filename):
83
+ if self._is_in_src(file_path, index.root):
84
+ rel = file_path.relative_to(index.root).as_posix()
85
+ reason = self._js_ts_reason(filename)
86
+ results.append(EntryPoint(path=rel, reason=reason))
87
+
88
+ # Next.js pages/index.tsx
89
+ for file_path in index.find_file(_PAGES_INDEX):
90
+ if self._is_nextjs_pages_index(file_path):
91
+ rel = file_path.relative_to(index.root).as_posix()
92
+ results.append(EntryPoint(path=rel, reason="Next.js pages entry point."))
93
+
94
+ # Go cmd/**/main.go
95
+ for file_path in index.find_file(_GO_ENTRY):
96
+ if self._is_go_cmd_entry(file_path):
97
+ rel = file_path.relative_to(index.root).as_posix()
98
+ results.append(EntryPoint(path=rel, reason="Go application entry point."))
99
+
100
+ return results
101
+
102
+ def _matches_rule(self, rule: _Rule, file_path: Path, root: Path) -> bool:
103
+ if rule.root_only:
104
+ return file_path.parent == root
105
+
106
+ # Next.js page.tsx must be inside app/ directory.
107
+ if rule.filename in _NEXTJS_DIRS:
108
+ return self._is_in_nextjs_dir(rule.filename, file_path)
109
+
110
+ # Rust main.rs must be inside src/ directory.
111
+ if rule.filename == "main.rs":
112
+ return self._is_in_src(file_path, root)
113
+
114
+ return True
115
+
116
+ def _is_in_src(self, file_path: Path, root: Path) -> bool:
117
+ rel = file_path.relative_to(root)
118
+ return "src" in rel.parent.parts
119
+
120
+ def _is_in_nextjs_dir(self, filename: str, file_path: Path) -> bool:
121
+ valid_dirs = _NEXTJS_DIRS[filename]
122
+ return any(part in valid_dirs for part in file_path.parts)
123
+
124
+ def _is_nextjs_pages_index(self, file_path: Path) -> bool:
125
+ parts = file_path.parts
126
+ return "pages" in parts
127
+
128
+ def _is_go_cmd_entry(self, file_path: Path) -> bool:
129
+ return "cmd" in file_path.parts
130
+
131
+ def _js_ts_reason(self, filename: str) -> str:
132
+ if filename.endswith((".tsx", ".jsx")):
133
+ return "React application bootstrap."
134
+ if filename.endswith(".ts"):
135
+ return "TypeScript application entry point."
136
+ return "JavaScript application entry point."
137
+
@@ -0,0 +1,16 @@
1
+ """
2
+ Entry point models.
3
+ """
4
+
5
+ from dataclasses import dataclass
6
+
7
+
8
+ @dataclass(slots=True)
9
+ class EntryPoint:
10
+ """
11
+ A detected application entry point.
12
+ """
13
+
14
+ path: str
15
+ reason: str
16
+
File without changes
File without changes