@defai.digital/ax-cli 3.2.0 → 3.4.0
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/.ax-cli/memory.json +8 -1
- package/README.md +118 -2
- package/config/models.yaml +13 -0
- package/config/settings.yaml +6 -0
- package/dist/agent/context-manager.d.ts +5 -5
- package/dist/agent/context-manager.js +19 -9
- package/dist/agent/context-manager.js.map +1 -1
- package/dist/agent/dependency-resolver.js +2 -1
- package/dist/agent/dependency-resolver.js.map +1 -1
- package/dist/agent/llm-agent.d.ts +3 -2
- package/dist/agent/llm-agent.js +64 -58
- package/dist/agent/llm-agent.js.map +1 -1
- package/dist/agent/subagent.js +2 -1
- package/dist/agent/subagent.js.map +1 -1
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.d.ts +29 -0
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.js +103 -0
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.js.map +1 -0
- package/dist/analyzers/architecture/architecture-analyzer.d.ts +58 -0
- package/dist/analyzers/architecture/architecture-analyzer.js +276 -0
- package/dist/analyzers/architecture/architecture-analyzer.js.map +1 -0
- package/dist/analyzers/architecture/index.d.ts +12 -0
- package/dist/analyzers/architecture/index.js +14 -0
- package/dist/analyzers/architecture/index.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/base-detector.d.ts +27 -0
- package/dist/analyzers/architecture/pattern-detectors/base-detector.js +31 -0
- package/dist/analyzers/architecture/pattern-detectors/base-detector.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.d.ts +11 -0
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.js +57 -0
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.d.ts +11 -0
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.js +43 -0
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.d.ts +11 -0
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.js +49 -0
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.js.map +1 -0
- package/dist/analyzers/architecture/project-structure-scanner.d.ts +54 -0
- package/dist/analyzers/architecture/project-structure-scanner.js +200 -0
- package/dist/analyzers/architecture/project-structure-scanner.js.map +1 -0
- package/dist/analyzers/best-practices/base-rule.d.ts +45 -0
- package/dist/analyzers/best-practices/base-rule.js +45 -0
- package/dist/analyzers/best-practices/base-rule.js.map +1 -0
- package/dist/analyzers/best-practices/best-practice-validator.d.ts +35 -0
- package/dist/analyzers/best-practices/best-practice-validator.js +181 -0
- package/dist/analyzers/best-practices/best-practice-validator.js.map +1 -0
- package/dist/analyzers/best-practices/rules/index.d.ts +7 -0
- package/dist/analyzers/best-practices/rules/index.js +56 -0
- package/dist/analyzers/best-practices/rules/index.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.js +41 -0
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.d.ts +27 -0
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.js +76 -0
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/index.d.ts +15 -0
- package/dist/analyzers/best-practices/rules/typescript/index.js +16 -0
- package/dist/analyzers/best-practices/rules/typescript/index.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.d.ts +18 -0
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.js +25 -0
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.js +27 -0
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.d.ts +18 -0
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.js +39 -0
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.js +32 -0
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.js +36 -0
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.js +33 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.js +34 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.js +27 -0
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.js.map +1 -0
- package/dist/analyzers/best-practices/types.d.ts +86 -0
- package/dist/analyzers/best-practices/types.js +7 -0
- package/dist/analyzers/best-practices/types.js.map +1 -0
- package/dist/analyzers/cache/analysis-cache.d.ts +41 -0
- package/dist/analyzers/cache/analysis-cache.js +84 -0
- package/dist/analyzers/cache/analysis-cache.js.map +1 -0
- package/dist/analyzers/errors.d.ts +51 -0
- package/dist/analyzers/errors.js +79 -0
- package/dist/analyzers/errors.js.map +1 -0
- package/dist/commands/doctor.js +3 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/frontend.d.ts +9 -0
- package/dist/commands/frontend.js +645 -0
- package/dist/commands/frontend.js.map +1 -0
- package/dist/commands/mcp.js +652 -3
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/models.js +2 -2
- package/dist/commands/models.js.map +1 -1
- package/dist/commands/setup.js +100 -41
- package/dist/commands/setup.js.map +1 -1
- package/dist/constants.d.ts +4 -0
- package/dist/constants.js +4 -0
- package/dist/constants.js.map +1 -1
- package/dist/hooks/use-enhanced-input.js +16 -3
- package/dist/hooks/use-enhanced-input.js.map +1 -1
- package/dist/hooks/use-input-handler.js +9 -4
- package/dist/hooks/use-input-handler.js.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/llm/client.d.ts +1 -0
- package/dist/llm/tools.js +86 -0
- package/dist/llm/tools.js.map +1 -1
- package/dist/llm/types.d.ts +49 -22
- package/dist/llm/types.js +12 -8
- package/dist/llm/types.js.map +1 -1
- package/dist/mcp/client.d.ts +5 -0
- package/dist/mcp/client.js +55 -0
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/config.d.ts +1 -1
- package/dist/mcp/config.js +2 -2
- package/dist/mcp/config.js.map +1 -1
- package/dist/mcp/health.d.ts +120 -0
- package/dist/mcp/health.js +267 -0
- package/dist/mcp/health.js.map +1 -0
- package/dist/mcp/reconnection.d.ts +93 -0
- package/dist/mcp/reconnection.js +216 -0
- package/dist/mcp/reconnection.js.map +1 -0
- package/dist/mcp/registry.d.ts +71 -0
- package/dist/mcp/registry.js +257 -0
- package/dist/mcp/registry.js.map +1 -0
- package/dist/mcp/resources.d.ts +53 -0
- package/dist/mcp/resources.js +135 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/templates.d.ts +52 -0
- package/dist/mcp/templates.js +624 -0
- package/dist/mcp/templates.js.map +1 -0
- package/dist/mcp/validation.d.ts +25 -0
- package/dist/mcp/validation.js +209 -0
- package/dist/mcp/validation.js.map +1 -0
- package/dist/memory/context-generator.js +1 -2
- package/dist/memory/context-generator.js.map +1 -1
- package/dist/planner/types.d.ts +2 -2
- package/dist/schemas/api-schemas.d.ts +2 -1
- package/dist/schemas/api-schemas.js +6 -4
- package/dist/schemas/api-schemas.js.map +1 -1
- package/dist/schemas/index.d.ts +4 -4
- package/dist/schemas/tool-schemas.d.ts +2 -2
- package/dist/schemas/yaml-schemas.d.ts +15 -0
- package/dist/schemas/yaml-schemas.js +3 -0
- package/dist/schemas/yaml-schemas.js.map +1 -1
- package/dist/sdk/index.d.ts +138 -0
- package/dist/sdk/index.js +173 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/sdk/types.d.ts +53 -0
- package/dist/sdk/types.js +8 -0
- package/dist/sdk/types.js.map +1 -0
- package/dist/tools/analysis-tools/architecture-tool.d.ts +46 -0
- package/dist/tools/analysis-tools/architecture-tool.js +124 -0
- package/dist/tools/analysis-tools/architecture-tool.js.map +1 -0
- package/dist/tools/analysis-tools/validation-tool.d.ts +51 -0
- package/dist/tools/analysis-tools/validation-tool.js +121 -0
- package/dist/tools/analysis-tools/validation-tool.js.map +1 -0
- package/dist/tools/bash.js +25 -10
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/web-search/cache.d.ts +62 -0
- package/dist/tools/web-search/cache.js +105 -0
- package/dist/tools/web-search/cache.js.map +1 -0
- package/dist/tools/web-search/engines/brave.d.ts +16 -0
- package/dist/tools/web-search/engines/brave.js +99 -0
- package/dist/tools/web-search/engines/brave.js.map +1 -0
- package/dist/tools/web-search/engines/crates.d.ts +19 -0
- package/dist/tools/web-search/engines/crates.js +87 -0
- package/dist/tools/web-search/engines/crates.js.map +1 -0
- package/dist/tools/web-search/engines/npm.d.ts +18 -0
- package/dist/tools/web-search/engines/npm.js +86 -0
- package/dist/tools/web-search/engines/npm.js.map +1 -0
- package/dist/tools/web-search/engines/pypi.d.ts +18 -0
- package/dist/tools/web-search/engines/pypi.js +75 -0
- package/dist/tools/web-search/engines/pypi.js.map +1 -0
- package/dist/tools/web-search/engines/tavily.d.ts +17 -0
- package/dist/tools/web-search/engines/tavily.js +73 -0
- package/dist/tools/web-search/engines/tavily.js.map +1 -0
- package/dist/tools/web-search/index.d.ts +13 -0
- package/dist/tools/web-search/index.js +13 -0
- package/dist/tools/web-search/index.js.map +1 -0
- package/dist/tools/web-search/router.d.ts +36 -0
- package/dist/tools/web-search/router.js +280 -0
- package/dist/tools/web-search/router.js.map +1 -0
- package/dist/tools/web-search/types.d.ts +45 -0
- package/dist/tools/web-search/types.js +6 -0
- package/dist/tools/web-search/types.js.map +1 -0
- package/dist/tools/web-search/web-search-tool.d.ts +51 -0
- package/dist/tools/web-search/web-search-tool.js +256 -0
- package/dist/tools/web-search/web-search-tool.js.map +1 -0
- package/dist/types/analysis.d.ts +177 -0
- package/dist/types/analysis.js +8 -0
- package/dist/types/analysis.js.map +1 -0
- package/dist/ui/components/api-key-input.js +2 -2
- package/dist/ui/components/api-key-input.js.map +1 -1
- package/dist/ui/components/chat-history.js +14 -7
- package/dist/ui/components/chat-history.js.map +1 -1
- package/dist/ui/components/chat-input.js +12 -7
- package/dist/ui/components/chat-input.js.map +1 -1
- package/dist/ui/components/chat-interface.js +75 -54
- package/dist/ui/components/chat-interface.js.map +1 -1
- package/dist/ui/components/keyboard-hints.js +5 -4
- package/dist/ui/components/keyboard-hints.js.map +1 -1
- package/dist/ui/components/quick-actions.js +1 -0
- package/dist/ui/components/quick-actions.js.map +1 -1
- package/dist/ui/components/reasoning-display.js +14 -4
- package/dist/ui/components/reasoning-display.js.map +1 -1
- package/dist/ui/components/status-bar.d.ts +1 -0
- package/dist/ui/components/status-bar.js +37 -39
- package/dist/ui/components/status-bar.js.map +1 -1
- package/dist/ui/components/toast-notification.d.ts +29 -0
- package/dist/ui/components/toast-notification.js +17 -3
- package/dist/ui/components/toast-notification.js.map +1 -1
- package/dist/ui/components/welcome-panel.d.ts +1 -0
- package/dist/ui/components/welcome-panel.js +106 -4
- package/dist/ui/components/welcome-panel.js.map +1 -1
- package/dist/utils/analysis-logger.d.ts +47 -0
- package/dist/utils/analysis-logger.js +70 -0
- package/dist/utils/analysis-logger.js.map +1 -0
- package/dist/utils/automatosx-detector.d.ts +19 -0
- package/dist/utils/automatosx-detector.js +52 -0
- package/dist/utils/automatosx-detector.js.map +1 -0
- package/dist/utils/config-loader.d.ts +4 -0
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/confirmation-service.js +1 -1
- package/dist/utils/confirmation-service.js.map +1 -1
- package/dist/utils/init-previewer.js +26 -4
- package/dist/utils/init-previewer.js.map +1 -1
- package/dist/utils/setup-validator.js +1 -0
- package/dist/utils/setup-validator.js.map +1 -1
- package/dist/utils/text-utils.d.ts +1 -0
- package/dist/utils/text-utils.js +12 -0
- package/dist/utils/text-utils.js.map +1 -1
- package/package.json +19 -4
- package/vitest.config.ts +1 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MVC Pattern Detector
|
|
3
|
+
*
|
|
4
|
+
* Detects Model-View-Controller architectural pattern.
|
|
5
|
+
* Looks for models/, views/, and controllers/ directories.
|
|
6
|
+
*/
|
|
7
|
+
import { BasePatternDetector } from './base-detector.js';
|
|
8
|
+
export class MVCDetector extends BasePatternDetector {
|
|
9
|
+
detect(structure) {
|
|
10
|
+
const hasModels = this.scanner.hasDirectory(structure, 'models');
|
|
11
|
+
const hasViews = this.scanner.hasDirectory(structure, 'views');
|
|
12
|
+
const hasControllers = this.scanner.hasDirectory(structure, 'controllers');
|
|
13
|
+
// Need at least 2 out of 3 components to suggest MVC
|
|
14
|
+
const matchCount = [hasModels, hasViews, hasControllers].filter(Boolean)
|
|
15
|
+
.length;
|
|
16
|
+
if (matchCount < 2) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const locations = [];
|
|
20
|
+
let confidence = 0;
|
|
21
|
+
if (hasModels) {
|
|
22
|
+
const modelDirs = structure.directories.filter((d) => d.relativePath.toLowerCase().includes('models'));
|
|
23
|
+
locations.push(...modelDirs.map((d) => d.relativePath));
|
|
24
|
+
confidence += 0.33;
|
|
25
|
+
}
|
|
26
|
+
if (hasViews) {
|
|
27
|
+
const viewDirs = structure.directories.filter((d) => d.relativePath.toLowerCase().includes('views'));
|
|
28
|
+
locations.push(...viewDirs.map((d) => d.relativePath));
|
|
29
|
+
confidence += 0.33;
|
|
30
|
+
}
|
|
31
|
+
if (hasControllers) {
|
|
32
|
+
const controllerDirs = structure.directories.filter((d) => d.relativePath.toLowerCase().includes('controllers'));
|
|
33
|
+
locations.push(...controllerDirs.map((d) => d.relativePath));
|
|
34
|
+
confidence += 0.34;
|
|
35
|
+
}
|
|
36
|
+
return this.createPattern('MVC (Model-View-Controller)', 'architectural', confidence, locations, 'Separates application into Models (data), Views (presentation), and Controllers (logic)', {
|
|
37
|
+
hasModels,
|
|
38
|
+
hasViews,
|
|
39
|
+
hasControllers,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=mvc-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mvc-detector.js","sourceRoot":"","sources":["../../../../src/analyzers/architecture/pattern-detectors/mvc-detector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,OAAO,WAAY,SAAQ,mBAAmB;IAClD,MAAM,CAAC,SAA2B;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC/D,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QAE3E,qDAAqD;QACrD,MAAM,UAAU,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;aACrE,MAAM,CAAC;QAEV,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,IAAI,UAAU,GAAG,CAAC,CAAC;QAEnB,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACnD,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAChD,CAAC;YACF,SAAS,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;YACxD,UAAU,IAAI,IAAI,CAAC;QACrB,CAAC;QAED,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAClD,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAC/C,CAAC;YACF,SAAS,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;YACvD,UAAU,IAAI,IAAI,CAAC;QACrB,CAAC;QAED,IAAI,cAAc,EAAE,CAAC;YACnB,MAAM,cAAc,GAAG,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACxD,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,CACrD,CAAC;YACF,SAAS,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;YAC7D,UAAU,IAAI,IAAI,CAAC;QACrB,CAAC;QAED,OAAO,IAAI,CAAC,aAAa,CACvB,6BAA6B,EAC7B,eAAe,EACf,UAAU,EACV,SAAS,EACT,yFAAyF,EACzF;YACE,SAAS;YACT,QAAQ;YACR,cAAc;SACf,CACF,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository Pattern Detector
|
|
3
|
+
*
|
|
4
|
+
* Detects Repository pattern for data access abstraction.
|
|
5
|
+
* Looks for files/directories with "repository" in the name.
|
|
6
|
+
*/
|
|
7
|
+
import type { DetectedPattern, ProjectStructure } from '../../../types/analysis.js';
|
|
8
|
+
import { BasePatternDetector } from './base-detector.js';
|
|
9
|
+
export declare class RepositoryDetector extends BasePatternDetector {
|
|
10
|
+
detect(structure: ProjectStructure): DetectedPattern | null;
|
|
11
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository Pattern Detector
|
|
3
|
+
*
|
|
4
|
+
* Detects Repository pattern for data access abstraction.
|
|
5
|
+
* Looks for files/directories with "repository" in the name.
|
|
6
|
+
*/
|
|
7
|
+
import { BasePatternDetector } from './base-detector.js';
|
|
8
|
+
export class RepositoryDetector extends BasePatternDetector {
|
|
9
|
+
detect(structure) {
|
|
10
|
+
// Look for repository directories
|
|
11
|
+
const hasRepositoryDir = this.scanner.hasDirectory(structure, 'repositories') ||
|
|
12
|
+
this.scanner.hasDirectory(structure, 'repository');
|
|
13
|
+
// Look for files with "repository" in the name
|
|
14
|
+
const repositoryFiles = this.scanner.getFilesByPattern(structure, /repository\.(ts|js|tsx|jsx)$/i);
|
|
15
|
+
if (!hasRepositoryDir && repositoryFiles.length === 0) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const locations = [];
|
|
19
|
+
let confidence = 0.6; // Base confidence
|
|
20
|
+
// Add directory locations
|
|
21
|
+
if (hasRepositoryDir) {
|
|
22
|
+
const repoDirs = structure.directories.filter((d) => d.relativePath.toLowerCase().includes('repositories') ||
|
|
23
|
+
d.relativePath.toLowerCase().includes('repository'));
|
|
24
|
+
locations.push(...repoDirs.map((d) => d.relativePath));
|
|
25
|
+
confidence += 0.2;
|
|
26
|
+
}
|
|
27
|
+
// Add file locations
|
|
28
|
+
if (repositoryFiles.length > 0) {
|
|
29
|
+
locations.push(...repositoryFiles.map((f) => f.relativePath));
|
|
30
|
+
// Check for interfaces/abstractions (higher confidence)
|
|
31
|
+
const hasInterfaces = repositoryFiles.some((f) => f.relativePath.toLowerCase().includes('interface') ||
|
|
32
|
+
f.relativePath.toLowerCase().includes('abstract') ||
|
|
33
|
+
f.relativePath.toLowerCase().includes('i-repository'));
|
|
34
|
+
if (hasInterfaces) {
|
|
35
|
+
confidence += 0.2;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
confidence += 0.1;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return this.createPattern('Repository Pattern', 'structural', Math.min(confidence, 1.0), locations, 'Encapsulates data access logic and provides a collection-like interface for domain entities', {
|
|
42
|
+
repositoryCount: repositoryFiles.length,
|
|
43
|
+
hasRepositoryDirectory: hasRepositoryDir,
|
|
44
|
+
hasInterfaces: repositoryFiles.some((f) => f.relativePath.toLowerCase().includes('interface') ||
|
|
45
|
+
f.relativePath.toLowerCase().includes('abstract')),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=repository-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository-detector.js","sourceRoot":"","sources":["../../../../src/analyzers/architecture/pattern-detectors/repository-detector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,OAAO,kBAAmB,SAAQ,mBAAmB;IACzD,MAAM,CAAC,SAA2B;QAChC,kCAAkC;QAClC,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,EAAE,cAAc,CAAC;YACnD,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QAE7E,+CAA+C;QAC/C,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CACpD,SAAS,EACT,+BAA+B,CAChC,CAAC;QAEF,IAAI,CAAC,gBAAgB,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,IAAI,UAAU,GAAG,GAAG,CAAC,CAAC,kBAAkB;QAExC,0BAA0B;QAC1B,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC,MAAM,CAC3C,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;gBACrD,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CACtD,CAAC;YACF,SAAS,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;YACvD,UAAU,IAAI,GAAG,CAAC;QACpB,CAAC;QAED,qBAAqB;QACrB,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,SAAS,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;YAE9D,wDAAwD;YACxD,MAAM,aAAa,GAAG,eAAe,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAClD,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;gBACjD,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,CACxD,CAAC;YAEF,IAAI,aAAa,EAAE,CAAC;gBAClB,UAAU,IAAI,GAAG,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,UAAU,IAAI,GAAG,CAAC;YACpB,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,aAAa,CACvB,oBAAoB,EACpB,YAAY,EACZ,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,EACzB,SAAS,EACT,6FAA6F,EAC7F;YACE,eAAe,EAAE,eAAe,CAAC,MAAM;YACvC,sBAAsB,EAAE,gBAAgB;YACxC,aAAa,EAAE,eAAe,CAAC,IAAI,CACjC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAClD,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CACpD;SACF,CACF,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Structure Scanner
|
|
3
|
+
*
|
|
4
|
+
* Scans project directory structure and gathers file/directory information.
|
|
5
|
+
* Implements ignore patterns for common non-source directories.
|
|
6
|
+
*/
|
|
7
|
+
import type { FileInfo, ProjectStructure } from '../../types/analysis.js';
|
|
8
|
+
export declare class ProjectStructureScanner {
|
|
9
|
+
private readonly ignorePatterns;
|
|
10
|
+
/**
|
|
11
|
+
* Scan project structure
|
|
12
|
+
*/
|
|
13
|
+
scan(projectPath: string): Promise<ProjectStructure>;
|
|
14
|
+
/**
|
|
15
|
+
* Validate project path exists and is a directory
|
|
16
|
+
*/
|
|
17
|
+
private validatePath;
|
|
18
|
+
/**
|
|
19
|
+
* Gather file information with concurrency control
|
|
20
|
+
*/
|
|
21
|
+
private gatherFileInfo;
|
|
22
|
+
/**
|
|
23
|
+
* Get information for a single file
|
|
24
|
+
*/
|
|
25
|
+
private getFileInfo;
|
|
26
|
+
/**
|
|
27
|
+
* Gather directory information with concurrency control
|
|
28
|
+
*/
|
|
29
|
+
private gatherDirectoryInfo;
|
|
30
|
+
/**
|
|
31
|
+
* Get information for a single directory
|
|
32
|
+
*/
|
|
33
|
+
private getDirectoryInfo;
|
|
34
|
+
/**
|
|
35
|
+
* Group files by extension
|
|
36
|
+
*/
|
|
37
|
+
private groupFilesByExtension;
|
|
38
|
+
/**
|
|
39
|
+
* Check if structure has a directory matching name (case-insensitive)
|
|
40
|
+
*/
|
|
41
|
+
hasDirectory(structure: ProjectStructure, dirName: string): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Check if structure has a file matching name (case-insensitive)
|
|
44
|
+
*/
|
|
45
|
+
hasFile(structure: ProjectStructure, fileName: string): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Get files matching a regex pattern
|
|
48
|
+
*/
|
|
49
|
+
getFilesByPattern(structure: ProjectStructure, pattern: RegExp): FileInfo[];
|
|
50
|
+
/**
|
|
51
|
+
* Get files by extension
|
|
52
|
+
*/
|
|
53
|
+
getFilesByExtension(structure: ProjectStructure, extension: string): FileInfo[];
|
|
54
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Structure Scanner
|
|
3
|
+
*
|
|
4
|
+
* Scans project directory structure and gathers file/directory information.
|
|
5
|
+
* Implements ignore patterns for common non-source directories.
|
|
6
|
+
*/
|
|
7
|
+
import { promises as fs } from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import { glob } from 'glob';
|
|
10
|
+
import { ProjectStructureError } from '../errors.js';
|
|
11
|
+
export class ProjectStructureScanner {
|
|
12
|
+
ignorePatterns = [
|
|
13
|
+
'**/node_modules/**',
|
|
14
|
+
'**/.git/**',
|
|
15
|
+
'**/dist/**',
|
|
16
|
+
'**/build/**',
|
|
17
|
+
'**/.next/**',
|
|
18
|
+
'**/coverage/**',
|
|
19
|
+
'**/.cache/**',
|
|
20
|
+
'**/.vscode/**',
|
|
21
|
+
'**/.idea/**',
|
|
22
|
+
'**/.DS_Store',
|
|
23
|
+
'**/package-lock.json',
|
|
24
|
+
'**/yarn.lock',
|
|
25
|
+
'**/pnpm-lock.yaml',
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* Scan project structure
|
|
29
|
+
*/
|
|
30
|
+
async scan(projectPath) {
|
|
31
|
+
// Validate path
|
|
32
|
+
await this.validatePath(projectPath);
|
|
33
|
+
// Find all files
|
|
34
|
+
const filePaths = await glob('**/*', {
|
|
35
|
+
cwd: projectPath,
|
|
36
|
+
ignore: this.ignorePatterns,
|
|
37
|
+
nodir: true,
|
|
38
|
+
absolute: false,
|
|
39
|
+
dot: false, // Don't include hidden files
|
|
40
|
+
});
|
|
41
|
+
// Gather file info in parallel (with concurrency limit)
|
|
42
|
+
const files = await this.gatherFileInfo(projectPath, filePaths);
|
|
43
|
+
// Find all directories
|
|
44
|
+
const dirPaths = await glob('**/', {
|
|
45
|
+
cwd: projectPath,
|
|
46
|
+
ignore: this.ignorePatterns,
|
|
47
|
+
absolute: false,
|
|
48
|
+
dot: false,
|
|
49
|
+
});
|
|
50
|
+
const directories = await this.gatherDirectoryInfo(projectPath, dirPaths);
|
|
51
|
+
// Group files by extension
|
|
52
|
+
const filesByExtension = this.groupFilesByExtension(files);
|
|
53
|
+
const totalLines = files.reduce((sum, f) => sum + f.lines, 0);
|
|
54
|
+
return Object.freeze({
|
|
55
|
+
rootPath: projectPath,
|
|
56
|
+
files: Object.freeze(files),
|
|
57
|
+
directories: Object.freeze(directories),
|
|
58
|
+
filesByExtension,
|
|
59
|
+
totalLines,
|
|
60
|
+
totalFiles: files.length,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Validate project path exists and is a directory
|
|
65
|
+
*/
|
|
66
|
+
async validatePath(projectPath) {
|
|
67
|
+
// Check for path traversal attempts
|
|
68
|
+
if (projectPath.includes('..')) {
|
|
69
|
+
throw new ProjectStructureError('Path traversal detected', {
|
|
70
|
+
path: projectPath,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
const stats = await fs.stat(projectPath);
|
|
75
|
+
if (!stats.isDirectory()) {
|
|
76
|
+
throw new ProjectStructureError('Path is not a directory', {
|
|
77
|
+
path: projectPath,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
if (error.code === 'ENOENT') {
|
|
83
|
+
throw new ProjectStructureError('Path does not exist', {
|
|
84
|
+
path: projectPath,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
throw new ProjectStructureError(`Failed to access path: ${error.message}`, { path: projectPath });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Gather file information with concurrency control
|
|
92
|
+
*/
|
|
93
|
+
async gatherFileInfo(rootPath, relativePaths) {
|
|
94
|
+
const CONCURRENCY = 10; // Process 10 files at a time
|
|
95
|
+
const results = [];
|
|
96
|
+
for (let i = 0; i < relativePaths.length; i += CONCURRENCY) {
|
|
97
|
+
const batch = relativePaths.slice(i, i + CONCURRENCY);
|
|
98
|
+
const batchResults = await Promise.all(batch.map((relativePath) => this.getFileInfo(rootPath, relativePath).catch((error) => {
|
|
99
|
+
console.warn(`Failed to read file ${relativePath}:`, error.message);
|
|
100
|
+
return null;
|
|
101
|
+
})));
|
|
102
|
+
results.push(...batchResults.filter((r) => r !== null));
|
|
103
|
+
}
|
|
104
|
+
return results;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get information for a single file
|
|
108
|
+
*/
|
|
109
|
+
async getFileInfo(rootPath, relativePath) {
|
|
110
|
+
const fullPath = path.join(rootPath, relativePath);
|
|
111
|
+
const stats = await fs.stat(fullPath);
|
|
112
|
+
// Count lines
|
|
113
|
+
let lines = 0;
|
|
114
|
+
try {
|
|
115
|
+
const content = await fs.readFile(fullPath, 'utf-8');
|
|
116
|
+
lines = content.split('\n').length;
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// If file can't be read as text, lines remain 0
|
|
120
|
+
lines = 0;
|
|
121
|
+
}
|
|
122
|
+
return Object.freeze({
|
|
123
|
+
path: fullPath,
|
|
124
|
+
relativePath,
|
|
125
|
+
lines,
|
|
126
|
+
size: stats.size,
|
|
127
|
+
extension: path.extname(relativePath),
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Gather directory information with concurrency control
|
|
132
|
+
*/
|
|
133
|
+
async gatherDirectoryInfo(rootPath, relativePaths) {
|
|
134
|
+
const CONCURRENCY = 10;
|
|
135
|
+
const results = [];
|
|
136
|
+
for (let i = 0; i < relativePaths.length; i += CONCURRENCY) {
|
|
137
|
+
const batch = relativePaths.slice(i, i + CONCURRENCY);
|
|
138
|
+
const batchResults = await Promise.all(batch.map((relativePath) => this.getDirectoryInfo(rootPath, relativePath).catch((error) => {
|
|
139
|
+
console.warn(`Failed to read directory ${relativePath}:`, error.message);
|
|
140
|
+
return null;
|
|
141
|
+
})));
|
|
142
|
+
results.push(...batchResults.filter((r) => r !== null));
|
|
143
|
+
}
|
|
144
|
+
return results;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get information for a single directory
|
|
148
|
+
*/
|
|
149
|
+
async getDirectoryInfo(rootPath, relativePath) {
|
|
150
|
+
const fullPath = path.join(rootPath, relativePath);
|
|
151
|
+
const entries = await fs.readdir(fullPath, { withFileTypes: true });
|
|
152
|
+
const fileCount = entries.filter((e) => e.isFile()).length;
|
|
153
|
+
const subdirCount = entries.filter((e) => e.isDirectory()).length;
|
|
154
|
+
return Object.freeze({
|
|
155
|
+
path: fullPath,
|
|
156
|
+
relativePath,
|
|
157
|
+
fileCount,
|
|
158
|
+
subdirCount,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Group files by extension
|
|
163
|
+
*/
|
|
164
|
+
groupFilesByExtension(files) {
|
|
165
|
+
const groups = new Map();
|
|
166
|
+
for (const file of files) {
|
|
167
|
+
const ext = file.extension || '.no-extension';
|
|
168
|
+
const existing = groups.get(ext) || [];
|
|
169
|
+
groups.set(ext, [...existing, file]);
|
|
170
|
+
}
|
|
171
|
+
// Freeze all arrays
|
|
172
|
+
return new Map(Array.from(groups.entries()).map(([k, v]) => [k, Object.freeze(v)]));
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Check if structure has a directory matching name (case-insensitive)
|
|
176
|
+
*/
|
|
177
|
+
hasDirectory(structure, dirName) {
|
|
178
|
+
return structure.directories.some((d) => d.relativePath.toLowerCase().includes(dirName.toLowerCase()));
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Check if structure has a file matching name (case-insensitive)
|
|
182
|
+
*/
|
|
183
|
+
hasFile(structure, fileName) {
|
|
184
|
+
return structure.files.some((f) => f.relativePath.toLowerCase().includes(fileName.toLowerCase()));
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Get files matching a regex pattern
|
|
188
|
+
*/
|
|
189
|
+
getFilesByPattern(structure, pattern) {
|
|
190
|
+
return structure.files.filter((f) => pattern.test(f.relativePath));
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Get files by extension
|
|
194
|
+
*/
|
|
195
|
+
getFilesByExtension(structure, extension) {
|
|
196
|
+
const ext = extension.startsWith('.') ? extension : `.${extension}`;
|
|
197
|
+
return Array.from(structure.filesByExtension.get(ext) || []);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=project-structure-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-structure-scanner.js","sourceRoot":"","sources":["../../../src/analyzers/architecture/project-structure-scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Validation Rule
|
|
3
|
+
*
|
|
4
|
+
* Abstract base class for all validation rules
|
|
5
|
+
* Provides common functionality and helpers
|
|
6
|
+
*/
|
|
7
|
+
import type { ValidationRule, ViolationFix } from './types.js';
|
|
8
|
+
import type { Violation, Severity } from '../../types/analysis.js';
|
|
9
|
+
import type { RuleCategory } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Abstract base class for validation rules
|
|
12
|
+
* Provides common functionality for all rules
|
|
13
|
+
*/
|
|
14
|
+
export declare abstract class BaseValidationRule implements ValidationRule {
|
|
15
|
+
abstract readonly id: string;
|
|
16
|
+
abstract readonly name: string;
|
|
17
|
+
abstract readonly description: string;
|
|
18
|
+
abstract readonly severity: Severity;
|
|
19
|
+
abstract readonly category: RuleCategory;
|
|
20
|
+
abstract readonly autoFixable: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Check file for violations
|
|
23
|
+
* Must be implemented by subclasses
|
|
24
|
+
*/
|
|
25
|
+
abstract check(filePath: string, content: string): Promise<Violation[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Generate fix for violation (optional)
|
|
28
|
+
*/
|
|
29
|
+
fix?(violation: Violation, content: string): Promise<ViolationFix | null>;
|
|
30
|
+
/**
|
|
31
|
+
* Helper: Create a violation object
|
|
32
|
+
*/
|
|
33
|
+
protected createViolation(file: string, line: number, column: number, message: string, suggestion?: string, metadata?: Record<string, unknown>): Violation;
|
|
34
|
+
/**
|
|
35
|
+
* Helper: Find line and column from character index
|
|
36
|
+
*/
|
|
37
|
+
protected getPosition(content: string, index: number): {
|
|
38
|
+
line: number;
|
|
39
|
+
column: number;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Helper: Count matches in content
|
|
43
|
+
*/
|
|
44
|
+
protected countMatches(content: string, pattern: RegExp): number;
|
|
45
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Validation Rule
|
|
3
|
+
*
|
|
4
|
+
* Abstract base class for all validation rules
|
|
5
|
+
* Provides common functionality and helpers
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Abstract base class for validation rules
|
|
9
|
+
* Provides common functionality for all rules
|
|
10
|
+
*/
|
|
11
|
+
export class BaseValidationRule {
|
|
12
|
+
/**
|
|
13
|
+
* Helper: Create a violation object
|
|
14
|
+
*/
|
|
15
|
+
createViolation(file, line, column, message, suggestion, metadata) {
|
|
16
|
+
return Object.freeze({
|
|
17
|
+
ruleId: this.id,
|
|
18
|
+
severity: this.severity,
|
|
19
|
+
file,
|
|
20
|
+
line,
|
|
21
|
+
column,
|
|
22
|
+
message,
|
|
23
|
+
suggestion,
|
|
24
|
+
metadata: metadata ? Object.freeze(metadata) : undefined,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Helper: Find line and column from character index
|
|
29
|
+
*/
|
|
30
|
+
getPosition(content, index) {
|
|
31
|
+
const lines = content.substring(0, index).split('\n');
|
|
32
|
+
return {
|
|
33
|
+
line: lines.length,
|
|
34
|
+
column: lines[lines.length - 1].length + 1,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Helper: Count matches in content
|
|
39
|
+
*/
|
|
40
|
+
countMatches(content, pattern) {
|
|
41
|
+
const matches = content.match(pattern);
|
|
42
|
+
return matches ? matches.length : 0;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=base-rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-rule.js","sourceRoot":"","sources":["../../../src/analyzers/best-practices/base-rule.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;;GAGG;AACH,MAAM,OAAgB,kBAAkB;IAmBtC;;OAEG;IACO,eAAe,CACvB,IAAY,EACZ,IAAY,EACZ,MAAc,EACd,OAAe,EACf,UAAmB,EACnB,QAAkC;QAElC,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,IAAI;YACJ,IAAI;YACJ,MAAM;YACN,OAAO;YACP,UAAU;YACV,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS;SACzD,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACO,WAAW,CACnB,OAAe,EACf,KAAa;QAEb,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtD,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,MAAM;YAClB,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;SAC3C,CAAC;IACJ,CAAC;IAED;;OAEG;IACO,YAAY,CAAC,OAAe,EAAE,OAAe;QACrD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;CACF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Best Practice Validator
|
|
3
|
+
*
|
|
4
|
+
* Main orchestrator for validation operations
|
|
5
|
+
*/
|
|
6
|
+
import type { ValidationResult, BatchValidationResult, ValidationOptions } from '../../types/analysis.js';
|
|
7
|
+
import type { Logger } from '../../utils/analysis-logger.js';
|
|
8
|
+
export declare class BestPracticeValidator {
|
|
9
|
+
private readonly logger;
|
|
10
|
+
constructor(logger?: Logger);
|
|
11
|
+
/**
|
|
12
|
+
* Validate a single file
|
|
13
|
+
*/
|
|
14
|
+
validateFile(filePath: string, options?: ValidationOptions): Promise<ValidationResult>;
|
|
15
|
+
/**
|
|
16
|
+
* Validate multiple files in batch
|
|
17
|
+
*/
|
|
18
|
+
validateBatch(filePaths: string[], options?: ValidationOptions): Promise<BatchValidationResult>;
|
|
19
|
+
/**
|
|
20
|
+
* Detect language from file extension
|
|
21
|
+
*/
|
|
22
|
+
private detectLanguage;
|
|
23
|
+
/**
|
|
24
|
+
* Calculate quality score (0-100)
|
|
25
|
+
*/
|
|
26
|
+
private calculateScore;
|
|
27
|
+
/**
|
|
28
|
+
* Generate summary text
|
|
29
|
+
*/
|
|
30
|
+
private generateSummary;
|
|
31
|
+
/**
|
|
32
|
+
* Generate batch summary
|
|
33
|
+
*/
|
|
34
|
+
private generateBatchSummary;
|
|
35
|
+
}
|