@girardelli/architect 5.0.0 → 8.1.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/dist/{cli.d.ts → src/adapters/cli.d.ts} +1 -2
- package/dist/{cli.js → src/adapters/cli.js} +191 -213
- package/dist/src/adapters/cli.js.map +1 -0
- package/dist/src/adapters/github-action.d.ts +9 -0
- package/dist/src/adapters/github-action.js +94 -0
- package/dist/src/adapters/github-action.js.map +1 -0
- package/dist/src/adapters/html-reporter/scripts.d.ts +5 -0
- package/dist/src/adapters/html-reporter/scripts.js +400 -0
- package/dist/src/adapters/html-reporter/scripts.js.map +1 -0
- package/dist/src/adapters/html-reporter/sections/agents.d.ts +2 -0
- package/dist/src/adapters/html-reporter/sections/agents.js +260 -0
- package/dist/src/adapters/html-reporter/sections/agents.js.map +1 -0
- package/dist/src/adapters/html-reporter/sections/anti-patterns.d.ts +13 -0
- package/dist/src/adapters/html-reporter/sections/anti-patterns.js +64 -0
- package/dist/src/adapters/html-reporter/sections/anti-patterns.js.map +1 -0
- package/dist/src/adapters/html-reporter/sections/header.d.ts +3 -0
- package/dist/src/adapters/html-reporter/sections/header.js +30 -0
- package/dist/src/adapters/html-reporter/sections/header.js.map +1 -0
- package/dist/src/adapters/html-reporter/sections/layers.d.ts +9 -0
- package/dist/src/adapters/html-reporter/sections/layers.js +143 -0
- package/dist/src/adapters/html-reporter/sections/layers.js.map +1 -0
- package/dist/src/adapters/html-reporter/sections/overview.d.ts +2 -0
- package/dist/src/adapters/html-reporter/sections/overview.js +58 -0
- package/dist/src/adapters/html-reporter/sections/overview.js.map +1 -0
- package/dist/src/adapters/html-reporter/sections/refactoring-plan.d.ts +3 -0
- package/dist/src/adapters/html-reporter/sections/refactoring-plan.js +151 -0
- package/dist/src/adapters/html-reporter/sections/refactoring-plan.js.map +1 -0
- package/dist/src/adapters/html-reporter/sections/score.d.ts +7 -0
- package/dist/src/adapters/html-reporter/sections/score.js +70 -0
- package/dist/src/adapters/html-reporter/sections/score.js.map +1 -0
- package/dist/src/adapters/html-reporter/sections/suggestions.d.ts +7 -0
- package/dist/src/adapters/html-reporter/sections/suggestions.js +34 -0
- package/dist/src/adapters/html-reporter/sections/suggestions.js.map +1 -0
- package/dist/src/adapters/html-reporter/styles.d.ts +1 -0
- package/dist/src/adapters/html-reporter/styles.js +526 -0
- package/dist/src/adapters/html-reporter/styles.js.map +1 -0
- package/dist/src/adapters/html-reporter/utils_adapters.d.ts +20 -0
- package/dist/src/adapters/html-reporter/utils_adapters.js +32 -0
- package/dist/src/adapters/html-reporter/utils_adapters.js.map +1 -0
- package/dist/src/adapters/html-reporter/utils_sections.d.ts +7 -0
- package/dist/src/adapters/html-reporter/utils_sections.js +58 -0
- package/dist/src/adapters/html-reporter/utils_sections.js.map +1 -0
- package/dist/src/adapters/html-reporter.d.ts +10 -0
- package/dist/src/adapters/html-reporter.js +97 -0
- package/dist/src/adapters/html-reporter.js.map +1 -0
- package/dist/src/adapters/progress-logger.d.ts +55 -0
- package/dist/src/adapters/progress-logger.js +200 -0
- package/dist/src/adapters/progress-logger.js.map +1 -0
- package/dist/{refactor-reporter.d.ts → src/adapters/refactor-reporter.d.ts} +1 -2
- package/dist/{refactor-reporter.js → src/adapters/refactor-reporter.js} +1 -1
- package/dist/src/adapters/refactor-reporter.js.map +1 -0
- package/dist/{reporter.d.ts → src/adapters/reporter.d.ts} +1 -2
- package/dist/src/adapters/reporter.js.map +1 -0
- package/dist/src/core/GenesisTerminal.d.ts +8 -0
- package/dist/src/core/GenesisTerminal.js +105 -0
- package/dist/src/core/GenesisTerminal.js.map +1 -0
- package/dist/{index.d.ts → src/core/architect.d.ts} +4 -18
- package/dist/{index.js → src/core/architect.js} +22 -21
- package/dist/src/core/architect.js.map +1 -0
- package/dist/tests/architect-adapter-enrichment.test.d.ts +1 -0
- package/dist/tests/architect-adapter-enrichment.test.js +11 -0
- package/dist/tests/architect-adapter-enrichment.test.js.map +1 -0
- package/dist/tests/github-action.test.d.ts +1 -0
- package/dist/tests/github-action.test.js +92 -0
- package/dist/tests/github-action.test.js.map +1 -0
- package/package.json +15 -65
- package/src/adapters/cli.ts +492 -0
- package/src/adapters/github-action.ts +109 -0
- package/src/adapters/html-reporter/scripts.ts +402 -0
- package/src/adapters/html-reporter/sections/agents.ts +267 -0
- package/src/adapters/html-reporter/sections/anti-patterns.ts +81 -0
- package/src/adapters/html-reporter/sections/header.ts +35 -0
- package/src/adapters/html-reporter/sections/layers.ts +165 -0
- package/src/adapters/html-reporter/sections/overview.ts +64 -0
- package/src/adapters/html-reporter/sections/refactoring-plan.ts +166 -0
- package/src/adapters/html-reporter/sections/score.ts +80 -0
- package/src/adapters/html-reporter/sections/suggestions.ts +39 -0
- package/src/adapters/html-reporter/styles.ts +525 -0
- package/src/adapters/html-reporter/utils_adapters.ts +39 -0
- package/src/adapters/html-reporter/utils_sections.ts +55 -0
- package/src/adapters/html-reporter.ts +102 -0
- package/src/adapters/progress-logger.ts +236 -0
- package/src/{refactor-reporter.ts → adapters/refactor-reporter.ts} +2 -2
- package/src/{reporter.ts → adapters/reporter.ts} +1 -1
- package/src/core/GenesisTerminal.ts +127 -0
- package/src/{index.ts → core/architect.ts} +27 -45
- package/tests/github-action.test.ts +109 -0
- package/tsconfig.json +12 -19
- package/CONTRIBUTING.md +0 -140
- package/LICENSE +0 -21
- package/PROJECT_STRUCTURE.txt +0 -168
- package/README.md +0 -257
- package/architect-run.sh +0 -431
- package/assets/banner-v3.html +0 -561
- package/dist/agent-generator/context-enricher.d.ts +0 -58
- package/dist/agent-generator/context-enricher.d.ts.map +0 -1
- package/dist/agent-generator/context-enricher.js +0 -613
- package/dist/agent-generator/context-enricher.js.map +0 -1
- package/dist/agent-generator/domain-inferrer.d.ts +0 -52
- package/dist/agent-generator/domain-inferrer.d.ts.map +0 -1
- package/dist/agent-generator/domain-inferrer.js +0 -585
- package/dist/agent-generator/domain-inferrer.js.map +0 -1
- package/dist/agent-generator/framework-detector.d.ts +0 -40
- package/dist/agent-generator/framework-detector.d.ts.map +0 -1
- package/dist/agent-generator/framework-detector.js +0 -611
- package/dist/agent-generator/framework-detector.js.map +0 -1
- package/dist/agent-generator/index.d.ts +0 -47
- package/dist/agent-generator/index.d.ts.map +0 -1
- package/dist/agent-generator/index.js +0 -545
- package/dist/agent-generator/index.js.map +0 -1
- package/dist/agent-generator/stack-detector.d.ts +0 -14
- package/dist/agent-generator/stack-detector.d.ts.map +0 -1
- package/dist/agent-generator/stack-detector.js +0 -124
- package/dist/agent-generator/stack-detector.js.map +0 -1
- package/dist/agent-generator/templates/core/agents.d.ts +0 -17
- package/dist/agent-generator/templates/core/agents.d.ts.map +0 -1
- package/dist/agent-generator/templates/core/agents.js +0 -1256
- package/dist/agent-generator/templates/core/agents.js.map +0 -1
- package/dist/agent-generator/templates/core/architecture-rules.d.ts +0 -7
- package/dist/agent-generator/templates/core/architecture-rules.d.ts.map +0 -1
- package/dist/agent-generator/templates/core/architecture-rules.js +0 -274
- package/dist/agent-generator/templates/core/architecture-rules.js.map +0 -1
- package/dist/agent-generator/templates/core/general-rules.d.ts +0 -8
- package/dist/agent-generator/templates/core/general-rules.d.ts.map +0 -1
- package/dist/agent-generator/templates/core/general-rules.js +0 -301
- package/dist/agent-generator/templates/core/general-rules.js.map +0 -1
- package/dist/agent-generator/templates/core/hooks-generator.d.ts +0 -21
- package/dist/agent-generator/templates/core/hooks-generator.d.ts.map +0 -1
- package/dist/agent-generator/templates/core/hooks-generator.js +0 -233
- package/dist/agent-generator/templates/core/hooks-generator.js.map +0 -1
- package/dist/agent-generator/templates/core/index-md.d.ts +0 -7
- package/dist/agent-generator/templates/core/index-md.d.ts.map +0 -1
- package/dist/agent-generator/templates/core/index-md.js +0 -246
- package/dist/agent-generator/templates/core/index-md.js.map +0 -1
- package/dist/agent-generator/templates/core/orchestrator.d.ts +0 -8
- package/dist/agent-generator/templates/core/orchestrator.d.ts.map +0 -1
- package/dist/agent-generator/templates/core/orchestrator.js +0 -422
- package/dist/agent-generator/templates/core/orchestrator.js.map +0 -1
- package/dist/agent-generator/templates/core/preflight.d.ts +0 -8
- package/dist/agent-generator/templates/core/preflight.d.ts.map +0 -1
- package/dist/agent-generator/templates/core/preflight.js +0 -213
- package/dist/agent-generator/templates/core/preflight.js.map +0 -1
- package/dist/agent-generator/templates/core/quality-gates.d.ts +0 -11
- package/dist/agent-generator/templates/core/quality-gates.d.ts.map +0 -1
- package/dist/agent-generator/templates/core/quality-gates.js +0 -254
- package/dist/agent-generator/templates/core/quality-gates.js.map +0 -1
- package/dist/agent-generator/templates/core/security-rules.d.ts +0 -7
- package/dist/agent-generator/templates/core/security-rules.d.ts.map +0 -1
- package/dist/agent-generator/templates/core/security-rules.js +0 -528
- package/dist/agent-generator/templates/core/security-rules.js.map +0 -1
- package/dist/agent-generator/templates/core/skills-generator.d.ts +0 -19
- package/dist/agent-generator/templates/core/skills-generator.d.ts.map +0 -1
- package/dist/agent-generator/templates/core/skills-generator.js +0 -546
- package/dist/agent-generator/templates/core/skills-generator.js.map +0 -1
- package/dist/agent-generator/templates/core/workflow-fix-bug.d.ts +0 -7
- package/dist/agent-generator/templates/core/workflow-fix-bug.d.ts.map +0 -1
- package/dist/agent-generator/templates/core/workflow-fix-bug.js +0 -237
- package/dist/agent-generator/templates/core/workflow-fix-bug.js.map +0 -1
- package/dist/agent-generator/templates/core/workflow-new-feature.d.ts +0 -8
- package/dist/agent-generator/templates/core/workflow-new-feature.d.ts.map +0 -1
- package/dist/agent-generator/templates/core/workflow-new-feature.js +0 -321
- package/dist/agent-generator/templates/core/workflow-new-feature.js.map +0 -1
- package/dist/agent-generator/templates/core/workflow-review.d.ts +0 -7
- package/dist/agent-generator/templates/core/workflow-review.d.ts.map +0 -1
- package/dist/agent-generator/templates/core/workflow-review.js +0 -104
- package/dist/agent-generator/templates/core/workflow-review.js.map +0 -1
- package/dist/agent-generator/templates/domain/index.d.ts +0 -22
- package/dist/agent-generator/templates/domain/index.d.ts.map +0 -1
- package/dist/agent-generator/templates/domain/index.js +0 -1176
- package/dist/agent-generator/templates/domain/index.js.map +0 -1
- package/dist/agent-generator/templates/stack/index.d.ts +0 -8
- package/dist/agent-generator/templates/stack/index.d.ts.map +0 -1
- package/dist/agent-generator/templates/stack/index.js +0 -695
- package/dist/agent-generator/templates/stack/index.js.map +0 -1
- package/dist/agent-generator/templates/template-helpers.d.ts +0 -75
- package/dist/agent-generator/templates/template-helpers.d.ts.map +0 -1
- package/dist/agent-generator/templates/template-helpers.js +0 -726
- package/dist/agent-generator/templates/template-helpers.js.map +0 -1
- package/dist/agent-generator/types.d.ts +0 -196
- package/dist/agent-generator/types.d.ts.map +0 -1
- package/dist/agent-generator/types.js +0 -27
- package/dist/agent-generator/types.js.map +0 -1
- package/dist/analyzer.d.ts +0 -38
- package/dist/analyzer.d.ts.map +0 -1
- package/dist/analyzer.js +0 -383
- package/dist/analyzer.js.map +0 -1
- package/dist/analyzers/forecast.d.ts +0 -85
- package/dist/analyzers/forecast.d.ts.map +0 -1
- package/dist/analyzers/forecast.js +0 -337
- package/dist/analyzers/forecast.js.map +0 -1
- package/dist/analyzers/git-cache.d.ts +0 -7
- package/dist/analyzers/git-cache.d.ts.map +0 -1
- package/dist/analyzers/git-cache.js +0 -41
- package/dist/analyzers/git-cache.js.map +0 -1
- package/dist/analyzers/git-history.d.ts +0 -113
- package/dist/analyzers/git-history.d.ts.map +0 -1
- package/dist/analyzers/git-history.js +0 -333
- package/dist/analyzers/git-history.js.map +0 -1
- package/dist/analyzers/index.d.ts +0 -10
- package/dist/analyzers/index.d.ts.map +0 -1
- package/dist/analyzers/index.js +0 -7
- package/dist/analyzers/index.js.map +0 -1
- package/dist/analyzers/temporal-scorer.d.ts +0 -72
- package/dist/analyzers/temporal-scorer.d.ts.map +0 -1
- package/dist/analyzers/temporal-scorer.js +0 -140
- package/dist/analyzers/temporal-scorer.js.map +0 -1
- package/dist/anti-patterns.d.ts +0 -24
- package/dist/anti-patterns.d.ts.map +0 -1
- package/dist/anti-patterns.js +0 -230
- package/dist/anti-patterns.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/config.d.ts +0 -12
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -110
- package/dist/config.js.map +0 -1
- package/dist/diagram.d.ts +0 -9
- package/dist/diagram.d.ts.map +0 -1
- package/dist/diagram.js +0 -116
- package/dist/diagram.js.map +0 -1
- package/dist/html-reporter.d.ts +0 -47
- package/dist/html-reporter.d.ts.map +0 -1
- package/dist/html-reporter.js +0 -1747
- package/dist/html-reporter.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/project-summarizer.d.ts +0 -38
- package/dist/project-summarizer.d.ts.map +0 -1
- package/dist/project-summarizer.js +0 -463
- package/dist/project-summarizer.js.map +0 -1
- package/dist/refactor-engine.d.ts +0 -18
- package/dist/refactor-engine.d.ts.map +0 -1
- package/dist/refactor-engine.js +0 -86
- package/dist/refactor-engine.js.map +0 -1
- package/dist/refactor-reporter.d.ts.map +0 -1
- package/dist/refactor-reporter.js.map +0 -1
- package/dist/reporter.d.ts.map +0 -1
- package/dist/reporter.js.map +0 -1
- package/dist/rules/barrel-optimizer.d.ts +0 -13
- package/dist/rules/barrel-optimizer.d.ts.map +0 -1
- package/dist/rules/barrel-optimizer.js +0 -77
- package/dist/rules/barrel-optimizer.js.map +0 -1
- package/dist/rules/dead-code-detector.d.ts +0 -21
- package/dist/rules/dead-code-detector.d.ts.map +0 -1
- package/dist/rules/dead-code-detector.js +0 -117
- package/dist/rules/dead-code-detector.js.map +0 -1
- package/dist/rules/hub-splitter.d.ts +0 -13
- package/dist/rules/hub-splitter.d.ts.map +0 -1
- package/dist/rules/hub-splitter.js +0 -110
- package/dist/rules/hub-splitter.js.map +0 -1
- package/dist/rules/import-organizer.d.ts +0 -13
- package/dist/rules/import-organizer.d.ts.map +0 -1
- package/dist/rules/import-organizer.js +0 -85
- package/dist/rules/import-organizer.js.map +0 -1
- package/dist/rules/module-grouper.d.ts +0 -13
- package/dist/rules/module-grouper.d.ts.map +0 -1
- package/dist/rules/module-grouper.js +0 -110
- package/dist/rules/module-grouper.js.map +0 -1
- package/dist/scanner.d.ts +0 -31
- package/dist/scanner.d.ts.map +0 -1
- package/dist/scanner.js +0 -328
- package/dist/scanner.js.map +0 -1
- package/dist/scorer.d.ts +0 -27
- package/dist/scorer.d.ts.map +0 -1
- package/dist/scorer.js +0 -229
- package/dist/scorer.js.map +0 -1
- package/dist/types.d.ts +0 -186
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/examples/sample-report.md +0 -207
- package/jest.config.js +0 -18
- package/src/agent-generator/context-enricher.ts +0 -672
- package/src/agent-generator/domain-inferrer.ts +0 -635
- package/src/agent-generator/framework-detector.ts +0 -669
- package/src/agent-generator/index.ts +0 -634
- package/src/agent-generator/stack-detector.ts +0 -115
- package/src/agent-generator/templates/core/agents.ts +0 -1296
- package/src/agent-generator/templates/core/architecture-rules.ts +0 -287
- package/src/agent-generator/templates/core/general-rules.ts +0 -306
- package/src/agent-generator/templates/core/hooks-generator.ts +0 -242
- package/src/agent-generator/templates/core/index-md.ts +0 -260
- package/src/agent-generator/templates/core/orchestrator.ts +0 -459
- package/src/agent-generator/templates/core/preflight.ts +0 -215
- package/src/agent-generator/templates/core/quality-gates.ts +0 -256
- package/src/agent-generator/templates/core/security-rules.ts +0 -543
- package/src/agent-generator/templates/core/skills-generator.ts +0 -585
- package/src/agent-generator/templates/core/workflow-fix-bug.ts +0 -239
- package/src/agent-generator/templates/core/workflow-new-feature.ts +0 -323
- package/src/agent-generator/templates/core/workflow-review.ts +0 -106
- package/src/agent-generator/templates/domain/index.ts +0 -1201
- package/src/agent-generator/templates/stack/index.ts +0 -705
- package/src/agent-generator/templates/template-helpers.ts +0 -776
- package/src/agent-generator/types.ts +0 -232
- package/src/analyzer.ts +0 -447
- package/src/analyzers/forecast.ts +0 -496
- package/src/analyzers/git-cache.ts +0 -52
- package/src/analyzers/git-history.ts +0 -488
- package/src/analyzers/index.ts +0 -33
- package/src/analyzers/temporal-scorer.ts +0 -227
- package/src/anti-patterns.ts +0 -287
- package/src/cli.ts +0 -517
- package/src/config.ts +0 -123
- package/src/diagram.ts +0 -144
- package/src/html-reporter.ts +0 -1830
- package/src/project-summarizer.ts +0 -521
- package/src/refactor-engine.ts +0 -117
- package/src/rules/barrel-optimizer.ts +0 -97
- package/src/rules/dead-code-detector.ts +0 -132
- package/src/rules/hub-splitter.ts +0 -123
- package/src/rules/import-organizer.ts +0 -98
- package/src/rules/module-grouper.ts +0 -124
- package/src/scanner.ts +0 -344
- package/src/scorer.ts +0 -254
- package/src/types.ts +0 -193
- package/tests/agent-generator.test.ts +0 -427
- package/tests/analyzers-integration.test.ts +0 -174
- package/tests/anti-patterns.test.ts +0 -94
- package/tests/context-enricher.test.ts +0 -971
- package/tests/fixtures/monorepo/package.json +0 -6
- package/tests/fixtures/monorepo/packages/app/package.json +0 -12
- package/tests/fixtures/monorepo/packages/app/src/index.ts +0 -6
- package/tests/fixtures/monorepo/packages/core/package.json +0 -7
- package/tests/fixtures/monorepo/packages/core/src/index.ts +0 -7
- package/tests/forecast.test.ts +0 -509
- package/tests/framework-detector.test.ts +0 -1172
- package/tests/git-history.test.ts +0 -254
- package/tests/monorepo-scan.test.ts +0 -170
- package/tests/scanner.test.ts +0 -54
- package/tests/scorer.test.ts +0 -674
- package/tests/stack-detector.test.ts +0 -241
- package/tests/template-generation.test.ts +0 -706
- package/tests/template-helpers.test.ts +0 -1152
- package/tests/temporal-scorer.test.ts +0 -307
- /package/dist/{reporter.js → src/adapters/reporter.js} +0 -0
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
import { AnalysisReport, RefactoringPlan } from '../types.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Stack detection result from project analysis.
|
|
5
|
-
*/
|
|
6
|
-
export interface StackInfo {
|
|
7
|
-
primary: string;
|
|
8
|
-
languages: string[];
|
|
9
|
-
frameworks: string[];
|
|
10
|
-
hasBackend: boolean;
|
|
11
|
-
hasFrontend: boolean;
|
|
12
|
-
hasMobile: boolean;
|
|
13
|
-
hasDatabase: boolean;
|
|
14
|
-
testFramework: string;
|
|
15
|
-
packageManager: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Audit finding for existing agent directories.
|
|
20
|
-
*/
|
|
21
|
-
export interface AgentAuditFinding {
|
|
22
|
-
type: 'MISSING' | 'OUTDATED' | 'IMPROVEMENT' | 'OK';
|
|
23
|
-
category: string;
|
|
24
|
-
file: string;
|
|
25
|
-
description: string;
|
|
26
|
-
suggestion?: string;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Status of each agent system item relative to existing .agent/ directory.
|
|
31
|
-
*/
|
|
32
|
-
export type AgentItemStatus = 'KEEP' | 'MODIFY' | 'CREATE' | 'DELETE';
|
|
33
|
-
|
|
34
|
-
export interface AgentItem {
|
|
35
|
-
name: string;
|
|
36
|
-
status: AgentItemStatus;
|
|
37
|
-
reason?: string;
|
|
38
|
-
description?: string;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Result from suggest() — no files written, just recommendations.
|
|
43
|
-
*/
|
|
44
|
-
export interface AgentSuggestion {
|
|
45
|
-
stack: StackInfo;
|
|
46
|
-
hasExistingAgents: boolean;
|
|
47
|
-
suggestedAgents: AgentItem[];
|
|
48
|
-
suggestedRules: AgentItem[];
|
|
49
|
-
suggestedGuards: AgentItem[];
|
|
50
|
-
suggestedWorkflows: AgentItem[];
|
|
51
|
-
suggestedSkills: { name: string; source: string; description: string; status: AgentItemStatus }[];
|
|
52
|
-
audit: AgentAuditFinding[];
|
|
53
|
-
command: string;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Context passed to all template generators.
|
|
58
|
-
*/
|
|
59
|
-
export interface TemplateContext {
|
|
60
|
-
report: AnalysisReport;
|
|
61
|
-
plan: RefactoringPlan;
|
|
62
|
-
stack: StackInfo;
|
|
63
|
-
projectName: string;
|
|
64
|
-
stackLabel: string;
|
|
65
|
-
config: AgentGeneratorConfig;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Configuration for agent generation — customizable per project.
|
|
70
|
-
*/
|
|
71
|
-
export interface AgentGeneratorConfig {
|
|
72
|
-
coverageMinimum: number;
|
|
73
|
-
scoreThreshold: number;
|
|
74
|
-
language: 'pt-BR' | 'en';
|
|
75
|
-
goldenRules: string[];
|
|
76
|
-
blockers: string[];
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Domain classification inferred from project analysis.
|
|
81
|
-
*/
|
|
82
|
-
export interface DomainInsights {
|
|
83
|
-
/** Primary domain category (e.g., 'fintech', 'healthtech', 'e-commerce') */
|
|
84
|
-
domain: string;
|
|
85
|
-
/** Specific sub-domain (e.g., 'tax-processing', 'payment-gateway') */
|
|
86
|
-
subDomain: string;
|
|
87
|
-
/** Human-readable description of what the project does */
|
|
88
|
-
description: string;
|
|
89
|
-
/** Business entities detected from models/entities/schemas */
|
|
90
|
-
businessEntities: BusinessEntity[];
|
|
91
|
-
/** Regulatory/compliance requirements inferred from domain */
|
|
92
|
-
compliance: ComplianceRequirement[];
|
|
93
|
-
/** External integrations detected or inferred */
|
|
94
|
-
integrations: ExternalIntegration[];
|
|
95
|
-
/** Domain-specific keywords extracted from code */
|
|
96
|
-
keywords: string[];
|
|
97
|
-
/** Confidence level of domain inference (0-1) */
|
|
98
|
-
confidence: number;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export interface BusinessEntity {
|
|
102
|
-
name: string;
|
|
103
|
-
source: string; // file path where detected
|
|
104
|
-
fields: string[];
|
|
105
|
-
relationships: string[];
|
|
106
|
-
layer: 'model' | 'entity' | 'schema' | 'dto' | 'unknown';
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export interface ComplianceRequirement {
|
|
110
|
-
name: string; // e.g., 'LGPD', 'HIPAA', 'PCI-DSS', 'SOX', 'GDPR'
|
|
111
|
-
reason: string;
|
|
112
|
-
mandatoryChecks: string[];
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export interface ExternalIntegration {
|
|
116
|
-
name: string;
|
|
117
|
-
type: 'api' | 'database' | 'queue' | 'storage' | 'payment' | 'auth' | 'government' | 'other';
|
|
118
|
-
detectedFrom: string;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Detailed module information extracted from project analysis.
|
|
123
|
-
*/
|
|
124
|
-
export interface ModuleDetail {
|
|
125
|
-
name: string;
|
|
126
|
-
path: string;
|
|
127
|
-
files: string[];
|
|
128
|
-
fileCount: number;
|
|
129
|
-
lineCount: number;
|
|
130
|
-
description: string;
|
|
131
|
-
hasTests: boolean;
|
|
132
|
-
testFiles: string[];
|
|
133
|
-
entities: string[];
|
|
134
|
-
controllers: string[];
|
|
135
|
-
services: string[];
|
|
136
|
-
layer: string;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* API endpoint detected from route/controller files.
|
|
141
|
-
*/
|
|
142
|
-
export interface DetectedEndpoint {
|
|
143
|
-
method: string; // GET, POST, PUT, DELETE, PATCH
|
|
144
|
-
path: string;
|
|
145
|
-
file: string;
|
|
146
|
-
handler: string;
|
|
147
|
-
hasAuth: boolean;
|
|
148
|
-
hasValidation: boolean;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Detected framework with version, detected from dependency files.
|
|
153
|
-
*/
|
|
154
|
-
export interface FrameworkInfo {
|
|
155
|
-
/** Framework name (e.g., 'FastAPI', 'NestJS', 'Django', 'Spring Boot') */
|
|
156
|
-
name: string;
|
|
157
|
-
/** Detected version (e.g., '0.104.1') or null */
|
|
158
|
-
version: string | null;
|
|
159
|
-
/** Category of framework */
|
|
160
|
-
category: 'web' | 'orm' | 'test' | 'lint' | 'build' | 'other';
|
|
161
|
-
/** Confidence level (0-1) */
|
|
162
|
-
confidence: number;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Detected toolchain — build, test, lint, run commands.
|
|
167
|
-
*/
|
|
168
|
-
export interface DetectedToolchain {
|
|
169
|
-
/** Build command (e.g., 'npm run build', 'make build', 'mvn package') */
|
|
170
|
-
buildCmd: string;
|
|
171
|
-
/** Test command (e.g., 'pytest', 'npm test', 'go test ./...') */
|
|
172
|
-
testCmd: string;
|
|
173
|
-
/** Lint command (e.g., 'ruff check .', 'eslint .', 'golangci-lint run') */
|
|
174
|
-
lintCmd: string;
|
|
175
|
-
/** Run/dev command (e.g., 'uvicorn main:app', 'npm run dev') */
|
|
176
|
-
runCmd: string;
|
|
177
|
-
/** Coverage command */
|
|
178
|
-
coverageCmd: string;
|
|
179
|
-
/** Dependency install command */
|
|
180
|
-
installCmd: string;
|
|
181
|
-
/** Migration command (if applicable) */
|
|
182
|
-
migrateCmd: string | null;
|
|
183
|
-
/** Dependency file (e.g., 'requirements.txt', 'package.json') */
|
|
184
|
-
depsFile: string;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Enriched template context with domain awareness.
|
|
189
|
-
*/
|
|
190
|
-
export interface EnrichedTemplateContext extends TemplateContext {
|
|
191
|
-
domain: DomainInsights;
|
|
192
|
-
modules: ModuleDetail[];
|
|
193
|
-
endpoints: DetectedEndpoint[];
|
|
194
|
-
untestedModules: string[];
|
|
195
|
-
criticalPaths: string[]; // files with highest coupling
|
|
196
|
-
projectDepth: 'small' | 'medium' | 'large' | 'enterprise'; // drives template verbosity
|
|
197
|
-
/** Detected frameworks with versions */
|
|
198
|
-
detectedFrameworks: FrameworkInfo[];
|
|
199
|
-
/** Primary web framework (e.g., 'FastAPI', 'NestJS', 'Django') */
|
|
200
|
-
primaryFramework: FrameworkInfo | null;
|
|
201
|
-
/** Detected toolchain commands */
|
|
202
|
-
toolchain: DetectedToolchain;
|
|
203
|
-
/** Real project structure pattern detected */
|
|
204
|
-
projectStructure: 'clean-architecture' | 'mvc' | 'modular' | 'flat' | 'monorepo' | 'unknown';
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
export const DEFAULT_AGENT_CONFIG: AgentGeneratorConfig = {
|
|
208
|
-
coverageMinimum: 80,
|
|
209
|
-
scoreThreshold: 70,
|
|
210
|
-
language: 'pt-BR',
|
|
211
|
-
goldenRules: [
|
|
212
|
-
'Git Flow completo (branch → PR → review → merge)',
|
|
213
|
-
'Arquitetura C4 (4 níveis de documentação)',
|
|
214
|
-
'BDD antes de código',
|
|
215
|
-
'TDD — Red → Green → Refactor',
|
|
216
|
-
'Diagnóstico obrigatório antes de codar',
|
|
217
|
-
'Mockup antes de qualquer UI',
|
|
218
|
-
'Nunca decidir sozinho — perguntar ao humano',
|
|
219
|
-
'Qualidade > Velocidade',
|
|
220
|
-
'Não abrir browser, não tirar screenshot — apenas código',
|
|
221
|
-
],
|
|
222
|
-
blockers: [
|
|
223
|
-
'console.log / print() em código de produção',
|
|
224
|
-
'TODO / FIXME / HACK sem issue vinculada',
|
|
225
|
-
'any (TypeScript) / type: ignore (Python) sem justificativa',
|
|
226
|
-
'Testes com .skip() ou @pytest.mark.skip sem motivo',
|
|
227
|
-
'Secrets, tokens ou senhas hardcoded',
|
|
228
|
-
'Push direto em main/develop',
|
|
229
|
-
'Arquivos > 500 linhas sem justificativa',
|
|
230
|
-
'Imports circulares',
|
|
231
|
-
],
|
|
232
|
-
};
|
package/src/analyzer.ts
DELETED
|
@@ -1,447 +0,0 @@
|
|
|
1
|
-
import { readFileSync, existsSync } from 'fs';
|
|
2
|
-
import { extname, relative, dirname, resolve, join } from 'path';
|
|
3
|
-
import { DependencyEdge, Layer, FileNode } from './types.js';
|
|
4
|
-
|
|
5
|
-
export class ArchitectureAnalyzer {
|
|
6
|
-
private projectPath: string;
|
|
7
|
-
private dependencyGraph: Map<string, Set<string>> = new Map();
|
|
8
|
-
private fileExtensions: Map<string, string> = new Map();
|
|
9
|
-
|
|
10
|
-
constructor(projectPath: string) {
|
|
11
|
-
this.projectPath = projectPath;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
analyzeDependencies(fileTree: FileNode): DependencyEdge[] {
|
|
15
|
-
this.getProjectPackageNames(fileTree);
|
|
16
|
-
this.buildDependencyGraph(fileTree);
|
|
17
|
-
return this.buildEdgeList();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
detectLayers(fileTree: FileNode): Layer[] {
|
|
21
|
-
const layers: Layer[] = [];
|
|
22
|
-
const apiFiles: string[] = [];
|
|
23
|
-
const serviceFiles: string[] = [];
|
|
24
|
-
const dataFiles: string[] = [];
|
|
25
|
-
const uiFiles: string[] = [];
|
|
26
|
-
const infraFiles: string[] = [];
|
|
27
|
-
|
|
28
|
-
this.categorizeFiles(fileTree, apiFiles, serviceFiles, dataFiles, uiFiles, infraFiles);
|
|
29
|
-
|
|
30
|
-
if (apiFiles.length > 0) {
|
|
31
|
-
layers.push({
|
|
32
|
-
name: 'API',
|
|
33
|
-
files: apiFiles,
|
|
34
|
-
description: 'API layer - handles external interfaces and routing',
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (serviceFiles.length > 0) {
|
|
39
|
-
layers.push({
|
|
40
|
-
name: 'Service',
|
|
41
|
-
files: serviceFiles,
|
|
42
|
-
description: 'Service layer - business logic and orchestration',
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (dataFiles.length > 0) {
|
|
47
|
-
layers.push({
|
|
48
|
-
name: 'Data',
|
|
49
|
-
files: dataFiles,
|
|
50
|
-
description: 'Data layer - database access and persistence',
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (uiFiles.length > 0) {
|
|
55
|
-
layers.push({
|
|
56
|
-
name: 'UI',
|
|
57
|
-
files: uiFiles,
|
|
58
|
-
description: 'UI layer - user interface components and views',
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (infraFiles.length > 0) {
|
|
63
|
-
layers.push({
|
|
64
|
-
name: 'Infrastructure',
|
|
65
|
-
files: infraFiles,
|
|
66
|
-
description: 'Infrastructure layer - configuration and setup',
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return layers;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
private buildDependencyGraph(node: FileNode): void {
|
|
74
|
-
if (node.type === 'file') {
|
|
75
|
-
const rawImports = this.parseImports(node.path);
|
|
76
|
-
const resolvedImports = rawImports.map(imp => this.resolveImportPath(node.path, imp));
|
|
77
|
-
this.dependencyGraph.set(node.path, new Set(resolvedImports));
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (node.children) {
|
|
81
|
-
for (const child of node.children) {
|
|
82
|
-
this.buildDependencyGraph(child);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Resolve a relative import path to an absolute file path.
|
|
89
|
-
* Tries common extensions (.ts, .tsx, .js, .jsx, /index.ts, etc.)
|
|
90
|
-
*/
|
|
91
|
-
private resolveImportPath(fromFile: string, importPath: string): string {
|
|
92
|
-
// Non-relative imports (Python module names, etc.) — return as-is
|
|
93
|
-
if (!importPath.startsWith('.')) return importPath;
|
|
94
|
-
|
|
95
|
-
const dir = dirname(fromFile);
|
|
96
|
-
const base = resolve(dir, importPath);
|
|
97
|
-
|
|
98
|
-
// Common extensions to try
|
|
99
|
-
const extensions = ['.ts', '.tsx', '.js', '.jsx', '.py', '.dart', '.go', '.java', '.rb'];
|
|
100
|
-
const indexFiles = extensions.map(ext => join(base, `index${ext}`));
|
|
101
|
-
|
|
102
|
-
// Try exact match first
|
|
103
|
-
if (existsSync(base) && !existsSync(base + '/')) return base;
|
|
104
|
-
|
|
105
|
-
// Try with extensions
|
|
106
|
-
for (const ext of extensions) {
|
|
107
|
-
const candidate = base + ext;
|
|
108
|
-
if (existsSync(candidate)) return candidate;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Try as directory with index file
|
|
112
|
-
for (const indexFile of indexFiles) {
|
|
113
|
-
if (existsSync(indexFile)) return indexFile;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Fallback: return the resolved path even if file not found
|
|
117
|
-
return base;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Known Python standard library modules (partial list of most common ones)
|
|
122
|
-
*/
|
|
123
|
-
private static readonly PYTHON_STDLIB: Set<string> = new Set([
|
|
124
|
-
'abc', 'aifc', 'argparse', 'array', 'ast', 'asynchat', 'asyncio', 'asyncore',
|
|
125
|
-
'atexit', 'base64', 'bdb', 'binascii', 'binhex', 'bisect', 'builtins',
|
|
126
|
-
'bz2', 'calendar', 'cgi', 'cgitb', 'chunk', 'cmath', 'cmd', 'code',
|
|
127
|
-
'codecs', 'codeop', 'collections', 'colorsys', 'compileall', 'concurrent',
|
|
128
|
-
'configparser', 'contextlib', 'contextvars', 'copy', 'copyreg', 'cProfile',
|
|
129
|
-
'crypt', 'csv', 'ctypes', 'curses', 'dataclasses', 'datetime', 'dbm',
|
|
130
|
-
'decimal', 'difflib', 'dis', 'distutils', 'doctest', 'email', 'encodings',
|
|
131
|
-
'enum', 'errno', 'faulthandler', 'fcntl', 'filecmp', 'fileinput', 'fnmatch',
|
|
132
|
-
'fractions', 'ftplib', 'functools', 'gc', 'getopt', 'getpass', 'gettext',
|
|
133
|
-
'glob', 'grp', 'gzip', 'hashlib', 'heapq', 'hmac', 'html', 'http',
|
|
134
|
-
'idlelib', 'imaplib', 'imghdr', 'imp', 'importlib', 'inspect', 'io',
|
|
135
|
-
'ipaddress', 'itertools', 'json', 'keyword', 'lib2to3', 'linecache',
|
|
136
|
-
'locale', 'logging', 'lzma', 'mailbox', 'mailcap', 'marshal', 'math',
|
|
137
|
-
'mimetypes', 'mmap', 'modulefinder', 'multiprocessing', 'netrc', 'nis',
|
|
138
|
-
'nntplib', 'numbers', 'operator', 'optparse', 'os', 'ossaudiodev',
|
|
139
|
-
'pathlib', 'pdb', 'pickle', 'pickletools', 'pipes', 'pkgutil', 'platform',
|
|
140
|
-
'plistlib', 'poplib', 'posix', 'posixpath', 'pprint', 'profile', 'pstats',
|
|
141
|
-
'pty', 'pwd', 'py_compile', 'pyclbr', 'pydoc', 'queue', 'quopri',
|
|
142
|
-
'random', 're', 'readline', 'reprlib', 'resource', 'rlcompleter', 'runpy',
|
|
143
|
-
'sched', 'secrets', 'select', 'selectors', 'shelve', 'shlex', 'shutil',
|
|
144
|
-
'signal', 'site', 'smtpd', 'smtplib', 'sndhdr', 'socket', 'socketserver',
|
|
145
|
-
'sqlite3', 'ssl', 'stat', 'statistics', 'string', 'stringprep', 'struct',
|
|
146
|
-
'subprocess', 'sunau', 'symtable', 'sys', 'sysconfig', 'syslog', 'tabnanny',
|
|
147
|
-
'tarfile', 'telnetlib', 'tempfile', 'termios', 'test', 'textwrap', 'threading',
|
|
148
|
-
'time', 'timeit', 'tkinter', 'token', 'tokenize', 'tomllib', 'trace',
|
|
149
|
-
'traceback', 'tracemalloc', 'tty', 'turtle', 'turtledemo', 'types',
|
|
150
|
-
'typing', 'unicodedata', 'unittest', 'urllib', 'uu', 'uuid', 'venv',
|
|
151
|
-
'warnings', 'wave', 'weakref', 'webbrowser', 'winreg', 'winsound',
|
|
152
|
-
'wsgiref', 'xdrlib', 'xml', 'xmlrpc', 'zipapp', 'zipfile', 'zipimport',
|
|
153
|
-
'zlib', '_thread',
|
|
154
|
-
]);
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Resolve the project's root Python package name from directory structure.
|
|
158
|
-
* E.g., for projectPath="/foo/src", if there's a "deepguard/" dir, the package is "deepguard".
|
|
159
|
-
*/
|
|
160
|
-
private projectPackageNames: Set<string> | null = null;
|
|
161
|
-
|
|
162
|
-
private getProjectPackageNames(fileTree: FileNode): Set<string> {
|
|
163
|
-
if (this.projectPackageNames) return this.projectPackageNames;
|
|
164
|
-
this.projectPackageNames = new Set<string>();
|
|
165
|
-
if (fileTree.children) {
|
|
166
|
-
for (const child of fileTree.children) {
|
|
167
|
-
if (child.type === 'directory') {
|
|
168
|
-
this.projectPackageNames.add(child.name);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
return this.projectPackageNames;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
private parseImports(filePath: string): string[] {
|
|
176
|
-
try {
|
|
177
|
-
const content = readFileSync(filePath, 'utf-8');
|
|
178
|
-
const ext = extname(filePath);
|
|
179
|
-
const imports: string[] = [];
|
|
180
|
-
|
|
181
|
-
if (ext === '.ts' || ext === '.tsx' || ext === '.js' || ext === '.jsx') {
|
|
182
|
-
const importRegex =
|
|
183
|
-
/(?:import|require)\s*(?:\{[^}]+\}|[^\s]+)\s*from\s*['"]([^'"]+)['"]/g;
|
|
184
|
-
let match;
|
|
185
|
-
while ((match = importRegex.exec(content)) !== null) {
|
|
186
|
-
const importPath = match[1];
|
|
187
|
-
// Only count relative imports (./ ../) as internal dependencies
|
|
188
|
-
if (importPath.startsWith('.')) {
|
|
189
|
-
imports.push(importPath);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
} else if (ext === '.py') {
|
|
193
|
-
// Parse "from X import Y" — capture X (the module source)
|
|
194
|
-
const fromImportRegex = /^from\s+([\w.]+)\s+import\b/gm;
|
|
195
|
-
let match;
|
|
196
|
-
while ((match = fromImportRegex.exec(content)) !== null) {
|
|
197
|
-
const moduleName = match[1];
|
|
198
|
-
if (this.isInternalPythonImport(moduleName)) {
|
|
199
|
-
imports.push(moduleName);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
// Parse "import X" — capture X
|
|
203
|
-
const directImportRegex = /^import\s+([\w.]+)(?:\s+as\s+\w+)?$/gm;
|
|
204
|
-
while ((match = directImportRegex.exec(content)) !== null) {
|
|
205
|
-
const moduleName = match[1];
|
|
206
|
-
if (this.isInternalPythonImport(moduleName)) {
|
|
207
|
-
imports.push(moduleName);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
} else if (ext === '.java') {
|
|
211
|
-
const importRegex = /import\s+([^\s;]+);/g;
|
|
212
|
-
let match;
|
|
213
|
-
while ((match = importRegex.exec(content)) !== null) {
|
|
214
|
-
imports.push(match[1]);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return imports;
|
|
219
|
-
} catch {
|
|
220
|
-
return [];
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Check if a Python import is internal to the project.
|
|
226
|
-
* Internal imports: relative (starts with .) or matches project package names.
|
|
227
|
-
* External imports: stdlib, third-party (numpy, cv2, PIL, etc.)
|
|
228
|
-
*/
|
|
229
|
-
private isInternalPythonImport(moduleName: string): boolean {
|
|
230
|
-
// Relative imports are always internal
|
|
231
|
-
if (moduleName.startsWith('.')) return true;
|
|
232
|
-
|
|
233
|
-
// Get the top-level module name (e.g., "deepguard" from "deepguard.cli")
|
|
234
|
-
const topLevel = moduleName.split('.')[0];
|
|
235
|
-
|
|
236
|
-
// Check against Python stdlib
|
|
237
|
-
if (ArchitectureAnalyzer.PYTHON_STDLIB.has(topLevel)) return false;
|
|
238
|
-
|
|
239
|
-
// Check if it matches a known project package directory
|
|
240
|
-
if (this.projectPackageNames && this.projectPackageNames.has(topLevel)) return true;
|
|
241
|
-
|
|
242
|
-
// Default: treat unknown imports as external (conservative approach)
|
|
243
|
-
return false;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
private buildEdgeList(): DependencyEdge[] {
|
|
247
|
-
const edges: DependencyEdge[] = [];
|
|
248
|
-
const seenEdges = new Set<string>();
|
|
249
|
-
|
|
250
|
-
for (const [from, toSet] of this.dependencyGraph.entries()) {
|
|
251
|
-
for (const to of toSet) {
|
|
252
|
-
const edgeKey = `${from}->${to}`;
|
|
253
|
-
if (!seenEdges.has(edgeKey)) {
|
|
254
|
-
edges.push({
|
|
255
|
-
from,
|
|
256
|
-
to,
|
|
257
|
-
type: 'import',
|
|
258
|
-
weight: 1,
|
|
259
|
-
});
|
|
260
|
-
seenEdges.add(edgeKey);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
return edges;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
private categorizeFiles(
|
|
269
|
-
node: FileNode,
|
|
270
|
-
apiFiles: string[],
|
|
271
|
-
serviceFiles: string[],
|
|
272
|
-
dataFiles: string[],
|
|
273
|
-
uiFiles: string[],
|
|
274
|
-
infraFiles: string[]
|
|
275
|
-
): void {
|
|
276
|
-
if (node.type === 'file') {
|
|
277
|
-
const path = node.path.toLowerCase();
|
|
278
|
-
const name = node.name.toLowerCase();
|
|
279
|
-
|
|
280
|
-
// Skip test files — they don't belong to any architectural layer
|
|
281
|
-
if (
|
|
282
|
-
name.endsWith('.test.ts') || name.endsWith('.test.js') ||
|
|
283
|
-
name.endsWith('.spec.ts') || name.endsWith('.spec.js') ||
|
|
284
|
-
path.includes('/__tests__/') || path.includes('/__mocks__/')
|
|
285
|
-
) {
|
|
286
|
-
// Don't categorize test files into any layer
|
|
287
|
-
}
|
|
288
|
-
// Skip node_modules files (safety barrier)
|
|
289
|
-
else if (path.includes('node_modules')) {
|
|
290
|
-
// Don't categorize third-party files
|
|
291
|
-
}
|
|
292
|
-
// Data layer — check first (more specific patterns)
|
|
293
|
-
else if (
|
|
294
|
-
path.includes('/entities/') ||
|
|
295
|
-
path.includes('/entity/') ||
|
|
296
|
-
path.includes('/migrations/') ||
|
|
297
|
-
path.includes('/migration/') ||
|
|
298
|
-
path.includes('/seeds/') ||
|
|
299
|
-
path.includes('/seeders/') ||
|
|
300
|
-
path.includes('/data/') ||
|
|
301
|
-
path.includes('/db/') ||
|
|
302
|
-
path.includes('/database/') ||
|
|
303
|
-
path.includes('/models/') ||
|
|
304
|
-
path.includes('/schema/') ||
|
|
305
|
-
path.includes('/subscribers/') ||
|
|
306
|
-
name.endsWith('.entity.ts') ||
|
|
307
|
-
name.endsWith('.entity.js') ||
|
|
308
|
-
name.endsWith('.model.ts') ||
|
|
309
|
-
name.endsWith('.model.js') ||
|
|
310
|
-
name.includes('repository') ||
|
|
311
|
-
name.includes('dao') ||
|
|
312
|
-
name.includes('mapper') ||
|
|
313
|
-
name.includes('migration') ||
|
|
314
|
-
name.includes('seed') ||
|
|
315
|
-
name.includes('subscriber')
|
|
316
|
-
) {
|
|
317
|
-
dataFiles.push(node.path);
|
|
318
|
-
}
|
|
319
|
-
// Infrastructure layer
|
|
320
|
-
else if (
|
|
321
|
-
path.includes('/config/') ||
|
|
322
|
-
path.includes('/infra/') ||
|
|
323
|
-
path.includes('/infrastructure/') ||
|
|
324
|
-
path.includes('/setup/') ||
|
|
325
|
-
path.includes('/guards/') ||
|
|
326
|
-
path.includes('/pipes/') ||
|
|
327
|
-
path.includes('/interceptors/') ||
|
|
328
|
-
path.includes('/filters/') ||
|
|
329
|
-
path.includes('/decorators/') ||
|
|
330
|
-
path.includes('/middleware/') ||
|
|
331
|
-
path.includes('/middlewares/') ||
|
|
332
|
-
path.includes('/common/') ||
|
|
333
|
-
path.includes('/shared/') ||
|
|
334
|
-
path.includes('docker') ||
|
|
335
|
-
path.includes('kubernetes') ||
|
|
336
|
-
name.endsWith('.guard.ts') ||
|
|
337
|
-
name.endsWith('.pipe.ts') ||
|
|
338
|
-
name.endsWith('.interceptor.ts') ||
|
|
339
|
-
name.endsWith('.filter.ts') ||
|
|
340
|
-
name.endsWith('.decorator.ts') ||
|
|
341
|
-
name.endsWith('.middleware.ts') ||
|
|
342
|
-
name.includes('.config.') ||
|
|
343
|
-
name.includes('.module.')
|
|
344
|
-
) {
|
|
345
|
-
infraFiles.push(node.path);
|
|
346
|
-
}
|
|
347
|
-
// API layer
|
|
348
|
-
else if (
|
|
349
|
-
path.includes('/api/') ||
|
|
350
|
-
path.includes('/routes/') ||
|
|
351
|
-
path.includes('/controllers/') ||
|
|
352
|
-
name.endsWith('.controller.ts') ||
|
|
353
|
-
name.endsWith('.controller.js') ||
|
|
354
|
-
name.includes('route') ||
|
|
355
|
-
name.includes('controller') ||
|
|
356
|
-
name.includes('handler') ||
|
|
357
|
-
name.endsWith('.dto.ts') ||
|
|
358
|
-
name.endsWith('.dto.js')
|
|
359
|
-
) {
|
|
360
|
-
apiFiles.push(node.path);
|
|
361
|
-
}
|
|
362
|
-
// Service layer
|
|
363
|
-
else if (
|
|
364
|
-
path.includes('/service') ||
|
|
365
|
-
path.includes('/business') ||
|
|
366
|
-
path.includes('/logic') ||
|
|
367
|
-
path.includes('/use-cases/') ||
|
|
368
|
-
path.includes('/usecases/') ||
|
|
369
|
-
name.endsWith('.service.ts') ||
|
|
370
|
-
name.endsWith('.service.js') ||
|
|
371
|
-
name.includes('service') ||
|
|
372
|
-
name.includes('manager') ||
|
|
373
|
-
name.includes('facade') ||
|
|
374
|
-
name.includes('usecase')
|
|
375
|
-
) {
|
|
376
|
-
serviceFiles.push(node.path);
|
|
377
|
-
}
|
|
378
|
-
// UI layer
|
|
379
|
-
else if (
|
|
380
|
-
path.includes('/ui/') ||
|
|
381
|
-
path.includes('/components/') ||
|
|
382
|
-
path.includes('/pages/') ||
|
|
383
|
-
path.includes('/views/') ||
|
|
384
|
-
path.includes('/screens/') ||
|
|
385
|
-
path.includes('/templates/') ||
|
|
386
|
-
node.extension === '.tsx' ||
|
|
387
|
-
node.extension === '.jsx' ||
|
|
388
|
-
node.extension === '.vue' ||
|
|
389
|
-
node.extension === '.html'
|
|
390
|
-
) {
|
|
391
|
-
uiFiles.push(node.path);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
if (node.children) {
|
|
396
|
-
for (const child of node.children) {
|
|
397
|
-
this.categorizeFiles(
|
|
398
|
-
child,
|
|
399
|
-
apiFiles,
|
|
400
|
-
serviceFiles,
|
|
401
|
-
dataFiles,
|
|
402
|
-
uiFiles,
|
|
403
|
-
infraFiles
|
|
404
|
-
);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
getModuleBoundaries(fileTree: FileNode): Map<string, string[]> {
|
|
410
|
-
const modules = new Map<string, string[]>();
|
|
411
|
-
this.identifyModules(fileTree, '', modules);
|
|
412
|
-
return modules;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
private identifyModules(
|
|
416
|
-
node: FileNode,
|
|
417
|
-
parentPath: string,
|
|
418
|
-
modules: Map<string, string[]>
|
|
419
|
-
): void {
|
|
420
|
-
if (node.type === 'directory') {
|
|
421
|
-
const moduleFiles: string[] = [];
|
|
422
|
-
this.collectFilesInModule(node, moduleFiles);
|
|
423
|
-
|
|
424
|
-
if (moduleFiles.length > 0) {
|
|
425
|
-
modules.set(node.name, moduleFiles);
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
if (node.children) {
|
|
430
|
-
for (const child of node.children) {
|
|
431
|
-
this.identifyModules(child, parentPath + '/' + node.name, modules);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
private collectFilesInModule(node: FileNode, files: string[]): void {
|
|
437
|
-
if (node.type === 'file') {
|
|
438
|
-
files.push(node.path);
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
if (node.children) {
|
|
442
|
-
for (const child of node.children) {
|
|
443
|
-
this.collectFilesInModule(child, files);
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
}
|