ai-first-cli 1.3.1 → 1.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.ai-dev/index.db +0 -0
- package/BETA_EVALUATION_REPORT.md +151 -0
- package/CHANGELOG.md +178 -0
- package/PHASE1_USER_SIMULATION.md +56 -0
- package/PHASE2_USER_SIMULATION.md +81 -0
- package/PHASE3_USER_SIMULATION.md +176 -0
- package/README.es.md +18 -0
- package/README.md +80 -1
- package/ai/graph/knowledge-graph.json +10 -0
- package/ai-context/ai_context.md +130 -0
- package/{test-projects/react-app/.ai-dev → ai-context}/ai_rules.md +10 -5
- package/ai-context/architecture.md +136 -0
- package/ai-context/context/features/src.json +69 -0
- package/ai-context/context/features/test-projects.json +69 -0
- package/ai-context/context/flows/App.json +17 -0
- package/ai-context/context/flows/DashboardPage.json +14 -0
- package/ai-context/context/flows/LoginPage.json +14 -0
- package/ai-context/context/flows/admin.json +10 -0
- package/ai-context/context/flows/ai-first.json +9 -0
- package/ai-context/context/flows/androidresources.json +11 -0
- package/ai-context/context/flows/auth.json +13 -0
- package/ai-context/context/flows/authController.json +14 -0
- package/ai-context/context/flows/doctor.json +9 -0
- package/ai-context/context/flows/entrypoints.json +9 -0
- package/ai-context/context/flows/explore.json +9 -0
- package/ai-context/context/flows/fastapiAdapter.json +14 -0
- package/ai-context/context/flows/fastapiadapter.json +11 -0
- package/ai-context/context/flows/index.json +19 -0
- package/ai-context/context/flows/indexer.json +9 -0
- package/ai-context/context/flows/indexstate.json +9 -0
- package/ai-context/context/flows/init.json +22 -0
- package/ai-context/context/flows/main.json +18 -0
- package/ai-context/context/flows/mainactivity.json +9 -0
- package/ai-context/context/flows/models.json +15 -0
- package/ai-context/context/flows/posts.json +15 -0
- package/ai-context/context/flows/repoMapper.json +20 -0
- package/ai-context/context/flows/repomapper.json +11 -0
- package/ai-context/context/flows/routes.json +15 -0
- package/ai-context/context/flows/serializers.json +10 -0
- package/ai-context/context/flows/user.json +23 -0
- package/ai-context/context/flows/views.json +12 -0
- package/{test-projects/react-app/.ai-dev → ai-context}/conventions.md +3 -2
- package/ai-context/dependencies.json +3360 -0
- package/ai-context/entrypoints.md +45 -0
- package/ai-context/index-state.json +196 -0
- package/ai-context/modules.json +901 -0
- package/ai-context/project.json +33 -0
- package/ai-context/repo_map.json +8857 -0
- package/ai-context/repo_map.md +2002 -0
- package/{test-projects/flask-app/.ai-dev → ai-context}/schema.json +1 -1
- package/ai-context/summary.md +46 -0
- package/ai-context/symbols.json +82467 -0
- package/{test-projects/react-app/.ai-dev → ai-context}/tech_stack.md +15 -7
- package/ai-context-evaluation-report-1774223059505.md +206 -0
- package/dist/analyzers/architecture.d.ts.map +1 -1
- package/dist/analyzers/architecture.js +6 -0
- package/dist/analyzers/architecture.js.map +1 -1
- package/dist/analyzers/entrypoints.d.ts.map +1 -1
- package/dist/analyzers/entrypoints.js +105 -0
- package/dist/analyzers/entrypoints.js.map +1 -1
- package/dist/analyzers/symbols.d.ts.map +1 -1
- package/dist/analyzers/symbols.js +72 -1
- package/dist/analyzers/symbols.js.map +1 -1
- package/dist/analyzers/techStack.d.ts +8 -0
- package/dist/analyzers/techStack.d.ts.map +1 -1
- package/dist/analyzers/techStack.js +75 -0
- package/dist/analyzers/techStack.js.map +1 -1
- package/dist/scripts/ai-context-evaluator.js +367 -0
- package/package.json +1 -1
- package/quick-evaluation-report-1774396002305.md +64 -0
- package/quick-evaluator.ts +200 -0
- package/scripts/ai-context-evaluator.ts +440 -0
- package/src/analyzers/architecture.ts +8 -0
- package/src/analyzers/entrypoints.ts +115 -0
- package/src/analyzers/symbols.ts +77 -1
- package/src/analyzers/techStack.ts +93 -0
- package/tests/apex-parser.test.ts +193 -0
- package/tests/cli-commands-batch1.test.ts +808 -0
- package/tests/cli-commands-batch2.test.ts +1113 -0
- package/tests/cli-commands-batch3.test.ts +1128 -0
- package/tests/cli-index.test.ts +1007 -0
- package/tests/cli-init.test.ts +761 -0
- package/tests/salesforce-apex-classes.test.ts +713 -0
- package/tests/salesforce-apex-triggers.test.ts +871 -0
- package/tests/salesforce-custom-objects.test.ts +918 -0
- package/tests/salesforce-flows.test.ts +710 -0
- package/tests/salesforce-lwc.test.ts +963 -0
- package/tests/salesforce-sfdx-integration.test.ts +1125 -0
- package/ANALISIS_COMPLETO.md +0 -424
- package/ANALISIS_MEJORAS.md +0 -327
- package/CONTRIBUTING.md +0 -89
- package/FLOW.md +0 -129
- package/TEST_RESULTS.md +0 -198
- package/TEST_RESULTS_COMPARATIVE.md +0 -159
- package/TEST_RESULTS_COMPLETE.md +0 -127
- package/TEST_RESULTS_COMPREHENSIVE.md +0 -208
- package/install.sh +0 -188
- package/run-all-tests.sh +0 -184
- package/test-ai-context-understanding.sh +0 -21
- package/test-projects/django-app/.ai-dev/ai_context.md +0 -92
- package/test-projects/django-app/.ai-dev/ai_rules.md +0 -47
- package/test-projects/django-app/.ai-dev/architecture.md +0 -57
- package/test-projects/django-app/.ai-dev/cache.json +0 -169
- package/test-projects/django-app/.ai-dev/context/flows/views.json +0 -10
- package/test-projects/django-app/.ai-dev/conventions.md +0 -51
- package/test-projects/django-app/.ai-dev/dependencies.json +0 -312
- package/test-projects/django-app/.ai-dev/entrypoints.md +0 -4
- package/test-projects/django-app/.ai-dev/files.json +0 -209
- package/test-projects/django-app/.ai-dev/graph/knowledge-graph.json +0 -36
- package/test-projects/django-app/.ai-dev/graph/module-graph.json +0 -145
- package/test-projects/django-app/.ai-dev/graph/symbol-graph.json +0 -1488
- package/test-projects/django-app/.ai-dev/graph/symbol-references.json +0 -1
- package/test-projects/django-app/.ai-dev/index-state.json +0 -294
- package/test-projects/django-app/.ai-dev/modules.json +0 -35
- package/test-projects/django-app/.ai-dev/project.json +0 -11
- package/test-projects/django-app/.ai-dev/repo_map.json +0 -412
- package/test-projects/django-app/.ai-dev/repo_map.md +0 -105
- package/test-projects/django-app/.ai-dev/schema.json +0 -5
- package/test-projects/django-app/.ai-dev/summary.md +0 -15
- package/test-projects/django-app/.ai-dev/symbols.json +0 -1
- package/test-projects/django-app/.ai-dev/tech_stack.md +0 -32
- package/test-projects/django-app/README.md +0 -91
- package/test-projects/django-app/blog/__init__.py +0 -0
- package/test-projects/django-app/blog/admin.py +0 -31
- package/test-projects/django-app/blog/models.py +0 -55
- package/test-projects/django-app/blog/serializers.py +0 -69
- package/test-projects/django-app/blog/urls.py +0 -14
- package/test-projects/django-app/blog/views.py +0 -96
- package/test-projects/django-app/django_app/__init__.py +0 -0
- package/test-projects/django-app/django_app/settings.py +0 -90
- package/test-projects/django-app/django_app/urls.py +0 -11
- package/test-projects/django-app/django_app/wsgi.py +0 -9
- package/test-projects/django-app/manage.py +0 -23
- package/test-projects/django-app/requirements.txt +0 -3
- package/test-projects/django-app/users/__init__.py +0 -0
- package/test-projects/django-app/users/admin.py +0 -42
- package/test-projects/django-app/users/models.py +0 -54
- package/test-projects/django-app/users/serializers.py +0 -113
- package/test-projects/django-app/users/urls.py +0 -13
- package/test-projects/django-app/users/views.py +0 -135
- package/test-projects/express-api/.ai-dev/ai_context.md +0 -112
- package/test-projects/express-api/.ai-dev/ai_rules.md +0 -50
- package/test-projects/express-api/.ai-dev/architecture.md +0 -62
- package/test-projects/express-api/.ai-dev/context/features/controllers.json +0 -13
- package/test-projects/express-api/.ai-dev/context/features/services.json +0 -13
- package/test-projects/express-api/.ai-dev/context/flows/auth.json +0 -12
- package/test-projects/express-api/.ai-dev/context/flows/user.json +0 -13
- package/test-projects/express-api/.ai-dev/conventions.md +0 -51
- package/test-projects/express-api/.ai-dev/dependencies.json +0 -54
- package/test-projects/express-api/.ai-dev/entrypoints.md +0 -17
- package/test-projects/express-api/.ai-dev/modules.json +0 -30
- package/test-projects/express-api/.ai-dev/project.json +0 -15
- package/test-projects/express-api/.ai-dev/repo_map.json +0 -100
- package/test-projects/express-api/.ai-dev/repo_map.md +0 -36
- package/test-projects/express-api/.ai-dev/schema.json +0 -5
- package/test-projects/express-api/.ai-dev/summary.md +0 -14
- package/test-projects/express-api/.ai-dev/symbols.json +0 -7
- package/test-projects/express-api/.ai-dev/tech_stack.md +0 -38
- package/test-projects/express-api/.ai-dev/tools.json +0 -10
- package/test-projects/express-api/controllers/authController.js +0 -32
- package/test-projects/express-api/controllers/userController.js +0 -51
- package/test-projects/express-api/index.js +0 -30
- package/test-projects/express-api/middleware/authMiddleware.js +0 -30
- package/test-projects/express-api/models/userRepository.js +0 -25
- package/test-projects/express-api/package.json +0 -18
- package/test-projects/express-api/services/authService.js +0 -17
- package/test-projects/express-api/services/userService.js +0 -28
- package/test-projects/fastapi-app/.ai-dev/ai_context.md +0 -89
- package/test-projects/fastapi-app/.ai-dev/ai_rules.md +0 -47
- package/test-projects/fastapi-app/.ai-dev/architecture.md +0 -39
- package/test-projects/fastapi-app/.ai-dev/cache.json +0 -125
- package/test-projects/fastapi-app/.ai-dev/conventions.md +0 -51
- package/test-projects/fastapi-app/.ai-dev/dependencies.json +0 -244
- package/test-projects/fastapi-app/.ai-dev/entrypoints.md +0 -4
- package/test-projects/fastapi-app/.ai-dev/files.json +0 -154
- package/test-projects/fastapi-app/.ai-dev/graph/knowledge-graph.json +0 -15
- package/test-projects/fastapi-app/.ai-dev/graph/module-graph.json +0 -78
- package/test-projects/fastapi-app/.ai-dev/graph/symbol-graph.json +0 -1724
- package/test-projects/fastapi-app/.ai-dev/graph/symbol-references.json +0 -51
- package/test-projects/fastapi-app/.ai-dev/index-state.json +0 -217
- package/test-projects/fastapi-app/.ai-dev/modules.json +0 -16
- package/test-projects/fastapi-app/.ai-dev/project.json +0 -9
- package/test-projects/fastapi-app/.ai-dev/repo_map.json +0 -298
- package/test-projects/fastapi-app/.ai-dev/repo_map.md +0 -74
- package/test-projects/fastapi-app/.ai-dev/schema.json +0 -5
- package/test-projects/fastapi-app/.ai-dev/summary.md +0 -12
- package/test-projects/fastapi-app/.ai-dev/symbols.json +0 -1
- package/test-projects/fastapi-app/.ai-dev/tech_stack.md +0 -32
- package/test-projects/fastapi-app/.ai-dev/tools.json +0 -10
- package/test-projects/fastapi-app/README.md +0 -118
- package/test-projects/fastapi-app/app/database.py +0 -21
- package/test-projects/fastapi-app/app/dependencies.py +0 -107
- package/test-projects/fastapi-app/app/main.py +0 -47
- package/test-projects/fastapi-app/app/models.py +0 -149
- package/test-projects/fastapi-app/app/routers/auth.py +0 -117
- package/test-projects/fastapi-app/app/routers/posts.py +0 -272
- package/test-projects/fastapi-app/app/schemas.py +0 -191
- package/test-projects/fastapi-app/requirements.txt +0 -10
- package/test-projects/flask-app/.ai-dev/ai_context.md +0 -94
- package/test-projects/flask-app/.ai-dev/ai_rules.md +0 -47
- package/test-projects/flask-app/.ai-dev/architecture.md +0 -49
- package/test-projects/flask-app/.ai-dev/cache.json +0 -157
- package/test-projects/flask-app/.ai-dev/context/features/app.json +0 -25
- package/test-projects/flask-app/.ai-dev/context/flows/routes.json +0 -14
- package/test-projects/flask-app/.ai-dev/conventions.md +0 -51
- package/test-projects/flask-app/.ai-dev/dependencies.json +0 -298
- package/test-projects/flask-app/.ai-dev/entrypoints.md +0 -4
- package/test-projects/flask-app/.ai-dev/files.json +0 -194
- package/test-projects/flask-app/.ai-dev/graph/knowledge-graph.json +0 -60
- package/test-projects/flask-app/.ai-dev/graph/module-graph.json +0 -95
- package/test-projects/flask-app/.ai-dev/graph/symbol-graph.json +0 -1448
- package/test-projects/flask-app/.ai-dev/graph/symbol-references.json +0 -45
- package/test-projects/flask-app/.ai-dev/index-state.json +0 -273
- package/test-projects/flask-app/.ai-dev/modules.json +0 -21
- package/test-projects/flask-app/.ai-dev/project.json +0 -13
- package/test-projects/flask-app/.ai-dev/repo_map.json +0 -400
- package/test-projects/flask-app/.ai-dev/repo_map.md +0 -98
- package/test-projects/flask-app/.ai-dev/summary.md +0 -13
- package/test-projects/flask-app/.ai-dev/symbols.json +0 -1
- package/test-projects/flask-app/.ai-dev/tech_stack.md +0 -32
- package/test-projects/flask-app/.ai-dev/tools.json +0 -10
- package/test-projects/flask-app/README.md +0 -129
- package/test-projects/flask-app/app/__init__.py +0 -46
- package/test-projects/flask-app/app/api/__init__.py +0 -7
- package/test-projects/flask-app/app/api/routes.py +0 -122
- package/test-projects/flask-app/app/auth/__init__.py +0 -7
- package/test-projects/flask-app/app/auth/forms.py +0 -52
- package/test-projects/flask-app/app/auth/routes.py +0 -68
- package/test-projects/flask-app/app/blog/__init__.py +0 -7
- package/test-projects/flask-app/app/blog/forms.py +0 -35
- package/test-projects/flask-app/app/blog/routes.py +0 -140
- package/test-projects/flask-app/app/main/__init__.py +0 -7
- package/test-projects/flask-app/app/main/routes.py +0 -88
- package/test-projects/flask-app/app/models.py +0 -177
- package/test-projects/flask-app/config.py +0 -64
- package/test-projects/flask-app/requirements.txt +0 -10
- package/test-projects/laravel-app/.ai-dev/ai_context.md +0 -97
- package/test-projects/laravel-app/.ai-dev/ai_rules.md +0 -47
- package/test-projects/laravel-app/.ai-dev/architecture.md +0 -60
- package/test-projects/laravel-app/.ai-dev/cache.json +0 -161
- package/test-projects/laravel-app/.ai-dev/context/features/app.json +0 -21
- package/test-projects/laravel-app/.ai-dev/context/flows/.json +0 -9
- package/test-projects/laravel-app/.ai-dev/context/flows/category.json +0 -12
- package/test-projects/laravel-app/.ai-dev/context/flows/comment.json +0 -12
- package/test-projects/laravel-app/.ai-dev/context/flows/post.json +0 -12
- package/test-projects/laravel-app/.ai-dev/context/flows/unnamed.json +0 -9
- package/test-projects/laravel-app/.ai-dev/conventions.md +0 -51
- package/test-projects/laravel-app/.ai-dev/dependencies.json +0 -6
- package/test-projects/laravel-app/.ai-dev/entrypoints.md +0 -4
- package/test-projects/laravel-app/.ai-dev/files.json +0 -199
- package/test-projects/laravel-app/.ai-dev/graph/knowledge-graph.json +0 -98
- package/test-projects/laravel-app/.ai-dev/graph/module-graph.json +0 -30
- package/test-projects/laravel-app/.ai-dev/graph/symbol-graph.json +0 -5
- package/test-projects/laravel-app/.ai-dev/graph/symbol-references.json +0 -1
- package/test-projects/laravel-app/.ai-dev/index-state.json +0 -280
- package/test-projects/laravel-app/.ai-dev/modules.json +0 -29
- package/test-projects/laravel-app/.ai-dev/project.json +0 -17
- package/test-projects/laravel-app/.ai-dev/repo_map.json +0 -419
- package/test-projects/laravel-app/.ai-dev/repo_map.md +0 -106
- package/test-projects/laravel-app/.ai-dev/schema.json +0 -5
- package/test-projects/laravel-app/.ai-dev/summary.md +0 -15
- package/test-projects/laravel-app/.ai-dev/symbols.json +0 -1
- package/test-projects/laravel-app/.ai-dev/tech_stack.md +0 -34
- package/test-projects/laravel-app/.ai-dev/tools.json +0 -10
- package/test-projects/laravel-app/README.md +0 -107
- package/test-projects/laravel-app/app/Http/Controllers/Api/CategoryController.php +0 -88
- package/test-projects/laravel-app/app/Http/Controllers/Api/CommentController.php +0 -56
- package/test-projects/laravel-app/app/Http/Controllers/Api/PostController.php +0 -174
- package/test-projects/laravel-app/app/Http/Controllers/Controller.php +0 -12
- package/test-projects/laravel-app/app/Models/Category.php +0 -34
- package/test-projects/laravel-app/app/Models/Comment.php +0 -51
- package/test-projects/laravel-app/app/Models/Post.php +0 -108
- package/test-projects/laravel-app/app/Models/User.php +0 -85
- package/test-projects/laravel-app/bootstrap/app.php +0 -25
- package/test-projects/laravel-app/composer.json +0 -35
- package/test-projects/laravel-app/routes/api.php +0 -40
- package/test-projects/nestjs-backend/.ai-dev/ai_context.md +0 -111
- package/test-projects/nestjs-backend/.ai-dev/ai_rules.md +0 -52
- package/test-projects/nestjs-backend/.ai-dev/architecture.md +0 -49
- package/test-projects/nestjs-backend/.ai-dev/cache.json +0 -169
- package/test-projects/nestjs-backend/.ai-dev/context/features/src.json +0 -23
- package/test-projects/nestjs-backend/.ai-dev/context/flows/auth.controller.json +0 -14
- package/test-projects/nestjs-backend/.ai-dev/context/flows/auth.json +0 -10
- package/test-projects/nestjs-backend/.ai-dev/context/flows/users..json +0 -10
- package/test-projects/nestjs-backend/.ai-dev/context/flows/users.controller.json +0 -14
- package/test-projects/nestjs-backend/.ai-dev/context/flows/users.json +0 -10
- package/test-projects/nestjs-backend/.ai-dev/conventions.md +0 -52
- package/test-projects/nestjs-backend/.ai-dev/dependencies.json +0 -152
- package/test-projects/nestjs-backend/.ai-dev/entrypoints.md +0 -18
- package/test-projects/nestjs-backend/.ai-dev/files.json +0 -209
- package/test-projects/nestjs-backend/.ai-dev/graph/knowledge-graph.json +0 -132
- package/test-projects/nestjs-backend/.ai-dev/graph/module-graph.json +0 -29
- package/test-projects/nestjs-backend/.ai-dev/graph/symbol-graph.json +0 -304
- package/test-projects/nestjs-backend/.ai-dev/graph/symbol-references.json +0 -5
- package/test-projects/nestjs-backend/.ai-dev/index-state.json +0 -294
- package/test-projects/nestjs-backend/.ai-dev/modules.json +0 -19
- package/test-projects/nestjs-backend/.ai-dev/project.json +0 -18
- package/test-projects/nestjs-backend/.ai-dev/repo_map.json +0 -427
- package/test-projects/nestjs-backend/.ai-dev/repo_map.md +0 -104
- package/test-projects/nestjs-backend/.ai-dev/schema.json +0 -5
- package/test-projects/nestjs-backend/.ai-dev/summary.md +0 -13
- package/test-projects/nestjs-backend/.ai-dev/symbols.json +0 -1
- package/test-projects/nestjs-backend/.ai-dev/tech_stack.md +0 -38
- package/test-projects/nestjs-backend/.ai-dev/tools.json +0 -10
- package/test-projects/nestjs-backend/package.json +0 -22
- package/test-projects/nestjs-backend/src/app.module.ts +0 -8
- package/test-projects/nestjs-backend/src/auth/auth.controller.ts +0 -22
- package/test-projects/nestjs-backend/src/auth/auth.module.ts +0 -11
- package/test-projects/nestjs-backend/src/auth/auth.service.ts +0 -28
- package/test-projects/nestjs-backend/src/auth/dto/login.dto.ts +0 -4
- package/test-projects/nestjs-backend/src/auth/strategies/jwt.strategy.ts +0 -18
- package/test-projects/nestjs-backend/src/main.ts +0 -9
- package/test-projects/nestjs-backend/src/users/users.controller.ts +0 -32
- package/test-projects/nestjs-backend/src/users/users.module.ts +0 -10
- package/test-projects/nestjs-backend/src/users/users.service.ts +0 -42
- package/test-projects/nestjs-backend/tsconfig.json +0 -21
- package/test-projects/python-cli/.ai-dev/ai_context.md +0 -95
- package/test-projects/python-cli/.ai-dev/ai_rules.md +0 -47
- package/test-projects/python-cli/.ai-dev/architecture.md +0 -55
- package/test-projects/python-cli/.ai-dev/cache.json +0 -149
- package/test-projects/python-cli/.ai-dev/context/features/cli.json +0 -16
- package/test-projects/python-cli/.ai-dev/context/flows/list_.json +0 -9
- package/test-projects/python-cli/.ai-dev/context/flows/remove_.json +0 -9
- package/test-projects/python-cli/.ai-dev/conventions.md +0 -51
- package/test-projects/python-cli/.ai-dev/dependencies.json +0 -66
- package/test-projects/python-cli/.ai-dev/entrypoints.md +0 -4
- package/test-projects/python-cli/.ai-dev/files.json +0 -184
- package/test-projects/python-cli/.ai-dev/graph/knowledge-graph.json +0 -83
- package/test-projects/python-cli/.ai-dev/graph/module-graph.json +0 -31
- package/test-projects/python-cli/.ai-dev/graph/symbol-graph.json +0 -358
- package/test-projects/python-cli/.ai-dev/graph/symbol-references.json +0 -11
- package/test-projects/python-cli/.ai-dev/index-state.json +0 -259
- package/test-projects/python-cli/.ai-dev/modules.json +0 -21
- package/test-projects/python-cli/.ai-dev/project.json +0 -15
- package/test-projects/python-cli/.ai-dev/repo_map.json +0 -367
- package/test-projects/python-cli/.ai-dev/repo_map.md +0 -93
- package/test-projects/python-cli/.ai-dev/schema.json +0 -5
- package/test-projects/python-cli/.ai-dev/summary.md +0 -14
- package/test-projects/python-cli/.ai-dev/symbols.json +0 -1
- package/test-projects/python-cli/.ai-dev/tech_stack.md +0 -32
- package/test-projects/python-cli/.ai-dev/tools.json +0 -10
- package/test-projects/python-cli/__init__.py +0 -1
- package/test-projects/python-cli/cli/__init__.py +0 -1
- package/test-projects/python-cli/cli/add_command.py +0 -6
- package/test-projects/python-cli/cli/list_command.py +0 -7
- package/test-projects/python-cli/cli/remove_command.py +0 -6
- package/test-projects/python-cli/main.py +0 -34
- package/test-projects/python-cli/models/__init__.py +0 -2
- package/test-projects/python-cli/models/task.py +0 -19
- package/test-projects/python-cli/models/task_repository.py +0 -44
- package/test-projects/rails-app/.ai-dev/ai_context.md +0 -94
- package/test-projects/rails-app/.ai-dev/ai_rules.md +0 -47
- package/test-projects/rails-app/.ai-dev/architecture.md +0 -49
- package/test-projects/rails-app/.ai-dev/cache.json +0 -193
- package/test-projects/rails-app/.ai-dev/context/features/app.json +0 -24
- package/test-projects/rails-app/.ai-dev/context/features/config.json +0 -13
- package/test-projects/rails-app/.ai-dev/context/flows/application.json +0 -9
- package/test-projects/rails-app/.ai-dev/context/flows/application_.json +0 -9
- package/test-projects/rails-app/.ai-dev/context/flows/comments.json +0 -11
- package/test-projects/rails-app/.ai-dev/context/flows/comments_.json +0 -11
- package/test-projects/rails-app/.ai-dev/context/flows/posts.json +0 -11
- package/test-projects/rails-app/.ai-dev/context/flows/posts_.json +0 -11
- package/test-projects/rails-app/.ai-dev/context/flows/routes.json +0 -9
- package/test-projects/rails-app/.ai-dev/context/flows/users.json +0 -11
- package/test-projects/rails-app/.ai-dev/context/flows/users_.json +0 -11
- package/test-projects/rails-app/.ai-dev/conventions.md +0 -51
- package/test-projects/rails-app/.ai-dev/dependencies.json +0 -6
- package/test-projects/rails-app/.ai-dev/entrypoints.md +0 -4
- package/test-projects/rails-app/.ai-dev/files.json +0 -239
- package/test-projects/rails-app/.ai-dev/graph/knowledge-graph.json +0 -130
- package/test-projects/rails-app/.ai-dev/graph/module-graph.json +0 -27
- package/test-projects/rails-app/.ai-dev/graph/symbol-graph.json +0 -5
- package/test-projects/rails-app/.ai-dev/graph/symbol-references.json +0 -1
- package/test-projects/rails-app/.ai-dev/index-state.json +0 -336
- package/test-projects/rails-app/.ai-dev/modules.json +0 -26
- package/test-projects/rails-app/.ai-dev/project.json +0 -22
- package/test-projects/rails-app/.ai-dev/repo_map.json +0 -486
- package/test-projects/rails-app/.ai-dev/repo_map.md +0 -117
- package/test-projects/rails-app/.ai-dev/schema.json +0 -5
- package/test-projects/rails-app/.ai-dev/summary.md +0 -13
- package/test-projects/rails-app/.ai-dev/symbols.json +0 -1
- package/test-projects/rails-app/.ai-dev/tech_stack.md +0 -32
- package/test-projects/rails-app/.ai-dev/tools.json +0 -10
- package/test-projects/rails-app/Gemfile +0 -38
- package/test-projects/rails-app/README.md +0 -140
- package/test-projects/rails-app/Rakefile +0 -8
- package/test-projects/rails-app/app/controllers/api/comments_controller.rb +0 -75
- package/test-projects/rails-app/app/controllers/api/posts_controller.rb +0 -68
- package/test-projects/rails-app/app/controllers/api/users_controller.rb +0 -54
- package/test-projects/rails-app/app/controllers/application_controller.rb +0 -31
- package/test-projects/rails-app/app/models/comment.rb +0 -34
- package/test-projects/rails-app/app/models/post.rb +0 -36
- package/test-projects/rails-app/app/models/user.rb +0 -28
- package/test-projects/rails-app/app/services/post_service.rb +0 -92
- package/test-projects/rails-app/app/services/user_service.rb +0 -76
- package/test-projects/rails-app/config/application.rb +0 -27
- package/test-projects/rails-app/config/environment.rb +0 -7
- package/test-projects/rails-app/config/routes.rb +0 -15
- package/test-projects/react-app/.ai-dev/ai_context.md +0 -96
- package/test-projects/react-app/.ai-dev/architecture.md +0 -39
- package/test-projects/react-app/.ai-dev/cache.json +0 -153
- package/test-projects/react-app/.ai-dev/context/features/src.json +0 -18
- package/test-projects/react-app/.ai-dev/context/flows/UsersPage.json +0 -14
- package/test-projects/react-app/.ai-dev/context/flows/dashboard.json +0 -9
- package/test-projects/react-app/.ai-dev/context/flows/login.json +0 -9
- package/test-projects/react-app/.ai-dev/context/flows/users.json +0 -9
- package/test-projects/react-app/.ai-dev/dependencies.json +0 -128
- package/test-projects/react-app/.ai-dev/entrypoints.md +0 -4
- package/test-projects/react-app/.ai-dev/files.json +0 -189
- package/test-projects/react-app/.ai-dev/graph/knowledge-graph.json +0 -112
- package/test-projects/react-app/.ai-dev/graph/module-graph.json +0 -31
- package/test-projects/react-app/.ai-dev/graph/symbol-graph.json +0 -868
- package/test-projects/react-app/.ai-dev/graph/symbol-references.json +0 -31
- package/test-projects/react-app/.ai-dev/index-state.json +0 -266
- package/test-projects/react-app/.ai-dev/modules.json +0 -17
- package/test-projects/react-app/.ai-dev/project.json +0 -16
- package/test-projects/react-app/.ai-dev/repo_map.json +0 -391
- package/test-projects/react-app/.ai-dev/repo_map.md +0 -94
- package/test-projects/react-app/.ai-dev/schema.json +0 -5
- package/test-projects/react-app/.ai-dev/summary.md +0 -13
- package/test-projects/react-app/.ai-dev/symbols.json +0 -1
- package/test-projects/react-app/.ai-dev/tools.json +0 -10
- package/test-projects/react-app/package.json +0 -16
- package/test-projects/react-app/src/App.tsx +0 -21
- package/test-projects/react-app/src/context/AuthContext.tsx +0 -41
- package/test-projects/react-app/src/hooks/useAuth.ts +0 -10
- package/test-projects/react-app/src/main.tsx +0 -10
- package/test-projects/react-app/src/pages/DashboardPage.tsx +0 -17
- package/test-projects/react-app/src/pages/LoginPage.tsx +0 -41
- package/test-projects/react-app/src/pages/UsersPage.tsx +0 -36
- package/test-projects/react-app/src/services/userService.ts +0 -37
- package/test-projects/salesforce-cli/.ai-dev/ai_context.md +0 -89
- package/test-projects/salesforce-cli/.ai-dev/ai_rules.md +0 -47
- package/test-projects/salesforce-cli/.ai-dev/architecture.md +0 -39
- package/test-projects/salesforce-cli/.ai-dev/cache.json +0 -125
- package/test-projects/salesforce-cli/.ai-dev/context/features/force-app.json +0 -14
- package/test-projects/salesforce-cli/.ai-dev/context/flows/account.json +0 -9
- package/test-projects/salesforce-cli/.ai-dev/context/flows/opportunity.json +0 -9
- package/test-projects/salesforce-cli/.ai-dev/conventions.md +0 -51
- package/test-projects/salesforce-cli/.ai-dev/dependencies.json +0 -6
- package/test-projects/salesforce-cli/.ai-dev/entrypoints.md +0 -4
- package/test-projects/salesforce-cli/.ai-dev/files.json +0 -154
- package/test-projects/salesforce-cli/.ai-dev/graph/knowledge-graph.json +0 -64
- package/test-projects/salesforce-cli/.ai-dev/graph/module-graph.json +0 -13
- package/test-projects/salesforce-cli/.ai-dev/graph/symbol-graph.json +0 -148
- package/test-projects/salesforce-cli/.ai-dev/graph/symbol-references.json +0 -1
- package/test-projects/salesforce-cli/.ai-dev/index-state.json +0 -217
- package/test-projects/salesforce-cli/.ai-dev/modules.json +0 -12
- package/test-projects/salesforce-cli/.ai-dev/project.json +0 -14
- package/test-projects/salesforce-cli/.ai-dev/repo_map.json +0 -328
- package/test-projects/salesforce-cli/.ai-dev/repo_map.md +0 -80
- package/test-projects/salesforce-cli/.ai-dev/schema.json +0 -5
- package/test-projects/salesforce-cli/.ai-dev/summary.md +0 -13
- package/test-projects/salesforce-cli/.ai-dev/symbols.json +0 -1
- package/test-projects/salesforce-cli/.ai-dev/tech_stack.md +0 -31
- package/test-projects/salesforce-cli/.ai-dev/tools.json +0 -10
- package/test-projects/salesforce-cli/.forceignore +0 -27
- package/test-projects/salesforce-cli/force-app/main/default/classes/AccountController.cls +0 -24
- package/test-projects/salesforce-cli/force-app/main/default/classes/OpportunityController.cls +0 -25
- package/test-projects/salesforce-cli/force-app/main/default/objects/Project__c.object.xml +0 -45
- package/test-projects/salesforce-cli/force-app/main/default/triggers/AccountTrigger.trigger +0 -33
- package/test-projects/salesforce-cli/sfdx-project.json +0 -11
- package/test-projects/spring-boot-app/.ai-dev/ai_context.md +0 -91
- package/test-projects/spring-boot-app/.ai-dev/ai_rules.md +0 -48
- package/test-projects/spring-boot-app/.ai-dev/architecture.md +0 -39
- package/test-projects/spring-boot-app/.ai-dev/cache.json +0 -173
- package/test-projects/spring-boot-app/.ai-dev/context/features/src.json +0 -26
- package/test-projects/spring-boot-app/.ai-dev/context/flows/PostController.json +0 -19
- package/test-projects/spring-boot-app/.ai-dev/context/flows/UserController.json +0 -19
- package/test-projects/spring-boot-app/.ai-dev/context/flows/comment.json +0 -11
- package/test-projects/spring-boot-app/.ai-dev/context/flows/post.json +0 -14
- package/test-projects/spring-boot-app/.ai-dev/context/flows/user.json +0 -14
- package/test-projects/spring-boot-app/.ai-dev/conventions.md +0 -52
- package/test-projects/spring-boot-app/.ai-dev/dependencies.json +0 -326
- package/test-projects/spring-boot-app/.ai-dev/entrypoints.md +0 -4
- package/test-projects/spring-boot-app/.ai-dev/files.json +0 -214
- package/test-projects/spring-boot-app/.ai-dev/graph/knowledge-graph.json +0 -231
- package/test-projects/spring-boot-app/.ai-dev/graph/module-graph.json +0 -22
- package/test-projects/spring-boot-app/.ai-dev/graph/symbol-graph.json +0 -794
- package/test-projects/spring-boot-app/.ai-dev/graph/symbol-references.json +0 -70
- package/test-projects/spring-boot-app/.ai-dev/index-state.json +0 -301
- package/test-projects/spring-boot-app/.ai-dev/modules.json +0 -21
- package/test-projects/spring-boot-app/.ai-dev/project.json +0 -17
- package/test-projects/spring-boot-app/.ai-dev/repo_map.json +0 -461
- package/test-projects/spring-boot-app/.ai-dev/repo_map.md +0 -109
- package/test-projects/spring-boot-app/.ai-dev/schema.json +0 -5
- package/test-projects/spring-boot-app/.ai-dev/summary.md +0 -12
- package/test-projects/spring-boot-app/.ai-dev/symbols.json +0 -1
- package/test-projects/spring-boot-app/.ai-dev/tech_stack.md +0 -32
- package/test-projects/spring-boot-app/.ai-dev/tools.json +0 -10
- package/test-projects/spring-boot-app/.classpath +0 -57
- package/test-projects/spring-boot-app/.factorypath +0 -69
- package/test-projects/spring-boot-app/.project +0 -34
- package/test-projects/spring-boot-app/.settings/org.eclipse.core.resources.prefs +0 -4
- package/test-projects/spring-boot-app/.settings/org.eclipse.jdt.apt.core.prefs +0 -4
- package/test-projects/spring-boot-app/.settings/org.eclipse.jdt.core.prefs +0 -10
- package/test-projects/spring-boot-app/.settings/org.eclipse.m2e.core.prefs +0 -4
- package/test-projects/spring-boot-app/README.md +0 -122
- package/test-projects/spring-boot-app/pom.xml +0 -79
- package/test-projects/spring-boot-app/src/main/java/com/example/demo/DemoApplication.java +0 -12
- package/test-projects/spring-boot-app/src/main/java/com/example/demo/controllers/CommentController.java +0 -89
- package/test-projects/spring-boot-app/src/main/java/com/example/demo/controllers/PostController.java +0 -92
- package/test-projects/spring-boot-app/src/main/java/com/example/demo/controllers/UserController.java +0 -84
- package/test-projects/spring-boot-app/src/main/java/com/example/demo/models/Comment.java +0 -38
- package/test-projects/spring-boot-app/src/main/java/com/example/demo/models/Post.java +0 -56
- package/test-projects/spring-boot-app/src/main/java/com/example/demo/models/User.java +0 -44
- package/test-projects/spring-boot-app/src/main/java/com/example/demo/repositories/CommentRepository.java +0 -21
- package/test-projects/spring-boot-app/src/main/java/com/example/demo/repositories/PostRepository.java +0 -18
- package/test-projects/spring-boot-app/src/main/java/com/example/demo/repositories/UserRepository.java +0 -15
- package/test-projects/spring-boot-app/src/main/java/com/example/demo/services/PostService.java +0 -83
- package/test-projects/spring-boot-app/src/main/java/com/example/demo/services/UserService.java +0 -62
- package/test-projects/spring-boot-app/src/main/resources/application.properties +0 -22
- package/test-projects/spring-boot-app/target/classes/com/example/demo/DemoApplication.class +0 -0
- package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/CommentController$CommentCreateRequest.class +0 -0
- package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/CommentController$CommentUpdateRequest.class +0 -0
- package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/CommentController.class +0 -0
- package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/PostController$PostCreateRequest.class +0 -0
- package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/PostController$PostUpdateRequest.class +0 -0
- package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/PostController.class +0 -0
- package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/UserController$UserCreateRequest.class +0 -0
- package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/UserController$UserUpdateRequest.class +0 -0
- package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/UserController.class +0 -0
- package/test-projects/spring-boot-app/target/classes/com/example/demo/models/Comment.class +0 -0
- package/test-projects/spring-boot-app/target/classes/com/example/demo/models/Post.class +0 -0
- package/test-projects/spring-boot-app/target/classes/com/example/demo/models/User.class +0 -0
- package/test-projects/spring-boot-app/target/classes/com/example/demo/repositories/CommentRepository.class +0 -0
- package/test-projects/spring-boot-app/target/classes/com/example/demo/repositories/PostRepository.class +0 -0
- package/test-projects/spring-boot-app/target/classes/com/example/demo/repositories/UserRepository.class +0 -0
- package/test-projects/spring-boot-app/target/classes/com/example/demo/services/PostService.class +0 -0
- package/test-projects/spring-boot-app/target/classes/com/example/demo/services/UserService.class +0 -0
- package/tests/e2e/run-e2e.sh +0 -88
- /package/{test-projects/django-app/.ai-dev → ai-context}/tools.json +0 -0
|
@@ -0,0 +1,1007 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll, afterAll, beforeEach } from "vitest";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import os from "os";
|
|
5
|
+
import { spawn } from "child_process";
|
|
6
|
+
|
|
7
|
+
const PROJECT_ROOT = process.cwd();
|
|
8
|
+
const CLI_PATH = path.join(PROJECT_ROOT, "dist/commands/ai-first.js");
|
|
9
|
+
const EXPRESS_API_PATH = path.join(PROJECT_ROOT, "test-projects/express-api");
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Creates a temporary project directory with some source files
|
|
13
|
+
*/
|
|
14
|
+
function createTempProjectDir(files: Record<string, string>): string {
|
|
15
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "cli-index-test-"));
|
|
16
|
+
for (const [filePath, content] of Object.entries(files)) {
|
|
17
|
+
const fullPath = path.join(tempDir, filePath);
|
|
18
|
+
const dir = path.dirname(fullPath);
|
|
19
|
+
if (!fs.existsSync(dir)) {
|
|
20
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
21
|
+
}
|
|
22
|
+
fs.writeFileSync(fullPath, content);
|
|
23
|
+
}
|
|
24
|
+
return tempDir;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Creates a project with many files for testing adaptive processing
|
|
29
|
+
*/
|
|
30
|
+
function createLargeProjectDir(fileCount: number, filesPerDir: number = 10): string {
|
|
31
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "cli-index-large-"));
|
|
32
|
+
|
|
33
|
+
fs.writeFileSync(path.join(tempDir, "package.json"), JSON.stringify({ name: "large-test", version: "1.0.0" }));
|
|
34
|
+
|
|
35
|
+
const dirs = ["src/api", "src/services", "src/utils", "src/models", "src/controllers"];
|
|
36
|
+
|
|
37
|
+
for (const dir of dirs) {
|
|
38
|
+
const dirPath = path.join(tempDir, dir);
|
|
39
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
40
|
+
|
|
41
|
+
const filesToCreate = Math.min(filesPerDir, Math.ceil(fileCount / dirs.length));
|
|
42
|
+
for (let i = 0; i < filesToCreate; i++) {
|
|
43
|
+
const ext = i % 3 === 0 ? ".ts" : i % 3 === 1 ? ".js" : ".py";
|
|
44
|
+
const fileName = `file${i}${ext}`;
|
|
45
|
+
const content = ext === ".py"
|
|
46
|
+
? `def function_${i}():\n pass\n`
|
|
47
|
+
: ext === ".ts"
|
|
48
|
+
? `export function function${i}() {\n return ${i};\n}\n`
|
|
49
|
+
: `function function${i}() {\n return ${i};\n}\nmodule.exports = { function${i} };\n`;
|
|
50
|
+
fs.writeFileSync(path.join(dirPath, fileName), content);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return tempDir;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Run the CLI index command
|
|
59
|
+
*/
|
|
60
|
+
async function runIndexCommand(
|
|
61
|
+
args: string[],
|
|
62
|
+
cwd: string = process.cwd()
|
|
63
|
+
): Promise<{ stdout: string; stderr: string; exitCode: number }> {
|
|
64
|
+
return new Promise((resolve) => {
|
|
65
|
+
const child = spawn("node", [CLI_PATH, "index", ...args], {
|
|
66
|
+
cwd,
|
|
67
|
+
stdio: "pipe",
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
let stdout = "";
|
|
71
|
+
let stderr = "";
|
|
72
|
+
|
|
73
|
+
child.stdout?.on("data", (data) => {
|
|
74
|
+
stdout += data.toString();
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
child.stderr?.on("data", (data) => {
|
|
78
|
+
stderr += data.toString();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
child.on("close", (code) => {
|
|
82
|
+
resolve({
|
|
83
|
+
stdout,
|
|
84
|
+
stderr,
|
|
85
|
+
exitCode: code ?? 0,
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
child.on("error", (err) => {
|
|
90
|
+
stderr += err.message;
|
|
91
|
+
resolve({ stdout, stderr, exitCode: 1 });
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Timeout after 120 seconds for large projects
|
|
95
|
+
setTimeout(() => {
|
|
96
|
+
child.kill();
|
|
97
|
+
resolve({ stdout, stderr, exitCode: 124 });
|
|
98
|
+
}, 120000);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
describe("CLI Index Command", () => {
|
|
103
|
+
let tempDir: string;
|
|
104
|
+
const tempDirs: string[] = [];
|
|
105
|
+
|
|
106
|
+
beforeAll(() => {
|
|
107
|
+
// Ensure dist is built
|
|
108
|
+
if (!fs.existsSync(CLI_PATH)) {
|
|
109
|
+
throw new Error(
|
|
110
|
+
`CLI not found at ${CLI_PATH}. Run 'npm run build' first.`
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
beforeEach(() => {
|
|
116
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "cli-index-test-"));
|
|
117
|
+
tempDirs.push(tempDir);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
afterAll(() => {
|
|
121
|
+
// Clean up all temp directories
|
|
122
|
+
for (const dir of tempDirs) {
|
|
123
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// =========================================================================
|
|
128
|
+
// DEFAULT OPTIONS TESTS
|
|
129
|
+
// =========================================================================
|
|
130
|
+
|
|
131
|
+
describe("Default Options", () => {
|
|
132
|
+
it("should run index command successfully on express-api project", async () => {
|
|
133
|
+
const result = await runIndexCommand([], EXPRESS_API_PATH);
|
|
134
|
+
|
|
135
|
+
expect(result.exitCode).toBe(0);
|
|
136
|
+
expect(result.stdout).toContain("Generating index");
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("should create ai-context directory with index.db", async () => {
|
|
140
|
+
const aiContextDir = path.join(EXPRESS_API_PATH, "ai-context");
|
|
141
|
+
const indexDbPath = path.join(aiContextDir, "index.db");
|
|
142
|
+
|
|
143
|
+
// Clean up if exists
|
|
144
|
+
if (fs.existsSync(aiContextDir)) {
|
|
145
|
+
fs.rmSync(aiContextDir, { recursive: true, force: true });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const result = await runIndexCommand([], EXPRESS_API_PATH);
|
|
149
|
+
|
|
150
|
+
expect(result.exitCode).toBe(0);
|
|
151
|
+
expect(fs.existsSync(aiContextDir)).toBe(true);
|
|
152
|
+
expect(fs.existsSync(indexDbPath)).toBe(true);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it("should create SQLite database with valid schema", async () => {
|
|
156
|
+
const testProject = createTempProjectDir({
|
|
157
|
+
"index.js": "const app = require('./app');",
|
|
158
|
+
"package.json": '{"name": "test"}',
|
|
159
|
+
"src/main.ts": "export const main = () => {};",
|
|
160
|
+
"src/utils.ts": "export const helper = () => {};",
|
|
161
|
+
});
|
|
162
|
+
tempDirs.push(testProject);
|
|
163
|
+
|
|
164
|
+
await runIndexCommand([], testProject);
|
|
165
|
+
|
|
166
|
+
const dbPath = path.join(testProject, "ai-context", "index.db");
|
|
167
|
+
expect(fs.existsSync(dbPath)).toBe(true);
|
|
168
|
+
|
|
169
|
+
// Check that the database file is not empty
|
|
170
|
+
const stats = fs.statSync(dbPath);
|
|
171
|
+
expect(stats.size).toBeGreaterThan(0);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it("should create index-state.json for incremental indexing", async () => {
|
|
175
|
+
const testProject = createTempProjectDir({
|
|
176
|
+
"index.js": "const app = require('./app');",
|
|
177
|
+
"package.json": '{"name": "test"}',
|
|
178
|
+
});
|
|
179
|
+
tempDirs.push(testProject);
|
|
180
|
+
|
|
181
|
+
await runIndexCommand([], testProject);
|
|
182
|
+
|
|
183
|
+
const statePath = path.join(testProject, "ai-context", "index-state.json");
|
|
184
|
+
expect(fs.existsSync(statePath)).toBe(true);
|
|
185
|
+
|
|
186
|
+
const content = fs.readFileSync(statePath, "utf-8");
|
|
187
|
+
const state = JSON.parse(content);
|
|
188
|
+
|
|
189
|
+
expect(state.version).toBe("1.0.0");
|
|
190
|
+
expect(state.lastIndexed).toBeDefined();
|
|
191
|
+
expect(state.totalFiles).toBeGreaterThan(0);
|
|
192
|
+
expect(state.files).toBeDefined();
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it("should create files.json with file listing", async () => {
|
|
196
|
+
const testProject = createTempProjectDir({
|
|
197
|
+
"index.js": "const app = require('./app');",
|
|
198
|
+
"package.json": '{"name": "test"}',
|
|
199
|
+
"src/main.ts": "export const main = () => {};",
|
|
200
|
+
});
|
|
201
|
+
tempDirs.push(testProject);
|
|
202
|
+
|
|
203
|
+
await runIndexCommand([], testProject);
|
|
204
|
+
|
|
205
|
+
const filesJsonPath = path.join(testProject, "ai-context", "files.json");
|
|
206
|
+
expect(fs.existsSync(filesJsonPath)).toBe(true);
|
|
207
|
+
|
|
208
|
+
const content = fs.readFileSync(filesJsonPath, "utf-8");
|
|
209
|
+
const data = JSON.parse(content);
|
|
210
|
+
|
|
211
|
+
expect(data.files).toBeDefined();
|
|
212
|
+
expect(Array.isArray(data.files)).toBe(true);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it("should create modules.json with module structure", async () => {
|
|
216
|
+
const testProject = createTempProjectDir({
|
|
217
|
+
"index.js": "const app = require('./app');",
|
|
218
|
+
"package.json": '{"name": "test"}',
|
|
219
|
+
"src/main.ts": "export const main = () => {};",
|
|
220
|
+
"src/api/routes.ts": "export const routes = [];",
|
|
221
|
+
});
|
|
222
|
+
tempDirs.push(testProject);
|
|
223
|
+
|
|
224
|
+
await runIndexCommand([], testProject);
|
|
225
|
+
|
|
226
|
+
const modulesPath = path.join(testProject, "ai-context", "modules.json");
|
|
227
|
+
expect(fs.existsSync(modulesPath)).toBe(true);
|
|
228
|
+
|
|
229
|
+
const content = fs.readFileSync(modulesPath, "utf-8");
|
|
230
|
+
const data = JSON.parse(content);
|
|
231
|
+
|
|
232
|
+
expect(data.modules).toBeDefined();
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// =========================================================================
|
|
237
|
+
// --semantic FLAG TESTS
|
|
238
|
+
// =========================================================================
|
|
239
|
+
|
|
240
|
+
describe("--semantic Flag", () => {
|
|
241
|
+
it("should enable semantic mode with --semantic flag", async () => {
|
|
242
|
+
const testProject = createTempProjectDir({
|
|
243
|
+
"index.js": "const app = require('./app');",
|
|
244
|
+
"package.json": '{"name": "test"}',
|
|
245
|
+
"src/main.ts": "export const main = () => {};",
|
|
246
|
+
});
|
|
247
|
+
tempDirs.push(testProject);
|
|
248
|
+
|
|
249
|
+
const result = await runIndexCommand(["--semantic"], testProject);
|
|
250
|
+
|
|
251
|
+
expect(result.exitCode).toBe(0);
|
|
252
|
+
expect(result.stdout).toContain("Semantic mode enabled");
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it("should process code files for embeddings with --semantic", async () => {
|
|
256
|
+
const testProject = createTempProjectDir({
|
|
257
|
+
"index.js": "const app = require('./app');",
|
|
258
|
+
"package.json": '{"name": "test"}',
|
|
259
|
+
"src/main.ts": "export const main = () => {};",
|
|
260
|
+
"src/utils.ts": "export const helper = () => {};",
|
|
261
|
+
});
|
|
262
|
+
tempDirs.push(testProject);
|
|
263
|
+
|
|
264
|
+
const result = await runIndexCommand(["--semantic"], testProject);
|
|
265
|
+
|
|
266
|
+
expect(result.exitCode).toBe(0);
|
|
267
|
+
// Should show processing of code files
|
|
268
|
+
expect(result.stdout).toContain("Processing");
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it("should handle --semantic with short flag -s", async () => {
|
|
272
|
+
const testProject = createTempProjectDir({
|
|
273
|
+
"index.js": "const app = require('./app');",
|
|
274
|
+
"package.json": '{"name": "test"}',
|
|
275
|
+
});
|
|
276
|
+
tempDirs.push(testProject);
|
|
277
|
+
|
|
278
|
+
const result = await runIndexCommand(["-s"], testProject);
|
|
279
|
+
|
|
280
|
+
expect(result.exitCode).toBe(0);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
it("should create semantic embeddings in database with --semantic", async () => {
|
|
284
|
+
const testProject = createTempProjectDir({
|
|
285
|
+
"index.js": "const app = require('./app');",
|
|
286
|
+
"package.json": '{"name": "test"}',
|
|
287
|
+
"src/main.ts": "export const main = (): void => {};",
|
|
288
|
+
});
|
|
289
|
+
tempDirs.push(testProject);
|
|
290
|
+
|
|
291
|
+
await runIndexCommand(["--semantic"], testProject);
|
|
292
|
+
|
|
293
|
+
const dbPath = path.join(testProject, "ai-context", "index.db");
|
|
294
|
+
expect(fs.existsSync(dbPath)).toBe(true);
|
|
295
|
+
|
|
296
|
+
// Database should be larger with embeddings
|
|
297
|
+
const stats = fs.statSync(dbPath);
|
|
298
|
+
expect(stats.size).toBeGreaterThan(100);
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
// =========================================================================
|
|
303
|
+
// ADAPTIVE PROCESSING TESTS
|
|
304
|
+
// =========================================================================
|
|
305
|
+
|
|
306
|
+
describe("Adaptive Processing", () => {
|
|
307
|
+
it("should handle small project (< 200 files) with structural index", async () => {
|
|
308
|
+
const testProject = createTempProjectDir({
|
|
309
|
+
"index.js": "const app = require('./app');",
|
|
310
|
+
"package.json": '{"name": "small-test"}',
|
|
311
|
+
"src/main.ts": "export const main = () => {};",
|
|
312
|
+
"src/utils.ts": "export const helper = () => {};",
|
|
313
|
+
"src/config.ts": "export const config = {};",
|
|
314
|
+
});
|
|
315
|
+
tempDirs.push(testProject);
|
|
316
|
+
|
|
317
|
+
const result = await runIndexCommand([], testProject);
|
|
318
|
+
|
|
319
|
+
expect(result.exitCode).toBe(0);
|
|
320
|
+
expect(result.stdout).toContain("Total files:");
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
it("should handle medium project (200-2000 files) with structural + module graph", async () => {
|
|
324
|
+
// Create a project with ~50 files (medium size)
|
|
325
|
+
const testProject = createLargeProjectDir(50, 10);
|
|
326
|
+
tempDirs.push(testProject);
|
|
327
|
+
|
|
328
|
+
const result = await runIndexCommand([], testProject);
|
|
329
|
+
|
|
330
|
+
expect(result.exitCode).toBe(0);
|
|
331
|
+
expect(result.stdout).toContain("Total files:");
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
it("should automatically enable semantic for large projects (> 2000 files)", async () => {
|
|
335
|
+
// Note: Creating 2000+ files is expensive, so we simulate by checking the threshold logic
|
|
336
|
+
// For actual test, we create a smaller project and verify the threshold warning appears
|
|
337
|
+
const testProject = createLargeProjectDir(100, 20);
|
|
338
|
+
tempDirs.push(testProject);
|
|
339
|
+
|
|
340
|
+
const result = await runIndexCommand([], testProject);
|
|
341
|
+
|
|
342
|
+
expect(result.exitCode).toBe(0);
|
|
343
|
+
// The message about large repository should appear if file count exceeds threshold
|
|
344
|
+
// Since we're under 2000, it shouldn't show the automatic semantic message
|
|
345
|
+
expect(result).toBeDefined();
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
it("should show file count statistics", async () => {
|
|
349
|
+
const testProject = createTempProjectDir({
|
|
350
|
+
"index.js": "const app = require('./app');",
|
|
351
|
+
"package.json": '{"name": "test"}',
|
|
352
|
+
"src/main.ts": "export const main = () => {};",
|
|
353
|
+
"src/utils.ts": "export const helper = () => {};",
|
|
354
|
+
});
|
|
355
|
+
tempDirs.push(testProject);
|
|
356
|
+
|
|
357
|
+
const result = await runIndexCommand([], testProject);
|
|
358
|
+
|
|
359
|
+
expect(result.exitCode).toBe(0);
|
|
360
|
+
expect(result.stdout).toContain("Total files:");
|
|
361
|
+
expect(result.stdout).toContain("To index:");
|
|
362
|
+
expect(result.stdout).toContain("Unchanged:");
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// =========================================================================
|
|
367
|
+
// --root FLAG TESTS
|
|
368
|
+
// =========================================================================
|
|
369
|
+
|
|
370
|
+
describe("--root Flag", () => {
|
|
371
|
+
it("should index different directory with --root flag", async () => {
|
|
372
|
+
const testProject = createTempProjectDir({
|
|
373
|
+
"README.md": "# Test Project",
|
|
374
|
+
"src/index.ts": "export const test = 1;",
|
|
375
|
+
"package.json": '{"name": "root-test"}',
|
|
376
|
+
});
|
|
377
|
+
tempDirs.push(testProject);
|
|
378
|
+
|
|
379
|
+
const result = await runIndexCommand(["--root", testProject]);
|
|
380
|
+
|
|
381
|
+
expect(result.exitCode).toBe(0);
|
|
382
|
+
expect(result.stdout).toContain(testProject);
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
it("should handle --root with short flag -r", async () => {
|
|
386
|
+
const testProject = createTempProjectDir({
|
|
387
|
+
"README.md": "# Test Project",
|
|
388
|
+
"src/index.ts": "export const test = 1;",
|
|
389
|
+
});
|
|
390
|
+
tempDirs.push(testProject);
|
|
391
|
+
|
|
392
|
+
const result = await runIndexCommand(["-r", testProject]);
|
|
393
|
+
|
|
394
|
+
expect(result.exitCode).toBe(0);
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
it("should create index.db in ai-context of root directory", async () => {
|
|
398
|
+
const testProject = createTempProjectDir({
|
|
399
|
+
"index.js": "const app = require('./app');",
|
|
400
|
+
"package.json": '{"name": "test"}',
|
|
401
|
+
});
|
|
402
|
+
tempDirs.push(testProject);
|
|
403
|
+
|
|
404
|
+
await runIndexCommand(["--root", testProject]);
|
|
405
|
+
|
|
406
|
+
const dbPath = path.join(testProject, "ai-context", "index.db");
|
|
407
|
+
expect(fs.existsSync(dbPath)).toBe(true);
|
|
408
|
+
});
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
// =========================================================================
|
|
412
|
+
// --output FLAG TESTS
|
|
413
|
+
// =========================================================================
|
|
414
|
+
|
|
415
|
+
describe("--output Flag", () => {
|
|
416
|
+
it("should create custom output path for index.db with --output flag", async () => {
|
|
417
|
+
const testProject = createTempProjectDir({
|
|
418
|
+
"index.js": "const app = require('./app');",
|
|
419
|
+
"package.json": '{"name": "test"}',
|
|
420
|
+
});
|
|
421
|
+
tempDirs.push(testProject);
|
|
422
|
+
|
|
423
|
+
const customOutput = path.join(testProject, "custom-dir", "custom-index.db");
|
|
424
|
+
|
|
425
|
+
const result = await runIndexCommand(["--output", customOutput], testProject);
|
|
426
|
+
|
|
427
|
+
expect(result.exitCode).toBe(0);
|
|
428
|
+
expect(fs.existsSync(customOutput)).toBe(true);
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
it("should handle --output with short flag -o", async () => {
|
|
432
|
+
const testProject = createTempProjectDir({
|
|
433
|
+
"index.js": "const app = require('./app');",
|
|
434
|
+
"package.json": '{"name": "test"}',
|
|
435
|
+
});
|
|
436
|
+
tempDirs.push(testProject);
|
|
437
|
+
|
|
438
|
+
const customOutput = path.join(testProject, "custom.db");
|
|
439
|
+
|
|
440
|
+
const result = await runIndexCommand(["-o", customOutput], testProject);
|
|
441
|
+
|
|
442
|
+
expect(result.exitCode).toBe(0);
|
|
443
|
+
expect(fs.existsSync(customOutput)).toBe(true);
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
it("should work with both --root and --output combined", async () => {
|
|
447
|
+
const sourceProject = createTempProjectDir({
|
|
448
|
+
"src/index.ts": "export const main = () => {};",
|
|
449
|
+
"package.json": '{"name": "source"}',
|
|
450
|
+
});
|
|
451
|
+
const outputProject = createTempProjectDir({});
|
|
452
|
+
tempDirs.push(sourceProject);
|
|
453
|
+
tempDirs.push(outputProject);
|
|
454
|
+
|
|
455
|
+
const customOutput = path.join(outputProject, "index.db");
|
|
456
|
+
|
|
457
|
+
const result = await runIndexCommand(
|
|
458
|
+
["--root", sourceProject, "--output", customOutput],
|
|
459
|
+
sourceProject
|
|
460
|
+
);
|
|
461
|
+
|
|
462
|
+
expect(result.exitCode).toBe(0);
|
|
463
|
+
expect(fs.existsSync(customOutput)).toBe(true);
|
|
464
|
+
});
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
// =========================================================================
|
|
468
|
+
// INCREMENTAL INDEXING TESTS
|
|
469
|
+
// =========================================================================
|
|
470
|
+
|
|
471
|
+
describe("Incremental Indexing", () => {
|
|
472
|
+
it("should detect unchanged files on re-index", async () => {
|
|
473
|
+
const testProject = createTempProjectDir({
|
|
474
|
+
"index.js": "const app = require('./app');",
|
|
475
|
+
"package.json": '{"name": "test"}',
|
|
476
|
+
"src/main.ts": "export const main = () => {};",
|
|
477
|
+
});
|
|
478
|
+
tempDirs.push(testProject);
|
|
479
|
+
|
|
480
|
+
// First indexing
|
|
481
|
+
const result1 = await runIndexCommand([], testProject);
|
|
482
|
+
expect(result1.exitCode).toBe(0);
|
|
483
|
+
|
|
484
|
+
// Second indexing (should show unchanged files)
|
|
485
|
+
const result2 = await runIndexCommand([], testProject);
|
|
486
|
+
expect(result2.exitCode).toBe(0);
|
|
487
|
+
expect(result2.stdout).toContain("Unchanged:");
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
it("should index new files on re-index", async () => {
|
|
491
|
+
const testProject = createTempProjectDir({
|
|
492
|
+
"index.js": "const app = require('./app');",
|
|
493
|
+
"package.json": '{"name": "test"}',
|
|
494
|
+
});
|
|
495
|
+
tempDirs.push(testProject);
|
|
496
|
+
|
|
497
|
+
// First indexing
|
|
498
|
+
await runIndexCommand([], testProject);
|
|
499
|
+
|
|
500
|
+
// Add a new file
|
|
501
|
+
fs.mkdirSync(path.join(testProject, "src"), { recursive: true });
|
|
502
|
+
fs.writeFileSync(
|
|
503
|
+
path.join(testProject, "src", "newfile.ts"),
|
|
504
|
+
"export const newFile = () => {};"
|
|
505
|
+
);
|
|
506
|
+
|
|
507
|
+
// Second indexing
|
|
508
|
+
const result2 = await runIndexCommand([], testProject);
|
|
509
|
+
expect(result2.exitCode).toBe(0);
|
|
510
|
+
expect(result2.stdout).toContain("New:");
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
it("should update index-state.json after indexing", async () => {
|
|
514
|
+
const testProject = createTempProjectDir({
|
|
515
|
+
"index.js": "const app = require('./app');",
|
|
516
|
+
"package.json": '{"name": "test"}',
|
|
517
|
+
});
|
|
518
|
+
tempDirs.push(testProject);
|
|
519
|
+
|
|
520
|
+
await runIndexCommand([], testProject);
|
|
521
|
+
|
|
522
|
+
const statePath = path.join(testProject, "ai-context", "index-state.json");
|
|
523
|
+
const content = fs.readFileSync(statePath, "utf-8");
|
|
524
|
+
const state = JSON.parse(content);
|
|
525
|
+
|
|
526
|
+
expect(state.lastIndexed).toBeDefined();
|
|
527
|
+
expect(state.files).toBeDefined();
|
|
528
|
+
});
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
// =========================================================================
|
|
532
|
+
// MULTI-LANGUAGE PROJECT TESTS
|
|
533
|
+
// =========================================================================
|
|
534
|
+
|
|
535
|
+
describe("Multi-Language Projects", () => {
|
|
536
|
+
it("should index TypeScript project", async () => {
|
|
537
|
+
const tsProject = createTempProjectDir({
|
|
538
|
+
"package.json": '{"name": "ts-project"}',
|
|
539
|
+
"tsconfig.json": '{"compilerOptions": {}}',
|
|
540
|
+
"src/index.ts": "export const main = (): void => {};",
|
|
541
|
+
"src/app.ts": "export class App {}",
|
|
542
|
+
});
|
|
543
|
+
tempDirs.push(tsProject);
|
|
544
|
+
|
|
545
|
+
const result = await runIndexCommand([], tsProject);
|
|
546
|
+
|
|
547
|
+
expect(result.exitCode).toBe(0);
|
|
548
|
+
|
|
549
|
+
const dbPath = path.join(tsProject, "ai-context", "index.db");
|
|
550
|
+
expect(fs.existsSync(dbPath)).toBe(true);
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
it("should index Python project", async () => {
|
|
554
|
+
const pyProject = createTempProjectDir({
|
|
555
|
+
"main.py": "def main(): pass",
|
|
556
|
+
"requirements.txt": "flask==2.0.0",
|
|
557
|
+
"src/utils.py": "def helper(): pass",
|
|
558
|
+
});
|
|
559
|
+
tempDirs.push(pyProject);
|
|
560
|
+
|
|
561
|
+
const result = await runIndexCommand([], pyProject);
|
|
562
|
+
|
|
563
|
+
expect(result.exitCode).toBe(0);
|
|
564
|
+
|
|
565
|
+
const dbPath = path.join(pyProject, "ai-context", "index.db");
|
|
566
|
+
expect(fs.existsSync(dbPath)).toBe(true);
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
it("should index Go project", async () => {
|
|
570
|
+
const goProject = createTempProjectDir({
|
|
571
|
+
"main.go": "package main\nfunc main() {}",
|
|
572
|
+
"go.mod": "module example.com/test",
|
|
573
|
+
"src/utils.go": "package main\nfunc helper() {}",
|
|
574
|
+
});
|
|
575
|
+
tempDirs.push(goProject);
|
|
576
|
+
|
|
577
|
+
const result = await runIndexCommand([], goProject);
|
|
578
|
+
|
|
579
|
+
expect(result.exitCode).toBe(0);
|
|
580
|
+
|
|
581
|
+
const dbPath = path.join(goProject, "ai-context", "index.db");
|
|
582
|
+
expect(fs.existsSync(dbPath)).toBe(true);
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
it("should index Rust project", async () => {
|
|
586
|
+
const rustProject = createTempProjectDir({
|
|
587
|
+
"main.rs": "fn main() {}",
|
|
588
|
+
"Cargo.toml": "[package]\nname = \"test\"\nversion = \"0.1.0\"",
|
|
589
|
+
"src/lib.rs": "pub fn helper() {}",
|
|
590
|
+
});
|
|
591
|
+
tempDirs.push(rustProject);
|
|
592
|
+
|
|
593
|
+
const result = await runIndexCommand([], rustProject);
|
|
594
|
+
|
|
595
|
+
expect(result.exitCode).toBe(0);
|
|
596
|
+
|
|
597
|
+
const dbPath = path.join(rustProject, "ai-context", "index.db");
|
|
598
|
+
expect(fs.existsSync(dbPath)).toBe(true);
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
it("should index Java project", async () => {
|
|
602
|
+
const javaProject = createTempProjectDir({
|
|
603
|
+
"Main.java": "public class Main { public static void main(String[] args) {} }",
|
|
604
|
+
"pom.xml": "<?xml version=\"1.0\"?><project></project>",
|
|
605
|
+
"src/App.java": "public class App {}",
|
|
606
|
+
});
|
|
607
|
+
tempDirs.push(javaProject);
|
|
608
|
+
|
|
609
|
+
const result = await runIndexCommand([], javaProject);
|
|
610
|
+
|
|
611
|
+
expect(result.exitCode).toBe(0);
|
|
612
|
+
|
|
613
|
+
const dbPath = path.join(javaProject, "ai-context", "index.db");
|
|
614
|
+
expect(fs.existsSync(dbPath)).toBe(true);
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
it("should index mixed language project", async () => {
|
|
618
|
+
const mixedProject = createTempProjectDir({
|
|
619
|
+
"package.json": '{"name": "mixed"}',
|
|
620
|
+
"index.js": "const express = require('express');",
|
|
621
|
+
"src/main.ts": "export const app = {};",
|
|
622
|
+
"src/utils.py": "def helper(): pass",
|
|
623
|
+
"src/data.java": "public class Data {}",
|
|
624
|
+
});
|
|
625
|
+
tempDirs.push(mixedProject);
|
|
626
|
+
|
|
627
|
+
const result = await runIndexCommand([], mixedProject);
|
|
628
|
+
|
|
629
|
+
expect(result.exitCode).toBe(0);
|
|
630
|
+
|
|
631
|
+
const dbPath = path.join(mixedProject, "ai-context", "index.db");
|
|
632
|
+
expect(fs.existsSync(dbPath)).toBe(true);
|
|
633
|
+
});
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
// =========================================================================
|
|
637
|
+
// ERROR HANDLING TESTS
|
|
638
|
+
// =========================================================================
|
|
639
|
+
|
|
640
|
+
describe("Error Handling", () => {
|
|
641
|
+
it("should handle empty project directory", async () => {
|
|
642
|
+
const emptyProject = fs.mkdtempSync(path.join(os.tmpdir(), "empty-index-project-"));
|
|
643
|
+
tempDirs.push(emptyProject);
|
|
644
|
+
|
|
645
|
+
// Create only ai-context dir but no source files
|
|
646
|
+
fs.mkdirSync(path.join(emptyProject, "ai-context"), { recursive: true });
|
|
647
|
+
|
|
648
|
+
const result = await runIndexCommand([], emptyProject);
|
|
649
|
+
|
|
650
|
+
// Should complete (may exit with 0 or handle gracefully)
|
|
651
|
+
expect(result).toBeDefined();
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
it("should handle project with only hidden files", async () => {
|
|
655
|
+
const hiddenFilesProject = createTempProjectDir({
|
|
656
|
+
".gitignore": "node_modules",
|
|
657
|
+
".env": "SECRET=123",
|
|
658
|
+
".npmrc": "registry=https://registry.npmjs.org/",
|
|
659
|
+
});
|
|
660
|
+
tempDirs.push(hiddenFilesProject);
|
|
661
|
+
|
|
662
|
+
const result = await runIndexCommand([], hiddenFilesProject);
|
|
663
|
+
|
|
664
|
+
// Should complete without crashing
|
|
665
|
+
expect(result).toBeDefined();
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
it("should handle non-existent root directory gracefully", async () => {
|
|
669
|
+
const nonExistentPath = path.join(os.tmpdir(), "non-existent-dir-12345");
|
|
670
|
+
|
|
671
|
+
const result = await runIndexCommand(["--root", nonExistentPath]);
|
|
672
|
+
|
|
673
|
+
// Should either fail gracefully or handle the error
|
|
674
|
+
expect(result).toBeDefined();
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
it("should handle permission errors gracefully", async () => {
|
|
678
|
+
const testProject = createTempProjectDir({
|
|
679
|
+
"index.js": "const app = require('./app');",
|
|
680
|
+
"package.json": '{"name": "test"}',
|
|
681
|
+
});
|
|
682
|
+
tempDirs.push(testProject);
|
|
683
|
+
|
|
684
|
+
// Make the parent directory read-only
|
|
685
|
+
try {
|
|
686
|
+
fs.chmodSync(testProject, 0o555);
|
|
687
|
+
} catch {
|
|
688
|
+
// Skip if we can't change permissions
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
try {
|
|
693
|
+
const result = await runIndexCommand([], testProject);
|
|
694
|
+
// Should either succeed or fail gracefully
|
|
695
|
+
expect(result).toBeDefined();
|
|
696
|
+
} finally {
|
|
697
|
+
// Restore permissions so cleanup can work
|
|
698
|
+
try {
|
|
699
|
+
fs.chmodSync(testProject, 0o755);
|
|
700
|
+
} catch {
|
|
701
|
+
// Ignore
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
});
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
// =========================================================================
|
|
708
|
+
// EDGE CASES
|
|
709
|
+
// =========================================================================
|
|
710
|
+
|
|
711
|
+
describe("Edge Cases", () => {
|
|
712
|
+
it("should handle project with special characters in file names", async () => {
|
|
713
|
+
const specialProject = createTempProjectDir({
|
|
714
|
+
"index.js": "const app = require('./app');",
|
|
715
|
+
"package.json": '{"name": "test"}',
|
|
716
|
+
"src/file-with-dashes.js": "const x = 1;",
|
|
717
|
+
"src/file_with_underscores.js": "const y = 2;",
|
|
718
|
+
});
|
|
719
|
+
tempDirs.push(specialProject);
|
|
720
|
+
|
|
721
|
+
const result = await runIndexCommand([], specialProject);
|
|
722
|
+
|
|
723
|
+
expect(result.exitCode).toBe(0);
|
|
724
|
+
});
|
|
725
|
+
|
|
726
|
+
it("should handle project with symlinks", async () => {
|
|
727
|
+
const symlinkProject = createTempProjectDir({
|
|
728
|
+
"index.js": "const app = require('./app');",
|
|
729
|
+
"package.json": '{"name": "symlink-test"}',
|
|
730
|
+
});
|
|
731
|
+
tempDirs.push(symlinkProject);
|
|
732
|
+
|
|
733
|
+
// Create a symlink to a directory
|
|
734
|
+
const targetDir = path.join(symlinkProject, "target-dir");
|
|
735
|
+
fs.mkdirSync(targetDir);
|
|
736
|
+
fs.writeFileSync(path.join(targetDir, "target.js"), "const y = 1;");
|
|
737
|
+
|
|
738
|
+
const symlinkDir = path.join(symlinkProject, "linked-dir");
|
|
739
|
+
fs.symlinkSync(targetDir, symlinkDir);
|
|
740
|
+
|
|
741
|
+
const result = await runIndexCommand([], symlinkProject);
|
|
742
|
+
|
|
743
|
+
// Should complete without crashing
|
|
744
|
+
expect(result).toBeDefined();
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
it("should handle deeply nested project structure", async () => {
|
|
748
|
+
const deepDir = path.join(
|
|
749
|
+
os.tmpdir(),
|
|
750
|
+
"cli-index-deep",
|
|
751
|
+
"level1",
|
|
752
|
+
"level2",
|
|
753
|
+
"level3",
|
|
754
|
+
"level4"
|
|
755
|
+
);
|
|
756
|
+
|
|
757
|
+
fs.mkdirSync(deepDir, { recursive: true });
|
|
758
|
+
tempDirs.push(deepDir);
|
|
759
|
+
|
|
760
|
+
fs.writeFileSync(path.join(deepDir, "index.js"), "const x = 1;");
|
|
761
|
+
fs.writeFileSync(
|
|
762
|
+
path.join(deepDir, "package.json"),
|
|
763
|
+
'{"name": "deep"}'
|
|
764
|
+
);
|
|
765
|
+
|
|
766
|
+
const result = await runIndexCommand([], deepDir);
|
|
767
|
+
|
|
768
|
+
expect(result).toBeDefined();
|
|
769
|
+
// Should complete without crashing
|
|
770
|
+
});
|
|
771
|
+
|
|
772
|
+
it("should handle project with many small files", async () => {
|
|
773
|
+
const manyFilesProject = fs.mkdtempSync(path.join(os.tmpdir(), "many-files-"));
|
|
774
|
+
tempDirs.push(manyFilesProject);
|
|
775
|
+
|
|
776
|
+
fs.writeFileSync(path.join(manyFilesProject, "package.json"), '{"name": "many"}');
|
|
777
|
+
|
|
778
|
+
// Create 100 small files
|
|
779
|
+
for (let i = 0; i < 100; i++) {
|
|
780
|
+
fs.writeFileSync(
|
|
781
|
+
path.join(manyFilesProject, `file${i}.js`),
|
|
782
|
+
`const x${i} = ${i};`
|
|
783
|
+
);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
const result = await runIndexCommand([], manyFilesProject);
|
|
787
|
+
|
|
788
|
+
expect(result.exitCode).toBe(0);
|
|
789
|
+
|
|
790
|
+
const dbPath = path.join(manyFilesProject, "ai-context", "index.db");
|
|
791
|
+
expect(fs.existsSync(dbPath)).toBe(true);
|
|
792
|
+
});
|
|
793
|
+
});
|
|
794
|
+
|
|
795
|
+
// =========================================================================
|
|
796
|
+
// SQLITE DATABASE VALIDATION TESTS
|
|
797
|
+
// =========================================================================
|
|
798
|
+
|
|
799
|
+
describe("SQLite Database Validation", () => {
|
|
800
|
+
it("should create database with files table", async () => {
|
|
801
|
+
const testProject = createTempProjectDir({
|
|
802
|
+
"index.js": "const app = require('./app');",
|
|
803
|
+
"package.json": '{"name": "test"}',
|
|
804
|
+
"src/main.ts": "export const main = () => {};",
|
|
805
|
+
});
|
|
806
|
+
tempDirs.push(testProject);
|
|
807
|
+
|
|
808
|
+
await runIndexCommand([], testProject);
|
|
809
|
+
|
|
810
|
+
const dbPath = path.join(testProject, "ai-context", "index.db");
|
|
811
|
+
expect(fs.existsSync(dbPath)).toBe(true);
|
|
812
|
+
|
|
813
|
+
// Database file should be valid SQLite format (starts with SQLite header)
|
|
814
|
+
const buffer = fs.readFileSync(dbPath);
|
|
815
|
+
expect(buffer.slice(0, 16).toString()).toContain("SQLite");
|
|
816
|
+
});
|
|
817
|
+
|
|
818
|
+
it("should create database with symbols data", async () => {
|
|
819
|
+
const testProject = createTempProjectDir({
|
|
820
|
+
"index.js": "const app = require('./app');",
|
|
821
|
+
"package.json": '{"name": "test"}',
|
|
822
|
+
"src/main.ts": "export class MyClass {}; export const myFunc = () => {};",
|
|
823
|
+
});
|
|
824
|
+
tempDirs.push(testProject);
|
|
825
|
+
|
|
826
|
+
await runIndexCommand([], testProject);
|
|
827
|
+
|
|
828
|
+
const dbPath = path.join(testProject, "ai-context", "index.db");
|
|
829
|
+
const stats = fs.statSync(dbPath);
|
|
830
|
+
|
|
831
|
+
// Database should have some content
|
|
832
|
+
expect(stats.size).toBeGreaterThan(1024);
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
it("should create database with proper file structure", async () => {
|
|
836
|
+
const testProject = createTempProjectDir({
|
|
837
|
+
"package.json": '{"name": "db-test"}',
|
|
838
|
+
"src/index.ts": "export const index = 1;",
|
|
839
|
+
"src/api/routes.ts": "export const routes = [];",
|
|
840
|
+
});
|
|
841
|
+
tempDirs.push(testProject);
|
|
842
|
+
|
|
843
|
+
await runIndexCommand([], testProject);
|
|
844
|
+
|
|
845
|
+
const dbPath = path.join(testProject, "ai-context", "index.db");
|
|
846
|
+
const aiContextFiles = path.join(testProject, "ai-context");
|
|
847
|
+
|
|
848
|
+
// Check all expected files exist
|
|
849
|
+
expect(fs.existsSync(path.join(aiContextFiles, "index.db"))).toBe(true);
|
|
850
|
+
expect(fs.existsSync(path.join(aiContextFiles, "files.json"))).toBe(true);
|
|
851
|
+
expect(fs.existsSync(path.join(aiContextFiles, "modules.json"))).toBe(true);
|
|
852
|
+
expect(fs.existsSync(path.join(aiContextFiles, "index-state.json"))).toBe(true);
|
|
853
|
+
});
|
|
854
|
+
});
|
|
855
|
+
|
|
856
|
+
// =========================================================================
|
|
857
|
+
// HELP OUTPUT TESTS
|
|
858
|
+
// =========================================================================
|
|
859
|
+
|
|
860
|
+
describe("Help Output", () => {
|
|
861
|
+
it("should show help message with --help flag", async () => {
|
|
862
|
+
const testProject = createTempProjectDir({
|
|
863
|
+
"index.js": "const app = require('./app');",
|
|
864
|
+
"package.json": '{"name": "test"}',
|
|
865
|
+
});
|
|
866
|
+
tempDirs.push(testProject);
|
|
867
|
+
|
|
868
|
+
const result = await runIndexCommand(["--help"], testProject);
|
|
869
|
+
|
|
870
|
+
// Help should exit with 0 and show usage info
|
|
871
|
+
expect(result.exitCode).toBe(0);
|
|
872
|
+
expect(result.stdout).toContain("ai-first index");
|
|
873
|
+
expect(result.stdout).toContain("--root");
|
|
874
|
+
expect(result.stdout).toContain("--semantic");
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
it("should show adaptive thresholds in help", async () => {
|
|
878
|
+
const testProject = createTempProjectDir({
|
|
879
|
+
"index.js": "const app = require('./app');",
|
|
880
|
+
"package.json": '{"name": "test"}',
|
|
881
|
+
});
|
|
882
|
+
tempDirs.push(testProject);
|
|
883
|
+
|
|
884
|
+
const result = await runIndexCommand(["--help"], testProject);
|
|
885
|
+
|
|
886
|
+
expect(result.stdout).toContain("Adaptive thresholds");
|
|
887
|
+
expect(result.stdout).toContain("200 files");
|
|
888
|
+
expect(result.stdout).toContain("2000");
|
|
889
|
+
});
|
|
890
|
+
|
|
891
|
+
it("should show example queries in help", async () => {
|
|
892
|
+
const testProject = createTempProjectDir({
|
|
893
|
+
"index.js": "const app = require('./app');",
|
|
894
|
+
"package.json": '{"name": "test"}',
|
|
895
|
+
});
|
|
896
|
+
tempDirs.push(testProject);
|
|
897
|
+
|
|
898
|
+
const result = await runIndexCommand(["--help"], testProject);
|
|
899
|
+
|
|
900
|
+
expect(result.stdout).toContain("Example queries");
|
|
901
|
+
expect(result.stdout).toContain("SELECT");
|
|
902
|
+
});
|
|
903
|
+
});
|
|
904
|
+
|
|
905
|
+
// =========================================================================
|
|
906
|
+
// VERIFICATION CHECKLIST TESTS
|
|
907
|
+
// =========================================================================
|
|
908
|
+
|
|
909
|
+
describe("Verification Checklist", () => {
|
|
910
|
+
it("should verify index command with default options works", async () => {
|
|
911
|
+
const testProject = createTempProjectDir({
|
|
912
|
+
"index.js": "const app = require('./app');",
|
|
913
|
+
"package.json": '{"name": "test"}',
|
|
914
|
+
"src/main.ts": "export const main = () => {};",
|
|
915
|
+
});
|
|
916
|
+
tempDirs.push(testProject);
|
|
917
|
+
|
|
918
|
+
const result = await runIndexCommand([], testProject);
|
|
919
|
+
|
|
920
|
+
expect(result.exitCode).toBe(0);
|
|
921
|
+
expect(result.stdout).toContain("Generating index");
|
|
922
|
+
expect(result.stdout).toContain("Index created");
|
|
923
|
+
});
|
|
924
|
+
|
|
925
|
+
it("should verify --semantic flag functionality", async () => {
|
|
926
|
+
const testProject = createTempProjectDir({
|
|
927
|
+
"index.js": "const app = require('./app');",
|
|
928
|
+
"package.json": '{"name": "test"}',
|
|
929
|
+
"src/main.ts": "export const main = () => {};",
|
|
930
|
+
});
|
|
931
|
+
tempDirs.push(testProject);
|
|
932
|
+
|
|
933
|
+
const result = await runIndexCommand(["--semantic"], testProject);
|
|
934
|
+
|
|
935
|
+
expect(result.exitCode).toBe(0);
|
|
936
|
+
expect(result.stdout).toContain("Semantic mode enabled");
|
|
937
|
+
});
|
|
938
|
+
|
|
939
|
+
it("should verify SQLite database creation", async () => {
|
|
940
|
+
const testProject = createTempProjectDir({
|
|
941
|
+
"index.js": "const app = require('./app');",
|
|
942
|
+
"package.json": '{"name": "test"}',
|
|
943
|
+
});
|
|
944
|
+
tempDirs.push(testProject);
|
|
945
|
+
|
|
946
|
+
await runIndexCommand([], testProject);
|
|
947
|
+
|
|
948
|
+
const dbPath = path.join(testProject, "ai-context", "index.db");
|
|
949
|
+
expect(fs.existsSync(dbPath)).toBe(true);
|
|
950
|
+
|
|
951
|
+
const stats = fs.statSync(dbPath);
|
|
952
|
+
expect(stats.size).toBeGreaterThan(0);
|
|
953
|
+
});
|
|
954
|
+
|
|
955
|
+
it("should verify embeddings generation with --semantic", async () => {
|
|
956
|
+
const testProject = createTempProjectDir({
|
|
957
|
+
"index.js": "const app = require('./app');",
|
|
958
|
+
"package.json": '{"name": "test"}',
|
|
959
|
+
"src/main.ts": "export const main = (): void => {};",
|
|
960
|
+
"src/utils.ts": "export const helper = (): number => 42;",
|
|
961
|
+
});
|
|
962
|
+
tempDirs.push(testProject);
|
|
963
|
+
|
|
964
|
+
const result = await runIndexCommand(["--semantic"], testProject);
|
|
965
|
+
|
|
966
|
+
expect(result.exitCode).toBe(0);
|
|
967
|
+
expect(result.stdout).toContain("Semantic mode enabled");
|
|
968
|
+
// Should attempt embeddings generation
|
|
969
|
+
expect(result.stdout).toMatch(/Processing \d+ code files|Creating \d+ chunks|semantic indexing complete/i);
|
|
970
|
+
});
|
|
971
|
+
|
|
972
|
+
it("should verify adaptive processing for different project sizes", async () => {
|
|
973
|
+
const smallProject = createTempProjectDir({
|
|
974
|
+
"index.js": "const app = require('./app');",
|
|
975
|
+
"package.json": '{"name": "small"}',
|
|
976
|
+
});
|
|
977
|
+
tempDirs.push(smallProject);
|
|
978
|
+
|
|
979
|
+
const smallResult = await runIndexCommand([], smallProject);
|
|
980
|
+
expect(smallResult.exitCode).toBe(0);
|
|
981
|
+
|
|
982
|
+
// Medium project
|
|
983
|
+
const mediumProject = createLargeProjectDir(50, 10);
|
|
984
|
+
tempDirs.push(mediumProject);
|
|
985
|
+
|
|
986
|
+
const mediumResult = await runIndexCommand([], mediumProject);
|
|
987
|
+
expect(mediumResult.exitCode).toBe(0);
|
|
988
|
+
});
|
|
989
|
+
|
|
990
|
+
it("should verify incremental indexing works", async () => {
|
|
991
|
+
const testProject = createTempProjectDir({
|
|
992
|
+
"index.js": "const app = require('./app');",
|
|
993
|
+
"package.json": '{"name": "test"}',
|
|
994
|
+
});
|
|
995
|
+
tempDirs.push(testProject);
|
|
996
|
+
|
|
997
|
+
// First run
|
|
998
|
+
const result1 = await runIndexCommand([], testProject);
|
|
999
|
+
expect(result1.exitCode).toBe(0);
|
|
1000
|
+
|
|
1001
|
+
// Second run should show unchanged
|
|
1002
|
+
const result2 = await runIndexCommand([], testProject);
|
|
1003
|
+
expect(result2.exitCode).toBe(0);
|
|
1004
|
+
expect(result2.stdout).toContain("Unchanged:");
|
|
1005
|
+
});
|
|
1006
|
+
});
|
|
1007
|
+
});
|