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,761 @@
|
|
|
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 { exec, spawn } from "child_process";
|
|
6
|
+
import { promisify } from "util";
|
|
7
|
+
|
|
8
|
+
const execAsync = promisify(exec);
|
|
9
|
+
|
|
10
|
+
const PROJECT_ROOT = process.cwd();
|
|
11
|
+
const CLI_PATH = path.join(PROJECT_ROOT, "dist/commands/ai-first.js");
|
|
12
|
+
const EXPRESS_API_PATH = path.join(PROJECT_ROOT, "test-projects/express-api");
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Creates a temporary project directory with some source files
|
|
16
|
+
*/
|
|
17
|
+
function createTempProjectDir(files: Record<string, string>): string {
|
|
18
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "cli-init-test-"));
|
|
19
|
+
for (const [filePath, content] of Object.entries(files)) {
|
|
20
|
+
const fullPath = path.join(tempDir, filePath);
|
|
21
|
+
const dir = path.dirname(fullPath);
|
|
22
|
+
if (!fs.existsSync(dir)) {
|
|
23
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
fs.writeFileSync(fullPath, content);
|
|
26
|
+
}
|
|
27
|
+
return tempDir;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Run the CLI init command
|
|
32
|
+
*/
|
|
33
|
+
async function runInitCommand(
|
|
34
|
+
args: string[],
|
|
35
|
+
cwd: string = process.cwd()
|
|
36
|
+
): Promise<{ stdout: string; stderr: string; exitCode: number }> {
|
|
37
|
+
return new Promise((resolve) => {
|
|
38
|
+
const cliArgs = ["node", CLI_PATH, "init", ...args];
|
|
39
|
+
const child = spawn("node", [CLI_PATH, "init", ...args], {
|
|
40
|
+
cwd,
|
|
41
|
+
stdio: "pipe",
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
let stdout = "";
|
|
45
|
+
let stderr = "";
|
|
46
|
+
|
|
47
|
+
child.stdout?.on("data", (data) => {
|
|
48
|
+
stdout += data.toString();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
child.stderr?.on("data", (data) => {
|
|
52
|
+
stderr += data.toString();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
child.on("close", (code) => {
|
|
56
|
+
resolve({
|
|
57
|
+
stdout,
|
|
58
|
+
stderr,
|
|
59
|
+
exitCode: code ?? 0,
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
child.on("error", (err) => {
|
|
64
|
+
stderr += err.message;
|
|
65
|
+
resolve({ stdout, stderr, exitCode: 1 });
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Timeout after 60 seconds
|
|
69
|
+
setTimeout(() => {
|
|
70
|
+
child.kill();
|
|
71
|
+
resolve({ stdout, stderr, exitCode: 124 });
|
|
72
|
+
}, 60000);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
describe("CLI Init Command", () => {
|
|
77
|
+
let tempDir: string;
|
|
78
|
+
const tempDirs: string[] = [];
|
|
79
|
+
|
|
80
|
+
beforeAll(() => {
|
|
81
|
+
// Ensure dist is built
|
|
82
|
+
if (!fs.existsSync(CLI_PATH)) {
|
|
83
|
+
throw new Error(
|
|
84
|
+
`CLI not found at ${CLI_PATH}. Run 'npm run build' first.`
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
beforeEach(() => {
|
|
90
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "cli-init-test-"));
|
|
91
|
+
tempDirs.push(tempDir);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
afterAll(() => {
|
|
95
|
+
// Clean up all temp directories
|
|
96
|
+
for (const dir of tempDirs) {
|
|
97
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// =========================================================================
|
|
102
|
+
// DEFAULT OPTIONS TESTS
|
|
103
|
+
// =========================================================================
|
|
104
|
+
|
|
105
|
+
describe("Default Options", () => {
|
|
106
|
+
it("should run init command successfully on express-api project", async () => {
|
|
107
|
+
const result = await runInitCommand([], EXPRESS_API_PATH);
|
|
108
|
+
|
|
109
|
+
expect(result.exitCode).toBe(0);
|
|
110
|
+
expect(result.stdout).toContain("Created");
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("should create ai-context directory with default options", async () => {
|
|
114
|
+
const aiContextDir = path.join(EXPRESS_API_PATH, "ai-context");
|
|
115
|
+
|
|
116
|
+
// Clean up if exists
|
|
117
|
+
if (fs.existsSync(aiContextDir)) {
|
|
118
|
+
fs.rmSync(aiContextDir, { recursive: true, force: true });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const result = await runInitCommand([], EXPRESS_API_PATH);
|
|
122
|
+
|
|
123
|
+
expect(result.exitCode).toBe(0);
|
|
124
|
+
expect(fs.existsSync(aiContextDir)).toBe(true);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("should create all expected context files", async () => {
|
|
128
|
+
const testProject = createTempProjectDir({
|
|
129
|
+
"index.js": "const app = require('./app');",
|
|
130
|
+
"package.json": '{"name": "test", "version": "1.0.0"}',
|
|
131
|
+
"src/main.ts": "export const main = () => {};",
|
|
132
|
+
});
|
|
133
|
+
tempDirs.push(testProject);
|
|
134
|
+
|
|
135
|
+
const aiContextDir = path.join(testProject, "ai-context");
|
|
136
|
+
|
|
137
|
+
const result = await runInitCommand([], testProject);
|
|
138
|
+
|
|
139
|
+
expect(result.exitCode).toBe(0);
|
|
140
|
+
expect(fs.existsSync(aiContextDir)).toBe(true);
|
|
141
|
+
|
|
142
|
+
// Check for expected files
|
|
143
|
+
const expectedFiles = [
|
|
144
|
+
"ai_context.md",
|
|
145
|
+
"repo_map.md",
|
|
146
|
+
"repo_map.json",
|
|
147
|
+
"summary.md",
|
|
148
|
+
"architecture.md",
|
|
149
|
+
"tech_stack.md",
|
|
150
|
+
"entrypoints.md",
|
|
151
|
+
"conventions.md",
|
|
152
|
+
"symbols.json",
|
|
153
|
+
"dependencies.json",
|
|
154
|
+
];
|
|
155
|
+
|
|
156
|
+
for (const file of expectedFiles) {
|
|
157
|
+
const filePath = path.join(aiContextDir, file);
|
|
158
|
+
expect(fs.existsSync(filePath), `Expected ${file} to exist`).toBe(true);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it("should generate non-empty file content", async () => {
|
|
163
|
+
const testProject = createTempProjectDir({
|
|
164
|
+
"index.js": "const app = require('./app');",
|
|
165
|
+
"package.json": '{"name": "test", "version": "1.0.0"}',
|
|
166
|
+
"src/main.ts": "export const main = () => {};",
|
|
167
|
+
});
|
|
168
|
+
tempDirs.push(testProject);
|
|
169
|
+
|
|
170
|
+
const aiContextDir = path.join(testProject, "ai-context");
|
|
171
|
+
|
|
172
|
+
await runInitCommand([], testProject);
|
|
173
|
+
|
|
174
|
+
// Check that files have content
|
|
175
|
+
const aiContextPath = path.join(aiContextDir, "ai_context.md");
|
|
176
|
+
const symbolsPath = path.join(aiContextDir, "symbols.json");
|
|
177
|
+
|
|
178
|
+
expect(fs.existsSync(aiContextPath)).toBe(true);
|
|
179
|
+
expect(fs.existsSync(symbolsPath)).toBe(true);
|
|
180
|
+
|
|
181
|
+
const aiContextContent = fs.readFileSync(aiContextPath, "utf-8");
|
|
182
|
+
expect(aiContextContent.length).toBeGreaterThan(100);
|
|
183
|
+
|
|
184
|
+
const symbolsContent = fs.readFileSync(symbolsPath, "utf-8");
|
|
185
|
+
const symbols = JSON.parse(symbolsContent);
|
|
186
|
+
expect(symbols).toBeDefined();
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// =========================================================================
|
|
191
|
+
// --root FLAG TESTS
|
|
192
|
+
// =========================================================================
|
|
193
|
+
|
|
194
|
+
describe("--root Flag", () => {
|
|
195
|
+
it("should scan different directory with --root flag", async () => {
|
|
196
|
+
const testProject = createTempProjectDir({
|
|
197
|
+
"README.md": "# Test Project",
|
|
198
|
+
"src/index.ts": "export const test = 1;",
|
|
199
|
+
});
|
|
200
|
+
tempDirs.push(testProject);
|
|
201
|
+
|
|
202
|
+
const result = await runInitCommand(["--root", testProject]);
|
|
203
|
+
|
|
204
|
+
expect(result.exitCode).toBe(0);
|
|
205
|
+
expect(result.stdout).toContain(testProject);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it("should handle --root with short flag -r", async () => {
|
|
209
|
+
const testProject = createTempProjectDir({
|
|
210
|
+
"README.md": "# Test Project",
|
|
211
|
+
"src/index.ts": "export const test = 1;",
|
|
212
|
+
});
|
|
213
|
+
tempDirs.push(testProject);
|
|
214
|
+
|
|
215
|
+
const result = await runInitCommand(["-r", testProject]);
|
|
216
|
+
|
|
217
|
+
expect(result.exitCode).toBe(0);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it("should error on non-existent root directory", async () => {
|
|
221
|
+
const nonExistentPath = path.join(os.tmpdir(), "non-existent-dir-12345");
|
|
222
|
+
|
|
223
|
+
const result = await runInitCommand(["--root", nonExistentPath]);
|
|
224
|
+
|
|
225
|
+
// Should complete but may have issues with the directory
|
|
226
|
+
// The CLI should handle this gracefully
|
|
227
|
+
expect(result).toBeDefined();
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it("should scan nested project structure with --root", async () => {
|
|
231
|
+
const testProject = createTempProjectDir({
|
|
232
|
+
"package.json": '{"name": "nested-test"}',
|
|
233
|
+
"src/api/routes.ts": "export const routes = [];",
|
|
234
|
+
"src/services/user.ts": "export const userService = {};",
|
|
235
|
+
});
|
|
236
|
+
tempDirs.push(testProject);
|
|
237
|
+
|
|
238
|
+
const result = await runInitCommand(["--root", testProject]);
|
|
239
|
+
|
|
240
|
+
expect(result.exitCode).toBe(0);
|
|
241
|
+
expect(result.stdout).toContain("Found 3 files");
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// =========================================================================
|
|
246
|
+
// --output FLAG TESTS
|
|
247
|
+
// =========================================================================
|
|
248
|
+
|
|
249
|
+
describe("--output Flag", () => {
|
|
250
|
+
it("should create custom output directory with --output flag", async () => {
|
|
251
|
+
const testProject = createTempProjectDir({
|
|
252
|
+
"index.js": "const app = require('./app');",
|
|
253
|
+
"package.json": '{"name": "test"}',
|
|
254
|
+
});
|
|
255
|
+
tempDirs.push(testProject);
|
|
256
|
+
|
|
257
|
+
const customOutput = path.join(testProject, "custom-ai-context");
|
|
258
|
+
|
|
259
|
+
const result = await runInitCommand(["--output", customOutput], testProject);
|
|
260
|
+
|
|
261
|
+
expect(result.exitCode).toBe(0);
|
|
262
|
+
expect(fs.existsSync(customOutput)).toBe(true);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
it("should create files in custom output directory", async () => {
|
|
266
|
+
const testProject = createTempProjectDir({
|
|
267
|
+
"index.js": "const app = require('./app');",
|
|
268
|
+
"package.json": '{"name": "test"}',
|
|
269
|
+
});
|
|
270
|
+
tempDirs.push(testProject);
|
|
271
|
+
|
|
272
|
+
const customOutput = path.join(testProject, "my-context");
|
|
273
|
+
|
|
274
|
+
await runInitCommand(["--output", customOutput], testProject);
|
|
275
|
+
|
|
276
|
+
// Check expected files exist in custom output
|
|
277
|
+
expect(fs.existsSync(path.join(customOutput, "ai_context.md"))).toBe(true);
|
|
278
|
+
expect(fs.existsSync(path.join(customOutput, "repo_map.md"))).toBe(true);
|
|
279
|
+
expect(fs.existsSync(path.join(customOutput, "symbols.json"))).toBe(true);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it("should handle --output with short flag -o", async () => {
|
|
283
|
+
const testProject = createTempProjectDir({
|
|
284
|
+
"index.js": "const app = require('./app');",
|
|
285
|
+
"package.json": '{"name": "test"}',
|
|
286
|
+
});
|
|
287
|
+
tempDirs.push(testProject);
|
|
288
|
+
|
|
289
|
+
const customOutput = path.join(testProject, "my-context");
|
|
290
|
+
|
|
291
|
+
const result = await runInitCommand(["-o", customOutput], testProject);
|
|
292
|
+
|
|
293
|
+
expect(result.exitCode).toBe(0);
|
|
294
|
+
expect(fs.existsSync(customOutput)).toBe(true);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it("should work with both --root and --output combined", async () => {
|
|
298
|
+
const sourceProject = createTempProjectDir({
|
|
299
|
+
"src/index.ts": "export const main = () => {};",
|
|
300
|
+
"package.json": '{"name": "source"}',
|
|
301
|
+
});
|
|
302
|
+
const outputProject = createTempProjectDir({});
|
|
303
|
+
tempDirs.push(sourceProject);
|
|
304
|
+
tempDirs.push(outputProject);
|
|
305
|
+
|
|
306
|
+
const customOutput = path.join(outputProject, "ai-output");
|
|
307
|
+
|
|
308
|
+
const result = await runInitCommand(
|
|
309
|
+
["--root", sourceProject, "--output", customOutput],
|
|
310
|
+
sourceProject
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
expect(result.exitCode).toBe(0);
|
|
314
|
+
expect(fs.existsSync(customOutput)).toBe(true);
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
// =========================================================================
|
|
319
|
+
// OVERWRITE BEHAVIOR TESTS
|
|
320
|
+
// =========================================================================
|
|
321
|
+
|
|
322
|
+
describe("Overwrite Behavior", () => {
|
|
323
|
+
it("should overwrite existing ai-context files", async () => {
|
|
324
|
+
const testProject = createTempProjectDir({
|
|
325
|
+
"index.js": "const app = require('./app');",
|
|
326
|
+
"package.json": '{"name": "test"}',
|
|
327
|
+
});
|
|
328
|
+
tempDirs.push(testProject);
|
|
329
|
+
|
|
330
|
+
const aiContextDir = path.join(testProject, "ai-context");
|
|
331
|
+
fs.mkdirSync(aiContextDir, { recursive: true });
|
|
332
|
+
|
|
333
|
+
// Create existing file
|
|
334
|
+
const existingFile = path.join(aiContextDir, "repo_map.md");
|
|
335
|
+
fs.writeFileSync(existingFile, "Old content");
|
|
336
|
+
|
|
337
|
+
// Run init again
|
|
338
|
+
const result = await runInitCommand([], testProject);
|
|
339
|
+
|
|
340
|
+
expect(result.exitCode).toBe(0);
|
|
341
|
+
|
|
342
|
+
// File should be overwritten with new content
|
|
343
|
+
const content = fs.readFileSync(existingFile, "utf-8");
|
|
344
|
+
expect(content).not.toBe("Old content");
|
|
345
|
+
expect(content.length).toBeGreaterThan(0);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
it("should handle existing custom output directory", async () => {
|
|
349
|
+
const testProject = createTempProjectDir({
|
|
350
|
+
"index.js": "const app = require('./app');",
|
|
351
|
+
"package.json": '{"name": "test"}',
|
|
352
|
+
});
|
|
353
|
+
tempDirs.push(testProject);
|
|
354
|
+
|
|
355
|
+
const customOutput = path.join(testProject, "my-context");
|
|
356
|
+
fs.mkdirSync(customOutput, { recursive: true });
|
|
357
|
+
|
|
358
|
+
// Create existing file in custom output
|
|
359
|
+
const existingFile = path.join(customOutput, "existing.txt");
|
|
360
|
+
fs.writeFileSync(existingFile, "Old content");
|
|
361
|
+
|
|
362
|
+
const result = await runInitCommand(["--output", customOutput], testProject);
|
|
363
|
+
|
|
364
|
+
expect(result.exitCode).toBe(0);
|
|
365
|
+
expect(fs.existsSync(existingFile)).toBe(true);
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
// =========================================================================
|
|
370
|
+
// ERROR HANDLING TESTS
|
|
371
|
+
// =========================================================================
|
|
372
|
+
|
|
373
|
+
describe("Error Handling", () => {
|
|
374
|
+
it("should handle permission errors gracefully", async () => {
|
|
375
|
+
// Create a directory without write permissions
|
|
376
|
+
const testProject = createTempProjectDir({
|
|
377
|
+
"index.js": "const app = require('./app');",
|
|
378
|
+
"package.json": '{"name": "test"}',
|
|
379
|
+
});
|
|
380
|
+
tempDirs.push(testProject);
|
|
381
|
+
|
|
382
|
+
// Make the directory read-only (remove write permissions)
|
|
383
|
+
// Note: This might not work on Windows, so we skip if not possible
|
|
384
|
+
try {
|
|
385
|
+
fs.chmodSync(testProject, 0o555);
|
|
386
|
+
} catch {
|
|
387
|
+
// Skip if we can't change permissions
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
try {
|
|
392
|
+
const result = await runInitCommand([], testProject);
|
|
393
|
+
// Should either succeed or fail gracefully
|
|
394
|
+
expect(result).toBeDefined();
|
|
395
|
+
} finally {
|
|
396
|
+
// Restore permissions so cleanup can work
|
|
397
|
+
try {
|
|
398
|
+
fs.chmodSync(testProject, 0o755);
|
|
399
|
+
} catch {
|
|
400
|
+
// Ignore
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
it("should handle invalid output path characters", async () => {
|
|
406
|
+
const testProject = createTempProjectDir({
|
|
407
|
+
"index.js": "const app = require('./app');",
|
|
408
|
+
"package.json": '{"name": "test"}',
|
|
409
|
+
});
|
|
410
|
+
tempDirs.push(testProject);
|
|
411
|
+
|
|
412
|
+
// Use a path that might cause issues
|
|
413
|
+
const invalidOutput = path.join(testProject, "valid-dir");
|
|
414
|
+
fs.mkdirSync(invalidOutput, { recursive: true });
|
|
415
|
+
|
|
416
|
+
const result = await runInitCommand(["--output", invalidOutput], testProject);
|
|
417
|
+
|
|
418
|
+
// Should complete without crashing
|
|
419
|
+
expect(result).toBeDefined();
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
it("should handle empty project directory", async () => {
|
|
423
|
+
const emptyProject = fs.mkdtempSync(path.join(os.tmpdir(), "empty-project-"));
|
|
424
|
+
tempDirs.push(emptyProject);
|
|
425
|
+
|
|
426
|
+
const result = await runInitCommand([], emptyProject);
|
|
427
|
+
|
|
428
|
+
// Should complete even with empty project
|
|
429
|
+
expect(result).toBeDefined();
|
|
430
|
+
// ai-context directory should be created
|
|
431
|
+
expect(fs.existsSync(path.join(emptyProject, "ai-context"))).toBe(true);
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
it("should handle project with only hidden files", async () => {
|
|
435
|
+
const hiddenFilesProject = createTempProjectDir({
|
|
436
|
+
".gitignore": "node_modules",
|
|
437
|
+
".env": "SECRET=123",
|
|
438
|
+
".npmrc": "registry=https://registry.npmjs.org/",
|
|
439
|
+
});
|
|
440
|
+
tempDirs.push(hiddenFilesProject);
|
|
441
|
+
|
|
442
|
+
const result = await runInitCommand([], hiddenFilesProject);
|
|
443
|
+
|
|
444
|
+
// Should complete
|
|
445
|
+
expect(result).toBeDefined();
|
|
446
|
+
});
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
// =========================================================================
|
|
450
|
+
// CONTENT VALIDATION TESTS
|
|
451
|
+
// =========================================================================
|
|
452
|
+
|
|
453
|
+
describe("Content Validation", () => {
|
|
454
|
+
it("should generate valid JSON in symbols.json", async () => {
|
|
455
|
+
const testProject = createTempProjectDir({
|
|
456
|
+
"index.js": "const app = require('./app');",
|
|
457
|
+
"package.json": '{"name": "test"}',
|
|
458
|
+
"src/main.ts": "export const main = () => {};",
|
|
459
|
+
});
|
|
460
|
+
tempDirs.push(testProject);
|
|
461
|
+
|
|
462
|
+
await runInitCommand([], testProject);
|
|
463
|
+
|
|
464
|
+
const symbolsPath = path.join(testProject, "ai-context", "symbols.json");
|
|
465
|
+
expect(fs.existsSync(symbolsPath)).toBe(true);
|
|
466
|
+
|
|
467
|
+
const content = fs.readFileSync(symbolsPath, "utf-8");
|
|
468
|
+
expect(() => JSON.parse(content)).not.toThrow();
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
it("should generate valid JSON in dependencies.json", async () => {
|
|
472
|
+
const testProject = createTempProjectDir({
|
|
473
|
+
"index.js": "const app = require('./app');",
|
|
474
|
+
"package.json": '{"name": "test"}',
|
|
475
|
+
});
|
|
476
|
+
tempDirs.push(testProject);
|
|
477
|
+
|
|
478
|
+
await runInitCommand([], testProject);
|
|
479
|
+
|
|
480
|
+
const depsPath = path.join(testProject, "ai-context", "dependencies.json");
|
|
481
|
+
expect(fs.existsSync(depsPath)).toBe(true);
|
|
482
|
+
|
|
483
|
+
const content = fs.readFileSync(depsPath, "utf-8");
|
|
484
|
+
expect(() => JSON.parse(content)).not.toThrow();
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
it("should generate valid JSON in repo_map.json", async () => {
|
|
488
|
+
const testProject = createTempProjectDir({
|
|
489
|
+
"index.js": "const app = require('./app');",
|
|
490
|
+
"package.json": '{"name": "test"}',
|
|
491
|
+
});
|
|
492
|
+
tempDirs.push(testProject);
|
|
493
|
+
|
|
494
|
+
await runInitCommand([], testProject);
|
|
495
|
+
|
|
496
|
+
const repoMapPath = path.join(testProject, "ai-context", "repo_map.json");
|
|
497
|
+
expect(fs.existsSync(repoMapPath)).toBe(true);
|
|
498
|
+
|
|
499
|
+
const content = fs.readFileSync(repoMapPath, "utf-8");
|
|
500
|
+
expect(() => JSON.parse(content)).not.toThrow();
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
it("should generate markdown files with content", async () => {
|
|
504
|
+
const testProject = createTempProjectDir({
|
|
505
|
+
"index.js": "const app = require('./app');",
|
|
506
|
+
"package.json": '{"name": "test"}',
|
|
507
|
+
});
|
|
508
|
+
tempDirs.push(testProject);
|
|
509
|
+
|
|
510
|
+
await runInitCommand([], testProject);
|
|
511
|
+
|
|
512
|
+
const markdownFiles = ["summary.md", "architecture.md", "tech_stack.md"];
|
|
513
|
+
|
|
514
|
+
for (const file of markdownFiles) {
|
|
515
|
+
const filePath = path.join(testProject, "ai-context", file);
|
|
516
|
+
expect(fs.existsSync(filePath), `Expected ${file} to exist`).toBe(true);
|
|
517
|
+
|
|
518
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
519
|
+
expect(content.length).toBeGreaterThan(10);
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
it("should include project name in ai_context.md", async () => {
|
|
524
|
+
const testProject = createTempProjectDir({
|
|
525
|
+
"index.js": "const app = require('./app');",
|
|
526
|
+
"package.json": '{"name": "my-test-project", "version": "1.0.0"}',
|
|
527
|
+
});
|
|
528
|
+
tempDirs.push(testProject);
|
|
529
|
+
|
|
530
|
+
await runInitCommand([], testProject);
|
|
531
|
+
|
|
532
|
+
const aiContextPath = path.join(testProject, "ai-context", "ai_context.md");
|
|
533
|
+
const content = fs.readFileSync(aiContextPath, "utf-8");
|
|
534
|
+
|
|
535
|
+
// Should mention AI context or repository
|
|
536
|
+
expect(
|
|
537
|
+
content.toLowerCase().includes("ai context") ||
|
|
538
|
+
content.toLowerCase().includes("repository") ||
|
|
539
|
+
content.toLowerCase().includes("project")
|
|
540
|
+
).toBe(true);
|
|
541
|
+
});
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
// =========================================================================
|
|
545
|
+
// MULTI-LANGUAGE PROJECT TESTS
|
|
546
|
+
// =========================================================================
|
|
547
|
+
|
|
548
|
+
describe("Multi-Language Projects", () => {
|
|
549
|
+
it("should handle TypeScript project", async () => {
|
|
550
|
+
const tsProject = createTempProjectDir({
|
|
551
|
+
"package.json": '{"name": "ts-project"}',
|
|
552
|
+
"tsconfig.json": '{"compilerOptions": {}}',
|
|
553
|
+
"src/index.ts": "export const main = (): void => {};",
|
|
554
|
+
"src/app.ts": "export class App {}",
|
|
555
|
+
});
|
|
556
|
+
tempDirs.push(tsProject);
|
|
557
|
+
|
|
558
|
+
const result = await runInitCommand([], tsProject);
|
|
559
|
+
|
|
560
|
+
expect(result.exitCode).toBe(0);
|
|
561
|
+
|
|
562
|
+
const symbolsPath = path.join(tsProject, "ai-context", "symbols.json");
|
|
563
|
+
expect(fs.existsSync(symbolsPath)).toBe(true);
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
it("should handle Python project", async () => {
|
|
567
|
+
const pyProject = createTempProjectDir({
|
|
568
|
+
"main.py": "def main(): pass",
|
|
569
|
+
"requirements.txt": "flask==2.0.0",
|
|
570
|
+
});
|
|
571
|
+
tempDirs.push(pyProject);
|
|
572
|
+
|
|
573
|
+
const result = await runInitCommand([], pyProject);
|
|
574
|
+
|
|
575
|
+
expect(result.exitCode).toBe(0);
|
|
576
|
+
|
|
577
|
+
const techStackPath = path.join(pyProject, "ai-context", "tech_stack.md");
|
|
578
|
+
expect(fs.existsSync(techStackPath)).toBe(true);
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
it("should handle mixed language project", async () => {
|
|
582
|
+
const mixedProject = createTempProjectDir({
|
|
583
|
+
"package.json": '{"name": "mixed"}',
|
|
584
|
+
"index.js": "const express = require('express');",
|
|
585
|
+
"src/main.ts": "export const app = {};",
|
|
586
|
+
"src/utils.py": "def helper(): pass",
|
|
587
|
+
"src/data.java": "public class Data {}",
|
|
588
|
+
});
|
|
589
|
+
tempDirs.push(mixedProject);
|
|
590
|
+
|
|
591
|
+
const result = await runInitCommand([], mixedProject);
|
|
592
|
+
|
|
593
|
+
expect(result.exitCode).toBe(0);
|
|
594
|
+
|
|
595
|
+
const techStackPath = path.join(mixedProject, "ai-context", "tech_stack.md");
|
|
596
|
+
const content = fs.readFileSync(techStackPath, "utf-8");
|
|
597
|
+
|
|
598
|
+
// Should detect multiple languages
|
|
599
|
+
expect(content).toBeDefined();
|
|
600
|
+
});
|
|
601
|
+
});
|
|
602
|
+
|
|
603
|
+
// =========================================================================
|
|
604
|
+
// EDGE CASES
|
|
605
|
+
// =========================================================================
|
|
606
|
+
|
|
607
|
+
describe("Edge Cases", () => {
|
|
608
|
+
it("should handle project with very long paths", async () => {
|
|
609
|
+
const deepDir = path.join(
|
|
610
|
+
os.tmpdir(),
|
|
611
|
+
"very-long-directory-name-test",
|
|
612
|
+
"another-long-directory-name",
|
|
613
|
+
"yet-another-long-name",
|
|
614
|
+
"final-long-directory-name"
|
|
615
|
+
);
|
|
616
|
+
|
|
617
|
+
fs.mkdirSync(deepDir, { recursive: true });
|
|
618
|
+
tempDirs.push(deepDir);
|
|
619
|
+
|
|
620
|
+
fs.writeFileSync(path.join(deepDir, "index.js"), "const x = 1;");
|
|
621
|
+
fs.writeFileSync(
|
|
622
|
+
path.join(deepDir, "package.json"),
|
|
623
|
+
'{"name": "deep"}'
|
|
624
|
+
);
|
|
625
|
+
|
|
626
|
+
const result = await runInitCommand([], deepDir);
|
|
627
|
+
|
|
628
|
+
expect(result).toBeDefined();
|
|
629
|
+
// Should complete without crashing
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
it("should handle project with special characters in file names", async () => {
|
|
633
|
+
const specialProject = createTempProjectDir({
|
|
634
|
+
"index.js": "const app = require('./app');",
|
|
635
|
+
"package.json": '{"name": "test"}',
|
|
636
|
+
"src/file-with-dashes.js": "const x = 1;",
|
|
637
|
+
"src/file_with_underscores.js": "const y = 2;",
|
|
638
|
+
});
|
|
639
|
+
tempDirs.push(specialProject);
|
|
640
|
+
|
|
641
|
+
const result = await runInitCommand([], specialProject);
|
|
642
|
+
|
|
643
|
+
expect(result.exitCode).toBe(0);
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
it("should handle project with large number of files", async () => {
|
|
647
|
+
const largeProject = fs.mkdtempSync(path.join(os.tmpdir(), "large-project-"));
|
|
648
|
+
tempDirs.push(largeProject);
|
|
649
|
+
|
|
650
|
+
fs.writeFileSync(path.join(largeProject, "package.json"), '{"name": "large"}');
|
|
651
|
+
|
|
652
|
+
// Create 50 files
|
|
653
|
+
for (let i = 0; i < 50; i++) {
|
|
654
|
+
fs.writeFileSync(
|
|
655
|
+
path.join(largeProject, `file${i}.js`),
|
|
656
|
+
`const x${i} = ${i};`
|
|
657
|
+
);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
const result = await runInitCommand([], largeProject);
|
|
661
|
+
|
|
662
|
+
expect(result.exitCode).toBe(0);
|
|
663
|
+
|
|
664
|
+
const repoMapPath = path.join(largeProject, "ai-context", "repo_map.json");
|
|
665
|
+
const content = fs.readFileSync(repoMapPath, "utf-8");
|
|
666
|
+
const data = JSON.parse(content);
|
|
667
|
+
|
|
668
|
+
expect(data.totalFiles).toBeGreaterThanOrEqual(50);
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
it("should handle project with symlinks", async () => {
|
|
672
|
+
const symlinkProject = createTempProjectDir({
|
|
673
|
+
"index.js": "const app = require('./app');",
|
|
674
|
+
"package.json": '{"name": "symlink-test"}',
|
|
675
|
+
});
|
|
676
|
+
tempDirs.push(symlinkProject);
|
|
677
|
+
|
|
678
|
+
// Create a symlink to a directory
|
|
679
|
+
const targetDir = path.join(symlinkProject, "target-dir");
|
|
680
|
+
fs.mkdirSync(targetDir);
|
|
681
|
+
fs.writeFileSync(path.join(targetDir, "target.js"), "const y = 1;");
|
|
682
|
+
|
|
683
|
+
const symlinkDir = path.join(symlinkProject, "linked-dir");
|
|
684
|
+
fs.symlinkSync(targetDir, symlinkDir);
|
|
685
|
+
|
|
686
|
+
const result = await runInitCommand([], symlinkProject);
|
|
687
|
+
|
|
688
|
+
// Should complete without crashing
|
|
689
|
+
expect(result).toBeDefined();
|
|
690
|
+
});
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
// =========================================================================
|
|
694
|
+
// FILE STRUCTURE VALIDATION
|
|
695
|
+
// =========================================================================
|
|
696
|
+
|
|
697
|
+
describe("File Structure Validation", () => {
|
|
698
|
+
it("should create proper directory structure in ai-context", async () => {
|
|
699
|
+
const testProject = createTempProjectDir({
|
|
700
|
+
"index.js": "const app = require('./app');",
|
|
701
|
+
"package.json": '{"name": "test"}',
|
|
702
|
+
});
|
|
703
|
+
tempDirs.push(testProject);
|
|
704
|
+
|
|
705
|
+
await runInitCommand([], testProject);
|
|
706
|
+
|
|
707
|
+
const aiContextDir = path.join(testProject, "ai-context");
|
|
708
|
+
const entries = fs.readdirSync(aiContextDir, { withFileTypes: true });
|
|
709
|
+
|
|
710
|
+
// Should have multiple files
|
|
711
|
+
const files = entries.filter((e) => e.isFile());
|
|
712
|
+
expect(files.length).toBeGreaterThan(5);
|
|
713
|
+
|
|
714
|
+
// Should have context subdirectory
|
|
715
|
+
const hasContextDir = entries.some(
|
|
716
|
+
(e) => e.isDirectory() && e.name === "context"
|
|
717
|
+
);
|
|
718
|
+
// context subdirectory might not always be created depending on the project
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
it("should create modules.json with proper structure", async () => {
|
|
722
|
+
const testProject = createTempProjectDir({
|
|
723
|
+
"package.json": '{"name": "module-test"}',
|
|
724
|
+
"src/index.ts": "export const main = () => {};",
|
|
725
|
+
"src/api/routes.ts": "export const routes = [];",
|
|
726
|
+
"src/services/user.ts": "export const userService = {};",
|
|
727
|
+
});
|
|
728
|
+
tempDirs.push(testProject);
|
|
729
|
+
|
|
730
|
+
await runInitCommand([], testProject);
|
|
731
|
+
|
|
732
|
+
const modulesPath = path.join(testProject, "ai-context", "modules.json");
|
|
733
|
+
expect(fs.existsSync(modulesPath)).toBe(true);
|
|
734
|
+
|
|
735
|
+
const content = fs.readFileSync(modulesPath, "utf-8");
|
|
736
|
+
const data = JSON.parse(content);
|
|
737
|
+
|
|
738
|
+
expect(data.modules).toBeDefined();
|
|
739
|
+
expect(typeof data.modules).toBe("object");
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
it("should include context subdirectory files when generated", async () => {
|
|
743
|
+
const testProject = createTempProjectDir({
|
|
744
|
+
"package.json": '{"name": "context-test"}',
|
|
745
|
+
"index.js": "const app = require('./app');",
|
|
746
|
+
});
|
|
747
|
+
tempDirs.push(testProject);
|
|
748
|
+
|
|
749
|
+
await runInitCommand([], testProject);
|
|
750
|
+
|
|
751
|
+
const contextDir = path.join(testProject, "ai-context", "context");
|
|
752
|
+
|
|
753
|
+
// Context directory should exist
|
|
754
|
+
if (fs.existsSync(contextDir)) {
|
|
755
|
+
const entries = fs.readdirSync(contextDir, { withFileTypes: true });
|
|
756
|
+
// Just verify the directory can be read
|
|
757
|
+
expect(entries).toBeDefined();
|
|
758
|
+
}
|
|
759
|
+
});
|
|
760
|
+
});
|
|
761
|
+
});
|