@archpilotlabs/archpilot 0.2.3 → 0.2.4
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.
- package/CHANGELOG.md +538 -0
- package/README.md +1 -0
- package/dist/archpilot-cli.js +335 -55
- package/package.json +3 -2
package/dist/archpilot-cli.js
CHANGED
|
@@ -13660,11 +13660,11 @@ ${lanes.join("\n")}
|
|
|
13660
13660
|
return toComponents;
|
|
13661
13661
|
}
|
|
13662
13662
|
const components = toComponents.slice(start);
|
|
13663
|
-
const
|
|
13663
|
+
const relative18 = [];
|
|
13664
13664
|
for (; start < fromComponents.length; start++) {
|
|
13665
|
-
|
|
13665
|
+
relative18.push("..");
|
|
13666
13666
|
}
|
|
13667
|
-
return ["", ...
|
|
13667
|
+
return ["", ...relative18, ...components];
|
|
13668
13668
|
}
|
|
13669
13669
|
function getRelativePathFromDirectory(fromDirectory, to, getCanonicalFileNameOrIgnoreCase) {
|
|
13670
13670
|
Debug.assert(getRootLength(fromDirectory) > 0 === getRootLength(to) > 0, "Paths must either both be absolute or both be relative");
|
|
@@ -52233,11 +52233,11 @@ ${lanes.join("\n")}
|
|
|
52233
52233
|
if (i < rootLength) {
|
|
52234
52234
|
return void 0;
|
|
52235
52235
|
}
|
|
52236
|
-
const
|
|
52237
|
-
if (
|
|
52236
|
+
const sep2 = directory.lastIndexOf(directorySeparator, i - 1);
|
|
52237
|
+
if (sep2 === -1) {
|
|
52238
52238
|
return void 0;
|
|
52239
52239
|
}
|
|
52240
|
-
return directory.substr(0, Math.max(
|
|
52240
|
+
return directory.substr(0, Math.max(sep2, rootLength));
|
|
52241
52241
|
}
|
|
52242
52242
|
}
|
|
52243
52243
|
}
|
|
@@ -58143,9 +58143,9 @@ ${lanes.join("\n")}
|
|
|
58143
58143
|
if (!startsWithDirectory(target, realPathDirectory, getCanonicalFileName)) {
|
|
58144
58144
|
return;
|
|
58145
58145
|
}
|
|
58146
|
-
const
|
|
58146
|
+
const relative18 = getRelativePathFromDirectory(realPathDirectory, target, getCanonicalFileName);
|
|
58147
58147
|
for (const symlinkDirectory of symlinkDirectories) {
|
|
58148
|
-
const option = resolvePath(symlinkDirectory,
|
|
58148
|
+
const option = resolvePath(symlinkDirectory, relative18);
|
|
58149
58149
|
const result2 = cb(option, target === referenceRedirect);
|
|
58150
58150
|
shouldFilterIgnoredPaths = true;
|
|
58151
58151
|
if (result2) return result2;
|
|
@@ -127982,7 +127982,7 @@ ${lanes.join("\n")}
|
|
|
127982
127982
|
}
|
|
127983
127983
|
}
|
|
127984
127984
|
function createImportCallExpressionAMD(arg, containsLexicalThis) {
|
|
127985
|
-
const
|
|
127985
|
+
const resolve10 = factory2.createUniqueName("resolve");
|
|
127986
127986
|
const reject = factory2.createUniqueName("reject");
|
|
127987
127987
|
const parameters = [
|
|
127988
127988
|
factory2.createParameterDeclaration(
|
|
@@ -127991,7 +127991,7 @@ ${lanes.join("\n")}
|
|
|
127991
127991
|
/*dotDotDotToken*/
|
|
127992
127992
|
void 0,
|
|
127993
127993
|
/*name*/
|
|
127994
|
-
|
|
127994
|
+
resolve10
|
|
127995
127995
|
),
|
|
127996
127996
|
factory2.createParameterDeclaration(
|
|
127997
127997
|
/*modifiers*/
|
|
@@ -128008,7 +128008,7 @@ ${lanes.join("\n")}
|
|
|
128008
128008
|
factory2.createIdentifier("require"),
|
|
128009
128009
|
/*typeArguments*/
|
|
128010
128010
|
void 0,
|
|
128011
|
-
[factory2.createArrayLiteralExpression([arg || factory2.createOmittedExpression()]),
|
|
128011
|
+
[factory2.createArrayLiteralExpression([arg || factory2.createOmittedExpression()]), resolve10, reject]
|
|
128012
128012
|
)
|
|
128013
128013
|
)
|
|
128014
128014
|
]);
|
|
@@ -214726,8 +214726,8 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
|
|
|
214726
214726
|
installPackage(options) {
|
|
214727
214727
|
this.packageInstallId++;
|
|
214728
214728
|
const request3 = { kind: "installPackage", ...options, id: this.packageInstallId };
|
|
214729
|
-
const promise = new Promise((
|
|
214730
|
-
(this.packageInstalledPromise ?? (this.packageInstalledPromise = /* @__PURE__ */ new Map())).set(this.packageInstallId, { resolve:
|
|
214729
|
+
const promise = new Promise((resolve10, reject) => {
|
|
214730
|
+
(this.packageInstalledPromise ?? (this.packageInstalledPromise = /* @__PURE__ */ new Map())).set(this.packageInstallId, { resolve: resolve10, reject });
|
|
214731
214731
|
});
|
|
214732
214732
|
this.installer.send(request3);
|
|
214733
214733
|
return promise;
|
|
@@ -215444,6 +215444,8 @@ function classifyValidationSourceScope(relativePath) {
|
|
|
215444
215444
|
const isFixture = hasPathSegment(normalized, /^(?:fixtures?|__fixtures__)$/u);
|
|
215445
215445
|
const isTestPlugin = hasPathSegment(normalized, /^(?:test-plugins?|testing-plugins?)$/u);
|
|
215446
215446
|
const isExamplePlugin = hasPathSegment(normalized, /^example-plugins?$/u) || hasTopLevelPathSegment(normalized, /^examples?$/u);
|
|
215447
|
+
const isMavenIntegrationTestModule = hasTopLevelPathSegment(normalized, /^[a-z0-9_.-]+-integration-tests?$/u) || hasTopLevelPathSegment(normalized, /^[a-z0-9_.-]+-it$/u);
|
|
215448
|
+
const isMavenExampleModule = hasTopLevelPathSegment(normalized, /^[a-z0-9_.-]+-examples?$/u);
|
|
215447
215449
|
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
215450
|
const isMigration = hasPathSegment(normalized, /^(?:migrations?|schema-migrations?|data-migrations|migration-utils?)$/u);
|
|
215449
215451
|
const isCliTooling = hasPathSegment(normalized, /^(?:cli|bin|scripts?|tools?|scaffold|scaffolding|generators?)$/u) || /(?:^|[./_-])(?:cli|script|tool|generator|scaffold)(?:[./_-]|$)/u.test(fileName);
|
|
@@ -215454,11 +215456,11 @@ function classifyValidationSourceScope(relativePath) {
|
|
|
215454
215456
|
category = "generated";
|
|
215455
215457
|
} else if (isE2e) {
|
|
215456
215458
|
category = "e2e";
|
|
215457
|
-
} else if (isTestFile || hasPathSegment(normalized, /^(?:test|tests|__tests__|spec|specs|__mocks__|cypress|cypress-tests)$/u)) {
|
|
215459
|
+
} else if (isTestFile || isMavenIntegrationTestModule || hasPathSegment(normalized, /^(?:test|tests|__tests__|spec|specs|__mocks__|cypress|cypress-tests)$/u)) {
|
|
215458
215460
|
category = "test";
|
|
215459
215461
|
} else if (isTestPlugin) {
|
|
215460
215462
|
category = "test-plugin";
|
|
215461
|
-
} else if (isExamplePlugin) {
|
|
215463
|
+
} else if (isExamplePlugin || isMavenExampleModule) {
|
|
215462
215464
|
category = "example-plugin";
|
|
215463
215465
|
} else if (isFixture) {
|
|
215464
215466
|
category = "fixture";
|
|
@@ -215970,6 +215972,41 @@ async function buildExplicitStandaloneModulePathMap(workspaceRoot, architectureC
|
|
|
215970
215972
|
function isTestSourcePath(relativePath) {
|
|
215971
215973
|
return classifyValidationSourceScope(relativePath).isTestLike;
|
|
215972
215974
|
}
|
|
215975
|
+
function hasStandardTestSourceRoot(relativePath) {
|
|
215976
|
+
const normalized = normalizePath4(relativePath);
|
|
215977
|
+
return /(?:^|\/)src\/(?:test|it|integration-test|integration-tests)\//u.test(normalized) || /(?:^|\/)(?:test|tests|__tests__|spec|specs|e2e|cypress)\//u.test(normalized) || /\.(?:spec|test|e2e-spec|integration-test)\.(?:ts|tsx|js|jsx|mjs|cjs|java|cs|py|php|go)$/u.test(
|
|
215978
|
+
normalized.split("/").at(-1) ?? normalized
|
|
215979
|
+
);
|
|
215980
|
+
}
|
|
215981
|
+
function shouldSkipDependencySource(relativePath, moduleRoot, workspaceRoot, includeTestFiles, includeConfiguredNonProductionModuleSources) {
|
|
215982
|
+
if (includeTestFiles) {
|
|
215983
|
+
return false;
|
|
215984
|
+
}
|
|
215985
|
+
const moduleRootRelativePath = normalizePath4(path7.relative(workspaceRoot, moduleRoot));
|
|
215986
|
+
const moduleRootScope = classifyValidationSourceScope(moduleRootRelativePath);
|
|
215987
|
+
if (hasStandardTestSourceRoot(relativePath)) {
|
|
215988
|
+
return !includeConfiguredNonProductionModuleSources || moduleRootScope.isProduction || moduleRootScope.isTestLike;
|
|
215989
|
+
}
|
|
215990
|
+
if (!isTestSourcePath(relativePath)) {
|
|
215991
|
+
return false;
|
|
215992
|
+
}
|
|
215993
|
+
return !includeConfiguredNonProductionModuleSources || !moduleRootScope.isTestLike;
|
|
215994
|
+
}
|
|
215995
|
+
function filterImportsForBoundaryChecks(imports, moduleRoots, workspaceRoot) {
|
|
215996
|
+
return imports.filter((dependencyImport) => {
|
|
215997
|
+
const moduleRoot = moduleRoots.get(dependencyImport.sourceModule);
|
|
215998
|
+
if (!moduleRoot) {
|
|
215999
|
+
return true;
|
|
216000
|
+
}
|
|
216001
|
+
return !shouldSkipDependencySource(
|
|
216002
|
+
dependencyImport.sourceFileRelativePath,
|
|
216003
|
+
moduleRoot,
|
|
216004
|
+
workspaceRoot,
|
|
216005
|
+
false,
|
|
216006
|
+
false
|
|
216007
|
+
);
|
|
216008
|
+
});
|
|
216009
|
+
}
|
|
215973
216010
|
async function collectSourceFiles(directoryPath, adapter, scanRootPath = directoryPath, excludedDirectoryRoots = []) {
|
|
215974
216011
|
const entries = await import_node_fs6.promises.readdir(directoryPath, { withFileTypes: true });
|
|
215975
216012
|
entries.sort((left, right) => left.name.localeCompare(right.name));
|
|
@@ -216197,7 +216234,7 @@ function extractJavaPackageName(sourceText) {
|
|
|
216197
216234
|
const match = /^\s*package\s+([a-zA-Z_][\w.]*)\s*;/mu.exec(sourceText);
|
|
216198
216235
|
return match?.[1];
|
|
216199
216236
|
}
|
|
216200
|
-
async function buildJavaImportIndex(workspaceRoot, moduleRoots, adapter) {
|
|
216237
|
+
async function buildJavaImportIndex(workspaceRoot, moduleRoots, adapter, options) {
|
|
216201
216238
|
const classes = /* @__PURE__ */ new Map();
|
|
216202
216239
|
const packageCandidates = /* @__PURE__ */ new Map();
|
|
216203
216240
|
for (const [moduleId, moduleRoot] of [...moduleRoots.entries()].sort(
|
|
@@ -216207,7 +216244,13 @@ async function buildJavaImportIndex(workspaceRoot, moduleRoots, adapter) {
|
|
|
216207
216244
|
const sourceFiles = await collectSourceFiles(moduleRoot, adapter, moduleRoot, childModuleRoots);
|
|
216208
216245
|
for (const sourceFilePath of sourceFiles) {
|
|
216209
216246
|
const relativePath = normalizePath4(path7.relative(workspaceRoot, sourceFilePath));
|
|
216210
|
-
if (
|
|
216247
|
+
if (shouldSkipDependencySource(
|
|
216248
|
+
relativePath,
|
|
216249
|
+
moduleRoot,
|
|
216250
|
+
workspaceRoot,
|
|
216251
|
+
false,
|
|
216252
|
+
options?.includeConfiguredNonProductionModuleSources === true
|
|
216253
|
+
)) {
|
|
216211
216254
|
continue;
|
|
216212
216255
|
}
|
|
216213
216256
|
const sourceText = await readTextFileIfExists2(sourceFilePath);
|
|
@@ -216850,10 +216893,13 @@ async function resolveCrossModuleImport(workspaceRoot, modulesRootRelativePath,
|
|
|
216850
216893
|
async function collectCrossModuleImports(workspaceRoot, modulesRootRelativePath, moduleRoots, explicitStandaloneModuleByPath, workspacePackageAliases, adapter, options) {
|
|
216851
216894
|
const imports = [];
|
|
216852
216895
|
const includeTestFiles = options?.includeTestFiles === true;
|
|
216896
|
+
const includeConfiguredNonProductionModuleSources = options?.includeConfiguredNonProductionModuleSources === true;
|
|
216853
216897
|
if (!supportsDependencyImportParsing(adapter)) {
|
|
216854
216898
|
return imports;
|
|
216855
216899
|
}
|
|
216856
|
-
const javaImportIndex = usesJavaImportParser(adapter) ? await buildJavaImportIndex(workspaceRoot, moduleRoots, adapter
|
|
216900
|
+
const javaImportIndex = usesJavaImportParser(adapter) ? await buildJavaImportIndex(workspaceRoot, moduleRoots, adapter, {
|
|
216901
|
+
includeConfiguredNonProductionModuleSources
|
|
216902
|
+
}) : void 0;
|
|
216857
216903
|
for (const [moduleName, moduleRoot] of [...moduleRoots.entries()].sort(
|
|
216858
216904
|
([left], [right]) => left.localeCompare(right)
|
|
216859
216905
|
)) {
|
|
@@ -216868,7 +216914,13 @@ async function collectCrossModuleImports(workspaceRoot, modulesRootRelativePath,
|
|
|
216868
216914
|
const sourceFileRelativePath = normalizePath4(
|
|
216869
216915
|
path7.relative(workspaceRoot, sourceFilePath)
|
|
216870
216916
|
);
|
|
216871
|
-
if (
|
|
216917
|
+
if (shouldSkipDependencySource(
|
|
216918
|
+
sourceFileRelativePath,
|
|
216919
|
+
moduleRoot,
|
|
216920
|
+
workspaceRoot,
|
|
216921
|
+
includeTestFiles,
|
|
216922
|
+
includeConfiguredNonProductionModuleSources
|
|
216923
|
+
)) {
|
|
216872
216924
|
continue;
|
|
216873
216925
|
}
|
|
216874
216926
|
const sourceText = await readTextFileIfExists2(sourceFilePath);
|
|
@@ -217418,7 +217470,10 @@ async function buildDependencyGraphSummary(workspaceRoot, architectureContract,
|
|
|
217418
217470
|
explicitStandaloneModuleByPath,
|
|
217419
217471
|
workspacePackageAliases,
|
|
217420
217472
|
adapter,
|
|
217421
|
-
{
|
|
217473
|
+
{
|
|
217474
|
+
includeConfiguredNonProductionModuleSources: true,
|
|
217475
|
+
resolutionContext
|
|
217476
|
+
}
|
|
217422
217477
|
);
|
|
217423
217478
|
options?.onCollectedImports?.(imports);
|
|
217424
217479
|
options?.onResolutionStats?.(resolutionContext.getStats());
|
|
@@ -217522,10 +217577,11 @@ async function validateDependencyContractBoundaries(workspaceRoot, architectureC
|
|
|
217522
217577
|
workspacePackageAliases,
|
|
217523
217578
|
adapter
|
|
217524
217579
|
);
|
|
217580
|
+
const boundaryImports = filterImportsForBoundaryChecks(imports, moduleRoots, workspaceRoot);
|
|
217525
217581
|
const dependencyContextResolver = createArchitectureDependencyContextResolver(
|
|
217526
217582
|
architectureContract
|
|
217527
217583
|
);
|
|
217528
|
-
const peerImports = filterPeerModuleImports(
|
|
217584
|
+
const peerImports = filterPeerModuleImports(boundaryImports);
|
|
217529
217585
|
const moduleScopedPeerImports = peerImports.filter(
|
|
217530
217586
|
(dependencyImport) => isModuleScopedDependencyImport(
|
|
217531
217587
|
architectureContract,
|
|
@@ -217836,7 +217892,8 @@ async function validateDependencyContractBoundaries(workspaceRoot, architectureC
|
|
|
217836
217892
|
workspaceRoot,
|
|
217837
217893
|
canonicalModuleRoots
|
|
217838
217894
|
),
|
|
217839
|
-
adapter
|
|
217895
|
+
adapter,
|
|
217896
|
+
{ includeConfiguredNonProductionModuleSources: true }
|
|
217840
217897
|
);
|
|
217841
217898
|
const canonicalPeerImports = filterPeerModuleImports(canonicalImports).filter(
|
|
217842
217899
|
(dependencyImport) => isModuleScopedDependencyImport(architectureContract, dependencyImport)
|
|
@@ -217934,8 +217991,9 @@ async function validateDependencyBoundaries(workspaceRoot, options) {
|
|
|
217934
217991
|
workspacePackageAliases,
|
|
217935
217992
|
adapter
|
|
217936
217993
|
);
|
|
217994
|
+
const boundaryImports = filterImportsForBoundaryChecks(imports, moduleRoots, workspaceRoot);
|
|
217937
217995
|
const dependencyContextResolver = parsedArchitectureContract ? createArchitectureDependencyContextResolver(parsedArchitectureContract) : void 0;
|
|
217938
|
-
const peerImports = filterPeerModuleImports(
|
|
217996
|
+
const peerImports = filterPeerModuleImports(boundaryImports);
|
|
217939
217997
|
const moduleScopedPeerImports = peerImports.filter(
|
|
217940
217998
|
(dependencyImport) => isModuleScopedDependencyImport(
|
|
217941
217999
|
parsedArchitectureContract,
|
|
@@ -218191,7 +218249,8 @@ async function buildModuleDependencyGraphSnapshot(workspaceRoot, options) {
|
|
|
218191
218249
|
moduleRoots,
|
|
218192
218250
|
explicitStandaloneModuleByPath,
|
|
218193
218251
|
workspacePackageAliases,
|
|
218194
|
-
adapter
|
|
218252
|
+
adapter,
|
|
218253
|
+
{ includeConfiguredNonProductionModuleSources: true }
|
|
218195
218254
|
);
|
|
218196
218255
|
const imports = filterPeerModuleImports(allImports).filter(
|
|
218197
218256
|
(dependencyImport) => moduleSet.has(dependencyImport.sourceModule) && moduleSet.has(dependencyImport.targetModule)
|
|
@@ -222217,7 +222276,7 @@ async function validateModuleContractIntegrity(workspaceRoot, contract, options)
|
|
|
222217
222276
|
"AP-ARCH-005",
|
|
222218
222277
|
"error",
|
|
222219
222278
|
true,
|
|
222220
|
-
"No modules are registered in architecture.json.
|
|
222279
|
+
"No explicit root modules are registered in architecture.json. Root module registry path checks are not applicable; component-backed contracts are validated by dependency checks."
|
|
222221
222280
|
)
|
|
222222
222281
|
});
|
|
222223
222282
|
}
|
|
@@ -222227,7 +222286,7 @@ async function validateModuleContractIntegrity(workspaceRoot, contract, options)
|
|
|
222227
222286
|
"AP-ARCH-006",
|
|
222228
222287
|
"error",
|
|
222229
222288
|
true,
|
|
222230
|
-
"No modules are registered in architecture.json.
|
|
222289
|
+
"No explicit root modules are registered in architecture.json. Root module contract file checks are not applicable; component-backed contracts are validated by dependency checks."
|
|
222231
222290
|
)
|
|
222232
222291
|
});
|
|
222233
222292
|
}
|
|
@@ -222237,7 +222296,7 @@ async function validateModuleContractIntegrity(workspaceRoot, contract, options)
|
|
|
222237
222296
|
"AP-ARCH-007",
|
|
222238
222297
|
"error",
|
|
222239
222298
|
true,
|
|
222240
|
-
"No modules are registered in architecture.json.
|
|
222299
|
+
"No explicit root modules are registered in architecture.json. Root module contract identity checks are not applicable; component-backed contracts are validated by dependency checks."
|
|
222241
222300
|
)
|
|
222242
222301
|
});
|
|
222243
222302
|
}
|
|
@@ -222247,7 +222306,7 @@ async function validateModuleContractIntegrity(workspaceRoot, contract, options)
|
|
|
222247
222306
|
"AP-ARCH-008",
|
|
222248
222307
|
"error",
|
|
222249
222308
|
true,
|
|
222250
|
-
"No modules are registered in architecture.json.
|
|
222309
|
+
"No explicit root modules are registered in architecture.json. Root module public entrypoint alignment checks are not applicable; component-backed contracts are validated by dependency checks."
|
|
222251
222310
|
)
|
|
222252
222311
|
});
|
|
222253
222312
|
}
|
|
@@ -223196,7 +223255,7 @@ async function loadRemotePolicyWithStatus(policySourceUrl, options) {
|
|
|
223196
223255
|
"info",
|
|
223197
223256
|
`Remote policy configured. Loading policy from ${policySourceUrl}.`
|
|
223198
223257
|
);
|
|
223199
|
-
return new Promise((
|
|
223258
|
+
return new Promise((resolve10) => {
|
|
223200
223259
|
const request3 = https.request(
|
|
223201
223260
|
{
|
|
223202
223261
|
protocol: validated.url.protocol,
|
|
@@ -223223,7 +223282,7 @@ async function loadRemotePolicyWithStatus(policySourceUrl, options) {
|
|
|
223223
223282
|
"warn",
|
|
223224
223283
|
`Remote policy request failed with HTTP ${statusCode}. Using local policy only.`
|
|
223225
223284
|
);
|
|
223226
|
-
|
|
223285
|
+
resolve10({
|
|
223227
223286
|
message: `Remote policy request failed with HTTP ${statusCode}. Using local policy only.`
|
|
223228
223287
|
});
|
|
223229
223288
|
return;
|
|
@@ -223237,7 +223296,7 @@ async function loadRemotePolicyWithStatus(policySourceUrl, options) {
|
|
|
223237
223296
|
"warn",
|
|
223238
223297
|
"Remote policy payload is invalid JSON. Using local policy only."
|
|
223239
223298
|
);
|
|
223240
|
-
|
|
223299
|
+
resolve10({
|
|
223241
223300
|
message: "Remote policy payload is invalid JSON. Using local policy only."
|
|
223242
223301
|
});
|
|
223243
223302
|
return;
|
|
@@ -223249,7 +223308,7 @@ async function loadRemotePolicyWithStatus(policySourceUrl, options) {
|
|
|
223249
223308
|
"warn",
|
|
223250
223309
|
"Remote policy payload has an invalid structure. Using local policy only."
|
|
223251
223310
|
);
|
|
223252
|
-
|
|
223311
|
+
resolve10({
|
|
223253
223312
|
message: "Remote policy payload has an invalid structure. Using local policy only."
|
|
223254
223313
|
});
|
|
223255
223314
|
return;
|
|
@@ -223259,7 +223318,7 @@ async function loadRemotePolicyWithStatus(policySourceUrl, options) {
|
|
|
223259
223318
|
"info",
|
|
223260
223319
|
"Remote policy loaded successfully."
|
|
223261
223320
|
);
|
|
223262
|
-
|
|
223321
|
+
resolve10({
|
|
223263
223322
|
policy: normalized,
|
|
223264
223323
|
message: "Remote policy loaded successfully."
|
|
223265
223324
|
});
|
|
@@ -223275,7 +223334,7 @@ async function loadRemotePolicyWithStatus(policySourceUrl, options) {
|
|
|
223275
223334
|
"warn",
|
|
223276
223335
|
"Remote policy unavailable. Using local policy only."
|
|
223277
223336
|
);
|
|
223278
|
-
|
|
223337
|
+
resolve10({
|
|
223279
223338
|
message: "Remote policy unavailable. Using local policy only."
|
|
223280
223339
|
});
|
|
223281
223340
|
});
|
|
@@ -225601,6 +225660,15 @@ function hasPaginationEvidence(statement) {
|
|
|
225601
225660
|
statement
|
|
225602
225661
|
);
|
|
225603
225662
|
}
|
|
225663
|
+
function hasEqualityPredicate(statement, columnPattern) {
|
|
225664
|
+
return new RegExp(
|
|
225665
|
+
`\\bwhere\\b[\\s\\S]*\\b(?:${columnPattern})\\b\\s*=\\s*(?:[\\w$:@?]+|'[^']+'|"[^"]+"|\\d+)`,
|
|
225666
|
+
"iu"
|
|
225667
|
+
).test(statement);
|
|
225668
|
+
}
|
|
225669
|
+
function isCatalogIdentifierPointLookup(statement) {
|
|
225670
|
+
return /\bfrom\s+information_schema\.schemata\b/iu.test(statement) && hasEqualityPredicate(statement, "schema_name");
|
|
225671
|
+
}
|
|
225604
225672
|
function isObviousPointLookup(statement) {
|
|
225605
225673
|
const normalized = statement.toLowerCase();
|
|
225606
225674
|
if (!normalized.includes("where")) {
|
|
@@ -225609,7 +225677,7 @@ function isObviousPointLookup(statement) {
|
|
|
225609
225677
|
if (normalized.includes(" or ")) {
|
|
225610
225678
|
return false;
|
|
225611
225679
|
}
|
|
225612
|
-
return
|
|
225680
|
+
return hasEqualityPredicate(normalized, "id|uuid|slug|email|identifier") || isCatalogIdentifierPointLookup(normalized);
|
|
225613
225681
|
}
|
|
225614
225682
|
function listModulePathEntries(contract) {
|
|
225615
225683
|
return Object.entries(contract.modules ?? {}).map(([moduleName, reference]) => {
|
|
@@ -226190,13 +226258,14 @@ function detectRepeatedQueryPattern(method) {
|
|
|
226190
226258
|
}
|
|
226191
226259
|
function extractSqlQueryLiterals(content) {
|
|
226192
226260
|
const queries = [];
|
|
226261
|
+
const searchableContent = maskSourceComments(content);
|
|
226193
226262
|
const patterns = [
|
|
226194
226263
|
/(?:\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,
|
|
226195
226264
|
/\b(?:DB::select|DB::statement|DB::raw|DB::table)\s*\([^'"`)]{0,180}?(['"`])([\s\S]{0,900}?)\1/gu,
|
|
226196
226265
|
/@Query\s*\(\s*(['"`])([\s\S]{0,900}?)\1/gu
|
|
226197
226266
|
];
|
|
226198
226267
|
for (const pattern of patterns) {
|
|
226199
|
-
for (const match of
|
|
226268
|
+
for (const match of searchableContent.matchAll(pattern)) {
|
|
226200
226269
|
const sql = match[2];
|
|
226201
226270
|
if (!sql || !/\b(?:select|update|delete|insert)\b/iu.test(sql)) {
|
|
226202
226271
|
continue;
|
|
@@ -226209,6 +226278,71 @@ function extractSqlQueryLiterals(content) {
|
|
|
226209
226278
|
}
|
|
226210
226279
|
return queries;
|
|
226211
226280
|
}
|
|
226281
|
+
function maskSourceComments(content) {
|
|
226282
|
+
let masked = "";
|
|
226283
|
+
let index = 0;
|
|
226284
|
+
let state = "code";
|
|
226285
|
+
let escaped = false;
|
|
226286
|
+
while (index < content.length) {
|
|
226287
|
+
const current = content[index] ?? "";
|
|
226288
|
+
const next = content[index + 1] ?? "";
|
|
226289
|
+
if (state === "line-comment") {
|
|
226290
|
+
if (current === "\r" || current === "\n") {
|
|
226291
|
+
masked += current;
|
|
226292
|
+
state = "code";
|
|
226293
|
+
} else {
|
|
226294
|
+
masked += " ";
|
|
226295
|
+
}
|
|
226296
|
+
index += 1;
|
|
226297
|
+
continue;
|
|
226298
|
+
}
|
|
226299
|
+
if (state === "block-comment") {
|
|
226300
|
+
if (current === "*" && next === "/") {
|
|
226301
|
+
masked += " ";
|
|
226302
|
+
index += 2;
|
|
226303
|
+
state = "code";
|
|
226304
|
+
continue;
|
|
226305
|
+
}
|
|
226306
|
+
masked += current === "\r" || current === "\n" ? current : " ";
|
|
226307
|
+
index += 1;
|
|
226308
|
+
continue;
|
|
226309
|
+
}
|
|
226310
|
+
if (state === "single" || state === "double" || state === "template") {
|
|
226311
|
+
masked += current;
|
|
226312
|
+
if (escaped) {
|
|
226313
|
+
escaped = false;
|
|
226314
|
+
} else if (current === "\\") {
|
|
226315
|
+
escaped = true;
|
|
226316
|
+
} else if (state === "single" && current === "'" || state === "double" && current === '"' || state === "template" && current === "`") {
|
|
226317
|
+
state = "code";
|
|
226318
|
+
}
|
|
226319
|
+
index += 1;
|
|
226320
|
+
continue;
|
|
226321
|
+
}
|
|
226322
|
+
if (current === "/" && next === "/") {
|
|
226323
|
+
masked += " ";
|
|
226324
|
+
index += 2;
|
|
226325
|
+
state = "line-comment";
|
|
226326
|
+
continue;
|
|
226327
|
+
}
|
|
226328
|
+
if (current === "/" && next === "*") {
|
|
226329
|
+
masked += " ";
|
|
226330
|
+
index += 2;
|
|
226331
|
+
state = "block-comment";
|
|
226332
|
+
continue;
|
|
226333
|
+
}
|
|
226334
|
+
if (current === "'") {
|
|
226335
|
+
state = "single";
|
|
226336
|
+
} else if (current === '"') {
|
|
226337
|
+
state = "double";
|
|
226338
|
+
} else if (current === "`") {
|
|
226339
|
+
state = "template";
|
|
226340
|
+
}
|
|
226341
|
+
masked += current;
|
|
226342
|
+
index += 1;
|
|
226343
|
+
}
|
|
226344
|
+
return masked;
|
|
226345
|
+
}
|
|
226212
226346
|
function detectCodeSqlQueryShapeFindings(file, config) {
|
|
226213
226347
|
const findings = [];
|
|
226214
226348
|
for (const query of extractSqlQueryLiterals(file.content)) {
|
|
@@ -226298,12 +226432,18 @@ function hasAssignedBuilderBoundedTerminal(methodBody, snippet) {
|
|
|
226298
226432
|
}
|
|
226299
226433
|
return new RegExp(`\\b${variableName}\\s*\\.\\s*(?:getOne|getRawOne|loadOne|getCount|getExists)\\s*\\(`, "iu").test(methodBody);
|
|
226300
226434
|
}
|
|
226435
|
+
function hasIdentifierPredicateEvidence(snippet) {
|
|
226436
|
+
return /\.(?:where|andWhere|orWhere)\s*\(\s*['"`][^'"`]{0,240}\b(?:\w*id|uuid|slug|email|identifier)\b[^'"`]{0,120}(?:=| in\b|IN\b)/iu.test(snippet) || /\bwhere\s*:\s*\{[\s\S]{0,420}\b(?:id|uuid|slug|email|identifier|channelId|orderId|customerId|userId|productId|variantId)\b\s*[:=]/iu.test(snippet);
|
|
226437
|
+
}
|
|
226438
|
+
function hasQueryBuilderTerminalEvidence(snippet, methodBody) {
|
|
226439
|
+
return /\.(?:getMany|getRawMany|loadMany|getOne|getRawOne|loadOne|getCount|getExists|execute)\s*\(/iu.test(snippet) || hasAssignedBuilderBoundedTerminal(methodBody, snippet);
|
|
226440
|
+
}
|
|
226301
226441
|
function isNonCollectionOrmRead(label, snippet, methodBody = snippet) {
|
|
226302
226442
|
const terminal = getOrmTerminalOperation(snippet);
|
|
226303
226443
|
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);
|
|
226304
226444
|
}
|
|
226305
226445
|
function hasOrmBoundEvidence(snippet) {
|
|
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);
|
|
226446
|
+
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) || hasIdentifierPredicateEvidence(snippet);
|
|
226307
226447
|
}
|
|
226308
226448
|
function getOrmQueryTarget(method, label, snippet) {
|
|
226309
226449
|
const terminal = getOrmTerminalOperation(snippet);
|
|
@@ -226326,6 +226466,9 @@ function getOrmQueryLabel(method, label, snippet) {
|
|
|
226326
226466
|
function detectOrmQueryShapeFindings(method, config) {
|
|
226327
226467
|
const findings = [];
|
|
226328
226468
|
for (const evidence of collectOrmReadEvidence(method)) {
|
|
226469
|
+
if (evidence.label === "node.query" && !hasQueryBuilderTerminalEvidence(evidence.snippet, method.body)) {
|
|
226470
|
+
continue;
|
|
226471
|
+
}
|
|
226329
226472
|
if (config.tenantModel === "same_db_same_schema" && !tenantPredicatePattern.test(evidence.snippet)) {
|
|
226330
226473
|
findings.push(createCodeFinding({
|
|
226331
226474
|
id: "AP-DQR-001",
|
|
@@ -227034,7 +227177,7 @@ function detectControllerBusinessLogic(entry, classification, moduleName, contex
|
|
|
227034
227177
|
});
|
|
227035
227178
|
}
|
|
227036
227179
|
function detectRepositoryBusinessLogic(entry, classification, moduleName) {
|
|
227037
|
-
if (!classification.isRepository) {
|
|
227180
|
+
if (!classification.isRepository || !isProductionBackendGovernanceScope(classification.scope)) {
|
|
227038
227181
|
return void 0;
|
|
227039
227182
|
}
|
|
227040
227183
|
if (entry.extension === ".java" && isPureSpringDataRepositoryInterface(entry.content)) {
|
|
@@ -227362,7 +227505,7 @@ var publicEvidencePattern = /@Public\b|@PermitAll\b|\[AllowAnonymous\b[^\]]*\]|p
|
|
|
227362
227505
|
var roleEvidencePattern = /@(?:Roles|Permissions|RequirePermission|PreAuthorize|Secured|RolesAllowed)\s*(?:\(|\b)([^)\n]*)|\[Authorize\s*\([^)\]]*(?:Roles|Policy)\s*=|(?:requireRole\w*|RequireRole\w*|require_role|RoleChecker|adminMiddleware|can:|permission:|scopes?\s*=|Security\s*\([^)]*scopes)\b/u;
|
|
227363
227506
|
var tenantSignalPattern = /\b(?:tenantId|tenant_id|organizationId|organization_id|orgId|org_id|workspaceId|workspace_id|accountId|account_id|companyId|company_id|customerId|customer_id|TenantContext|CurrentTenant|TenantResolver|TenantProvider|request\.tenant|req\.tenant|user\.tenantId|user\.tenant_id|user\.organizationId|user\.organization_id|user\.orgId|user\.accountId|user\.workspaceId|user\.companyId|user\.customerId|HibernateFilter|CurrentTenant)\b/u;
|
|
227364
227507
|
var tenantPredicateEvidencePattern = /\b(?:tenantId|tenant_id|organizationId|organization_id|orgId|org_id|workspaceId|workspace_id|accountId|account_id|companyId|company_id|customerId|customer_id|TenantContext|CurrentTenant|TenantResolver|TenantProvider|request\.tenant|req\.tenant|user\.tenantId|user\.tenant_id|user\.organizationId|user\.organization_id|user\.orgId|user\.accountId|user\.workspaceId|user\.companyId|user\.customerId|HibernateFilter|CurrentTenant)\b/u;
|
|
227365
|
-
var
|
|
227508
|
+
var executableAuthorizationDecisionPattern = /@(?:PreAuthorize|PostAuthorize|Secured|RolesAllowed)\b|\[(?:Authorize)\b[^\]]*(?:Roles|Policy)\s*=|\b(?:hasRole|hasAuthority|hasPermission|isUserInRole|checkPermission|requireRole\w*|RequireRole\w*|require_role|canActivate|authorize|assertAuthorized|PermissionChecker|AccessDecisionManager|SecurityContextHolder\.getContext\(\)\.getAuthentication)\s*\(|\b(?:user|principal|currentUser|account)\.(?:role|roles|permission|permissions|isAdmin)\b\s*(?:[=!]==?|\.includes\s*\(|\.contains\s*\()/u;
|
|
227366
227509
|
function normalizePath12(value) {
|
|
227367
227510
|
return value.replace(/\\/g, "/");
|
|
227368
227511
|
}
|
|
@@ -227790,7 +227933,7 @@ function detectAuthorizationFindings(files, contract, astCache) {
|
|
|
227790
227933
|
}
|
|
227791
227934
|
}
|
|
227792
227935
|
for (const file of files.filter((candidate) => isRepositoryFile(candidate, astCache))) {
|
|
227793
|
-
const roleMatch =
|
|
227936
|
+
const roleMatch = executableAuthorizationDecisionPattern.exec(file.content);
|
|
227794
227937
|
if (!roleMatch) {
|
|
227795
227938
|
continue;
|
|
227796
227939
|
}
|
|
@@ -230589,8 +230732,9 @@ function extractJavaSignals(file) {
|
|
|
230589
230732
|
publishes: []
|
|
230590
230733
|
});
|
|
230591
230734
|
}
|
|
230592
|
-
for (const match of file.content.matchAll(/(?:await\s+)?(?:\w+\.)?(?:publishEvent|publish|emit)\s*\(\s*(?:new\s+)
|
|
230593
|
-
const
|
|
230735
|
+
for (const match of file.content.matchAll(/(?:await\s+)?(?:\w+\.)?(?:publishEvent|publish|emit)\s*\(\s*(?:(new)\s+([A-Za-z_]\w*(?:\.[A-Za-z_]\w*)*)\s*\(|(["'])([A-Za-z][\w.]*Event?|[a-z][\w.]+)\3|([A-Z][A-Za-z0-9_]*Event)\b)/gu)) {
|
|
230736
|
+
const constructedType = match[2]?.split(".").at(-1);
|
|
230737
|
+
const eventName = constructedType ?? match[4] ?? match[5];
|
|
230594
230738
|
if (!eventName) {
|
|
230595
230739
|
continue;
|
|
230596
230740
|
}
|
|
@@ -234446,7 +234590,7 @@ ${infoLines.join("\n")}
|
|
|
234446
234590
|
## Passed Checks
|
|
234447
234591
|
${passedLines.join("\n")}
|
|
234448
234592
|
|
|
234449
|
-
## Module Dependency Summary
|
|
234593
|
+
## Module / Component Contract Dependency Summary
|
|
234450
234594
|
${dependencyGraphLines.join("\n")}
|
|
234451
234595
|
|
|
234452
234596
|
## Disabled Rules
|
|
@@ -236682,7 +236826,7 @@ ${appliedFixesSection}
|
|
|
236682
236826
|
## Remaining Violations
|
|
236683
236827
|
${remainingViolationsLine}
|
|
236684
236828
|
|
|
236685
|
-
## Module Dependency Summary
|
|
236829
|
+
## Module / Component Contract Dependency Summary
|
|
236686
236830
|
${moduleCatalog.length === 0 ? "- Module details are not available in this run." : moduleCatalog.map(
|
|
236687
236831
|
(entry) => `- ${entry.moduleName} | Role: ${entry.role} | Path: ${entry.path ?? "(not configured)"} | Contract: ${entry.hasContract ? "yes" : "no"} | Declared deps: ${entry.declaredDependencyCount} | Actual deps: ${entry.actualDependencyCount} | Used by: ${entry.inboundDependencyCount}`
|
|
236688
236832
|
).join("\n")}
|
|
@@ -238934,11 +239078,11 @@ function normalizeAnnotationPath(workspaceRoot, sourceFile) {
|
|
|
238934
239078
|
if (!path43.isAbsolute(sourceFile)) {
|
|
238935
239079
|
return normalized;
|
|
238936
239080
|
}
|
|
238937
|
-
const
|
|
238938
|
-
if (
|
|
239081
|
+
const relative18 = path43.relative(workspaceRoot, sourceFile).replace(/\\/g, "/");
|
|
239082
|
+
if (relative18.startsWith("..") || path43.isAbsolute(relative18)) {
|
|
238939
239083
|
return void 0;
|
|
238940
239084
|
}
|
|
238941
|
-
return
|
|
239085
|
+
return relative18;
|
|
238942
239086
|
}
|
|
238943
239087
|
function toAnnotatableFinding(workspaceRoot, finding) {
|
|
238944
239088
|
if (typeof finding.id !== "string" || !finding.id.startsWith("AP-DEP-")) {
|
|
@@ -239122,7 +239266,7 @@ async function emitGithubInlineArchitectureAnnotations(workspaceRoot) {
|
|
|
239122
239266
|
var reviewCommentMarker = "<!-- archpilot-pr-review -->";
|
|
239123
239267
|
var legacyReviewCommentMarker = "<!-- ARCHPILOT_REVIEW_COMMENT -->";
|
|
239124
239268
|
function requestGithubApi(options) {
|
|
239125
|
-
return new Promise((
|
|
239269
|
+
return new Promise((resolve10, reject) => {
|
|
239126
239270
|
const payload = options.body !== void 0 ? JSON.stringify(options.body) : void 0;
|
|
239127
239271
|
const request3 = https2.request(
|
|
239128
239272
|
{
|
|
@@ -239143,7 +239287,7 @@ function requestGithubApi(options) {
|
|
|
239143
239287
|
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
239144
239288
|
});
|
|
239145
239289
|
response.on("end", () => {
|
|
239146
|
-
|
|
239290
|
+
resolve10({
|
|
239147
239291
|
statusCode: response.statusCode ?? 0,
|
|
239148
239292
|
body: Buffer.concat(chunks).toString("utf8")
|
|
239149
239293
|
});
|
|
@@ -245420,6 +245564,9 @@ function addEvidence6(evidence, value) {
|
|
|
245420
245564
|
evidence.push(value);
|
|
245421
245565
|
}
|
|
245422
245566
|
}
|
|
245567
|
+
function hasDeclaredMavenReactorEvidence(candidate) {
|
|
245568
|
+
return candidate.evidence.some((entry) => /Declared (?:by )?Maven|nested Maven reactor/iu.test(entry));
|
|
245569
|
+
}
|
|
245423
245570
|
function isIgnoredComponentCandidatePath(componentPath) {
|
|
245424
245571
|
const normalized = normalizePath25(componentPath).replace(/^\.\//u, "");
|
|
245425
245572
|
if (normalized === "." || normalized.length === 0) {
|
|
@@ -245459,7 +245606,9 @@ function isIgnoredComponentCandidatePath(componentPath) {
|
|
|
245459
245606
|
"build",
|
|
245460
245607
|
"coverage"
|
|
245461
245608
|
];
|
|
245462
|
-
|
|
245609
|
+
const isExampleContainer = firstSegment === "examples" || firstSegment === "example";
|
|
245610
|
+
const isIgnoredRootSegment = ignoredRootSegments.includes(firstSegment ?? "") && (!isExampleContainer || segments.length === 1);
|
|
245611
|
+
return isIgnoredRootSegment || segments.some((segment) => ignoredSupportingSegments.includes(segment.toLowerCase()));
|
|
245463
245612
|
}
|
|
245464
245613
|
function pathExists19(pathValue) {
|
|
245465
245614
|
try {
|
|
@@ -245523,6 +245672,9 @@ function readFirstXmlTag(value, tagName) {
|
|
|
245523
245672
|
const match = value.match(new RegExp(`<${tagName}(?:\\s[^>]*)?>([\\s\\S]*?)</${tagName}>`, "iu"));
|
|
245524
245673
|
return match?.[1]?.trim().replace(/\s+/gu, " ");
|
|
245525
245674
|
}
|
|
245675
|
+
function readXmlTagValues(value, tagName) {
|
|
245676
|
+
return [...value.matchAll(new RegExp(`<${tagName}(?:\\s[^>]*)?>([\\s\\S]*?)</${tagName}>`, "giu"))].map((match) => match[1]?.trim().replace(/\s+/gu, " ") ?? "").filter((entry) => entry.length > 0);
|
|
245677
|
+
}
|
|
245526
245678
|
function readMavenMetadata(workspaceRoot, componentPath) {
|
|
245527
245679
|
if (isUnderJvmResourceRoot4(componentPath)) {
|
|
245528
245680
|
return void 0;
|
|
@@ -245560,6 +245712,95 @@ function readMavenMetadata(workspaceRoot, componentPath) {
|
|
|
245560
245712
|
hasTestResources: pathExists19(path64.join(absoluteRoot, "src", "test", "resources"))
|
|
245561
245713
|
};
|
|
245562
245714
|
}
|
|
245715
|
+
function workspaceRelativePath(workspaceRoot, absolutePathValue) {
|
|
245716
|
+
const relative18 = path64.relative(workspaceRoot, absolutePathValue);
|
|
245717
|
+
if (relative18.length === 0) {
|
|
245718
|
+
return ".";
|
|
245719
|
+
}
|
|
245720
|
+
if (relative18.startsWith("..") || path64.isAbsolute(relative18)) {
|
|
245721
|
+
return void 0;
|
|
245722
|
+
}
|
|
245723
|
+
return normalizePath25(relative18);
|
|
245724
|
+
}
|
|
245725
|
+
function canonicalRealPath(filePath) {
|
|
245726
|
+
try {
|
|
245727
|
+
return fs58.realpathSync.native(filePath);
|
|
245728
|
+
} catch {
|
|
245729
|
+
return void 0;
|
|
245730
|
+
}
|
|
245731
|
+
}
|
|
245732
|
+
function readMavenDeclaredModules(pomPath) {
|
|
245733
|
+
const pomXml = readTextFileSafe(pomPath);
|
|
245734
|
+
if (!pomXml) {
|
|
245735
|
+
return [];
|
|
245736
|
+
}
|
|
245737
|
+
return uniqueSorted4(
|
|
245738
|
+
readXmlTagValues(stripXmlComments(pomXml), "module").filter((modulePath) => !/[${}]/u.test(modulePath))
|
|
245739
|
+
);
|
|
245740
|
+
}
|
|
245741
|
+
function collectMavenReactorCandidates(workspaceRoot, rootPaths) {
|
|
245742
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
245743
|
+
const visitedPomPaths = /* @__PURE__ */ new Set();
|
|
245744
|
+
const workspaceRealPath = canonicalRealPath(workspaceRoot) ?? path64.resolve(workspaceRoot);
|
|
245745
|
+
const workspaceRealPathForCompare = process.platform === "win32" ? workspaceRealPath.toLowerCase() : workspaceRealPath;
|
|
245746
|
+
const maxVisitedPoms = 500;
|
|
245747
|
+
const addCandidate = (candidatePath, evidence, parentPath) => {
|
|
245748
|
+
const normalized = normalizePath25(candidatePath);
|
|
245749
|
+
const existing = candidates.get(normalized) ?? { path: normalized, evidence: [] };
|
|
245750
|
+
addEvidence6(existing.evidence, evidence);
|
|
245751
|
+
if (parentPath && !existing.parentPath) {
|
|
245752
|
+
existing.parentPath = parentPath;
|
|
245753
|
+
}
|
|
245754
|
+
candidates.set(normalized, existing);
|
|
245755
|
+
};
|
|
245756
|
+
const visitPom = (pomPath, parentPath) => {
|
|
245757
|
+
if (visitedPomPaths.size >= maxVisitedPoms) {
|
|
245758
|
+
return;
|
|
245759
|
+
}
|
|
245760
|
+
const realPomPath = canonicalRealPath(pomPath);
|
|
245761
|
+
if (!realPomPath || visitedPomPaths.has(realPomPath)) {
|
|
245762
|
+
return;
|
|
245763
|
+
}
|
|
245764
|
+
const realPomPathForCompare = process.platform === "win32" ? realPomPath.toLowerCase() : realPomPath;
|
|
245765
|
+
if (realPomPathForCompare !== workspaceRealPathForCompare && !realPomPathForCompare.startsWith(`${workspaceRealPathForCompare}${path64.sep}`)) {
|
|
245766
|
+
return;
|
|
245767
|
+
}
|
|
245768
|
+
visitedPomPaths.add(realPomPath);
|
|
245769
|
+
const pomDirectory = path64.dirname(pomPath);
|
|
245770
|
+
const relativePomDirectory = workspaceRelativePath(workspaceRoot, pomDirectory);
|
|
245771
|
+
if (!relativePomDirectory) {
|
|
245772
|
+
return;
|
|
245773
|
+
}
|
|
245774
|
+
addCandidate(
|
|
245775
|
+
relativePomDirectory,
|
|
245776
|
+
parentPath ? `Declared by Maven reactor parent ${parentPath}` : "Detected Maven reactor root",
|
|
245777
|
+
parentPath
|
|
245778
|
+
);
|
|
245779
|
+
for (const declaredModule of readMavenDeclaredModules(pomPath)) {
|
|
245780
|
+
const childDirectory = path64.resolve(pomDirectory, declaredModule);
|
|
245781
|
+
const childRelativePath = workspaceRelativePath(workspaceRoot, childDirectory);
|
|
245782
|
+
if (!childRelativePath || isUnderJvmResourceRoot4(childRelativePath)) {
|
|
245783
|
+
continue;
|
|
245784
|
+
}
|
|
245785
|
+
const childPom = path64.join(childDirectory, "pom.xml");
|
|
245786
|
+
if (!pathExists19(childPom)) {
|
|
245787
|
+
addCandidate(childRelativePath, `Declared Maven module '${declaredModule}' is missing pom.xml`, relativePomDirectory);
|
|
245788
|
+
continue;
|
|
245789
|
+
}
|
|
245790
|
+
addCandidate(childRelativePath, `Declared Maven module '${declaredModule}' from ${relativePomDirectory}`, relativePomDirectory);
|
|
245791
|
+
visitPom(childPom, relativePomDirectory);
|
|
245792
|
+
}
|
|
245793
|
+
};
|
|
245794
|
+
for (const rootPath of uniqueSorted4(rootPaths)) {
|
|
245795
|
+
const normalizedRoot = normalizePath25(rootPath);
|
|
245796
|
+
const absoluteRoot = normalizedRoot === "." ? workspaceRoot : path64.join(workspaceRoot, ...normalizedRoot.split("/"));
|
|
245797
|
+
const pomPath = path64.join(absoluteRoot, "pom.xml");
|
|
245798
|
+
if (pathExists19(pomPath)) {
|
|
245799
|
+
visitPom(pomPath);
|
|
245800
|
+
}
|
|
245801
|
+
}
|
|
245802
|
+
return [...candidates.values()].sort((left, right) => left.path.localeCompare(right.path));
|
|
245803
|
+
}
|
|
245563
245804
|
function toComponentRoot(modulePath) {
|
|
245564
245805
|
const normalized = normalizePath25(modulePath);
|
|
245565
245806
|
const segments = normalized.split("/").filter((segment) => segment.length > 0);
|
|
@@ -245594,6 +245835,18 @@ function buildRootCandidates(input2) {
|
|
|
245594
245835
|
for (const root of input2.topology.detectedRoots ?? []) {
|
|
245595
245836
|
addCandidate(root, `Detected project root ${root}`);
|
|
245596
245837
|
}
|
|
245838
|
+
if (input2.workspaceRoot) {
|
|
245839
|
+
const mavenRoots = [".", ...input2.topology.detectedRoots ?? []];
|
|
245840
|
+
for (const candidate of collectMavenReactorCandidates(input2.workspaceRoot, mavenRoots)) {
|
|
245841
|
+
addCandidate(
|
|
245842
|
+
candidate.path,
|
|
245843
|
+
candidate.parentPath ? `Detected nested Maven reactor module under ${candidate.parentPath}` : "Detected Maven reactor module"
|
|
245844
|
+
);
|
|
245845
|
+
for (const evidence of candidate.evidence) {
|
|
245846
|
+
addCandidate(candidate.path, evidence);
|
|
245847
|
+
}
|
|
245848
|
+
}
|
|
245849
|
+
}
|
|
245597
245850
|
for (const moduleEntry of input2.modules?.modules ?? []) {
|
|
245598
245851
|
const componentRoot = toComponentRoot(moduleEntry.path);
|
|
245599
245852
|
if (componentRoot) {
|
|
@@ -246102,6 +246355,9 @@ function classifyGovernanceRole(input2) {
|
|
|
246102
246355
|
const hasMavenDistributionPackagingEvidence = Boolean(
|
|
246103
246356
|
maven?.packaging === "pom" && !hasMavenMainSource && hasAnyToken(pathText, [/(^|\/)(distribution|dist|downloads|assembl(y|ies)|feature-packs?)(\/|$)/u])
|
|
246104
246357
|
);
|
|
246358
|
+
const hasMavenStarterPackagingEvidence = Boolean(
|
|
246359
|
+
maven && !hasMavenMainJvmSourceEvidence && hasAnyToken(`${pathText} ${mavenMetadataText}`, [/\bstarters?\b|\bspring-boot-starter\b|\bstarter[-\s]/u])
|
|
246360
|
+
);
|
|
246105
246361
|
if (input2.candidate.architectureRoot?.classification === "backend_app" || input2.candidate.architectureRoot?.classification === "frontend_app") {
|
|
246106
246362
|
runtimeScore += 3;
|
|
246107
246363
|
addEvidence6(evidence, `Runtime architecture root signal: ${input2.candidate.architectureRoot.classification}`);
|
|
@@ -246211,6 +246467,10 @@ function classifyGovernanceRole(input2) {
|
|
|
246211
246467
|
supportScore += 1;
|
|
246212
246468
|
addEvidence6(evidence, "Maven POM-only aggregator/packaging module");
|
|
246213
246469
|
}
|
|
246470
|
+
if (hasMavenStarterPackagingEvidence) {
|
|
246471
|
+
supportScore += 4;
|
|
246472
|
+
addEvidence6(evidence, "Maven starter/resource artifact without JVM runtime source");
|
|
246473
|
+
}
|
|
246214
246474
|
if (isPlainResourcesSurface) {
|
|
246215
246475
|
supportScore += 4;
|
|
246216
246476
|
addEvidence6(evidence, "Resources-only surface without runtime source or manifest evidence");
|
|
@@ -246222,6 +246482,13 @@ function classifyGovernanceRole(input2) {
|
|
|
246222
246482
|
selectedByDefault: false
|
|
246223
246483
|
};
|
|
246224
246484
|
}
|
|
246485
|
+
if (hasMavenStarterPackagingEvidence && !hasMavenMainJvmSourceEvidence) {
|
|
246486
|
+
return {
|
|
246487
|
+
governanceRole: "support",
|
|
246488
|
+
governanceEvidence: uniqueSorted4(evidence),
|
|
246489
|
+
selectedByDefault: false
|
|
246490
|
+
};
|
|
246491
|
+
}
|
|
246225
246492
|
if (hasMavenDistributionPackagingEvidence && hasAnyToken(mavenMetadataText, [/\b(docs?|documentation|metadata tests?|licenses?|maven plugins?|builds?)\b/u])) {
|
|
246226
246493
|
supportScore += 3;
|
|
246227
246494
|
addEvidence6(evidence, "Maven documentation/build/distribution packaging evidence without runtime source");
|
|
@@ -246281,7 +246548,7 @@ function detectComponents(input2) {
|
|
|
246281
246548
|
const manifestBackedRoots = new Set(
|
|
246282
246549
|
(input2.topology.detectedRoots ?? []).filter((root) => !isUnderJvmResourceRoot4(root))
|
|
246283
246550
|
);
|
|
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) => {
|
|
246551
|
+
const rootCandidates = buildRootCandidates({ ...input2, workspaceRoot: input2.workspaceRoot }).filter((candidate) => !ignoreMatcher.isIgnored(candidate.path) || hasDeclaredMavenReactorEvidence(candidate)).filter((candidate) => !isIgnoredComponentCandidatePath(candidate.path)).filter((candidate) => !(isUnderJvmResourceRoot4(candidate.path) && !hasRuntimeSourceFiles(input2.workspaceRoot, candidate.path))).filter((candidate) => {
|
|
246285
246552
|
if (input2.topology.topology !== "monorepo" || manifestBackedRoots.size === 0) {
|
|
246286
246553
|
return true;
|
|
246287
246554
|
}
|
|
@@ -246579,7 +246846,7 @@ function isCliSupportCandidate(component, allComponents) {
|
|
|
246579
246846
|
}
|
|
246580
246847
|
function hasIndependentRuntimeEvidence(component) {
|
|
246581
246848
|
const text = componentEvidenceText(component);
|
|
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));
|
|
246849
|
+
return component.governanceRole === "runtime" && (/Maven executable application evidence/iu.test(text) || /Maven deployable WAR artifact/iu.test(text) || /Maven library main source\/resource surface/iu.test(text) || /Maven Spring Boot auto-configuration\/starter library evidence/iu.test(text) || /Published package surface signal/iu.test(text) && !/Path contains support\/tooling role tokens/iu.test(text));
|
|
246583
246850
|
}
|
|
246584
246851
|
function hasSupportRoleEvidence(component) {
|
|
246585
246852
|
const text = componentEvidenceText(component);
|
|
@@ -246789,7 +247056,20 @@ function hasAttributableBackendRoot(detection) {
|
|
|
246789
247056
|
return getBackendComponents(detection).length > 0;
|
|
246790
247057
|
}
|
|
246791
247058
|
function isGenericLibraryStack(stack) {
|
|
246792
|
-
return stack === "node_typescript" || stack === "node_javascript" || stack === "python" || stack === "go" || stack === "kotlin" || stack === "terraform" || stack === "ansible";
|
|
247059
|
+
return stack === "node_typescript" || stack === "node_javascript" || stack === "library_generic" || stack === "java" || stack === "spring" || stack === "python" || stack === "go" || stack === "kotlin" || stack === "kotlin_spring" || stack === "terraform" || stack === "ansible";
|
|
247060
|
+
}
|
|
247061
|
+
function preferredLibraryStack(stacks) {
|
|
247062
|
+
const uniqueStacks = uniqueInOrder2(stacks);
|
|
247063
|
+
if (uniqueStacks.length <= 1) {
|
|
247064
|
+
return isJvmLibraryStack(uniqueStacks[0]) ? "library_generic" : uniqueStacks[0];
|
|
247065
|
+
}
|
|
247066
|
+
if (uniqueStacks.some(isJvmLibraryStack) && uniqueStacks.every((candidate) => isJvmLibraryStack(candidate) || candidate === "node_typescript" || candidate === "node_javascript")) {
|
|
247067
|
+
return "library_generic";
|
|
247068
|
+
}
|
|
247069
|
+
return void 0;
|
|
247070
|
+
}
|
|
247071
|
+
function isJvmLibraryStack(stack) {
|
|
247072
|
+
return stack === "java" || stack === "spring";
|
|
246793
247073
|
}
|
|
246794
247074
|
function hasProjectKindEvidence(detection, patterns) {
|
|
246795
247075
|
const evidence = detection.projectKinds?.evidence ?? [];
|
|
@@ -247211,7 +247491,7 @@ function resolveStackSelections(detection, projectKinds) {
|
|
|
247211
247491
|
const libraryComponentStacks = uniqueInOrder2(
|
|
247212
247492
|
libraryComponents.map((component) => component.stack).filter((stack) => isGenericLibraryStack(stack))
|
|
247213
247493
|
);
|
|
247214
|
-
const selectedLibrary = detection.topology.topology === "monorepo" ? libraryComponentStacks
|
|
247494
|
+
const selectedLibrary = detection.topology.topology === "monorepo" ? preferredLibraryStack(libraryComponentStacks) : detection.stacks.selectedAdapterId;
|
|
247215
247495
|
if (isGenericLibraryStack(selectedLibrary)) {
|
|
247216
247496
|
selections.library = selectedLibrary;
|
|
247217
247497
|
}
|
|
@@ -247233,7 +247513,7 @@ function resolveProjectProfiles(detection, projectKinds, stackSelections, apiSty
|
|
|
247233
247513
|
selectedAdapterId: stackId,
|
|
247234
247514
|
selectedAdapterCategory: getStackAdapterById(stackId).category,
|
|
247235
247515
|
projectKinds: [kind],
|
|
247236
|
-
apiStyleHint: kind === "backend" && apiStyle ? apiStyle : resolveRoleApiStyleHint(detection, stackId, component),
|
|
247516
|
+
apiStyleHint: kind === "backend" && apiStyle ? apiStyle : stackId === "library_generic" ? void 0 : resolveRoleApiStyleHint(detection, stackId, component),
|
|
247237
247517
|
databaseHints: detection.toolingHints?.databaseHints,
|
|
247238
247518
|
toolingHints: detection.toolingHints?.toolingHints,
|
|
247239
247519
|
repoTopology: detection.topology.topology === "unknown" ? "single_project" : detection.topology.topology
|