pumuki 6.3.129 → 6.3.130
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/AGENTS.md +16 -1
- package/CHANGELOG.md +9 -0
- package/README.md +14 -10
- package/VERSION +1 -1
- package/core/facts/detectors/text/android.test.ts +2583 -24
- package/core/facts/detectors/text/android.ts +4633 -34
- package/core/facts/detectors/typescript/index.test.ts +3639 -73
- package/core/facts/detectors/typescript/index.ts +4819 -270
- package/core/facts/extractHeuristicFacts.ts +271 -6
- package/core/rules/presets/heuristics/android.test.ts +314 -1
- package/core/rules/presets/heuristics/android.ts +1220 -50
- package/core/rules/presets/heuristics/typescript.test.ts +158 -2
- package/core/rules/presets/heuristics/typescript.ts +508 -0
- package/docs/README.md +3 -3
- package/docs/operations/RELEASE_NOTES.md +7 -1
- package/docs/operations/framework-menu-consumer-walkthrough.md +18 -15
- package/docs/product/API_REFERENCE.md +1 -1
- package/docs/product/USAGE.md +1 -1
- package/docs/validation/README.md +3 -1
- package/integrations/config/skillsCompilerTemplates.test.ts +131 -0
- package/integrations/config/skillsCompilerTemplates.ts +953 -7
- package/integrations/config/skillsDetectorRegistry.ts +451 -8
- package/integrations/config/skillsMarkdownRules.ts +884 -2
- package/integrations/evidence/buildEvidence.ts +29 -1
- package/integrations/evidence/platformSummary.test.ts +73 -9
- package/integrations/evidence/platformSummary.ts +165 -7
- package/integrations/evidence/repoState.ts +3 -0
- package/integrations/evidence/schema.ts +18 -0
- package/integrations/evidence/trackingContract.ts +17 -0
- package/integrations/evidence/writeEvidence.test.ts +3 -0
- package/integrations/evidence/writeEvidence.ts +29 -1
- package/integrations/gate/evaluateAiGate.ts +251 -8
- package/integrations/gate/governanceActionCatalog.ts +275 -0
- package/integrations/gate/remediationCatalog.ts +8 -0
- package/integrations/git/runPlatformGate.ts +9 -1
- package/integrations/lifecycle/adapter.ts +24 -0
- package/integrations/lifecycle/bootstrapManifest.ts +248 -0
- package/integrations/lifecycle/cliGovernanceConsole.ts +69 -0
- package/integrations/lifecycle/governanceNextAction.ts +171 -0
- package/integrations/lifecycle/governanceObservationSnapshot.ts +369 -0
- package/integrations/lifecycle/packageInfo.ts +118 -1
- package/integrations/lifecycle/state.ts +8 -1
- package/integrations/lifecycle/trackingState.ts +403 -0
- package/integrations/lifecycle/watch.ts +1 -1
- package/integrations/mcp/aiGateCheck.ts +194 -10
- package/integrations/mcp/alignedPlatformGate.ts +232 -0
- package/integrations/mcp/enterpriseServer.ts +19 -3
- package/integrations/mcp/preFlightCheck.ts +66 -3
- package/integrations/mcp/readMcpPrePushStdin.ts +7 -0
- package/package.json +1 -1
- package/scripts/build-ruralgo-s1-evidence-pack.ts +85 -0
- package/scripts/check-tracking-single-active.sh +1 -1
- package/scripts/framework-menu-advanced-view-lib.ts +49 -0
- package/scripts/framework-menu-consumer-actions-lib.ts +32 -32
- package/scripts/framework-menu-consumer-preflight-render.ts +10 -0
- package/scripts/framework-menu-consumer-preflight-run.ts +23 -0
- package/scripts/framework-menu-consumer-preflight-types.ts +12 -0
- package/scripts/framework-menu-consumer-runtime-actions.ts +11 -5
- package/scripts/framework-menu-consumer-runtime-audit.ts +0 -28
- package/scripts/framework-menu-consumer-runtime-evidence-classic.ts +118 -42
- package/scripts/framework-menu-consumer-runtime-lib.ts +38 -0
- package/scripts/framework-menu-consumer-runtime-menu.ts +55 -15
- package/scripts/framework-menu-consumer-runtime-types.ts +4 -0
- package/scripts/framework-menu-evidence-summary-read.ts +17 -1
- package/scripts/framework-menu-evidence-summary-types.ts +3 -0
- package/scripts/framework-menu-layout-data.ts +3 -23
- package/scripts/framework-menu-system-notifications-macos-applescript-dialog.ts +1 -1
- package/scripts/framework-menu-system-notifications-macos-dialog-payload.ts +14 -2
- package/scripts/framework-menu-system-notifications-macos-swift-source.ts +1 -1
- package/scripts/framework-menu-system-notifications-payloads-blocked.ts +128 -4
- package/scripts/framework-menu-system-notifications-payloads.ts +8 -1
- package/scripts/framework-menu-system-notifications-text.ts +7 -1
- package/scripts/framework-menu.ts +37 -2
- package/scripts/package-install-smoke-consumer-git-repo-lib.ts +10 -1
- package/scripts/package-install-smoke-consumer-npm-lib.ts +46 -9
- package/scripts/ruralgo-s1-evidence-pack-lib.ts +200 -0
- package/skills.lock.json +613 -698
|
@@ -60,6 +60,13 @@ const isTypeScriptHeuristicTargetPath = (
|
|
|
60
60
|
);
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
+
const isTypeScriptFrontendPath = (path: string): boolean => {
|
|
64
|
+
if (!isTypeScriptHeuristicTargetPath(path)) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
return path.startsWith('apps/frontend/') || path.startsWith('apps/web/');
|
|
68
|
+
};
|
|
69
|
+
|
|
63
70
|
const isTypeScriptDomainOrApplicationPath = (path: string): boolean => {
|
|
64
71
|
if (!isTypeScriptHeuristicTargetPath(path)) {
|
|
65
72
|
return false;
|
|
@@ -99,6 +106,55 @@ const isAndroidSourcePath = (path: string): boolean => {
|
|
|
99
106
|
return isAndroidKotlinPath(path) || isAndroidJavaPath(path);
|
|
100
107
|
};
|
|
101
108
|
|
|
109
|
+
const isAndroidGradlePath = (path: string): boolean => {
|
|
110
|
+
const normalized = path.replace(/\\/g, '/').toLowerCase();
|
|
111
|
+
if (!normalized.startsWith('apps/android/')) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
normalized.endsWith('/build.gradle') ||
|
|
117
|
+
normalized.endsWith('/build.gradle.kts') ||
|
|
118
|
+
normalized.endsWith('.gradle') ||
|
|
119
|
+
normalized.endsWith('.gradle.kts')
|
|
120
|
+
);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const isAndroidVersionCatalogPath = (path: string): boolean => {
|
|
124
|
+
const normalized = path.replace(/\\/g, '/').toLowerCase();
|
|
125
|
+
return normalized.startsWith('apps/android/') && normalized.endsWith('libs.versions.toml');
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const isAndroidLocalizedStringsXmlPath = (path: string): boolean => {
|
|
129
|
+
const normalized = path.replace(/\\/g, '/').toLowerCase();
|
|
130
|
+
return (
|
|
131
|
+
normalized.startsWith('apps/android/') &&
|
|
132
|
+
/\/res\/values-[^/]+\/strings\.xml$/.test(normalized)
|
|
133
|
+
);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const isAndroidLocalizedPluralsXmlPath = (path: string): boolean => {
|
|
137
|
+
const normalized = path.replace(/\\/g, '/').toLowerCase();
|
|
138
|
+
return (
|
|
139
|
+
normalized.startsWith('apps/android/') &&
|
|
140
|
+
/\/res\/values-[^/]+\/plurals\.xml$/.test(normalized)
|
|
141
|
+
);
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const isAndroidInstrumentedTestPath = (path: string): boolean => {
|
|
145
|
+
const normalized = path.replace(/\\/g, '/').toLowerCase();
|
|
146
|
+
return normalized.startsWith('apps/android/') && normalized.includes('/androidtest/');
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const isAndroidJvmTestPath = (path: string): boolean => {
|
|
150
|
+
const normalized = path.replace(/\\/g, '/').toLowerCase();
|
|
151
|
+
return (
|
|
152
|
+
normalized.startsWith('apps/android/') &&
|
|
153
|
+
normalized.includes('/test/') &&
|
|
154
|
+
!normalized.includes('/androidtest/')
|
|
155
|
+
);
|
|
156
|
+
};
|
|
157
|
+
|
|
102
158
|
const isAndroidPresentationPath = (path: string): boolean => {
|
|
103
159
|
return isAndroidKotlinPath(path) && path.includes('/presentation/');
|
|
104
160
|
};
|
|
@@ -419,6 +475,10 @@ const astDetectorRegistry: ReadonlyArray<ASTDetectorRegistryEntry> = [
|
|
|
419
475
|
{ detect: TS.hasSetTimeoutStringCallback, ruleId: 'heuristics.ts.set-timeout-string.ast', code: 'HEURISTICS_SET_TIMEOUT_STRING_AST', message: 'AST heuristic detected setTimeout with a string callback.' },
|
|
420
476
|
{ detect: TS.hasSetIntervalStringCallback, ruleId: 'heuristics.ts.set-interval-string.ast', code: 'HEURISTICS_SET_INTERVAL_STRING_AST', message: 'AST heuristic detected setInterval with a string callback.' },
|
|
421
477
|
{ detect: TS.hasAsyncPromiseExecutor, ruleId: 'heuristics.ts.new-promise-async.ast', code: 'HEURISTICS_NEW_PROMISE_ASYNC_AST', message: 'AST heuristic detected async Promise executor usage.' },
|
|
478
|
+
{ detect: TS.hasCallbackHellPattern, ruleId: 'heuristics.ts.callback-hell.ast', code: 'HEURISTICS_CALLBACK_HELL_AST', message: 'AST heuristic detected callback hell / nested promise callback usage.' },
|
|
479
|
+
{ detect: TS.hasMagicNumberPattern, ruleId: 'heuristics.ts.magic-numbers.ast', code: 'HEURISTICS_MAGIC_NUMBERS_AST', message: 'AST heuristic detected magic number usage.' },
|
|
480
|
+
{ detect: TS.hasHardcodedValuePattern, ruleId: 'heuristics.ts.hardcoded-values.ast', code: 'HEURISTICS_HARDCODED_VALUES_AST', message: 'AST heuristic detected hardcoded config value usage.' },
|
|
481
|
+
{ detect: TS.hasEnvDefaultFallbackPattern, ruleId: 'heuristics.ts.env-default-fallback.ast', code: 'HEURISTICS_ENV_DEFAULT_FALLBACK_AST', message: 'AST heuristic detected environment default fallback usage.' },
|
|
422
482
|
{ detect: TS.hasWithStatement, ruleId: 'heuristics.ts.with-statement.ast', code: 'HEURISTICS_WITH_STATEMENT_AST', message: 'AST heuristic detected with-statement usage.' },
|
|
423
483
|
{ detect: TS.hasDeleteOperator, ruleId: 'heuristics.ts.delete-operator.ast', code: 'HEURISTICS_DELETE_OPERATOR_AST', message: 'AST heuristic detected delete-operator usage.' },
|
|
424
484
|
{ detect: TS.hasDebuggerStatement, ruleId: 'heuristics.ts.debugger.ast', code: 'HEURISTICS_DEBUGGER_AST', message: 'AST heuristic detected debugger statement usage.' },
|
|
@@ -428,7 +488,34 @@ const astDetectorRegistry: ReadonlyArray<ASTDetectorRegistryEntry> = [
|
|
|
428
488
|
{ detect: TS.hasOverrideMethodThrowingNotImplemented, ruleId: 'heuristics.ts.solid.lsp.override-not-implemented.ast', code: 'HEURISTICS_SOLID_LSP_OVERRIDE_NOT_IMPLEMENTED_AST', message: 'AST heuristic detected LSP risk: override throws not-implemented/unsupported.' },
|
|
429
489
|
{ detect: TS.hasFrameworkDependencyImport, ruleId: 'heuristics.ts.solid.dip.framework-import.ast', code: 'HEURISTICS_SOLID_DIP_FRAMEWORK_IMPORT_AST', message: 'AST heuristic detected DIP risk: framework dependency imported in domain/application code.', pathCheck: isTypeScriptDomainOrApplicationPath },
|
|
430
490
|
{ detect: TS.hasConcreteDependencyInstantiation, ruleId: 'heuristics.ts.solid.dip.concrete-instantiation.ast', code: 'HEURISTICS_SOLID_DIP_CONCRETE_INSTANTIATION_AST', message: 'AST heuristic detected DIP risk: direct instantiation of concrete framework dependency.', pathCheck: isTypeScriptDomainOrApplicationPath },
|
|
491
|
+
{ detect: (ast) => TS.findCleanArchitectureMatch(ast) !== undefined, ruleId: 'heuristics.ts.clean-architecture.ast', code: 'HEURISTICS_CLEAN_ARCHITECTURE_AST', message: 'AST heuristic detected clean architecture dependency direction risk in domain/application code.', pathCheck: isTypeScriptDomainOrApplicationPath },
|
|
492
|
+
{ detect: TS.hasProductionMockCall, ruleId: 'heuristics.ts.production-mock.ast', code: 'HEURISTICS_PRODUCTION_MOCK_AST', message: 'AST heuristic detected production mock usage in backend runtime code.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
493
|
+
{ detect: TS.hasExceptionFilterClass, ruleId: 'heuristics.ts.exception-filter.ast', code: 'HEURISTICS_EXCEPTION_FILTER_AST', message: 'AST heuristic detected global exception filter usage in backend runtime code.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
494
|
+
{ detect: TS.hasGuardUseGuardsJwtAuthGuard, ruleId: 'heuristics.ts.guards-useguards-jwtauthguard.ast', code: 'HEURISTICS_GUARDS_USEGUARDS_JWTAUTHGUARD_AST', message: 'AST heuristic detected @UseGuards(JwtAuthGuard) usage in backend runtime code.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
495
|
+
{ detect: TS.hasUseInterceptorsLoggingTransform, ruleId: 'heuristics.ts.interceptors-useinterceptors-logging-transform.ast', code: 'HEURISTICS_INTERCEPTORS_USEINTERCEPTORS_LOGGING_TRANSFORM_AST', message: 'AST heuristic detected @UseInterceptors logging/transform usage in backend runtime code.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
496
|
+
{ detect: TS.hasSensitiveLogCall, ruleId: 'heuristics.ts.no-sensitive-log.ast', code: 'HEURISTICS_NO_SENSITIVE_LOG_AST', message: 'AST heuristic detected sensitive data emitted to backend logs.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
497
|
+
{ detect: TS.hasCorrelationIdsPattern, ruleId: 'heuristics.ts.correlation-ids.ast', code: 'HEURISTICS_CORRELATION_IDS_AST', message: 'AST heuristic detected correlation IDs propagation in backend runtime code.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
498
|
+
{ detect: TS.hasCorsConfiguredPattern, ruleId: 'heuristics.ts.cors-configured.ast', code: 'HEURISTICS_CORS_CONFIGURED_AST', message: 'AST heuristic detected backend CORS configuration with allowed origins.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
499
|
+
{ detect: TS.hasValidationPipeGlobalPattern, ruleId: 'heuristics.ts.validationpipe-global.ast', code: 'HEURISTICS_VALIDATIONPIPE_GLOBAL_AST', message: 'AST heuristic detected global ValidationPipe configuration with whitelist enabled.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
500
|
+
{ detect: TS.hasApiVersioningPattern, ruleId: 'heuristics.ts.versionado-api-v1-api-v2.ast', code: 'HEURISTICS_VERSIONADO_API_V1_API_V2_AST', message: 'AST heuristic detected backend API versioning through versioned NestJS controllers.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
501
|
+
{ detect: TS.hasValidationConfigPattern, ruleId: 'heuristics.ts.validation-config.ast', code: 'HEURISTICS_VALIDATION_CONFIG_AST', message: 'AST heuristic detected backend config validation in ConfigModule.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
502
|
+
{ detect: TS.hasClassValidatorDecoratorsPattern, ruleId: 'heuristics.ts.class-validator-decorators.ast', code: 'HEURISTICS_CLASS_VALIDATOR_DECORATORS_AST', message: 'AST heuristic detected class-validator decorator usage in backend DTOs.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
503
|
+
{ detect: TS.hasClassTransformerDecoratorsPattern, ruleId: 'heuristics.ts.class-transformer-decorators.ast', code: 'HEURISTICS_CLASS_TRANSFORMER_DECORATORS_AST', message: 'AST heuristic detected class-transformer decorator usage in backend DTOs.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
504
|
+
{ detect: TS.hasInputValidationPattern, ruleId: 'heuristics.ts.input-validation-siempre-validar-con-dtos.ast', code: 'HEURISTICS_INPUT_VALIDATION_SIEMPRE_VALIDAR_CON_DTOS_AST', message: 'AST heuristic detected backend controller input DTO validation through typed NestJS route parameters.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
505
|
+
{ detect: TS.hasNestedValidationPattern, ruleId: 'heuristics.ts.nested-validation-validatenested-type.ast', code: 'HEURISTICS_NESTED_VALIDATION_VALIDATENESTED_TYPE_AST', message: 'AST heuristic detected backend nested DTO validation through @ValidateNested() and @Type().', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
506
|
+
{ detect: TS.hasDtoBoundaryPattern, ruleId: 'heuristics.ts.dtos-en-boundaries-validacio-n-en-entrada-salida.ast', code: 'HEURISTICS_DTOS_EN_BOUNDARIES_VALIDACIO_N_EN_ENTRADA_SALIDA_AST', message: 'AST heuristic detected backend DTO boundary classes with explicit contract boundaries.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
507
|
+
{ detect: TS.hasSeparatedDtoPattern, ruleId: 'heuristics.ts.dtos-separados-createorderdto-updateorderdto-orderresponsedto.ast', code: 'HEURISTICS_DTOS_SEPARADOS_CREATEORDERDTO_UPDATEORDERDTO_ORDERRESPONSEDTO_AST', message: 'AST heuristic detected backend DTO classes split into create, update and response contracts.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
508
|
+
{ detect: TS.hasBackendReturnDtosExposureUsage, locateLines: TS.findBackendReturnDtosExposureLines, ruleId: 'heuristics.ts.return-dtos-no-exponer-entidades-directamente.ast', code: 'HEURISTICS_TS_RETURN_DTOS_NO_EXPONER_ENTIDADES_DIRECTAMENTE_AST', message: 'AST heuristic detected backend code returning entities directly instead of DTOs.', pathCheck: (path) => path.startsWith('apps/backend/'), excludePaths: [isTestPath] },
|
|
509
|
+
{ detect: TS.hasBackendCriticalTransactionsUsage, locateLines: TS.findBackendCriticalTransactionsLines, ruleId: 'heuristics.ts.transacciones-para-operaciones-cri-ticas.ast', code: 'HEURISTICS_TS_TRANSACCIONES_PARA_OPERACIONES_CRI_TICAS_AST', message: 'AST heuristic detected backend transaction usage for critical operations.', pathCheck: (path) => path.startsWith('apps/backend/'), excludePaths: [isTestPath] },
|
|
510
|
+
{ detect: TS.hasBackendMultiTableTransactionsUsage, locateLines: TS.findBackendMultiTableTransactionsLines, ruleId: 'heuristics.ts.transacciones-para-operaciones-multi-tabla.ast', code: 'HEURISTICS_TS_TRANSACCIONES_PARA_OPERACIONES_MULTI_TABLA_AST', message: 'AST heuristic detected backend transaction usage for multi-table operations.', pathCheck: (path) => path.startsWith('apps/backend/'), excludePaths: [isTestPath] },
|
|
511
|
+
{ detect: TS.hasPrometheusMetricsPattern, ruleId: 'heuristics.ts.prometheus-prom-client.ast', code: 'HEURISTICS_PROMETHEUS_PROM_CLIENT_AST', message: 'AST heuristic detected Prometheus metrics instrumentation via prom-client.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
512
|
+
{ detect: TS.hasPasswordHashingPattern, ruleId: 'heuristics.ts.password-hashing-bcrypt-salt-rounds-10.ast', code: 'HEURISTICS_PASSWORD_HASHING_BCRYPT_SALT_ROUNDS_10_AST', message: 'AST heuristic detected weak bcrypt salt rounds.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
513
|
+
{ detect: TS.hasRateLimitingThrottlerPattern, ruleId: 'heuristics.ts.rate-limiting-throttler.ast', code: 'HEURISTICS_RATE_LIMITING_THROTTLER_AST', message: 'AST heuristic detected NestJS throttler rate limiting.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
514
|
+
{ detect: TS.hasWinstonStructuredLoggerPattern, ruleId: 'heuristics.ts.winston-structured-json-logger.ast', code: 'HEURISTICS_WINSTON_STRUCTURED_JSON_LOGGER_AST', message: 'AST heuristic detected Winston structured JSON logger usage.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
515
|
+
{ detect: TS.hasErrorLoggingFullContextPattern, ruleId: 'heuristics.ts.error-logging-full-context.ast', code: 'HEURISTICS_ERROR_LOGGING_FULL_CONTEXT_AST', message: 'AST heuristic detected backend error logging without full context.', pathCheck: (path) => path.startsWith('apps/backend/') },
|
|
431
516
|
{ detect: TS.hasLargeClassDeclaration, ruleId: 'heuristics.ts.god-class-large-class.ast', code: 'HEURISTICS_GOD_CLASS_LARGE_CLASS_AST', message: 'AST heuristic detected God Class candidate by mixed responsibility nodes in a single class declaration.' },
|
|
517
|
+
{ detect: TS.hasReactClassComponentUsage, locateLines: TS.findReactClassComponentLines, ruleId: 'heuristics.ts.react-class-component.ast', code: 'HEURISTICS_TS_REACT_CLASS_COMPONENT_AST', message: 'AST heuristic detected React class component usage in frontend production code where functional components are required.', pathCheck: isTypeScriptFrontendPath },
|
|
518
|
+
{ detect: TS.hasSingletonPattern, ruleId: 'heuristics.ts.singleton-pattern.ast', code: 'HEURISTICS_SINGLETON_PATTERN_AST', message: 'AST heuristic detected singleton pattern usage in a class declaration.' },
|
|
432
519
|
{ detect: TS.hasRecordStringUnknownType, locateLines: TS.findRecordStringUnknownTypeLines, ruleId: 'common.types.record_unknown_requires_type', code: 'COMMON_TYPES_RECORD_UNKNOWN_REQUIRES_TYPE_AST', message: 'AST heuristic detected Record<string, unknown> without explicit value union.' },
|
|
433
520
|
{ detect: TS.hasUnknownWithoutGuard, locateLines: TS.findUnknownWithoutGuardLines, ruleId: 'common.types.unknown_without_guard', code: 'COMMON_TYPES_UNKNOWN_WITHOUT_GUARD_AST', message: 'AST heuristic detected unknown usage without explicit guard evidence.', pathCheck: isTypeScriptDomainOrApplicationPath },
|
|
434
521
|
{ detect: TS.hasUndefinedInBaseTypeUnion, locateLines: TS.findUndefinedInBaseTypeUnionLines, ruleId: 'common.types.undefined_in_base_type', code: 'COMMON_TYPES_UNDEFINED_IN_BASE_TYPE_AST', message: 'AST heuristic detected undefined inside base-type unions.' },
|
|
@@ -654,6 +741,41 @@ const textDetectorRegistry: ReadonlyArray<TextDetectorRegistryEntry> = [
|
|
|
654
741
|
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasKotlinThreadSleepCall, ruleId: 'heuristics.android.thread-sleep.ast', code: 'HEURISTICS_ANDROID_THREAD_SLEEP_AST', message: 'AST heuristic detected Thread.sleep usage in production Kotlin code.' },
|
|
655
742
|
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasKotlinGlobalScopeUsage, ruleId: 'heuristics.android.globalscope.ast', code: 'HEURISTICS_ANDROID_GLOBAL_SCOPE_AST', message: 'AST heuristic detected GlobalScope coroutine usage in production Kotlin code.' },
|
|
656
743
|
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasKotlinRunBlockingUsage, ruleId: 'heuristics.android.run-blocking.ast', code: 'HEURISTICS_ANDROID_RUN_BLOCKING_AST', message: 'AST heuristic detected runBlocking usage in production Kotlin code.' },
|
|
744
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidCoroutineCallbackUsage, ruleId: 'heuristics.android.coroutines-async-await-no-callbacks.ast', code: 'HEURISTICS_ANDROID_COROUTINES_ASYNC_AWAIT_NO_CALLBACKS_AST', message: 'AST heuristic detected callback-based asynchronous work in Android production code where coroutines or Flow should be used.' },
|
|
745
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidAsyncAwaitParallelismUsage, ruleId: 'heuristics.android.async-await-paralelismo.ast', code: 'HEURISTICS_ANDROID_ASYNC_AWAIT_PARALELISMO_AST', message: 'AST heuristic detected async/await parallelism in Android production code.' },
|
|
746
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidSuspendFunctionsApiServiceUsage, ruleId: 'heuristics.android.suspend-functions-en-api-service.ast', code: 'HEURISTICS_ANDROID_SUSPEND_FUNCTIONS_EN_API_SERVICE_AST', message: 'AST heuristic detected suspend functions in Android API service production code.' },
|
|
747
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidSuspendFunctionsAsyncUsage, ruleId: 'heuristics.android.suspend-functions-para-operaciones-async.ast', code: 'HEURISTICS_ANDROID_SUSPEND_FUNCTIONS_PARA_OPERACIONES_ASYNC_AST', message: 'AST heuristic detected suspend functions in Android production code where async operations should remain explicit.' },
|
|
748
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidDaoSuspendFunctionsUsage, ruleId: 'heuristics.android.dao-data-access-objects-con-suspend-functions.ast', code: 'HEURISTICS_ANDROID_DAO_DATA_ACCESS_OBJECTS_CON_SUSPEND_FUNCTIONS_AST', message: 'AST heuristic detected suspend functions in Android DAO production code.' },
|
|
749
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidTransactionUsage, ruleId: 'heuristics.android.transaction-para-operaciones-multi-query.ast', code: 'HEURISTICS_ANDROID_TRANSACTION_PARA_OPERACIONES_MULTI_QUERY_AST', message: 'AST heuristic detected @Transaction usage in Android DAO production code.' },
|
|
750
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidStateFlowUsage, ruleId: 'heuristics.android.stateflow-estado-mutable-observable.ast', code: 'HEURISTICS_ANDROID_STATEFLOW_ESTADO_MUTABLE_OBSERVABLE_AST', message: 'AST heuristic detected StateFlow usage in Android ViewModel production code where observable state should remain explicit.' },
|
|
751
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidSingleSourceOfTruthUsage, ruleId: 'heuristics.android.single-source-of-truth-viewmodel-es-la-fuente.ast', code: 'HEURISTICS_ANDROID_SINGLE_SOURCE_OF_TRUTH_VIEWMODEL_ES_LA_FUENTE_AST', message: 'AST heuristic detected single source of truth state exposure in Android ViewModel production code where observable state should remain explicit and owned by one ViewModel.' },
|
|
752
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidSharedFlowUsage, ruleId: 'heuristics.android.sharedflow-hot-stream-puede-no-tener-valor-para-eventos.ast', code: 'HEURISTICS_ANDROID_SHAREDFLOW_HOT_STREAM_PUEDE_NO_TENER_VALOR_PARA_EVENTOS_AST', message: 'AST heuristic detected SharedFlow usage in Android production code where events should remain explicit.' },
|
|
753
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidFlowBuilderUsage, ruleId: 'heuristics.android.flow-builders-flow-emit-flowof-asflow.ast', code: 'HEURISTICS_ANDROID_FLOW_BUILDERS_FLOW_EMIT_FLOWOF_ASFLOW_AST', message: 'AST heuristic detected Flow builder usage in Android production code where reactive streams should remain explicit.' },
|
|
754
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidFlowCollectUsage, ruleId: 'heuristics.android.collect-terminal-operator-para-consumir-flow.ast', code: 'HEURISTICS_ANDROID_COLLECT_TERMINAL_OPERATOR_PARA_CONSUMIR_FLOW_AST', message: 'AST heuristic detected Flow terminal operator usage in Android production code where streams should be consumed explicitly.' },
|
|
755
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidCollectAsStateUsage, ruleId: 'heuristics.android.collect-as-state-consumir-flow-en-compose.ast', code: 'HEURISTICS_ANDROID_COLLECT_AS_STATE_CONSUMIR_FLOW_EN_COMPOSE_AST', message: 'AST heuristic detected collectAsState usage in Android Compose production code where Flow should be observed as UI state.' },
|
|
756
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidRememberUsage, ruleId: 'heuristics.android.remember-evitar-recrear-objetos.ast', code: 'HEURISTICS_ANDROID_REMEMBER_EVITAR_RECREAR_OBJETOS_AST', message: 'AST heuristic detected remember usage in Android Compose production code where objects or values should not be recreated on every recomposition.' },
|
|
757
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidRememberUsage, ruleId: 'heuristics.android.remember-para-mantener-estado-entre-recomposiciones.ast', code: 'HEURISTICS_ANDROID_REMEMBER_PARA_MANTENER_ESTADO_ENTRE_RECOMPOSICIONES_AST', message: 'AST heuristic detected remember usage in Android Compose production code where state should remain stable across recompositions.' },
|
|
758
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidRepositoryPatternUsage, ruleId: 'heuristics.android.repository-pattern-abstraer-acceso-a-datos.ast', code: 'HEURISTICS_ANDROID_REPOSITORY_PATTERN_ABSTRAER_ACCESO_A_DATOS_AST', message: 'AST heuristic detected repository abstraction in Android production code where data access should remain behind a stable boundary.' },
|
|
759
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidDerivedStateOfUsage, ruleId: 'heuristics.android.derivedstateof-ca-lculos-caros-solo-cuando-cambia-input.ast', code: 'HEURISTICS_ANDROID_DERIVEDSTATEOF_CALCULOS_CAROS_SOLO_CUANDO_CAMBIA_INPUT_AST', message: 'AST heuristic detected derivedStateOf usage in Android Compose production code where expensive derived values should only recompute when input changes.' },
|
|
760
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidDerivedStateOfUsage, ruleId: 'heuristics.android.derivedstateof-ca-lculos-derivados-de-state.ast', code: 'HEURISTICS_ANDROID_DERIVEDSTATEOF_CALCULOS_DERIVADOS_DE_STATE_AST', message: 'AST heuristic detected derivedStateOf usage in Android Compose production code where state-derived values should stay explicit and local to Compose.' },
|
|
761
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidLaunchedEffectUsage, ruleId: 'heuristics.android.launchedeffect-side-effects-con-lifecycle.ast', code: 'HEURISTICS_ANDROID_LAUNCHEDEFFECT_SIDE_EFFECTS_CON_LIFECYCLE_AST', message: 'AST heuristic detected LaunchedEffect usage in Android Compose production code where lifecycle-bound side effects should remain explicit.' },
|
|
762
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidLaunchedEffectKeysUsage, ruleId: 'heuristics.android.launchedeffect-keys-controlar-cuando-se-relanza-effect.ast', code: 'HEURISTICS_ANDROID_LAUNCHEDEFFECT_KEYS_CONTROLAR_CUANDO_SE_RELANZA_EFFECT_AST', message: 'AST heuristic detected LaunchedEffect keys usage in Android Compose production code where relaunch keys should remain explicit and stable.' },
|
|
763
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidDisposableEffectUsage, ruleId: 'heuristics.android.disposableeffect-cleanup-cuando-composable-sale-de-composicio-n.ast', code: 'HEURISTICS_ANDROID_DISPOSABLE_EFFECT_CLEANUP_CUANDO_COMPOSABLE_SALE_DE_COMPOSICIO_N_AST', message: 'AST heuristic detected DisposableEffect usage in Android Compose production code where cleanup should run when the composable leaves composition.' },
|
|
764
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidPreviewUsage, ruleId: 'heuristics.android.preview-preview-para-ver-ui-sin-correr-app.ast', code: 'HEURISTICS_ANDROID_PREVIEW_PREVIEW_PARA_VER_UI_SIN_CORRER_APP_AST', message: 'AST heuristic detected @Preview usage in Android Compose production code where UI should be inspectable without running the app.' },
|
|
765
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidAdaptiveLayoutsUsage, ruleId: 'heuristics.android.adaptive-layouts-responsive-design-windowsizeclass.ast', code: 'HEURISTICS_ANDROID_ADAPTIVE_LAYOUTS_RESPONSIVE_DESIGN_WINDOW_SIZE_CLASS_AST', message: 'AST heuristic detected WindowSizeClass usage in Android Compose production code where the layout should adapt to the available window size.' },
|
|
766
|
+
{ platform: 'android', pathCheck: isAndroidSourcePath, excludePaths: [isKotlinTestPath, isJavaTestPath], detect: TextAndroid.hasAndroidExistingStructureUsage, ruleId: 'heuristics.android.analizar-estructura-existente-mo-dulos-interfaces-dependencias-gradle.ast', code: 'HEURISTICS_ANDROID_ANALIZAR_ESTRUCTURA_EXISTENTE_MO_DULOS_INTERFACES_DEPENDENCIAS_GRADLE_AST', message: 'AST heuristic detected Android structure usage where existing modules, interfaces and dependencies should be reviewed before introducing changes.' },
|
|
767
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidThemeUsage, ruleId: 'heuristics.android.theme-color-scheme-typography-shapes.ast', code: 'HEURISTICS_ANDROID_THEME_COLOR_SCHEME_TYPOGRAPHY_SHAPES_AST', message: 'AST heuristic detected MaterialTheme usage in Android Compose production code where theme configuration should remain explicit.' },
|
|
768
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidDarkThemeUsage, ruleId: 'heuristics.android.dark-theme-soportar-desde-di-a-1-issystemindarktheme.ast', code: 'HEURISTICS_ANDROID_DARK_THEME_SOPORTAR_DESDE_DI_A_1_ISSYSTEMINDARKTHEME_AST', message: 'AST heuristic detected explicit dark theme support in Android Compose production code where the UI should respect the system color scheme from day one.' },
|
|
769
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidTextScalingUsage, ruleId: 'heuristics.android.text-scaling-soportar-font-scaling-del-sistema.ast', code: 'HEURISTICS_ANDROID_TEXT_SCALING_SOPORTAR_FONT_SCALING_DEL_SISTEMA_AST', message: 'AST heuristic detected text scaling support in Android Compose production code where the UI should respect the system font scale and remain readable with accessibility settings.' },
|
|
770
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidAccessibilityUsage, ruleId: 'heuristics.android.accessibility-semantics-contentdescription.ast', code: 'HEURISTICS_ANDROID_ACCESSIBILITY_SEMANTICS_CONTENTDESCRIPTION_AST', message: 'AST heuristic detected accessibility semantics/contentDescription usage in Android Compose production code where the UI should remain accessible to screen readers and assistive technologies.' },
|
|
771
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidContentDescriptionUsage, ruleId: 'heuristics.android.contentdescription-para-ima-genes-y-botones.ast', code: 'HEURISTICS_ANDROID_CONTENTDESCRIPTION_PARA_IMAGENES_Y_BOTONES_AST', message: 'AST heuristic detected contentDescription usage in Android Compose production code where images and buttons should remain accessible to screen readers and assistive technologies.' },
|
|
772
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidTalkBackUsage, ruleId: 'heuristics.android.talkback-screen-reader-de-android.ast', code: 'HEURISTICS_ANDROID_TALKBACK_SCREEN_READER_DE_ANDROID_AST', message: 'AST heuristic detected TalkBack-related accessibility usage in Android Compose production code where the UI should remain accessible to screen readers.' },
|
|
773
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidRecompositionUsage, ruleId: 'heuristics.android.recomposition-composables-deben-ser-idempotentes.ast', code: 'HEURISTICS_ANDROID_RECOMPOSITION_COMPOSABLES_DEBEN_SER_IDEMPOTENTES_AST', message: 'AST heuristic detected non-idempotent Compose recomposition behavior in Android production code where composables should remain pure during recomposition.' },
|
|
774
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidUiStateUsage, ruleId: 'heuristics.android.uistate-sealed-class-loading-success-error-states.ast', code: 'HEURISTICS_ANDROID_UISTATE_SEALED_CLASS_LOADING_SUCCESS_ERROR_STATES_AST', message: 'AST heuristic detected UiState sealed class usage in Android production code where loading, success, and error states should stay explicit.' },
|
|
775
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidUseCaseUsage, ruleId: 'heuristics.android.use-cases-lo-gica-de-negocio-encapsulada.ast', code: 'HEURISTICS_ANDROID_USE_CASES_LOGICA_DE_NEGOCIO_ENCAPSULADA_AST', message: 'AST heuristic detected Android UseCase usage in production code where business logic should stay encapsulated.' },
|
|
776
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidStateHoistingUsage, ruleId: 'heuristics.android.state-hoisting-elevar-estado-al-nivel-apropiado.ast', code: 'HEURISTICS_ANDROID_STATE_HOISTING_ELEVAR_ESTADO_AL_NIVEL_APROPIADO_AST', message: 'AST heuristic detected state hoisting issues in Android Compose production code where UI state should be elevated to the appropriate owner.' },
|
|
777
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidViewModelUsage, ruleId: 'heuristics.android.viewmodel-androidx-lifecycle-viewmodel.ast', code: 'HEURISTICS_ANDROID_VIEWMODEL_ANDROIDX_LIFECYCLE_VIEWMODEL_AST', message: 'AST heuristic detected AndroidX ViewModel usage in Android production code.' },
|
|
778
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidViewModelUsage, ruleId: 'heuristics.android.viewmodel-sobrevive-configuration-changes.ast', code: 'HEURISTICS_ANDROID_VIEWMODEL_SOBREVIVE_CONFIGURATION_CHANGES_AST', message: 'AST heuristic detected AndroidX ViewModel usage in Android production code that should survive configuration changes.' },
|
|
657
779
|
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasKotlinForceUnwrapUsage, ruleId: 'heuristics.android.force-unwrap.ast', code: 'HEURISTICS_ANDROID_FORCE_UNWRAP_AST', message: 'AST heuristic detected Kotlin force unwrap (!!) usage in production code.' },
|
|
658
780
|
{ platform: 'android', pathCheck: isAndroidJavaPath, excludePaths: [isJavaTestPath], detect: TextAndroid.hasAndroidJavaSourceCode, ruleId: 'heuristics.android.java-source.ast', code: 'HEURISTICS_ANDROID_JAVA_SOURCE_AST', message: 'AST heuristic detected Java source in Android production code where Kotlin is required for new code.' },
|
|
659
781
|
{ platform: 'android', pathCheck: isAndroidSourcePath, excludePaths: [isKotlinTestPath, isJavaTestPath], detect: TextAndroid.hasAndroidAsyncTaskUsage, ruleId: 'heuristics.android.asynctask-deprecated.ast', code: 'HEURISTICS_ANDROID_ASYNCTASK_DEPRECATED_AST', message: 'AST heuristic detected AsyncTask usage in Android production code where Coroutines are required.' },
|
|
@@ -662,9 +784,39 @@ const textDetectorRegistry: ReadonlyArray<TextDetectorRegistryEntry> = [
|
|
|
662
784
|
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidDispatcherUsage, ruleId: 'heuristics.android.dispatchers-main-ui-io-network-disk-default-cpu.ast', code: 'HEURISTICS_ANDROID_DISPATCHERS_MAIN_UI_IO_NETWORK_DISK_DEFAULT_CPU_AST', message: 'AST heuristic detected explicit Dispatchers.Main/IO/Default usage in Android production code where dispatcher selection must remain intentional.' },
|
|
663
785
|
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidWithContextUsage, ruleId: 'heuristics.android.withcontext-change-dispatcher.ast', code: 'HEURISTICS_ANDROID_WITHCONTEXT_CHANGE_DISPATCHER_AST', message: 'AST heuristic detected withContext usage in Android production code where dispatcher switching is intentional.' },
|
|
664
786
|
{ platform: 'android', pathCheck: isAndroidSourcePath, excludePaths: [isKotlinTestPath, isJavaTestPath], detect: TextAndroid.hasAndroidNoConsoleLogUsage, ruleId: 'heuristics.android.no-console-log.ast', code: 'HEURISTICS_ANDROID_NO_CONSOLE_LOG_AST', message: 'AST heuristic detected Android logging usage in production code without a debug-only guard.' },
|
|
787
|
+
{ platform: 'android', pathCheck: isAndroidSourcePath, excludePaths: [isKotlinTestPath, isJavaTestPath], detect: TextAndroid.hasAndroidTimberUsage, ruleId: 'heuristics.android.timber-logging-library.ast', code: 'HEURISTICS_ANDROID_TIMBER_LOGGING_LIBRARY_AST', message: 'AST heuristic detected Timber logging usage in Android production code.' },
|
|
788
|
+
{ platform: 'android', pathCheck: isAndroidSourcePath, excludePaths: [isKotlinTestPath, isJavaTestPath], detect: TextAndroid.hasAndroidTouchTargetsUsage, ruleId: 'heuristics.android.touch-targets-mi-nimo-48dp.ast', code: 'HEURISTICS_ANDROID_TOUCH_TARGETS_MI_NIMO_48DP_AST', message: 'AST heuristic detected minimum touch target usage in Android production Compose code.' },
|
|
789
|
+
{ platform: 'android', pathCheck: isAndroidSourcePath, excludePaths: [isKotlinTestPath, isJavaTestPath], detect: TextAndroid.hasAndroidBuildConfigConstantUsage, ruleId: 'heuristics.android.buildconfig-constantes-en-tiempo-de-compilacio-n.ast', code: 'HEURISTICS_ANDROID_BUILDCONFIG_CONSTANTES_EN_TIEMPO_DE_COMPILACION_AST', message: 'AST heuristic detected Android BuildConfig constant usage in production code.' },
|
|
665
790
|
{ platform: 'android', pathCheck: isAndroidSourcePath, excludePaths: [isKotlinTestPath, isJavaTestPath], detect: TextAndroid.hasAndroidHardcodedStringUsage, ruleId: 'heuristics.android.hardcoded-strings.ast', code: 'HEURISTICS_ANDROID_HARDCODED_STRINGS_AST', message: 'AST heuristic detected hardcoded string literal usage in Android production code where strings.xml should be used.' },
|
|
791
|
+
{ platform: 'android', pathCheck: isAndroidLocalizedStringsXmlPath, excludePaths: [], detect: TextAndroid.hasAndroidStringsXmlUsage, ruleId: 'heuristics.android.localization-strings-xml-por-idioma-values-es-values-en.ast', code: 'HEURISTICS_ANDROID_LOCALIZATION_STRINGS_XML_POR_IDIOMA_VALUES_ES_VALUES_EN_AST', message: 'AST heuristic detected localized strings.xml resources in Android production code where language-specific text should remain in values-*/strings.xml.' },
|
|
792
|
+
{ platform: 'android', pathCheck: isAndroidLocalizedStringsXmlPath, excludePaths: [], detect: TextAndroid.hasAndroidStringFormattingUsage, ruleId: 'heuristics.android.string-formatting-1-s-2-d-para-argumentos.ast', code: 'HEURISTICS_ANDROID_STRING_FORMATTING_1_S_2_D_PARA_ARGUMENTOS_AST', message: 'AST heuristic detected positional string formatting placeholders in Android strings.xml resources where argument order should remain explicit and translation-safe.' },
|
|
793
|
+
{ platform: 'android', pathCheck: isAndroidLocalizedPluralsXmlPath, excludePaths: [], detect: TextAndroid.hasAndroidPluralsXmlUsage, ruleId: 'heuristics.android.plurals-values-plurals-xml.ast', code: 'HEURISTICS_ANDROID_PLURALS_VALUES_PLURALS_XML_AST', message: 'AST heuristic detected plurals.xml resources in Android production code where quantity strings should remain explicit.' },
|
|
666
794
|
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidSingletonUsage, ruleId: 'heuristics.android.no-singleton.ast', code: 'HEURISTICS_ANDROID_NO_SINGLETON_AST', message: 'AST heuristic detected Kotlin singleton object or companion singleton holder usage in Android production code where Hilt or Dagger DI should be used.' },
|
|
795
|
+
{ platform: 'android', pathCheck: isAndroidGradlePath, excludePaths: [], detect: TextAndroid.hasAndroidHiltDependencyUsage, ruleId: 'heuristics.android.hilt-com-google-dagger-hilt-android.ast', code: 'HEURISTICS_ANDROID_HILT_COM_GOOGLE_DAGGER_HILT_ANDROID_AST', message: 'AST heuristic detected Hilt Gradle dependency usage in Android build files.' },
|
|
796
|
+
{ platform: 'android', pathCheck: isAndroidInstrumentedTestPath, excludePaths: [], detect: TextAndroid.hasAndroidInstrumentedTestUsage, ruleId: 'heuristics.android.androidtest-instrumented-tests-device-emulator.ast', code: 'HEURISTICS_ANDROID_ANDROIDTEST_INSTRUMENTED_TESTS_DEVICE_EMULATOR_AST', message: 'AST heuristic detected Android instrumented tests in androidTest/ where device/emulator coverage should remain explicit.' },
|
|
797
|
+
{ platform: 'android', pathCheck: isKotlinTestPath, excludePaths: [], detect: TextAndroid.hasAndroidAaaPatternUsage, ruleId: 'heuristics.android.aaa-pattern-arrange-act-assert.ast', code: 'HEURISTICS_ANDROID_AAA_PATTERN_ARRANGE_ACT_ASSERT_AST', message: 'AST heuristic detected AAA test structure in Android tests where Arrange, Act, and Assert should remain explicit.' },
|
|
798
|
+
{ platform: 'android', pathCheck: isKotlinTestPath, excludePaths: [], detect: TextAndroid.hasAndroidGivenWhenThenUsage, ruleId: 'heuristics.android.given-when-then-bdd-style.ast', code: 'HEURISTICS_ANDROID_GIVEN_WHEN_THEN_BDD_STYLE_AST', message: 'AST heuristic detected Given-When-Then test structure in Android tests where behavior should remain explicit.' },
|
|
799
|
+
{ platform: 'android', pathCheck: isAndroidJvmTestPath, excludePaths: [], detect: TextAndroid.hasAndroidJvmUnitTestUsage, ruleId: 'heuristics.android.test-unit-tests-jvm.ast', code: 'HEURISTICS_ANDROID_TEST_UNIT_TESTS_JVM_AST', message: 'AST heuristic detected JVM unit tests in Android test/ source set where local unit tests should remain explicit.' },
|
|
800
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidHiltFrameworkUsage, ruleId: 'heuristics.android.hilt-di-framework-no-manual-factories.ast', code: 'HEURISTICS_ANDROID_HILT_DI_FRAMEWORK_NO_MANUAL_FACTORIES_AST', message: 'AST heuristic detected Hilt DI framework usage instead of manual factories in Android production code.' },
|
|
801
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidHiltAndroidAppUsage, ruleId: 'heuristics.android.hiltandroidapp-application-class.ast', code: 'HEURISTICS_ANDROID_HILTANDROIDAPP_APPLICATION_CLASS_AST', message: 'AST heuristic detected @HiltAndroidApp usage in Android production code.' },
|
|
802
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidAndroidEntryPointUsage, ruleId: 'heuristics.android.androidentrypoint-activity-fragment-viewmodel.ast', code: 'HEURISTICS_ANDROID_ANDROIDENTRYPOINT_ACTIVITY_FRAGMENT_VIEWMODEL_AST', message: 'AST heuristic detected @AndroidEntryPoint usage in Android production code.' },
|
|
803
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidInjectConstructorUsage, ruleId: 'heuristics.android.inject-constructor-constructor-injection.ast', code: 'HEURISTICS_ANDROID_INJECT_CONSTRUCTOR_CONSTRUCTOR_INJECTION_AST', message: 'AST heuristic detected @Inject constructor usage in Android production code.' },
|
|
804
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidModuleInstallInUsage, ruleId: 'heuristics.android.module-installin-provide-dependencies.ast', code: 'HEURISTICS_ANDROID_MODULE_INSTALLIN_PROVIDE_DEPENDENCIES_AST', message: 'AST heuristic detected @Module + @InstallIn usage in Android production code.' },
|
|
805
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidBindsUsage, ruleId: 'heuristics.android.binds-para-implementaciones-de-interfaces-ma-s-eficiente.ast', code: 'HEURISTICS_ANDROID_BINDS_PARA_IMPLEMENTACIONES_DE_INTERFACES_MA_S_EFICIENTE_AST', message: 'AST heuristic detected @Binds usage in Android production code where interface bindings should remain explicit and efficient.' },
|
|
806
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidProvidesUsage, ruleId: 'heuristics.android.provides-para-interfaces-o-third-party.ast', code: 'HEURISTICS_ANDROID_PROVIDES_PARA_INTERFACES_O_THIRD_PARTY_AST', message: 'AST heuristic detected @Provides usage in Android production code where interfaces or third-party bindings should remain explicit.' },
|
|
807
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidViewModelScopeUsage, ruleId: 'heuristics.android.viewmodelscope-scope-de-viewmodel-cancelado-automa-ticamente.ast', code: 'HEURISTICS_ANDROID_VIEWMODELSCOPE_SCOPE_DE_VIEWMODEL_CANCELADO_AUTOMATICAMENTE_AST', message: 'AST heuristic detected viewModelScope usage in Android production code where coroutine work should remain tied to the ViewModel lifecycle.' },
|
|
808
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidAnalyticsUsage, ruleId: 'heuristics.android.analytics-firebase-analytics-o-custom.ast', code: 'HEURISTICS_ANDROID_ANALYTICS_FIREBASE_ANALYTICS_O_CUSTOM_AST', message: 'AST heuristic detected analytics tracking usage in Android production code where app instrumentation should remain explicit.' },
|
|
809
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidProfilerUsage, ruleId: 'heuristics.android.android-profiler-cpu-memory-network-profiling.ast', code: 'HEURISTICS_ANDROID_ANDROID_PROFILER_CPU_MEMORY_NETWORK_PROFILING_AST', message: 'AST heuristic detected Android profiling instrumentation in production code where CPU, memory, and trace capture should remain explicit.' },
|
|
810
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidAppStartupUsage, ruleId: 'heuristics.android.app-startup-androidx-startup-para-lazy-init.ast', code: 'HEURISTICS_ANDROID_APP_STARTUP_ANDROIDX_STARTUP_PARA_LAZY_INIT_AST', message: 'AST heuristic detected androidx.startup Initializer usage in Android production code where app initialization should remain lazy and explicit.' },
|
|
811
|
+
{ platform: 'android', pathCheck: isAndroidInstrumentedTestPath, excludePaths: [], detect: TextAndroid.hasAndroidBaselineProfilesUsage, ruleId: 'heuristics.android.baseline-profiles-optimizacio-n-de-startup.ast', code: 'HEURISTICS_ANDROID_BASELINE_PROFILES_OPTIMIZACION_DE_STARTUP_AST', message: 'AST heuristic detected BaselineProfileRule usage in Android benchmark or instrumented test code where startup optimization should remain explicit.' },
|
|
812
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidSkipRecompositionUsage, ruleId: 'heuristics.android.skip-recomposition-para-metros-inmutables-o-estables.ast', code: 'HEURISTICS_ANDROID_SKIP_RECOMPOSITION_PARA_METROS_INMUTABLES_O_ESTABLES_AST', message: 'AST heuristic detected stable or immutable Compose parameters in Android production code where recomposition should be skippable.' },
|
|
813
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidStabilityUsage, ruleId: 'heuristics.android.stability-composables-estables-recomponen-menos.ast', code: 'HEURISTICS_ANDROID_STABILITY_COMPOSABLES_ESTABLES_RECOMPONEN_MENOS_AST', message: 'AST heuristic detected stable or immutable Compose model usage in Android production code where Compose recomposition should remain predictable.' },
|
|
814
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidViewModelScopedUsage, ruleId: 'heuristics.android.viewmodelscoped-para-dependencias-de-viewmodel.ast', code: 'HEURISTICS_ANDROID_VIEWMODELSCOPED_PARA_DEPENDENCIAS_DE_VIEWMODEL_AST', message: 'AST heuristic detected @ViewModelScoped usage in Android production code.' },
|
|
667
815
|
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidCoroutineTryCatchUsage, ruleId: 'heuristics.android.try-catch-manejo-de-errores-en-coroutines.ast', code: 'HEURISTICS_ANDROID_TRY_CATCH_MANEJO_DE_ERRORES_EN_COROUTINES_AST', message: 'AST heuristic detected try/catch usage in Android coroutine code where error handling must remain explicit.' },
|
|
816
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidSupervisorScopeUsage, ruleId: 'heuristics.android.supervisorscope-errores-no-cancelan-otros-jobs.ast', code: 'HEURISTICS_ANDROID_SUPERVISORSCOPE_ERRORES_NO_CANCELAN_OTROS_JOBS_AST', message: 'AST heuristic detected supervisorScope usage in Android coroutine code where sibling jobs should remain isolated.' },
|
|
817
|
+
{ platform: 'android', pathCheck: isAndroidKotlinPath, excludePaths: [isKotlinTestPath], detect: TextAndroid.hasAndroidWorkManagerBackgroundTaskUsage, ruleId: 'heuristics.android.workmanager-background-tasks.ast', code: 'HEURISTICS_ANDROID_WORKMANAGER_BACKGROUND_TASKS_AST', message: 'AST heuristic detected WorkManager worker usage in Android production code where background tasks should remain explicit.' },
|
|
818
|
+
{ platform: 'android', pathCheck: isAndroidVersionCatalogPath, excludePaths: [], detect: TextAndroid.hasAndroidVersionCatalogUsage, ruleId: 'heuristics.android.version-catalogs-libs-versions-toml-para-dependencias.ast', code: 'HEURISTICS_ANDROID_VERSION_CATALOGS_LIBS_VERSIONS_TOML_PARA_DEPENDENCIAS_AST', message: 'AST heuristic detected Android libs.versions.toml usage in dependency management files where version catalogs should remain explicit.' },
|
|
819
|
+
{ platform: 'android', pathCheck: isAndroidGradlePath, excludePaths: [], detect: TextAndroid.hasAndroidWorkManagerDependencyUsage, ruleId: 'heuristics.android.workmanager-androidx-work-work-runtime-ktx.ast', code: 'HEURISTICS_ANDROID_WORKMANAGER_ANDROIDX_WORK_WORK_RUNTIME_KTX_AST', message: 'AST heuristic detected WorkManager Gradle dependency usage in Android build files.' },
|
|
668
820
|
];
|
|
669
821
|
|
|
670
822
|
const extractWorkflowHeuristicFacts = (
|
|
@@ -904,7 +1056,7 @@ export const extractHeuristicFacts = (
|
|
|
904
1056
|
|
|
905
1057
|
if (
|
|
906
1058
|
params.detectedPlatforms.android?.detected &&
|
|
907
|
-
|
|
1059
|
+
isAndroidKotlinPath(fileFact.path) &&
|
|
908
1060
|
!isKotlinTestPath(fileFact.path)
|
|
909
1061
|
) {
|
|
910
1062
|
const semanticOcpMatch = TextAndroid.findKotlinOpenClosedWhenMatch(fileFact.content);
|
|
@@ -986,6 +1138,88 @@ export const extractHeuristicFacts = (
|
|
|
986
1138
|
})
|
|
987
1139
|
);
|
|
988
1140
|
}
|
|
1141
|
+
|
|
1142
|
+
const semanticComposableMatch = TextAndroid.findAndroidComposableFunctionMatch(fileFact.content);
|
|
1143
|
+
if (semanticComposableMatch) {
|
|
1144
|
+
heuristicFacts.push(
|
|
1145
|
+
createHeuristicFact({
|
|
1146
|
+
ruleId: 'heuristics.android.composable-functions-composable-para-ui.ast',
|
|
1147
|
+
code: 'HEURISTICS_ANDROID_COMPOSABLE_FUNCTIONS_COMPOSABLE_PARA_UI_AST',
|
|
1148
|
+
message:
|
|
1149
|
+
'Semantic Android Compose heuristic detected @Composable UI functions in production code.',
|
|
1150
|
+
filePath: fileFact.path,
|
|
1151
|
+
lines: semanticComposableMatch.lines,
|
|
1152
|
+
severity: 'WARN',
|
|
1153
|
+
primary_node: semanticComposableMatch.primary_node,
|
|
1154
|
+
related_nodes: semanticComposableMatch.related_nodes,
|
|
1155
|
+
why: semanticComposableMatch.why,
|
|
1156
|
+
impact: semanticComposableMatch.impact,
|
|
1157
|
+
expected_fix: semanticComposableMatch.expected_fix,
|
|
1158
|
+
})
|
|
1159
|
+
);
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
const semanticArgumentsMatch = TextAndroid.findAndroidArgumentsMatch(fileFact.content);
|
|
1163
|
+
if (semanticArgumentsMatch) {
|
|
1164
|
+
heuristicFacts.push(
|
|
1165
|
+
createHeuristicFact({
|
|
1166
|
+
ruleId: 'heuristics.android.arguments-pasar-datos-entre-pantallas.ast',
|
|
1167
|
+
code: 'HEURISTICS_ANDROID_ARGUMENTS_PASAR_DATOS_ENTRE_PANTALLAS_AST',
|
|
1168
|
+
message:
|
|
1169
|
+
'Semantic Android navigation heuristic detected explicit arguments passed between screens.',
|
|
1170
|
+
filePath: fileFact.path,
|
|
1171
|
+
lines: semanticArgumentsMatch.lines,
|
|
1172
|
+
severity: 'WARN',
|
|
1173
|
+
primary_node: semanticArgumentsMatch.primary_node,
|
|
1174
|
+
related_nodes: semanticArgumentsMatch.related_nodes,
|
|
1175
|
+
why: semanticArgumentsMatch.why,
|
|
1176
|
+
impact: semanticArgumentsMatch.impact,
|
|
1177
|
+
expected_fix: semanticArgumentsMatch.expected_fix,
|
|
1178
|
+
})
|
|
1179
|
+
);
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
const semanticSingleActivityMatch = TextAndroid.findAndroidSingleActivityComposeShellMatch(
|
|
1183
|
+
fileFact.content
|
|
1184
|
+
);
|
|
1185
|
+
if (semanticSingleActivityMatch) {
|
|
1186
|
+
heuristicFacts.push(
|
|
1187
|
+
createHeuristicFact({
|
|
1188
|
+
ruleId: 'heuristics.android.single-activity-multiples-composables-fragments-no-activities.ast',
|
|
1189
|
+
code: 'HEURISTICS_ANDROID_SINGLE_ACTIVITY_MULTIPLES_COMPOSABLES_FRAGMENTS_NO_ACTIVITIES_AST',
|
|
1190
|
+
message:
|
|
1191
|
+
'Semantic Android Compose heuristic detected a single Activity compose shell in production code.',
|
|
1192
|
+
filePath: fileFact.path,
|
|
1193
|
+
lines: semanticSingleActivityMatch.lines,
|
|
1194
|
+
severity: 'WARN',
|
|
1195
|
+
primary_node: semanticSingleActivityMatch.primary_node,
|
|
1196
|
+
related_nodes: semanticSingleActivityMatch.related_nodes,
|
|
1197
|
+
why: semanticSingleActivityMatch.why,
|
|
1198
|
+
impact: semanticSingleActivityMatch.impact,
|
|
1199
|
+
expected_fix: semanticSingleActivityMatch.expected_fix,
|
|
1200
|
+
})
|
|
1201
|
+
);
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
const semanticGodActivityMatch = TextAndroid.findAndroidGodActivityMatch(fileFact.content);
|
|
1205
|
+
if (semanticGodActivityMatch) {
|
|
1206
|
+
heuristicFacts.push(
|
|
1207
|
+
createHeuristicFact({
|
|
1208
|
+
ruleId: 'heuristics.android.god-activities-single-activity-composables.ast',
|
|
1209
|
+
code: 'HEURISTICS_ANDROID_GOD_ACTIVITIES_SINGLE_ACTIVITY_COMPOSABLES_AST',
|
|
1210
|
+
message:
|
|
1211
|
+
'Semantic Android Compose heuristic detected an Activity that concentrates Compose shell and composables in the same file.',
|
|
1212
|
+
filePath: fileFact.path,
|
|
1213
|
+
lines: semanticGodActivityMatch.lines,
|
|
1214
|
+
severity: 'ERROR',
|
|
1215
|
+
primary_node: semanticGodActivityMatch.primary_node,
|
|
1216
|
+
related_nodes: semanticGodActivityMatch.related_nodes,
|
|
1217
|
+
why: semanticGodActivityMatch.why,
|
|
1218
|
+
impact: semanticGodActivityMatch.impact,
|
|
1219
|
+
expected_fix: semanticGodActivityMatch.expected_fix,
|
|
1220
|
+
})
|
|
1221
|
+
);
|
|
1222
|
+
}
|
|
989
1223
|
}
|
|
990
1224
|
|
|
991
1225
|
// AST-based heuristics
|
|
@@ -1001,7 +1235,7 @@ export const extractHeuristicFacts = (
|
|
|
1001
1235
|
try {
|
|
1002
1236
|
const ast = parse(fileFact.content, {
|
|
1003
1237
|
sourceType: 'unambiguous',
|
|
1004
|
-
plugins: ['typescript', 'jsx'],
|
|
1238
|
+
plugins: ['typescript', 'jsx', 'decorators-legacy'],
|
|
1005
1239
|
});
|
|
1006
1240
|
|
|
1007
1241
|
for (const entry of astDetectorRegistry) {
|
|
@@ -1013,7 +1247,26 @@ export const extractHeuristicFacts = (
|
|
|
1013
1247
|
}
|
|
1014
1248
|
if (entry.detect(ast)) {
|
|
1015
1249
|
const semanticMatch =
|
|
1016
|
-
entry.ruleId === 'heuristics.ts.
|
|
1250
|
+
entry.ruleId === 'heuristics.ts.console-log.ast'
|
|
1251
|
+
? TS.findConsoleLogCallMatch(ast)
|
|
1252
|
+
: entry.ruleId === 'heuristics.ts.explicit-any.ast'
|
|
1253
|
+
? TS.findExplicitAnyTypeMatch(ast)
|
|
1254
|
+
: entry.ruleId === 'heuristics.ts.clean-architecture.ast'
|
|
1255
|
+
? TS.findCleanArchitectureMatch(ast)
|
|
1256
|
+
: entry.ruleId === 'heuristics.ts.production-mock.ast'
|
|
1257
|
+
? TS.findProductionMockCallMatch(ast)
|
|
1258
|
+
: entry.ruleId === 'heuristics.ts.exception-filter.ast'
|
|
1259
|
+
? TS.findExceptionFilterClassMatch(ast)
|
|
1260
|
+
: entry.ruleId === 'heuristics.ts.guards-useguards-jwtauthguard.ast'
|
|
1261
|
+
? TS.findGuardUseGuardsJwtAuthGuardMatch(ast)
|
|
1262
|
+
: entry.ruleId === 'heuristics.ts.interceptors-useinterceptors-logging-transform.ast'
|
|
1263
|
+
? TS.findUseInterceptorsLoggingTransformMatch(ast)
|
|
1264
|
+
: entry.ruleId === 'heuristics.ts.no-sensitive-log.ast'
|
|
1265
|
+
? TS.findSensitiveLogCallMatch(ast)
|
|
1266
|
+
: entry.ruleId === 'heuristics.ts.empty-catch.ast' ||
|
|
1267
|
+
entry.ruleId === 'common.error.empty_catch'
|
|
1268
|
+
? TS.findEmptyCatchClauseMatch(ast)
|
|
1269
|
+
: entry.ruleId === 'heuristics.ts.solid.srp.class-command-query-mix.ast'
|
|
1017
1270
|
? TS.findMixedCommandQueryClassMatch(ast)
|
|
1018
1271
|
: entry.ruleId === 'heuristics.ts.solid.isp.interface-command-query-mix.ast'
|
|
1019
1272
|
? TS.findMixedCommandQueryInterfaceMatch(ast)
|
|
@@ -1023,9 +1276,21 @@ export const extractHeuristicFacts = (
|
|
|
1023
1276
|
? TS.findOverrideMethodThrowingNotImplementedMatch(ast)
|
|
1024
1277
|
: entry.ruleId === 'heuristics.ts.solid.dip.framework-import.ast'
|
|
1025
1278
|
? TS.findFrameworkDependencyImportMatch(ast)
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1279
|
+
: entry.ruleId === 'heuristics.ts.solid.dip.concrete-instantiation.ast'
|
|
1280
|
+
? TS.findConcreteDependencyInstantiationMatch(ast)
|
|
1281
|
+
: entry.ruleId === 'heuristics.ts.singleton-pattern.ast'
|
|
1282
|
+
? TS.findSingletonPatternMatch(ast)
|
|
1283
|
+
: entry.ruleId === 'heuristics.ts.callback-hell.ast'
|
|
1284
|
+
? TS.findCallbackHellPatternMatch(ast)
|
|
1285
|
+
: entry.ruleId === 'heuristics.ts.magic-numbers.ast'
|
|
1286
|
+
? TS.findMagicNumberPatternMatch(ast)
|
|
1287
|
+
: entry.ruleId === 'heuristics.ts.hardcoded-values.ast'
|
|
1288
|
+
? TS.findHardcodedValuePatternMatch(ast)
|
|
1289
|
+
: entry.ruleId === 'heuristics.ts.env-default-fallback.ast'
|
|
1290
|
+
? TS.findEnvDefaultFallbackPatternMatch(ast)
|
|
1291
|
+
: entry.ruleId === 'heuristics.ts.god-class-large-class.ast'
|
|
1292
|
+
? TS.findLargeClassDeclarationMatch(ast)
|
|
1293
|
+
: undefined;
|
|
1029
1294
|
const lineLocator = entry.locateLines ?? astDetectorLineLocatorRegistry.get(entry.detect);
|
|
1030
1295
|
const lines = semanticMatch?.lines ?? lineLocator?.(ast);
|
|
1031
1296
|
heuristicFacts.push(
|