@archpilotlabs/archpilot 0.2.3 → 0.2.5
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 +568 -0
- package/README.md +1 -0
- package/dist/archpilot-cli.js +449 -65
- 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
|
});
|
|
@@ -225597,19 +225656,40 @@ function hasSelectStar(statement) {
|
|
|
225597
225656
|
return /\bselect\s+(distinct\s+)?\*/i.test(statement);
|
|
225598
225657
|
}
|
|
225599
225658
|
function hasPaginationEvidence(statement) {
|
|
225600
|
-
|
|
225659
|
+
const boundValuePattern = "(?:\\d+|\\$\\d+|\\?|:[A-Za-z_]\\w*|@[A-Za-z_]\\w*|\\$\\{[^}]{1,120}\\}|[A-Za-z_]\\w*)";
|
|
225660
|
+
const valueTerminatorPattern = "(?=\\s|,|;|\\)|$)";
|
|
225661
|
+
return new RegExp(
|
|
225662
|
+
`\\blimit\\s+${boundValuePattern}${valueTerminatorPattern}|\\boffset\\s+${boundValuePattern}${valueTerminatorPattern}|\\bfetch\\s+(first|next)\\b|\\btop\\s+${boundValuePattern}${valueTerminatorPattern}`,
|
|
225663
|
+
"i"
|
|
225664
|
+
).test(
|
|
225601
225665
|
statement
|
|
225602
225666
|
);
|
|
225603
225667
|
}
|
|
225668
|
+
function hasEqualityPredicate(statement, columnPattern) {
|
|
225669
|
+
return new RegExp(
|
|
225670
|
+
`\\bwhere\\b[\\s\\S]*\\b(?:${columnPattern})\\b\\s*=\\s*(?:[\\w$:@?]+|'[^']+'|"[^"]+"|\\d+)`,
|
|
225671
|
+
"iu"
|
|
225672
|
+
).test(statement);
|
|
225673
|
+
}
|
|
225674
|
+
function isCatalogIdentifierPointLookup(statement) {
|
|
225675
|
+
const metadataSourcePattern = /\bfrom\s+(?:information_schema\.(?:schemata|tables|columns|key_column_usage|table_constraints)|pg_catalog\.(?:pg_class|pg_namespace|pg_attribute|pg_constraint|pg_type|pg_enum|pg_tables|pg_indexes)|pg_(?:class|namespace|attribute|constraint|type|enum|tables|indexes))\b/iu;
|
|
225676
|
+
if (!metadataSourcePattern.test(statement)) {
|
|
225677
|
+
return false;
|
|
225678
|
+
}
|
|
225679
|
+
return hasEqualityPredicate(statement, "schema_name|table_schema|table_name|column_name|constraint_name") || hasEqualityPredicate(statement, "schemaname|tablename|relname|nspname|attname|conname|typname|enumlabel|indexname");
|
|
225680
|
+
}
|
|
225604
225681
|
function isObviousPointLookup(statement) {
|
|
225605
225682
|
const normalized = statement.toLowerCase();
|
|
225683
|
+
if (/\bselect\s+exists\s*\(/i.test(normalized)) {
|
|
225684
|
+
return true;
|
|
225685
|
+
}
|
|
225606
225686
|
if (!normalized.includes("where")) {
|
|
225607
225687
|
return false;
|
|
225608
225688
|
}
|
|
225609
225689
|
if (normalized.includes(" or ")) {
|
|
225610
225690
|
return false;
|
|
225611
225691
|
}
|
|
225612
|
-
return
|
|
225692
|
+
return hasEqualityPredicate(normalized, "id|uuid|slug|email|identifier") || isCatalogIdentifierPointLookup(normalized);
|
|
225613
225693
|
}
|
|
225614
225694
|
function listModulePathEntries(contract) {
|
|
225615
225695
|
return Object.entries(contract.modules ?? {}).map(([moduleName, reference]) => {
|
|
@@ -226190,13 +226270,14 @@ function detectRepeatedQueryPattern(method) {
|
|
|
226190
226270
|
}
|
|
226191
226271
|
function extractSqlQueryLiterals(content) {
|
|
226192
226272
|
const queries = [];
|
|
226273
|
+
const searchableContent = maskSourceComments(content);
|
|
226193
226274
|
const patterns = [
|
|
226194
226275
|
/(?:\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
226276
|
/\b(?:DB::select|DB::statement|DB::raw|DB::table)\s*\([^'"`)]{0,180}?(['"`])([\s\S]{0,900}?)\1/gu,
|
|
226196
226277
|
/@Query\s*\(\s*(['"`])([\s\S]{0,900}?)\1/gu
|
|
226197
226278
|
];
|
|
226198
226279
|
for (const pattern of patterns) {
|
|
226199
|
-
for (const match of
|
|
226280
|
+
for (const match of searchableContent.matchAll(pattern)) {
|
|
226200
226281
|
const sql = match[2];
|
|
226201
226282
|
if (!sql || !/\b(?:select|update|delete|insert)\b/iu.test(sql)) {
|
|
226202
226283
|
continue;
|
|
@@ -226209,6 +226290,71 @@ function extractSqlQueryLiterals(content) {
|
|
|
226209
226290
|
}
|
|
226210
226291
|
return queries;
|
|
226211
226292
|
}
|
|
226293
|
+
function maskSourceComments(content) {
|
|
226294
|
+
let masked = "";
|
|
226295
|
+
let index = 0;
|
|
226296
|
+
let state = "code";
|
|
226297
|
+
let escaped = false;
|
|
226298
|
+
while (index < content.length) {
|
|
226299
|
+
const current = content[index] ?? "";
|
|
226300
|
+
const next = content[index + 1] ?? "";
|
|
226301
|
+
if (state === "line-comment") {
|
|
226302
|
+
if (current === "\r" || current === "\n") {
|
|
226303
|
+
masked += current;
|
|
226304
|
+
state = "code";
|
|
226305
|
+
} else {
|
|
226306
|
+
masked += " ";
|
|
226307
|
+
}
|
|
226308
|
+
index += 1;
|
|
226309
|
+
continue;
|
|
226310
|
+
}
|
|
226311
|
+
if (state === "block-comment") {
|
|
226312
|
+
if (current === "*" && next === "/") {
|
|
226313
|
+
masked += " ";
|
|
226314
|
+
index += 2;
|
|
226315
|
+
state = "code";
|
|
226316
|
+
continue;
|
|
226317
|
+
}
|
|
226318
|
+
masked += current === "\r" || current === "\n" ? current : " ";
|
|
226319
|
+
index += 1;
|
|
226320
|
+
continue;
|
|
226321
|
+
}
|
|
226322
|
+
if (state === "single" || state === "double" || state === "template") {
|
|
226323
|
+
masked += current;
|
|
226324
|
+
if (escaped) {
|
|
226325
|
+
escaped = false;
|
|
226326
|
+
} else if (current === "\\") {
|
|
226327
|
+
escaped = true;
|
|
226328
|
+
} else if (state === "single" && current === "'" || state === "double" && current === '"' || state === "template" && current === "`") {
|
|
226329
|
+
state = "code";
|
|
226330
|
+
}
|
|
226331
|
+
index += 1;
|
|
226332
|
+
continue;
|
|
226333
|
+
}
|
|
226334
|
+
if (current === "/" && next === "/") {
|
|
226335
|
+
masked += " ";
|
|
226336
|
+
index += 2;
|
|
226337
|
+
state = "line-comment";
|
|
226338
|
+
continue;
|
|
226339
|
+
}
|
|
226340
|
+
if (current === "/" && next === "*") {
|
|
226341
|
+
masked += " ";
|
|
226342
|
+
index += 2;
|
|
226343
|
+
state = "block-comment";
|
|
226344
|
+
continue;
|
|
226345
|
+
}
|
|
226346
|
+
if (current === "'") {
|
|
226347
|
+
state = "single";
|
|
226348
|
+
} else if (current === '"') {
|
|
226349
|
+
state = "double";
|
|
226350
|
+
} else if (current === "`") {
|
|
226351
|
+
state = "template";
|
|
226352
|
+
}
|
|
226353
|
+
masked += current;
|
|
226354
|
+
index += 1;
|
|
226355
|
+
}
|
|
226356
|
+
return masked;
|
|
226357
|
+
}
|
|
226212
226358
|
function detectCodeSqlQueryShapeFindings(file, config) {
|
|
226213
226359
|
const findings = [];
|
|
226214
226360
|
for (const query of extractSqlQueryLiterals(file.content)) {
|
|
@@ -226298,12 +226444,18 @@ function hasAssignedBuilderBoundedTerminal(methodBody, snippet) {
|
|
|
226298
226444
|
}
|
|
226299
226445
|
return new RegExp(`\\b${variableName}\\s*\\.\\s*(?:getOne|getRawOne|loadOne|getCount|getExists)\\s*\\(`, "iu").test(methodBody);
|
|
226300
226446
|
}
|
|
226447
|
+
function hasIdentifierPredicateEvidence(snippet) {
|
|
226448
|
+
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);
|
|
226449
|
+
}
|
|
226450
|
+
function hasQueryBuilderTerminalEvidence(snippet, methodBody) {
|
|
226451
|
+
return /\.(?:getMany|getRawMany|loadMany|getOne|getRawOne|loadOne|getCount|getExists|execute)\s*\(/iu.test(snippet) || hasAssignedBuilderBoundedTerminal(methodBody, snippet);
|
|
226452
|
+
}
|
|
226301
226453
|
function isNonCollectionOrmRead(label, snippet, methodBody = snippet) {
|
|
226302
226454
|
const terminal = getOrmTerminalOperation(snippet);
|
|
226303
226455
|
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
226456
|
}
|
|
226305
226457
|
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);
|
|
226458
|
+
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
226459
|
}
|
|
226308
226460
|
function getOrmQueryTarget(method, label, snippet) {
|
|
226309
226461
|
const terminal = getOrmTerminalOperation(snippet);
|
|
@@ -226326,6 +226478,9 @@ function getOrmQueryLabel(method, label, snippet) {
|
|
|
226326
226478
|
function detectOrmQueryShapeFindings(method, config) {
|
|
226327
226479
|
const findings = [];
|
|
226328
226480
|
for (const evidence of collectOrmReadEvidence(method)) {
|
|
226481
|
+
if (evidence.label === "node.query" && !hasQueryBuilderTerminalEvidence(evidence.snippet, method.body)) {
|
|
226482
|
+
continue;
|
|
226483
|
+
}
|
|
226329
226484
|
if (config.tenantModel === "same_db_same_schema" && !tenantPredicatePattern.test(evidence.snippet)) {
|
|
226330
226485
|
findings.push(createCodeFinding({
|
|
226331
226486
|
id: "AP-DQR-001",
|
|
@@ -227034,7 +227189,7 @@ function detectControllerBusinessLogic(entry, classification, moduleName, contex
|
|
|
227034
227189
|
});
|
|
227035
227190
|
}
|
|
227036
227191
|
function detectRepositoryBusinessLogic(entry, classification, moduleName) {
|
|
227037
|
-
if (!classification.isRepository) {
|
|
227192
|
+
if (!classification.isRepository || !isProductionBackendGovernanceScope(classification.scope)) {
|
|
227038
227193
|
return void 0;
|
|
227039
227194
|
}
|
|
227040
227195
|
if (entry.extension === ".java" && isPureSpringDataRepositoryInterface(entry.content)) {
|
|
@@ -227324,6 +227479,7 @@ var import_node_fs26 = require("node:fs");
|
|
|
227324
227479
|
var ts4 = __toESM(require_typescript());
|
|
227325
227480
|
init_moduleDiscovery();
|
|
227326
227481
|
init_archpilotIgnore();
|
|
227482
|
+
init_sourceScopeClassification();
|
|
227327
227483
|
var RuleIds = {
|
|
227328
227484
|
AUTH_MISSING_ENFORCEMENT: "AP-AUTH-001",
|
|
227329
227485
|
AUTH_INCONSISTENT_ENFORCEMENT: "AP-AUTH-002",
|
|
@@ -227362,7 +227518,7 @@ var publicEvidencePattern = /@Public\b|@PermitAll\b|\[AllowAnonymous\b[^\]]*\]|p
|
|
|
227362
227518
|
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
227519
|
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
227520
|
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
|
|
227521
|
+
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
227522
|
function normalizePath12(value) {
|
|
227367
227523
|
return value.replace(/\\/g, "/");
|
|
227368
227524
|
}
|
|
@@ -227754,7 +227910,10 @@ function isProtectedLooking(endpoint) {
|
|
|
227754
227910
|
}
|
|
227755
227911
|
function detectAuthorizationFindings(files, contract, astCache) {
|
|
227756
227912
|
const findings = [];
|
|
227757
|
-
|
|
227913
|
+
const productionFiles = files.filter(
|
|
227914
|
+
(file) => isProductionBackendGovernanceScope(classifyValidationSourceScope(file.relativePath))
|
|
227915
|
+
);
|
|
227916
|
+
for (const file of productionFiles) {
|
|
227758
227917
|
const moduleName = inferModuleForPath3(contract, file.relativePath);
|
|
227759
227918
|
const endpoints = extractEndpoints(file, moduleName);
|
|
227760
227919
|
if (endpoints.length === 0 && !isControllerFile(file, astCache)) {
|
|
@@ -227789,8 +227948,8 @@ function detectAuthorizationFindings(files, contract, astCache) {
|
|
|
227789
227948
|
}
|
|
227790
227949
|
}
|
|
227791
227950
|
}
|
|
227792
|
-
for (const file of
|
|
227793
|
-
const roleMatch =
|
|
227951
|
+
for (const file of productionFiles.filter((candidate) => isRepositoryFile(candidate, astCache))) {
|
|
227952
|
+
const roleMatch = executableAuthorizationDecisionPattern.exec(file.content);
|
|
227794
227953
|
if (!roleMatch) {
|
|
227795
227954
|
continue;
|
|
227796
227955
|
}
|
|
@@ -228272,7 +228431,7 @@ function classifySourceFile2(file, contract, astCache) {
|
|
|
228272
228431
|
const scope = classifyValidationSourceScope(file.relativePath);
|
|
228273
228432
|
const roles = new Set(getDeclaredRoles2(file, astCache));
|
|
228274
228433
|
const lowerPath = file.relativePath.toLowerCase();
|
|
228275
|
-
if (/(^|[./_-])controller\.(ts|tsx|js|jsx|mjs|cjs|java|cs|py|php|go)$/u.test(lowerPath) || /(^|\/)(controllers?|routers?|routes
|
|
228434
|
+
if (/(^|[./_-])controller\.(ts|tsx|js|jsx|mjs|cjs|java|cs|py|php|go)$/u.test(lowerPath) || /(^|\/)(controllers?|routers?|routes?)\//u.test(lowerPath)) {
|
|
228276
228435
|
roles.add("controller");
|
|
228277
228436
|
}
|
|
228278
228437
|
if (/(^|[./_-])service\.(ts|tsx|js|jsx|mjs|cjs|java|cs|py|php|go)$/u.test(lowerPath) || /(^|\/)(services?)\//u.test(lowerPath)) {
|
|
@@ -230589,8 +230748,9 @@ function extractJavaSignals(file) {
|
|
|
230589
230748
|
publishes: []
|
|
230590
230749
|
});
|
|
230591
230750
|
}
|
|
230592
|
-
for (const match of file.content.matchAll(/(?:await\s+)?(?:\w+\.)?(?:publishEvent|publish|emit)\s*\(\s*(?:new\s+)
|
|
230593
|
-
const
|
|
230751
|
+
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)) {
|
|
230752
|
+
const constructedType = match[2]?.split(".").at(-1);
|
|
230753
|
+
const eventName = constructedType ?? match[4] ?? match[5];
|
|
230594
230754
|
if (!eventName) {
|
|
230595
230755
|
continue;
|
|
230596
230756
|
}
|
|
@@ -234446,7 +234606,7 @@ ${infoLines.join("\n")}
|
|
|
234446
234606
|
## Passed Checks
|
|
234447
234607
|
${passedLines.join("\n")}
|
|
234448
234608
|
|
|
234449
|
-
## Module Dependency Summary
|
|
234609
|
+
## Module / Component Contract Dependency Summary
|
|
234450
234610
|
${dependencyGraphLines.join("\n")}
|
|
234451
234611
|
|
|
234452
234612
|
## Disabled Rules
|
|
@@ -236682,7 +236842,7 @@ ${appliedFixesSection}
|
|
|
236682
236842
|
## Remaining Violations
|
|
236683
236843
|
${remainingViolationsLine}
|
|
236684
236844
|
|
|
236685
|
-
## Module Dependency Summary
|
|
236845
|
+
## Module / Component Contract Dependency Summary
|
|
236686
236846
|
${moduleCatalog.length === 0 ? "- Module details are not available in this run." : moduleCatalog.map(
|
|
236687
236847
|
(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
236848
|
).join("\n")}
|
|
@@ -238934,11 +239094,11 @@ function normalizeAnnotationPath(workspaceRoot, sourceFile) {
|
|
|
238934
239094
|
if (!path43.isAbsolute(sourceFile)) {
|
|
238935
239095
|
return normalized;
|
|
238936
239096
|
}
|
|
238937
|
-
const
|
|
238938
|
-
if (
|
|
239097
|
+
const relative18 = path43.relative(workspaceRoot, sourceFile).replace(/\\/g, "/");
|
|
239098
|
+
if (relative18.startsWith("..") || path43.isAbsolute(relative18)) {
|
|
238939
239099
|
return void 0;
|
|
238940
239100
|
}
|
|
238941
|
-
return
|
|
239101
|
+
return relative18;
|
|
238942
239102
|
}
|
|
238943
239103
|
function toAnnotatableFinding(workspaceRoot, finding) {
|
|
238944
239104
|
if (typeof finding.id !== "string" || !finding.id.startsWith("AP-DEP-")) {
|
|
@@ -239122,7 +239282,7 @@ async function emitGithubInlineArchitectureAnnotations(workspaceRoot) {
|
|
|
239122
239282
|
var reviewCommentMarker = "<!-- archpilot-pr-review -->";
|
|
239123
239283
|
var legacyReviewCommentMarker = "<!-- ARCHPILOT_REVIEW_COMMENT -->";
|
|
239124
239284
|
function requestGithubApi(options) {
|
|
239125
|
-
return new Promise((
|
|
239285
|
+
return new Promise((resolve10, reject) => {
|
|
239126
239286
|
const payload = options.body !== void 0 ? JSON.stringify(options.body) : void 0;
|
|
239127
239287
|
const request3 = https2.request(
|
|
239128
239288
|
{
|
|
@@ -239143,7 +239303,7 @@ function requestGithubApi(options) {
|
|
|
239143
239303
|
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
239144
239304
|
});
|
|
239145
239305
|
response.on("end", () => {
|
|
239146
|
-
|
|
239306
|
+
resolve10({
|
|
239147
239307
|
statusCode: response.statusCode ?? 0,
|
|
239148
239308
|
body: Buffer.concat(chunks).toString("utf8")
|
|
239149
239309
|
});
|
|
@@ -245420,6 +245580,9 @@ function addEvidence6(evidence, value) {
|
|
|
245420
245580
|
evidence.push(value);
|
|
245421
245581
|
}
|
|
245422
245582
|
}
|
|
245583
|
+
function hasDeclaredMavenReactorEvidence(candidate) {
|
|
245584
|
+
return candidate.evidence.some((entry) => /Declared (?:by )?Maven|nested Maven reactor/iu.test(entry));
|
|
245585
|
+
}
|
|
245423
245586
|
function isIgnoredComponentCandidatePath(componentPath) {
|
|
245424
245587
|
const normalized = normalizePath25(componentPath).replace(/^\.\//u, "");
|
|
245425
245588
|
if (normalized === "." || normalized.length === 0) {
|
|
@@ -245459,7 +245622,9 @@ function isIgnoredComponentCandidatePath(componentPath) {
|
|
|
245459
245622
|
"build",
|
|
245460
245623
|
"coverage"
|
|
245461
245624
|
];
|
|
245462
|
-
|
|
245625
|
+
const isExampleContainer = firstSegment === "examples" || firstSegment === "example";
|
|
245626
|
+
const isIgnoredRootSegment = ignoredRootSegments.includes(firstSegment ?? "") && (!isExampleContainer || segments.length === 1);
|
|
245627
|
+
return isIgnoredRootSegment || segments.some((segment) => ignoredSupportingSegments.includes(segment.toLowerCase()));
|
|
245463
245628
|
}
|
|
245464
245629
|
function pathExists19(pathValue) {
|
|
245465
245630
|
try {
|
|
@@ -245502,6 +245667,14 @@ function hasObject(value) {
|
|
|
245502
245667
|
function hasPackagePublishSurface(packageJson) {
|
|
245503
245668
|
return hasObject(packageJson?.exports) || typeof packageJson?.main === "string" || typeof packageJson?.module === "string" || typeof packageJson?.types === "string" || hasObject(packageJson?.publishConfig) || Array.isArray(packageJson?.files);
|
|
245504
245669
|
}
|
|
245670
|
+
function packageDependencyNames(packageJson) {
|
|
245671
|
+
return [
|
|
245672
|
+
...recordKeys(packageJson?.dependencies),
|
|
245673
|
+
...recordKeys(packageJson?.devDependencies),
|
|
245674
|
+
...recordKeys(packageJson?.peerDependencies),
|
|
245675
|
+
...recordKeys(packageJson?.optionalDependencies)
|
|
245676
|
+
];
|
|
245677
|
+
}
|
|
245505
245678
|
function absoluteComponentRoot(workspaceRoot, componentPath) {
|
|
245506
245679
|
return componentPath === "." ? workspaceRoot : path64.join(workspaceRoot, ...componentPath.split("/"));
|
|
245507
245680
|
}
|
|
@@ -245509,6 +245682,10 @@ function readPackageJson(workspaceRoot, componentPath) {
|
|
|
245509
245682
|
const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
|
|
245510
245683
|
return safeReadJson(path64.join(absoluteRoot, "package.json"));
|
|
245511
245684
|
}
|
|
245685
|
+
function readProjectJson(workspaceRoot, componentPath) {
|
|
245686
|
+
const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
|
|
245687
|
+
return safeReadJson(path64.join(absoluteRoot, "project.json"));
|
|
245688
|
+
}
|
|
245512
245689
|
function readTextFileSafe(filePath) {
|
|
245513
245690
|
try {
|
|
245514
245691
|
return fs58.readFileSync(filePath, { encoding: "utf8" });
|
|
@@ -245523,6 +245700,9 @@ function readFirstXmlTag(value, tagName) {
|
|
|
245523
245700
|
const match = value.match(new RegExp(`<${tagName}(?:\\s[^>]*)?>([\\s\\S]*?)</${tagName}>`, "iu"));
|
|
245524
245701
|
return match?.[1]?.trim().replace(/\s+/gu, " ");
|
|
245525
245702
|
}
|
|
245703
|
+
function readXmlTagValues(value, tagName) {
|
|
245704
|
+
return [...value.matchAll(new RegExp(`<${tagName}(?:\\s[^>]*)?>([\\s\\S]*?)</${tagName}>`, "giu"))].map((match) => match[1]?.trim().replace(/\s+/gu, " ") ?? "").filter((entry) => entry.length > 0);
|
|
245705
|
+
}
|
|
245526
245706
|
function readMavenMetadata(workspaceRoot, componentPath) {
|
|
245527
245707
|
if (isUnderJvmResourceRoot4(componentPath)) {
|
|
245528
245708
|
return void 0;
|
|
@@ -245560,6 +245740,95 @@ function readMavenMetadata(workspaceRoot, componentPath) {
|
|
|
245560
245740
|
hasTestResources: pathExists19(path64.join(absoluteRoot, "src", "test", "resources"))
|
|
245561
245741
|
};
|
|
245562
245742
|
}
|
|
245743
|
+
function workspaceRelativePath(workspaceRoot, absolutePathValue) {
|
|
245744
|
+
const relative18 = path64.relative(workspaceRoot, absolutePathValue);
|
|
245745
|
+
if (relative18.length === 0) {
|
|
245746
|
+
return ".";
|
|
245747
|
+
}
|
|
245748
|
+
if (relative18.startsWith("..") || path64.isAbsolute(relative18)) {
|
|
245749
|
+
return void 0;
|
|
245750
|
+
}
|
|
245751
|
+
return normalizePath25(relative18);
|
|
245752
|
+
}
|
|
245753
|
+
function canonicalRealPath(filePath) {
|
|
245754
|
+
try {
|
|
245755
|
+
return fs58.realpathSync.native(filePath);
|
|
245756
|
+
} catch {
|
|
245757
|
+
return void 0;
|
|
245758
|
+
}
|
|
245759
|
+
}
|
|
245760
|
+
function readMavenDeclaredModules(pomPath) {
|
|
245761
|
+
const pomXml = readTextFileSafe(pomPath);
|
|
245762
|
+
if (!pomXml) {
|
|
245763
|
+
return [];
|
|
245764
|
+
}
|
|
245765
|
+
return uniqueSorted4(
|
|
245766
|
+
readXmlTagValues(stripXmlComments(pomXml), "module").filter((modulePath) => !/[${}]/u.test(modulePath))
|
|
245767
|
+
);
|
|
245768
|
+
}
|
|
245769
|
+
function collectMavenReactorCandidates(workspaceRoot, rootPaths) {
|
|
245770
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
245771
|
+
const visitedPomPaths = /* @__PURE__ */ new Set();
|
|
245772
|
+
const workspaceRealPath = canonicalRealPath(workspaceRoot) ?? path64.resolve(workspaceRoot);
|
|
245773
|
+
const workspaceRealPathForCompare = process.platform === "win32" ? workspaceRealPath.toLowerCase() : workspaceRealPath;
|
|
245774
|
+
const maxVisitedPoms = 500;
|
|
245775
|
+
const addCandidate = (candidatePath, evidence, parentPath) => {
|
|
245776
|
+
const normalized = normalizePath25(candidatePath);
|
|
245777
|
+
const existing = candidates.get(normalized) ?? { path: normalized, evidence: [] };
|
|
245778
|
+
addEvidence6(existing.evidence, evidence);
|
|
245779
|
+
if (parentPath && !existing.parentPath) {
|
|
245780
|
+
existing.parentPath = parentPath;
|
|
245781
|
+
}
|
|
245782
|
+
candidates.set(normalized, existing);
|
|
245783
|
+
};
|
|
245784
|
+
const visitPom = (pomPath, parentPath) => {
|
|
245785
|
+
if (visitedPomPaths.size >= maxVisitedPoms) {
|
|
245786
|
+
return;
|
|
245787
|
+
}
|
|
245788
|
+
const realPomPath = canonicalRealPath(pomPath);
|
|
245789
|
+
if (!realPomPath || visitedPomPaths.has(realPomPath)) {
|
|
245790
|
+
return;
|
|
245791
|
+
}
|
|
245792
|
+
const realPomPathForCompare = process.platform === "win32" ? realPomPath.toLowerCase() : realPomPath;
|
|
245793
|
+
if (realPomPathForCompare !== workspaceRealPathForCompare && !realPomPathForCompare.startsWith(`${workspaceRealPathForCompare}${path64.sep}`)) {
|
|
245794
|
+
return;
|
|
245795
|
+
}
|
|
245796
|
+
visitedPomPaths.add(realPomPath);
|
|
245797
|
+
const pomDirectory = path64.dirname(pomPath);
|
|
245798
|
+
const relativePomDirectory = workspaceRelativePath(workspaceRoot, pomDirectory);
|
|
245799
|
+
if (!relativePomDirectory) {
|
|
245800
|
+
return;
|
|
245801
|
+
}
|
|
245802
|
+
addCandidate(
|
|
245803
|
+
relativePomDirectory,
|
|
245804
|
+
parentPath ? `Declared by Maven reactor parent ${parentPath}` : "Detected Maven reactor root",
|
|
245805
|
+
parentPath
|
|
245806
|
+
);
|
|
245807
|
+
for (const declaredModule of readMavenDeclaredModules(pomPath)) {
|
|
245808
|
+
const childDirectory = path64.resolve(pomDirectory, declaredModule);
|
|
245809
|
+
const childRelativePath = workspaceRelativePath(workspaceRoot, childDirectory);
|
|
245810
|
+
if (!childRelativePath || isUnderJvmResourceRoot4(childRelativePath)) {
|
|
245811
|
+
continue;
|
|
245812
|
+
}
|
|
245813
|
+
const childPom = path64.join(childDirectory, "pom.xml");
|
|
245814
|
+
if (!pathExists19(childPom)) {
|
|
245815
|
+
addCandidate(childRelativePath, `Declared Maven module '${declaredModule}' is missing pom.xml`, relativePomDirectory);
|
|
245816
|
+
continue;
|
|
245817
|
+
}
|
|
245818
|
+
addCandidate(childRelativePath, `Declared Maven module '${declaredModule}' from ${relativePomDirectory}`, relativePomDirectory);
|
|
245819
|
+
visitPom(childPom, relativePomDirectory);
|
|
245820
|
+
}
|
|
245821
|
+
};
|
|
245822
|
+
for (const rootPath of uniqueSorted4(rootPaths)) {
|
|
245823
|
+
const normalizedRoot = normalizePath25(rootPath);
|
|
245824
|
+
const absoluteRoot = normalizedRoot === "." ? workspaceRoot : path64.join(workspaceRoot, ...normalizedRoot.split("/"));
|
|
245825
|
+
const pomPath = path64.join(absoluteRoot, "pom.xml");
|
|
245826
|
+
if (pathExists19(pomPath)) {
|
|
245827
|
+
visitPom(pomPath);
|
|
245828
|
+
}
|
|
245829
|
+
}
|
|
245830
|
+
return [...candidates.values()].sort((left, right) => left.path.localeCompare(right.path));
|
|
245831
|
+
}
|
|
245563
245832
|
function toComponentRoot(modulePath) {
|
|
245564
245833
|
const normalized = normalizePath25(modulePath);
|
|
245565
245834
|
const segments = normalized.split("/").filter((segment) => segment.length > 0);
|
|
@@ -245594,6 +245863,18 @@ function buildRootCandidates(input2) {
|
|
|
245594
245863
|
for (const root of input2.topology.detectedRoots ?? []) {
|
|
245595
245864
|
addCandidate(root, `Detected project root ${root}`);
|
|
245596
245865
|
}
|
|
245866
|
+
if (input2.workspaceRoot) {
|
|
245867
|
+
const mavenRoots = [".", ...input2.topology.detectedRoots ?? []];
|
|
245868
|
+
for (const candidate of collectMavenReactorCandidates(input2.workspaceRoot, mavenRoots)) {
|
|
245869
|
+
addCandidate(
|
|
245870
|
+
candidate.path,
|
|
245871
|
+
candidate.parentPath ? `Detected nested Maven reactor module under ${candidate.parentPath}` : "Detected Maven reactor module"
|
|
245872
|
+
);
|
|
245873
|
+
for (const evidence of candidate.evidence) {
|
|
245874
|
+
addCandidate(candidate.path, evidence);
|
|
245875
|
+
}
|
|
245876
|
+
}
|
|
245877
|
+
}
|
|
245597
245878
|
for (const moduleEntry of input2.modules?.modules ?? []) {
|
|
245598
245879
|
const componentRoot = toComponentRoot(moduleEntry.path);
|
|
245599
245880
|
if (componentRoot) {
|
|
@@ -245972,11 +246253,57 @@ function hasRuntimeSourceFiles(workspaceRoot, componentPath) {
|
|
|
245972
246253
|
}
|
|
245973
246254
|
return false;
|
|
245974
246255
|
}
|
|
246256
|
+
function hasFileMatchingUnderRoot(root, pattern) {
|
|
246257
|
+
if (!pathExists19(root)) {
|
|
246258
|
+
return false;
|
|
246259
|
+
}
|
|
246260
|
+
const entries = fs58.readdirSync(root, { recursive: true, withFileTypes: true });
|
|
246261
|
+
return entries.some((entry) => entry.isFile() && pattern.test(normalizePath25(path64.join(entry.parentPath, entry.name))));
|
|
246262
|
+
}
|
|
246263
|
+
function hasNestRuntimeApplicationEvidence(workspaceRoot, componentPath, packageJson = readPackageJson(workspaceRoot, componentPath)) {
|
|
246264
|
+
const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
|
|
246265
|
+
const dependencies = new Set(packageDependencyNames(packageJson));
|
|
246266
|
+
const scripts = recordKeys(packageJson?.scripts);
|
|
246267
|
+
const hasNestCore = dependencies.has("@nestjs/core");
|
|
246268
|
+
if (!hasNestCore) {
|
|
246269
|
+
return false;
|
|
246270
|
+
}
|
|
246271
|
+
const hasRuntimePlatform = dependencies.has("@nestjs/platform-express") || dependencies.has("@nestjs/platform-fastify") || dependencies.has("@nestjs/microservices") || dependencies.has("@nestjs/graphql") || dependencies.has("@nestjs/apollo");
|
|
246272
|
+
const hasRunnableScript = scripts.some((script) => /^(?:start|serve|dev|worker)(?::|$)/u.test(script));
|
|
246273
|
+
const hasNestCliConfig = ["nest-cli.json", "nest.config.js", "nest.config.ts"].some(
|
|
246274
|
+
(fileName) => pathExists19(path64.join(absoluteRoot, fileName))
|
|
246275
|
+
);
|
|
246276
|
+
const hasBootstrapEntrypoint = [
|
|
246277
|
+
path64.join(absoluteRoot, "src", "main.ts"),
|
|
246278
|
+
path64.join(absoluteRoot, "src", "main.js"),
|
|
246279
|
+
path64.join(absoluteRoot, "main.ts"),
|
|
246280
|
+
path64.join(absoluteRoot, "main.js")
|
|
246281
|
+
].some((filePath) => {
|
|
246282
|
+
const contents = readTextFileSafe(filePath);
|
|
246283
|
+
return Boolean(contents && /\bNestFactory\.create(?:ApplicationContext)?\s*\(/u.test(contents));
|
|
246284
|
+
});
|
|
246285
|
+
const srcRoot = path64.join(absoluteRoot, "src");
|
|
246286
|
+
const hasRuntimeSourceShape = hasFileMatchingUnderRoot(srcRoot, /\.(?:controller|resolver|gateway|processor|module|worker|queue)\.(?:ts|js)$/iu) || hasFileMatchingUnderRoot(srcRoot, /[/\\](?:controllers?|resolvers?|queues?|workers?)[/\\][^/\\]+\.(?:ts|js)$/iu);
|
|
246287
|
+
const hasDatabaseRuntimeIntegration = [...dependencies].some(
|
|
246288
|
+
(dependency) => /^(?:typeorm|@nestjs\/typeorm|@prisma\/client|prisma|mongoose|@nestjs\/mongoose|sequelize|@mikro-orm\/core)$/u.test(dependency)
|
|
246289
|
+
);
|
|
246290
|
+
const structuralEvidenceCount = [
|
|
246291
|
+
hasRuntimePlatform,
|
|
246292
|
+
hasRunnableScript,
|
|
246293
|
+
hasNestCliConfig,
|
|
246294
|
+
hasBootstrapEntrypoint,
|
|
246295
|
+
hasRuntimeSourceShape,
|
|
246296
|
+
hasDatabaseRuntimeIntegration
|
|
246297
|
+
].filter(Boolean).length;
|
|
246298
|
+
return hasBootstrapEntrypoint || hasRuntimePlatform && structuralEvidenceCount >= 2 || hasRunnableScript && hasRuntimeSourceShape && structuralEvidenceCount >= 3;
|
|
246299
|
+
}
|
|
245975
246300
|
function resolveKind(workspaceRoot, candidate, localProjectKinds) {
|
|
245976
246301
|
const lowerPath = candidate.path.toLowerCase();
|
|
245977
246302
|
const packageJson = readPackageJson(workspaceRoot, candidate.path);
|
|
245978
246303
|
const maven = readMavenMetadata(workspaceRoot, candidate.path);
|
|
246304
|
+
const dependencies = new Set(packageDependencyNames(packageJson));
|
|
245979
246305
|
const hasRunnableFrontendEvidence = hasRunnableFrontendComponentEvidence(workspaceRoot, candidate.path);
|
|
246306
|
+
const hasNestRuntimeEvidence = hasNestRuntimeApplicationEvidence(workspaceRoot, candidate.path, packageJson);
|
|
245980
246307
|
const hasPublishSurface = hasPackagePublishSurface(packageJson);
|
|
245981
246308
|
const hasMavenRunnableEvidence = Boolean(
|
|
245982
246309
|
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))
|
|
@@ -245998,6 +246325,12 @@ function resolveKind(workspaceRoot, candidate, localProjectKinds) {
|
|
|
245998
246325
|
return hasPublishSurface && !hasRunnableFrontendEvidence ? "library" : "frontend";
|
|
245999
246326
|
}
|
|
246000
246327
|
if (classification === "backend_app") {
|
|
246328
|
+
if (hasPublishSurface && dependencies.has("@nestjs/core") && !hasNestRuntimeEvidence) {
|
|
246329
|
+
return "library";
|
|
246330
|
+
}
|
|
246331
|
+
return "backend";
|
|
246332
|
+
}
|
|
246333
|
+
if (hasNestRuntimeEvidence) {
|
|
246001
246334
|
return "backend";
|
|
246002
246335
|
}
|
|
246003
246336
|
if (hasRunnableFrontendEvidence && localProjectKinds.primaryKind !== "backend" && localProjectKinds.primaryKind !== "service" && localProjectKinds.primaryKind !== "cli") {
|
|
@@ -246061,6 +246394,7 @@ function hasAnyToken(value, patterns) {
|
|
|
246061
246394
|
}
|
|
246062
246395
|
function classifyGovernanceRole(input2) {
|
|
246063
246396
|
const packageJson = readPackageJson(input2.workspaceRoot, input2.candidate.path);
|
|
246397
|
+
const projectJson = readProjectJson(input2.workspaceRoot, input2.candidate.path);
|
|
246064
246398
|
const maven = readMavenMetadata(input2.workspaceRoot, input2.candidate.path);
|
|
246065
246399
|
const evidence = [];
|
|
246066
246400
|
let supportScore = 0;
|
|
@@ -246074,11 +246408,15 @@ function classifyGovernanceRole(input2) {
|
|
|
246074
246408
|
const scripts = recordKeys(packageJson?.scripts);
|
|
246075
246409
|
const dependencies = recordKeys(packageJson?.dependencies);
|
|
246076
246410
|
const devDependencies = recordKeys(packageJson?.devDependencies);
|
|
246411
|
+
const projectTags = toStringArray(projectJson?.tags);
|
|
246412
|
+
const projectTargets = recordKeys(projectJson?.targets);
|
|
246077
246413
|
const scriptText = scripts.join(" ").toLowerCase();
|
|
246414
|
+
const projectMetadataText = `${projectTags.join(" ")} ${projectTargets.join(" ")}`.toLowerCase();
|
|
246078
246415
|
const dependencyText = [...dependencies, ...devDependencies].join(" ").toLowerCase();
|
|
246416
|
+
const hasNestRuntimeEvidence = hasNestRuntimeApplicationEvidence(input2.workspaceRoot, input2.candidate.path, packageJson);
|
|
246079
246417
|
const hasStrongSupportPath = hasAnyToken(pathText, [
|
|
246080
|
-
/(^|\/)(testing|test-plugins|cypress-tests|fixtures?|
|
|
246081
|
-
/(^|\/)(dev-server|scaffold|scaffolding|generators?|devkit|tooling|tools)(\/|$)/u
|
|
246418
|
+
/(^|\/)(testing|e2e-testing|test-plugins|cypress-tests|fixtures?|benchmarks?|smoke)(\/|$)/u,
|
|
246419
|
+
/(^|\/)(dev-server|scaffold|scaffolding|generators?|devkit|tooling|tools|templates?)(\/|$)/u
|
|
246082
246420
|
]);
|
|
246083
246421
|
const isPlainResourcesSurface = isUnderJvmResourceRoot4(pathText) && !hasRuntimeSourceFiles(input2.workspaceRoot, input2.candidate.path) && !packageJson && !maven;
|
|
246084
246422
|
const hasPublishSurface = hasPackagePublishSurface(packageJson);
|
|
@@ -246102,6 +246440,9 @@ function classifyGovernanceRole(input2) {
|
|
|
246102
246440
|
const hasMavenDistributionPackagingEvidence = Boolean(
|
|
246103
246441
|
maven?.packaging === "pom" && !hasMavenMainSource && hasAnyToken(pathText, [/(^|\/)(distribution|dist|downloads|assembl(y|ies)|feature-packs?)(\/|$)/u])
|
|
246104
246442
|
);
|
|
246443
|
+
const hasMavenStarterPackagingEvidence = Boolean(
|
|
246444
|
+
maven && !hasMavenMainJvmSourceEvidence && hasAnyToken(`${pathText} ${mavenMetadataText}`, [/\bstarters?\b|\bspring-boot-starter\b|\bstarter[-\s]/u])
|
|
246445
|
+
);
|
|
246105
246446
|
if (input2.candidate.architectureRoot?.classification === "backend_app" || input2.candidate.architectureRoot?.classification === "frontend_app") {
|
|
246106
246447
|
runtimeScore += 3;
|
|
246107
246448
|
addEvidence6(evidence, `Runtime architecture root signal: ${input2.candidate.architectureRoot.classification}`);
|
|
@@ -246120,6 +246461,10 @@ function classifyGovernanceRole(input2) {
|
|
|
246120
246461
|
runtimeScore += 1;
|
|
246121
246462
|
addEvidence6(evidence, `Runtime framework stack signal: ${input2.stack}`);
|
|
246122
246463
|
}
|
|
246464
|
+
if (hasNestRuntimeEvidence) {
|
|
246465
|
+
runtimeScore += 3;
|
|
246466
|
+
addEvidence6(evidence, "NestJS runtime application evidence");
|
|
246467
|
+
}
|
|
246123
246468
|
if (hasPublishSurface && !isPrivate) {
|
|
246124
246469
|
runtimeScore += 1;
|
|
246125
246470
|
addEvidence6(evidence, "Published package surface signal");
|
|
@@ -246144,25 +246489,37 @@ function classifyGovernanceRole(input2) {
|
|
|
246144
246489
|
if (hasMavenAutoConfigurationEvidence && !hasMavenRunnableApplicationEvidence) {
|
|
246145
246490
|
addEvidence6(evidence, "Maven Spring Boot auto-configuration/starter library evidence");
|
|
246146
246491
|
}
|
|
246147
|
-
if (hasAnyToken(descriptiveManifestText, [/\b(e2e|end-to-end|testing|test helper|test utilities|fixtures
|
|
246492
|
+
if (hasAnyToken(descriptiveManifestText, [/\b(e2e|end-to-end|testing|test helper|test utilities|fixtures?|test harness)\b/u])) {
|
|
246148
246493
|
supportScore += 3;
|
|
246149
246494
|
addEvidence6(evidence, "Package metadata describes test/support usage");
|
|
246150
246495
|
}
|
|
246496
|
+
if (hasAnyToken(`${packageName.toLowerCase()} ${projectMetadataText}`, [/\b(e2e|end-to-end|testing|test harness|scope:testing|test:ui|test:debug|test:report)\b/u]) && hasAnyToken(dependencyText, [/\b(?:playwright|@playwright\/test|cypress|vitest|jest|mocha)\b/u])) {
|
|
246497
|
+
supportScore += 4;
|
|
246498
|
+
addEvidence6(evidence, "Project metadata and dependencies indicate test-only workspace");
|
|
246499
|
+
}
|
|
246151
246500
|
if (hasAnyToken(descriptiveManifestText, [/\b(scaffold|scaffolding|generator|codegen|template|starter|create)\b/u])) {
|
|
246152
246501
|
supportScore += 3;
|
|
246153
246502
|
addEvidence6(evidence, "Package metadata describes scaffolding/generation usage");
|
|
246154
246503
|
}
|
|
246155
|
-
if (hasAnyToken(descriptiveManifestText, [/\b(dev server|development server|development tooling|tooling|devkit)\b/u])) {
|
|
246504
|
+
if (hasAnyToken(descriptiveManifestText, [/\b(dev server|development server|development tooling|tooling|devkit|lint rules?|linter|build tooling|repository tooling)\b/u])) {
|
|
246156
246505
|
supportScore += 2;
|
|
246157
246506
|
addEvidence6(evidence, "Package metadata describes development/tooling usage");
|
|
246158
246507
|
}
|
|
246159
246508
|
if (hasAnyToken(pathText, [
|
|
246160
|
-
/(^|\/)(test|tests|testing|__tests__|cypress|cypress-tests|fixtures?|
|
|
246161
|
-
/(^|\/)(dev-server|test-plugins|scaffold|scaffolding|generators?|devkit|tooling|tools)(\/|$)/u
|
|
246509
|
+
/(^|\/)(test|tests|testing|e2e-testing|__tests__|cypress|cypress-tests|fixtures?|benchmarks?|smoke)(\/|$)/u,
|
|
246510
|
+
/(^|\/)(dev-server|test-plugins|scaffold|scaffolding|generators?|devkit|tooling|tools|templates?)(\/|$)/u
|
|
246162
246511
|
])) {
|
|
246163
246512
|
supportScore += 1;
|
|
246164
246513
|
addEvidence6(evidence, "Path contains support/tooling role tokens");
|
|
246165
246514
|
}
|
|
246515
|
+
if (hasAnyToken(pathText, [/(^|\/)(?:src\/constants\/)?templates?(\/|$)/u])) {
|
|
246516
|
+
supportScore += 4;
|
|
246517
|
+
addEvidence6(evidence, "Nested scaffold/template source surface");
|
|
246518
|
+
}
|
|
246519
|
+
if (hasAnyToken(dependencyText, [/\b(?:eslint|oxlint|prettier|typescript-eslint|ts-morph|jscodeshift|schematics|yeoman)\b/u])) {
|
|
246520
|
+
supportScore += 2;
|
|
246521
|
+
addEvidence6(evidence, "Package dependencies indicate lint/build/generation tooling");
|
|
246522
|
+
}
|
|
246166
246523
|
if (scripts.length > 0 && scripts.every((script) => /^(test|e2e|smoke|bench|benchmark|lint|typecheck|dev|dev:|load-test|generate|scaffold)/u.test(script))) {
|
|
246167
246524
|
supportScore += 1;
|
|
246168
246525
|
addEvidence6(evidence, "Package scripts are dominated by development/test workflows");
|
|
@@ -246211,6 +246568,10 @@ function classifyGovernanceRole(input2) {
|
|
|
246211
246568
|
supportScore += 1;
|
|
246212
246569
|
addEvidence6(evidence, "Maven POM-only aggregator/packaging module");
|
|
246213
246570
|
}
|
|
246571
|
+
if (hasMavenStarterPackagingEvidence) {
|
|
246572
|
+
supportScore += 4;
|
|
246573
|
+
addEvidence6(evidence, "Maven starter/resource artifact without JVM runtime source");
|
|
246574
|
+
}
|
|
246214
246575
|
if (isPlainResourcesSurface) {
|
|
246215
246576
|
supportScore += 4;
|
|
246216
246577
|
addEvidence6(evidence, "Resources-only surface without runtime source or manifest evidence");
|
|
@@ -246222,6 +246583,13 @@ function classifyGovernanceRole(input2) {
|
|
|
246222
246583
|
selectedByDefault: false
|
|
246223
246584
|
};
|
|
246224
246585
|
}
|
|
246586
|
+
if (hasMavenStarterPackagingEvidence && !hasMavenMainJvmSourceEvidence) {
|
|
246587
|
+
return {
|
|
246588
|
+
governanceRole: "support",
|
|
246589
|
+
governanceEvidence: uniqueSorted4(evidence),
|
|
246590
|
+
selectedByDefault: false
|
|
246591
|
+
};
|
|
246592
|
+
}
|
|
246225
246593
|
if (hasMavenDistributionPackagingEvidence && hasAnyToken(mavenMetadataText, [/\b(docs?|documentation|metadata tests?|licenses?|maven plugins?|builds?)\b/u])) {
|
|
246226
246594
|
supportScore += 3;
|
|
246227
246595
|
addEvidence6(evidence, "Maven documentation/build/distribution packaging evidence without runtime source");
|
|
@@ -246281,7 +246649,7 @@ function detectComponents(input2) {
|
|
|
246281
246649
|
const manifestBackedRoots = new Set(
|
|
246282
246650
|
(input2.topology.detectedRoots ?? []).filter((root) => !isUnderJvmResourceRoot4(root))
|
|
246283
246651
|
);
|
|
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) => {
|
|
246652
|
+
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
246653
|
if (input2.topology.topology !== "monorepo" || manifestBackedRoots.size === 0) {
|
|
246286
246654
|
return true;
|
|
246287
246655
|
}
|
|
@@ -246579,7 +246947,7 @@ function isCliSupportCandidate(component, allComponents) {
|
|
|
246579
246947
|
}
|
|
246580
246948
|
function hasIndependentRuntimeEvidence(component) {
|
|
246581
246949
|
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));
|
|
246950
|
+
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
246951
|
}
|
|
246584
246952
|
function hasSupportRoleEvidence(component) {
|
|
246585
246953
|
const text = componentEvidenceText(component);
|
|
@@ -246789,7 +247157,20 @@ function hasAttributableBackendRoot(detection) {
|
|
|
246789
247157
|
return getBackendComponents(detection).length > 0;
|
|
246790
247158
|
}
|
|
246791
247159
|
function isGenericLibraryStack(stack) {
|
|
246792
|
-
return stack === "node_typescript" || stack === "node_javascript" || stack === "python" || stack === "go" || stack === "kotlin" || stack === "terraform" || stack === "ansible";
|
|
247160
|
+
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";
|
|
247161
|
+
}
|
|
247162
|
+
function preferredLibraryStack(stacks) {
|
|
247163
|
+
const uniqueStacks = uniqueInOrder2(stacks);
|
|
247164
|
+
if (uniqueStacks.length <= 1) {
|
|
247165
|
+
return isJvmLibraryStack(uniqueStacks[0]) ? "library_generic" : uniqueStacks[0];
|
|
247166
|
+
}
|
|
247167
|
+
if (uniqueStacks.some(isJvmLibraryStack) && uniqueStacks.every((candidate) => isJvmLibraryStack(candidate) || candidate === "node_typescript" || candidate === "node_javascript")) {
|
|
247168
|
+
return "library_generic";
|
|
247169
|
+
}
|
|
247170
|
+
return void 0;
|
|
247171
|
+
}
|
|
247172
|
+
function isJvmLibraryStack(stack) {
|
|
247173
|
+
return stack === "java" || stack === "spring";
|
|
246793
247174
|
}
|
|
246794
247175
|
function hasProjectKindEvidence(detection, patterns) {
|
|
246795
247176
|
const evidence = detection.projectKinds?.evidence ?? [];
|
|
@@ -247211,7 +247592,7 @@ function resolveStackSelections(detection, projectKinds) {
|
|
|
247211
247592
|
const libraryComponentStacks = uniqueInOrder2(
|
|
247212
247593
|
libraryComponents.map((component) => component.stack).filter((stack) => isGenericLibraryStack(stack))
|
|
247213
247594
|
);
|
|
247214
|
-
const selectedLibrary = detection.topology.topology === "monorepo" ? libraryComponentStacks
|
|
247595
|
+
const selectedLibrary = detection.topology.topology === "monorepo" ? preferredLibraryStack(libraryComponentStacks) : detection.stacks.selectedAdapterId;
|
|
247215
247596
|
if (isGenericLibraryStack(selectedLibrary)) {
|
|
247216
247597
|
selections.library = selectedLibrary;
|
|
247217
247598
|
}
|
|
@@ -247233,7 +247614,7 @@ function resolveProjectProfiles(detection, projectKinds, stackSelections, apiSty
|
|
|
247233
247614
|
selectedAdapterId: stackId,
|
|
247234
247615
|
selectedAdapterCategory: getStackAdapterById(stackId).category,
|
|
247235
247616
|
projectKinds: [kind],
|
|
247236
|
-
apiStyleHint: kind === "backend" && apiStyle ? apiStyle : resolveRoleApiStyleHint(detection, stackId, component),
|
|
247617
|
+
apiStyleHint: kind === "backend" && apiStyle ? apiStyle : stackId === "library_generic" ? void 0 : resolveRoleApiStyleHint(detection, stackId, component),
|
|
247237
247618
|
databaseHints: detection.toolingHints?.databaseHints,
|
|
247238
247619
|
toolingHints: detection.toolingHints?.toolingHints,
|
|
247239
247620
|
repoTopology: detection.topology.topology === "unknown" ? "single_project" : detection.topology.topology
|
|
@@ -249874,6 +250255,9 @@ function readFlagValue(args, flag) {
|
|
|
249874
250255
|
return value && value.length > 0 ? value : void 0;
|
|
249875
250256
|
}
|
|
249876
250257
|
async function readCliPackageVersion() {
|
|
250258
|
+
if ("0.2.5".trim().length > 0) {
|
|
250259
|
+
return "0.2.5".trim();
|
|
250260
|
+
}
|
|
249877
250261
|
const candidatePackageJsonPaths = [
|
|
249878
250262
|
path73.join(__dirname, "..", "package.json"),
|
|
249879
250263
|
path73.join(__dirname, "..", "..", "..", "..", "cli", "package.json")
|