ai-first-cli 1.2.3 → 1.3.1
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/.github/workflows/publish.yml +4 -1
- package/CHANGELOG.md +292 -6
- package/README.md +24 -4
- package/dist/analyzers/symbols.d.ts.map +1 -1
- package/dist/analyzers/symbols.js +9 -7
- package/dist/analyzers/symbols.js.map +1 -1
- package/dist/analyzers/techStack.d.ts.map +1 -1
- package/dist/analyzers/techStack.js +198 -3
- package/dist/analyzers/techStack.js.map +1 -1
- package/dist/commands/ai-first.d.ts.map +1 -1
- package/dist/commands/ai-first.js +14 -13
- package/dist/commands/ai-first.js.map +1 -1
- package/dist/core/analysis/architectureDetector.d.ts +37 -0
- package/dist/core/analysis/architectureDetector.d.ts.map +1 -0
- package/dist/core/analysis/architectureDetector.js +316 -0
- package/dist/core/analysis/architectureDetector.js.map +1 -0
- package/dist/core/analysis/callGraphBuilder.d.ts +37 -0
- package/dist/core/analysis/callGraphBuilder.d.ts.map +1 -0
- package/dist/core/analysis/callGraphBuilder.js +101 -0
- package/dist/core/analysis/callGraphBuilder.js.map +1 -0
- package/dist/core/analysis/dependencyAnalyzer.d.ts +45 -0
- package/dist/core/analysis/dependencyAnalyzer.d.ts.map +1 -0
- package/dist/core/analysis/dependencyAnalyzer.js +98 -0
- package/dist/core/analysis/dependencyAnalyzer.js.map +1 -0
- package/dist/core/analysis/index.d.ts +5 -0
- package/dist/core/analysis/index.d.ts.map +1 -0
- package/dist/core/analysis/index.js +5 -0
- package/dist/core/analysis/index.js.map +1 -0
- package/dist/core/analysis/inheritanceAnalyzer.d.ts +35 -0
- package/dist/core/analysis/inheritanceAnalyzer.d.ts.map +1 -0
- package/dist/core/analysis/inheritanceAnalyzer.js +115 -0
- package/dist/core/analysis/inheritanceAnalyzer.js.map +1 -0
- package/dist/core/ccp.d.ts.map +1 -1
- package/dist/core/ccp.js +3 -2
- package/dist/core/ccp.js.map +1 -1
- package/dist/core/generation/aiContextGenerator.d.ts +71 -0
- package/dist/core/generation/aiContextGenerator.d.ts.map +1 -0
- package/dist/core/generation/aiContextGenerator.js +217 -0
- package/dist/core/generation/aiContextGenerator.js.map +1 -0
- package/dist/core/generation/architectureGenerator.d.ts +17 -0
- package/dist/core/generation/architectureGenerator.d.ts.map +1 -0
- package/dist/core/generation/architectureGenerator.js +160 -0
- package/dist/core/generation/architectureGenerator.js.map +1 -0
- package/dist/core/generation/flowGenerator.d.ts +52 -0
- package/dist/core/generation/flowGenerator.d.ts.map +1 -0
- package/dist/core/generation/flowGenerator.js +164 -0
- package/dist/core/generation/flowGenerator.js.map +1 -0
- package/dist/core/generation/index.d.ts +4 -0
- package/dist/core/generation/index.d.ts.map +1 -0
- package/dist/core/generation/index.js +4 -0
- package/dist/core/generation/index.js.map +1 -0
- package/dist/core/hierarchyGenerator.d.ts.map +1 -1
- package/dist/core/hierarchyGenerator.js +3 -2
- package/dist/core/hierarchyGenerator.js.map +1 -1
- package/dist/core/parsers/index.d.ts +20 -0
- package/dist/core/parsers/index.d.ts.map +1 -0
- package/dist/core/parsers/index.js +76 -0
- package/dist/core/parsers/index.js.map +1 -0
- package/dist/core/parsers/pythonParser.d.ts +37 -0
- package/dist/core/parsers/pythonParser.d.ts.map +1 -0
- package/dist/core/parsers/pythonParser.js +229 -0
- package/dist/core/parsers/pythonParser.js.map +1 -0
- package/dist/core/parsers/typescriptParser.d.ts +54 -0
- package/dist/core/parsers/typescriptParser.d.ts.map +1 -0
- package/dist/core/parsers/typescriptParser.js +291 -0
- package/dist/core/parsers/typescriptParser.js.map +1 -0
- package/dist/core/pipeline.d.ts +42 -0
- package/dist/core/pipeline.d.ts.map +1 -0
- package/dist/core/pipeline.js +172 -0
- package/dist/core/pipeline.js.map +1 -0
- package/dist/core/semanticContexts.js +1 -1
- package/dist/core/semanticContexts.js.map +1 -1
- package/dist/utils/constants.d.ts +46 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +67 -0
- package/dist/utils/constants.js.map +1 -0
- package/package.json +1 -1
- package/run-all-tests.sh +184 -0
- package/src/analyzers/symbols.ts +12 -7
- package/src/analyzers/techStack.ts +203 -3
- package/src/commands/ai-first.ts +14 -13
- package/src/core/analysis/architectureDetector.ts +487 -0
- package/src/core/analysis/callGraphBuilder.ts +158 -0
- package/src/core/analysis/dependencyAnalyzer.ts +167 -0
- package/src/core/analysis/index.ts +28 -0
- package/src/core/analysis/inheritanceAnalyzer.ts +169 -0
- package/src/core/ccp.ts +3 -2
- package/src/core/generation/aiContextGenerator.ts +335 -0
- package/src/core/generation/architectureGenerator.ts +200 -0
- package/src/core/generation/flowGenerator.ts +238 -0
- package/src/core/generation/index.ts +16 -0
- package/src/core/hierarchyGenerator.ts +3 -2
- package/src/core/parsers/index.ts +99 -0
- package/src/core/parsers/pythonParser.ts +302 -0
- package/src/core/parsers/typescriptParser.ts +445 -0
- package/src/core/pipeline.ts +241 -0
- package/src/core/semanticContexts.ts +1 -1
- package/src/utils/constants.ts +78 -0
- package/test-ai-context-understanding.sh +21 -0
- package/test_adapters.mjs +11 -11
- package/tests/analysis.test.ts +283 -0
- package/tests/architectureDetector.test.ts +137 -0
- package/tests/generation.test.ts +216 -0
- package/tests/parserRegistry.test.ts +139 -0
- package/tests/pipeline.integration.test.ts +245 -0
- package/tests/pythonParser.test.ts +210 -0
- package/tests/typescriptParser.test.ts +197 -0
- package/.ai-dev/index.db +0 -0
- package/BUGS.md +0 -455
- package/PLAN_MEJORAS.md +0 -216
- package/STATUS_ADAPTADORES +0 -126
- package/TEST_RESULTS_PHASE1.md +0 -420
- package/ai/dependencies.json +0 -15
- package/ai/graph/knowledge-graph.json +0 -12
- package/ai-context/ai_context.md +0 -130
- package/ai-context/ai_rules.md +0 -54
- package/ai-context/architecture.md +0 -136
- package/ai-context/cache.json +0 -2349
- package/ai-context/ccp/jira-123/context.json +0 -7
- package/ai-context/context/features/commands.json +0 -18
- package/ai-context/context/features/src.json +0 -61
- package/ai-context/context/features/test-projects.json +0 -69
- package/ai-context/context/flows/account.json +0 -9
- package/ai-context/context/flows/ai-first.json +0 -9
- package/ai-context/context/flows/api.json +0 -9
- package/ai-context/context/flows/auth.json +0 -13
- package/ai-context/context/flows/category.json +0 -12
- package/ai-context/context/flows/comment.json +0 -16
- package/ai-context/context/flows/dashboard.json +0 -9
- package/ai-context/context/flows/doctor.json +0 -9
- package/ai-context/context/flows/explore.json +0 -9
- package/ai-context/context/flows/login.json +0 -9
- package/ai-context/context/flows/opportunity.json +0 -9
- package/ai-context/context/flows/post.json +0 -18
- package/ai-context/context/flows/routes.json +0 -19
- package/ai-context/context/flows/user.json +0 -20
- package/ai-context/context/flows/users.json +0 -9
- package/ai-context/context/flows/views.json +0 -14
- package/ai-context/context/repo.json +0 -56
- package/ai-context/context/utils.json +0 -7
- package/ai-context/conventions.md +0 -53
- package/ai-context/dependencies.json +0 -2978
- package/ai-context/embeddings.json +0 -23828
- package/ai-context/entrypoints.md +0 -42
- package/ai-context/files.json +0 -2944
- package/ai-context/git/commit-activity.json +0 -8646
- package/ai-context/git/recent-features.json +0 -1
- package/ai-context/git/recent-files.json +0 -52
- package/ai-context/git/recent-flows.json +0 -1
- package/ai-context/graph/knowledge-graph.json +0 -44129
- package/ai-context/graph/module-graph.json +0 -866
- package/ai-context/graph/symbol-graph.json +0 -200622
- package/ai-context/graph/symbol-references.json +0 -6778
- package/ai-context/hierarchy.json +0 -20
- package/ai-context/index-state.json +0 -4487
- package/ai-context/index.db +0 -0
- package/ai-context/modules.json +0 -933
- package/ai-context/project.json +0 -30
- package/ai-context/repo_map.json +0 -9116
- package/ai-context/repo_map.md +0 -2061
- package/ai-context/schema.json +0 -5
- package/ai-context/summary.md +0 -47
- package/ai-context/symbols.json +0 -65351
- package/ai-context/tech_stack.md +0 -47
- package/ai-context/tools.json +0 -10
- package/test-projects/django-app/.ai-dev/index.db +0 -0
- package/test-projects/django-app/ai-context/ai_context.md +0 -92
- package/test-projects/django-app/ai-context/ai_rules.md +0 -47
- package/test-projects/django-app/ai-context/architecture.md +0 -57
- package/test-projects/django-app/ai-context/cache.json +0 -169
- package/test-projects/django-app/ai-context/context/flows/views.json +0 -10
- package/test-projects/django-app/ai-context/conventions.md +0 -51
- package/test-projects/django-app/ai-context/dependencies.json +0 -312
- package/test-projects/django-app/ai-context/entrypoints.md +0 -4
- package/test-projects/django-app/ai-context/files.json +0 -209
- package/test-projects/django-app/ai-context/graph/knowledge-graph.json +0 -36
- package/test-projects/django-app/ai-context/graph/module-graph.json +0 -145
- package/test-projects/django-app/ai-context/graph/symbol-graph.json +0 -1488
- package/test-projects/django-app/ai-context/graph/symbol-references.json +0 -1
- package/test-projects/django-app/ai-context/index-state.json +0 -294
- package/test-projects/django-app/ai-context/index.db +0 -0
- package/test-projects/django-app/ai-context/modules.json +0 -35
- package/test-projects/django-app/ai-context/project.json +0 -11
- package/test-projects/django-app/ai-context/repo_map.json +0 -412
- package/test-projects/django-app/ai-context/repo_map.md +0 -105
- package/test-projects/django-app/ai-context/schema.json +0 -5
- package/test-projects/django-app/ai-context/summary.md +0 -15
- package/test-projects/django-app/ai-context/symbols.json +0 -1
- package/test-projects/django-app/ai-context/tech_stack.md +0 -32
- package/test-projects/django-app/ai-context/tools.json +0 -10
- package/test-projects/express-api/ai-context/ai_context.md +0 -112
- package/test-projects/express-api/ai-context/ai_rules.md +0 -50
- package/test-projects/express-api/ai-context/architecture.md +0 -62
- package/test-projects/express-api/ai-context/context/features/controllers.json +0 -13
- package/test-projects/express-api/ai-context/context/features/services.json +0 -13
- package/test-projects/express-api/ai-context/context/flows/auth.json +0 -12
- package/test-projects/express-api/ai-context/context/flows/user.json +0 -13
- package/test-projects/express-api/ai-context/conventions.md +0 -51
- package/test-projects/express-api/ai-context/dependencies.json +0 -54
- package/test-projects/express-api/ai-context/entrypoints.md +0 -17
- package/test-projects/express-api/ai-context/modules.json +0 -30
- package/test-projects/express-api/ai-context/project.json +0 -15
- package/test-projects/express-api/ai-context/repo_map.json +0 -100
- package/test-projects/express-api/ai-context/repo_map.md +0 -36
- package/test-projects/express-api/ai-context/schema.json +0 -5
- package/test-projects/express-api/ai-context/summary.md +0 -14
- package/test-projects/express-api/ai-context/symbols.json +0 -7
- package/test-projects/express-api/ai-context/tech_stack.md +0 -38
- package/test-projects/express-api/ai-context/tools.json +0 -10
- package/test-projects/fastapi-app/.ai-dev/index.db +0 -0
- package/test-projects/fastapi-app/ai-context/ai_context.md +0 -89
- package/test-projects/fastapi-app/ai-context/ai_rules.md +0 -47
- package/test-projects/fastapi-app/ai-context/architecture.md +0 -39
- package/test-projects/fastapi-app/ai-context/cache.json +0 -125
- package/test-projects/fastapi-app/ai-context/conventions.md +0 -51
- package/test-projects/fastapi-app/ai-context/dependencies.json +0 -244
- package/test-projects/fastapi-app/ai-context/entrypoints.md +0 -4
- package/test-projects/fastapi-app/ai-context/files.json +0 -154
- package/test-projects/fastapi-app/ai-context/graph/knowledge-graph.json +0 -15
- package/test-projects/fastapi-app/ai-context/graph/module-graph.json +0 -78
- package/test-projects/fastapi-app/ai-context/graph/symbol-graph.json +0 -1724
- package/test-projects/fastapi-app/ai-context/graph/symbol-references.json +0 -51
- package/test-projects/fastapi-app/ai-context/index-state.json +0 -217
- package/test-projects/fastapi-app/ai-context/index.db +0 -0
- package/test-projects/fastapi-app/ai-context/modules.json +0 -16
- package/test-projects/fastapi-app/ai-context/project.json +0 -9
- package/test-projects/fastapi-app/ai-context/repo_map.json +0 -298
- package/test-projects/fastapi-app/ai-context/repo_map.md +0 -74
- package/test-projects/fastapi-app/ai-context/schema.json +0 -5
- package/test-projects/fastapi-app/ai-context/summary.md +0 -12
- package/test-projects/fastapi-app/ai-context/symbols.json +0 -1
- package/test-projects/fastapi-app/ai-context/tech_stack.md +0 -32
- package/test-projects/fastapi-app/ai-context/tools.json +0 -10
- package/test-projects/flask-app/.ai-dev/index.db +0 -0
- package/test-projects/flask-app/ai-context/ai_context.md +0 -94
- package/test-projects/flask-app/ai-context/ai_rules.md +0 -47
- package/test-projects/flask-app/ai-context/architecture.md +0 -49
- package/test-projects/flask-app/ai-context/cache.json +0 -157
- package/test-projects/flask-app/ai-context/context/features/app.json +0 -25
- package/test-projects/flask-app/ai-context/context/flows/routes.json +0 -14
- package/test-projects/flask-app/ai-context/conventions.md +0 -51
- package/test-projects/flask-app/ai-context/dependencies.json +0 -298
- package/test-projects/flask-app/ai-context/entrypoints.md +0 -4
- package/test-projects/flask-app/ai-context/files.json +0 -194
- package/test-projects/flask-app/ai-context/graph/knowledge-graph.json +0 -60
- package/test-projects/flask-app/ai-context/graph/module-graph.json +0 -95
- package/test-projects/flask-app/ai-context/graph/symbol-graph.json +0 -1448
- package/test-projects/flask-app/ai-context/graph/symbol-references.json +0 -45
- package/test-projects/flask-app/ai-context/index-state.json +0 -273
- package/test-projects/flask-app/ai-context/index.db +0 -0
- package/test-projects/flask-app/ai-context/modules.json +0 -21
- package/test-projects/flask-app/ai-context/project.json +0 -13
- package/test-projects/flask-app/ai-context/repo_map.json +0 -400
- package/test-projects/flask-app/ai-context/repo_map.md +0 -98
- package/test-projects/flask-app/ai-context/schema.json +0 -5
- package/test-projects/flask-app/ai-context/summary.md +0 -13
- package/test-projects/flask-app/ai-context/symbols.json +0 -1
- package/test-projects/flask-app/ai-context/tech_stack.md +0 -32
- package/test-projects/flask-app/ai-context/tools.json +0 -10
- package/test-projects/laravel-app/.ai-dev/index.db +0 -0
- package/test-projects/laravel-app/ai-context/ai_context.md +0 -97
- package/test-projects/laravel-app/ai-context/ai_rules.md +0 -47
- package/test-projects/laravel-app/ai-context/architecture.md +0 -60
- package/test-projects/laravel-app/ai-context/cache.json +0 -161
- package/test-projects/laravel-app/ai-context/context/features/app.json +0 -21
- package/test-projects/laravel-app/ai-context/context/flows/.json +0 -9
- package/test-projects/laravel-app/ai-context/context/flows/category.json +0 -12
- package/test-projects/laravel-app/ai-context/context/flows/comment.json +0 -12
- package/test-projects/laravel-app/ai-context/context/flows/post.json +0 -12
- package/test-projects/laravel-app/ai-context/context/flows/unnamed.json +0 -9
- package/test-projects/laravel-app/ai-context/conventions.md +0 -51
- package/test-projects/laravel-app/ai-context/dependencies.json +0 -6
- package/test-projects/laravel-app/ai-context/entrypoints.md +0 -4
- package/test-projects/laravel-app/ai-context/files.json +0 -199
- package/test-projects/laravel-app/ai-context/graph/knowledge-graph.json +0 -98
- package/test-projects/laravel-app/ai-context/graph/module-graph.json +0 -30
- package/test-projects/laravel-app/ai-context/graph/symbol-graph.json +0 -5
- package/test-projects/laravel-app/ai-context/graph/symbol-references.json +0 -1
- package/test-projects/laravel-app/ai-context/index-state.json +0 -280
- package/test-projects/laravel-app/ai-context/index.db +0 -0
- package/test-projects/laravel-app/ai-context/modules.json +0 -29
- package/test-projects/laravel-app/ai-context/project.json +0 -17
- package/test-projects/laravel-app/ai-context/repo_map.json +0 -419
- package/test-projects/laravel-app/ai-context/repo_map.md +0 -106
- package/test-projects/laravel-app/ai-context/schema.json +0 -5
- package/test-projects/laravel-app/ai-context/summary.md +0 -15
- package/test-projects/laravel-app/ai-context/symbols.json +0 -1
- package/test-projects/laravel-app/ai-context/tech_stack.md +0 -34
- package/test-projects/laravel-app/ai-context/tools.json +0 -10
- package/test-projects/nestjs-backend/.ai-dev/index.db +0 -0
- package/test-projects/nestjs-backend/ai-context/ai_context.md +0 -111
- package/test-projects/nestjs-backend/ai-context/ai_rules.md +0 -52
- package/test-projects/nestjs-backend/ai-context/architecture.md +0 -49
- package/test-projects/nestjs-backend/ai-context/cache.json +0 -169
- package/test-projects/nestjs-backend/ai-context/context/features/src.json +0 -23
- package/test-projects/nestjs-backend/ai-context/context/flows/auth.controller.json +0 -14
- package/test-projects/nestjs-backend/ai-context/context/flows/auth.json +0 -10
- package/test-projects/nestjs-backend/ai-context/context/flows/users..json +0 -10
- package/test-projects/nestjs-backend/ai-context/context/flows/users.controller.json +0 -14
- package/test-projects/nestjs-backend/ai-context/context/flows/users.json +0 -10
- package/test-projects/nestjs-backend/ai-context/conventions.md +0 -52
- package/test-projects/nestjs-backend/ai-context/dependencies.json +0 -152
- package/test-projects/nestjs-backend/ai-context/entrypoints.md +0 -18
- package/test-projects/nestjs-backend/ai-context/files.json +0 -209
- package/test-projects/nestjs-backend/ai-context/graph/knowledge-graph.json +0 -132
- package/test-projects/nestjs-backend/ai-context/graph/module-graph.json +0 -29
- package/test-projects/nestjs-backend/ai-context/graph/symbol-graph.json +0 -304
- package/test-projects/nestjs-backend/ai-context/graph/symbol-references.json +0 -5
- package/test-projects/nestjs-backend/ai-context/index-state.json +0 -294
- package/test-projects/nestjs-backend/ai-context/index.db +0 -0
- package/test-projects/nestjs-backend/ai-context/modules.json +0 -19
- package/test-projects/nestjs-backend/ai-context/project.json +0 -18
- package/test-projects/nestjs-backend/ai-context/repo_map.json +0 -427
- package/test-projects/nestjs-backend/ai-context/repo_map.md +0 -104
- package/test-projects/nestjs-backend/ai-context/schema.json +0 -5
- package/test-projects/nestjs-backend/ai-context/summary.md +0 -13
- package/test-projects/nestjs-backend/ai-context/symbols.json +0 -1
- package/test-projects/nestjs-backend/ai-context/tech_stack.md +0 -38
- package/test-projects/nestjs-backend/ai-context/tools.json +0 -10
- package/test-projects/python-cli/.ai-dev/index.db +0 -0
- package/test-projects/python-cli/ai-context/ai_context.md +0 -95
- package/test-projects/python-cli/ai-context/ai_rules.md +0 -47
- package/test-projects/python-cli/ai-context/architecture.md +0 -55
- package/test-projects/python-cli/ai-context/cache.json +0 -149
- package/test-projects/python-cli/ai-context/context/features/cli.json +0 -16
- package/test-projects/python-cli/ai-context/context/flows/list_.json +0 -9
- package/test-projects/python-cli/ai-context/context/flows/remove_.json +0 -9
- package/test-projects/python-cli/ai-context/conventions.md +0 -51
- package/test-projects/python-cli/ai-context/dependencies.json +0 -66
- package/test-projects/python-cli/ai-context/entrypoints.md +0 -4
- package/test-projects/python-cli/ai-context/files.json +0 -184
- package/test-projects/python-cli/ai-context/graph/knowledge-graph.json +0 -83
- package/test-projects/python-cli/ai-context/graph/module-graph.json +0 -31
- package/test-projects/python-cli/ai-context/graph/symbol-graph.json +0 -358
- package/test-projects/python-cli/ai-context/graph/symbol-references.json +0 -11
- package/test-projects/python-cli/ai-context/index-state.json +0 -259
- package/test-projects/python-cli/ai-context/index.db +0 -0
- package/test-projects/python-cli/ai-context/modules.json +0 -21
- package/test-projects/python-cli/ai-context/project.json +0 -15
- package/test-projects/python-cli/ai-context/repo_map.json +0 -367
- package/test-projects/python-cli/ai-context/repo_map.md +0 -93
- package/test-projects/python-cli/ai-context/schema.json +0 -5
- package/test-projects/python-cli/ai-context/summary.md +0 -14
- package/test-projects/python-cli/ai-context/symbols.json +0 -1
- package/test-projects/python-cli/ai-context/tech_stack.md +0 -32
- package/test-projects/python-cli/ai-context/tools.json +0 -10
- package/test-projects/rails-app/.ai-dev/index.db +0 -0
- package/test-projects/rails-app/ai-context/ai_context.md +0 -94
- package/test-projects/rails-app/ai-context/ai_rules.md +0 -47
- package/test-projects/rails-app/ai-context/architecture.md +0 -49
- package/test-projects/rails-app/ai-context/cache.json +0 -193
- package/test-projects/rails-app/ai-context/context/features/app.json +0 -24
- package/test-projects/rails-app/ai-context/context/features/config.json +0 -13
- package/test-projects/rails-app/ai-context/context/flows/application.json +0 -9
- package/test-projects/rails-app/ai-context/context/flows/application_.json +0 -9
- package/test-projects/rails-app/ai-context/context/flows/comments.json +0 -11
- package/test-projects/rails-app/ai-context/context/flows/comments_.json +0 -11
- package/test-projects/rails-app/ai-context/context/flows/posts.json +0 -11
- package/test-projects/rails-app/ai-context/context/flows/posts_.json +0 -11
- package/test-projects/rails-app/ai-context/context/flows/routes.json +0 -9
- package/test-projects/rails-app/ai-context/context/flows/users.json +0 -11
- package/test-projects/rails-app/ai-context/context/flows/users_.json +0 -11
- package/test-projects/rails-app/ai-context/conventions.md +0 -51
- package/test-projects/rails-app/ai-context/dependencies.json +0 -6
- package/test-projects/rails-app/ai-context/entrypoints.md +0 -4
- package/test-projects/rails-app/ai-context/files.json +0 -239
- package/test-projects/rails-app/ai-context/graph/knowledge-graph.json +0 -130
- package/test-projects/rails-app/ai-context/graph/module-graph.json +0 -27
- package/test-projects/rails-app/ai-context/graph/symbol-graph.json +0 -5
- package/test-projects/rails-app/ai-context/graph/symbol-references.json +0 -1
- package/test-projects/rails-app/ai-context/index-state.json +0 -336
- package/test-projects/rails-app/ai-context/index.db +0 -0
- package/test-projects/rails-app/ai-context/modules.json +0 -26
- package/test-projects/rails-app/ai-context/project.json +0 -22
- package/test-projects/rails-app/ai-context/repo_map.json +0 -486
- package/test-projects/rails-app/ai-context/repo_map.md +0 -117
- package/test-projects/rails-app/ai-context/schema.json +0 -5
- package/test-projects/rails-app/ai-context/summary.md +0 -13
- package/test-projects/rails-app/ai-context/symbols.json +0 -1
- package/test-projects/rails-app/ai-context/tech_stack.md +0 -32
- package/test-projects/rails-app/ai-context/tools.json +0 -10
- package/test-projects/react-app/.ai-dev/index.db +0 -0
- package/test-projects/react-app/ai-context/ai_context.md +0 -96
- package/test-projects/react-app/ai-context/ai_rules.md +0 -49
- package/test-projects/react-app/ai-context/architecture.md +0 -39
- package/test-projects/react-app/ai-context/cache.json +0 -153
- package/test-projects/react-app/ai-context/context/features/src.json +0 -18
- package/test-projects/react-app/ai-context/context/flows/UsersPage.json +0 -14
- package/test-projects/react-app/ai-context/context/flows/dashboard.json +0 -9
- package/test-projects/react-app/ai-context/context/flows/login.json +0 -9
- package/test-projects/react-app/ai-context/context/flows/users.json +0 -9
- package/test-projects/react-app/ai-context/conventions.md +0 -52
- package/test-projects/react-app/ai-context/dependencies.json +0 -128
- package/test-projects/react-app/ai-context/entrypoints.md +0 -4
- package/test-projects/react-app/ai-context/files.json +0 -189
- package/test-projects/react-app/ai-context/graph/knowledge-graph.json +0 -112
- package/test-projects/react-app/ai-context/graph/module-graph.json +0 -31
- package/test-projects/react-app/ai-context/graph/symbol-graph.json +0 -868
- package/test-projects/react-app/ai-context/graph/symbol-references.json +0 -31
- package/test-projects/react-app/ai-context/index-state.json +0 -266
- package/test-projects/react-app/ai-context/index.db +0 -0
- package/test-projects/react-app/ai-context/modules.json +0 -17
- package/test-projects/react-app/ai-context/project.json +0 -16
- package/test-projects/react-app/ai-context/repo_map.json +0 -391
- package/test-projects/react-app/ai-context/repo_map.md +0 -94
- package/test-projects/react-app/ai-context/schema.json +0 -5
- package/test-projects/react-app/ai-context/summary.md +0 -13
- package/test-projects/react-app/ai-context/symbols.json +0 -1
- package/test-projects/react-app/ai-context/tech_stack.md +0 -39
- package/test-projects/react-app/ai-context/tools.json +0 -10
- package/test-projects/salesforce-cli/.ai-dev/index.db +0 -0
- package/test-projects/salesforce-cli/ai-context/ai_context.md +0 -89
- package/test-projects/salesforce-cli/ai-context/ai_rules.md +0 -47
- package/test-projects/salesforce-cli/ai-context/architecture.md +0 -39
- package/test-projects/salesforce-cli/ai-context/cache.json +0 -125
- package/test-projects/salesforce-cli/ai-context/context/features/force-app.json +0 -14
- package/test-projects/salesforce-cli/ai-context/context/flows/account.json +0 -9
- package/test-projects/salesforce-cli/ai-context/context/flows/opportunity.json +0 -9
- package/test-projects/salesforce-cli/ai-context/conventions.md +0 -51
- package/test-projects/salesforce-cli/ai-context/dependencies.json +0 -6
- package/test-projects/salesforce-cli/ai-context/entrypoints.md +0 -4
- package/test-projects/salesforce-cli/ai-context/files.json +0 -154
- package/test-projects/salesforce-cli/ai-context/graph/knowledge-graph.json +0 -64
- package/test-projects/salesforce-cli/ai-context/graph/module-graph.json +0 -13
- package/test-projects/salesforce-cli/ai-context/graph/symbol-graph.json +0 -148
- package/test-projects/salesforce-cli/ai-context/graph/symbol-references.json +0 -1
- package/test-projects/salesforce-cli/ai-context/index-state.json +0 -217
- package/test-projects/salesforce-cli/ai-context/index.db +0 -0
- package/test-projects/salesforce-cli/ai-context/modules.json +0 -12
- package/test-projects/salesforce-cli/ai-context/project.json +0 -14
- package/test-projects/salesforce-cli/ai-context/repo_map.json +0 -328
- package/test-projects/salesforce-cli/ai-context/repo_map.md +0 -80
- package/test-projects/salesforce-cli/ai-context/schema.json +0 -5
- package/test-projects/salesforce-cli/ai-context/summary.md +0 -13
- package/test-projects/salesforce-cli/ai-context/symbols.json +0 -1
- package/test-projects/salesforce-cli/ai-context/tech_stack.md +0 -31
- package/test-projects/salesforce-cli/ai-context/tools.json +0 -10
- package/test-projects/spring-boot-app/.ai-dev/index.db +0 -0
- package/test-projects/spring-boot-app/ai-context/ai_context.md +0 -91
- package/test-projects/spring-boot-app/ai-context/ai_rules.md +0 -48
- package/test-projects/spring-boot-app/ai-context/architecture.md +0 -39
- package/test-projects/spring-boot-app/ai-context/cache.json +0 -173
- package/test-projects/spring-boot-app/ai-context/context/features/src.json +0 -26
- package/test-projects/spring-boot-app/ai-context/context/flows/PostController.json +0 -19
- package/test-projects/spring-boot-app/ai-context/context/flows/UserController.json +0 -19
- package/test-projects/spring-boot-app/ai-context/context/flows/comment.json +0 -11
- package/test-projects/spring-boot-app/ai-context/context/flows/post.json +0 -14
- package/test-projects/spring-boot-app/ai-context/context/flows/user.json +0 -14
- package/test-projects/spring-boot-app/ai-context/conventions.md +0 -52
- package/test-projects/spring-boot-app/ai-context/dependencies.json +0 -326
- package/test-projects/spring-boot-app/ai-context/entrypoints.md +0 -4
- package/test-projects/spring-boot-app/ai-context/files.json +0 -214
- package/test-projects/spring-boot-app/ai-context/graph/knowledge-graph.json +0 -231
- package/test-projects/spring-boot-app/ai-context/graph/module-graph.json +0 -22
- package/test-projects/spring-boot-app/ai-context/graph/symbol-graph.json +0 -794
- package/test-projects/spring-boot-app/ai-context/graph/symbol-references.json +0 -70
- package/test-projects/spring-boot-app/ai-context/index-state.json +0 -301
- package/test-projects/spring-boot-app/ai-context/index.db +0 -0
- package/test-projects/spring-boot-app/ai-context/modules.json +0 -21
- package/test-projects/spring-boot-app/ai-context/project.json +0 -17
- package/test-projects/spring-boot-app/ai-context/repo_map.json +0 -461
- package/test-projects/spring-boot-app/ai-context/repo_map.md +0 -109
- package/test-projects/spring-boot-app/ai-context/schema.json +0 -5
- package/test-projects/spring-boot-app/ai-context/summary.md +0 -12
- package/test-projects/spring-boot-app/ai-context/symbols.json +0 -1
- package/test-projects/spring-boot-app/ai-context/tech_stack.md +0 -32
- package/test-projects/spring-boot-app/ai-context/tools.json +0 -10
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
export interface Call {
|
|
2
|
+
caller: string;
|
|
3
|
+
callee: string;
|
|
4
|
+
location: {
|
|
5
|
+
file: string;
|
|
6
|
+
line: number;
|
|
7
|
+
character: number;
|
|
8
|
+
};
|
|
9
|
+
arguments?: string[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface CallGraph {
|
|
13
|
+
nodes: string[];
|
|
14
|
+
edges: Call[];
|
|
15
|
+
callsByFunction: Map<string, Call[]>;
|
|
16
|
+
calledBy: Map<string, Call[]>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class CallGraphBuilder {
|
|
20
|
+
buildCallGraph(
|
|
21
|
+
symbols: Array<{
|
|
22
|
+
id: string;
|
|
23
|
+
name: string;
|
|
24
|
+
file: string;
|
|
25
|
+
type: string;
|
|
26
|
+
}>,
|
|
27
|
+
callExpressions: Array<{
|
|
28
|
+
caller: string;
|
|
29
|
+
callee: string;
|
|
30
|
+
line: number;
|
|
31
|
+
character: number;
|
|
32
|
+
args?: string[];
|
|
33
|
+
}>
|
|
34
|
+
): CallGraph {
|
|
35
|
+
const graph: CallGraph = {
|
|
36
|
+
nodes: symbols.map((s) => s.id),
|
|
37
|
+
edges: [],
|
|
38
|
+
callsByFunction: new Map(),
|
|
39
|
+
calledBy: new Map(),
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
for (const expr of callExpressions) {
|
|
43
|
+
const call: Call = {
|
|
44
|
+
caller: expr.caller,
|
|
45
|
+
callee: expr.callee,
|
|
46
|
+
location: {
|
|
47
|
+
file: expr.caller.split("#")[0],
|
|
48
|
+
line: expr.line,
|
|
49
|
+
character: expr.character,
|
|
50
|
+
},
|
|
51
|
+
arguments: expr.args,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
graph.edges.push(call);
|
|
55
|
+
|
|
56
|
+
const callerCalls = graph.callsByFunction.get(expr.caller) || [];
|
|
57
|
+
callerCalls.push(call);
|
|
58
|
+
graph.callsByFunction.set(expr.caller, callerCalls);
|
|
59
|
+
|
|
60
|
+
const calleeCalled = graph.calledBy.get(expr.callee) || [];
|
|
61
|
+
calleeCalled.push(call);
|
|
62
|
+
graph.calledBy.set(expr.callee, calleeCalled);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return graph;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
findUnusedFunctions(graph: CallGraph): string[] {
|
|
69
|
+
const unused: string[] = [];
|
|
70
|
+
|
|
71
|
+
for (const node of graph.nodes) {
|
|
72
|
+
const calledBy = graph.calledBy.get(node);
|
|
73
|
+
const isEntryPoint = this.isEntryPoint(node);
|
|
74
|
+
|
|
75
|
+
if ((!calledBy || calledBy.length === 0) && !isEntryPoint) {
|
|
76
|
+
unused.push(node);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return unused;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
findDeadCode(graph: CallGraph, entryPoints: string[]): string[] {
|
|
84
|
+
const reachable = new Set<string>();
|
|
85
|
+
|
|
86
|
+
const traverse = (node: string) => {
|
|
87
|
+
if (reachable.has(node)) return;
|
|
88
|
+
reachable.add(node);
|
|
89
|
+
|
|
90
|
+
const calls = graph.callsByFunction.get(node) || [];
|
|
91
|
+
for (const call of calls) {
|
|
92
|
+
traverse(call.callee);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
for (const entry of entryPoints) {
|
|
97
|
+
traverse(entry);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return graph.nodes.filter((n) => !reachable.has(n));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
getCallChain(graph: CallGraph, startFunction: string, depth: number = 5): string[] {
|
|
104
|
+
const chain: string[] = [];
|
|
105
|
+
const visited = new Set<string>();
|
|
106
|
+
|
|
107
|
+
const traverse = (func: string, currentDepth: number) => {
|
|
108
|
+
if (currentDepth > depth || visited.has(func)) return;
|
|
109
|
+
|
|
110
|
+
visited.add(func);
|
|
111
|
+
chain.push(func);
|
|
112
|
+
|
|
113
|
+
const calls = graph.callsByFunction.get(func) || [];
|
|
114
|
+
for (const call of calls) {
|
|
115
|
+
traverse(call.callee, currentDepth + 1);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
traverse(startFunction, 0);
|
|
120
|
+
return chain;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
calculateComplexity(graph: CallGraph, functionId: string): number {
|
|
124
|
+
const outgoing = graph.callsByFunction.get(functionId) || [];
|
|
125
|
+
const incoming = graph.calledBy.get(functionId) || [];
|
|
126
|
+
|
|
127
|
+
return outgoing.length + incoming.length * 2;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private isEntryPoint(symbolId: string): boolean {
|
|
131
|
+
const name = symbolId.split("#")[1] || "";
|
|
132
|
+
const file = symbolId.split("#")[0] || "";
|
|
133
|
+
|
|
134
|
+
const entryPatterns = [
|
|
135
|
+
/main$/,
|
|
136
|
+
/index$/,
|
|
137
|
+
/init$/,
|
|
138
|
+
/start$/,
|
|
139
|
+
/handler$/,
|
|
140
|
+
/controller$/,
|
|
141
|
+
/route$/,
|
|
142
|
+
];
|
|
143
|
+
|
|
144
|
+
if (entryPatterns.some((p) => p.test(name))) return true;
|
|
145
|
+
|
|
146
|
+
if (
|
|
147
|
+
file.includes("main.") ||
|
|
148
|
+
file.includes("index.") ||
|
|
149
|
+
file.includes("app.")
|
|
150
|
+
) {
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export const callGraphBuilder = new CallGraphBuilder();
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
export interface ImportRelation {
|
|
2
|
+
from: string;
|
|
3
|
+
to: string;
|
|
4
|
+
type: "import" | "export" | "re-export";
|
|
5
|
+
symbols?: string[];
|
|
6
|
+
isDefault?: boolean;
|
|
7
|
+
isNamespace?: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface DependencyGraph {
|
|
11
|
+
nodes: string[];
|
|
12
|
+
edges: ImportRelation[];
|
|
13
|
+
importsByFile: Map<string, ImportRelation[]>;
|
|
14
|
+
exportsByFile: Map<string, string[]>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class DependencyAnalyzer {
|
|
18
|
+
analyzeImports(
|
|
19
|
+
filePath: string,
|
|
20
|
+
imports: Array<{
|
|
21
|
+
name: string;
|
|
22
|
+
module: string;
|
|
23
|
+
isDefault?: boolean;
|
|
24
|
+
isNamespace?: boolean;
|
|
25
|
+
}>,
|
|
26
|
+
exports: string[]
|
|
27
|
+
): ImportRelation[] {
|
|
28
|
+
const relations: ImportRelation[] = [];
|
|
29
|
+
|
|
30
|
+
for (const imp of imports) {
|
|
31
|
+
relations.push({
|
|
32
|
+
from: filePath,
|
|
33
|
+
to: imp.module,
|
|
34
|
+
type: "import",
|
|
35
|
+
symbols: [imp.name],
|
|
36
|
+
isDefault: imp.isDefault,
|
|
37
|
+
isNamespace: imp.isNamespace,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
for (const exp of exports) {
|
|
42
|
+
relations.push({
|
|
43
|
+
from: filePath,
|
|
44
|
+
to: "exports",
|
|
45
|
+
type: "export",
|
|
46
|
+
symbols: [exp],
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return relations;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
buildDependencyGraph(
|
|
54
|
+
parsedFiles: Array<{
|
|
55
|
+
filePath: string;
|
|
56
|
+
imports: Array<{
|
|
57
|
+
name: string;
|
|
58
|
+
module: string;
|
|
59
|
+
isDefault?: boolean;
|
|
60
|
+
isNamespace?: boolean;
|
|
61
|
+
}>;
|
|
62
|
+
exports: string[];
|
|
63
|
+
}>
|
|
64
|
+
): DependencyGraph {
|
|
65
|
+
const graph: DependencyGraph = {
|
|
66
|
+
nodes: [],
|
|
67
|
+
edges: [],
|
|
68
|
+
importsByFile: new Map(),
|
|
69
|
+
exportsByFile: new Map(),
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
for (const file of parsedFiles) {
|
|
73
|
+
graph.nodes.push(file.filePath);
|
|
74
|
+
|
|
75
|
+
const relations = this.analyzeImports(
|
|
76
|
+
file.filePath,
|
|
77
|
+
file.imports,
|
|
78
|
+
file.exports
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
graph.edges.push(...relations);
|
|
82
|
+
|
|
83
|
+
const imports = relations.filter((r) => r.type === "import");
|
|
84
|
+
graph.importsByFile.set(file.filePath, imports);
|
|
85
|
+
|
|
86
|
+
const exports = relations
|
|
87
|
+
.filter((r) => r.type === "export")
|
|
88
|
+
.flatMap((r) => r.symbols || []);
|
|
89
|
+
graph.exportsByFile.set(file.filePath, exports);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return graph;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
detectCircularDependencies(graph: DependencyGraph): string[][] {
|
|
96
|
+
const cycles: string[][] = [];
|
|
97
|
+
const visited = new Set<string>();
|
|
98
|
+
const recursionStack = new Set<string>();
|
|
99
|
+
|
|
100
|
+
const dfs = (node: string, path: string[]) => {
|
|
101
|
+
if (recursionStack.has(node)) {
|
|
102
|
+
const cycleStart = path.indexOf(node);
|
|
103
|
+
cycles.push(path.slice(cycleStart).concat([node]));
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (visited.has(node)) return;
|
|
108
|
+
|
|
109
|
+
visited.add(node);
|
|
110
|
+
recursionStack.add(node);
|
|
111
|
+
path.push(node);
|
|
112
|
+
|
|
113
|
+
const outgoingEdges = graph.edges.filter((e) => e.from === node);
|
|
114
|
+
for (const edge of outgoingEdges) {
|
|
115
|
+
if (edge.type === "import") {
|
|
116
|
+
dfs(edge.to, [...path]);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
recursionStack.delete(node);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
for (const node of graph.nodes) {
|
|
124
|
+
if (!visited.has(node)) {
|
|
125
|
+
dfs(node, []);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return cycles;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
calculateMetrics(graph: DependencyGraph): {
|
|
133
|
+
totalFiles: number;
|
|
134
|
+
totalImports: number;
|
|
135
|
+
totalExports: number;
|
|
136
|
+
avgImportsPerFile: number;
|
|
137
|
+
mostImported: { module: string; count: number }[];
|
|
138
|
+
} {
|
|
139
|
+
const moduleImportCounts = new Map<string, number>();
|
|
140
|
+
|
|
141
|
+
for (const edge of graph.edges) {
|
|
142
|
+
if (edge.type === "import") {
|
|
143
|
+
const count = moduleImportCounts.get(edge.to) || 0;
|
|
144
|
+
moduleImportCounts.set(edge.to, count + 1);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const mostImported = Array.from(moduleImportCounts.entries())
|
|
149
|
+
.map(([module, count]) => ({ module, count }))
|
|
150
|
+
.sort((a, b) => b.count - a.count)
|
|
151
|
+
.slice(0, 10);
|
|
152
|
+
|
|
153
|
+
const importEdges = graph.edges.filter((e) => e.type === "import");
|
|
154
|
+
const exportEdges = graph.edges.filter((e) => e.type === "export");
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
totalFiles: graph.nodes.length,
|
|
158
|
+
totalImports: importEdges.length,
|
|
159
|
+
totalExports: exportEdges.length,
|
|
160
|
+
avgImportsPerFile:
|
|
161
|
+
graph.nodes.length > 0 ? importEdges.length / graph.nodes.length : 0,
|
|
162
|
+
mostImported,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export const dependencyAnalyzer = new DependencyAnalyzer();
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export {
|
|
2
|
+
DependencyAnalyzer,
|
|
3
|
+
dependencyAnalyzer,
|
|
4
|
+
type ImportRelation,
|
|
5
|
+
type DependencyGraph,
|
|
6
|
+
} from "./dependencyAnalyzer.js";
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
CallGraphBuilder,
|
|
10
|
+
callGraphBuilder,
|
|
11
|
+
type Call,
|
|
12
|
+
type CallGraph,
|
|
13
|
+
} from "./callGraphBuilder.js";
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
InheritanceAnalyzer,
|
|
17
|
+
inheritanceAnalyzer,
|
|
18
|
+
type InheritanceRelation,
|
|
19
|
+
type InheritanceGraph,
|
|
20
|
+
} from "./inheritanceAnalyzer.js";
|
|
21
|
+
|
|
22
|
+
export {
|
|
23
|
+
ArchitectureDetector,
|
|
24
|
+
architectureDetector,
|
|
25
|
+
type ArchitecturePattern,
|
|
26
|
+
type Layer,
|
|
27
|
+
type ArchitectureAnalysis,
|
|
28
|
+
} from "./architectureDetector.js";
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
export interface InheritanceRelation {
|
|
2
|
+
child: string;
|
|
3
|
+
parent: string;
|
|
4
|
+
type: "extends" | "implements";
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface InheritanceGraph {
|
|
8
|
+
nodes: string[];
|
|
9
|
+
edges: InheritanceRelation[];
|
|
10
|
+
classHierarchy: Map<string, string[]>;
|
|
11
|
+
implementations: Map<string, string[]>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class InheritanceAnalyzer {
|
|
15
|
+
buildHierarchy(
|
|
16
|
+
symbols: Array<{
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
type: string;
|
|
20
|
+
heritage?: {
|
|
21
|
+
extends?: string[];
|
|
22
|
+
implements?: string[];
|
|
23
|
+
};
|
|
24
|
+
}>
|
|
25
|
+
): InheritanceGraph {
|
|
26
|
+
const graph: InheritanceGraph = {
|
|
27
|
+
nodes: symbols.filter((s) => s.type === "class" || s.type === "interface").map((s) => s.id),
|
|
28
|
+
edges: [],
|
|
29
|
+
classHierarchy: new Map(),
|
|
30
|
+
implementations: new Map(),
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
for (const symbol of symbols) {
|
|
34
|
+
if (symbol.type !== "class" && symbol.type !== "interface") continue;
|
|
35
|
+
|
|
36
|
+
const parents: string[] = [];
|
|
37
|
+
|
|
38
|
+
if (symbol.heritage?.extends) {
|
|
39
|
+
for (const parent of symbol.heritage.extends) {
|
|
40
|
+
graph.edges.push({
|
|
41
|
+
child: symbol.id,
|
|
42
|
+
parent,
|
|
43
|
+
type: "extends",
|
|
44
|
+
});
|
|
45
|
+
parents.push(parent);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (symbol.heritage?.implements) {
|
|
50
|
+
for (const iface of symbol.heritage.implements) {
|
|
51
|
+
graph.edges.push({
|
|
52
|
+
child: symbol.id,
|
|
53
|
+
parent: iface,
|
|
54
|
+
type: "implements",
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const impls = graph.implementations.get(iface) || [];
|
|
58
|
+
impls.push(symbol.id);
|
|
59
|
+
graph.implementations.set(iface, impls);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (parents.length > 0) {
|
|
64
|
+
graph.classHierarchy.set(symbol.id, parents);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return graph;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
getAncestors(graph: InheritanceGraph, classId: string): string[] {
|
|
72
|
+
const ancestors: string[] = [];
|
|
73
|
+
const visited = new Set<string>();
|
|
74
|
+
|
|
75
|
+
const traverse = (current: string) => {
|
|
76
|
+
if (visited.has(current)) return;
|
|
77
|
+
visited.add(current);
|
|
78
|
+
|
|
79
|
+
const edges = graph.edges.filter((e) => e.child === current);
|
|
80
|
+
for (const edge of edges) {
|
|
81
|
+
ancestors.push(edge.parent);
|
|
82
|
+
traverse(edge.parent);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
traverse(classId);
|
|
87
|
+
return ancestors;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
getDescendants(graph: InheritanceGraph, classId: string): string[] {
|
|
91
|
+
const descendants: string[] = [];
|
|
92
|
+
const visited = new Set<string>();
|
|
93
|
+
|
|
94
|
+
const traverse = (current: string) => {
|
|
95
|
+
if (visited.has(current)) return;
|
|
96
|
+
visited.add(current);
|
|
97
|
+
|
|
98
|
+
const edges = graph.edges.filter(
|
|
99
|
+
(e) => e.parent === current && e.type === "extends"
|
|
100
|
+
);
|
|
101
|
+
for (const edge of edges) {
|
|
102
|
+
descendants.push(edge.child);
|
|
103
|
+
traverse(edge.child);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
traverse(classId);
|
|
108
|
+
return descendants;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
getImplementations(graph: InheritanceGraph, interfaceName: string): string[] {
|
|
112
|
+
return graph.implementations.get(interfaceName) || [];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
detectInheritanceDepth(graph: InheritanceGraph): Map<string, number> {
|
|
116
|
+
const depths = new Map<string, number>();
|
|
117
|
+
|
|
118
|
+
const calculateDepth = (classId: string): number => {
|
|
119
|
+
if (depths.has(classId)) return depths.get(classId)!;
|
|
120
|
+
|
|
121
|
+
const parents = graph.classHierarchy.get(classId) || [];
|
|
122
|
+
if (parents.length === 0) {
|
|
123
|
+
depths.set(classId, 0);
|
|
124
|
+
return 0;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const parentDepths = parents.map((p) => calculateDepth(p));
|
|
128
|
+
const depth = Math.max(...parentDepths) + 1;
|
|
129
|
+
depths.set(classId, depth);
|
|
130
|
+
return depth;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
for (const node of graph.nodes) {
|
|
134
|
+
calculateDepth(node);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return depths;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
findBaseClasses(graph: InheritanceGraph): string[] {
|
|
141
|
+
return graph.nodes.filter((node) => {
|
|
142
|
+
const parents = graph.classHierarchy.get(node);
|
|
143
|
+
return !parents || parents.length === 0;
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
calculateInheritanceMetrics(graph: InheritanceGraph): {
|
|
148
|
+
totalClasses: number;
|
|
149
|
+
totalInterfaces: number;
|
|
150
|
+
inheritanceDepth: number;
|
|
151
|
+
multipleInheritance: number;
|
|
152
|
+
} {
|
|
153
|
+
const depths = this.detectInheritanceDepth(graph);
|
|
154
|
+
const maxDepth = Math.max(...depths.values(), 0);
|
|
155
|
+
|
|
156
|
+
const multipleInheritance = Array.from(graph.classHierarchy.values()).filter(
|
|
157
|
+
(parents) => parents.length > 1
|
|
158
|
+
).length;
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
totalClasses: graph.nodes.length,
|
|
162
|
+
totalInterfaces: graph.implementations.size,
|
|
163
|
+
inheritanceDepth: maxDepth,
|
|
164
|
+
multipleInheritance,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export const inheritanceAnalyzer = new InheritanceAnalyzer();
|
package/src/core/ccp.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { ensureDir, writeFile, readJsonFile } from "../utils/fileUtils.js";
|
|
4
|
+
import { getCcpDir, getCcpPath } from "../utils/constants.js";
|
|
4
5
|
|
|
5
6
|
export interface ContextModule {
|
|
6
7
|
name: string;
|
|
@@ -206,7 +207,7 @@ export function createCCP(
|
|
|
206
207
|
* List all CCPs
|
|
207
208
|
*/
|
|
208
209
|
export function listCCPs(rootDir: string): string[] {
|
|
209
|
-
const ccpDir =
|
|
210
|
+
const ccpDir = getCcpDir(rootDir);
|
|
210
211
|
|
|
211
212
|
if (!fs.existsSync(ccpDir)) {
|
|
212
213
|
return [];
|
|
@@ -222,7 +223,7 @@ export function listCCPs(rootDir: string): string[] {
|
|
|
222
223
|
* Get CCP details
|
|
223
224
|
*/
|
|
224
225
|
export function getCCP(rootDir: string, name: string): CCPContext | null {
|
|
225
|
-
const contextPath =
|
|
226
|
+
const contextPath = getCcpPath(rootDir, name);
|
|
226
227
|
|
|
227
228
|
if (!fs.existsSync(contextPath)) {
|
|
228
229
|
return null;
|