@thoughtflow/codebase 0.2.0 → 0.3.1

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 (222) hide show
  1. package/package.json +4 -3
  2. package/tsconfig.json +13 -2
  3. package/dist/contexts/context-decomposer.d.ts +0 -13
  4. package/dist/contexts/context-decomposer.d.ts.map +0 -1
  5. package/dist/contexts/context-decomposer.js +0 -97
  6. package/dist/contexts/context-decomposer.js.map +0 -1
  7. package/dist/contexts/context-document-manager.d.ts +0 -21
  8. package/dist/contexts/context-document-manager.d.ts.map +0 -1
  9. package/dist/contexts/context-document-manager.js +0 -69
  10. package/dist/contexts/context-document-manager.js.map +0 -1
  11. package/dist/contexts/context-router.d.ts +0 -13
  12. package/dist/contexts/context-router.d.ts.map +0 -1
  13. package/dist/contexts/context-router.js +0 -94
  14. package/dist/contexts/context-router.js.map +0 -1
  15. package/dist/index.d.ts +0 -53
  16. package/dist/index.d.ts.map +0 -1
  17. package/dist/index.js +0 -76
  18. package/dist/index.js.map +0 -1
  19. package/dist/libs/codebase/deep-analyzer.d.ts +0 -58
  20. package/dist/libs/codebase/deep-analyzer.d.ts.map +0 -1
  21. package/dist/libs/codebase/deep-analyzer.js +0 -239
  22. package/dist/libs/codebase/deep-analyzer.js.map +0 -1
  23. package/dist/libs/codebase/graph/dependency-extractor.d.ts +0 -20
  24. package/dist/libs/codebase/graph/dependency-extractor.d.ts.map +0 -1
  25. package/dist/libs/codebase/graph/dependency-extractor.js +0 -174
  26. package/dist/libs/codebase/graph/dependency-extractor.js.map +0 -1
  27. package/dist/libs/codebase/graph/graph-analysis.d.ts +0 -42
  28. package/dist/libs/codebase/graph/graph-analysis.d.ts.map +0 -1
  29. package/dist/libs/codebase/graph/graph-analysis.js +0 -222
  30. package/dist/libs/codebase/graph/graph-analysis.js.map +0 -1
  31. package/dist/libs/codebase/graph/graph-visualizer.d.ts +0 -12
  32. package/dist/libs/codebase/graph/graph-visualizer.d.ts.map +0 -1
  33. package/dist/libs/codebase/graph/graph-visualizer.js +0 -99
  34. package/dist/libs/codebase/graph/graph-visualizer.js.map +0 -1
  35. package/dist/libs/codebase/indexer/batch-processor.d.ts +0 -18
  36. package/dist/libs/codebase/indexer/batch-processor.d.ts.map +0 -1
  37. package/dist/libs/codebase/indexer/batch-processor.js +0 -39
  38. package/dist/libs/codebase/indexer/batch-processor.js.map +0 -1
  39. package/dist/libs/codebase/indexer/chunker-markdown.d.ts +0 -19
  40. package/dist/libs/codebase/indexer/chunker-markdown.d.ts.map +0 -1
  41. package/dist/libs/codebase/indexer/chunker-markdown.js +0 -138
  42. package/dist/libs/codebase/indexer/chunker-markdown.js.map +0 -1
  43. package/dist/libs/codebase/indexer/chunker.d.ts +0 -21
  44. package/dist/libs/codebase/indexer/chunker.d.ts.map +0 -1
  45. package/dist/libs/codebase/indexer/chunker.js +0 -133
  46. package/dist/libs/codebase/indexer/chunker.js.map +0 -1
  47. package/dist/libs/codebase/indexer/explorer.d.ts +0 -29
  48. package/dist/libs/codebase/indexer/explorer.d.ts.map +0 -1
  49. package/dist/libs/codebase/indexer/explorer.js +0 -278
  50. package/dist/libs/codebase/indexer/explorer.js.map +0 -1
  51. package/dist/libs/codebase/indexer/indexer.d.ts +0 -35
  52. package/dist/libs/codebase/indexer/indexer.d.ts.map +0 -1
  53. package/dist/libs/codebase/indexer/indexer.js +0 -172
  54. package/dist/libs/codebase/indexer/indexer.js.map +0 -1
  55. package/dist/libs/codebase/knowledge/cross-referencer.d.ts +0 -32
  56. package/dist/libs/codebase/knowledge/cross-referencer.d.ts.map +0 -1
  57. package/dist/libs/codebase/knowledge/cross-referencer.js +0 -132
  58. package/dist/libs/codebase/knowledge/cross-referencer.js.map +0 -1
  59. package/dist/libs/codebase/knowledge/markdown-extractor.d.ts +0 -34
  60. package/dist/libs/codebase/knowledge/markdown-extractor.d.ts.map +0 -1
  61. package/dist/libs/codebase/knowledge/markdown-extractor.js +0 -273
  62. package/dist/libs/codebase/knowledge/markdown-extractor.js.map +0 -1
  63. package/dist/libs/codebase/knowledge/summarizer.d.ts +0 -25
  64. package/dist/libs/codebase/knowledge/summarizer.d.ts.map +0 -1
  65. package/dist/libs/codebase/knowledge/summarizer.js +0 -61
  66. package/dist/libs/codebase/knowledge/summarizer.js.map +0 -1
  67. package/dist/libs/codebase/search/bm25.d.ts +0 -23
  68. package/dist/libs/codebase/search/bm25.d.ts.map +0 -1
  69. package/dist/libs/codebase/search/bm25.js +0 -93
  70. package/dist/libs/codebase/search/bm25.js.map +0 -1
  71. package/dist/libs/codebase/search/hybrid-search.d.ts +0 -22
  72. package/dist/libs/codebase/search/hybrid-search.d.ts.map +0 -1
  73. package/dist/libs/codebase/search/hybrid-search.js +0 -80
  74. package/dist/libs/codebase/search/hybrid-search.js.map +0 -1
  75. package/dist/libs/codebase-index.class.d.ts +0 -66
  76. package/dist/libs/codebase-index.class.d.ts.map +0 -1
  77. package/dist/libs/codebase-index.class.js +0 -595
  78. package/dist/libs/codebase-index.class.js.map +0 -1
  79. package/dist/tools/codebase/codebase-analyze.tool.d.ts +0 -8
  80. package/dist/tools/codebase/codebase-analyze.tool.d.ts.map +0 -1
  81. package/dist/tools/codebase/codebase-analyze.tool.js +0 -20
  82. package/dist/tools/codebase/codebase-analyze.tool.js.map +0 -1
  83. package/dist/tools/codebase/codebase-crossref.tool.d.ts +0 -8
  84. package/dist/tools/codebase/codebase-crossref.tool.d.ts.map +0 -1
  85. package/dist/tools/codebase/codebase-crossref.tool.js +0 -20
  86. package/dist/tools/codebase/codebase-crossref.tool.js.map +0 -1
  87. package/dist/tools/codebase/codebase-flow.tool.d.ts +0 -8
  88. package/dist/tools/codebase/codebase-flow.tool.d.ts.map +0 -1
  89. package/dist/tools/codebase/codebase-flow.tool.js +0 -20
  90. package/dist/tools/codebase/codebase-flow.tool.js.map +0 -1
  91. package/dist/tools/codebase/codebase-graph-circular.tool.d.ts +0 -8
  92. package/dist/tools/codebase/codebase-graph-circular.tool.d.ts.map +0 -1
  93. package/dist/tools/codebase/codebase-graph-circular.tool.js +0 -17
  94. package/dist/tools/codebase/codebase-graph-circular.tool.js.map +0 -1
  95. package/dist/tools/codebase/codebase-graph-query.tool.d.ts +0 -8
  96. package/dist/tools/codebase/codebase-graph-query.tool.d.ts.map +0 -1
  97. package/dist/tools/codebase/codebase-graph-query.tool.js +0 -21
  98. package/dist/tools/codebase/codebase-graph-query.tool.js.map +0 -1
  99. package/dist/tools/codebase/codebase-graph-stats.tool.d.ts +0 -8
  100. package/dist/tools/codebase/codebase-graph-stats.tool.d.ts.map +0 -1
  101. package/dist/tools/codebase/codebase-graph-stats.tool.js +0 -17
  102. package/dist/tools/codebase/codebase-graph-stats.tool.js.map +0 -1
  103. package/dist/tools/codebase/codebase-graph-visualize.tool.d.ts +0 -8
  104. package/dist/tools/codebase/codebase-graph-visualize.tool.d.ts.map +0 -1
  105. package/dist/tools/codebase/codebase-graph-visualize.tool.js +0 -21
  106. package/dist/tools/codebase/codebase-graph-visualize.tool.js.map +0 -1
  107. package/dist/tools/codebase/codebase-impact.tool.d.ts +0 -8
  108. package/dist/tools/codebase/codebase-impact.tool.d.ts.map +0 -1
  109. package/dist/tools/codebase/codebase-impact.tool.js +0 -21
  110. package/dist/tools/codebase/codebase-impact.tool.js.map +0 -1
  111. package/dist/tools/codebase/codebase-index.tool.d.ts +0 -8
  112. package/dist/tools/codebase/codebase-index.tool.d.ts.map +0 -1
  113. package/dist/tools/codebase/codebase-index.tool.js +0 -21
  114. package/dist/tools/codebase/codebase-index.tool.js.map +0 -1
  115. package/dist/tools/codebase/codebase-knowledge.tool.d.ts +0 -8
  116. package/dist/tools/codebase/codebase-knowledge.tool.d.ts.map +0 -1
  117. package/dist/tools/codebase/codebase-knowledge.tool.js +0 -22
  118. package/dist/tools/codebase/codebase-knowledge.tool.js.map +0 -1
  119. package/dist/tools/codebase/codebase-search.tool.d.ts +0 -8
  120. package/dist/tools/codebase/codebase-search.tool.d.ts.map +0 -1
  121. package/dist/tools/codebase/codebase-search.tool.js +0 -24
  122. package/dist/tools/codebase/codebase-search.tool.js.map +0 -1
  123. package/dist/tools/codebase/codebase-status.tool.d.ts +0 -8
  124. package/dist/tools/codebase/codebase-status.tool.d.ts.map +0 -1
  125. package/dist/tools/codebase/codebase-status.tool.js +0 -19
  126. package/dist/tools/codebase/codebase-status.tool.js.map +0 -1
  127. package/dist/tools/neural/comparative-analysis.tool.d.ts +0 -37
  128. package/dist/tools/neural/comparative-analysis.tool.d.ts.map +0 -1
  129. package/dist/tools/neural/comparative-analysis.tool.js +0 -241
  130. package/dist/tools/neural/comparative-analysis.tool.js.map +0 -1
  131. package/dist/tools/neural/index.d.ts +0 -12
  132. package/dist/tools/neural/index.d.ts.map +0 -1
  133. package/dist/tools/neural/index.js +0 -28
  134. package/dist/tools/neural/index.js.map +0 -1
  135. package/dist/tools/neural/neural-deadcode.tool.d.ts +0 -10
  136. package/dist/tools/neural/neural-deadcode.tool.d.ts.map +0 -1
  137. package/dist/tools/neural/neural-deadcode.tool.js +0 -133
  138. package/dist/tools/neural/neural-deadcode.tool.js.map +0 -1
  139. package/dist/tools/neural/neural-debug.tool.d.ts +0 -11
  140. package/dist/tools/neural/neural-debug.tool.d.ts.map +0 -1
  141. package/dist/tools/neural/neural-debug.tool.js +0 -205
  142. package/dist/tools/neural/neural-debug.tool.js.map +0 -1
  143. package/dist/tools/neural/neural-explain.tool.d.ts +0 -9
  144. package/dist/tools/neural/neural-explain.tool.d.ts.map +0 -1
  145. package/dist/tools/neural/neural-explain.tool.js +0 -100
  146. package/dist/tools/neural/neural-explain.tool.js.map +0 -1
  147. package/dist/tools/neural/neural-optimize.tool.d.ts +0 -9
  148. package/dist/tools/neural/neural-optimize.tool.d.ts.map +0 -1
  149. package/dist/tools/neural/neural-optimize.tool.js +0 -117
  150. package/dist/tools/neural/neural-optimize.tool.js.map +0 -1
  151. package/dist/tools/neural/neural-pattern.tool.d.ts +0 -10
  152. package/dist/tools/neural/neural-pattern.tool.d.ts.map +0 -1
  153. package/dist/tools/neural/neural-pattern.tool.js +0 -169
  154. package/dist/tools/neural/neural-pattern.tool.js.map +0 -1
  155. package/dist/tools/neural/neural-review.tool.d.ts +0 -11
  156. package/dist/tools/neural/neural-review.tool.d.ts.map +0 -1
  157. package/dist/tools/neural/neural-review.tool.js +0 -152
  158. package/dist/tools/neural/neural-review.tool.js.map +0 -1
  159. package/dist/tools/neural/neural-security.tool.d.ts +0 -16
  160. package/dist/tools/neural/neural-security.tool.d.ts.map +0 -1
  161. package/dist/tools/neural/neural-security.tool.js +0 -256
  162. package/dist/tools/neural/neural-security.tool.js.map +0 -1
  163. package/dist/tools/neural/neural-similar.tool.d.ts +0 -9
  164. package/dist/tools/neural/neural-similar.tool.d.ts.map +0 -1
  165. package/dist/tools/neural/neural-similar.tool.js +0 -139
  166. package/dist/tools/neural/neural-similar.tool.js.map +0 -1
  167. package/dist/tools/neural/neural-smells.tool.d.ts +0 -9
  168. package/dist/tools/neural/neural-smells.tool.d.ts.map +0 -1
  169. package/dist/tools/neural/neural-smells.tool.js +0 -123
  170. package/dist/tools/neural/neural-smells.tool.js.map +0 -1
  171. package/dist/tools/neural/neural-suggest.tool.d.ts +0 -9
  172. package/dist/tools/neural/neural-suggest.tool.d.ts.map +0 -1
  173. package/dist/tools/neural/neural-suggest.tool.js +0 -64
  174. package/dist/tools/neural/neural-suggest.tool.js.map +0 -1
  175. package/dist/tools/quality/index.d.ts +0 -8
  176. package/dist/tools/quality/index.d.ts.map +0 -1
  177. package/dist/tools/quality/index.js +0 -24
  178. package/dist/tools/quality/index.js.map +0 -1
  179. package/dist/tools/quality/quality-complexity.tool.d.ts +0 -11
  180. package/dist/tools/quality/quality-complexity.tool.d.ts.map +0 -1
  181. package/dist/tools/quality/quality-complexity.tool.js +0 -152
  182. package/dist/tools/quality/quality-complexity.tool.js.map +0 -1
  183. package/dist/tools/quality/quality-coupling.tool.d.ts +0 -9
  184. package/dist/tools/quality/quality-coupling.tool.d.ts.map +0 -1
  185. package/dist/tools/quality/quality-coupling.tool.js +0 -51
  186. package/dist/tools/quality/quality-coupling.tool.js.map +0 -1
  187. package/dist/tools/quality/quality-coverage.tool.d.ts +0 -9
  188. package/dist/tools/quality/quality-coverage.tool.d.ts.map +0 -1
  189. package/dist/tools/quality/quality-coverage.tool.js +0 -104
  190. package/dist/tools/quality/quality-coverage.tool.js.map +0 -1
  191. package/dist/tools/quality/quality-deps.tool.d.ts +0 -11
  192. package/dist/tools/quality/quality-deps.tool.d.ts.map +0 -1
  193. package/dist/tools/quality/quality-deps.tool.js +0 -119
  194. package/dist/tools/quality/quality-deps.tool.js.map +0 -1
  195. package/dist/tools/quality/quality-duplication.tool.d.ts +0 -9
  196. package/dist/tools/quality/quality-duplication.tool.d.ts.map +0 -1
  197. package/dist/tools/quality/quality-duplication.tool.js +0 -100
  198. package/dist/tools/quality/quality-duplication.tool.js.map +0 -1
  199. package/dist/tools/quality/quality-size.tool.d.ts +0 -9
  200. package/dist/tools/quality/quality-size.tool.d.ts.map +0 -1
  201. package/dist/tools/quality/quality-size.tool.js +0 -94
  202. package/dist/tools/quality/quality-size.tool.js.map +0 -1
  203. package/dist/tools/quality/quality-types.tool.d.ts +0 -9
  204. package/dist/tools/quality/quality-types.tool.d.ts.map +0 -1
  205. package/dist/tools/quality/quality-types.tool.js +0 -95
  206. package/dist/tools/quality/quality-types.tool.js.map +0 -1
  207. package/dist/tools/workspace/analyze-project.tool.d.ts +0 -36
  208. package/dist/tools/workspace/analyze-project.tool.d.ts.map +0 -1
  209. package/dist/tools/workspace/analyze-project.tool.js +0 -454
  210. package/dist/tools/workspace/analyze-project.tool.js.map +0 -1
  211. package/dist/tools/workspace/codebase-research.tool.d.ts +0 -10
  212. package/dist/tools/workspace/codebase-research.tool.d.ts.map +0 -1
  213. package/dist/tools/workspace/codebase-research.tool.js +0 -89
  214. package/dist/tools/workspace/codebase-research.tool.js.map +0 -1
  215. package/dist/tools/workspace/project-scanner.tool.d.ts +0 -55
  216. package/dist/tools/workspace/project-scanner.tool.d.ts.map +0 -1
  217. package/dist/tools/workspace/project-scanner.tool.js +0 -978
  218. package/dist/tools/workspace/project-scanner.tool.js.map +0 -1
  219. package/dist/tools/workspace/search-code.tool.d.ts +0 -14
  220. package/dist/tools/workspace/search-code.tool.d.ts.map +0 -1
  221. package/dist/tools/workspace/search-code.tool.js +0 -286
  222. package/dist/tools/workspace/search-code.tool.js.map +0 -1
@@ -1,978 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.ProjectScannerTool = exports.MONOREPO_RULES = exports.TECH_RULES = void 0;
37
- const zod_1 = require("zod");
38
- const fs = __importStar(require("fs"));
39
- const path = __importStar(require("path"));
40
- const core_1 = require("@thoughtflow/core");
41
- /* ═══════════════════════════════════════════════════════════════
42
- TECH RULES — sorted by category, then by specificity.
43
- Framework rules should come AFTER language rules so the
44
- output reads naturally (language first, then framework).
45
- ═══════════════════════════════════════════════════════════════ */
46
- exports.TECH_RULES = [
47
- // ——— Languages ———————————————————————————————————————
48
- {
49
- id: "typescript",
50
- name: "TypeScript",
51
- category: "language",
52
- fileMarkers: ["tsconfig.json", "tsconfig.base.json"],
53
- dirMarkers: [],
54
- ignoreDirs: ["node_modules", "dist", "build", ".tsbuildinfo"],
55
- keyFiles: ["tsconfig.json"],
56
- explorePatterns: [],
57
- hints: [],
58
- },
59
- {
60
- id: "nodejs",
61
- name: "Node.js",
62
- category: "language",
63
- fileMarkers: ["package.json"],
64
- dirMarkers: [],
65
- ignoreDirs: ["node_modules", "dist", "build", ".cache", ".parcel-cache"],
66
- keyFiles: ["package.json"],
67
- explorePatterns: [],
68
- hints: ["Check 'scripts' in package.json for build/start/test commands"],
69
- },
70
- {
71
- id: "python",
72
- name: "Python",
73
- category: "language",
74
- fileMarkers: [
75
- "pyproject.toml",
76
- "setup.py",
77
- "requirements.txt",
78
- "Pipfile",
79
- "setup.cfg",
80
- ],
81
- dirMarkers: [],
82
- ignoreDirs: [
83
- "__pycache__",
84
- ".venv",
85
- "venv",
86
- "env",
87
- ".eggs",
88
- ".mypy_cache",
89
- ".pytest_cache",
90
- ".ruff_cache",
91
- ],
92
- keyFiles: ["pyproject.toml", "requirements.txt", "setup.py"],
93
- explorePatterns: ["**/*.py"],
94
- hints: ["Entry points in pyproject.toml [project.scripts] or setup.py"],
95
- },
96
- {
97
- id: "rust",
98
- name: "Rust",
99
- category: "language",
100
- fileMarkers: ["Cargo.toml"],
101
- dirMarkers: [],
102
- ignoreDirs: ["target"],
103
- keyFiles: ["Cargo.toml", "src/main.rs", "src/lib.rs"],
104
- explorePatterns: ["**/*.rs"],
105
- hints: ["Binaries in src/bin/, library in src/lib.rs"],
106
- },
107
- {
108
- id: "go",
109
- name: "Go",
110
- category: "language",
111
- fileMarkers: ["go.mod"],
112
- dirMarkers: [],
113
- ignoreDirs: ["vendor"],
114
- keyFiles: ["go.mod"],
115
- explorePatterns: ["**/*.go"],
116
- hints: ["Binaries in cmd/, private libs in internal/"],
117
- },
118
- {
119
- id: "php",
120
- name: "PHP",
121
- category: "language",
122
- fileMarkers: ["composer.json"],
123
- dirMarkers: [],
124
- ignoreDirs: ["vendor", "storage/framework"],
125
- keyFiles: ["composer.json"],
126
- explorePatterns: ["**/*.php"],
127
- hints: ["PSR-4 autoloading in composer.json"],
128
- },
129
- {
130
- id: "java",
131
- name: "Java",
132
- category: "language",
133
- fileMarkers: ["pom.xml", "build.gradle", "build.gradle.kts"],
134
- dirMarkers: [],
135
- ignoreDirs: ["target", "build", ".gradle", "out"],
136
- keyFiles: ["pom.xml", "build.gradle", "build.gradle.kts"],
137
- explorePatterns: ["**/*.java", "**/*.kt"],
138
- hints: ["Source in src/main/java, tests in src/test/java"],
139
- },
140
- {
141
- id: "dotnet",
142
- name: ".NET/C#",
143
- category: "language",
144
- fileMarkers: [], // detected via extension scan in detectTechs
145
- dirMarkers: [],
146
- ignoreDirs: ["bin", "obj", ".vs"],
147
- keyFiles: [],
148
- explorePatterns: ["**/*.cs", "**/*.csproj"],
149
- hints: [".sln defines project structure, .csproj defines build"],
150
- },
151
- {
152
- id: "ruby",
153
- name: "Ruby",
154
- category: "language",
155
- fileMarkers: ["Gemfile"],
156
- dirMarkers: [],
157
- ignoreDirs: ["vendor/bundle", ".bundle"],
158
- keyFiles: ["Gemfile"],
159
- explorePatterns: ["**/*.rb"],
160
- hints: ["Application code in lib/ or app/"],
161
- },
162
- // ——— Frameworks ——————————————————————————————————————
163
- {
164
- id: "nestjs",
165
- name: "NestJS",
166
- category: "framework",
167
- fileMarkers: ["nest-cli.json"],
168
- dirMarkers: [],
169
- packageDeps: ["@nestjs/core"],
170
- ignoreDirs: [],
171
- keyFiles: ["nest-cli.json", "src/main.ts", "src/app.module.ts"],
172
- explorePatterns: [
173
- "**/*.controller.ts",
174
- "**/*.module.ts",
175
- "**/*.service.ts",
176
- "**/*.guard.ts",
177
- "**/*.gateway.ts",
178
- ],
179
- hints: [
180
- "Controllers: @Get/@Post/@Put/@Delete define HTTP endpoints",
181
- "Modules: imports[] shows feature dependencies",
182
- ],
183
- },
184
- {
185
- id: "angular",
186
- name: "Angular",
187
- category: "framework",
188
- fileMarkers: ["angular.json"],
189
- dirMarkers: [],
190
- packageDeps: ["@angular/core"],
191
- ignoreDirs: [".angular"],
192
- keyFiles: [
193
- "angular.json",
194
- "src/app/app.routes.ts",
195
- "src/app/app.module.ts",
196
- "src/app/app.config.ts",
197
- ],
198
- explorePatterns: [
199
- "**/*.component.ts",
200
- "**/*routing*",
201
- "**/*.module.ts",
202
- ],
203
- hints: [
204
- "Routes: app.routes.ts (standalone) or *-routing.module.ts",
205
- "Components: @Component decorator, templates inline or .html",
206
- ],
207
- },
208
- {
209
- id: "react",
210
- name: "React",
211
- category: "framework",
212
- fileMarkers: [],
213
- dirMarkers: [],
214
- packageDeps: ["react"],
215
- ignoreDirs: [],
216
- keyFiles: ["src/App.tsx", "src/App.jsx", "src/index.tsx"],
217
- explorePatterns: ["**/*.tsx", "**/*.jsx"],
218
- hints: ["Components in src/, routing often in App.tsx or routes/"],
219
- },
220
- {
221
- id: "nextjs",
222
- name: "Next.js",
223
- category: "framework",
224
- fileMarkers: ["next.config.js", "next.config.mjs", "next.config.ts"],
225
- dirMarkers: [],
226
- packageDeps: ["next"],
227
- ignoreDirs: [".next"],
228
- keyFiles: ["next.config.js", "next.config.mjs", "next.config.ts"],
229
- explorePatterns: ["app/**/page.tsx", "app/**/route.ts", "pages/**/*.tsx"],
230
- hints: [
231
- "App Router: app/ dir, page.tsx=pages, route.ts=API",
232
- "Pages Router: pages/ dir, file-based routing",
233
- ],
234
- },
235
- {
236
- id: "vue",
237
- name: "Vue.js",
238
- category: "framework",
239
- fileMarkers: ["vue.config.js"],
240
- dirMarkers: [],
241
- packageDeps: ["vue"],
242
- ignoreDirs: [],
243
- keyFiles: ["src/App.vue", "src/main.ts", "src/router/index.ts"],
244
- explorePatterns: ["**/*.vue"],
245
- hints: ["Single-file components (.vue), routing in src/router/"],
246
- },
247
- {
248
- id: "nuxt",
249
- name: "Nuxt",
250
- category: "framework",
251
- fileMarkers: ["nuxt.config.ts", "nuxt.config.js"],
252
- dirMarkers: [],
253
- packageDeps: ["nuxt"],
254
- ignoreDirs: [".nuxt", ".output"],
255
- keyFiles: ["nuxt.config.ts"],
256
- explorePatterns: ["pages/**/*.vue", "server/api/**/*.ts"],
257
- hints: ["File-based routing in pages/, server API in server/api/"],
258
- },
259
- {
260
- id: "express",
261
- name: "Express.js",
262
- category: "framework",
263
- fileMarkers: [],
264
- dirMarkers: [],
265
- packageDeps: ["express"],
266
- ignoreDirs: [],
267
- keyFiles: ["src/app.ts", "src/app.js", "src/server.ts"],
268
- explorePatterns: ["**/*route*", "**/*controller*", "**/*middleware*"],
269
- hints: ["Routes in routes/ or src/routes/"],
270
- },
271
- {
272
- id: "fastify",
273
- name: "Fastify",
274
- category: "framework",
275
- fileMarkers: [],
276
- dirMarkers: [],
277
- packageDeps: ["fastify"],
278
- ignoreDirs: [],
279
- keyFiles: ["src/app.ts", "src/server.ts"],
280
- explorePatterns: ["**/*route*", "**/*plugin*"],
281
- hints: ["Routes as plugins, registered via app.register()"],
282
- },
283
- {
284
- id: "hono",
285
- name: "Hono",
286
- category: "framework",
287
- fileMarkers: [],
288
- dirMarkers: [],
289
- packageDeps: ["hono"],
290
- ignoreDirs: [],
291
- keyFiles: ["src/index.ts"],
292
- explorePatterns: ["**/*route*"],
293
- hints: ["Lightweight HTTP framework, routes via app.get/post"],
294
- },
295
- {
296
- id: "django",
297
- name: "Django",
298
- category: "framework",
299
- fileMarkers: ["manage.py"],
300
- dirMarkers: [],
301
- ignoreDirs: ["staticfiles", "media"],
302
- keyFiles: ["manage.py"],
303
- explorePatterns: [
304
- "**/views.py",
305
- "**/models.py",
306
- "**/urls.py",
307
- "**/serializers.py",
308
- ],
309
- hints: [
310
- "Apps in INSTALLED_APPS (settings.py)",
311
- "URLs in urls.py, views define endpoints, models define DB",
312
- ],
313
- },
314
- {
315
- id: "fastapi",
316
- name: "FastAPI",
317
- category: "framework",
318
- fileMarkers: [],
319
- dirMarkers: [],
320
- packageDeps: ["fastapi"],
321
- ignoreDirs: [],
322
- keyFiles: ["main.py", "app/main.py"],
323
- explorePatterns: ["**/*router*", "**/*route*"],
324
- hints: ["Routes with @app.get/@app.post, routers in separate files"],
325
- },
326
- {
327
- id: "flask",
328
- name: "Flask",
329
- category: "framework",
330
- fileMarkers: [],
331
- dirMarkers: [],
332
- packageDeps: ["flask"],
333
- ignoreDirs: [],
334
- keyFiles: ["app.py", "wsgi.py"],
335
- explorePatterns: ["**/*route*", "**/*view*"],
336
- hints: ["Routes via @app.route or blueprints"],
337
- },
338
- {
339
- id: "laravel",
340
- name: "Laravel",
341
- category: "framework",
342
- fileMarkers: ["artisan"],
343
- dirMarkers: ["app/Http/Controllers"],
344
- ignoreDirs: ["vendor", "storage/framework", "bootstrap/cache"],
345
- keyFiles: [
346
- "routes/web.php",
347
- "routes/api.php",
348
- "app/Http/Kernel.php",
349
- ".env.example",
350
- ],
351
- explorePatterns: [
352
- "app/Http/Controllers/**/*.php",
353
- "app/Models/**/*.php",
354
- "database/migrations/*.php",
355
- ],
356
- hints: [
357
- "Routes: routes/web.php + routes/api.php",
358
- "Controllers: app/Http/Controllers, Models: app/Models",
359
- ],
360
- },
361
- {
362
- id: "rails",
363
- name: "Ruby on Rails",
364
- category: "framework",
365
- fileMarkers: ["config/routes.rb"],
366
- dirMarkers: ["app/controllers", "app/models"],
367
- ignoreDirs: ["vendor/bundle", "tmp", "log"],
368
- keyFiles: ["config/routes.rb", "Gemfile", "config/database.yml"],
369
- explorePatterns: [
370
- "app/controllers/**/*.rb",
371
- "app/models/**/*.rb",
372
- "db/migrate/*.rb",
373
- ],
374
- hints: ["Routes in config/routes.rb, MVC in app/"],
375
- },
376
- {
377
- id: "spring",
378
- name: "Spring Boot",
379
- category: "framework",
380
- fileMarkers: [
381
- "src/main/resources/application.properties",
382
- "src/main/resources/application.yml",
383
- ],
384
- dirMarkers: [],
385
- ignoreDirs: ["target", "build"],
386
- keyFiles: [
387
- "src/main/resources/application.yml",
388
- "src/main/resources/application.properties",
389
- ],
390
- explorePatterns: [
391
- "**/*Controller.java",
392
- "**/*Service.java",
393
- "**/*Repository.java",
394
- ],
395
- hints: ["@RestController, @Service, @Entity, JPA for data access"],
396
- },
397
- // ——— Database / ORM ——————————————————————————————————
398
- {
399
- id: "prisma",
400
- name: "Prisma",
401
- category: "database",
402
- fileMarkers: ["prisma/schema.prisma"],
403
- dirMarkers: [],
404
- packageDeps: ["prisma", "@prisma/client"],
405
- ignoreDirs: [],
406
- keyFiles: ["prisma/schema.prisma"],
407
- explorePatterns: ["prisma/migrations/**/migration.sql"],
408
- hints: ["All models in schema.prisma, migrations in prisma/migrations/"],
409
- },
410
- {
411
- id: "typeorm",
412
- name: "TypeORM",
413
- category: "database",
414
- fileMarkers: ["ormconfig.json", "ormconfig.ts"],
415
- dirMarkers: [],
416
- packageDeps: ["typeorm"],
417
- ignoreDirs: [],
418
- keyFiles: ["ormconfig.json", "ormconfig.ts"],
419
- explorePatterns: ["**/*.entity.ts", "**/migration/*.ts"],
420
- hints: ["Entities with @Entity, migrations in migrations/"],
421
- },
422
- {
423
- id: "drizzle",
424
- name: "Drizzle ORM",
425
- category: "database",
426
- fileMarkers: ["drizzle.config.ts"],
427
- dirMarkers: [],
428
- packageDeps: ["drizzle-orm"],
429
- ignoreDirs: [],
430
- keyFiles: ["drizzle.config.ts"],
431
- explorePatterns: ["**/*schema*", "**/drizzle/**"],
432
- hints: ["Schema in schema files, migrations in drizzle/"],
433
- },
434
- {
435
- id: "sequelize",
436
- name: "Sequelize",
437
- category: "database",
438
- fileMarkers: [".sequelizerc"],
439
- dirMarkers: [],
440
- packageDeps: ["sequelize"],
441
- ignoreDirs: [],
442
- keyFiles: [".sequelizerc"],
443
- explorePatterns: ["**/models/**", "**/migrations/**"],
444
- hints: ["Models in models/, migrations in migrations/"],
445
- },
446
- {
447
- id: "mongoose",
448
- name: "Mongoose",
449
- category: "database",
450
- fileMarkers: [],
451
- dirMarkers: [],
452
- packageDeps: ["mongoose"],
453
- ignoreDirs: [],
454
- keyFiles: [],
455
- explorePatterns: ["**/*schema*", "**/*model*"],
456
- hints: ["MongoDB schemas, usually in schemas/ or models/"],
457
- },
458
- // ——— Infrastructure ——————————————————————————————————
459
- {
460
- id: "docker",
461
- name: "Docker",
462
- category: "infra",
463
- fileMarkers: [
464
- "Dockerfile",
465
- "docker-compose.yml",
466
- "docker-compose.yaml",
467
- "compose.yml",
468
- "compose.yaml",
469
- ],
470
- dirMarkers: [],
471
- ignoreDirs: [],
472
- keyFiles: [
473
- "Dockerfile",
474
- "docker-compose.yml",
475
- "docker-compose.yaml",
476
- "compose.yml",
477
- "compose.yaml",
478
- ".dockerignore",
479
- ],
480
- explorePatterns: ["**/Dockerfile*"],
481
- hints: ["docker-compose defines services, ports, volumes, networks"],
482
- },
483
- {
484
- id: "kubernetes",
485
- name: "Kubernetes",
486
- category: "infra",
487
- fileMarkers: ["kustomization.yaml", "skaffold.yaml"],
488
- dirMarkers: ["k8s", "kubernetes", "manifests"],
489
- ignoreDirs: [],
490
- keyFiles: ["kustomization.yaml"],
491
- explorePatterns: ["k8s/**/*.yaml", "kubernetes/**/*.yaml"],
492
- hints: ["Manifests: deployments, services, configmaps, secrets"],
493
- },
494
- {
495
- id: "terraform",
496
- name: "Terraform",
497
- category: "infra",
498
- fileMarkers: ["main.tf"],
499
- dirMarkers: [],
500
- ignoreDirs: [".terraform"],
501
- keyFiles: ["main.tf", "variables.tf", "outputs.tf"],
502
- explorePatterns: ["**/*.tf"],
503
- hints: ["main.tf=resources, variables.tf=inputs, outputs.tf=exports"],
504
- },
505
- // ——— Testing —————————————————————————————————————————
506
- {
507
- id: "jest",
508
- name: "Jest",
509
- category: "testing",
510
- fileMarkers: ["jest.config.ts", "jest.config.js", "jest.config.mjs"],
511
- dirMarkers: [],
512
- packageDeps: ["jest"],
513
- ignoreDirs: [],
514
- keyFiles: ["jest.config.ts", "jest.config.js"],
515
- explorePatterns: ["**/*.test.ts", "**/*.spec.ts"],
516
- hints: ["Tests in *.test.ts / *.spec.ts"],
517
- },
518
- {
519
- id: "vitest",
520
- name: "Vitest",
521
- category: "testing",
522
- fileMarkers: ["vitest.config.ts", "vitest.config.js"],
523
- dirMarkers: [],
524
- packageDeps: ["vitest"],
525
- ignoreDirs: [],
526
- keyFiles: ["vitest.config.ts"],
527
- explorePatterns: ["**/*.test.ts", "**/*.spec.ts"],
528
- hints: ["Tests in *.test.ts / *.spec.ts"],
529
- },
530
- {
531
- id: "pytest",
532
- name: "pytest",
533
- category: "testing",
534
- fileMarkers: ["pytest.ini", "conftest.py"],
535
- dirMarkers: [],
536
- ignoreDirs: [".pytest_cache"],
537
- keyFiles: ["pytest.ini", "conftest.py"],
538
- explorePatterns: ["**/test_*.py", "**/*_test.py"],
539
- hints: ["Tests in test_*.py, fixtures in conftest.py"],
540
- },
541
- {
542
- id: "playwright",
543
- name: "Playwright",
544
- category: "testing",
545
- fileMarkers: ["playwright.config.ts", "playwright.config.js"],
546
- dirMarkers: [],
547
- packageDeps: ["@playwright/test"],
548
- ignoreDirs: ["test-results", "playwright-report"],
549
- keyFiles: ["playwright.config.ts"],
550
- explorePatterns: ["**/*.spec.ts"],
551
- hints: ["E2E tests, config in playwright.config.ts"],
552
- },
553
- // ——— Build tools —————————————————————————————————————
554
- {
555
- id: "webpack",
556
- name: "Webpack",
557
- category: "build",
558
- fileMarkers: ["webpack.config.js", "webpack.config.ts"],
559
- dirMarkers: [],
560
- packageDeps: ["webpack"],
561
- ignoreDirs: [],
562
- keyFiles: ["webpack.config.js", "webpack.config.ts"],
563
- explorePatterns: [],
564
- hints: [],
565
- },
566
- {
567
- id: "vite",
568
- name: "Vite",
569
- category: "build",
570
- fileMarkers: ["vite.config.ts", "vite.config.js"],
571
- dirMarkers: [],
572
- packageDeps: ["vite"],
573
- ignoreDirs: [],
574
- keyFiles: ["vite.config.ts", "vite.config.js"],
575
- explorePatterns: [],
576
- hints: [],
577
- },
578
- {
579
- id: "esbuild",
580
- name: "esbuild",
581
- category: "build",
582
- fileMarkers: [],
583
- dirMarkers: [],
584
- packageDeps: ["esbuild"],
585
- ignoreDirs: [],
586
- keyFiles: [],
587
- explorePatterns: [],
588
- hints: [],
589
- },
590
- ];
591
- /* ═══════════════════════════════════════════════════════════════
592
- MONOREPO RULES
593
- ═══════════════════════════════════════════════════════════════ */
594
- exports.MONOREPO_RULES = [
595
- {
596
- id: "nx",
597
- name: "NX",
598
- fileMarkers: ["nx.json"],
599
- workspaceDirs: ["apps", "libs", "packages"],
600
- ignoreDirs: [".nx", "node_modules"],
601
- hints: [
602
- "project.json in each sub-project defines targets (build/serve/test)",
603
- "nx graph shows dependency graph",
604
- ],
605
- },
606
- {
607
- id: "turborepo",
608
- name: "Turborepo",
609
- fileMarkers: ["turbo.json"],
610
- workspaceDirs: ["apps", "packages"],
611
- ignoreDirs: [".turbo", "node_modules"],
612
- hints: ["Pipeline in turbo.json, packages in packages/ and apps/"],
613
- },
614
- {
615
- id: "lerna",
616
- name: "Lerna",
617
- fileMarkers: ["lerna.json"],
618
- workspaceDirs: ["packages"],
619
- ignoreDirs: ["node_modules"],
620
- hints: ["Packages in packages/, version mgmt via lerna.json"],
621
- },
622
- {
623
- id: "pnpm-workspaces",
624
- name: "pnpm workspaces",
625
- fileMarkers: ["pnpm-workspace.yaml"],
626
- workspaceDirs: ["packages", "apps", "libs"],
627
- ignoreDirs: ["node_modules"],
628
- hints: ["Workspace members defined in pnpm-workspace.yaml"],
629
- },
630
- {
631
- id: "go-workspaces",
632
- name: "Go workspaces",
633
- fileMarkers: ["go.work"],
634
- workspaceDirs: ["cmd", "internal", "pkg"],
635
- ignoreDirs: ["vendor"],
636
- hints: ["Workspace modules in go.work"],
637
- },
638
- ];
639
- /** Dirs always excluded regardless of detected tech. */
640
- const ALWAYS_IGNORE = new Set([".git", "coverage", ".idea", ".vscode"]);
641
- /* ═══════════════════════════════════════════════════════════════
642
- TOOL
643
- ═══════════════════════════════════════════════════════════════ */
644
- class ProjectScannerTool extends core_1.ToolBase {
645
- rootDir;
646
- name = "projectScanner";
647
- readonly = true;
648
- description = "Fast structural scan of a project or monorepo. " +
649
- "Detects languages, frameworks, databases, infrastructure, testing, build tools, " +
650
- "and monorepo layout including sub-projects. " +
651
- "Returns compact guidance: dirs to ignore, key files to read, " +
652
- "patterns for find_files, and technology-specific hints. " +
653
- "Use FIRST before any deep file exploration.";
654
- constructor(rootDir) {
655
- super(zod_1.z.object({
656
- path: zod_1.z
657
- .string()
658
- .optional()
659
- .describe("Path to scan, relative to project root. Defaults to root."),
660
- }));
661
- this.rootDir = rootDir;
662
- }
663
- async run(input, _ctx) {
664
- const relPath = input.path || ".";
665
- const scanDir = (0, core_1.resolveSafePath)(this.rootDir, relPath);
666
- if (!scanDir) {
667
- return { success: false, error: "Path traversal not allowed." };
668
- }
669
- if (!fs.existsSync(scanDir) || !fs.statSync(scanDir).isDirectory()) {
670
- return { success: false, error: `Not a directory: ${relPath}` };
671
- }
672
- const result = this.scan(scanDir);
673
- return { success: true, output: this.format(result, scanDir) };
674
- }
675
- /* ——— Scanning ——————————————————————————————————————— */
676
- scan(dir) {
677
- const rootDeps = this.readDeps(dir);
678
- const rootTechs = this.detectTechs(dir, rootDeps);
679
- // Monorepo detection
680
- let monorepo = null;
681
- for (const rule of exports.MONOREPO_RULES) {
682
- if (rule.fileMarkers.some((f) => fs.existsSync(path.join(dir, f)))) {
683
- monorepo = rule;
684
- break;
685
- }
686
- }
687
- // Yarn/npm workspaces (package.json "workspaces" field)
688
- const yarnWorkspaceDirs = [];
689
- const pkg = this.readPackageJson(dir);
690
- if (pkg?.workspaces) {
691
- const patterns = Array.isArray(pkg.workspaces)
692
- ? pkg.workspaces
693
- : pkg.workspaces.packages || [];
694
- for (const pattern of patterns) {
695
- const prefix = pattern.split(/[*{]/)[0].replace(/\/$/, "");
696
- if (prefix && !yarnWorkspaceDirs.includes(prefix)) {
697
- yarnWorkspaceDirs.push(prefix);
698
- }
699
- }
700
- }
701
- // Collect workspace dirs to scan
702
- const wsDirs = new Set();
703
- if (monorepo) {
704
- for (const d of monorepo.workspaceDirs)
705
- wsDirs.add(d);
706
- }
707
- for (const d of yarnWorkspaceDirs)
708
- wsDirs.add(d);
709
- // Detect sub-projects
710
- const subProjects = [];
711
- for (const wsDir of wsDirs) {
712
- this.scanWorkspaceDir(dir, wsDir, rootDeps, subProjects);
713
- }
714
- // No monorepo tool detected — check for plain multi-project layout
715
- if (!monorepo && yarnWorkspaceDirs.length === 0 && subProjects.length === 0) {
716
- this.detectPlainSubProjects(dir, subProjects);
717
- }
718
- return { monorepo, yarnWorkspaceDirs, rootTechs, subProjects };
719
- }
720
- scanWorkspaceDir(rootDir, wsDir, rootDeps, out) {
721
- const full = path.join(rootDir, wsDir);
722
- if (!fs.existsSync(full) || !fs.statSync(full).isDirectory())
723
- return;
724
- let entries;
725
- try {
726
- entries = fs.readdirSync(full, { withFileTypes: true });
727
- }
728
- catch {
729
- return;
730
- }
731
- for (const entry of entries) {
732
- if (!entry.isDirectory() || entry.name.startsWith("."))
733
- continue;
734
- const projDir = path.join(full, entry.name);
735
- const projDeps = this.readDeps(projDir, rootDeps);
736
- const techs = this.detectTechs(projDir, projDeps);
737
- if (techs.length > 0) {
738
- out.push({ relPath: path.relative(rootDir, projDir), techs });
739
- }
740
- }
741
- }
742
- /**
743
- * Fallback: scan top-level dirs that have their own config file
744
- * (looks like independent projects grouped in a directory).
745
- */
746
- detectPlainSubProjects(dir, out) {
747
- const PROJECT_CONFIGS = [
748
- "package.json",
749
- "Cargo.toml",
750
- "go.mod",
751
- "pyproject.toml",
752
- "composer.json",
753
- "Gemfile",
754
- "pom.xml",
755
- "build.gradle",
756
- ];
757
- let entries;
758
- try {
759
- entries = fs.readdirSync(dir, { withFileTypes: true });
760
- }
761
- catch {
762
- return;
763
- }
764
- for (const entry of entries) {
765
- if (!entry.isDirectory() || entry.name.startsWith("."))
766
- continue;
767
- if (ALWAYS_IGNORE.has(entry.name))
768
- continue;
769
- const subDir = path.join(dir, entry.name);
770
- const hasOwnConfig = PROJECT_CONFIGS.some((f) => fs.existsSync(path.join(subDir, f)));
771
- if (!hasOwnConfig)
772
- continue;
773
- const subDeps = this.readDeps(subDir);
774
- const techs = this.detectTechs(subDir, subDeps);
775
- if (techs.length > 0) {
776
- out.push({ relPath: entry.name, techs });
777
- }
778
- }
779
- }
780
- /* ——— Tech detection ———————————————————————————————— */
781
- detectTechs(dir, deps) {
782
- const detected = [];
783
- for (const rule of exports.TECH_RULES) {
784
- const evidence = [];
785
- for (const f of rule.fileMarkers) {
786
- if (fs.existsSync(path.join(dir, f)))
787
- evidence.push(f);
788
- }
789
- for (const d of rule.dirMarkers) {
790
- const full = path.join(dir, d);
791
- try {
792
- if (fs.existsSync(full) && fs.statSync(full).isDirectory()) {
793
- evidence.push(d + "/");
794
- }
795
- }
796
- catch {
797
- /* permission error etc. */
798
- }
799
- }
800
- if (rule.packageDeps) {
801
- for (const dep of rule.packageDeps) {
802
- if (deps.has(dep))
803
- evidence.push(`dep:${dep}`);
804
- }
805
- }
806
- if (evidence.length > 0) {
807
- detected.push({ rule, evidence });
808
- }
809
- }
810
- // Special: .NET detection via extensions (no fixed filenames)
811
- this.detectByExtension(dir, detected);
812
- return detected;
813
- }
814
- detectByExtension(dir, detected) {
815
- // Skip if .NET already detected
816
- if (detected.some((d) => d.rule.id === "dotnet"))
817
- return;
818
- let entries;
819
- try {
820
- entries = fs.readdirSync(dir);
821
- }
822
- catch {
823
- return;
824
- }
825
- const hasSln = entries.some((e) => e.endsWith(".sln"));
826
- const hasCsproj = entries.some((e) => e.endsWith(".csproj"));
827
- if (hasSln || hasCsproj) {
828
- const rule = exports.TECH_RULES.find((r) => r.id === "dotnet");
829
- const evidence = hasSln ? ["*.sln"] : ["*.csproj"];
830
- detected.push({ rule, evidence });
831
- }
832
- }
833
- /* ——— Dependency reading ————————————————————————————— */
834
- readPackageJson(dir) {
835
- const p = path.join(dir, "package.json");
836
- try {
837
- if (fs.existsSync(p)) {
838
- return JSON.parse(fs.readFileSync(p, "utf-8"));
839
- }
840
- }
841
- catch {
842
- /* malformed JSON */
843
- }
844
- return null;
845
- }
846
- readDeps(dir, fallback) {
847
- const deps = new Set(fallback ?? []);
848
- // package.json
849
- const pkg = this.readPackageJson(dir);
850
- if (pkg) {
851
- for (const section of [
852
- "dependencies",
853
- "devDependencies",
854
- "peerDependencies",
855
- ]) {
856
- if (pkg[section]) {
857
- for (const name of Object.keys(pkg[section]))
858
- deps.add(name);
859
- }
860
- }
861
- }
862
- // Python: read requirements.txt package names
863
- const reqTxt = path.join(dir, "requirements.txt");
864
- try {
865
- if (fs.existsSync(reqTxt)) {
866
- const lines = fs.readFileSync(reqTxt, "utf-8").split("\n");
867
- for (const line of lines) {
868
- const trimmed = line.trim();
869
- if (!trimmed || trimmed.startsWith("#") || trimmed.startsWith("-"))
870
- continue;
871
- const name = trimmed.split(/[>=<!~\[;]/)[0].trim().toLowerCase();
872
- if (name)
873
- deps.add(name);
874
- }
875
- }
876
- }
877
- catch {
878
- /* read error */
879
- }
880
- return deps;
881
- }
882
- /* ——— Output formatting ————————————————————————————— */
883
- format(result, scanDir) {
884
- const lines = [];
885
- const hasSubProjects = result.subProjects.length > 0;
886
- // Structure
887
- if (result.monorepo) {
888
- lines.push(`Structure: monorepo (${result.monorepo.name})`);
889
- }
890
- else if (result.yarnWorkspaceDirs.length > 0) {
891
- lines.push(`Structure: monorepo (npm/yarn workspaces)`);
892
- }
893
- else if (hasSubProjects) {
894
- lines.push(`Structure: multi-project`);
895
- }
896
- else {
897
- lines.push(`Structure: single project`);
898
- }
899
- // Aggregate ignore dirs
900
- const ignoreSet = new Set(ALWAYS_IGNORE);
901
- const allTechs = [...result.rootTechs];
902
- for (const sp of result.subProjects) {
903
- for (const t of sp.techs)
904
- allTechs.push(t);
905
- }
906
- if (result.monorepo) {
907
- for (const d of result.monorepo.ignoreDirs)
908
- ignoreSet.add(d);
909
- }
910
- for (const t of allTechs) {
911
- for (const d of t.rule.ignoreDirs)
912
- ignoreSet.add(d);
913
- }
914
- lines.push(`Ignore: ${[...ignoreSet].sort().join(", ")}`);
915
- lines.push("");
916
- // Root technologies
917
- if (result.rootTechs.length > 0) {
918
- const label = hasSubProjects ? "Root" : "Detected";
919
- lines.push(this.formatSection(label, result.rootTechs, scanDir));
920
- }
921
- // Sub-projects
922
- for (const sp of result.subProjects) {
923
- const spDir = path.join(scanDir, sp.relPath);
924
- lines.push(this.formatSection(sp.relPath, sp.techs, spDir));
925
- }
926
- // Monorepo-specific hints
927
- if (result.monorepo && result.monorepo.hints.length > 0) {
928
- lines.push("Monorepo:");
929
- for (const h of result.monorepo.hints)
930
- lines.push(` ${h}`);
931
- }
932
- return lines.join("\n").trimEnd();
933
- }
934
- formatSection(label, techs, dir) {
935
- const lines = [];
936
- // Tech names
937
- const names = techs.map((t) => t.rule.name).join(", ");
938
- lines.push(`${label}: ${names}`);
939
- // Key files (only those that actually exist on disk)
940
- const keyFiles = [];
941
- for (const t of techs) {
942
- for (const f of t.rule.keyFiles) {
943
- if (!keyFiles.includes(f) && fs.existsSync(path.join(dir, f))) {
944
- keyFiles.push(f);
945
- }
946
- }
947
- }
948
- if (keyFiles.length > 0) {
949
- lines.push(` read: ${keyFiles.join(", ")}`);
950
- }
951
- // Explore patterns (deduplicated)
952
- const patterns = [];
953
- for (const t of techs) {
954
- for (const p of t.rule.explorePatterns) {
955
- if (!patterns.includes(p))
956
- patterns.push(p);
957
- }
958
- }
959
- if (patterns.length > 0) {
960
- lines.push(` find: ${patterns.join(", ")}`);
961
- }
962
- // Hints — only from framework, database, and infra categories (skip generic language/build hints)
963
- const hints = [];
964
- for (const t of techs) {
965
- if (["framework", "database", "infra"].includes(t.rule.category)) {
966
- for (const h of t.rule.hints)
967
- hints.push(h);
968
- }
969
- }
970
- if (hints.length > 0) {
971
- lines.push(` hints: ${hints.join(" · ")}`);
972
- }
973
- lines.push("");
974
- return lines.join("\n");
975
- }
976
- }
977
- exports.ProjectScannerTool = ProjectScannerTool;
978
- //# sourceMappingURL=project-scanner.tool.js.map