@archpilotlabs/archpilot 0.2.2 → 0.2.3

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 (296) hide show
  1. package/dist/archpilot-cli.js +516 -105
  2. package/dist/cli/src/archpilot-cli.js +5523 -0
  3. package/dist/cli/src/archpilot-cli.js.map +1 -0
  4. package/dist/core/src/adr/adrLoader.js +97 -0
  5. package/dist/core/src/adr/adrLoader.js.map +1 -0
  6. package/dist/core/src/adr/adrParser.js +77 -0
  7. package/dist/core/src/adr/adrParser.js.map +1 -0
  8. package/dist/core/src/adr/adrTemplate.js +45 -0
  9. package/dist/core/src/adr/adrTemplate.js.map +1 -0
  10. package/dist/core/src/adr/adrTypes.js +3 -0
  11. package/dist/core/src/adr/adrTypes.js.map +1 -0
  12. package/dist/core/src/adr/adrValidation.js +160 -0
  13. package/dist/core/src/adr/adrValidation.js.map +1 -0
  14. package/dist/core/src/adr/index.js +9 -0
  15. package/dist/core/src/adr/index.js.map +1 -0
  16. package/dist/core/src/adrManagement.js +174 -0
  17. package/dist/core/src/adrManagement.js.map +1 -0
  18. package/dist/core/src/adrRequirementStatus.js +62 -0
  19. package/dist/core/src/adrRequirementStatus.js.map +1 -0
  20. package/dist/core/src/adrScaffoldGeneration.js +325 -0
  21. package/dist/core/src/adrScaffoldGeneration.js.map +1 -0
  22. package/dist/core/src/apiDesignAnalysis.js +869 -0
  23. package/dist/core/src/apiDesignAnalysis.js.map +1 -0
  24. package/dist/core/src/applicationLayeringAnalysis.js +920 -0
  25. package/dist/core/src/applicationLayeringAnalysis.js.map +1 -0
  26. package/dist/core/src/applyRulePack.js +117 -0
  27. package/dist/core/src/applyRulePack.js.map +1 -0
  28. package/dist/core/src/architectureBaseline.js +271 -0
  29. package/dist/core/src/architectureBaseline.js.map +1 -0
  30. package/dist/core/src/architectureComponentDiscoveryDefaults.js +139 -0
  31. package/dist/core/src/architectureComponentDiscoveryDefaults.js.map +1 -0
  32. package/dist/core/src/architectureDependencyContext.js +316 -0
  33. package/dist/core/src/architectureDependencyContext.js.map +1 -0
  34. package/dist/core/src/architectureDriftDetection.js +96 -0
  35. package/dist/core/src/architectureDriftDetection.js.map +1 -0
  36. package/dist/core/src/architectureDriftTimeline.js +221 -0
  37. package/dist/core/src/architectureDriftTimeline.js.map +1 -0
  38. package/dist/core/src/architectureGovernanceBaseline.js +469 -0
  39. package/dist/core/src/architectureGovernanceBaseline.js.map +1 -0
  40. package/dist/core/src/architectureHealthHistory.js +208 -0
  41. package/dist/core/src/architectureHealthHistory.js.map +1 -0
  42. package/dist/core/src/architectureHealthScore.js +657 -0
  43. package/dist/core/src/architectureHealthScore.js.map +1 -0
  44. package/dist/core/src/architectureInit.js +826 -0
  45. package/dist/core/src/architectureInit.js.map +1 -0
  46. package/dist/core/src/architectureMap.js +727 -0
  47. package/dist/core/src/architectureMap.js.map +1 -0
  48. package/dist/core/src/architectureMigrationPreview.js +467 -0
  49. package/dist/core/src/architectureMigrationPreview.js.map +1 -0
  50. package/dist/core/src/architectureModelRefresh.js +209 -0
  51. package/dist/core/src/architectureModelRefresh.js.map +1 -0
  52. package/dist/core/src/architectureReportWorkflow.js +139 -0
  53. package/dist/core/src/architectureReportWorkflow.js.map +1 -0
  54. package/dist/core/src/architectureValidation.js +3879 -0
  55. package/dist/core/src/architectureValidation.js.map +1 -0
  56. package/dist/core/src/architectureWorkspaceModel.js +166 -0
  57. package/dist/core/src/architectureWorkspaceModel.js.map +1 -0
  58. package/dist/core/src/authorizationTenantAnalysis.js +652 -0
  59. package/dist/core/src/authorizationTenantAnalysis.js.map +1 -0
  60. package/dist/core/src/bootstrapArchitectureConfig.js +150 -0
  61. package/dist/core/src/bootstrapArchitectureConfig.js.map +1 -0
  62. package/dist/core/src/changeRisk/changeRiskAssessment.js +251 -0
  63. package/dist/core/src/changeRisk/changeRiskAssessment.js.map +1 -0
  64. package/dist/core/src/changeRisk/changeRiskTypes.js +3 -0
  65. package/dist/core/src/changeRisk/changeRiskTypes.js.map +1 -0
  66. package/dist/core/src/changeRisk/index.js +6 -0
  67. package/dist/core/src/changeRisk/index.js.map +1 -0
  68. package/dist/core/src/ci/githubInlineAnnotations.js +245 -0
  69. package/dist/core/src/ci/githubInlineAnnotations.js.map +1 -0
  70. package/dist/core/src/ci/githubPrCommentAdapter.js +232 -0
  71. package/dist/core/src/ci/githubPrCommentAdapter.js.map +1 -0
  72. package/dist/core/src/ciWorkflowTemplates.js +1042 -0
  73. package/dist/core/src/ciWorkflowTemplates.js.map +1 -0
  74. package/dist/core/src/compliance/complianceExportBuilder.js +122 -0
  75. package/dist/core/src/compliance/complianceExportBuilder.js.map +1 -0
  76. package/dist/core/src/compliance/complianceExportTypes.js +3 -0
  77. package/dist/core/src/compliance/complianceExportTypes.js.map +1 -0
  78. package/dist/core/src/compliance/complianceExportWriter.js +48 -0
  79. package/dist/core/src/compliance/complianceExportWriter.js.map +1 -0
  80. package/dist/core/src/compliance/complianceRulePackResolver.js +62 -0
  81. package/dist/core/src/compliance/complianceRulePackResolver.js.map +1 -0
  82. package/dist/core/src/config/index.js +17 -0
  83. package/dist/core/src/config/index.js.map +1 -0
  84. package/dist/core/src/config/projectConfig.js +224 -0
  85. package/dist/core/src/config/projectConfig.js.map +1 -0
  86. package/dist/core/src/config/projectIdentity.js +160 -0
  87. package/dist/core/src/config/projectIdentity.js.map +1 -0
  88. package/dist/core/src/dataQueryRiskDetection.js +1203 -0
  89. package/dist/core/src/dataQueryRiskDetection.js.map +1 -0
  90. package/dist/core/src/dependencyValidation.js +2557 -0
  91. package/dist/core/src/dependencyValidation.js.map +1 -0
  92. package/dist/core/src/discoverAdrs.js +15 -0
  93. package/dist/core/src/discoverAdrs.js.map +1 -0
  94. package/dist/core/src/drift/driftComparator.js +49 -0
  95. package/dist/core/src/drift/driftComparator.js.map +1 -0
  96. package/dist/core/src/drift/driftSnapshotLoader.js +136 -0
  97. package/dist/core/src/drift/driftSnapshotLoader.js.map +1 -0
  98. package/dist/core/src/drift/driftSnapshotTypes.js +3 -0
  99. package/dist/core/src/drift/driftSnapshotTypes.js.map +1 -0
  100. package/dist/core/src/drift/driftSnapshotWriter.js +48 -0
  101. package/dist/core/src/drift/driftSnapshotWriter.js.map +1 -0
  102. package/dist/core/src/drift/index.js +6 -0
  103. package/dist/core/src/drift/index.js.map +1 -0
  104. package/dist/core/src/eventArchitectureAnalysis.js +925 -0
  105. package/dist/core/src/eventArchitectureAnalysis.js.map +1 -0
  106. package/dist/core/src/findingTargetResolution.js +117 -0
  107. package/dist/core/src/findingTargetResolution.js.map +1 -0
  108. package/dist/core/src/generateArchitectureDiagrams.js +57 -0
  109. package/dist/core/src/generateArchitectureDiagrams.js.map +1 -0
  110. package/dist/core/src/generateImpactAnalysis.js +366 -0
  111. package/dist/core/src/generateImpactAnalysis.js.map +1 -0
  112. package/dist/core/src/generateOnboardingDocs.js +262 -0
  113. package/dist/core/src/generateOnboardingDocs.js.map +1 -0
  114. package/dist/core/src/governance/cloudConnection.js +203 -0
  115. package/dist/core/src/governance/cloudConnection.js.map +1 -0
  116. package/dist/core/src/governance/governanceContracts.js +129 -0
  117. package/dist/core/src/governance/governanceContracts.js.map +1 -0
  118. package/dist/core/src/governance/governanceGitMetadata.js +78 -0
  119. package/dist/core/src/governance/governanceGitMetadata.js.map +1 -0
  120. package/dist/core/src/governance/governanceUploadClient.js +119 -0
  121. package/dist/core/src/governance/governanceUploadClient.js.map +1 -0
  122. package/dist/core/src/governance/governanceUploadLimitErrorFormatting.js +155 -0
  123. package/dist/core/src/governance/governanceUploadLimitErrorFormatting.js.map +1 -0
  124. package/dist/core/src/governance/governanceUploadPayload.js +439 -0
  125. package/dist/core/src/governance/governanceUploadPayload.js.map +1 -0
  126. package/dist/core/src/governance/runGovernanceUpload.js +103 -0
  127. package/dist/core/src/governance/runGovernanceUpload.js.map +1 -0
  128. package/dist/core/src/impactAnalysisEngine.js +376 -0
  129. package/dist/core/src/impactAnalysisEngine.js.map +1 -0
  130. package/dist/core/src/initializationState.js +99 -0
  131. package/dist/core/src/initializationState.js.map +1 -0
  132. package/dist/core/src/managedArtifacts.js +151 -0
  133. package/dist/core/src/managedArtifacts.js.map +1 -0
  134. package/dist/core/src/moduleContractValidation.js +266 -0
  135. package/dist/core/src/moduleContractValidation.js.map +1 -0
  136. package/dist/core/src/moduleContractsGenerator.js +337 -0
  137. package/dist/core/src/moduleContractsGenerator.js.map +1 -0
  138. package/dist/core/src/moduleDiscovery.js +416 -0
  139. package/dist/core/src/moduleDiscovery.js.map +1 -0
  140. package/dist/core/src/moduleScope.js +426 -0
  141. package/dist/core/src/moduleScope.js.map +1 -0
  142. package/dist/core/src/onboardingGuidance.js +74 -0
  143. package/dist/core/src/onboardingGuidance.js.map +1 -0
  144. package/dist/core/src/operationalLogging.js +7 -0
  145. package/dist/core/src/operationalLogging.js.map +1 -0
  146. package/dist/core/src/packageVersion.js +52 -0
  147. package/dist/core/src/packageVersion.js.map +1 -0
  148. package/dist/core/src/policy/effectivePolicyResolver.js +91 -0
  149. package/dist/core/src/policy/effectivePolicyResolver.js.map +1 -0
  150. package/dist/core/src/policy/exceptionLoader.js +285 -0
  151. package/dist/core/src/policy/exceptionLoader.js.map +1 -0
  152. package/dist/core/src/policy/remotePolicyLoader.js +227 -0
  153. package/dist/core/src/policy/remotePolicyLoader.js.map +1 -0
  154. package/dist/core/src/policy/remotePolicyTypes.js +3 -0
  155. package/dist/core/src/policy/remotePolicyTypes.js.map +1 -0
  156. package/dist/core/src/policy/riskPolicyConfig.js +206 -0
  157. package/dist/core/src/policy/riskPolicyConfig.js.map +1 -0
  158. package/dist/core/src/policy/riskPolicyEnforcement.js +203 -0
  159. package/dist/core/src/policy/riskPolicyEnforcement.js.map +1 -0
  160. package/dist/core/src/policy/riskPolicyExitCode.js +16 -0
  161. package/dist/core/src/policy/riskPolicyExitCode.js.map +1 -0
  162. package/dist/core/src/policy/riskPolicyInitializer.js +90 -0
  163. package/dist/core/src/policy/riskPolicyInitializer.js.map +1 -0
  164. package/dist/core/src/quickFix/quickFixEngine.js +132 -0
  165. package/dist/core/src/quickFix/quickFixEngine.js.map +1 -0
  166. package/dist/core/src/quickFix/quickFixMessaging.js +15 -0
  167. package/dist/core/src/quickFix/quickFixMessaging.js.map +1 -0
  168. package/dist/core/src/quickFix/quickFixProviders.js +87 -0
  169. package/dist/core/src/quickFix/quickFixProviders.js.map +1 -0
  170. package/dist/core/src/quickFix/quickFixTypes.js +3 -0
  171. package/dist/core/src/quickFix/quickFixTypes.js.map +1 -0
  172. package/dist/core/src/remediation/fileHelpers.js +86 -0
  173. package/dist/core/src/remediation/fileHelpers.js.map +1 -0
  174. package/dist/core/src/remediation/fixRegistry.js +645 -0
  175. package/dist/core/src/remediation/fixRegistry.js.map +1 -0
  176. package/dist/core/src/remediation/index.js +8 -0
  177. package/dist/core/src/remediation/index.js.map +1 -0
  178. package/dist/core/src/remediation/remediationEngine.js +207 -0
  179. package/dist/core/src/remediation/remediationEngine.js.map +1 -0
  180. package/dist/core/src/reporting/adrReporter.js +59 -0
  181. package/dist/core/src/reporting/adrReporter.js.map +1 -0
  182. package/dist/core/src/reporting/architectureBaselineReporter.js +64 -0
  183. package/dist/core/src/reporting/architectureBaselineReporter.js.map +1 -0
  184. package/dist/core/src/reporting/architectureDiagramReporter.js +148 -0
  185. package/dist/core/src/reporting/architectureDiagramReporter.js.map +1 -0
  186. package/dist/core/src/reporting/architectureDriftTimelineReporter.js +44 -0
  187. package/dist/core/src/reporting/architectureDriftTimelineReporter.js.map +1 -0
  188. package/dist/core/src/reporting/architectureHealthHistoryReporter.js +51 -0
  189. package/dist/core/src/reporting/architectureHealthHistoryReporter.js.map +1 -0
  190. package/dist/core/src/reporting/architectureMapReporter.js +228 -0
  191. package/dist/core/src/reporting/architectureMapReporter.js.map +1 -0
  192. package/dist/core/src/reporting/architecturePrCommentReporter.js +324 -0
  193. package/dist/core/src/reporting/architecturePrCommentReporter.js.map +1 -0
  194. package/dist/core/src/reporting/architecturePrReviewReporter.js +389 -0
  195. package/dist/core/src/reporting/architecturePrReviewReporter.js.map +1 -0
  196. package/dist/core/src/reporting/architectureReportArtifacts.js +166 -0
  197. package/dist/core/src/reporting/architectureReportArtifacts.js.map +1 -0
  198. package/dist/core/src/reporting/architectureReviewReportGenerator.js +382 -0
  199. package/dist/core/src/reporting/architectureReviewReportGenerator.js.map +1 -0
  200. package/dist/core/src/reporting/architectureReviewReporter.js +1633 -0
  201. package/dist/core/src/reporting/architectureReviewReporter.js.map +1 -0
  202. package/dist/core/src/reporting/architectureRiskAssessment.js +101 -0
  203. package/dist/core/src/reporting/architectureRiskAssessment.js.map +1 -0
  204. package/dist/core/src/reporting/architectureScoreBadge.js +177 -0
  205. package/dist/core/src/reporting/architectureScoreBadge.js.map +1 -0
  206. package/dist/core/src/reporting/architectureSupplementalReporters.js +124 -0
  207. package/dist/core/src/reporting/architectureSupplementalReporters.js.map +1 -0
  208. package/dist/core/src/reporting/changeRiskAssessment.js +6 -0
  209. package/dist/core/src/reporting/changeRiskAssessment.js.map +1 -0
  210. package/dist/core/src/reporting/changeRiskTypes.js +3 -0
  211. package/dist/core/src/reporting/changeRiskTypes.js.map +1 -0
  212. package/dist/core/src/reporting/impactAnalysisReporter.js +111 -0
  213. package/dist/core/src/reporting/impactAnalysisReporter.js.map +1 -0
  214. package/dist/core/src/reporting/onboardingDocsReporter.js +113 -0
  215. package/dist/core/src/reporting/onboardingDocsReporter.js.map +1 -0
  216. package/dist/core/src/reporting/rulePackReporter.js +61 -0
  217. package/dist/core/src/reporting/rulePackReporter.js.map +1 -0
  218. package/dist/core/src/reporting/safetyControlsDetection.js +343 -0
  219. package/dist/core/src/reporting/safetyControlsDetection.js.map +1 -0
  220. package/dist/core/src/resolveRuleAdrs.js +31 -0
  221. package/dist/core/src/resolveRuleAdrs.js.map +1 -0
  222. package/dist/core/src/reviewGenerationWorkflow.js +220 -0
  223. package/dist/core/src/reviewGenerationWorkflow.js.map +1 -0
  224. package/dist/core/src/rulePacks/index.js +17 -0
  225. package/dist/core/src/rulePacks/index.js.map +1 -0
  226. package/dist/core/src/rulePacks/layeredMonolithRulePack.js +45 -0
  227. package/dist/core/src/rulePacks/layeredMonolithRulePack.js.map +1 -0
  228. package/dist/core/src/rulePacks/modularMonolithRulePack.js +41 -0
  229. package/dist/core/src/rulePacks/modularMonolithRulePack.js.map +1 -0
  230. package/dist/core/src/rulePacks/types.js +3 -0
  231. package/dist/core/src/rulePacks/types.js.map +1 -0
  232. package/dist/core/src/setupNextSteps.js +939 -0
  233. package/dist/core/src/setupNextSteps.js.map +1 -0
  234. package/dist/core/src/setupRefresh.js +152 -0
  235. package/dist/core/src/setupRefresh.js.map +1 -0
  236. package/dist/core/src/smartInit/apiDbHintDetection.js +836 -0
  237. package/dist/core/src/smartInit/apiDbHintDetection.js.map +1 -0
  238. package/dist/core/src/smartInit/architectureProposalBuilder.js +1215 -0
  239. package/dist/core/src/smartInit/architectureProposalBuilder.js.map +1 -0
  240. package/dist/core/src/smartInit/architectureStyleDetection.js +472 -0
  241. package/dist/core/src/smartInit/architectureStyleDetection.js.map +1 -0
  242. package/dist/core/src/smartInit/archpilotIgnore.js +139 -0
  243. package/dist/core/src/smartInit/archpilotIgnore.js.map +1 -0
  244. package/dist/core/src/smartInit/componentDetection.js +1084 -0
  245. package/dist/core/src/smartInit/componentDetection.js.map +1 -0
  246. package/dist/core/src/smartInit/implementationProfileResolution.js +53 -0
  247. package/dist/core/src/smartInit/implementationProfileResolution.js.map +1 -0
  248. package/dist/core/src/smartInit/index.js +31 -0
  249. package/dist/core/src/smartInit/index.js.map +1 -0
  250. package/dist/core/src/smartInit/moduleDetection.js +982 -0
  251. package/dist/core/src/smartInit/moduleDetection.js.map +1 -0
  252. package/dist/core/src/smartInit/projectKindDetection.js +437 -0
  253. package/dist/core/src/smartInit/projectKindDetection.js.map +1 -0
  254. package/dist/core/src/smartInit/repoTopologyDetection.js +470 -0
  255. package/dist/core/src/smartInit/repoTopologyDetection.js.map +1 -0
  256. package/dist/core/src/smartInit/runContext.js +112 -0
  257. package/dist/core/src/smartInit/runContext.js.map +1 -0
  258. package/dist/core/src/smartInit/smartInitEngine.js +94 -0
  259. package/dist/core/src/smartInit/smartInitEngine.js.map +1 -0
  260. package/dist/core/src/smartInit/stackDetection.js +503 -0
  261. package/dist/core/src/smartInit/stackDetection.js.map +1 -0
  262. package/dist/core/src/smartInit/toolingHintDetection.js +345 -0
  263. package/dist/core/src/smartInit/toolingHintDetection.js.map +1 -0
  264. package/dist/core/src/sourceScopeClassification.js +83 -0
  265. package/dist/core/src/sourceScopeClassification.js.map +1 -0
  266. package/dist/core/src/stackAdapters.js +2475 -0
  267. package/dist/core/src/stackAdapters.js.map +1 -0
  268. package/dist/core/src/stackMetadata.js +157 -0
  269. package/dist/core/src/stackMetadata.js.map +1 -0
  270. package/dist/core/src/suppressions/index.js +3 -0
  271. package/dist/core/src/suppressions/index.js.map +1 -0
  272. package/dist/core/src/suppressions/suppressionReporter.js +38 -0
  273. package/dist/core/src/suppressions/suppressionReporter.js.map +1 -0
  274. package/dist/core/src/suppressions/suppressionTypes.js +3 -0
  275. package/dist/core/src/suppressions/suppressionTypes.js.map +1 -0
  276. package/dist/core/src/suppressions/suppressionValidator.js +119 -0
  277. package/dist/core/src/suppressions/suppressionValidator.js.map +1 -0
  278. package/dist/core/src/transactionDomainAnalysis.js +1416 -0
  279. package/dist/core/src/transactionDomainAnalysis.js.map +1 -0
  280. package/dist/core/src/validation/changedFilesResolver.js +165 -0
  281. package/dist/core/src/validation/changedFilesResolver.js.map +1 -0
  282. package/dist/core/src/validationProfiling.js +33 -0
  283. package/dist/core/src/validationProfiling.js.map +1 -0
  284. package/dist/core/src/validationRuleExplanations.js +69 -0
  285. package/dist/core/src/validationRuleExplanations.js.map +1 -0
  286. package/dist/core/src/validationSourceInventory.js +200 -0
  287. package/dist/core/src/validationSourceInventory.js.map +1 -0
  288. package/dist/core/src/validationSuppressions.js +231 -0
  289. package/dist/core/src/validationSuppressions.js.map +1 -0
  290. package/dist/core/src/validationTypeScriptAstCache.js +82 -0
  291. package/dist/core/src/validationTypeScriptAstCache.js.map +1 -0
  292. package/dist/core/src/validationWorkflow.js +222 -0
  293. package/dist/core/src/validationWorkflow.js.map +1 -0
  294. package/dist/core/src/workspaceRoot.js +68 -0
  295. package/dist/core/src/workspaceRoot.js.map +1 -0
  296. package/package.json +1 -1
@@ -0,0 +1,1084 @@
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.detectComponents = detectComponents;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const stackMetadata_1 = require("../stackMetadata");
40
+ const apiDbHintDetection_1 = require("./apiDbHintDetection");
41
+ const projectKindDetection_1 = require("./projectKindDetection");
42
+ const stackDetection_1 = require("./stackDetection");
43
+ const archpilotIgnore_1 = require("./archpilotIgnore");
44
+ function normalizePath(value) {
45
+ return value.replaceAll('\\', '/').replace(/\/+$/u, '') || '.';
46
+ }
47
+ function uniqueSorted(values) {
48
+ return [...new Set(values)].sort((left, right) => left.localeCompare(right));
49
+ }
50
+ function addEvidence(evidence, value) {
51
+ if (!evidence.includes(value)) {
52
+ evidence.push(value);
53
+ }
54
+ }
55
+ function isIgnoredComponentCandidatePath(componentPath) {
56
+ const normalized = normalizePath(componentPath).replace(/^\.\//u, '');
57
+ if (normalized === '.' || normalized.length === 0) {
58
+ return false;
59
+ }
60
+ const segments = normalized.split('/').filter((segment) => segment.length > 0);
61
+ const firstSegment = segments[0];
62
+ const ignoredRootSegments = [
63
+ 'tests',
64
+ 'test',
65
+ 'cypress',
66
+ 'cypress-tests',
67
+ '__tests__',
68
+ 'fixtures',
69
+ 'smoke',
70
+ 'docs',
71
+ 'doc',
72
+ 'reports',
73
+ 'report',
74
+ 'examples',
75
+ 'example',
76
+ 'spec',
77
+ 'badges',
78
+ ];
79
+ const ignoredSupportingSegments = [
80
+ 'public',
81
+ 'static',
82
+ 'assets',
83
+ 'vendor',
84
+ 'plugins',
85
+ 'plugin',
86
+ 'themes',
87
+ 'theme',
88
+ 'generated',
89
+ 'storage',
90
+ 'dist',
91
+ 'build',
92
+ 'coverage',
93
+ ];
94
+ return ignoredRootSegments.includes(firstSegment ?? '') ||
95
+ segments.some((segment) => ignoredSupportingSegments.includes(segment.toLowerCase()));
96
+ }
97
+ function pathExists(pathValue) {
98
+ try {
99
+ fs.accessSync(pathValue);
100
+ return true;
101
+ }
102
+ catch {
103
+ return false;
104
+ }
105
+ }
106
+ function hasManifest(workspaceRoot, componentPath) {
107
+ const absoluteRoot = componentPath === '.'
108
+ ? workspaceRoot
109
+ : path.join(workspaceRoot, ...componentPath.split('/'));
110
+ return [
111
+ 'package.json',
112
+ 'pom.xml',
113
+ 'requirements.txt',
114
+ 'go.mod',
115
+ 'composer.json',
116
+ ].some((fileName) => pathExists(path.join(absoluteRoot, fileName)));
117
+ }
118
+ function safeReadJson(filePath) {
119
+ try {
120
+ const parsed = JSON.parse(fs.readFileSync(filePath, { encoding: 'utf8' }));
121
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
122
+ ? parsed
123
+ : undefined;
124
+ }
125
+ catch {
126
+ return undefined;
127
+ }
128
+ }
129
+ function toStringArray(value) {
130
+ if (Array.isArray(value)) {
131
+ return value.filter((entry) => typeof entry === 'string');
132
+ }
133
+ return [];
134
+ }
135
+ function recordKeys(value) {
136
+ return value && typeof value === 'object' && !Array.isArray(value)
137
+ ? Object.keys(value)
138
+ : [];
139
+ }
140
+ function hasObject(value) {
141
+ return Boolean(value && typeof value === 'object' && !Array.isArray(value));
142
+ }
143
+ function hasPackagePublishSurface(packageJson) {
144
+ return hasObject(packageJson?.exports) ||
145
+ typeof packageJson?.main === 'string' ||
146
+ typeof packageJson?.module === 'string' ||
147
+ typeof packageJson?.types === 'string' ||
148
+ hasObject(packageJson?.publishConfig) ||
149
+ Array.isArray(packageJson?.files);
150
+ }
151
+ function absoluteComponentRoot(workspaceRoot, componentPath) {
152
+ return componentPath === '.'
153
+ ? workspaceRoot
154
+ : path.join(workspaceRoot, ...componentPath.split('/'));
155
+ }
156
+ function readPackageJson(workspaceRoot, componentPath) {
157
+ const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
158
+ return safeReadJson(path.join(absoluteRoot, 'package.json'));
159
+ }
160
+ function readTextFileSafe(filePath) {
161
+ try {
162
+ return fs.readFileSync(filePath, { encoding: 'utf8' });
163
+ }
164
+ catch {
165
+ return undefined;
166
+ }
167
+ }
168
+ function stripXmlComments(value) {
169
+ return value.replace(/<!--[\s\S]*?-->/gu, '');
170
+ }
171
+ function readFirstXmlTag(value, tagName) {
172
+ const match = value.match(new RegExp(`<${tagName}(?:\\s[^>]*)?>([\\s\\S]*?)</${tagName}>`, 'iu'));
173
+ return match?.[1]?.trim().replace(/\s+/gu, ' ');
174
+ }
175
+ function countMatches(value, pattern) {
176
+ return [...value.matchAll(pattern)].length;
177
+ }
178
+ function readMavenMetadata(workspaceRoot, componentPath) {
179
+ if (isUnderJvmResourceRoot(componentPath)) {
180
+ return undefined;
181
+ }
182
+ const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
183
+ const pomXml = readTextFileSafe(path.join(absoluteRoot, 'pom.xml'));
184
+ if (!pomXml) {
185
+ return undefined;
186
+ }
187
+ const normalizedPom = stripXmlComments(pomXml);
188
+ const packaging = readFirstXmlTag(normalizedPom, 'packaging') ?? 'jar';
189
+ const dependencyBlocks = [...normalizedPom.matchAll(/<dependency\b[\s\S]*?<\/dependency>/giu)].map((match) => match[0]);
190
+ return {
191
+ packaging,
192
+ artifactId: readFirstXmlTag(normalizedPom, 'artifactId'),
193
+ name: readFirstXmlTag(normalizedPom, 'name'),
194
+ hasPom: true,
195
+ hasModules: /<modules\b/iu.test(normalizedPom),
196
+ hasDependencyManagement: /<dependencyManagement\b/iu.test(normalizedPom),
197
+ hasSpringBootPlugin: /\bspring-boot-maven-plugin\b/iu.test(normalizedPom),
198
+ hasSpringBootRepackageGoal: /<goal>\s*repackage\s*<\/goal>/iu.test(normalizedPom),
199
+ configuredMainClass: readFirstXmlTag(normalizedPom, 'mainClass') ?? readFirstXmlTag(normalizedPom, 'start-class'),
200
+ hasSpringBootStarterDependency: dependencyBlocks.some((block) => /<artifactId>\s*spring-boot-starter(?:-[^<]+)?\s*<\/artifactId>/iu.test(block)),
201
+ hasSpringBootAutoconfigureDependency: dependencyBlocks.some((block) => /<artifactId>\s*spring-boot-autoconfigure\s*<\/artifactId>/iu.test(block)),
202
+ hasSpringBootAutoconfigureProcessor: /spring-boot-autoconfigure-processor|spring-boot-configuration-processor/iu.test(normalizedPom),
203
+ hasDocumentationTooling: /asciidoctor-maven-plugin|maven-site-plugin|doxia|antora|javadoc|<goal>\s*site\s*<\/goal>/iu.test(normalizedPom),
204
+ testScopedDependencyCount: dependencyBlocks.filter((block) => /<scope>\s*test\s*<\/scope>/iu.test(block)).length,
205
+ totalDependencyCount: dependencyBlocks.length,
206
+ hasMavenPluginConfiguration: packaging === 'maven-plugin' || /maven-plugin-plugin|<goalPrefix>|<mojo/iu.test(normalizedPom),
207
+ hasTestLifecycleConfiguration: /maven-surefire-plugin|maven-failsafe-plugin|integration-test|failsafe|surefire/iu.test(normalizedPom),
208
+ hasArquillianEvidence: /arquillian/iu.test(normalizedPom),
209
+ hasMainJava: pathExists(path.join(absoluteRoot, 'src', 'main', 'java')),
210
+ hasMainResources: pathExists(path.join(absoluteRoot, 'src', 'main', 'resources')),
211
+ hasTestJava: pathExists(path.join(absoluteRoot, 'src', 'test', 'java')),
212
+ hasTestResources: pathExists(path.join(absoluteRoot, 'src', 'test', 'resources')),
213
+ };
214
+ }
215
+ function toComponentRoot(modulePath) {
216
+ const normalized = normalizePath(modulePath);
217
+ const segments = normalized.split('/').filter((segment) => segment.length > 0);
218
+ if (segments.length === 0) {
219
+ return undefined;
220
+ }
221
+ if (segments[0] === 'src' || segments[0] === 'app' || segments[0] === 'routes') {
222
+ return '.';
223
+ }
224
+ if (['apps', 'packages', 'services', 'libs'].includes(segments[0]) && segments.length >= 2) {
225
+ return `${segments[0]}/${segments[1]}`;
226
+ }
227
+ if ((segments[0] === 'backend' || segments[0] === 'frontend') && segments.length >= 2) {
228
+ return segments[0];
229
+ }
230
+ return undefined;
231
+ }
232
+ function buildRootCandidates(input) {
233
+ const candidatesByPath = new Map();
234
+ const addCandidate = (candidatePath, evidence, architectureRoot) => {
235
+ const normalized = normalizePath(candidatePath);
236
+ const existing = candidatesByPath.get(normalized) ?? { path: normalized, evidence: [] };
237
+ addEvidence(existing.evidence, evidence);
238
+ if (architectureRoot) {
239
+ existing.architectureRoot = architectureRoot;
240
+ }
241
+ candidatesByPath.set(normalized, existing);
242
+ };
243
+ for (const root of input.architectureStyleSignals?.roots ?? []) {
244
+ addCandidate(root.root, `Detected architecture root ${root.root}`, root);
245
+ }
246
+ for (const root of input.topology.detectedRoots ?? []) {
247
+ addCandidate(root, `Detected project root ${root}`);
248
+ }
249
+ for (const moduleEntry of input.modules?.modules ?? []) {
250
+ const componentRoot = toComponentRoot(moduleEntry.path);
251
+ if (componentRoot) {
252
+ addCandidate(componentRoot, `Detected module path ${moduleEntry.path}`);
253
+ }
254
+ }
255
+ if (candidatesByPath.size === 0 && input.topology.topology === 'single_project') {
256
+ addCandidate('.', 'Detected single-project repository root');
257
+ }
258
+ return [...candidatesByPath.values()].sort((left, right) => left.path.localeCompare(right.path));
259
+ }
260
+ function readPackageName(workspaceRoot, componentPath) {
261
+ const packageJson = readPackageJson(workspaceRoot, componentPath);
262
+ const name = packageJson?.name;
263
+ return typeof name === 'string' && name.trim().length > 0 ? name.trim() : undefined;
264
+ }
265
+ function resolveName(workspaceRoot, componentPath) {
266
+ const packageName = readPackageName(workspaceRoot, componentPath);
267
+ if (packageName) {
268
+ return packageName;
269
+ }
270
+ if (componentPath === '.') {
271
+ return path.basename(workspaceRoot);
272
+ }
273
+ return componentPath.split('/').at(-1) ?? componentPath;
274
+ }
275
+ function resolveId(componentPath, usedIds) {
276
+ const base = componentPath === '.'
277
+ ? 'repo'
278
+ : componentPath
279
+ .replaceAll('/', '-')
280
+ .replace(/[^a-z0-9_-]+/giu, '-')
281
+ .replace(/^-+|-+$/gu, '')
282
+ .toLowerCase() || 'component';
283
+ let id = base;
284
+ let suffix = 2;
285
+ while (usedIds.has(id)) {
286
+ id = `${base}-${suffix}`;
287
+ suffix += 1;
288
+ }
289
+ usedIds.add(id);
290
+ return id;
291
+ }
292
+ function hasRunnableFrontendComponentEvidence(workspaceRoot, componentPath) {
293
+ const absoluteRoot = componentPath === '.'
294
+ ? workspaceRoot
295
+ : path.join(workspaceRoot, ...componentPath.split('/'));
296
+ const packageJson = readPackageJson(workspaceRoot, componentPath);
297
+ const dependencies = [
298
+ ...recordKeys(packageJson?.dependencies),
299
+ ...recordKeys(packageJson?.devDependencies),
300
+ ];
301
+ const scripts = recordKeys(packageJson?.scripts);
302
+ const hasFrontendFramework = dependencies.some((dependency) => /^(?:react|next|vue|@angular\/core|@sveltejs\/kit)$/u.test(dependency));
303
+ const hasInteractiveRunnableScript = scripts.some((script) => /^(?:dev|start|serve|preview)(?::|$)/u.test(script));
304
+ const hasBundlerConfig = [
305
+ 'next.config.js',
306
+ 'next.config.ts',
307
+ 'vite.config.js',
308
+ 'vite.config.ts',
309
+ 'angular.json',
310
+ ].some((relativePath) => pathExists(path.join(absoluteRoot, ...relativePath.split('/'))));
311
+ const hasApplicationEntry = [
312
+ 'index.html',
313
+ 'src/main.tsx',
314
+ 'src/main.ts',
315
+ 'src/App.tsx',
316
+ 'src/app',
317
+ 'pages',
318
+ ].some((relativePath) => pathExists(path.join(absoluteRoot, ...relativePath.split('/'))));
319
+ return hasFrontendFramework && (hasApplicationEntry || (hasInteractiveRunnableScript && hasBundlerConfig));
320
+ }
321
+ function isUnderJvmResourceRoot(componentPath) {
322
+ return /(^|\/)src\/main\/resources(?:\/|$)/u.test(normalizePath(componentPath).toLowerCase());
323
+ }
324
+ function hasFileUnderRoot(root, pattern) {
325
+ if (!pathExists(root)) {
326
+ return false;
327
+ }
328
+ const entries = fs.readdirSync(root, { recursive: true, withFileTypes: true });
329
+ return entries.some((entry) => entry.isFile() && pattern.test(entry.name));
330
+ }
331
+ const javaMainMethodPattern = /\bpublic\s+static\s+void\s+main\s*\(\s*String\s*(?:(?:\[\s*\]\s*)|\.\.\.\s*)[A-Za-z_$][\w$]*\s*(?:\[\s*\])?\s*\)/u;
332
+ function stripJavaLikeCommentsAndStrings(value) {
333
+ let result = '';
334
+ let index = 0;
335
+ let state = 'code';
336
+ while (index < value.length) {
337
+ const current = value[index] ?? '';
338
+ const next = value[index + 1] ?? '';
339
+ const nextTwo = value.slice(index, index + 3);
340
+ if (state === 'code') {
341
+ if (current === '/' && next === '/') {
342
+ result += ' ';
343
+ index += 2;
344
+ state = 'line-comment';
345
+ continue;
346
+ }
347
+ if (current === '/' && next === '*') {
348
+ result += ' ';
349
+ index += 2;
350
+ state = 'block-comment';
351
+ continue;
352
+ }
353
+ if (nextTwo === '"""') {
354
+ result += ' ';
355
+ index += 3;
356
+ state = 'text-block';
357
+ continue;
358
+ }
359
+ if (current === '"') {
360
+ result += ' ';
361
+ index += 1;
362
+ state = 'string';
363
+ continue;
364
+ }
365
+ if (current === "'") {
366
+ result += ' ';
367
+ index += 1;
368
+ state = 'char';
369
+ continue;
370
+ }
371
+ result += current;
372
+ index += 1;
373
+ continue;
374
+ }
375
+ if (state === 'line-comment') {
376
+ result += current === '\n' || current === '\r' ? current : ' ';
377
+ index += 1;
378
+ if (current === '\n') {
379
+ state = 'code';
380
+ }
381
+ continue;
382
+ }
383
+ if (state === 'block-comment') {
384
+ if (current === '*' && next === '/') {
385
+ result += ' ';
386
+ index += 2;
387
+ state = 'code';
388
+ continue;
389
+ }
390
+ result += current === '\n' || current === '\r' ? current : ' ';
391
+ index += 1;
392
+ continue;
393
+ }
394
+ if (state === 'text-block') {
395
+ if (nextTwo === '"""') {
396
+ result += ' ';
397
+ index += 3;
398
+ state = 'code';
399
+ continue;
400
+ }
401
+ result += current === '\n' || current === '\r' ? current : ' ';
402
+ index += 1;
403
+ continue;
404
+ }
405
+ if (state === 'string') {
406
+ if (current === '\\') {
407
+ result += ' ';
408
+ index += next ? 2 : 1;
409
+ if (next) {
410
+ result += ' ';
411
+ }
412
+ continue;
413
+ }
414
+ result += current === '\n' || current === '\r' ? current : ' ';
415
+ index += 1;
416
+ if (current === '"') {
417
+ state = 'code';
418
+ }
419
+ continue;
420
+ }
421
+ if (current === '\\') {
422
+ result += ' ';
423
+ index += next ? 2 : 1;
424
+ if (next) {
425
+ result += ' ';
426
+ }
427
+ continue;
428
+ }
429
+ result += current === '\n' || current === '\r' ? current : ' ';
430
+ index += 1;
431
+ if (current === "'") {
432
+ state = 'code';
433
+ }
434
+ }
435
+ return result;
436
+ }
437
+ function readMavenProductionSourceFiles(workspaceRoot, componentPath) {
438
+ const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
439
+ const mainRoots = [
440
+ path.join(absoluteRoot, 'src', 'main', 'java'),
441
+ path.join(absoluteRoot, 'src', 'main', 'kotlin'),
442
+ path.join(absoluteRoot, 'src', 'main', 'scala'),
443
+ ];
444
+ const files = [];
445
+ for (const sourceRoot of mainRoots) {
446
+ if (!pathExists(sourceRoot)) {
447
+ continue;
448
+ }
449
+ const entries = fs.readdirSync(sourceRoot, { recursive: true, withFileTypes: true });
450
+ for (const entry of entries) {
451
+ if (!entry.isFile() || !/\.(?:java|kt|scala)$/iu.test(entry.name)) {
452
+ continue;
453
+ }
454
+ const contents = readTextFileSafe(path.join(entry.parentPath, entry.name));
455
+ if (contents) {
456
+ files.push({ fileName: entry.name, contents });
457
+ }
458
+ }
459
+ }
460
+ return files;
461
+ }
462
+ function findMatchingBrace(value, openBraceIndex) {
463
+ let depth = 0;
464
+ for (let index = openBraceIndex; index < value.length; index += 1) {
465
+ const current = value[index];
466
+ if (current === '{') {
467
+ depth += 1;
468
+ }
469
+ else if (current === '}') {
470
+ depth -= 1;
471
+ if (depth === 0) {
472
+ return index;
473
+ }
474
+ }
475
+ }
476
+ return -1;
477
+ }
478
+ function getDeclaredPackageName(value) {
479
+ return value.match(/\bpackage\s+([a-zA-Z_$][\w$]*(?:\.[a-zA-Z_$][\w$]*)*)\s*;/u)?.[1];
480
+ }
481
+ function classNameMatchesConfiguredMainClass(className, packageName, configuredMainClass) {
482
+ const normalized = configuredMainClass.trim();
483
+ if (normalized.length === 0) {
484
+ return false;
485
+ }
486
+ return normalized === className || (packageName ? normalized === `${packageName}.${className}` : false);
487
+ }
488
+ function normalizeAnnotationName(value) {
489
+ return value.slice(value.lastIndexOf('.') + 1);
490
+ }
491
+ function hasAnnotation(annotations, annotationNames) {
492
+ return annotations.some((annotation) => annotationNames.has(normalizeAnnotationName(annotation)));
493
+ }
494
+ function extractAnnotations(annotationBlock) {
495
+ return [...annotationBlock.matchAll(/@\s*([A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*)/gu)]
496
+ .map((match) => match[1])
497
+ .filter((annotation) => Boolean(annotation));
498
+ }
499
+ function extractConcreteClassDeclarations(contents) {
500
+ const sanitized = stripJavaLikeCommentsAndStrings(contents);
501
+ const packageName = getDeclaredPackageName(sanitized);
502
+ const classPattern = /((?:@\s*[\w.]+(?:\s*\([^)]*\))?\s*)*)(?:public\s+|protected\s+|private\s+|abstract\s+|final\s+|sealed\s+|non-sealed\s+|static\s+)*class\s+([A-Za-z_$][\w$]*)[^{]*\{/gu;
503
+ const declarations = [];
504
+ for (const match of sanitized.matchAll(classPattern)) {
505
+ const annotationBlock = match[1] ?? '';
506
+ const className = match[2] ?? '';
507
+ const openBraceIndex = (match.index ?? 0) + match[0].length - 1;
508
+ const closeBraceIndex = findMatchingBrace(sanitized, openBraceIndex);
509
+ if (closeBraceIndex < 0) {
510
+ continue;
511
+ }
512
+ declarations.push({
513
+ className,
514
+ ...(packageName ? { packageName } : {}),
515
+ annotations: extractAnnotations(annotationBlock),
516
+ body: sanitized.slice(openBraceIndex + 1, closeBraceIndex),
517
+ });
518
+ }
519
+ return declarations;
520
+ }
521
+ function extractApplicationAnnotationNames(sourceFiles) {
522
+ const applicationAnnotations = new Set(['SpringBootApplication']);
523
+ let changed = true;
524
+ while (changed) {
525
+ changed = false;
526
+ for (const sourceFile of sourceFiles) {
527
+ const sanitized = stripJavaLikeCommentsAndStrings(sourceFile.contents);
528
+ const annotationPattern = /((?:@\s*[\w.]+(?:\s*\([^)]*\))?\s*)*)public\s+@interface\s+([A-Za-z_$][\w$]*)\b/gu;
529
+ for (const match of sanitized.matchAll(annotationPattern)) {
530
+ const annotations = extractAnnotations(match[1] ?? '');
531
+ const annotationName = match[2];
532
+ if (annotationName &&
533
+ !applicationAnnotations.has(annotationName) &&
534
+ hasAnnotation(annotations, applicationAnnotations)) {
535
+ applicationAnnotations.add(annotationName);
536
+ changed = true;
537
+ }
538
+ }
539
+ }
540
+ }
541
+ return applicationAnnotations;
542
+ }
543
+ function hasSpringApplicationRunForClass(body, className) {
544
+ return new RegExp(`\\bSpringApplication\\.run\\s*\\(\\s*${className}\\.class\\b`, 'u').test(body);
545
+ }
546
+ function hasIndirectSpringApplicationRunForClass(body, className) {
547
+ const helperCalls = [...body.matchAll(/\b([A-Za-z_$][\w$]*)\s*\(\s*([A-Za-z_$][\w$]*)\.class\s*,/gu)]
548
+ .filter((match) => match[2] === className)
549
+ .map((match) => match[1])
550
+ .filter((methodName) => Boolean(methodName));
551
+ return helperCalls.some((methodName) => new RegExp(`\\b${methodName}\\s*\\([^)]*\\)\\s*\\{[\\s\\S]*?\\bSpringApplication\\.run\\s*\\(`, 'u').test(body));
552
+ }
553
+ function hasConcreteSpringBootApplicationBootstrap(sourceFiles) {
554
+ const applicationAnnotations = extractApplicationAnnotationNames(sourceFiles);
555
+ const declarations = sourceFiles.flatMap((sourceFile) => extractConcreteClassDeclarations(sourceFile.contents));
556
+ const applicationClassNames = new Set(declarations
557
+ .filter((declaration) => hasAnnotation(declaration.annotations, applicationAnnotations))
558
+ .map((declaration) => declaration.className));
559
+ if (applicationClassNames.size === 0) {
560
+ return false;
561
+ }
562
+ const hasLauncherForApplicationClass = (declaration) => javaMainMethodPattern.test(declaration.body) &&
563
+ [...applicationClassNames].some((applicationClassName) => hasSpringApplicationRunForClass(declaration.body, applicationClassName) ||
564
+ (applicationClassName === declaration.className &&
565
+ hasIndirectSpringApplicationRunForClass(declaration.body, applicationClassName)));
566
+ if (declarations.some(hasLauncherForApplicationClass)) {
567
+ return true;
568
+ }
569
+ for (const sourceFile of sourceFiles) {
570
+ for (const declaration of extractConcreteClassDeclarations(sourceFile.contents)) {
571
+ if (!hasAnnotation(declaration.annotations, applicationAnnotations)) {
572
+ continue;
573
+ }
574
+ if (javaMainMethodPattern.test(declaration.body) &&
575
+ (hasSpringApplicationRunForClass(declaration.body, declaration.className) ||
576
+ hasIndirectSpringApplicationRunForClass(declaration.body, declaration.className))) {
577
+ return true;
578
+ }
579
+ }
580
+ }
581
+ return false;
582
+ }
583
+ function hasConfiguredMainClassEntrypoint(contents, configuredMainClass) {
584
+ for (const declaration of extractConcreteClassDeclarations(contents)) {
585
+ if (!classNameMatchesConfiguredMainClass(declaration.className, declaration.packageName, configuredMainClass)) {
586
+ continue;
587
+ }
588
+ if (javaMainMethodPattern.test(declaration.body)) {
589
+ return true;
590
+ }
591
+ }
592
+ return false;
593
+ }
594
+ function hasMavenMainEntrypoint(workspaceRoot, componentPath) {
595
+ return hasConcreteSpringBootApplicationBootstrap(readMavenProductionSourceFiles(workspaceRoot, componentPath));
596
+ }
597
+ function hasMavenConfiguredMainClassEntrypoint(workspaceRoot, componentPath, configuredMainClass) {
598
+ if (!configuredMainClass) {
599
+ return false;
600
+ }
601
+ return readMavenProductionSourceFiles(workspaceRoot, componentPath)
602
+ .some((sourceFile) => hasConfiguredMainClassEntrypoint(sourceFile.contents, configuredMainClass));
603
+ }
604
+ function hasMavenAutoConfigurationMetadata(workspaceRoot, componentPath) {
605
+ const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
606
+ return [
607
+ path.join(absoluteRoot, 'src', 'main', 'resources', 'META-INF', 'spring.factories'),
608
+ path.join(absoluteRoot, 'src', 'main', 'resources', 'META-INF', 'spring', 'org.springframework.boot.autoconfigure.AutoConfiguration.imports'),
609
+ ].some(pathExists);
610
+ }
611
+ function hasMavenMainJvmSource(workspaceRoot, componentPath) {
612
+ const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
613
+ return [
614
+ path.join(absoluteRoot, 'src', 'main', 'java'),
615
+ path.join(absoluteRoot, 'src', 'main', 'kotlin'),
616
+ path.join(absoluteRoot, 'src', 'main', 'scala'),
617
+ ].some((root) => hasFileUnderRoot(root, /\.(?:java|kt|scala)$/iu));
618
+ }
619
+ function hasRuntimeSourceFiles(workspaceRoot, componentPath) {
620
+ if (isUnderJvmResourceRoot(componentPath)) {
621
+ return false;
622
+ }
623
+ const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
624
+ const sourceRoots = [
625
+ path.join(absoluteRoot, 'src', 'main', 'java'),
626
+ path.join(absoluteRoot, 'src'),
627
+ path.join(absoluteRoot, 'app'),
628
+ path.join(absoluteRoot, 'server'),
629
+ ];
630
+ for (const sourceRoot of sourceRoots) {
631
+ if (!pathExists(sourceRoot)) {
632
+ continue;
633
+ }
634
+ const entries = fs.readdirSync(sourceRoot, { recursive: true, withFileTypes: true });
635
+ if (entries.some((entry) => entry.isFile() && /\.(?:ts|tsx|js|jsx|java|cs|py|php|go)$/iu.test(entry.name))) {
636
+ return true;
637
+ }
638
+ }
639
+ return false;
640
+ }
641
+ function resolveKind(workspaceRoot, candidate, localProjectKinds) {
642
+ const lowerPath = candidate.path.toLowerCase();
643
+ const packageJson = readPackageJson(workspaceRoot, candidate.path);
644
+ const maven = readMavenMetadata(workspaceRoot, candidate.path);
645
+ const hasRunnableFrontendEvidence = hasRunnableFrontendComponentEvidence(workspaceRoot, candidate.path);
646
+ const hasPublishSurface = hasPackagePublishSurface(packageJson);
647
+ const hasMavenRunnableEvidence = Boolean(maven &&
648
+ (hasMavenMainEntrypoint(workspaceRoot, candidate.path) ||
649
+ hasMavenConfiguredMainClassEntrypoint(workspaceRoot, candidate.path, maven.configuredMainClass) ||
650
+ (maven.hasSpringBootPlugin && maven.hasSpringBootRepackageGoal && hasMavenMainEntrypoint(workspaceRoot, candidate.path)) ||
651
+ (maven.packaging === 'war' && hasMavenMainEntrypoint(workspaceRoot, candidate.path))));
652
+ const hasMavenLibraryEvidence = Boolean(maven &&
653
+ !hasMavenRunnableEvidence &&
654
+ (maven.packaging === 'jar' || maven.packaging === 'maven-plugin' || maven.packaging === 'pom') &&
655
+ (hasMavenMainJvmSource(workspaceRoot, candidate.path) ||
656
+ maven.hasMainResources ||
657
+ maven.hasDependencyManagement ||
658
+ maven.hasSpringBootAutoconfigureDependency ||
659
+ maven.hasSpringBootAutoconfigureProcessor ||
660
+ hasMavenAutoConfigurationMetadata(workspaceRoot, candidate.path) ||
661
+ maven.hasDocumentationTooling ||
662
+ maven.hasTestJava ||
663
+ maven.hasTestResources));
664
+ if (lowerPath.endsWith('/db') || lowerPath.endsWith('/database') || lowerPath.endsWith('/data')) {
665
+ return 'data';
666
+ }
667
+ if (hasMavenLibraryEvidence) {
668
+ return 'library';
669
+ }
670
+ if (maven && !hasMavenRunnableEvidence && localProjectKinds.primaryKind === 'backend') {
671
+ return 'library';
672
+ }
673
+ const classification = candidate.architectureRoot?.classification;
674
+ if (classification === 'frontend_app') {
675
+ return hasPublishSurface && !hasRunnableFrontendEvidence ? 'library' : 'frontend';
676
+ }
677
+ if (classification === 'backend_app') {
678
+ return 'backend';
679
+ }
680
+ if (hasRunnableFrontendEvidence &&
681
+ localProjectKinds.primaryKind !== 'backend' &&
682
+ localProjectKinds.primaryKind !== 'service' &&
683
+ localProjectKinds.primaryKind !== 'cli') {
684
+ return 'frontend';
685
+ }
686
+ if (classification === 'shared_package') {
687
+ return 'library';
688
+ }
689
+ if (hasPublishSurface && !hasRunnableFrontendEvidence) {
690
+ return 'library';
691
+ }
692
+ if (localProjectKinds.primaryKind === 'service') {
693
+ return 'worker';
694
+ }
695
+ if (localProjectKinds.primaryKind === 'frontend') {
696
+ return 'frontend';
697
+ }
698
+ if (localProjectKinds.primaryKind === 'backend' || localProjectKinds.primaryKind === 'fullstack') {
699
+ return 'backend';
700
+ }
701
+ if (localProjectKinds.primaryKind === 'library' || localProjectKinds.primaryKind === 'cli') {
702
+ return 'library';
703
+ }
704
+ if (lowerPath.startsWith('packages/') || lowerPath.startsWith('libs/')) {
705
+ return 'library';
706
+ }
707
+ if (lowerPath.includes('infra') || lowerPath.includes('terraform')) {
708
+ return 'infrastructure';
709
+ }
710
+ if (lowerPath.endsWith('/db') || lowerPath.endsWith('/database') || lowerPath.endsWith('/data')) {
711
+ return 'data';
712
+ }
713
+ return 'unknown';
714
+ }
715
+ function resolveStack(kind, stackDetection) {
716
+ if (kind === 'frontend') {
717
+ return stackDetection.frontendStacks[0] ?? stackDetection.stacks[0];
718
+ }
719
+ if (kind === 'backend' || kind === 'worker') {
720
+ return stackDetection.backendStacks.find((stack) => stack !== 'node_typescript' && stack !== 'node_javascript') ??
721
+ stackDetection.backendStacks[0] ??
722
+ stackDetection.stacks[0];
723
+ }
724
+ if (kind === 'infrastructure') {
725
+ return stackDetection.stacks.find((stack) => stack === 'terraform' || stack === 'ansible');
726
+ }
727
+ if (kind === 'library' || kind === 'data') {
728
+ return stackDetection.stacks.find((stack) => stack !== 'other' && stack !== 'unknown');
729
+ }
730
+ return stackDetection.stacks.find((stack) => stack !== 'other' && stack !== 'unknown');
731
+ }
732
+ function resolveConfidence(input) {
733
+ if (input.kind !== 'unknown' &&
734
+ (input.architectureRoot?.classification !== 'unknown' || input.stackConfidence === 'high')) {
735
+ return 'high';
736
+ }
737
+ if (input.kind !== 'unknown' || input.stack || input.rootEvidenceCount >= 2) {
738
+ return 'medium';
739
+ }
740
+ return 'low';
741
+ }
742
+ function hasAnyToken(value, patterns) {
743
+ return patterns.some((pattern) => pattern.test(value));
744
+ }
745
+ function classifyGovernanceRole(input) {
746
+ const packageJson = readPackageJson(input.workspaceRoot, input.candidate.path);
747
+ const maven = readMavenMetadata(input.workspaceRoot, input.candidate.path);
748
+ const evidence = [];
749
+ let supportScore = 0;
750
+ let runtimeScore = 0;
751
+ const packageName = typeof packageJson?.name === 'string' ? packageJson.name : '';
752
+ const description = typeof packageJson?.description === 'string' ? packageJson.description : '';
753
+ const keywords = toStringArray(packageJson?.keywords).join(' ');
754
+ const manifestText = `${packageName} ${description} ${keywords}`.toLowerCase();
755
+ const descriptiveManifestText = `${description} ${keywords}`.toLowerCase();
756
+ const pathText = input.candidate.path.toLowerCase();
757
+ const scripts = recordKeys(packageJson?.scripts);
758
+ const dependencies = recordKeys(packageJson?.dependencies);
759
+ const devDependencies = recordKeys(packageJson?.devDependencies);
760
+ const scriptText = scripts.join(' ').toLowerCase();
761
+ const dependencyText = [...dependencies, ...devDependencies].join(' ').toLowerCase();
762
+ const hasStrongSupportPath = hasAnyToken(pathText, [
763
+ /(^|\/)(testing|test-plugins|cypress-tests|fixtures?|examples?|benchmarks?|smoke)(\/|$)/u,
764
+ /(^|\/)(dev-server|scaffold|scaffolding|generators?|devkit|tooling|tools)(\/|$)/u,
765
+ ]);
766
+ const isPlainResourcesSurface = isUnderJvmResourceRoot(pathText) &&
767
+ !hasRuntimeSourceFiles(input.workspaceRoot, input.candidate.path) &&
768
+ !packageJson &&
769
+ !maven;
770
+ const hasPublishSurface = hasPackagePublishSurface(packageJson);
771
+ const isPrivate = packageJson?.private === true;
772
+ const hasBin = hasObject(packageJson?.bin) || typeof packageJson?.bin === 'string';
773
+ const mavenMetadataText = `${maven?.artifactId ?? ''} ${maven?.name ?? ''}`.toLowerCase();
774
+ const hasMavenMainSource = Boolean(maven?.hasMainJava || maven?.hasMainResources);
775
+ const hasMavenTestSource = Boolean(maven?.hasTestJava || maven?.hasTestResources);
776
+ const hasMavenMainEntrypointEvidence = Boolean(maven && hasMavenMainEntrypoint(input.workspaceRoot, input.candidate.path));
777
+ const hasMavenMainJvmSourceEvidence = Boolean(maven && hasMavenMainJvmSource(input.workspaceRoot, input.candidate.path));
778
+ const hasMavenAutoConfigurationEvidence = Boolean(maven && (hasMavenAutoConfigurationMetadata(input.workspaceRoot, input.candidate.path) ||
779
+ maven.hasSpringBootAutoconfigureDependency ||
780
+ maven.hasSpringBootAutoconfigureProcessor));
781
+ const hasMavenExecutableConfiguration = Boolean(maven && (hasMavenConfiguredMainClassEntrypoint(input.workspaceRoot, input.candidate.path, maven.configuredMainClass) ||
782
+ (maven.hasSpringBootPlugin && maven.hasSpringBootRepackageGoal && hasMavenMainEntrypointEvidence) ||
783
+ (maven.packaging === 'war' && hasMavenMainEntrypointEvidence)));
784
+ const hasMavenRunnableApplicationEvidence = Boolean(hasMavenMainEntrypointEvidence || hasMavenExecutableConfiguration);
785
+ const isMavenPomOnly = Boolean(maven?.packaging === 'pom' && !hasMavenMainSource && !hasMavenTestSource);
786
+ const hasMavenTestContext = hasAnyToken(pathText, [
787
+ /(^|\/)(test-framework|testsuite|integration-tests?|test-apps)(\/|$)/u,
788
+ ]) && (hasAnyToken(mavenMetadataText, [/\b(test|testsuite|test framework|arquillian|integration test)\b/u]) ||
789
+ Boolean(maven?.hasTestLifecycleConfiguration || maven?.hasArquillianEvidence || hasMavenTestSource));
790
+ const hasMavenBomEvidence = Boolean(maven?.packaging === 'pom' &&
791
+ maven.hasDependencyManagement &&
792
+ !hasMavenMainSource &&
793
+ hasAnyToken(mavenMetadataText, [/\b(bom|bill of materials|dependency management|platform)\b/u]));
794
+ const hasMavenDistributionPackagingEvidence = Boolean(maven?.packaging === 'pom' &&
795
+ !hasMavenMainSource &&
796
+ hasAnyToken(pathText, [/(^|\/)(distribution|dist|downloads|assembl(y|ies)|feature-packs?)(\/|$)/u]));
797
+ if (input.candidate.architectureRoot?.classification === 'backend_app' || input.candidate.architectureRoot?.classification === 'frontend_app') {
798
+ runtimeScore += 3;
799
+ addEvidence(evidence, `Runtime architecture root signal: ${input.candidate.architectureRoot.classification}`);
800
+ }
801
+ else if (input.candidate.architectureRoot?.classification === 'shared_package') {
802
+ runtimeScore += 1;
803
+ addEvidence(evidence, 'Shared package architecture root signal');
804
+ }
805
+ if (input.localProjectKinds.primaryKind === 'backend' || input.localProjectKinds.primaryKind === 'frontend' || input.localProjectKinds.primaryKind === 'fullstack' || input.localProjectKinds.primaryKind === 'service') {
806
+ runtimeScore += 2;
807
+ addEvidence(evidence, `Runtime project kind signal: ${input.localProjectKinds.primaryKind}`);
808
+ }
809
+ if (input.kind === 'backend' || input.kind === 'frontend' || input.kind === 'worker') {
810
+ runtimeScore += 1;
811
+ }
812
+ if (input.stack && input.stack !== 'node_typescript' && input.stack !== 'node_javascript') {
813
+ runtimeScore += 1;
814
+ addEvidence(evidence, `Runtime framework stack signal: ${input.stack}`);
815
+ }
816
+ if (hasPublishSurface && !isPrivate) {
817
+ runtimeScore += 1;
818
+ addEvidence(evidence, 'Published package surface signal');
819
+ }
820
+ else if (hasPublishSurface && !hasBin) {
821
+ runtimeScore += 1;
822
+ addEvidence(evidence, 'Package entrypoint/export surface signal');
823
+ }
824
+ if (maven?.hasPom) {
825
+ addEvidence(evidence, `Maven packaging ${maven.packaging ?? 'jar'}`);
826
+ }
827
+ if (maven && (maven.packaging === 'jar' || maven.packaging === 'war') && hasMavenRunnableApplicationEvidence) {
828
+ runtimeScore += 3;
829
+ addEvidence(evidence, 'Maven executable application evidence');
830
+ }
831
+ if (maven?.packaging === 'war' && hasMavenMainJvmSourceEvidence) {
832
+ runtimeScore += 1;
833
+ addEvidence(evidence, 'Maven deployable WAR artifact');
834
+ }
835
+ if (maven && hasMavenMainSource && !hasMavenRunnableApplicationEvidence && !hasMavenTestContext && !hasMavenBomEvidence && maven.packaging !== 'maven-plugin') {
836
+ addEvidence(evidence, 'Maven library main source/resource surface');
837
+ }
838
+ if (hasMavenAutoConfigurationEvidence && !hasMavenRunnableApplicationEvidence) {
839
+ addEvidence(evidence, 'Maven Spring Boot auto-configuration/starter library evidence');
840
+ }
841
+ if (hasAnyToken(descriptiveManifestText, [/\b(e2e|end-to-end|testing|test helper|test utilities|fixtures?)\b/u])) {
842
+ supportScore += 3;
843
+ addEvidence(evidence, 'Package metadata describes test/support usage');
844
+ }
845
+ if (hasAnyToken(descriptiveManifestText, [/\b(scaffold|scaffolding|generator|codegen|template|starter|create)\b/u])) {
846
+ supportScore += 3;
847
+ addEvidence(evidence, 'Package metadata describes scaffolding/generation usage');
848
+ }
849
+ if (hasAnyToken(descriptiveManifestText, [/\b(dev server|development server|development tooling|tooling|devkit)\b/u])) {
850
+ supportScore += 2;
851
+ addEvidence(evidence, 'Package metadata describes development/tooling usage');
852
+ }
853
+ if (hasAnyToken(pathText, [
854
+ /(^|\/)(test|tests|testing|__tests__|cypress|cypress-tests|fixtures?|examples?|benchmarks?|smoke)(\/|$)/u,
855
+ /(^|\/)(dev-server|test-plugins|scaffold|scaffolding|generators?|devkit|tooling|tools)(\/|$)/u,
856
+ ])) {
857
+ supportScore += 1;
858
+ addEvidence(evidence, 'Path contains support/tooling role tokens');
859
+ }
860
+ if (scripts.length > 0 && scripts.every((script) => /^(test|e2e|smoke|bench|benchmark|lint|typecheck|dev|dev:|load-test|generate|scaffold)/u.test(script))) {
861
+ supportScore += 1;
862
+ addEvidence(evidence, 'Package scripts are dominated by development/test workflows');
863
+ }
864
+ if (hasAnyToken(scriptText, [/\b(e2e|test:|load-test|scaffold|generate|dev:server|dev:worker)\b/u])) {
865
+ supportScore += 1;
866
+ addEvidence(evidence, 'Package scripts include development/test/support workflows');
867
+ }
868
+ if (isPrivate && supportScore > 0 && !hasPublishSurface) {
869
+ supportScore += 1;
870
+ addEvidence(evidence, 'Private package without runtime publish surface');
871
+ }
872
+ if (input.localProjectKinds.primaryKind === 'cli' && (isPrivate || supportScore > 0 || hasAnyToken(dependencyText, [/\b(commander|yargs|ts-morph|schematics|yeoman|inquirer|prompts)\b/u]))) {
873
+ supportScore += 1;
874
+ addEvidence(evidence, 'CLI/tooling project kind evidence');
875
+ }
876
+ if (maven?.packaging === 'maven-plugin' && input.candidate.path !== '.') {
877
+ supportScore += 5;
878
+ addEvidence(evidence, 'Maven plugin/build-tooling module');
879
+ }
880
+ if (maven?.hasDocumentationTooling && !hasMavenMainJvmSourceEvidence) {
881
+ supportScore += 4;
882
+ addEvidence(evidence, 'Maven documentation tooling without JVM runtime source');
883
+ }
884
+ if (hasMavenBomEvidence) {
885
+ supportScore += 5;
886
+ addEvidence(evidence, 'Maven BOM/dependency-management module without runtime source');
887
+ }
888
+ if (maven && hasMavenTestSource && !hasMavenMainSource) {
889
+ supportScore += 5;
890
+ addEvidence(evidence, 'Maven test-only source layout');
891
+ }
892
+ if (hasMavenTestContext) {
893
+ supportScore += hasMavenMainSource ? 4 : 5;
894
+ addEvidence(evidence, 'Maven test-framework/testsuite context with structural test evidence');
895
+ }
896
+ if (maven?.hasTestLifecycleConfiguration || maven?.hasArquillianEvidence) {
897
+ supportScore += hasMavenMainSource ? 1 : 2;
898
+ addEvidence(evidence, 'Maven test lifecycle or Arquillian evidence');
899
+ }
900
+ if (maven &&
901
+ maven.totalDependencyCount > 0 &&
902
+ maven.testScopedDependencyCount >= 3 &&
903
+ maven.testScopedDependencyCount >= Math.ceil(maven.totalDependencyCount * 0.5) &&
904
+ !hasMavenMainSource) {
905
+ supportScore += 3;
906
+ addEvidence(evidence, 'Maven dependencies are dominated by test scope without runtime source');
907
+ }
908
+ if (maven?.packaging === 'pom' && !hasMavenMainSource) {
909
+ supportScore += 1;
910
+ addEvidence(evidence, 'Maven POM-only aggregator/packaging module');
911
+ }
912
+ if (isPlainResourcesSurface) {
913
+ supportScore += 4;
914
+ addEvidence(evidence, 'Resources-only surface without runtime source or manifest evidence');
915
+ }
916
+ if (isPlainResourcesSurface &&
917
+ input.kind !== 'infrastructure' &&
918
+ input.stack !== 'terraform' &&
919
+ input.stack !== 'ansible') {
920
+ return {
921
+ governanceRole: 'support',
922
+ governanceEvidence: uniqueSorted(evidence),
923
+ selectedByDefault: false,
924
+ };
925
+ }
926
+ if (hasMavenDistributionPackagingEvidence &&
927
+ hasAnyToken(mavenMetadataText, [/\b(docs?|documentation|metadata tests?|licenses?|maven plugins?|builds?)\b/u])) {
928
+ supportScore += 3;
929
+ addEvidence(evidence, 'Maven documentation/build/distribution packaging evidence without runtime source');
930
+ }
931
+ if ((supportScore >= 3 && supportScore > runtimeScore) ||
932
+ (hasStrongSupportPath && supportScore >= 2 && runtimeScore <= 5) ||
933
+ (maven?.packaging === 'maven-plugin' && input.candidate.path !== '.' && supportScore >= 5) ||
934
+ (maven && supportScore >= 5 && !hasMavenMainSource) ||
935
+ (maven && supportScore >= 4 && hasMavenTestContext) ||
936
+ (maven && supportScore >= 4 && hasMavenDistributionPackagingEvidence &&
937
+ hasAnyToken(mavenMetadataText, [/\b(docs?|documentation|metadata tests?|licenses?|maven plugins?|builds?)\b/u]))) {
938
+ return {
939
+ governanceRole: 'support',
940
+ governanceEvidence: uniqueSorted(evidence),
941
+ selectedByDefault: false,
942
+ };
943
+ }
944
+ if (maven && (isMavenPomOnly || hasMavenDistributionPackagingEvidence) && supportScore >= 1) {
945
+ return {
946
+ governanceRole: 'support',
947
+ governanceEvidence: uniqueSorted(evidence),
948
+ selectedByDefault: false,
949
+ };
950
+ }
951
+ if (runtimeScore >= 2) {
952
+ return {
953
+ governanceRole: 'runtime',
954
+ governanceEvidence: uniqueSorted(evidence),
955
+ selectedByDefault: true,
956
+ };
957
+ }
958
+ return {
959
+ governanceRole: 'ambiguous',
960
+ governanceEvidence: uniqueSorted(evidence.length > 0 ? evidence : ['No strong support-only governance evidence']),
961
+ selectedByDefault: true,
962
+ };
963
+ }
964
+ function maybeAddAttributedApiAndDb(component, workspaceRoot, componentPath, architectureRoot, runContext) {
965
+ const absoluteRoot = componentPath === '.'
966
+ ? workspaceRoot
967
+ : path.join(workspaceRoot, ...componentPath.split('/'));
968
+ if (!pathExists(absoluteRoot)) {
969
+ return;
970
+ }
971
+ const hints = runContext?.detectApiDbHints(absoluteRoot) ?? (0, apiDbHintDetection_1.detectApiDbHints)(absoluteRoot);
972
+ const stackDetection = runContext?.detectStacks(absoluteRoot) ?? (0, stackDetection_1.detectStacks)(absoluteRoot);
973
+ const selectedStackCandidate = stackDetection.candidates?.find((candidate) => candidate.adapterId === stackDetection.selectedAdapterId);
974
+ if (architectureRoot?.hasApiBoundary &&
975
+ hints.api.apiStyle !== 'unknown' &&
976
+ hints.api.apiStyle !== 'none') {
977
+ component.apiStyle = hints.api.apiStyle;
978
+ addEvidence(component.evidence, `Attributed ${hints.api.apiStyle.toUpperCase()} API hints to ${componentPath}`);
979
+ }
980
+ if (architectureRoot?.hasDatabaseAccess &&
981
+ hints.database.database !== 'unknown' &&
982
+ hints.database.database !== 'none') {
983
+ component.database = hints.database.database;
984
+ addEvidence(component.evidence, `Attributed ${hints.database.database} database hints to ${componentPath}`);
985
+ }
986
+ if (!component.apiStyle &&
987
+ (component.kind === 'backend' || component.kind === 'worker') &&
988
+ (selectedStackCandidate?.apiStyleHint === 'rest' || selectedStackCandidate?.apiStyleHint === 'graphql')) {
989
+ component.apiStyle = selectedStackCandidate.apiStyleHint;
990
+ addEvidence(component.evidence, `Attributed ${selectedStackCandidate.apiStyleHint.toUpperCase()} API hints from local stack evidence`);
991
+ }
992
+ }
993
+ function detectComponents(input) {
994
+ const ignoreMatcher = input.ignoreMatcher ?? (0, archpilotIgnore_1.loadArchpilotIgnoreMatcher)(input.workspaceRoot);
995
+ const manifestBackedRoots = new Set((input.topology.detectedRoots ?? []).filter((root) => !isUnderJvmResourceRoot(root)));
996
+ const rootCandidates = buildRootCandidates(input)
997
+ .filter((candidate) => !ignoreMatcher.isIgnored(candidate.path))
998
+ .filter((candidate) => !isIgnoredComponentCandidatePath(candidate.path))
999
+ .filter((candidate) => !(isUnderJvmResourceRoot(candidate.path) && !hasRuntimeSourceFiles(input.workspaceRoot, candidate.path)))
1000
+ .filter((candidate) => {
1001
+ if (input.topology.topology !== 'monorepo' || manifestBackedRoots.size === 0) {
1002
+ return true;
1003
+ }
1004
+ if (candidate.path === '.') {
1005
+ return true;
1006
+ }
1007
+ const firstSegment = candidate.path.split('/')[0];
1008
+ if (!['apps', 'packages', 'services', 'libs'].includes(firstSegment ?? '')) {
1009
+ return true;
1010
+ }
1011
+ return manifestBackedRoots.has(candidate.path) || hasManifest(input.workspaceRoot, candidate.path);
1012
+ });
1013
+ const usedIds = new Set();
1014
+ const detectedComponents = [];
1015
+ const summaryEvidence = [];
1016
+ for (const candidate of rootCandidates) {
1017
+ const absoluteRoot = candidate.path === '.'
1018
+ ? input.workspaceRoot
1019
+ : path.join(input.workspaceRoot, ...candidate.path.split('/'));
1020
+ if (!pathExists(absoluteRoot)) {
1021
+ continue;
1022
+ }
1023
+ const localProjectKinds = input.runContext?.detectProjectKinds(absoluteRoot) ?? (0, projectKindDetection_1.detectProjectKinds)(absoluteRoot);
1024
+ const stackDetection = input.runContext?.detectStacks(absoluteRoot) ?? (0, stackDetection_1.detectStacks)(absoluteRoot);
1025
+ const kind = resolveKind(input.workspaceRoot, candidate, localProjectKinds);
1026
+ const stack = resolveStack(kind, stackDetection);
1027
+ const evidence = [...candidate.evidence];
1028
+ if (candidate.architectureRoot?.classification && candidate.architectureRoot.classification !== 'unknown') {
1029
+ addEvidence(evidence, `Classified from architecture root signal: ${candidate.architectureRoot.classification}`);
1030
+ }
1031
+ if (localProjectKinds.primaryKind !== 'unknown') {
1032
+ addEvidence(evidence, `Detected project kind ${localProjectKinds.primaryKind}`);
1033
+ }
1034
+ if (stack && stack !== 'other' && stack !== 'unknown') {
1035
+ const label = stackMetadata_1.canonicalStackLabels[stack] ?? stack;
1036
+ addEvidence(evidence, `Detected stack ${label}`);
1037
+ }
1038
+ const component = {
1039
+ id: resolveId(candidate.path, usedIds),
1040
+ name: resolveName(input.workspaceRoot, candidate.path),
1041
+ kind,
1042
+ path: candidate.path,
1043
+ ...(stack && stack !== 'other' && stack !== 'unknown' ? { stack } : {}),
1044
+ confidence: resolveConfidence({
1045
+ kind,
1046
+ stack,
1047
+ stackConfidence: stackDetection.confidence,
1048
+ architectureRoot: candidate.architectureRoot,
1049
+ rootEvidenceCount: evidence.length,
1050
+ }),
1051
+ evidence: uniqueSorted(evidence),
1052
+ };
1053
+ maybeAddAttributedApiAndDb(component, input.workspaceRoot, candidate.path, candidate.architectureRoot, input.runContext);
1054
+ const governance = classifyGovernanceRole({
1055
+ workspaceRoot: input.workspaceRoot,
1056
+ candidate,
1057
+ kind,
1058
+ stack,
1059
+ localProjectKinds,
1060
+ });
1061
+ component.governanceRole = governance.governanceRole;
1062
+ component.governanceEvidence = governance.governanceEvidence;
1063
+ component.selectedByDefault = governance.selectedByDefault;
1064
+ for (const item of governance.governanceEvidence) {
1065
+ addEvidence(component.evidence, item);
1066
+ }
1067
+ component.evidence = uniqueSorted(component.evidence);
1068
+ detectedComponents.push(component);
1069
+ addEvidence(summaryEvidence, `Detected ${component.kind} component at ${component.path}`);
1070
+ }
1071
+ const confidence = detectedComponents.some((component) => component.confidence === 'high')
1072
+ ? 'high'
1073
+ : detectedComponents.some((component) => component.confidence === 'medium')
1074
+ ? 'medium'
1075
+ : 'low';
1076
+ return {
1077
+ detectedComponents: detectedComponents.sort((left, right) => left.path.localeCompare(right.path)),
1078
+ confidence,
1079
+ evidence: summaryEvidence.length > 0
1080
+ ? uniqueSorted(summaryEvidence)
1081
+ : ['No clear component roots detected'],
1082
+ };
1083
+ }
1084
+ //# sourceMappingURL=componentDetection.js.map