@archpilotlabs/archpilot 0.2.1 → 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 +1036 -341
  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
@@ -140818,9 +140818,9 @@ ${lanes.join("\n")}
140818
140818
  /*ignoreCase*/
140819
140819
  false
140820
140820
  )) {
140821
- const basename8 = getBaseFileName(a.fileName);
140822
- if (basename8 === "lib.d.ts" || basename8 === "lib.es6.d.ts") return 0;
140823
- const name = removeSuffix(removePrefix(basename8, "lib."), ".d.ts");
140821
+ const basename9 = getBaseFileName(a.fileName);
140822
+ if (basename9 === "lib.d.ts" || basename9 === "lib.es6.d.ts") return 0;
140823
+ const name = removeSuffix(removePrefix(basename9, "lib."), ".d.ts");
140824
140824
  const index = libs.indexOf(name);
140825
140825
  if (index !== -1) return index + 1;
140826
140826
  }
@@ -204566,8 +204566,8 @@ ${options.prefix}` : "\n" : options.prefix
204566
204566
  }
204567
204567
  };
204568
204568
  for (const file of files) {
204569
- const basename8 = getBaseFileName(file);
204570
- if (basename8 === "package.json" || basename8 === "bower.json") {
204569
+ const basename9 = getBaseFileName(file);
204570
+ if (basename9 === "package.json" || basename9 === "bower.json") {
204571
204571
  createProjectWatcher(
204572
204572
  file,
204573
204573
  "FileWatcher"
@@ -208239,8 +208239,8 @@ All files are: ${JSON.stringify(names)}`,
208239
208239
  var _a;
208240
208240
  const fileOrDirectoryPath = removeIgnoredPath(this.toPath(fileOrDirectory));
208241
208241
  if (!fileOrDirectoryPath) return;
208242
- const basename8 = getBaseFileName(fileOrDirectoryPath);
208243
- if (((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size) && (basename8 === "package.json" || basename8 === "node_modules")) {
208242
+ const basename9 = getBaseFileName(fileOrDirectoryPath);
208243
+ if (((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size) && (basename9 === "package.json" || basename9 === "node_modules")) {
208244
208244
  result.affectedModuleSpecifierCacheProjects.forEach((project) => {
208245
208245
  var _a2;
208246
208246
  (_a2 = project.getModuleSpecifierCache()) == null ? void 0 : _a2.clear();
@@ -215175,9 +215175,9 @@ function pathHasFileExtension(value) {
215175
215175
  function isRelativeImport(importSpecifier) {
215176
215176
  return importSpecifier === "." || importSpecifier === ".." || importSpecifier.startsWith("./") || importSpecifier.startsWith("../");
215177
215177
  }
215178
- function isPathInsideOrEqual(childPath, parentPath) {
215179
- const child = normalizePath2(childPath).toLowerCase();
215180
- const parent = normalizePath2(parentPath).toLowerCase();
215178
+ function isNormalizedPathInsideOrEqual(normalizedChildPath, normalizedParentPath) {
215179
+ const child = normalizedChildPath.toLowerCase();
215180
+ const parent = normalizedParentPath.toLowerCase();
215181
215181
  return child === parent || child.startsWith(`${parent}/`);
215182
215182
  }
215183
215183
  function toEndpoint(candidate) {
@@ -215196,38 +215196,43 @@ function compareCandidates(left, right) {
215196
215196
  }
215197
215197
  return left.component.id.localeCompare(right.component.id);
215198
215198
  }
215199
- function modulePathMatchScore(inputPath, modulePath) {
215200
- const normalizedModulePath = normalizePath2(modulePath);
215199
+ function normalizedModulePathMatchScore(normalizedInputPath, normalizedModulePath) {
215201
215200
  if (pathHasFileExtension(normalizedModulePath)) {
215202
- return isPathInsideOrEqual(inputPath, normalizedModulePath) || isPathInsideOrEqual(normalizedModulePath, inputPath) ? normalizedModulePath.length + 1e3 : void 0;
215201
+ return isNormalizedPathInsideOrEqual(normalizedInputPath, normalizedModulePath) || isNormalizedPathInsideOrEqual(normalizedModulePath, normalizedInputPath) ? normalizedModulePath.length + 1e3 : void 0;
215203
215202
  }
215204
- return isPathInsideOrEqual(inputPath, normalizedModulePath) ? normalizedModulePath.length + 1e3 : void 0;
215203
+ return isNormalizedPathInsideOrEqual(normalizedInputPath, normalizedModulePath) ? normalizedModulePath.length + 1e3 : void 0;
215204
+ }
215205
+ function modulePathMatchScore(inputPath, modulePath) {
215206
+ return normalizedModulePathMatchScore(normalizePath2(inputPath), normalizePath2(modulePath));
215205
215207
  }
215206
215208
  function findComponentForPath(components, inputPath) {
215207
215209
  const normalizedInputPath = normalizePath2(inputPath);
215208
215210
  const candidates = [];
215209
215211
  for (const component of components) {
215210
- for (const [moduleId, moduleReference] of Object.entries(component.modules)) {
215211
- if (!moduleReference.path) {
215212
+ for (const moduleReference of component.modules) {
215213
+ if (!moduleReference.normalizedPath) {
215212
215214
  continue;
215213
215215
  }
215214
- const score = modulePathMatchScore(normalizedInputPath, moduleReference.path);
215216
+ const score = normalizedModulePathMatchScore(
215217
+ normalizedInputPath,
215218
+ moduleReference.normalizedPath
215219
+ );
215215
215220
  if (score !== void 0) {
215216
215221
  candidates.push({
215217
- component,
215218
- moduleId,
215222
+ component: component.component,
215223
+ moduleId: moduleReference.moduleId,
215219
215224
  path: moduleReference.path,
215220
215225
  ownership: "module-path",
215221
215226
  score
215222
215227
  });
215223
215228
  }
215224
215229
  }
215225
- if (component.path && isPathInsideOrEqual(normalizedInputPath, component.path)) {
215230
+ if (component.normalizedPath && isNormalizedPathInsideOrEqual(normalizedInputPath, component.normalizedPath)) {
215226
215231
  candidates.push({
215227
- component,
215228
- path: component.path,
215232
+ component: component.component,
215233
+ path: component.component.path,
215229
215234
  ownership: "component-path",
215230
- score: normalizePath2(component.path).length
215235
+ score: component.normalizedPath.length
215231
215236
  });
215232
215237
  }
215233
215238
  }
@@ -215238,19 +215243,20 @@ function findComponentForModuleSpecifier(components, importSpecifier) {
215238
215243
  const normalizedSegments = normalizedImport.split("/").filter((segment) => segment.length > 0);
215239
215244
  const candidates = [];
215240
215245
  for (const component of components) {
215241
- for (const [moduleId, moduleReference] of Object.entries(component.modules)) {
215246
+ for (const moduleReference of component.modules) {
215247
+ const moduleId = moduleReference.moduleId;
215242
215248
  if (normalizedImport === moduleId || normalizedImport.startsWith(`${moduleId}/`)) {
215243
215249
  candidates.push({
215244
- component,
215250
+ component: component.component,
215245
215251
  moduleId,
215246
215252
  ...moduleReference.path ? { path: moduleReference.path } : {},
215247
215253
  ownership: moduleReference.path ? "module-path" : "component-path",
215248
215254
  score: moduleId.length + 500
215249
215255
  });
215250
215256
  }
215251
- if (component.id === VIRTUAL_WORKSPACE_COMPONENT_ID && normalizedSegments.includes(moduleId)) {
215257
+ if (component.component.id === VIRTUAL_WORKSPACE_COMPONENT_ID && normalizedSegments.includes(moduleId)) {
215252
215258
  candidates.push({
215253
- component,
215259
+ component: component.component,
215254
215260
  moduleId,
215255
215261
  ...moduleReference.path ? { path: moduleReference.path } : {},
215256
215262
  ownership: "virtual-workspace",
@@ -215258,20 +215264,20 @@ function findComponentForModuleSpecifier(components, importSpecifier) {
215258
215264
  });
215259
215265
  }
215260
215266
  }
215261
- if (component.path && isPathInsideOrEqual(normalizedImport, component.path)) {
215267
+ if (component.normalizedPath && isNormalizedPathInsideOrEqual(normalizedImport, component.normalizedPath)) {
215262
215268
  candidates.push({
215263
- component,
215264
- path: component.path,
215269
+ component: component.component,
215270
+ path: component.component.path,
215265
215271
  ownership: "component-path",
215266
- score: normalizePath2(component.path).length
215272
+ score: component.normalizedPath.length
215267
215273
  });
215268
215274
  }
215269
- if (normalizedImport === component.id || normalizedImport.startsWith(`${component.id}/`)) {
215275
+ if (normalizedImport === component.component.id || normalizedImport.startsWith(`${component.component.id}/`)) {
215270
215276
  candidates.push({
215271
- component,
215272
- ...component.path ? { path: component.path } : {},
215273
- ownership: component.path ? "component-path" : "virtual-workspace",
215274
- score: component.id.length
215277
+ component: component.component,
215278
+ ...component.component.path ? { path: component.component.path } : {},
215279
+ ownership: component.component.path ? "component-path" : "virtual-workspace",
215280
+ score: component.component.id.length
215275
215281
  });
215276
215282
  }
215277
215283
  }
@@ -215315,12 +215321,12 @@ function resolveSourceCandidate(contract, components, sourceFile) {
215315
215321
  return directMatch;
215316
215322
  }
215317
215323
  const virtualComponent = components.find(
215318
- (component) => component.id === VIRTUAL_WORKSPACE_COMPONENT_ID
215319
- );
215324
+ (component) => component.component.id === VIRTUAL_WORKSPACE_COMPONENT_ID
215325
+ )?.component;
215320
215326
  if (virtualComponent) {
215321
215327
  return resolveLegacyVirtualSource(contract, sourceFile, virtualComponent);
215322
215328
  }
215323
- const fallback = [...components].sort((left, right) => left.id.localeCompare(right.id))[0];
215329
+ const fallback = [...components].map((component) => component.component).sort((left, right) => left.id.localeCompare(right.id))[0];
215324
215330
  if (fallback) {
215325
215331
  return {
215326
215332
  component: fallback,
@@ -215331,7 +215337,7 @@ function resolveSourceCandidate(contract, components, sourceFile) {
215331
215337
  }
215332
215338
  throw new Error("Architecture dependency context requires at least one normalized component.");
215333
215339
  }
215334
- function resolveTargetCandidate(components, sourceFile, importSpecifier) {
215340
+ function resolveTargetCandidate(contract, components, sourceFile, importSpecifier) {
215335
215341
  if (isRelativeImport(importSpecifier)) {
215336
215342
  const resolvedTargetPath = resolveRelativeImportPath(sourceFile, importSpecifier);
215337
215343
  return {
@@ -215340,7 +215346,8 @@ function resolveTargetCandidate(components, sourceFile, importSpecifier) {
215340
215346
  };
215341
215347
  }
215342
215348
  const normalizedImport = normalizeImportPath(importSpecifier);
215343
- if (normalizedImport.startsWith("src/") || normalizedImport.startsWith("apps/") || normalizedImport.startsWith("services/") || normalizedImport.startsWith("packages/") || normalizedImport.startsWith("libs/") || normalizedImport.startsWith("libraries/") || normalizedImport.startsWith("workers/")) {
215349
+ const normalizedModulesRoot = normalizePath2(resolveModulesRootFromContract(contract));
215350
+ if (normalizedModulesRoot.length > 0 && normalizedImport.startsWith(`${normalizedModulesRoot}/`) || normalizedImport.startsWith("src/") || normalizedImport.startsWith("app/") || normalizedImport.startsWith("apps/") || normalizedImport.startsWith("services/") || normalizedImport.startsWith("packages/") || normalizedImport.startsWith("libs/") || normalizedImport.startsWith("libraries/") || normalizedImport.startsWith("workers/")) {
215344
215351
  return {
215345
215352
  candidate: findComponentForPath(components, normalizedImport),
215346
215353
  resolvedTargetPath: normalizedImport
@@ -215352,20 +215359,28 @@ function resolveTargetCandidate(components, sourceFile, importSpecifier) {
215352
215359
  }
215353
215360
  return {};
215354
215361
  }
215355
- function resolveDependencyContext(contract, input2) {
215356
- const model = normalizeArchitectureWorkspaceModel(contract);
215357
- const sourceCandidate = resolveSourceCandidate(contract, model.components, input2.sourceFile);
215362
+ function prepareComponentReferences(components) {
215363
+ return components.map((component) => ({
215364
+ component,
215365
+ ...component.path ? { normalizedPath: normalizePath2(component.path) } : {},
215366
+ modules: Object.entries(component.modules).map(([moduleId, moduleReference]) => ({
215367
+ moduleId,
215368
+ ...moduleReference.path ? {
215369
+ path: moduleReference.path,
215370
+ normalizedPath: normalizePath2(moduleReference.path)
215371
+ } : {}
215372
+ }))
215373
+ }));
215374
+ }
215375
+ function resolveDependencyContextWithPreparedComponents(contract, components, input2) {
215376
+ const sourceCandidate = resolveSourceCandidate(contract, components, input2.sourceFile);
215358
215377
  const { candidate: resolvedTargetCandidate, resolvedTargetPath } = resolveTargetCandidate(
215359
- model.components,
215378
+ contract,
215379
+ components,
215360
215380
  input2.sourceFile,
215361
215381
  input2.importSpecifier
215362
215382
  );
215363
- const targetCandidate = resolvedTargetCandidate ?? (resolvedTargetPath ? {
215364
- ...sourceCandidate,
215365
- path: resolvedTargetPath,
215366
- ownership: sourceCandidate.ownership,
215367
- score: 0
215368
- } : void 0);
215383
+ const targetCandidate = resolvedTargetCandidate ?? (resolvedTargetPath ? resolveSourceCandidate(contract, components, resolvedTargetPath) : void 0);
215369
215384
  if (!targetCandidate) {
215370
215385
  return {
215371
215386
  dependencyType: "external",
@@ -215386,6 +215401,19 @@ function resolveDependencyContext(contract, input2) {
215386
215401
  isExternal: false
215387
215402
  };
215388
215403
  }
215404
+ function createArchitectureDependencyContextResolver(contract) {
215405
+ const model = normalizeArchitectureWorkspaceModel(contract);
215406
+ const components = prepareComponentReferences(model.components);
215407
+ return {
215408
+ contract,
215409
+ model,
215410
+ resolve: (input2) => resolveDependencyContextWithPreparedComponents(
215411
+ contract,
215412
+ components,
215413
+ input2
215414
+ )
215415
+ };
215416
+ }
215389
215417
  var path6;
215390
215418
  var init_architectureDependencyContext = __esm({
215391
215419
  "../core/src/architectureDependencyContext.ts"() {
@@ -215396,17 +215424,85 @@ var init_architectureDependencyContext = __esm({
215396
215424
  }
215397
215425
  });
215398
215426
 
215427
+ // ../core/src/sourceScopeClassification.ts
215428
+ function normalizePath3(value) {
215429
+ return value.replace(/\\/g, "/").toLowerCase();
215430
+ }
215431
+ function hasPathSegment(pathValue, pattern) {
215432
+ return pathValue.split("/").some((segment) => pattern.test(segment));
215433
+ }
215434
+ function hasTopLevelPathSegment(pathValue, pattern) {
215435
+ const [firstSegment] = pathValue.split("/");
215436
+ return !!firstSegment && pattern.test(firstSegment);
215437
+ }
215438
+ function classifyValidationSourceScope(relativePath) {
215439
+ const normalized = normalizePath3(relativePath);
215440
+ const fileName = normalized.split("/").at(-1) ?? normalized;
215441
+ const extension = fileName.includes(".") ? fileName.slice(fileName.lastIndexOf(".")) : "";
215442
+ const isTestFile = /\.(?:spec|test|e2e-spec|integration-test)\.(?:ts|tsx|js|jsx|mjs|cjs|java|cs|py|php|go)$/u.test(fileName);
215443
+ const isE2e = isTestFile && /(?:^|[./_-])e2e(?:[./_-]|$)/u.test(fileName) || hasPathSegment(normalized, /^e2e$/u);
215444
+ const isFixture = hasPathSegment(normalized, /^(?:fixtures?|__fixtures__)$/u);
215445
+ const isTestPlugin = hasPathSegment(normalized, /^(?:test-plugins?|testing-plugins?)$/u);
215446
+ const isExamplePlugin = hasPathSegment(normalized, /^example-plugins?$/u) || hasTopLevelPathSegment(normalized, /^examples?$/u);
215447
+ const isGenerated = hasPathSegment(normalized, /^(?:generated|__generated__|gen|templates?)$/u) || /\.(?:generated|gen|g)\.(?:ts|tsx|js|jsx|java|cs|py|php|go)$/u.test(fileName) || /\.d\.ts$/u.test(fileName);
215448
+ const isMigration = hasPathSegment(normalized, /^(?:migrations?|schema-migrations?|data-migrations|migration-utils?)$/u);
215449
+ const isCliTooling = hasPathSegment(normalized, /^(?:cli|bin|scripts?|tools?|scaffold|scaffolding|generators?)$/u) || /(?:^|[./_-])(?:cli|script|tool|generator|scaffold)(?:[./_-]|$)/u.test(fileName);
215450
+ const isFrontend = extension === ".tsx" || extension === ".jsx" || hasPathSegment(normalized, /^(?:frontend|client|browser|ui|admin-ui|dashboard|web-app)$/u) || /\b(?:react|angular|vue|svelte)\b/u.test(normalized);
215451
+ const isInfrastructure = hasPathSegment(normalized, /^(?:infrastructure|infra|framework|adapters?|persistence|providers?)$/u) || /(?:transactional-connection|transaction-wrapper|transaction-subscriber|transaction-manager|query-runner|query-builder|event-bus|telemetry|interceptor)\.(?:ts|js|java|cs|py|php|go)$/u.test(fileName);
215452
+ let category = "production-backend";
215453
+ if (isGenerated) {
215454
+ category = "generated";
215455
+ } else if (isE2e) {
215456
+ category = "e2e";
215457
+ } else if (isTestFile || hasPathSegment(normalized, /^(?:test|tests|__tests__|spec|specs|__mocks__|cypress|cypress-tests)$/u)) {
215458
+ category = "test";
215459
+ } else if (isTestPlugin) {
215460
+ category = "test-plugin";
215461
+ } else if (isExamplePlugin) {
215462
+ category = "example-plugin";
215463
+ } else if (isFixture) {
215464
+ category = "fixture";
215465
+ } else if (isMigration) {
215466
+ category = "migration";
215467
+ } else if (isCliTooling) {
215468
+ category = "cli-tooling";
215469
+ } else if (isFrontend) {
215470
+ category = "production-frontend";
215471
+ } else if (isInfrastructure) {
215472
+ category = "infrastructure";
215473
+ }
215474
+ const isTestLike = category === "test" || category === "e2e" || category === "fixture" || category === "test-plugin" || category === "example-plugin";
215475
+ return {
215476
+ category,
215477
+ isProduction: category === "production-backend" || category === "production-frontend" || category === "infrastructure",
215478
+ isFrontend: category === "production-frontend",
215479
+ isTestLike,
215480
+ isGenerated: category === "generated",
215481
+ isMigration: category === "migration",
215482
+ isCliTooling: category === "cli-tooling",
215483
+ isInfrastructure: category === "infrastructure"
215484
+ };
215485
+ }
215486
+ function isProductionBackendGovernanceScope(scope) {
215487
+ return scope.category === "production-backend";
215488
+ }
215489
+ var init_sourceScopeClassification = __esm({
215490
+ "../core/src/sourceScopeClassification.ts"() {
215491
+ "use strict";
215492
+ }
215493
+ });
215494
+
215399
215495
  // ../core/src/dependencyValidation.ts
215400
- function normalizePath3(filePath) {
215496
+ function normalizePath4(filePath) {
215401
215497
  return filePath.replace(/\\/g, "/");
215402
215498
  }
215403
215499
  function toSafeContractModuleFileStem(moduleName) {
215404
- return normalizePath3(moduleName).split("/").map((segment) => segment.trim()).filter((segment) => segment.length > 0).join(".");
215500
+ return normalizePath4(moduleName).split("/").map((segment) => segment.trim()).filter((segment) => segment.length > 0).join(".");
215405
215501
  }
215406
215502
  function normalizeAbsolutePath(filePath) {
215407
- return normalizePath3(path7.resolve(filePath)).toLowerCase();
215503
+ return normalizePath4(path7.resolve(filePath)).toLowerCase();
215408
215504
  }
215409
- function isPathInsideOrEqual2(childPath, parentPath) {
215505
+ function isPathInsideOrEqual(childPath, parentPath) {
215410
215506
  const child = normalizeAbsolutePath(childPath);
215411
215507
  const parent = normalizeAbsolutePath(parentPath);
215412
215508
  return child === parent || child.startsWith(`${parent}/`);
@@ -215442,7 +215538,7 @@ function getComponentModuleRoots(workspaceRoot, architectureContract) {
215442
215538
  }
215443
215539
  const typed = value;
215444
215540
  const componentId = typeof typed.id === "string" && typed.id.trim().length > 0 ? typed.id.trim() : typeof key === "string" && key.trim().length > 0 ? key.trim() : void 0;
215445
- const componentPath = typeof typed.path === "string" && typed.path.trim().length > 0 ? normalizePath3(typed.path.trim()) : void 0;
215541
+ const componentPath = typeof typed.path === "string" && typed.path.trim().length > 0 ? normalizePath4(typed.path.trim()) : void 0;
215446
215542
  if (!componentId || !componentPath || componentPath === ".") {
215447
215543
  continue;
215448
215544
  }
@@ -215487,6 +215583,9 @@ function buildChildModulesByParent(hierarchyEdges) {
215487
215583
  ])
215488
215584
  );
215489
215585
  }
215586
+ function isIsolatedContractlessHierarchyModule(input2) {
215587
+ return !input2.hasContract && input2.parentModule !== void 0 && input2.declaredDependencies.length === 0 && input2.actualDependencies.length === 0 && input2.inboundDeclaredFrom.length === 0 && input2.inboundActualFrom.length === 0 && input2.unusedDeclaredDependencies.length === 0 && input2.undeclaredActualDependencies.length === 0;
215588
+ }
215490
215589
  function getScriptKind(filePath) {
215491
215590
  const extension = path7.extname(filePath).toLowerCase();
215492
215591
  switch (extension) {
@@ -215642,9 +215741,9 @@ async function buildTsConfigPathAliasMap(workspaceRoot, moduleRoots) {
215642
215741
  continue;
215643
215742
  }
215644
215743
  const isWildcard = /\/\*$/u.test(aliasPattern) && /\/\*$/u.test(targetPattern);
215645
- const normalizedTarget = normalizePath3(targetPattern).replace(/\/\*$/u, "");
215744
+ const normalizedTarget = normalizePath4(targetPattern).replace(/\/\*$/u, "");
215646
215745
  const absoluteTarget = path7.join(workspaceRoot, ...normalizedTarget.split("/"));
215647
- const moduleEntry = [...moduleRoots.entries()].filter(([, moduleRoot2]) => isPathInsideOrEqual2(absoluteTarget, moduleRoot2)).sort((left, right) => right[1].length - left[1].length || left[0].localeCompare(right[0]))[0];
215746
+ const moduleEntry = [...moduleRoots.entries()].filter(([, moduleRoot2]) => isPathInsideOrEqual(absoluteTarget, moduleRoot2)).sort((left, right) => right[1].length - left[1].length || left[0].localeCompare(right[0]))[0];
215648
215747
  if (!moduleEntry) {
215649
215748
  continue;
215650
215749
  }
@@ -215745,7 +215844,7 @@ async function findModuleRoots(workspaceRoot, modulesRootRelativePath = "src/mod
215745
215844
  if (!configuredPath || typeof configuredPath !== "string") {
215746
215845
  continue;
215747
215846
  }
215748
- const normalizedConfiguredPath = normalizePath3(configuredPath);
215847
+ const normalizedConfiguredPath = normalizePath4(configuredPath);
215749
215848
  if (/\.[a-z0-9]+$/iu.test(normalizedConfiguredPath)) {
215750
215849
  continue;
215751
215850
  }
@@ -215853,7 +215952,7 @@ async function buildExplicitStandaloneModulePathMap(workspaceRoot, architectureC
215853
215952
  if (!configuredPath || typeof configuredPath !== "string") {
215854
215953
  continue;
215855
215954
  }
215856
- const normalizedConfiguredPath = normalizePath3(configuredPath);
215955
+ const normalizedConfiguredPath = normalizePath4(configuredPath);
215857
215956
  if (!/\.[a-z0-9]+$/iu.test(normalizedConfiguredPath)) {
215858
215957
  continue;
215859
215958
  }
@@ -215869,11 +215968,7 @@ async function buildExplicitStandaloneModulePathMap(workspaceRoot, architectureC
215869
215968
  return map;
215870
215969
  }
215871
215970
  function isTestSourcePath(relativePath) {
215872
- const normalized = normalizePath3(relativePath).toLowerCase();
215873
- if (normalized.includes("/__tests__/") || normalized.includes("/test/") || normalized.includes("/tests/") || normalized.includes("/__mocks__/")) {
215874
- return true;
215875
- }
215876
- return /(^|\/)[^/]+\.(test|spec)\.[cm]?[jt]sx?$/u.test(normalized);
215971
+ return classifyValidationSourceScope(relativePath).isTestLike;
215877
215972
  }
215878
215973
  async function collectSourceFiles(directoryPath, adapter, scanRootPath = directoryPath, excludedDirectoryRoots = []) {
215879
215974
  const entries = await import_node_fs6.promises.readdir(directoryPath, { withFileTypes: true });
@@ -215883,11 +215978,11 @@ async function collectSourceFiles(directoryPath, adapter, scanRootPath = directo
215883
215978
  const fullPath = path7.join(directoryPath, entry.name);
215884
215979
  if (entry.isDirectory()) {
215885
215980
  if (excludedDirectoryRoots.some(
215886
- (excludedRoot) => isPathInsideOrEqual2(fullPath, excludedRoot)
215981
+ (excludedRoot) => isPathInsideOrEqual(fullPath, excludedRoot)
215887
215982
  )) {
215888
215983
  continue;
215889
215984
  }
215890
- const normalizedRelativeDirectory = normalizePath3(
215985
+ const normalizedRelativeDirectory = normalizePath4(
215891
215986
  path7.relative(scanRootPath, fullPath)
215892
215987
  );
215893
215988
  if (adapter.ignoreDirectoryNames.includes(entry.name) || adapter.ignoreDirectoryNames.includes(normalizedRelativeDirectory)) {
@@ -216098,6 +216193,80 @@ function extractGoImportSpecifiers(sourceText) {
216098
216193
  return left.specifier.localeCompare(right.specifier);
216099
216194
  });
216100
216195
  }
216196
+ function extractJavaPackageName(sourceText) {
216197
+ const match = /^\s*package\s+([a-zA-Z_][\w.]*)\s*;/mu.exec(sourceText);
216198
+ return match?.[1];
216199
+ }
216200
+ async function buildJavaImportIndex(workspaceRoot, moduleRoots, adapter) {
216201
+ const classes = /* @__PURE__ */ new Map();
216202
+ const packageCandidates = /* @__PURE__ */ new Map();
216203
+ for (const [moduleId, moduleRoot] of [...moduleRoots.entries()].sort(
216204
+ ([left], [right]) => left.localeCompare(right)
216205
+ )) {
216206
+ const childModuleRoots = [...moduleRoots.entries()].filter(([childModuleName, childModuleRoot]) => childModuleName !== moduleId && isPathInsideOrEqual(childModuleRoot, moduleRoot)).map(([, childModuleRoot]) => childModuleRoot);
216207
+ const sourceFiles = await collectSourceFiles(moduleRoot, adapter, moduleRoot, childModuleRoots);
216208
+ for (const sourceFilePath of sourceFiles) {
216209
+ const relativePath = normalizePath4(path7.relative(workspaceRoot, sourceFilePath));
216210
+ if (isTestSourcePath(relativePath)) {
216211
+ continue;
216212
+ }
216213
+ const sourceText = await readTextFileIfExists2(sourceFilePath);
216214
+ if (!sourceText) {
216215
+ continue;
216216
+ }
216217
+ const packageName = extractJavaPackageName(sourceText);
216218
+ if (!packageName) {
216219
+ continue;
216220
+ }
216221
+ const className = path7.basename(sourceFilePath, path7.extname(sourceFilePath));
216222
+ const entry = { moduleId, resolvedPath: sourceFilePath };
216223
+ classes.set(`${packageName}.${className}`, entry);
216224
+ const existing = packageCandidates.get(packageName) ?? [];
216225
+ existing.push(entry);
216226
+ packageCandidates.set(packageName, existing);
216227
+ }
216228
+ }
216229
+ const packages = /* @__PURE__ */ new Map();
216230
+ for (const [packageName, entries] of packageCandidates) {
216231
+ const moduleIds = new Set(entries.map((entry) => entry.moduleId));
216232
+ packages.set(packageName, moduleIds.size === 1 ? entries[0] : "ambiguous");
216233
+ }
216234
+ return { classes, packages };
216235
+ }
216236
+ function resolveJavaImportFromIndex(importSpecifier, index, workspaceRoot) {
216237
+ if (!index) {
216238
+ return void 0;
216239
+ }
216240
+ if (importSpecifier.endsWith(".*")) {
216241
+ const packageName = importSpecifier.slice(0, -2);
216242
+ const entry = index.packages.get(packageName);
216243
+ if (!entry || entry === "ambiguous") {
216244
+ return void 0;
216245
+ }
216246
+ return {
216247
+ targetModule: entry.moduleId,
216248
+ resolvedRelativePath: normalizePath4(path7.relative(workspaceRoot, entry.resolvedPath)),
216249
+ isPublicImport: false
216250
+ };
216251
+ }
216252
+ const exactEntry = index.classes.get(importSpecifier);
216253
+ if (exactEntry) {
216254
+ return {
216255
+ targetModule: exactEntry.moduleId,
216256
+ resolvedRelativePath: normalizePath4(path7.relative(workspaceRoot, exactEntry.resolvedPath)),
216257
+ isPublicImport: false
216258
+ };
216259
+ }
216260
+ const ownerCandidate = [...index.classes.entries()].filter(([classImport]) => importSpecifier.startsWith(`${classImport}.`)).sort((left, right) => right[0].length - left[0].length || left[0].localeCompare(right[0]))[0];
216261
+ if (!ownerCandidate) {
216262
+ return void 0;
216263
+ }
216264
+ return {
216265
+ targetModule: ownerCandidate[1].moduleId,
216266
+ resolvedRelativePath: normalizePath4(path7.relative(workspaceRoot, ownerCandidate[1].resolvedPath)),
216267
+ isPublicImport: false
216268
+ };
216269
+ }
216101
216270
  function extractPythonImportSpecifiers(sourceText) {
216102
216271
  const imports = [];
216103
216272
  const lines = sourceText.split(/\r?\n/u);
@@ -216200,7 +216369,7 @@ function resolveJavaModuleImport(modulesRootRelativePath, moduleRoots, importSpe
216200
216369
  const lastSegment = segments[segments.length - 1];
216201
216370
  const defaultEntrypointFileName = adapter.scaffoldingDefaults?.moduleIndexFileName ?? "Application.java";
216202
216371
  const resolvedFileName = lastSegment === "*" ? defaultEntrypointFileName : lastSegment.endsWith(".java") ? lastSegment : `${lastSegment}.java`;
216203
- const resolvedRelativePath = normalizePath3(
216372
+ const resolvedRelativePath = normalizePath4(
216204
216373
  `${modulesRootRelativePath}/${targetModule}/${resolvedFileName}`
216205
216374
  );
216206
216375
  return {
@@ -216538,13 +216707,17 @@ async function resolveWorkspacePackageImportTarget(importSpecifier, workspacePac
216538
216707
  }
216539
216708
  return void 0;
216540
216709
  }
216541
- async function resolveCrossModuleImport(workspaceRoot, modulesRootRelativePath, moduleRoots, explicitStandaloneModuleByPath, workspacePackageAliases, sourceFilePath, importSpecifier, adapter, resolutionContext) {
216710
+ async function resolveCrossModuleImport(workspaceRoot, modulesRootRelativePath, moduleRoots, explicitStandaloneModuleByPath, workspacePackageAliases, sourceFilePath, importSpecifier, adapter, javaImportIndex, resolutionContext) {
216542
216711
  const candidateBasePaths = [];
216543
216712
  let packageAliasTargetModule;
216544
216713
  let packageAliasTargetModuleRoot;
216545
216714
  let isPublicPackageAliasImport = false;
216546
- const normalizedModulesRoot = normalizePath3(modulesRootRelativePath).replace(/^\/+/, "");
216715
+ const normalizedModulesRoot = normalizePath4(modulesRootRelativePath).replace(/^\/+/, "");
216547
216716
  if (usesJavaImportParser(adapter) && !importSpecifier.startsWith(".")) {
216717
+ const indexedJava = resolveJavaImportFromIndex(importSpecifier, javaImportIndex, workspaceRoot);
216718
+ if (indexedJava) {
216719
+ return indexedJava;
216720
+ }
216548
216721
  const resolvedJava = resolveJavaModuleImport(
216549
216722
  normalizedModulesRoot,
216550
216723
  moduleRoots,
@@ -216638,22 +216811,22 @@ async function resolveCrossModuleImport(workspaceRoot, modulesRootRelativePath,
216638
216811
  if (!resolvedPath) {
216639
216812
  return void 0;
216640
216813
  }
216641
- const targetModuleEntry = packageAliasTargetModule && packageAliasTargetModuleRoot ? [packageAliasTargetModule, packageAliasTargetModuleRoot] : [...moduleRoots.entries()].filter(([, moduleRoot]) => isPathInsideOrEqual2(resolvedPath, moduleRoot)).sort((left, right) => right[1].length - left[1].length || left[0].localeCompare(right[0]))[0];
216814
+ const targetModuleEntry = packageAliasTargetModule && packageAliasTargetModuleRoot ? [packageAliasTargetModule, packageAliasTargetModuleRoot] : [...moduleRoots.entries()].filter(([, moduleRoot]) => isPathInsideOrEqual(resolvedPath, moduleRoot)).sort((left, right) => right[1].length - left[1].length || left[0].localeCompare(right[0]))[0];
216642
216815
  if (!targetModuleEntry) {
216643
216816
  const standaloneTargetModule = explicitStandaloneModuleByPath.get(
216644
- normalizePath3(path7.relative(workspaceRoot, resolvedPath))
216817
+ normalizePath4(path7.relative(workspaceRoot, resolvedPath))
216645
216818
  );
216646
216819
  if (!standaloneTargetModule) {
216647
216820
  return void 0;
216648
216821
  }
216649
216822
  return {
216650
216823
  targetModule: standaloneTargetModule,
216651
- resolvedRelativePath: normalizePath3(path7.relative(workspaceRoot, resolvedPath)),
216824
+ resolvedRelativePath: normalizePath4(path7.relative(workspaceRoot, resolvedPath)),
216652
216825
  isPublicImport: true
216653
216826
  };
216654
216827
  }
216655
216828
  const [targetModule, targetModuleRoot] = targetModuleEntry;
216656
- const targetSubPath = normalizePath3(path7.relative(targetModuleRoot, resolvedPath));
216829
+ const targetSubPath = normalizePath4(path7.relative(targetModuleRoot, resolvedPath));
216657
216830
  if (targetSubPath === "" || targetSubPath.startsWith("../") || targetSubPath.startsWith("..\\")) {
216658
216831
  return void 0;
216659
216832
  }
@@ -216669,7 +216842,7 @@ async function resolveCrossModuleImport(workspaceRoot, modulesRootRelativePath,
216669
216842
  );
216670
216843
  return {
216671
216844
  targetModule,
216672
- resolvedRelativePath: normalizePath3(path7.relative(workspaceRoot, resolvedPath)),
216845
+ resolvedRelativePath: normalizePath4(path7.relative(workspaceRoot, resolvedPath)),
216673
216846
  isPublicImport,
216674
216847
  ...isPublicPackageAliasImport ? { isPackagePublicImport: true } : {}
216675
216848
  };
@@ -216680,10 +216853,11 @@ async function collectCrossModuleImports(workspaceRoot, modulesRootRelativePath,
216680
216853
  if (!supportsDependencyImportParsing(adapter)) {
216681
216854
  return imports;
216682
216855
  }
216856
+ const javaImportIndex = usesJavaImportParser(adapter) ? await buildJavaImportIndex(workspaceRoot, moduleRoots, adapter) : void 0;
216683
216857
  for (const [moduleName, moduleRoot] of [...moduleRoots.entries()].sort(
216684
216858
  ([left], [right]) => left.localeCompare(right)
216685
216859
  )) {
216686
- const childModuleRoots = [...moduleRoots.entries()].filter(([childModuleName, childModuleRoot]) => childModuleName !== moduleName && isPathInsideOrEqual2(childModuleRoot, moduleRoot)).map(([, childModuleRoot]) => childModuleRoot);
216860
+ const childModuleRoots = [...moduleRoots.entries()].filter(([childModuleName, childModuleRoot]) => childModuleName !== moduleName && isPathInsideOrEqual(childModuleRoot, moduleRoot)).map(([, childModuleRoot]) => childModuleRoot);
216687
216861
  const sourceFiles = await collectSourceFiles(
216688
216862
  moduleRoot,
216689
216863
  adapter,
@@ -216691,7 +216865,7 @@ async function collectCrossModuleImports(workspaceRoot, modulesRootRelativePath,
216691
216865
  childModuleRoots
216692
216866
  );
216693
216867
  for (const sourceFilePath of sourceFiles) {
216694
- const sourceFileRelativePath = normalizePath3(
216868
+ const sourceFileRelativePath = normalizePath4(
216695
216869
  path7.relative(workspaceRoot, sourceFilePath)
216696
216870
  );
216697
216871
  if (!includeTestFiles && isTestSourcePath(sourceFileRelativePath)) {
@@ -216716,6 +216890,7 @@ async function collectCrossModuleImports(workspaceRoot, modulesRootRelativePath,
216716
216890
  sourceFilePath,
216717
216891
  importReference.specifier,
216718
216892
  adapter,
216893
+ javaImportIndex,
216719
216894
  options?.resolutionContext
216720
216895
  );
216721
216896
  if (!resolved || resolved.targetModule === moduleName) {
@@ -216818,15 +216993,15 @@ function toDependencyContextMetadata(context) {
216818
216993
  isExternal: context.isExternal
216819
216994
  };
216820
216995
  }
216821
- function resolveImportDependencyContextMetadata(architectureContract, dependencyImport) {
216822
- const directContext = resolveDependencyContext(architectureContract, {
216996
+ function resolveImportDependencyContextMetadata(architectureContract, dependencyImport, resolver = createArchitectureDependencyContextResolver(architectureContract)) {
216997
+ const directContext = resolver.resolve({
216823
216998
  sourceFile: dependencyImport.sourceFileRelativePath,
216824
216999
  importSpecifier: dependencyImport.importSpecifier
216825
217000
  });
216826
217001
  if (!directContext.isExternal) {
216827
217002
  return toDependencyContextMetadata(directContext);
216828
217003
  }
216829
- const moduleTargetContext = resolveDependencyContext(architectureContract, {
217004
+ const moduleTargetContext = resolver.resolve({
216830
217005
  sourceFile: dependencyImport.sourceFileRelativePath,
216831
217006
  importSpecifier: dependencyImport.targetModule
216832
217007
  });
@@ -216837,7 +217012,7 @@ function resolveImportDependencyContextMetadata(architectureContract, dependency
216837
217012
  resolvedTargetPath: dependencyImport.resolvedTargetRelativePath
216838
217013
  });
216839
217014
  }
216840
- const resolvedPathContext = resolveDependencyContext(architectureContract, {
217015
+ const resolvedPathContext = resolver.resolve({
216841
217016
  sourceFile: dependencyImport.sourceFileRelativePath,
216842
217017
  importSpecifier: dependencyImport.resolvedTargetRelativePath
216843
217018
  });
@@ -216875,11 +217050,15 @@ function validateComponentDependencyPolicies(architectureContract, imports) {
216875
217050
  if (!architectureContract || policies.size === 0) {
216876
217051
  return [];
216877
217052
  }
217053
+ const dependencyContextResolver = createArchitectureDependencyContextResolver(
217054
+ architectureContract
217055
+ );
216878
217056
  const findings = [];
216879
217057
  for (const dependencyImport of imports) {
216880
217058
  const dependencyMetadata = resolveImportDependencyContextMetadata(
216881
217059
  architectureContract,
216882
- dependencyImport
217060
+ dependencyImport,
217061
+ dependencyContextResolver
216883
217062
  );
216884
217063
  if (dependencyMetadata.dependencyType !== "cross-component" || dependencyMetadata.isExternal || !dependencyMetadata.sourceComponentId || !dependencyMetadata.targetComponentId) {
216885
217064
  continue;
@@ -216915,7 +217094,7 @@ function validateComponentDependencyPolicies(architectureContract, imports) {
216915
217094
  }
216916
217095
  return findings;
216917
217096
  }
216918
- function isModuleScopedDependencyImport(architectureContract, dependencyImport) {
217097
+ function isModuleScopedDependencyImport(architectureContract, dependencyImport, resolver) {
216919
217098
  if (dependencyImport.sourceModule === dependencyImport.targetModule || isParentChildModuleRelationship(
216920
217099
  dependencyImport.sourceModule,
216921
217100
  dependencyImport.targetModule
@@ -216927,7 +217106,8 @@ function isModuleScopedDependencyImport(architectureContract, dependencyImport)
216927
217106
  }
216928
217107
  const dependencyMetadata = resolveImportDependencyContextMetadata(
216929
217108
  architectureContract,
216930
- dependencyImport
217109
+ dependencyImport,
217110
+ resolver
216931
217111
  );
216932
217112
  return !dependencyMetadata.isExternal;
216933
217113
  }
@@ -216956,7 +217136,7 @@ function buildDependencyConfigSkippedFindings(reason, options) {
216956
217136
  return findings;
216957
217137
  }
216958
217138
  function normalizePathList(values) {
216959
- return values.map((value) => normalizePath3(value)).sort((left, right) => left.localeCompare(right));
217139
+ return values.map((value) => normalizePath4(value)).sort((left, right) => left.localeCompare(right));
216960
217140
  }
216961
217141
  function normalizeModuleContract(contractLike) {
216962
217142
  if (typeof contractLike.module !== "string") {
@@ -217059,7 +217239,7 @@ function buildContractSkipMessage(ruleId, sourceModule, targetModule, sourceCont
217059
217239
  )}.`;
217060
217240
  }
217061
217241
  function isImportWithinPublicEntrypoints(resolvedTargetRelativePath, publicEntrypoints) {
217062
- const normalizedTargetPath = normalizePath3(resolvedTargetRelativePath);
217242
+ const normalizedTargetPath = normalizePath4(resolvedTargetRelativePath);
217063
217243
  for (const publicEntrypoint of normalizePathList(publicEntrypoints)) {
217064
217244
  const isFileEntrypoint = /\.[a-z0-9]+$/iu.test(publicEntrypoint);
217065
217245
  if (isFileEntrypoint && normalizedTargetPath === publicEntrypoint) {
@@ -217106,17 +217286,18 @@ async function inferExistingPublicEntrypointsFromModuleRoot(workspaceRoot, modul
217106
217286
  const candidatePath = path7.join(moduleRoot, ...candidateSubpath.split("/"));
217107
217287
  if (await pathExists4(candidatePath)) {
217108
217288
  existingEntrypoints.push(
217109
- normalizePath3(path7.relative(workspaceRoot, candidatePath))
217289
+ normalizePath4(path7.relative(workspaceRoot, candidatePath))
217110
217290
  );
217111
217291
  }
217112
217292
  }
217113
217293
  return existingEntrypoints.sort((left, right) => left.localeCompare(right));
217114
217294
  }
217115
- async function resolveModulePublicEntrypoints(workspaceRoot, architectureContract, moduleName, targetContract, moduleRoots) {
217116
- const registryPublicEntrypoints = architectureContract.modules[moduleName]?.publicEntrypoints ?? [];
217295
+ async function resolveKnownModulePublicEntrypoints(workspaceRoot, architectureContract, moduleName, targetContract, moduleRoots, adapter) {
217296
+ const registryPublicEntrypoints = architectureContract?.modules[moduleName]?.publicEntrypoints ?? [];
217297
+ const contractPublicEntrypoints = targetContract?.publicEntrypoints ?? [];
217117
217298
  const explicitPublicEntrypoints = sortUnique2([
217118
217299
  ...registryPublicEntrypoints,
217119
- ...targetContract.publicEntrypoints
217300
+ ...contractPublicEntrypoints
217120
217301
  ]);
217121
217302
  const existingExplicitEntrypoints = await filterExistingPublicEntrypoints(
217122
217303
  workspaceRoot,
@@ -217125,13 +217306,16 @@ async function resolveModulePublicEntrypoints(workspaceRoot, architectureContrac
217125
217306
  if (existingExplicitEntrypoints.length > 0) {
217126
217307
  return existingExplicitEntrypoints;
217127
217308
  }
217309
+ if (usesJavaImportParser(adapter)) {
217310
+ return [];
217311
+ }
217128
217312
  return inferExistingPublicEntrypointsFromModuleRoot(
217129
217313
  workspaceRoot,
217130
217314
  moduleRoots.get(moduleName)
217131
217315
  );
217132
217316
  }
217133
217317
  function labelPublicEntrypoint(publicEntrypoint) {
217134
- const normalizedEntrypoint = normalizePath3(publicEntrypoint);
217318
+ const normalizedEntrypoint = normalizePath4(publicEntrypoint);
217135
217319
  const fileName = normalizedEntrypoint.split("/").at(-1) ?? "";
217136
217320
  return /^index\.[cm]?[jt]sx?$/iu.test(fileName) ? `${fileName} public entrypoint` : "public entrypoint";
217137
217321
  }
@@ -217151,7 +217335,7 @@ async function describeModulePublicImportGuidance(workspaceRoot, moduleName, mod
217151
217335
  return `Use the public entrypoint at ${describePublicEntrypointTargets(inferredEntrypoints)} instead.`;
217152
217336
  }
217153
217337
  if (moduleRoot) {
217154
- return `Use an existing public entrypoint under ${normalizePath3(path7.relative(workspaceRoot, moduleRoot))} instead.`;
217338
+ return `Use an existing public entrypoint under ${normalizePath4(path7.relative(workspaceRoot, moduleRoot))} instead.`;
217155
217339
  }
217156
217340
  return "Use an existing target module public entrypoint instead.";
217157
217341
  }
@@ -217273,34 +217457,42 @@ async function buildDependencyGraphSummary(workspaceRoot, architectureContract,
217273
217457
  const inboundDeclared = buildInboundDependencyMap(declaredBySource, moduleIds);
217274
217458
  const inboundActual = buildInboundDependencyMap(actualBySource, moduleIds);
217275
217459
  const hierarchyEdges = buildModuleHierarchyEdges(moduleIds);
217276
- const childModulesByParent = buildChildModulesByParent(hierarchyEdges);
217277
217460
  const parentModuleByChild = new Map(
217278
217461
  hierarchyEdges.map((edge) => [edge.childModule, edge.parentModule])
217279
217462
  );
217463
+ const moduleSummaries = moduleIds.map((moduleId) => {
217464
+ const declaredDependencies = sortUnique2(declaredBySource.get(moduleId) ?? []);
217465
+ const actualDependencies = sortUnique2(actualBySource.get(moduleId) ?? []);
217466
+ const unusedDeclaredDependencies = declaredDependencies.filter(
217467
+ (declaredDependency) => !actualDependencies.includes(declaredDependency)
217468
+ );
217469
+ const undeclaredActualDependencies = actualDependencies.filter(
217470
+ (actualDependency) => !declaredDependencies.includes(actualDependency)
217471
+ );
217472
+ return {
217473
+ module: moduleId,
217474
+ hasContract: hasContractByModule.get(moduleId) ?? false,
217475
+ ...parentModuleByChild.has(moduleId) ? { parentModule: parentModuleByChild.get(moduleId) } : {},
217476
+ childModules: [],
217477
+ declaredDependencies,
217478
+ actualDependencies,
217479
+ inboundDeclaredFrom: inboundDeclared.get(moduleId) ?? [],
217480
+ inboundActualFrom: inboundActual.get(moduleId) ?? [],
217481
+ unusedDeclaredDependencies,
217482
+ undeclaredActualDependencies
217483
+ };
217484
+ }).filter((moduleSummary) => !isIsolatedContractlessHierarchyModule(moduleSummary));
217485
+ const retainedModuleIds = new Set(moduleSummaries.map((moduleSummary) => moduleSummary.module));
217486
+ const retainedHierarchyEdges = hierarchyEdges.filter(
217487
+ (edge) => retainedModuleIds.has(edge.parentModule) && retainedModuleIds.has(edge.childModule)
217488
+ );
217489
+ const childModulesByParent = buildChildModulesByParent(retainedHierarchyEdges);
217280
217490
  return {
217281
- modules: moduleIds.map((moduleId) => {
217282
- const declaredDependencies = sortUnique2(declaredBySource.get(moduleId) ?? []);
217283
- const actualDependencies = sortUnique2(actualBySource.get(moduleId) ?? []);
217284
- const unusedDeclaredDependencies = declaredDependencies.filter(
217285
- (declaredDependency) => !actualDependencies.includes(declaredDependency)
217286
- );
217287
- const undeclaredActualDependencies = actualDependencies.filter(
217288
- (actualDependency) => !declaredDependencies.includes(actualDependency)
217289
- );
217290
- return {
217291
- module: moduleId,
217292
- hasContract: hasContractByModule.get(moduleId) ?? false,
217293
- ...parentModuleByChild.has(moduleId) ? { parentModule: parentModuleByChild.get(moduleId) } : {},
217294
- childModules: childModulesByParent.get(moduleId) ?? [],
217295
- declaredDependencies,
217296
- actualDependencies,
217297
- inboundDeclaredFrom: inboundDeclared.get(moduleId) ?? [],
217298
- inboundActualFrom: inboundActual.get(moduleId) ?? [],
217299
- unusedDeclaredDependencies,
217300
- undeclaredActualDependencies
217301
- };
217302
- }),
217303
- hierarchyEdges
217491
+ modules: moduleSummaries.map((moduleSummary) => ({
217492
+ ...moduleSummary,
217493
+ childModules: childModulesByParent.get(moduleSummary.module) ?? []
217494
+ })),
217495
+ hierarchyEdges: retainedHierarchyEdges
217304
217496
  };
217305
217497
  }
217306
217498
  async function validateDependencyContractBoundaries(workspaceRoot, architectureContract, options) {
@@ -217330,9 +217522,16 @@ async function validateDependencyContractBoundaries(workspaceRoot, architectureC
217330
217522
  workspacePackageAliases,
217331
217523
  adapter
217332
217524
  );
217525
+ const dependencyContextResolver = createArchitectureDependencyContextResolver(
217526
+ architectureContract
217527
+ );
217333
217528
  const peerImports = filterPeerModuleImports(imports);
217334
217529
  const moduleScopedPeerImports = peerImports.filter(
217335
- (dependencyImport) => isModuleScopedDependencyImport(architectureContract, dependencyImport)
217530
+ (dependencyImport) => isModuleScopedDependencyImport(
217531
+ architectureContract,
217532
+ dependencyImport,
217533
+ dependencyContextResolver
217534
+ )
217336
217535
  );
217337
217536
  const findings = [];
217338
217537
  const moduleContractCache = /* @__PURE__ */ new Map();
@@ -217342,7 +217541,8 @@ async function validateDependencyContractBoundaries(workspaceRoot, architectureC
217342
217541
  for (const dependencyImport of moduleScopedPeerImports) {
217343
217542
  const dependencyMetadata = resolveImportDependencyContextMetadata(
217344
217543
  architectureContract,
217345
- dependencyImport
217544
+ dependencyImport,
217545
+ dependencyContextResolver
217346
217546
  );
217347
217547
  if (dependencyMetadata.isExternal) {
217348
217548
  continue;
@@ -217474,7 +217674,8 @@ async function validateDependencyContractBoundaries(workspaceRoot, architectureC
217474
217674
  for (const dependencyImport of moduleScopedPeerImports) {
217475
217675
  const dependencyMetadata = resolveImportDependencyContextMetadata(
217476
217676
  architectureContract,
217477
- dependencyImport
217677
+ dependencyImport,
217678
+ dependencyContextResolver
217478
217679
  );
217479
217680
  if (dependencyMetadata.isExternal) {
217480
217681
  continue;
@@ -217548,12 +217749,13 @@ async function validateDependencyContractBoundaries(workspaceRoot, architectureC
217548
217749
  }
217549
217750
  continue;
217550
217751
  }
217551
- const publicEntrypoints = await resolveModulePublicEntrypoints(
217752
+ const publicEntrypoints = await resolveKnownModulePublicEntrypoints(
217552
217753
  workspaceRoot,
217553
217754
  architectureContract,
217554
217755
  dependencyImport.targetModule,
217555
217756
  targetContract.contract,
217556
- moduleRoots
217757
+ moduleRoots,
217758
+ adapter
217557
217759
  );
217558
217760
  if (publicEntrypoints.length === 0) {
217559
217761
  continue;
@@ -217732,11 +217934,17 @@ async function validateDependencyBoundaries(workspaceRoot, options) {
217732
217934
  workspacePackageAliases,
217733
217935
  adapter
217734
217936
  );
217937
+ const dependencyContextResolver = parsedArchitectureContract ? createArchitectureDependencyContextResolver(parsedArchitectureContract) : void 0;
217735
217938
  const peerImports = filterPeerModuleImports(imports);
217736
217939
  const moduleScopedPeerImports = peerImports.filter(
217737
- (dependencyImport) => isModuleScopedDependencyImport(parsedArchitectureContract, dependencyImport)
217940
+ (dependencyImport) => isModuleScopedDependencyImport(
217941
+ parsedArchitectureContract,
217942
+ dependencyImport,
217943
+ dependencyContextResolver
217944
+ )
217738
217945
  );
217739
217946
  const findings = [];
217947
+ const moduleContractCache = /* @__PURE__ */ new Map();
217740
217948
  let dependencyRules;
217741
217949
  let dependencyRulesSkipReason;
217742
217950
  if (options.dependencyRulesConfigOverride) {
@@ -217792,7 +218000,8 @@ async function validateDependencyBoundaries(workspaceRoot, options) {
217792
218000
  if (parsedArchitectureContract) {
217793
218001
  const dependencyMetadata = resolveImportDependencyContextMetadata(
217794
218002
  parsedArchitectureContract,
217795
- dependencyImport
218003
+ dependencyImport,
218004
+ dependencyContextResolver
217796
218005
  );
217797
218006
  if (dependencyMetadata.isExternal) {
217798
218007
  return false;
@@ -217816,7 +218025,11 @@ async function validateDependencyBoundaries(workspaceRoot, options) {
217816
218025
  });
217817
218026
  } else {
217818
218027
  for (const violation of violations) {
217819
- const dependencyMetadata = parsedArchitectureContract ? resolveImportDependencyContextMetadata(parsedArchitectureContract, violation) : void 0;
218028
+ const dependencyMetadata = parsedArchitectureContract ? resolveImportDependencyContextMetadata(
218029
+ parsedArchitectureContract,
218030
+ violation,
218031
+ dependencyContextResolver
218032
+ ) : void 0;
217820
218033
  const allowedDependencies = dependencyRules.modules[violation.sourceModule]?.allowedDependencies ?? [];
217821
218034
  const allowedDescription = allowedDependencies.length === 0 ? "may not depend on any other modules" : `may only depend on: ${allowedDependencies.join(", ")}`;
217822
218035
  findings.push({
@@ -217853,19 +218066,50 @@ async function validateDependencyBoundaries(workspaceRoot, options) {
217853
218066
  })
217854
218067
  );
217855
218068
  } else {
217856
- const violations = moduleScopedPeerImports.filter((dependencyImport) => {
218069
+ const violations = [];
218070
+ for (const dependencyImport of moduleScopedPeerImports) {
217857
218071
  if (parsedArchitectureContract) {
217858
218072
  const dependencyMetadata = resolveImportDependencyContextMetadata(
217859
218073
  parsedArchitectureContract,
217860
- dependencyImport
218074
+ dependencyImport,
218075
+ dependencyContextResolver
217861
218076
  );
217862
218077
  if (dependencyMetadata.isExternal) {
217863
- return false;
218078
+ continue;
217864
218079
  }
217865
218080
  }
217866
218081
  const moduleRules = dependencyRules.modules[dependencyImport.sourceModule];
217867
- return moduleRules?.publicEntrypointsOnly === true && !dependencyImport.isPublicImport;
217868
- });
218082
+ if (moduleRules?.publicEntrypointsOnly !== true || dependencyImport.isPublicImport) {
218083
+ continue;
218084
+ }
218085
+ if (dependencyImport.isPackagePublicImport === true) {
218086
+ continue;
218087
+ }
218088
+ const targetContract = parsedArchitectureContract ? await loadModuleArchitectureContract(
218089
+ workspaceRoot,
218090
+ parsedArchitectureContract,
218091
+ dependencyImport.targetModule,
218092
+ moduleContractCache
218093
+ ) : void 0;
218094
+ const publicEntrypoints = await resolveKnownModulePublicEntrypoints(
218095
+ workspaceRoot,
218096
+ parsedArchitectureContract,
218097
+ dependencyImport.targetModule,
218098
+ targetContract?.contract,
218099
+ moduleRoots,
218100
+ adapter
218101
+ );
218102
+ if (publicEntrypoints.length === 0) {
218103
+ continue;
218104
+ }
218105
+ if (isImportWithinPublicEntrypoints(
218106
+ dependencyImport.resolvedTargetRelativePath,
218107
+ publicEntrypoints
218108
+ )) {
218109
+ continue;
218110
+ }
218111
+ violations.push(dependencyImport);
218112
+ }
217869
218113
  if (violations.length === 0) {
217870
218114
  findings.push({
217871
218115
  result: makeValidationResult(
@@ -217877,7 +218121,11 @@ async function validateDependencyBoundaries(workspaceRoot, options) {
217877
218121
  });
217878
218122
  } else {
217879
218123
  for (const violation of violations) {
217880
- const dependencyMetadata = parsedArchitectureContract ? resolveImportDependencyContextMetadata(parsedArchitectureContract, violation) : void 0;
218124
+ const dependencyMetadata = parsedArchitectureContract ? resolveImportDependencyContextMetadata(
218125
+ parsedArchitectureContract,
218126
+ violation,
218127
+ dependencyContextResolver
218128
+ ) : void 0;
217881
218129
  const publicImportGuidance = await describeModulePublicImportGuidance(
217882
218130
  workspaceRoot,
217883
218131
  violation.targetModule,
@@ -218014,6 +218262,7 @@ var init_dependencyValidation = __esm({
218014
218262
  init_architectureDependencyContext();
218015
218263
  init_moduleDiscovery();
218016
218264
  init_stackAdapters();
218265
+ init_sourceScopeClassification();
218017
218266
  dependencyRulesConfigFile = ".archpilot/dependency-rules.json";
218018
218267
  DependencyRulesConfigError = class extends Error {
218019
218268
  };
@@ -218021,7 +218270,7 @@ var init_dependencyValidation = __esm({
218021
218270
  });
218022
218271
 
218023
218272
  // ../core/src/moduleScope.ts
218024
- function normalizePath4(value) {
218273
+ function normalizePath5(value) {
218025
218274
  return value.replace(/\\/g, "/").replace(/^\.\/+/u, "").replace(/\/+$/u, "").toLowerCase();
218026
218275
  }
218027
218276
  function pathExists5(targetPath) {
@@ -218074,7 +218323,7 @@ function hasJsxEnabled(configPath) {
218074
218323
  return typeof jsx === "string" && jsx.trim().length > 0;
218075
218324
  }
218076
218325
  function listPathSegments(modulePath) {
218077
- return normalizePath4(modulePath).split("/").filter((entry) => entry.length > 0);
218326
+ return normalizePath5(modulePath).split("/").filter((entry) => entry.length > 0);
218078
218327
  }
218079
218328
  function getCandidateRoots(workspaceRoot, modulePath) {
218080
218329
  const resolvedWorkspaceRoot = path8.resolve(workspaceRoot);
@@ -218406,9 +218655,12 @@ var init_moduleScope = __esm({
218406
218655
  });
218407
218656
 
218408
218657
  // ../core/src/smartInit/moduleDetection.ts
218409
- function normalizePath5(value) {
218658
+ function normalizePath6(value) {
218410
218659
  return value.replaceAll("\\", "/");
218411
218660
  }
218661
+ function isUnderJvmResourceRoot(relativePath) {
218662
+ return /(^|\/)src\/main\/resources(?:\/|$)/u.test(normalizePath6(relativePath).toLowerCase());
218663
+ }
218412
218664
  function safeReadDirEntries(directoryPath) {
218413
218665
  try {
218414
218666
  return fs8.readdirSync(directoryPath, { withFileTypes: true });
@@ -218425,7 +218677,7 @@ function pathExists6(pathValue) {
218425
218677
  }
218426
218678
  }
218427
218679
  function isIgnoredPath(context, relativePath) {
218428
- return context?.ignoreMatcher?.isIgnored(normalizePath5(relativePath)) ?? false;
218680
+ return context?.ignoreMatcher?.isIgnored(normalizePath6(relativePath)) ?? false;
218429
218681
  }
218430
218682
  function uniqueSorted(values) {
218431
218683
  return [...new Set(values)].sort((left, right) => left.localeCompare(right));
@@ -218440,15 +218692,15 @@ function normalizeIdentity(value) {
218440
218692
  return value.toLowerCase().replace(/[^a-z0-9]+/gu, "");
218441
218693
  }
218442
218694
  function pathLeafIdentity(value) {
218443
- const normalized = normalizePath5(value).replace(/\/+$/gu, "");
218695
+ const normalized = normalizePath6(value).replace(/\/+$/gu, "");
218444
218696
  const leaf = normalized.split("/").filter((segment) => segment.length > 0).at(-1) ?? normalized;
218445
218697
  return normalizeIdentity(leaf);
218446
218698
  }
218447
218699
  function getComponentAlignedEvidence(input2) {
218448
- const modulePath = normalizePath5(input2.modulePath).replace(/\/+$/gu, "");
218700
+ const modulePath = normalizePath6(input2.modulePath).replace(/\/+$/gu, "");
218449
218701
  const moduleNameIdentity = normalizeIdentity(input2.moduleName);
218450
218702
  const modulePathLeaf = pathLeafIdentity(modulePath);
218451
- const matchingPath = input2.context?.componentPaths?.map((entry) => normalizePath5(entry).replace(/\/+$/gu, "")).find(
218703
+ const matchingPath = input2.context?.componentPaths?.map((entry) => normalizePath6(entry).replace(/\/+$/gu, "")).find(
218452
218704
  (componentPath) => componentPath.length > 0 && componentPath !== "." && (componentPath === modulePath || componentPath.startsWith(`${modulePath}/`))
218453
218705
  );
218454
218706
  if (matchingPath) {
@@ -218458,7 +218710,7 @@ function getComponentAlignedEvidence(input2) {
218458
218710
  if (matchingName) {
218459
218711
  return `Matches detected component/service/app identity ${input2.moduleName}`;
218460
218712
  }
218461
- const matchingResourcePath = input2.context?.resourcePaths?.map((entry) => normalizePath5(entry).replace(/\/+$/gu, "")).find(
218713
+ const matchingResourcePath = input2.context?.resourcePaths?.map((entry) => normalizePath6(entry).replace(/\/+$/gu, "")).find(
218462
218714
  (resourcePath) => resourcePath.length > 0 && resourcePath !== "." && (resourcePath === modulePath || resourcePath.startsWith(`${modulePath}/`))
218463
218715
  );
218464
218716
  if (matchingResourcePath) {
@@ -218638,6 +218890,9 @@ function containsAppRouteFiles(absolutePath) {
218638
218890
  return false;
218639
218891
  }
218640
218892
  function makeDetectedModule(workspaceRoot, moduleName, modulePath, rootPath, hasSourceFiles, hasRoleFiles, sourceFileCount, context) {
218893
+ if (isUnderJvmResourceRoot(modulePath)) {
218894
+ return void 0;
218895
+ }
218641
218896
  const evidence = [];
218642
218897
  if (hasSourceFiles) {
218643
218898
  evidence.push("Contains source files");
@@ -218696,11 +218951,14 @@ function collectModuleCandidatesFromRoot(workspaceRoot, modulesRootRelative, def
218696
218951
  const rootLower = modulesRootRelative.toLowerCase();
218697
218952
  const skipFrontendUtilities = rootLower === "src/features" || rootLower.endsWith("/src/features") || rootLower === "app" || rootLower === "src/app" || rootLower.endsWith("/app") || rootLower.endsWith("/src/app");
218698
218953
  const entries = safeReadDirEntries(absoluteRoot).filter(
218699
- (entry) => entry.isDirectory() && !ignoredDirectoryNames.has(entry.name) && !isIgnoredPath(context, normalizePath5(`${modulesRootRelative}/${entry.name}`))
218954
+ (entry) => entry.isDirectory() && !ignoredDirectoryNames.has(entry.name) && !isIgnoredPath(context, normalizePath6(`${modulesRootRelative}/${entry.name}`))
218700
218955
  ).sort((left, right) => left.name.localeCompare(right.name));
218701
218956
  const modules = [];
218702
218957
  for (const entry of entries) {
218703
- const candidateProjectRoot = normalizePath5(`${modulesRootRelative}/${entry.name}`);
218958
+ const candidateProjectRoot = normalizePath6(`${modulesRootRelative}/${entry.name}`);
218959
+ if (isUnderJvmResourceRoot(candidateProjectRoot)) {
218960
+ continue;
218961
+ }
218704
218962
  if (["apps", "packages", "services", "libs"].includes(rootLower) && (context?.projectRoots?.length ?? 0) > 0 && !context?.projectRoots?.includes(candidateProjectRoot)) {
218705
218963
  continue;
218706
218964
  }
@@ -218717,7 +218975,7 @@ function collectModuleCandidatesFromRoot(workspaceRoot, modulesRootRelative, def
218717
218975
  const detected = makeDetectedModule(
218718
218976
  workspaceRoot,
218719
218977
  moduleName,
218720
- normalizePath5(`${modulesRootRelative}/${entry.name}`),
218978
+ normalizePath6(`${modulesRootRelative}/${entry.name}`),
218721
218979
  modulesRootRelative,
218722
218980
  inspected.hasSourceFiles,
218723
218981
  inspected.hasRoleFiles,
@@ -218740,7 +218998,7 @@ function collectAppRouteModules(workspaceRoot, appRootRelative, context) {
218740
218998
  return [];
218741
218999
  }
218742
219000
  const entries = safeReadDirEntries(absoluteRoot).filter(
218743
- (entry) => entry.isDirectory() && !ignoredDirectoryNames.has(entry.name) && !isIgnoredPath(context, normalizePath5(`${appRootRelative}/${entry.name}`))
219001
+ (entry) => entry.isDirectory() && !ignoredDirectoryNames.has(entry.name) && !isIgnoredPath(context, normalizePath6(`${appRootRelative}/${entry.name}`))
218744
219002
  ).sort((left, right) => left.name.localeCompare(right.name));
218745
219003
  const modules = [];
218746
219004
  for (const entry of entries) {
@@ -218754,7 +219012,7 @@ function collectAppRouteModules(workspaceRoot, appRootRelative, context) {
218754
219012
  if (!moduleName || frontendUtilityDirectoryNames.has(moduleName.toLowerCase())) {
218755
219013
  continue;
218756
219014
  }
218757
- const moduleRelativePath = normalizePath5(`${appRootRelative}/${rawName}`);
219015
+ const moduleRelativePath = normalizePath6(`${appRootRelative}/${rawName}`);
218758
219016
  const moduleAbsolutePath = path9.join(absoluteRoot, rawName);
218759
219017
  if (!containsAppRouteFiles(moduleAbsolutePath)) {
218760
219018
  continue;
@@ -218881,14 +219139,14 @@ function collectJavaPackageRoots(workspaceRoot, context) {
218881
219139
  continue;
218882
219140
  }
218883
219141
  for (const entry of safeReadDirEntries(current.absolutePath)) {
218884
- const childRelativePath = normalizePath5(`${current.relativePath}/${entry.name}`);
219142
+ const childRelativePath = normalizePath6(`${current.relativePath}/${entry.name}`);
218885
219143
  if (!entry.isDirectory() || ignoredDirectoryNames.has(entry.name) || isIgnoredPath(context, childRelativePath)) {
218886
219144
  continue;
218887
219145
  }
218888
219146
  const lowerName = entry.name.toLowerCase();
218889
219147
  if (lowerName === "modules" || lowerName === "features") {
218890
219148
  const childCount = safeReadDirEntries(path9.join(current.absolutePath, entry.name)).filter(
218891
- (child) => child.isDirectory() && !ignoredDirectoryNames.has(child.name) && !isIgnoredPath(context, normalizePath5(`${childRelativePath}/${child.name}`))
219149
+ (child) => child.isDirectory() && !ignoredDirectoryNames.has(child.name) && !isIgnoredPath(context, normalizePath6(`${childRelativePath}/${child.name}`))
218892
219150
  ).length;
218893
219151
  if (childCount >= 2) {
218894
219152
  roots.push(childRelativePath);
@@ -218947,10 +219205,10 @@ function detectModules(workspaceRoot, options) {
218947
219205
  projectKinds: options?.projectKinds,
218948
219206
  stacks: options?.stacks,
218949
219207
  ignoreMatcher: options?.ignoreMatcher,
218950
- projectRoots: options?.projectRoots?.map(normalizePath5),
218951
- componentPaths: options?.componentPaths?.map(normalizePath5),
219208
+ projectRoots: options?.projectRoots?.map(normalizePath6),
219209
+ componentPaths: options?.componentPaths?.map(normalizePath6),
218952
219210
  componentNames: options?.componentNames,
218953
- resourcePaths: options?.resourcePaths?.map(normalizePath5),
219211
+ resourcePaths: options?.resourcePaths?.map(normalizePath6),
218954
219212
  resourceNames: options?.resourceNames
218955
219213
  };
218956
219214
  const explicitRoots = collectExplicitRoots(workspaceRoot, context);
@@ -219028,7 +219286,7 @@ function detectModules(workspaceRoot, options) {
219028
219286
  };
219029
219287
  }
219030
219288
  function detectModuleCandidatesForRoot(workspaceRoot, modulesRootRelative, options) {
219031
- const normalizedRoot = normalizePath5(modulesRootRelative.trim()).replace(/^\/+|\/+$/gu, "");
219289
+ const normalizedRoot = normalizePath6(modulesRootRelative.trim()).replace(/^\/+|\/+$/gu, "");
219032
219290
  if (normalizedRoot.length === 0) {
219033
219291
  return [];
219034
219292
  }
@@ -219040,10 +219298,10 @@ function detectModuleCandidatesForRoot(workspaceRoot, modulesRootRelative, optio
219040
219298
  projectKinds: options?.projectKinds,
219041
219299
  stacks: options?.stacks,
219042
219300
  ignoreMatcher: options?.ignoreMatcher,
219043
- projectRoots: options?.projectRoots?.map(normalizePath5),
219044
- componentPaths: options?.componentPaths?.map(normalizePath5),
219301
+ projectRoots: options?.projectRoots?.map(normalizePath6),
219302
+ componentPaths: options?.componentPaths?.map(normalizePath6),
219045
219303
  componentNames: options?.componentNames,
219046
- resourcePaths: options?.resourcePaths?.map(normalizePath5),
219304
+ resourcePaths: options?.resourcePaths?.map(normalizePath6),
219047
219305
  resourceNames: options?.resourceNames
219048
219306
  }
219049
219307
  );
@@ -219084,6 +219342,7 @@ var init_moduleDetection = __esm({
219084
219342
  "scripts",
219085
219343
  "test",
219086
219344
  "tests",
219345
+ "cypress-tests",
219087
219346
  "__tests__",
219088
219347
  "fixtures",
219089
219348
  "docs",
@@ -219307,7 +219566,7 @@ var init_moduleDetection = __esm({
219307
219566
  });
219308
219567
 
219309
219568
  // ../core/src/architectureMap.ts
219310
- function normalizePath6(value) {
219569
+ function normalizePath7(value) {
219311
219570
  return value.replace(/\\/g, "/");
219312
219571
  }
219313
219572
  async function pathExists7(targetPath) {
@@ -219329,7 +219588,7 @@ function sortUnique3(values) {
219329
219588
  return [...new Set(values)].sort((left, right) => left.localeCompare(right));
219330
219589
  }
219331
219590
  function toSafeContractModuleFileStem2(moduleName) {
219332
- return normalizePath6(moduleName).split("/").map((segment) => segment.trim()).filter((segment) => segment.length > 0).join(".");
219591
+ return normalizePath7(moduleName).split("/").map((segment) => segment.trim()).filter((segment) => segment.length > 0).join(".");
219333
219592
  }
219334
219593
  function getModuleRegistry(contract) {
219335
219594
  const modules = contract?.modules;
@@ -219374,7 +219633,7 @@ function hasExplicitModuleRegistry(config) {
219374
219633
  );
219375
219634
  }
219376
219635
  function normalizePublicEntrypointList(entries) {
219377
- return sortUnique3(entries.map((entry) => normalizePath6(entry.trim())).filter((entry) => entry.length > 0));
219636
+ return sortUnique3(entries.map((entry) => normalizePath7(entry.trim())).filter((entry) => entry.length > 0));
219378
219637
  }
219379
219638
  function hasConfiguredPublicEntrypoint(registryEntry) {
219380
219639
  return Array.isArray(registryEntry?.publicEntrypoints) && registryEntry.publicEntrypoints.some(
@@ -219484,10 +219743,10 @@ function parseCycleString(cycle) {
219484
219743
  }
219485
219744
  async function discoverModulesFromArchitectureContract(workspaceRoot, contract, modulesRoot) {
219486
219745
  const moduleRegistry = getModuleRegistry(contract);
219487
- const normalizedModulesRoot = normalizePath6(modulesRoot);
219488
- const contractsRoot = normalizePath6(contract.structure.contractsRoot ?? ".archpilot/contracts");
219746
+ const normalizedModulesRoot = normalizePath7(modulesRoot);
219747
+ const contractsRoot = normalizePath7(contract.structure.contractsRoot ?? ".archpilot/contracts");
219489
219748
  const discovered = [];
219490
- const toContractPath = (moduleName, registryEntry) => normalizePath6(
219749
+ const toContractPath = (moduleName, registryEntry) => normalizePath7(
219491
219750
  typeof registryEntry?.contract === "string" ? registryEntry.contract : `${contractsRoot}/${toSafeContractModuleFileStem2(moduleName)}.contract.json`
219492
219751
  );
219493
219752
  const resolveMissingPublicEntrypointAlignment = async (registryEntry, contractPath) => {
@@ -219515,7 +219774,7 @@ async function discoverModulesFromArchitectureContract(workspaceRoot, contract,
219515
219774
  if (!registryEntry.path || typeof registryEntry.path !== "string") {
219516
219775
  continue;
219517
219776
  }
219518
- const normalizedSourcePath = normalizePath6(registryEntry.path);
219777
+ const normalizedSourcePath = normalizePath7(registryEntry.path);
219519
219778
  const absoluteSourcePath = path10.join(workspaceRoot, ...normalizedSourcePath.split("/"));
219520
219779
  let sourcePathExists = false;
219521
219780
  let sourceIsDirectory = false;
@@ -219531,7 +219790,7 @@ async function discoverModulesFromArchitectureContract(workspaceRoot, contract,
219531
219790
  if (!sourceIsDirectory && !sourceIsFile) {
219532
219791
  continue;
219533
219792
  }
219534
- const contractPath = normalizePath6(
219793
+ const contractPath = normalizePath7(
219535
219794
  typeof registryEntry.contract === "string" ? registryEntry.contract : `${contractsRoot}/${toSafeContractModuleFileStem2(moduleName)}.contract.json`
219536
219795
  );
219537
219796
  const contractExists = await pathExists7(path10.join(workspaceRoot, ...contractPath.split("/")));
@@ -219615,7 +219874,7 @@ function getComponentEntries(contract) {
219615
219874
  }
219616
219875
  const typed = value;
219617
219876
  const componentId = typeof typed.id === "string" && typed.id.trim().length > 0 ? typed.id.trim() : typeof key === "string" && key.trim().length > 0 ? key.trim() : void 0;
219618
- const sourcePath = typeof typed.path === "string" && typed.path.trim().length > 0 ? normalizePath6(typed.path.trim()) : void 0;
219877
+ const sourcePath = typeof typed.path === "string" && typed.path.trim().length > 0 ? normalizePath7(typed.path.trim()) : void 0;
219619
219878
  if (!componentId || !sourcePath || sourcePath === ".") {
219620
219879
  continue;
219621
219880
  }
@@ -219740,7 +219999,7 @@ async function generateArchitectureMap(workspaceRoot, options) {
219740
219999
  const shouldUseConfiguredRootInference = hasArchitectureJson && !contractHasConfiguredModules && !hasExplicitEmptyModuleRegistry && hasExplicitModuleRootConfig(rawArchitectureConfig);
219741
220000
  const shouldUseTopLevelWorkspaceInference = hasArchitectureJson && !contractHasConfiguredModules && !hasExplicitEmptyModuleRegistry && !shouldUseConfiguredRootInference;
219742
220001
  const discoveryMode = hasArchitectureJson ? "architecture-json" : "inferred-src-modules";
219743
- const modulesRoot = normalizePath6(
220002
+ const modulesRoot = normalizePath7(
219744
220003
  await resolveConfiguredModulesRoot(
219745
220004
  workspaceRoot,
219746
220005
  resolveModulesRootFromContract(contract)
@@ -220638,7 +220897,7 @@ var init_archpilotIgnore = __esm({
220638
220897
  });
220639
220898
 
220640
220899
  // ../core/src/moduleContractsGenerator.ts
220641
- function normalizePath7(value) {
220900
+ function normalizePath8(value) {
220642
220901
  return value.replace(/\\/g, "/");
220643
220902
  }
220644
220903
  function toAbsolutePath(workspaceRoot, relativePath) {
@@ -220656,7 +220915,7 @@ function sortUnique4(values) {
220656
220915
  return [...new Set(values)].sort((left, right) => left.localeCompare(right));
220657
220916
  }
220658
220917
  function toSafeContractModuleFileStem3(moduleName) {
220659
- return normalizePath7(moduleName).split("/").map((segment) => segment.trim()).filter((segment) => segment.length > 0).join(".");
220918
+ return normalizePath8(moduleName).split("/").map((segment) => segment.trim()).filter((segment) => segment.length > 0).join(".");
220660
220919
  }
220661
220920
  function wildcardToRegex(pattern) {
220662
220921
  const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
@@ -220670,14 +220929,14 @@ function getModuleRegistry2(contract) {
220670
220929
  return modules;
220671
220930
  }
220672
220931
  async function inferModulePublicEntrypoints(workspaceRoot, moduleSourcePath, adapter) {
220673
- const normalizedSourcePath = normalizePath7(moduleSourcePath);
220932
+ const normalizedSourcePath = normalizePath8(moduleSourcePath);
220674
220933
  if (/\.[a-z0-9]+$/iu.test(normalizedSourcePath)) {
220675
220934
  const absoluteSourcePath = toAbsolutePath(workspaceRoot, normalizedSourcePath);
220676
220935
  if (await pathExists8(absoluteSourcePath)) {
220677
220936
  return [normalizedSourcePath];
220678
220937
  }
220679
220938
  }
220680
- const candidateFiles = adapter.defaultEntrypointHints.map((hint) => normalizePath7(hint)).filter((hint) => !hint.includes("/"));
220939
+ const candidateFiles = adapter.defaultEntrypointHints.map((hint) => normalizePath8(hint)).filter((hint) => !hint.includes("/"));
220681
220940
  const exactCandidates = candidateFiles.filter((hint) => !hint.includes("*"));
220682
220941
  const wildcardCandidates = candidateFiles.filter((hint) => hint.includes("*"));
220683
220942
  const resolvedWildcardCandidates = [];
@@ -220712,10 +220971,6 @@ async function inferModulePublicEntrypoints(workspaceRoot, moduleSourcePath, ada
220712
220971
  break;
220713
220972
  }
220714
220973
  }
220715
- if (inferred.length === 0) {
220716
- const fallbackName = adapter.scaffoldingDefaults?.moduleIndexFileName ?? orderedCandidates.find((entry) => entry.startsWith("index.")) ?? "index.ts";
220717
- inferred.push(`${normalizedSourcePath}/${fallbackName}`);
220718
- }
220719
220974
  return sortUnique4(inferred);
220720
220975
  }
220721
220976
  function buildDependsOnBySource(edges) {
@@ -220736,9 +220991,9 @@ function resolveContractPath(contract, moduleName) {
220736
220991
  const moduleRegistry = getModuleRegistry2(contract);
220737
220992
  const configured = moduleRegistry[moduleName]?.contract;
220738
220993
  if (configured && configured.trim().length > 0) {
220739
- return normalizePath7(configured);
220994
+ return normalizePath8(configured);
220740
220995
  }
220741
- return normalizePath7(
220996
+ return normalizePath8(
220742
220997
  path15.posix.join(
220743
220998
  resolveContractsRootFromContract(contract),
220744
220999
  `${toSafeContractModuleFileStem3(moduleName)}.contract.json`
@@ -220769,7 +221024,7 @@ async function readExistingModuleContractPublicEntrypoints(workspaceRoot, contra
220769
221024
  if (parsed.publicEntrypoints.some((entry) => typeof entry !== "string")) {
220770
221025
  return void 0;
220771
221026
  }
220772
- return sortUnique4(parsed.publicEntrypoints.map((entry) => normalizePath7(entry)));
221027
+ return sortUnique4(parsed.publicEntrypoints.map((entry) => normalizePath8(entry)));
220773
221028
  } catch {
220774
221029
  return void 0;
220775
221030
  }
@@ -220832,14 +221087,14 @@ async function generateMissingModuleContracts(workspaceRoot) {
220832
221087
  (left, right) => left.moduleName.localeCompare(right.moduleName)
220833
221088
  )) {
220834
221089
  const contractPath = resolveContractPath(contract, moduleEntry.moduleName);
220835
- const sourcePath = normalizePath7(moduleEntry.sourcePath);
221090
+ const sourcePath = normalizePath8(moduleEntry.sourcePath);
220836
221091
  const absoluteContractPath = toAbsolutePath(workspaceRoot, contractPath);
220837
221092
  const contractExists = await pathExists8(absoluteContractPath);
220838
221093
  const existingContract = contractExists ? await readExistingModuleContract(workspaceRoot, contractPath) : void 0;
220839
221094
  const existingContractPublicEntrypoints = contractExists ? await readExistingModuleContractPublicEntrypoints(workspaceRoot, contractPath) : void 0;
220840
221095
  const configuredPublicEntrypoints = !contractExists && Array.isArray(getModuleRegistry2(contract)[moduleEntry.moduleName]?.publicEntrypoints) ? sortUnique4(
220841
221096
  getModuleRegistry2(contract)[moduleEntry.moduleName]?.publicEntrypoints?.map(
220842
- (entry) => normalizePath7(entry)
221097
+ (entry) => normalizePath8(entry)
220843
221098
  ) ?? []
220844
221099
  ) : void 0;
220845
221100
  const publicEntrypoints = existingContractPublicEntrypoints ?? configuredPublicEntrypoints ?? await inferModulePublicEntrypoints(
@@ -220892,7 +221147,7 @@ async function generateMissingModuleContracts(workspaceRoot) {
220892
221147
  });
220893
221148
  createdContracts.push(contractPath);
220894
221149
  }
220895
- if (isRegistryEntryDifferent({
221150
+ if (moduleEntry.discoverySource === "architecture.json" && isRegistryEntryDifferent({
220896
221151
  contract,
220897
221152
  moduleName: moduleEntry.moduleName,
220898
221153
  sourcePath,
@@ -220941,7 +221196,7 @@ var bootstrapArchitectureConfig_exports = {};
220941
221196
  __export(bootstrapArchitectureConfig_exports, {
220942
221197
  bootstrapArchitectureConfig: () => bootstrapArchitectureConfig
220943
221198
  });
220944
- function normalizePath8(value) {
221199
+ function normalizePath9(value) {
220945
221200
  return value.replace(/\\/g, "/");
220946
221201
  }
220947
221202
  function toAbsolutePath2(workspaceRoot, relativePath) {
@@ -221044,9 +221299,9 @@ async function bootstrapArchitectureConfig(workspaceRoot, options) {
221044
221299
  }
221045
221300
  }
221046
221301
  return {
221047
- createdFiles: sortUnique5(createdFiles.map((entry) => normalizePath8(entry))),
221048
- ensuredDirectories: sortUnique5(ensuredDirectories.map((entry) => normalizePath8(entry))),
221049
- skippedExistingFiles: sortUnique5(skippedExistingFiles.map((entry) => normalizePath8(entry))),
221302
+ createdFiles: sortUnique5(createdFiles.map((entry) => normalizePath9(entry))),
221303
+ ensuredDirectories: sortUnique5(ensuredDirectories.map((entry) => normalizePath9(entry))),
221304
+ skippedExistingFiles: sortUnique5(skippedExistingFiles.map((entry) => normalizePath9(entry))),
221050
221305
  moduleCount: modules.length,
221051
221306
  ...contractGeneration ? { contractGeneration } : {},
221052
221307
  ...contractGenerationSkippedReason ? { contractGenerationSkippedReason } : {}
@@ -221871,7 +222126,15 @@ function formatArchitectureDriftSummaryMessage(areas) {
221871
222126
  }
221872
222127
  return `Architecture drift detected in ${labels.slice(0, -1).join(", ")}, and ${labels.at(-1)}.`;
221873
222128
  }
221874
- function buildArchitectureDriftSummary(results, _suppressedResults = []) {
222129
+ function buildArchitectureDriftSummary(results, _suppressedResults = [], options = {}) {
222130
+ if (options.baselineAvailable !== true) {
222131
+ return {
222132
+ detected: false,
222133
+ areas: [],
222134
+ message: "No comparison baseline available; architecture drift was not evaluated.",
222135
+ baselineAvailable: false
222136
+ };
222137
+ }
221875
222138
  const activeFailedResults = results.filter(
221876
222139
  (result) => !result.passed && result.severity !== "info"
221877
222140
  );
@@ -221879,7 +222142,8 @@ function buildArchitectureDriftSummary(results, _suppressedResults = []) {
221879
222142
  return {
221880
222143
  detected: areas.length > 0,
221881
222144
  areas,
221882
- message: formatArchitectureDriftSummaryMessage(areas)
222145
+ message: formatArchitectureDriftSummaryMessage(areas),
222146
+ baselineAvailable: true
221883
222147
  };
221884
222148
  }
221885
222149
 
@@ -222179,7 +222443,7 @@ async function validateModuleContractIntegrity(workspaceRoot, contract, options)
222179
222443
  var path19 = __toESM(require("node:path"));
222180
222444
  var import_node_fs15 = require("node:fs");
222181
222445
  var suppressionsRelativePath = ".archpilot/suppressions.json";
222182
- function normalizePath9(value) {
222446
+ function normalizePath10(value) {
222183
222447
  let normalized = value.replace(/\\/g, "/").trim();
222184
222448
  while (normalized.startsWith("./")) {
222185
222449
  normalized = normalized.slice(2);
@@ -222217,8 +222481,8 @@ function globToRegex(pattern) {
222217
222481
  return new RegExp(expression, "u");
222218
222482
  }
222219
222483
  function isSuppressionPathMatch(pattern, findingPath) {
222220
- const normalizedPattern = normalizePath9(pattern);
222221
- const normalizedFindingPath = normalizePath9(findingPath);
222484
+ const normalizedPattern = normalizePath10(pattern);
222485
+ const normalizedFindingPath = normalizePath10(findingPath);
222222
222486
  if (!normalizedPattern || !normalizedFindingPath) {
222223
222487
  return false;
222224
222488
  }
@@ -222321,7 +222585,7 @@ async function readValidationSuppressions(workspaceRoot, knownRuleIds) {
222321
222585
  ignored.push({
222322
222586
  index,
222323
222587
  ruleId,
222324
- ...entryScopeValue ? { scope: normalizePath9(entryScopeValue) } : {},
222588
+ ...entryScopeValue ? { scope: normalizePath10(entryScopeValue) } : {},
222325
222589
  reason: "Unknown rule ID. Entry was ignored.",
222326
222590
  ...expiresOn ? { expiresOn } : {}
222327
222591
  });
@@ -222330,7 +222594,7 @@ async function readValidationSuppressions(workspaceRoot, knownRuleIds) {
222330
222594
  suppressions.push({
222331
222595
  index,
222332
222596
  ruleId,
222333
- ...entryScopeValue ? { scope: normalizePath9(entryScopeValue) } : {},
222597
+ ...entryScopeValue ? { scope: normalizePath10(entryScopeValue) } : {},
222334
222598
  ...reason ? { reason } : {},
222335
222599
  ...expiresOn ? { expiresOn } : {}
222336
222600
  });
@@ -225107,66 +225371,8 @@ async function profileValidationPhase(label, run, details) {
225107
225371
  }
225108
225372
  }
225109
225373
 
225110
- // ../core/src/sourceScopeClassification.ts
225111
- function normalizePath10(value) {
225112
- return value.replace(/\\/g, "/").toLowerCase();
225113
- }
225114
- function hasPathSegment(pathValue, pattern) {
225115
- return pathValue.split("/").some((segment) => pattern.test(segment));
225116
- }
225117
- function classifyValidationSourceScope(relativePath) {
225118
- const normalized = normalizePath10(relativePath);
225119
- const fileName = normalized.split("/").at(-1) ?? normalized;
225120
- const extension = fileName.includes(".") ? fileName.slice(fileName.lastIndexOf(".")) : "";
225121
- const isTestFile = /\.(?:spec|test|e2e-spec)\.(?:ts|tsx|js|jsx|mjs|cjs|java|cs|py|php|go)$/u.test(fileName);
225122
- const isE2e = isTestFile && /(?:^|[./_-])e2e(?:[./_-]|$)/u.test(fileName) || hasPathSegment(normalized, /^e2e$/u);
225123
- const isFixture = hasPathSegment(normalized, /^(?:fixtures?|__fixtures__)$/u);
225124
- const isTestPlugin = hasPathSegment(normalized, /^(?:test-plugins?|testing-plugins?)$/u);
225125
- const isExamplePlugin = hasPathSegment(normalized, /^(?:example-plugins?|examples?)$/u);
225126
- const isGenerated = hasPathSegment(normalized, /^(?:generated|__generated__|gen|templates?)$/u) || /\.(?:generated|gen|g)\.(?:ts|tsx|js|jsx|java|cs|py|php|go)$/u.test(fileName) || /\.d\.ts$/u.test(fileName);
225127
- const isMigration = hasPathSegment(normalized, /^(?:migrations?|schema-migrations?|migration-utils?)$/u) || /(?:^|[./_-])migration(?:[./_-]|$)/u.test(fileName);
225128
- const isCliTooling = hasPathSegment(normalized, /^(?:cli|bin|scripts?|tools?|scaffold|scaffolding|generators?)$/u) || /(?:^|[./_-])(?:cli|script|tool|generator|scaffold)(?:[./_-]|$)/u.test(fileName);
225129
- const isFrontend = extension === ".tsx" || extension === ".jsx" || hasPathSegment(normalized, /^(?:frontend|client|browser|ui|admin-ui|dashboard|web-app)$/u) || /\b(?:react|angular|vue|svelte)\b/u.test(normalized);
225130
- const isInfrastructure = hasPathSegment(normalized, /^(?:infrastructure|infra|framework|adapters?|persistence|providers?)$/u) || /(?:transactional-connection|transaction-wrapper|transaction-subscriber|transaction-manager|query-runner|query-builder|event-bus|telemetry|interceptor)\.(?:ts|js|java|cs|py|php|go)$/u.test(fileName);
225131
- let category = "production-backend";
225132
- if (isGenerated) {
225133
- category = "generated";
225134
- } else if (isE2e) {
225135
- category = "e2e";
225136
- } else if (isTestFile || hasPathSegment(normalized, /^(?:test|tests|__tests__|spec|specs)$/u)) {
225137
- category = "test";
225138
- } else if (isTestPlugin) {
225139
- category = "test-plugin";
225140
- } else if (isExamplePlugin) {
225141
- category = "example-plugin";
225142
- } else if (isFixture) {
225143
- category = "fixture";
225144
- } else if (isMigration) {
225145
- category = "migration";
225146
- } else if (isCliTooling) {
225147
- category = "cli-tooling";
225148
- } else if (isFrontend) {
225149
- category = "production-frontend";
225150
- } else if (isInfrastructure) {
225151
- category = "infrastructure";
225152
- }
225153
- const isTestLike = category === "test" || category === "e2e" || category === "fixture" || category === "test-plugin" || category === "example-plugin";
225154
- return {
225155
- category,
225156
- isProduction: category === "production-backend" || category === "production-frontend" || category === "infrastructure",
225157
- isFrontend: category === "production-frontend",
225158
- isTestLike,
225159
- isGenerated: category === "generated",
225160
- isMigration: category === "migration",
225161
- isCliTooling: category === "cli-tooling",
225162
- isInfrastructure: category === "infrastructure"
225163
- };
225164
- }
225165
- function isProductionBackendGovernanceScope(scope) {
225166
- return scope.category === "production-backend";
225167
- }
225168
-
225169
225374
  // ../core/src/dataQueryRiskDetection.ts
225375
+ init_sourceScopeClassification();
225170
225376
  var maxFileSizeBytes = 256 * 1024;
225171
225377
  var supplementalRiskScanExtensions = [".json", ".yaml", ".yml", ".sql"];
225172
225378
  var backendCodeExtensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".java", ".cs", ".py", ".php", ".go"];
@@ -225174,7 +225380,7 @@ var supplementalIgnoredDirectoryNames = [".vscode-test", ".tmp"];
225174
225380
  var batchingEvidencePattern = /\b(?:DataLoader|Promise\.all|findMany\s*\([\s\S]{0,300}\bin\b|where\s*:\s*\{[\s\S]{0,300}\bin\s*:|include\s*:|join\s*\(|leftJoin|innerJoin|JOIN\b)\b/iu;
225175
225381
  var queryReadPattern = /\b((?:this\.)?(?:prisma\.(\w+)|([A-Za-z_$][\w$]*Repository|repository))\.(find\w*|count|aggregate|groupBy)\s*\()/giu;
225176
225382
  var unboundedLoadPattern = /\b(?:const|let|var)\s+(\w+)\s*=\s*await\s+((?:this\.)?(?:prisma\.\w+|\w*Repository|repository)\.(?:findMany|findAll|find))\s*\(([\s\S]{0,700}?)\)\s*;?[\s\S]{0,1000}\b\1\.(?:filter|map|reduce)\s*\(/iu;
225177
- var boundEvidencePattern = /\b(?:take|limit|page|cursor|skip|offset|PageRequest|Pageable)\b/iu;
225383
+ var boundEvidencePattern = /\b(?:take|limit|page|cursor|skip|offset|PageRequest|Pageable|findOne|findOneOrFail|findOneBy|findOneByOrFail|findUnique|findFirst|getOne|getRawOne|first)\b/iu;
225178
225384
  var repeatedQueryPattern = /\b((?:this\.)?(?:prisma\.(\w+)|(\w*Repository|repository))\.(find\w*|count|aggregate|groupBy)\s*\(\s*(?:\{[\s\S]{0,300}?\}|\w+)\s*\))/giu;
225179
225385
  var tenantPredicatePattern = /\b(?:tenantId|tenant_id|organizationId|organization_id|orgId|org_id|accountId|account_id|workspaceId|workspace_id|companyId|company_id|customerId|customer_id)\b/u;
225180
225386
  var codePaginationEvidencePattern = /\b(?:take|skip|limit|offset|page|perPage|pageSize|cursor|Pageable|PageRequest|paginate|simplePaginate|Limit|Offset|Take|Skip|TOP\s+\d+)\b/iu;
@@ -225985,7 +226191,7 @@ function detectRepeatedQueryPattern(method) {
225985
226191
  function extractSqlQueryLiterals(content) {
225986
226192
  const queries = [];
225987
226193
  const patterns = [
225988
- /(?:\b(?:query|execute|executeQuery|createNativeQuery|createQuery|FromSqlRaw|FromSqlInterpolated|Query|QueryContext|QueryRow|QueryRowContext|Exec|ExecContext|Raw|text)|\$queryRaw|\$executeRaw)\s*\([^'"`)]{0,180}?(['"`])([\s\S]{0,900}?)\1/giu,
226194
+ /(?:\b(?:[\w$]+\.)?(?:query|execute|executeQuery|createNativeQuery|createQuery|FromSqlRaw|FromSqlInterpolated|Query|QueryContext|QueryRow|QueryRowContext|Exec|ExecContext|Raw|text)|\$queryRaw|\$executeRaw)\s*\([^'"`)]{0,180}?(['"`])([\s\S]{0,900}?)\1/giu,
225989
226195
  /\b(?:DB::select|DB::statement|DB::raw|DB::table)\s*\([^'"`)]{0,180}?(['"`])([\s\S]{0,900}?)\1/gu,
225990
226196
  /@Query\s*\(\s*(['"`])([\s\S]{0,900}?)\1/gu
225991
226197
  ];
@@ -226072,7 +226278,7 @@ function collectOrmReadEvidence(method) {
226072
226278
  return evidence;
226073
226279
  }
226074
226280
  function getOrmTerminalOperation(snippet) {
226075
- const match = /\.(getMany|getRawMany|getOne|getRawOne|getCount|getExists|execute|findOne|findOneBy|findUnique|findFirst|count|exists|update|delete|remove|save|insert)\s*\(/iu.exec(snippet);
226281
+ const match = /\.(getMany|getRawMany|loadMany|getOne|getRawOne|loadOne|getCount|getExists|execute|findOne|findOneOrFail|findOneBy|findOneByOrFail|findUnique|findFirst|count|exists|update|delete|remove|save|insert)\s*\(/iu.exec(snippet);
226076
226282
  return match?.[1];
226077
226283
  }
226078
226284
  function isOperationalOrBatchQueryContext(file, methodName) {
@@ -226081,12 +226287,20 @@ function isOperationalOrBatchQueryContext(file, methodName) {
226081
226287
  const method = methodName?.toLowerCase() ?? "";
226082
226288
  return segments.some((segment) => /\b(?:health|cache|job|queue|scheduler|indexer|telemetry|metrics)\b/u.test(segment.replace(/-/g, " "))) || /(^|\/)(?:health-check|healthchecks?|cache|job-queue|scheduler|search|indexer|telemetry|metrics)(?:\/|-)/u.test(pathValue) || /(?:health-check|healthcheck|cache|job-queue|scheduler|search|indexer|telemetry|metrics)\.(?:ts|tsx|js|jsx|java|cs|py|php|go)$/u.test(pathValue) || /\b(?:health|cache|job|queue|schedule|scheduler|index|telemetry|metrics|buffer|worker|batch)\b/u.test(method) || method.includes("batch") || /^on(?:moduleinit|applicationbootstrap|applicationstart|init)$/u.test(method);
226083
226289
  }
226084
- function isPointLookupMethodName(methodName) {
226085
- return /^(?:getorcreate|findone|findby|getby|loadby|resolveby)/iu.test(methodName);
226290
+ function isScopedRelationLoad(snippet) {
226291
+ return /\.relation\s*\(/iu.test(snippet) && /\.of\s*\(\s*[^)]{1,180}\)\s*\.loadMany\s*\(/iu.test(snippet);
226086
226292
  }
226087
- function isNonCollectionOrmRead(label, snippet) {
226293
+ function hasAssignedBuilderBoundedTerminal(methodBody, snippet) {
226294
+ const variableMatch = /\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*(?:[\s\S]{0,240}?)createQueryBuilder\s*\(/iu.exec(snippet);
226295
+ const variableName = variableMatch?.[1];
226296
+ if (!variableName) {
226297
+ return false;
226298
+ }
226299
+ return new RegExp(`\\b${variableName}\\s*\\.\\s*(?:getOne|getRawOne|loadOne|getCount|getExists)\\s*\\(`, "iu").test(methodBody);
226300
+ }
226301
+ function isNonCollectionOrmRead(label, snippet, methodBody = snippet) {
226088
226302
  const terminal = getOrmTerminalOperation(snippet);
226089
- return /\b(?:findOne|findOneBy|findUnique|findFirst|count|exists|aggregate)\b/iu.test(label) || !!terminal && /^(?:getOne|getRawOne|getCount|getExists|findOne|findOneBy|findUnique|findFirst|count|exists|update|delete|remove|save|insert|execute)$/iu.test(terminal);
226303
+ return /\b(?:findOne|findOneOrFail|findOneBy|findOneByOrFail|findUnique|findFirst|count|exists|aggregate)\b/iu.test(label) || !!terminal && /^(?:getOne|getRawOne|loadOne|getCount|getExists|findOne|findOneOrFail|findOneBy|findOneByOrFail|findUnique|findFirst|count|exists|update|delete|remove|save|insert|execute)$/iu.test(terminal) || isScopedRelationLoad(snippet) || hasAssignedBuilderBoundedTerminal(methodBody, snippet);
226090
226304
  }
226091
226305
  function hasOrmBoundEvidence(snippet) {
226092
226306
  return codePaginationEvidencePattern.test(snippet) || /\.(?:take|limit|offset|skip)\s*\(/iu.test(snippet) || /\b(?:maxResults|setMaxResults|firstResult|setFirstResult)\s*\(/iu.test(snippet) || /\b(?:pageSize|perPage|limit|take)\s*[:=]\s*\d+\b/iu.test(snippet);
@@ -226121,7 +226335,7 @@ function detectOrmQueryShapeFindings(method, config) {
226121
226335
  target: evidence.label
226122
226336
  }));
226123
226337
  }
226124
- if (!isOperationalOrBatchQueryContext(method.file, method.name) && !isPointLookupMethodName(method.name) && !isNonCollectionOrmRead(evidence.label, evidence.snippet) && !hasOrmBoundEvidence(evidence.snippet)) {
226338
+ if (!isOperationalOrBatchQueryContext(method.file, method.name) && !isNonCollectionOrmRead(evidence.label, evidence.snippet, method.body) && !hasOrmBoundEvidence(evidence.snippet)) {
226125
226339
  const target = getOrmQueryTarget(method, evidence.label, evidence.snippet);
226126
226340
  const label = getOrmQueryLabel(method, evidence.label, evidence.snippet);
226127
226341
  findings.push(createCodeFinding({
@@ -226146,9 +226360,12 @@ function detectCodeQueryRiskFindings(files, config, astCache) {
226146
226360
  findings.push(...detectCodeSqlQueryShapeFindings(file, config));
226147
226361
  }
226148
226362
  for (const method of extractMethodBodies(file, astCache)) {
226363
+ if (!isProductionBackend) {
226364
+ continue;
226365
+ }
226149
226366
  nPlusOneEvidence.push(...detectNPlusOneQueryRisk(method));
226150
226367
  findings.push(
226151
- ...isProductionBackend ? detectOrmQueryShapeFindings(method, config) : [],
226368
+ ...detectOrmQueryShapeFindings(method, config),
226152
226369
  ...detectLargeCollectionLoading(method),
226153
226370
  ...detectMissingProjection(method),
226154
226371
  ...detectRepeatedQueryPattern(method)
@@ -226241,6 +226458,7 @@ var import_node_fs25 = require("node:fs");
226241
226458
  var ts3 = __toESM(require_typescript());
226242
226459
  init_moduleDiscovery();
226243
226460
  init_archpilotIgnore();
226461
+ init_sourceScopeClassification();
226244
226462
  var ApplicationLayeringRuleIds = {
226245
226463
  CONTROLLER_BUSINESS_LOGIC: "AP-APP-001",
226246
226464
  REPOSITORY_BUSINESS_LOGIC: "AP-APP-002",
@@ -226577,17 +226795,40 @@ function getModulePathForName(contract, moduleName) {
226577
226795
  const reference = contract.modules?.[moduleName];
226578
226796
  return normalizePath11(reference?.path ?? `${modulesRoot}/${moduleName}`);
226579
226797
  }
226580
- function getPathSegmentsInsideModule(relativePath, modulePath) {
226798
+ function getComponentEntries2(contract) {
226799
+ const components = contract.components;
226800
+ if (!components) {
226801
+ return [];
226802
+ }
226803
+ return Array.isArray(components) ? components.map((component, index) => [
226804
+ typeof component.id === "string" && component.id.trim().length > 0 ? component.id.trim() : `component-${index}`,
226805
+ component
226806
+ ]) : Object.entries(components);
226807
+ }
226808
+ function getComponentPathForFile(contract, relativePath) {
226581
226809
  const normalized = normalizePath11(relativePath).toLowerCase();
226582
- if (!modulePath) {
226810
+ const candidates = getComponentEntries2(contract).map(([, component]) => component.path).filter(
226811
+ (componentPath) => typeof componentPath === "string" && componentPath.trim().length > 0
226812
+ ).map((componentPath) => normalizePath11(componentPath)).filter((componentPath) => {
226813
+ const normalizedComponentPath = componentPath.toLowerCase();
226814
+ return normalized === normalizedComponentPath || normalized.startsWith(`${normalizedComponentPath}/`);
226815
+ }).sort((left, right) => right.length - left.length || left.localeCompare(right));
226816
+ return candidates[0];
226817
+ }
226818
+ function getOwnershipPathForFile(contract, relativePath, moduleName) {
226819
+ return getModulePathForName(contract, moduleName) ?? getComponentPathForFile(contract, relativePath);
226820
+ }
226821
+ function getPathSegmentsInsideModule(relativePath, ownershipPath) {
226822
+ const normalized = normalizePath11(relativePath).toLowerCase();
226823
+ if (!ownershipPath) {
226583
226824
  return normalized.split("/");
226584
226825
  }
226585
- const normalizedModulePath = normalizePath11(modulePath).toLowerCase();
226586
- if (normalized === normalizedModulePath) {
226826
+ const normalizedOwnershipPath = normalizePath11(ownershipPath).toLowerCase();
226827
+ if (normalized === normalizedOwnershipPath) {
226587
226828
  return [];
226588
226829
  }
226589
- if (normalized.startsWith(`${normalizedModulePath}/`)) {
226590
- return normalized.slice(normalizedModulePath.length + 1).split("/");
226830
+ if (normalized.startsWith(`${normalizedOwnershipPath}/`)) {
226831
+ return normalized.slice(normalizedOwnershipPath.length + 1).split("/");
226591
226832
  }
226592
226833
  return normalized.split("/");
226593
226834
  }
@@ -226723,7 +226964,10 @@ function createFinding(input2) {
226723
226964
  function hasRepositoryLayer(files, contract) {
226724
226965
  return files.some((file) => {
226725
226966
  const moduleName = inferModuleForPath2(contract, file.relativePath);
226726
- return classifySourceFile(file, getModulePathForName(contract, moduleName)).isRepository;
226967
+ return classifySourceFile(
226968
+ file,
226969
+ getOwnershipPathForFile(contract, file.relativePath, moduleName)
226970
+ ).isRepository;
226727
226971
  });
226728
226972
  }
226729
226973
  function hasServiceLayer(files) {
@@ -226912,35 +227156,30 @@ function isDbModelEvidenceToken(value) {
226912
227156
  const lower = normalized.toLowerCase();
226913
227157
  const excluded = /* @__PURE__ */ new Set([
226914
227158
  "a",
227159
+ "all",
226915
227160
  "an",
226916
- "api",
226917
- "client",
226918
- "database",
226919
- "from",
226920
- "into",
226921
- "join",
226922
- "openapi",
226923
- "or",
226924
- "paddle",
226925
- "provider",
227161
+ "doing",
227162
+ "first",
227163
+ "is",
227164
+ "outside",
226926
227165
  "resend",
226927
- "s3",
226928
- "select",
226929
- "stripe",
227166
+ "scratch",
226930
227167
  "swagger",
226931
- "table",
226932
- "the",
226933
- "this",
226934
- "to",
226935
- "update",
226936
- "where",
226937
- "with"
227168
+ "the"
226938
227169
  ]);
226939
227170
  if (excluded.has(lower)) {
226940
227171
  return false;
226941
227172
  }
226942
227173
  return !/(?:client|provider|service|controller|guard|swagger|openapi)$/iu.test(normalized);
226943
227174
  }
227175
+ function isStructuredSqlTableEvidence(value, keyword, quote, following = "") {
227176
+ const normalized = value.trim();
227177
+ const hasStructuralEvidence = /^(?:from|update|into)$/iu.test(keyword) || quote !== void 0 && quote.length > 0 || /[_.]/u.test(normalized) || /^join$/iu.test(keyword) && /\bon\b/iu.test(following);
227178
+ return hasStructuralEvidence && isDbModelEvidenceToken(normalized);
227179
+ }
227180
+ function extractSqlLikeLiterals(content) {
227181
+ return [...content.matchAll(/(['"`])([\s\S]{0,1200}?)\1/gu)].map((match) => match[2] ?? "").filter((literal) => /\b(?:select|update|delete|insert)\b[\s\S]{0,400}\b(?:from|join|into|update)\b/iu.test(literal));
227182
+ }
226944
227183
  function extractDbModelsTouched(content) {
226945
227184
  const models = /* @__PURE__ */ new Set();
226946
227185
  for (const match of content.matchAll(/\b(?:this\.)?prisma\.([a-z]\w*)\./giu)) {
@@ -226948,9 +227187,13 @@ function extractDbModelsTouched(content) {
226948
227187
  models.add(match[1]);
226949
227188
  }
226950
227189
  }
226951
- for (const match of content.matchAll(/\b(?:from|join|update|into)\s+["`]?([A-Za-z_][\w]*)["`]?/giu)) {
226952
- if (match[1] && isDbModelEvidenceToken(match[1])) {
226953
- models.add(match[1]);
227190
+ for (const sqlLiteral of extractSqlLikeLiterals(content)) {
227191
+ for (const match of sqlLiteral.matchAll(/\b(?:from|join|update|into)\s+(["`]?)([A-Za-z_][\w]*(?:\.[A-Za-z_][\w]*)?)\1/giu)) {
227192
+ const keyword = /\b(from|join|update|into)\b/iu.exec(match[0])?.[1] ?? "";
227193
+ const following = sqlLiteral.slice((match.index ?? 0) + match[0].length, (match.index ?? 0) + match[0].length + 120);
227194
+ if (match[2] && isStructuredSqlTableEvidence(match[2], keyword, match[1], following)) {
227195
+ models.add(match[2]);
227196
+ }
226954
227197
  }
226955
227198
  }
226956
227199
  return sortUnique6(models).slice(0, 6);
@@ -227046,7 +227289,7 @@ async function detectApplicationLayeringFindings(input2) {
227046
227289
  const moduleName = inferModuleForPath2(input2.contract, file.relativePath);
227047
227290
  const classification = classifySourceFile(
227048
227291
  file,
227049
- getModulePathForName(input2.contract, moduleName),
227292
+ getOwnershipPathForFile(input2.contract, file.relativePath, moduleName),
227050
227293
  input2.astCache
227051
227294
  );
227052
227295
  const candidates = [
@@ -227694,6 +227937,7 @@ var import_node_fs27 = require("node:fs");
227694
227937
  var ts5 = __toESM(require_typescript());
227695
227938
  init_moduleDiscovery();
227696
227939
  init_archpilotIgnore();
227940
+ init_sourceScopeClassification();
227697
227941
  var RuleIds2 = {
227698
227942
  TXN_BOUNDARY_TOO_BROAD: "AP-TXN-001",
227699
227943
  TXN_IN_CONTROLLER: "AP-TXN-002",
@@ -228737,35 +228981,30 @@ function isDbModelEvidenceToken2(value) {
228737
228981
  const lower = normalized.toLowerCase();
228738
228982
  const excluded = /* @__PURE__ */ new Set([
228739
228983
  "a",
228984
+ "all",
228740
228985
  "an",
228741
- "api",
228742
- "client",
228743
- "database",
228744
- "from",
228745
- "into",
228746
- "join",
228747
- "openapi",
228748
- "or",
228749
- "paddle",
228750
- "provider",
228986
+ "doing",
228987
+ "first",
228988
+ "is",
228989
+ "outside",
228751
228990
  "resend",
228752
- "s3",
228753
- "select",
228754
- "stripe",
228991
+ "scratch",
228755
228992
  "swagger",
228756
- "table",
228757
- "the",
228758
- "this",
228759
- "to",
228760
- "update",
228761
- "where",
228762
- "with"
228993
+ "the"
228763
228994
  ]);
228764
228995
  if (excluded.has(lower)) {
228765
228996
  return false;
228766
228997
  }
228767
228998
  return !/(?:client|provider|service|controller|guard|swagger|openapi)$/iu.test(normalized);
228768
228999
  }
229000
+ function isStructuredSqlTableEvidence2(value, keyword, quote, following = "") {
229001
+ const normalized = value.trim();
229002
+ const hasStructuralEvidence = /^(?:from|update|into)$/iu.test(keyword) || quote !== void 0 && quote.length > 0 || /[_.]/u.test(normalized) || /^join$/iu.test(keyword) && /\bon\b/iu.test(following);
229003
+ return hasStructuralEvidence && isDbModelEvidenceToken2(normalized);
229004
+ }
229005
+ function extractSqlLikeLiterals2(content) {
229006
+ return [...content.matchAll(/(['"`])([\s\S]{0,1200}?)\1/gu)].map((match) => match[2] ?? "").filter((literal) => /\b(?:select|update|delete|insert)\b[\s\S]{0,400}\b(?:from|join|into|update)\b/iu.test(literal));
229007
+ }
228769
229008
  function extractDbModelsTouched2(content) {
228770
229009
  const models = /* @__PURE__ */ new Set();
228771
229010
  for (const match of content.matchAll(/\b(?:this\.)?prisma\.([a-z]\w*)\./giu)) {
@@ -228773,9 +229012,13 @@ function extractDbModelsTouched2(content) {
228773
229012
  models.add(match[1]);
228774
229013
  }
228775
229014
  }
228776
- for (const match of content.matchAll(/\b(?:from|join|update|into)\s+["`]?([A-Za-z_][\w]*)["`]?/giu)) {
228777
- if (match[1] && isDbModelEvidenceToken2(match[1])) {
228778
- models.add(match[1]);
229015
+ for (const sqlLiteral of extractSqlLikeLiterals2(content)) {
229016
+ for (const match of sqlLiteral.matchAll(/\b(?:from|join|update|into)\s+(["`]?)([A-Za-z_][\w]*(?:\.[A-Za-z_][\w]*)?)\1/giu)) {
229017
+ const keyword = /\b(from|join|update|into)\b/iu.exec(match[0])?.[1] ?? "";
229018
+ const following = sqlLiteral.slice((match.index ?? 0) + match[0].length, (match.index ?? 0) + match[0].length + 120);
229019
+ if (match[2] && isStructuredSqlTableEvidence2(match[2], keyword, match[1], following)) {
229020
+ models.add(match[2]);
229021
+ }
228779
229022
  }
228780
229023
  }
228781
229024
  return sortUnique7(models).slice(0, 6);
@@ -229025,6 +229268,7 @@ var path33 = __toESM(require("node:path"));
229025
229268
  var import_node_fs28 = require("node:fs");
229026
229269
  init_moduleDiscovery();
229027
229270
  init_archpilotIgnore();
229271
+ init_sourceScopeClassification();
229028
229272
  var RuleIds3 = {
229029
229273
  MISSING_PAGINATION: "AP-API-010",
229030
229274
  BULK_OPERATION_RISK: "AP-API-011",
@@ -229541,8 +229785,34 @@ function hasPaginationEvidence2(endpoint, contractEndpoints) {
229541
229785
  ${endpoint.signature}
229542
229786
  ${endpoint.body}`);
229543
229787
  }
229788
+ function stripStaticLiteralNoise(value) {
229789
+ return value.replace(/\/\*[\s\S]*?\*\//gu, " ").replace(/\/\/.*$/gmu, " ").replace(/(['"`])(?:\\.|(?!\1)[\s\S])*\1/gu, '""');
229790
+ }
229791
+ function isStaticCollectionExpression(expression) {
229792
+ const normalized = expression.trim().replace(/;$/u, "").trim();
229793
+ return /^(?:Object\.)?(?:freeze|values|entries|keys)\s*\(/u.test(normalized) || /^(?:\[[\s\S]*\]|\{[\s\S]*\})$/u.test(normalized) || /^(?:[A-Z][A-Za-z0-9_]*|[a-z][A-Za-z0-9_]*(?:Config|Configs|Catalog|Catalogs|Metadata|Definitions|Types|Widgets|Constants))$/u.test(normalized);
229794
+ }
229795
+ function hasStaticDeclarationEvidence(fileContent, identifier) {
229796
+ const escaped = identifier.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
229797
+ return new RegExp(`\\bimport\\s+(?:\\{[^}]*\\b${escaped}\\b[^}]*\\}|${escaped}\\b)`, "u").test(fileContent) || new RegExp(`\\b(?:const|readonly)\\s+${escaped}\\s*=\\s*(?:Object\\.freeze\\s*\\(|\\[|\\{)`, "u").test(fileContent) || new RegExp(`\\benum\\s+${escaped}\\b`, "u").test(fileContent);
229798
+ }
229799
+ function isStaticCollectionBackedEndpoint(endpoint) {
229800
+ const body = endpoint.body.trim();
229801
+ if (/\b(?:await|repository|Repository|createQueryBuilder|findMany|findAll|find\s*\(|query\s*\(|execute\s*\(|service\.)\b/iu.test(body)) {
229802
+ return false;
229803
+ }
229804
+ const returnMatch = /\breturn\s+([\s\S]{0,500}?);/u.exec(body) ?? /\bres\.(?:json|send)\s*\(\s*([\s\S]{0,500}?)\s*\)\s*;?/u.exec(body) ?? /\bOk\s*\(\s*([\s\S]{0,500}?)\s*\)\s*;?/u.exec(body);
229805
+ if (!returnMatch?.[1]) {
229806
+ return false;
229807
+ }
229808
+ const expression = returnMatch[1].trim();
229809
+ if (/^[A-Za-z_$][\w$]*$/u.test(expression)) {
229810
+ return hasStaticDeclarationEvidence(endpoint.file.content, expression);
229811
+ }
229812
+ return isStaticCollectionExpression(stripStaticLiteralNoise(expression));
229813
+ }
229544
229814
  function detectPaginationFindings(endpoints, contractEndpoints) {
229545
- return endpoints.filter((endpoint) => isCollectionGet(endpoint) && !hasPaginationEvidence2(endpoint, contractEndpoints)).map((endpoint) => createFinding4({
229815
+ return endpoints.filter((endpoint) => isCollectionGet(endpoint) && !hasPaginationEvidence2(endpoint, contractEndpoints) && !isStaticCollectionBackedEndpoint(endpoint)).map((endpoint) => createFinding4({
229546
229816
  id: RuleIds3.MISSING_PAGINATION,
229547
229817
  message: `Collection endpoint ${endpoint.httpMethod.toUpperCase()} ${endpoint.path} lacks visible pagination evidence.`,
229548
229818
  endpoint
@@ -231200,7 +231470,7 @@ src/
231200
231470
  architectureScope: "module",
231201
231471
  applicability: { requiresArchitectureModules: true },
231202
231472
  description: "Checks whether cross-module imports target another module through its public entrypoints rather than internal implementation files.",
231203
- recommendedFix: "Import another module through src/modules/<module>/index.ts or src/modules/<module>/public rather than reaching into internal files."
231473
+ recommendedFix: "Import through the target module or package public entrypoint declared in its contract rather than reaching into internal implementation files."
231204
231474
  },
231205
231475
  DEP_CROSS_MODULE_DEPENDENCY_DECLARED_IN_CONTRACT: {
231206
231476
  id: ValidationRuleIds.DEP_CROSS_MODULE_DEPENDENCY_DECLARED_IN_CONTRACT,
@@ -242593,6 +242863,9 @@ var ignoredRootPathPrefixes = [
242593
242863
  function normalizeRelativePath5(value) {
242594
242864
  return value.replaceAll("\\", "/");
242595
242865
  }
242866
+ function isUnderJvmResourceRoot2(relativePath) {
242867
+ return /(^|\/)src\/main\/resources(?:\/|$)/u.test(normalizeRelativePath5(relativePath).toLowerCase());
242868
+ }
242596
242869
  function sortUnique16(values) {
242597
242870
  return [...new Set(values)].sort((left, right) => left.localeCompare(right));
242598
242871
  }
@@ -242730,7 +243003,7 @@ function collectDetectedRoots(scan) {
242730
243003
  const roots = /* @__PURE__ */ new Set();
242731
243004
  for (const manifestName of manifestFileNames) {
242732
243005
  for (const manifestPath of scan.manifestPathsByName[manifestName]) {
242733
- if (isIgnoredRelativePath(manifestPath)) {
243006
+ if (isIgnoredRelativePath(manifestPath) || isUnderJvmResourceRoot2(manifestPath)) {
242734
243007
  continue;
242735
243008
  }
242736
243009
  const containingDirectory = normalizeRelativePath5(path58.dirname(manifestPath));
@@ -242745,11 +243018,11 @@ function buildResultFromScan(scan) {
242745
243018
  const evidence = [];
242746
243019
  const detectedRoots = collectDetectedRoots(scan);
242747
243020
  const filteredManifestPathsByName = {
242748
- "package.json": scan.manifestPathsByName["package.json"].filter((entry) => !isIgnoredRelativePath(entry)),
242749
- "pom.xml": scan.manifestPathsByName["pom.xml"].filter((entry) => !isIgnoredRelativePath(entry)),
242750
- "requirements.txt": scan.manifestPathsByName["requirements.txt"].filter((entry) => !isIgnoredRelativePath(entry)),
242751
- "go.mod": scan.manifestPathsByName["go.mod"].filter((entry) => !isIgnoredRelativePath(entry)),
242752
- "composer.json": scan.manifestPathsByName["composer.json"].filter((entry) => !isIgnoredRelativePath(entry))
243021
+ "package.json": scan.manifestPathsByName["package.json"].filter((entry) => !isIgnoredRelativePath(entry) && !isUnderJvmResourceRoot2(entry)),
243022
+ "pom.xml": scan.manifestPathsByName["pom.xml"].filter((entry) => !isIgnoredRelativePath(entry) && !isUnderJvmResourceRoot2(entry)),
243023
+ "requirements.txt": scan.manifestPathsByName["requirements.txt"].filter((entry) => !isIgnoredRelativePath(entry) && !isUnderJvmResourceRoot2(entry)),
243024
+ "go.mod": scan.manifestPathsByName["go.mod"].filter((entry) => !isIgnoredRelativePath(entry) && !isUnderJvmResourceRoot2(entry)),
243025
+ "composer.json": scan.manifestPathsByName["composer.json"].filter((entry) => !isIgnoredRelativePath(entry) && !isUnderJvmResourceRoot2(entry))
242753
243026
  };
242754
243027
  let monorepoStrongSignals = 0;
242755
243028
  let monorepoWeakSignals = 0;
@@ -243049,6 +243322,12 @@ function confidenceWeight(confidence) {
243049
243322
  return 1;
243050
243323
  }
243051
243324
  function compareCandidates2(left, right) {
243325
+ if (left.result.confidence === "high" && right.result.confidence === "high" && left.adapter.category === "framework" && right.adapter.category === "generic-language" && left.adapter.ecosystem === right.adapter.ecosystem) {
243326
+ return -1;
243327
+ }
243328
+ if (left.result.confidence === "high" && right.result.confidence === "high" && left.adapter.category === "generic-language" && right.adapter.category === "framework" && left.adapter.ecosystem === right.adapter.ecosystem) {
243329
+ return 1;
243330
+ }
243052
243331
  const confidenceDiff = confidenceWeight(right.result.confidence) - confidenceWeight(left.result.confidence);
243053
243332
  if (confidenceDiff !== 0) {
243054
243333
  return confidenceDiff;
@@ -244794,6 +245073,9 @@ var ignoredDirectoryNames12 = /* @__PURE__ */ new Set([
244794
245073
  function normalizePath24(value) {
244795
245074
  return value.replaceAll("\\", "/");
244796
245075
  }
245076
+ function isUnderJvmResourceRoot3(relativePath) {
245077
+ return /(^|\/)src\/main\/resources(?:\/|$)/u.test(normalizePath24(relativePath).toLowerCase());
245078
+ }
244797
245079
  function unique(values) {
244798
245080
  return [...new Set(values)];
244799
245081
  }
@@ -244942,7 +245224,7 @@ function hasAnyDependency2(summary, dependencyNames) {
244942
245224
  function collectCandidateRoots(workspaceRoot, topology, ignoreMatcher) {
244943
245225
  const roots = /* @__PURE__ */ new Set();
244944
245226
  for (const root of topology.detectedRoots ?? []) {
244945
- if (root && root !== "." && !isIgnoredPath6(ignoreMatcher, root) && !isSupportingAssetRoot(root)) {
245227
+ if (root && root !== "." && !isIgnoredPath6(ignoreMatcher, root) && !isSupportingAssetRoot(root) && !isUnderJvmResourceRoot3(root)) {
244946
245228
  roots.add(normalizePath24(root));
244947
245229
  }
244948
245230
  }
@@ -244950,7 +245232,7 @@ function collectCandidateRoots(workspaceRoot, topology, ignoreMatcher) {
244950
245232
  const absoluteBase = path63.join(workspaceRoot, base);
244951
245233
  for (const entry of safeReadDirEntries4(absoluteBase)) {
244952
245234
  const relativePath = `${base}/${entry.name}`;
244953
- if (!entry.isDirectory() || ignoredDirectoryNames12.has(entry.name) || isIgnoredPath6(ignoreMatcher, relativePath) || isSupportingAssetRoot(relativePath) || (topology.detectedRoots?.length ?? 0) > 0 && !topology.detectedRoots?.includes(relativePath) && !hasManifest(workspaceRoot, relativePath)) {
245235
+ if (!entry.isDirectory() || ignoredDirectoryNames12.has(entry.name) || isIgnoredPath6(ignoreMatcher, relativePath) || isSupportingAssetRoot(relativePath) || isUnderJvmResourceRoot3(relativePath) || (topology.detectedRoots?.length ?? 0) > 0 && !topology.detectedRoots?.includes(relativePath) && !hasManifest(workspaceRoot, relativePath)) {
244954
245236
  continue;
244955
245237
  }
244956
245238
  roots.add(relativePath);
@@ -245034,9 +245316,10 @@ function inspectRoot(workspaceRoot, root, ignoreMatcher) {
245034
245316
  addEvidence5(evidence, "Detected modules root");
245035
245317
  }
245036
245318
  const hasFrontendSignals = fileExists5(scan.files, "next.config.js") || fileExists5(scan.files, "next.config.ts") || fileExists5(scan.files, "angular.json") || fileExists5(scan.files, "vite.config.ts") || fileExists5(scan.files, "vite.config.js") || hasDirectory(scan.directories, "pages") || hasDirectory(scan.directories, "public") || hasAnyDependency2(packageJson, ["next", "react", "vue", "@angular/core"]);
245319
+ const hasRunnableFrontendSignals = fileExists5(scan.files, "next.config.js") || fileExists5(scan.files, "next.config.ts") || fileExists5(scan.files, "angular.json") || fileExists5(scan.files, "vite.config.ts") || fileExists5(scan.files, "vite.config.js") || fileExists5(scan.files, "index.html") || hasDirectory(scan.directories, "pages") || hasDirectory(scan.directories, "src/app");
245037
245320
  const hasBackendSignals = hasApiBoundary || hasDatabaseAccess || fileExists5(scan.files, "pom.xml") || fileExists5(scan.files, "requirements.txt") || fileExists5(scan.files, "go.mod") || hasDirectory(scan.directories, "src/main/java");
245038
245321
  let classification = "unknown";
245039
- if ((root.startsWith("packages/") || root.startsWith("libs/")) && !hasApiBoundary) {
245322
+ if ((root.startsWith("packages/") || root.startsWith("libs/")) && !hasRunnableFrontendSignals && !hasApiBoundary) {
245040
245323
  classification = "shared_package";
245041
245324
  } else if (hasBackendSignals && !hasFrontendSignals) {
245042
245325
  classification = "backend_app";
@@ -245147,6 +245430,8 @@ function isIgnoredComponentCandidatePath(componentPath) {
245147
245430
  const ignoredRootSegments = [
245148
245431
  "tests",
245149
245432
  "test",
245433
+ "cypress",
245434
+ "cypress-tests",
245150
245435
  "__tests__",
245151
245436
  "fixtures",
245152
245437
  "smoke",
@@ -245214,8 +245499,14 @@ function recordKeys(value) {
245214
245499
  function hasObject(value) {
245215
245500
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
245216
245501
  }
245502
+ function hasPackagePublishSurface(packageJson) {
245503
+ return hasObject(packageJson?.exports) || typeof packageJson?.main === "string" || typeof packageJson?.module === "string" || typeof packageJson?.types === "string" || hasObject(packageJson?.publishConfig) || Array.isArray(packageJson?.files);
245504
+ }
245505
+ function absoluteComponentRoot(workspaceRoot, componentPath) {
245506
+ return componentPath === "." ? workspaceRoot : path64.join(workspaceRoot, ...componentPath.split("/"));
245507
+ }
245217
245508
  function readPackageJson(workspaceRoot, componentPath) {
245218
- const absoluteRoot = componentPath === "." ? workspaceRoot : path64.join(workspaceRoot, ...componentPath.split("/"));
245509
+ const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
245219
245510
  return safeReadJson(path64.join(absoluteRoot, "package.json"));
245220
245511
  }
245221
245512
  function readTextFileSafe(filePath) {
@@ -245233,7 +245524,10 @@ function readFirstXmlTag(value, tagName) {
245233
245524
  return match?.[1]?.trim().replace(/\s+/gu, " ");
245234
245525
  }
245235
245526
  function readMavenMetadata(workspaceRoot, componentPath) {
245236
- const absoluteRoot = componentPath === "." ? workspaceRoot : path64.join(workspaceRoot, ...componentPath.split("/"));
245527
+ if (isUnderJvmResourceRoot4(componentPath)) {
245528
+ return void 0;
245529
+ }
245530
+ const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
245237
245531
  const pomXml = readTextFileSafe(path64.join(absoluteRoot, "pom.xml"));
245238
245532
  if (!pomXml) {
245239
245533
  return void 0;
@@ -245246,7 +245540,15 @@ function readMavenMetadata(workspaceRoot, componentPath) {
245246
245540
  artifactId: readFirstXmlTag(normalizedPom, "artifactId"),
245247
245541
  name: readFirstXmlTag(normalizedPom, "name"),
245248
245542
  hasPom: true,
245543
+ hasModules: /<modules\b/iu.test(normalizedPom),
245249
245544
  hasDependencyManagement: /<dependencyManagement\b/iu.test(normalizedPom),
245545
+ hasSpringBootPlugin: /\bspring-boot-maven-plugin\b/iu.test(normalizedPom),
245546
+ hasSpringBootRepackageGoal: /<goal>\s*repackage\s*<\/goal>/iu.test(normalizedPom),
245547
+ configuredMainClass: readFirstXmlTag(normalizedPom, "mainClass") ?? readFirstXmlTag(normalizedPom, "start-class"),
245548
+ hasSpringBootStarterDependency: dependencyBlocks.some((block) => /<artifactId>\s*spring-boot-starter(?:-[^<]+)?\s*<\/artifactId>/iu.test(block)),
245549
+ hasSpringBootAutoconfigureDependency: dependencyBlocks.some((block) => /<artifactId>\s*spring-boot-autoconfigure\s*<\/artifactId>/iu.test(block)),
245550
+ hasSpringBootAutoconfigureProcessor: /spring-boot-autoconfigure-processor|spring-boot-configuration-processor/iu.test(normalizedPom),
245551
+ hasDocumentationTooling: /asciidoctor-maven-plugin|maven-site-plugin|doxia|antora|javadoc|<goal>\s*site\s*<\/goal>/iu.test(normalizedPom),
245250
245552
  testScopedDependencyCount: dependencyBlocks.filter((block) => /<scope>\s*test\s*<\/scope>/iu.test(block)).length,
245251
245553
  totalDependencyCount: dependencyBlocks.length,
245252
245554
  hasMavenPluginConfiguration: packaging === "maven-plugin" || /maven-plugin-plugin|<goalPrefix>|<mojo/iu.test(normalizedPom),
@@ -245329,21 +245631,384 @@ function resolveId(componentPath, usedIds) {
245329
245631
  usedIds.add(id);
245330
245632
  return id;
245331
245633
  }
245332
- function resolveKind(candidate, localProjectKinds) {
245634
+ function hasRunnableFrontendComponentEvidence(workspaceRoot, componentPath) {
245635
+ const absoluteRoot = componentPath === "." ? workspaceRoot : path64.join(workspaceRoot, ...componentPath.split("/"));
245636
+ const packageJson = readPackageJson(workspaceRoot, componentPath);
245637
+ const dependencies = [
245638
+ ...recordKeys(packageJson?.dependencies),
245639
+ ...recordKeys(packageJson?.devDependencies)
245640
+ ];
245641
+ const scripts = recordKeys(packageJson?.scripts);
245642
+ const hasFrontendFramework = dependencies.some(
245643
+ (dependency) => /^(?:react|next|vue|@angular\/core|@sveltejs\/kit)$/u.test(dependency)
245644
+ );
245645
+ const hasInteractiveRunnableScript = scripts.some(
245646
+ (script) => /^(?:dev|start|serve|preview)(?::|$)/u.test(script)
245647
+ );
245648
+ const hasBundlerConfig = [
245649
+ "next.config.js",
245650
+ "next.config.ts",
245651
+ "vite.config.js",
245652
+ "vite.config.ts",
245653
+ "angular.json"
245654
+ ].some((relativePath) => pathExists19(path64.join(absoluteRoot, ...relativePath.split("/"))));
245655
+ const hasApplicationEntry = [
245656
+ "index.html",
245657
+ "src/main.tsx",
245658
+ "src/main.ts",
245659
+ "src/App.tsx",
245660
+ "src/app",
245661
+ "pages"
245662
+ ].some((relativePath) => pathExists19(path64.join(absoluteRoot, ...relativePath.split("/"))));
245663
+ return hasFrontendFramework && (hasApplicationEntry || hasInteractiveRunnableScript && hasBundlerConfig);
245664
+ }
245665
+ function isUnderJvmResourceRoot4(componentPath) {
245666
+ return /(^|\/)src\/main\/resources(?:\/|$)/u.test(normalizePath25(componentPath).toLowerCase());
245667
+ }
245668
+ function hasFileUnderRoot(root, pattern) {
245669
+ if (!pathExists19(root)) {
245670
+ return false;
245671
+ }
245672
+ const entries = fs58.readdirSync(root, { recursive: true, withFileTypes: true });
245673
+ return entries.some((entry) => entry.isFile() && pattern.test(entry.name));
245674
+ }
245675
+ var javaMainMethodPattern = /\bpublic\s+static\s+void\s+main\s*\(\s*String\s*(?:(?:\[\s*\]\s*)|\.\.\.\s*)[A-Za-z_$][\w$]*\s*(?:\[\s*\])?\s*\)/u;
245676
+ function stripJavaLikeCommentsAndStrings(value) {
245677
+ let result = "";
245678
+ let index = 0;
245679
+ let state = "code";
245680
+ while (index < value.length) {
245681
+ const current = value[index] ?? "";
245682
+ const next = value[index + 1] ?? "";
245683
+ const nextTwo = value.slice(index, index + 3);
245684
+ if (state === "code") {
245685
+ if (current === "/" && next === "/") {
245686
+ result += " ";
245687
+ index += 2;
245688
+ state = "line-comment";
245689
+ continue;
245690
+ }
245691
+ if (current === "/" && next === "*") {
245692
+ result += " ";
245693
+ index += 2;
245694
+ state = "block-comment";
245695
+ continue;
245696
+ }
245697
+ if (nextTwo === '"""') {
245698
+ result += " ";
245699
+ index += 3;
245700
+ state = "text-block";
245701
+ continue;
245702
+ }
245703
+ if (current === '"') {
245704
+ result += " ";
245705
+ index += 1;
245706
+ state = "string";
245707
+ continue;
245708
+ }
245709
+ if (current === "'") {
245710
+ result += " ";
245711
+ index += 1;
245712
+ state = "char";
245713
+ continue;
245714
+ }
245715
+ result += current;
245716
+ index += 1;
245717
+ continue;
245718
+ }
245719
+ if (state === "line-comment") {
245720
+ result += current === "\n" || current === "\r" ? current : " ";
245721
+ index += 1;
245722
+ if (current === "\n") {
245723
+ state = "code";
245724
+ }
245725
+ continue;
245726
+ }
245727
+ if (state === "block-comment") {
245728
+ if (current === "*" && next === "/") {
245729
+ result += " ";
245730
+ index += 2;
245731
+ state = "code";
245732
+ continue;
245733
+ }
245734
+ result += current === "\n" || current === "\r" ? current : " ";
245735
+ index += 1;
245736
+ continue;
245737
+ }
245738
+ if (state === "text-block") {
245739
+ if (nextTwo === '"""') {
245740
+ result += " ";
245741
+ index += 3;
245742
+ state = "code";
245743
+ continue;
245744
+ }
245745
+ result += current === "\n" || current === "\r" ? current : " ";
245746
+ index += 1;
245747
+ continue;
245748
+ }
245749
+ if (state === "string") {
245750
+ if (current === "\\") {
245751
+ result += " ";
245752
+ index += next ? 2 : 1;
245753
+ if (next) {
245754
+ result += " ";
245755
+ }
245756
+ continue;
245757
+ }
245758
+ result += current === "\n" || current === "\r" ? current : " ";
245759
+ index += 1;
245760
+ if (current === '"') {
245761
+ state = "code";
245762
+ }
245763
+ continue;
245764
+ }
245765
+ if (current === "\\") {
245766
+ result += " ";
245767
+ index += next ? 2 : 1;
245768
+ if (next) {
245769
+ result += " ";
245770
+ }
245771
+ continue;
245772
+ }
245773
+ result += current === "\n" || current === "\r" ? current : " ";
245774
+ index += 1;
245775
+ if (current === "'") {
245776
+ state = "code";
245777
+ }
245778
+ }
245779
+ return result;
245780
+ }
245781
+ function readMavenProductionSourceFiles(workspaceRoot, componentPath) {
245782
+ const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
245783
+ const mainRoots = [
245784
+ path64.join(absoluteRoot, "src", "main", "java"),
245785
+ path64.join(absoluteRoot, "src", "main", "kotlin"),
245786
+ path64.join(absoluteRoot, "src", "main", "scala")
245787
+ ];
245788
+ const files = [];
245789
+ for (const sourceRoot of mainRoots) {
245790
+ if (!pathExists19(sourceRoot)) {
245791
+ continue;
245792
+ }
245793
+ const entries = fs58.readdirSync(sourceRoot, { recursive: true, withFileTypes: true });
245794
+ for (const entry of entries) {
245795
+ if (!entry.isFile() || !/\.(?:java|kt|scala)$/iu.test(entry.name)) {
245796
+ continue;
245797
+ }
245798
+ const contents = readTextFileSafe(path64.join(entry.parentPath, entry.name));
245799
+ if (contents) {
245800
+ files.push({ fileName: entry.name, contents });
245801
+ }
245802
+ }
245803
+ }
245804
+ return files;
245805
+ }
245806
+ function findMatchingBrace6(value, openBraceIndex) {
245807
+ let depth = 0;
245808
+ for (let index = openBraceIndex; index < value.length; index += 1) {
245809
+ const current = value[index];
245810
+ if (current === "{") {
245811
+ depth += 1;
245812
+ } else if (current === "}") {
245813
+ depth -= 1;
245814
+ if (depth === 0) {
245815
+ return index;
245816
+ }
245817
+ }
245818
+ }
245819
+ return -1;
245820
+ }
245821
+ function getDeclaredPackageName(value) {
245822
+ return value.match(/\bpackage\s+([a-zA-Z_$][\w$]*(?:\.[a-zA-Z_$][\w$]*)*)\s*;/u)?.[1];
245823
+ }
245824
+ function classNameMatchesConfiguredMainClass(className, packageName, configuredMainClass) {
245825
+ const normalized = configuredMainClass.trim();
245826
+ if (normalized.length === 0) {
245827
+ return false;
245828
+ }
245829
+ return normalized === className || (packageName ? normalized === `${packageName}.${className}` : false);
245830
+ }
245831
+ function normalizeAnnotationName(value) {
245832
+ return value.slice(value.lastIndexOf(".") + 1);
245833
+ }
245834
+ function hasAnnotation(annotations, annotationNames) {
245835
+ return annotations.some((annotation) => annotationNames.has(normalizeAnnotationName(annotation)));
245836
+ }
245837
+ function extractAnnotations(annotationBlock) {
245838
+ return [...annotationBlock.matchAll(/@\s*([A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*)/gu)].map((match) => match[1]).filter((annotation) => Boolean(annotation));
245839
+ }
245840
+ function extractConcreteClassDeclarations(contents) {
245841
+ const sanitized = stripJavaLikeCommentsAndStrings(contents);
245842
+ const packageName = getDeclaredPackageName(sanitized);
245843
+ 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;
245844
+ const declarations = [];
245845
+ for (const match of sanitized.matchAll(classPattern)) {
245846
+ const annotationBlock = match[1] ?? "";
245847
+ const className = match[2] ?? "";
245848
+ const openBraceIndex = (match.index ?? 0) + match[0].length - 1;
245849
+ const closeBraceIndex = findMatchingBrace6(sanitized, openBraceIndex);
245850
+ if (closeBraceIndex < 0) {
245851
+ continue;
245852
+ }
245853
+ declarations.push({
245854
+ className,
245855
+ ...packageName ? { packageName } : {},
245856
+ annotations: extractAnnotations(annotationBlock),
245857
+ body: sanitized.slice(openBraceIndex + 1, closeBraceIndex)
245858
+ });
245859
+ }
245860
+ return declarations;
245861
+ }
245862
+ function extractApplicationAnnotationNames(sourceFiles) {
245863
+ const applicationAnnotations = /* @__PURE__ */ new Set(["SpringBootApplication"]);
245864
+ let changed = true;
245865
+ while (changed) {
245866
+ changed = false;
245867
+ for (const sourceFile of sourceFiles) {
245868
+ const sanitized = stripJavaLikeCommentsAndStrings(sourceFile.contents);
245869
+ const annotationPattern = /((?:@\s*[\w.]+(?:\s*\([^)]*\))?\s*)*)public\s+@interface\s+([A-Za-z_$][\w$]*)\b/gu;
245870
+ for (const match of sanitized.matchAll(annotationPattern)) {
245871
+ const annotations = extractAnnotations(match[1] ?? "");
245872
+ const annotationName = match[2];
245873
+ if (annotationName && !applicationAnnotations.has(annotationName) && hasAnnotation(annotations, applicationAnnotations)) {
245874
+ applicationAnnotations.add(annotationName);
245875
+ changed = true;
245876
+ }
245877
+ }
245878
+ }
245879
+ }
245880
+ return applicationAnnotations;
245881
+ }
245882
+ function hasSpringApplicationRunForClass(body, className) {
245883
+ return new RegExp(`\\bSpringApplication\\.run\\s*\\(\\s*${className}\\.class\\b`, "u").test(body);
245884
+ }
245885
+ function hasIndirectSpringApplicationRunForClass(body, className) {
245886
+ const helperCalls = [...body.matchAll(/\b([A-Za-z_$][\w$]*)\s*\(\s*([A-Za-z_$][\w$]*)\.class\s*,/gu)].filter((match) => match[2] === className).map((match) => match[1]).filter((methodName) => Boolean(methodName));
245887
+ return helperCalls.some(
245888
+ (methodName) => new RegExp(`\\b${methodName}\\s*\\([^)]*\\)\\s*\\{[\\s\\S]*?\\bSpringApplication\\.run\\s*\\(`, "u").test(body)
245889
+ );
245890
+ }
245891
+ function hasConcreteSpringBootApplicationBootstrap(sourceFiles) {
245892
+ const applicationAnnotations = extractApplicationAnnotationNames(sourceFiles);
245893
+ const declarations = sourceFiles.flatMap((sourceFile) => extractConcreteClassDeclarations(sourceFile.contents));
245894
+ const applicationClassNames = new Set(
245895
+ declarations.filter((declaration) => hasAnnotation(declaration.annotations, applicationAnnotations)).map((declaration) => declaration.className)
245896
+ );
245897
+ if (applicationClassNames.size === 0) {
245898
+ return false;
245899
+ }
245900
+ const hasLauncherForApplicationClass = (declaration) => javaMainMethodPattern.test(declaration.body) && [...applicationClassNames].some(
245901
+ (applicationClassName) => hasSpringApplicationRunForClass(declaration.body, applicationClassName) || applicationClassName === declaration.className && hasIndirectSpringApplicationRunForClass(declaration.body, applicationClassName)
245902
+ );
245903
+ if (declarations.some(hasLauncherForApplicationClass)) {
245904
+ return true;
245905
+ }
245906
+ for (const sourceFile of sourceFiles) {
245907
+ for (const declaration of extractConcreteClassDeclarations(sourceFile.contents)) {
245908
+ if (!hasAnnotation(declaration.annotations, applicationAnnotations)) {
245909
+ continue;
245910
+ }
245911
+ if (javaMainMethodPattern.test(declaration.body) && (hasSpringApplicationRunForClass(declaration.body, declaration.className) || hasIndirectSpringApplicationRunForClass(declaration.body, declaration.className))) {
245912
+ return true;
245913
+ }
245914
+ }
245915
+ }
245916
+ return false;
245917
+ }
245918
+ function hasConfiguredMainClassEntrypoint(contents, configuredMainClass) {
245919
+ for (const declaration of extractConcreteClassDeclarations(contents)) {
245920
+ if (!classNameMatchesConfiguredMainClass(declaration.className, declaration.packageName, configuredMainClass)) {
245921
+ continue;
245922
+ }
245923
+ if (javaMainMethodPattern.test(declaration.body)) {
245924
+ return true;
245925
+ }
245926
+ }
245927
+ return false;
245928
+ }
245929
+ function hasMavenMainEntrypoint(workspaceRoot, componentPath) {
245930
+ return hasConcreteSpringBootApplicationBootstrap(readMavenProductionSourceFiles(workspaceRoot, componentPath));
245931
+ }
245932
+ function hasMavenConfiguredMainClassEntrypoint(workspaceRoot, componentPath, configuredMainClass) {
245933
+ if (!configuredMainClass) {
245934
+ return false;
245935
+ }
245936
+ return readMavenProductionSourceFiles(workspaceRoot, componentPath).some((sourceFile) => hasConfiguredMainClassEntrypoint(sourceFile.contents, configuredMainClass));
245937
+ }
245938
+ function hasMavenAutoConfigurationMetadata(workspaceRoot, componentPath) {
245939
+ const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
245940
+ return [
245941
+ path64.join(absoluteRoot, "src", "main", "resources", "META-INF", "spring.factories"),
245942
+ path64.join(absoluteRoot, "src", "main", "resources", "META-INF", "spring", "org.springframework.boot.autoconfigure.AutoConfiguration.imports")
245943
+ ].some(pathExists19);
245944
+ }
245945
+ function hasMavenMainJvmSource(workspaceRoot, componentPath) {
245946
+ const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
245947
+ return [
245948
+ path64.join(absoluteRoot, "src", "main", "java"),
245949
+ path64.join(absoluteRoot, "src", "main", "kotlin"),
245950
+ path64.join(absoluteRoot, "src", "main", "scala")
245951
+ ].some((root) => hasFileUnderRoot(root, /\.(?:java|kt|scala)$/iu));
245952
+ }
245953
+ function hasRuntimeSourceFiles(workspaceRoot, componentPath) {
245954
+ if (isUnderJvmResourceRoot4(componentPath)) {
245955
+ return false;
245956
+ }
245957
+ const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
245958
+ const sourceRoots = [
245959
+ path64.join(absoluteRoot, "src", "main", "java"),
245960
+ path64.join(absoluteRoot, "src"),
245961
+ path64.join(absoluteRoot, "app"),
245962
+ path64.join(absoluteRoot, "server")
245963
+ ];
245964
+ for (const sourceRoot of sourceRoots) {
245965
+ if (!pathExists19(sourceRoot)) {
245966
+ continue;
245967
+ }
245968
+ const entries = fs58.readdirSync(sourceRoot, { recursive: true, withFileTypes: true });
245969
+ if (entries.some((entry) => entry.isFile() && /\.(?:ts|tsx|js|jsx|java|cs|py|php|go)$/iu.test(entry.name))) {
245970
+ return true;
245971
+ }
245972
+ }
245973
+ return false;
245974
+ }
245975
+ function resolveKind(workspaceRoot, candidate, localProjectKinds) {
245333
245976
  const lowerPath = candidate.path.toLowerCase();
245977
+ const packageJson = readPackageJson(workspaceRoot, candidate.path);
245978
+ const maven = readMavenMetadata(workspaceRoot, candidate.path);
245979
+ const hasRunnableFrontendEvidence = hasRunnableFrontendComponentEvidence(workspaceRoot, candidate.path);
245980
+ const hasPublishSurface = hasPackagePublishSurface(packageJson);
245981
+ const hasMavenRunnableEvidence = Boolean(
245982
+ maven && (hasMavenMainEntrypoint(workspaceRoot, candidate.path) || hasMavenConfiguredMainClassEntrypoint(workspaceRoot, candidate.path, maven.configuredMainClass) || maven.hasSpringBootPlugin && maven.hasSpringBootRepackageGoal && hasMavenMainEntrypoint(workspaceRoot, candidate.path) || maven.packaging === "war" && hasMavenMainEntrypoint(workspaceRoot, candidate.path))
245983
+ );
245984
+ const hasMavenLibraryEvidence = Boolean(
245985
+ maven && !hasMavenRunnableEvidence && (maven.packaging === "jar" || maven.packaging === "maven-plugin" || maven.packaging === "pom") && (hasMavenMainJvmSource(workspaceRoot, candidate.path) || maven.hasMainResources || maven.hasDependencyManagement || maven.hasSpringBootAutoconfigureDependency || maven.hasSpringBootAutoconfigureProcessor || hasMavenAutoConfigurationMetadata(workspaceRoot, candidate.path) || maven.hasDocumentationTooling || maven.hasTestJava || maven.hasTestResources)
245986
+ );
245334
245987
  if (lowerPath.endsWith("/db") || lowerPath.endsWith("/database") || lowerPath.endsWith("/data")) {
245335
245988
  return "data";
245336
245989
  }
245990
+ if (hasMavenLibraryEvidence) {
245991
+ return "library";
245992
+ }
245993
+ if (maven && !hasMavenRunnableEvidence && localProjectKinds.primaryKind === "backend") {
245994
+ return "library";
245995
+ }
245337
245996
  const classification = candidate.architectureRoot?.classification;
245338
245997
  if (classification === "frontend_app") {
245339
- return "frontend";
245998
+ return hasPublishSurface && !hasRunnableFrontendEvidence ? "library" : "frontend";
245340
245999
  }
245341
246000
  if (classification === "backend_app") {
245342
246001
  return "backend";
245343
246002
  }
246003
+ if (hasRunnableFrontendEvidence && localProjectKinds.primaryKind !== "backend" && localProjectKinds.primaryKind !== "service" && localProjectKinds.primaryKind !== "cli") {
246004
+ return "frontend";
246005
+ }
245344
246006
  if (classification === "shared_package") {
245345
246007
  return "library";
245346
246008
  }
246009
+ if (hasPublishSurface && !hasRunnableFrontendEvidence) {
246010
+ return "library";
246011
+ }
245347
246012
  if (localProjectKinds.primaryKind === "service") {
245348
246013
  return "worker";
245349
246014
  }
@@ -245412,15 +246077,21 @@ function classifyGovernanceRole(input2) {
245412
246077
  const scriptText = scripts.join(" ").toLowerCase();
245413
246078
  const dependencyText = [...dependencies, ...devDependencies].join(" ").toLowerCase();
245414
246079
  const hasStrongSupportPath = hasAnyToken(pathText, [
245415
- /(^|\/)(testing|test-plugins|fixtures?|examples?|benchmarks?|smoke)(\/|$)/u,
246080
+ /(^|\/)(testing|test-plugins|cypress-tests|fixtures?|examples?|benchmarks?|smoke)(\/|$)/u,
245416
246081
  /(^|\/)(dev-server|scaffold|scaffolding|generators?|devkit|tooling|tools)(\/|$)/u
245417
246082
  ]);
245418
- const hasPublishSurface = hasObject(packageJson?.exports) || typeof packageJson?.main === "string" || typeof packageJson?.module === "string" || typeof packageJson?.types === "string" || hasObject(packageJson?.publishConfig) || Array.isArray(packageJson?.files);
246083
+ const isPlainResourcesSurface = isUnderJvmResourceRoot4(pathText) && !hasRuntimeSourceFiles(input2.workspaceRoot, input2.candidate.path) && !packageJson && !maven;
246084
+ const hasPublishSurface = hasPackagePublishSurface(packageJson);
245419
246085
  const isPrivate = packageJson?.private === true;
245420
246086
  const hasBin = hasObject(packageJson?.bin) || typeof packageJson?.bin === "string";
245421
246087
  const mavenMetadataText = `${maven?.artifactId ?? ""} ${maven?.name ?? ""}`.toLowerCase();
245422
246088
  const hasMavenMainSource = Boolean(maven?.hasMainJava || maven?.hasMainResources);
245423
246089
  const hasMavenTestSource = Boolean(maven?.hasTestJava || maven?.hasTestResources);
246090
+ const hasMavenMainEntrypointEvidence = Boolean(maven && hasMavenMainEntrypoint(input2.workspaceRoot, input2.candidate.path));
246091
+ const hasMavenMainJvmSourceEvidence = Boolean(maven && hasMavenMainJvmSource(input2.workspaceRoot, input2.candidate.path));
246092
+ const hasMavenAutoConfigurationEvidence = Boolean(maven && (hasMavenAutoConfigurationMetadata(input2.workspaceRoot, input2.candidate.path) || maven.hasSpringBootAutoconfigureDependency || maven.hasSpringBootAutoconfigureProcessor));
246093
+ const hasMavenExecutableConfiguration = Boolean(maven && (hasMavenConfiguredMainClassEntrypoint(input2.workspaceRoot, input2.candidate.path, maven.configuredMainClass) || maven.hasSpringBootPlugin && maven.hasSpringBootRepackageGoal && hasMavenMainEntrypointEvidence || maven.packaging === "war" && hasMavenMainEntrypointEvidence));
246094
+ const hasMavenRunnableApplicationEvidence = Boolean(hasMavenMainEntrypointEvidence || hasMavenExecutableConfiguration);
245424
246095
  const isMavenPomOnly = Boolean(maven?.packaging === "pom" && !hasMavenMainSource && !hasMavenTestSource);
245425
246096
  const hasMavenTestContext = hasAnyToken(pathText, [
245426
246097
  /(^|\/)(test-framework|testsuite|integration-tests?|test-apps)(\/|$)/u
@@ -245459,17 +246130,19 @@ function classifyGovernanceRole(input2) {
245459
246130
  if (maven?.hasPom) {
245460
246131
  addEvidence6(evidence, `Maven packaging ${maven.packaging ?? "jar"}`);
245461
246132
  }
245462
- if (maven && (maven.packaging === "jar" || maven.packaging === "war") && hasMavenMainSource) {
246133
+ if (maven && (maven.packaging === "jar" || maven.packaging === "war") && hasMavenRunnableApplicationEvidence) {
245463
246134
  runtimeScore += 3;
245464
- addEvidence6(evidence, "Maven runtime source layout");
246135
+ addEvidence6(evidence, "Maven executable application evidence");
245465
246136
  }
245466
- if (maven?.packaging === "war" && hasMavenMainSource) {
246137
+ if (maven?.packaging === "war" && hasMavenMainJvmSourceEvidence) {
245467
246138
  runtimeScore += 1;
245468
246139
  addEvidence6(evidence, "Maven deployable WAR artifact");
245469
246140
  }
245470
- if (maven && hasMavenMainSource && !hasMavenTestContext && !hasMavenBomEvidence && maven.packaging !== "maven-plugin") {
245471
- runtimeScore += 1;
245472
- addEvidence6(evidence, "Maven main source/resource surface");
246141
+ if (maven && hasMavenMainSource && !hasMavenRunnableApplicationEvidence && !hasMavenTestContext && !hasMavenBomEvidence && maven.packaging !== "maven-plugin") {
246142
+ addEvidence6(evidence, "Maven library main source/resource surface");
246143
+ }
246144
+ if (hasMavenAutoConfigurationEvidence && !hasMavenRunnableApplicationEvidence) {
246145
+ addEvidence6(evidence, "Maven Spring Boot auto-configuration/starter library evidence");
245473
246146
  }
245474
246147
  if (hasAnyToken(descriptiveManifestText, [/\b(e2e|end-to-end|testing|test helper|test utilities|fixtures?)\b/u])) {
245475
246148
  supportScore += 3;
@@ -245484,7 +246157,7 @@ function classifyGovernanceRole(input2) {
245484
246157
  addEvidence6(evidence, "Package metadata describes development/tooling usage");
245485
246158
  }
245486
246159
  if (hasAnyToken(pathText, [
245487
- /(^|\/)(test|tests|testing|__tests__|fixtures?|examples?|benchmarks?|smoke)(\/|$)/u,
246160
+ /(^|\/)(test|tests|testing|__tests__|cypress|cypress-tests|fixtures?|examples?|benchmarks?|smoke)(\/|$)/u,
245488
246161
  /(^|\/)(dev-server|test-plugins|scaffold|scaffolding|generators?|devkit|tooling|tools)(\/|$)/u
245489
246162
  ])) {
245490
246163
  supportScore += 1;
@@ -245510,6 +246183,10 @@ function classifyGovernanceRole(input2) {
245510
246183
  supportScore += 5;
245511
246184
  addEvidence6(evidence, "Maven plugin/build-tooling module");
245512
246185
  }
246186
+ if (maven?.hasDocumentationTooling && !hasMavenMainJvmSourceEvidence) {
246187
+ supportScore += 4;
246188
+ addEvidence6(evidence, "Maven documentation tooling without JVM runtime source");
246189
+ }
245513
246190
  if (hasMavenBomEvidence) {
245514
246191
  supportScore += 5;
245515
246192
  addEvidence6(evidence, "Maven BOM/dependency-management module without runtime source");
@@ -245534,6 +246211,17 @@ function classifyGovernanceRole(input2) {
245534
246211
  supportScore += 1;
245535
246212
  addEvidence6(evidence, "Maven POM-only aggregator/packaging module");
245536
246213
  }
246214
+ if (isPlainResourcesSurface) {
246215
+ supportScore += 4;
246216
+ addEvidence6(evidence, "Resources-only surface without runtime source or manifest evidence");
246217
+ }
246218
+ if (isPlainResourcesSurface && input2.kind !== "infrastructure" && input2.stack !== "terraform" && input2.stack !== "ansible") {
246219
+ return {
246220
+ governanceRole: "support",
246221
+ governanceEvidence: uniqueSorted4(evidence),
246222
+ selectedByDefault: false
246223
+ };
246224
+ }
245537
246225
  if (hasMavenDistributionPackagingEvidence && hasAnyToken(mavenMetadataText, [/\b(docs?|documentation|metadata tests?|licenses?|maven plugins?|builds?)\b/u])) {
245538
246226
  supportScore += 3;
245539
246227
  addEvidence6(evidence, "Maven documentation/build/distribution packaging evidence without runtime source");
@@ -245547,9 +246235,9 @@ function classifyGovernanceRole(input2) {
245547
246235
  }
245548
246236
  if (maven && (isMavenPomOnly || hasMavenDistributionPackagingEvidence) && supportScore >= 1) {
245549
246237
  return {
245550
- governanceRole: "ambiguous",
246238
+ governanceRole: "support",
245551
246239
  governanceEvidence: uniqueSorted4(evidence),
245552
- selectedByDefault: true
246240
+ selectedByDefault: false
245553
246241
  };
245554
246242
  }
245555
246243
  if (runtimeScore >= 2) {
@@ -245590,8 +246278,10 @@ function maybeAddAttributedApiAndDb(component, workspaceRoot, componentPath, arc
245590
246278
  }
245591
246279
  function detectComponents(input2) {
245592
246280
  const ignoreMatcher = input2.ignoreMatcher ?? loadArchpilotIgnoreMatcher(input2.workspaceRoot);
245593
- const manifestBackedRoots = new Set(input2.topology.detectedRoots ?? []);
245594
- const rootCandidates = buildRootCandidates(input2).filter((candidate) => !ignoreMatcher.isIgnored(candidate.path)).filter((candidate) => !isIgnoredComponentCandidatePath(candidate.path)).filter((candidate) => {
246281
+ const manifestBackedRoots = new Set(
246282
+ (input2.topology.detectedRoots ?? []).filter((root) => !isUnderJvmResourceRoot4(root))
246283
+ );
246284
+ const rootCandidates = buildRootCandidates(input2).filter((candidate) => !ignoreMatcher.isIgnored(candidate.path)).filter((candidate) => !isIgnoredComponentCandidatePath(candidate.path)).filter((candidate) => !(isUnderJvmResourceRoot4(candidate.path) && !hasRuntimeSourceFiles(input2.workspaceRoot, candidate.path))).filter((candidate) => {
245595
246285
  if (input2.topology.topology !== "monorepo" || manifestBackedRoots.size === 0) {
245596
246286
  return true;
245597
246287
  }
@@ -245614,7 +246304,7 @@ function detectComponents(input2) {
245614
246304
  }
245615
246305
  const localProjectKinds = input2.runContext?.detectProjectKinds(absoluteRoot) ?? detectProjectKinds(absoluteRoot);
245616
246306
  const stackDetection = input2.runContext?.detectStacks(absoluteRoot) ?? detectStacks(absoluteRoot);
245617
- const kind = resolveKind(candidate, localProjectKinds);
246307
+ const kind = resolveKind(input2.workspaceRoot, candidate, localProjectKinds);
245618
246308
  const stack = resolveStack(kind, stackDetection);
245619
246309
  const evidence = [...candidate.evidence];
245620
246310
  if (candidate.architectureRoot?.classification && candidate.architectureRoot.classification !== "unknown") {
@@ -245851,6 +246541,10 @@ function getSelectedCandidate(detection) {
245851
246541
  function getBackendComponents(detection) {
245852
246542
  return (detection.detectedComponents ?? []).filter((component) => component.kind === "backend" || component.kind === "worker");
245853
246543
  }
246544
+ function getDefaultGovernedBackendComponents(detection) {
246545
+ const components = detection.detectedComponents ?? [];
246546
+ return components.filter((component) => component.kind === "backend" || component.kind === "worker").filter((component) => isDefaultGovernedComponent(component, components));
246547
+ }
245854
246548
  function getFrontendComponents(detection) {
245855
246549
  return (detection.detectedComponents ?? []).filter((component) => component.kind === "frontend");
245856
246550
  }
@@ -245885,7 +246579,7 @@ function isCliSupportCandidate(component, allComponents) {
245885
246579
  }
245886
246580
  function hasIndependentRuntimeEvidence(component) {
245887
246581
  const text = componentEvidenceText(component);
245888
- return component.governanceRole === "runtime" && (/Maven runtime source layout/iu.test(text) || /Maven main source\/resource surface/iu.test(text) || /Published package surface signal/iu.test(text) && !/Path contains support\/tooling role tokens/iu.test(text));
246582
+ return component.governanceRole === "runtime" && (/Maven executable application evidence/iu.test(text) || /Maven deployable WAR artifact/iu.test(text) || /Published package surface signal/iu.test(text) && !/Path contains support\/tooling role tokens/iu.test(text));
245889
246583
  }
245890
246584
  function hasSupportRoleEvidence(component) {
245891
246585
  const text = componentEvidenceText(component);
@@ -245990,7 +246684,8 @@ function resolveProposalComponents(detection) {
245990
246684
  return components.length > 0 ? components : void 0;
245991
246685
  }
245992
246686
  function resolveResourceOwnerComponent(detection) {
245993
- return getBackendComponents(detection).find((component) => component.kind === "backend") ?? getBackendComponents(detection)[0];
246687
+ const backendComponents = getDefaultGovernedBackendComponents(detection);
246688
+ return backendComponents.find((component) => component.kind === "backend") ?? backendComponents[0];
245994
246689
  }
245995
246690
  function resourceIdFor(ownerId, suffix) {
245996
246691
  if (suffix === "api" && /(^|-)api$/u.test(ownerId)) {
@@ -246025,7 +246720,7 @@ function resolveProposalResources(input2) {
246025
246720
  usedIds.add(resource.id);
246026
246721
  resources.push(resource);
246027
246722
  };
246028
- for (const component of getBackendComponents(input2.detection)) {
246723
+ for (const component of getDefaultGovernedBackendComponents(input2.detection)) {
246029
246724
  if (component.apiStyle && component.apiStyle !== "unknown" && component.apiStyle !== "none") {
246030
246725
  addResource({
246031
246726
  id: resourceIdFor(component.id, "api"),