ntc-dev-kit 1.1.0__tar.gz → 1.2.0__tar.gz

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.
Files changed (193) hide show
  1. {ntc_dev_kit-1.1.0/ntc_dev_kit.egg-info → ntc_dev_kit-1.2.0}/PKG-INFO +26 -2
  2. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/README.md +25 -1
  3. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/__init__.py +1 -1
  4. ntc_dev_kit-1.2.0/ntc/cli_enhanced.py +421 -0
  5. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/main.py +2 -2
  6. ntc_dev_kit-1.2.0/ntc/templates/auth_app/migrations/0001_initial.py +50 -0
  7. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/main.py +19 -19
  8. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/utils/output.py +10 -0
  9. ntc_dev_kit-1.2.0/ntc/utils/prompts.py +271 -0
  10. ntc_dev_kit-1.2.0/ntc/wizard.py +294 -0
  11. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0/ntc_dev_kit.egg-info}/PKG-INFO +26 -2
  12. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc_dev_kit.egg-info/SOURCES.txt +3 -0
  13. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/pyproject.toml +1 -1
  14. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/setup.py +1 -1
  15. ntc_dev_kit-1.1.0/ntc/cli_enhanced.py +0 -934
  16. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/LICENSE +0 -0
  17. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/MANIFEST.in +0 -0
  18. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/app_creator.py +0 -0
  19. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/cli.py +0 -0
  20. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/composer/__init__.py +0 -0
  21. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/composer/main.py +0 -0
  22. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/deployment/__init__.py +0 -0
  23. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/__init__.py +0 -0
  24. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/auth_app/__init__.py +0 -0
  25. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/auth_app/admin.py +0 -0
  26. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/auth_app/apps.py +0 -0
  27. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/auth_app/models.py +0 -0
  28. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/auth_app/serializers.py +0 -0
  29. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/auth_app/tests.py +0 -0
  30. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/auth_app/urls.py +0 -0
  31. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/auth_app/views.py +0 -0
  32. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/__init__.py +0 -0
  33. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/drf_structure.md +0 -0
  34. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/structure.json +0 -0
  35. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/.entry/start_core_backend.sh +0 -0
  36. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/.entry/start_tasks_backend.sh +0 -0
  37. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/CLAUDE.md +0 -0
  38. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/README.md +0 -0
  39. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/apps/app_admin.py +0 -0
  40. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/apps/app_apps.py +0 -0
  41. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/apps/app_models.py +0 -0
  42. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/apps/app_urls.py +0 -0
  43. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/apps/app_views.py +0 -0
  44. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/apps/common_apps.py +0 -0
  45. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/apps/common_models.py +0 -0
  46. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/config/gunicorn_config.py +0 -0
  47. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/config/http.conf +0 -0
  48. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/core/exceptions/handler.py +0 -0
  49. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/core/formatter.py +0 -0
  50. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/core/logger.py +0 -0
  51. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/core/pagination.py +0 -0
  52. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/core/response_wrapper.py +0 -0
  53. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/core/services/azure/email/backend.py +0 -0
  54. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/core/services/azure/email/client.py +0 -0
  55. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/core/services/azure/email/notifier.py +0 -0
  56. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/core/services/object_storage.py +0 -0
  57. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/core/utils/request.py +0 -0
  58. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/django_project/asgi.py +0 -0
  59. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/django_project/celery.py +0 -0
  60. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/django_project/dev_settings.py +0 -0
  61. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/django_project/django_settings.txt +0 -0
  62. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/django_project/prod_settings.py +0 -0
  63. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/django_project/project_init.py +0 -0
  64. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/django_project/schema.py +0 -0
  65. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/django_project/test_settings.py +0 -0
  66. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/django_project/urls.py +0 -0
  67. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/django_project/wsgi.py +0 -0
  68. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/docker/Dockerfile +0 -0
  69. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/docker/captain-definition +0 -0
  70. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/docker/docker-compose.yml +0 -0
  71. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/knowledge/knowledge_description.md +0 -0
  72. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/knowledge/knowledge_design_pattern.md +0 -0
  73. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/knowledge/knowledge_structure.md +0 -0
  74. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/root/README.md +0 -0
  75. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/root/django_env.txt +0 -0
  76. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/root/django_requirements.txt +0 -0
  77. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/root/django_requirements_dev.txt +0 -0
  78. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/root/dockerignore.txt +0 -0
  79. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/root/gitattributes.txt +0 -0
  80. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/root/gitignore.txt +0 -0
  81. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/root/manage.py +0 -0
  82. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/root/pytest_ini.txt +0 -0
  83. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/drf_structure/templates/root/ruff_toml.txt +0 -0
  84. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/.gitignore +0 -0
  85. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/.knowledge/knowledge_description.md +0 -0
  86. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/.knowledge/knowledge_design_pattern.md +0 -0
  87. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/.knowledge/knowledge_structure.md +0 -0
  88. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/CLAUDE.md +0 -0
  89. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/__init__.py +0 -0
  90. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/analysis_options.yaml +0 -0
  91. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/lib/core/config/app_config.dart +0 -0
  92. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/lib/core/config/environment.dart +0 -0
  93. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/lib/core/constants/app_constants.dart +0 -0
  94. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/lib/core/network/dio_client.dart +0 -0
  95. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/lib/features/home/presentation/home_screen.dart +0 -0
  96. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/lib/l10n/app_localizations.dart +0 -0
  97. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/lib/main.dart +0 -0
  98. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/lib/services/api_service.dart +0 -0
  99. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/lib/shared/localization/locale_provider.dart +0 -0
  100. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/lib/shared/theme/app_theme.dart +0 -0
  101. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/lib/shared/theme/theme_provider.dart +0 -0
  102. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/main.py +0 -0
  103. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/pubspec.yaml +0 -0
  104. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/flutter/structure.json +0 -0
  105. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/.env.example +0 -0
  106. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/.gitignore +0 -0
  107. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/CLAUDE.md +0 -0
  108. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/README.md +0 -0
  109. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/__init__.py +0 -0
  110. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/eslint.config.mjs +0 -0
  111. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/knowledge/knowledge_description.md +0 -0
  112. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/knowledge/knowledge_design_pattern.md +0 -0
  113. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/knowledge/knowledge_structure.md +0 -0
  114. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/main.py +0 -0
  115. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/next.config.js +0 -0
  116. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/package.json +0 -0
  117. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/src/app/globals.css +0 -0
  118. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/src/app/layout.tsx +0 -0
  119. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/src/app/page.tsx +0 -0
  120. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/src/components/Header.tsx +0 -0
  121. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/src/services/api.ts +0 -0
  122. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/src/services/server.ts +0 -0
  123. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/src/utils/constants.ts +0 -0
  124. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/structure.json +0 -0
  125. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/nextjs/tsconfig.json +0 -0
  126. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/.env.example +0 -0
  127. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/.gitignore +0 -0
  128. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/CLAUDE.md +0 -0
  129. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/README.md +0 -0
  130. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/__init__.py +0 -0
  131. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/eslint.config.js +0 -0
  132. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/index.html +0 -0
  133. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/knowledge/knowledge_description.md +0 -0
  134. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/knowledge/knowledge_design_pattern.md +0 -0
  135. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/knowledge/knowledge_structure.md +0 -0
  136. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/main.py +0 -0
  137. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/package.json +0 -0
  138. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/App.tsx +0 -0
  139. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/components/ProtectedRoute.tsx +0 -0
  140. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/components/Sidebar.tsx +0 -0
  141. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/components/TopNav.tsx +0 -0
  142. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/context/AuthContext.tsx +0 -0
  143. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/context/ThemeContext.tsx +0 -0
  144. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/context/WorkspaceContext.tsx +0 -0
  145. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/hooks/useApi.ts +0 -0
  146. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/index.css +0 -0
  147. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/layouts/AuthLayout.tsx +0 -0
  148. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/layouts/DashboardLayout.tsx +0 -0
  149. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/main.tsx +0 -0
  150. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/pages/DashboardPage.tsx +0 -0
  151. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/pages/auth/LoginPage.tsx +0 -0
  152. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/services/api.service.ts +0 -0
  153. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/services/base.service.ts +0 -0
  154. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/services/token.ts +0 -0
  155. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/src/vite-env.d.ts +0 -0
  156. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/structure.json +0 -0
  157. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/tsconfig.app.json +0 -0
  158. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/tsconfig.json +0 -0
  159. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/tsconfig.node.json +0 -0
  160. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_admin/vite.config.ts +0 -0
  161. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/App.css +0 -0
  162. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/CLAUDE.md +0 -0
  163. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/__init__.py +0 -0
  164. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/index.css +0 -0
  165. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/index.html +0 -0
  166. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/knowledge/knowledge_description.md +0 -0
  167. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/knowledge/knowledge_design_pattern.md +0 -0
  168. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/knowledge/knowledge_structure.md +0 -0
  169. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/main.py +0 -0
  170. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/package.json +0 -0
  171. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/src/App.tsx +0 -0
  172. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/src/components/Header.tsx +0 -0
  173. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/src/main.tsx +0 -0
  174. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/src/services/api.ts +0 -0
  175. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/src/utils/constants.ts +0 -0
  176. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/src/vite-env.d.ts +0 -0
  177. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/structure.json +0 -0
  178. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/tsconfig.app.json +0 -0
  179. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/tsconfig.json +0 -0
  180. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/tsconfig.node.json +0 -0
  181. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/templates/react_structure/vite.config.ts +0 -0
  182. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/ui/__init__.py +0 -0
  183. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/ui/app.py +0 -0
  184. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/utils/__init__.py +0 -0
  185. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/utils/environment.py +0 -0
  186. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/utils/shell.py +0 -0
  187. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc/utils/validation.py +0 -0
  188. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc_dev_kit.egg-info/dependency_links.txt +0 -0
  189. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc_dev_kit.egg-info/entry_points.txt +0 -0
  190. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc_dev_kit.egg-info/requires.txt +0 -0
  191. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/ntc_dev_kit.egg-info/top_level.txt +0 -0
  192. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/requirements.txt +0 -0
  193. {ntc_dev_kit-1.1.0 → ntc_dev_kit-1.2.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ntc-dev-kit
3
- Version: 1.1.0
3
+ Version: 1.2.0
4
4
  Summary: Nexent Toolkit Console - A CLI tool for scaffolding Django REST Framework, React, Next.js, and Flutter projects
5
5
  Home-page: https://github.com/nexent/ntc
6
6
  Author: Nexent
@@ -97,7 +97,31 @@ ntc init --technology flutter
97
97
  ntc init
98
98
  ```
99
99
 
100
- Navigate menus with **arrow keys**, select with **Enter**, exit with **Escape**.
100
+ A few questions, asked inline: project name, what you're building, where it goes, then the
101
+ options for that technology (sign-in and Python environment for Django; installing dependencies
102
+ for the others), a summary, and **Create?**. The defaults are already selected, so Enter takes
103
+ them; **↑/↓** move, a **number key** picks an option at once, **Esc** cancels without writing
104
+ anything. Each answer collapses to one line, and the only progress shown is for real work
105
+ (creating the environment, installing packages).
106
+
107
+ ### Without questions
108
+
109
+ Every answer can be given as a flag; with `--yes` nothing is asked (scripts, CI, AI agents):
110
+
111
+ ```bash
112
+ ntc init -t django --name shop-api --with-auth --env venv --yes
113
+ ntc init -t nextjs --name site --install --yes
114
+ ```
115
+
116
+ | Flag | Meaning |
117
+ |------|---------|
118
+ | `-t`, `--technology` | `django`, `nextjs`, `react-admin`, `react`, `flutter` |
119
+ | `--name` | Project name (`.` = the current folder) |
120
+ | `--path` | Folder to create the project in (default: current folder) |
121
+ | `--with-auth` / `--no-auth` | Django: include the sign-in app (custom User model, JWT, migration included) |
122
+ | `--env` | Django: `venv`, `conda`, `existing` (the active virtualenv) or `skip` |
123
+ | `--install` / `--no-install` | Others: run `npm install` / `flutter pub get` |
124
+ | `--yes`, `-y` | Ask nothing; needs `--name` and `--technology` |
101
125
 
102
126
  ### Technology Options
103
127
 
@@ -57,7 +57,31 @@ ntc init --technology flutter
57
57
  ntc init
58
58
  ```
59
59
 
60
- Navigate menus with **arrow keys**, select with **Enter**, exit with **Escape**.
60
+ A few questions, asked inline: project name, what you're building, where it goes, then the
61
+ options for that technology (sign-in and Python environment for Django; installing dependencies
62
+ for the others), a summary, and **Create?**. The defaults are already selected, so Enter takes
63
+ them; **↑/↓** move, a **number key** picks an option at once, **Esc** cancels without writing
64
+ anything. Each answer collapses to one line, and the only progress shown is for real work
65
+ (creating the environment, installing packages).
66
+
67
+ ### Without questions
68
+
69
+ Every answer can be given as a flag; with `--yes` nothing is asked (scripts, CI, AI agents):
70
+
71
+ ```bash
72
+ ntc init -t django --name shop-api --with-auth --env venv --yes
73
+ ntc init -t nextjs --name site --install --yes
74
+ ```
75
+
76
+ | Flag | Meaning |
77
+ |------|---------|
78
+ | `-t`, `--technology` | `django`, `nextjs`, `react-admin`, `react`, `flutter` |
79
+ | `--name` | Project name (`.` = the current folder) |
80
+ | `--path` | Folder to create the project in (default: current folder) |
81
+ | `--with-auth` / `--no-auth` | Django: include the sign-in app (custom User model, JWT, migration included) |
82
+ | `--env` | Django: `venv`, `conda`, `existing` (the active virtualenv) or `skip` |
83
+ | `--install` / `--no-install` | Others: run `npm install` / `flutter pub get` |
84
+ | `--yes`, `-y` | Ask nothing; needs `--name` and `--technology` |
61
85
 
62
86
  ### Technology Options
63
87
 
@@ -1,5 +1,5 @@
1
1
  """NTC - Nexent Toolkit Console."""
2
2
 
3
- __version__ = "1.1.0"
3
+ __version__ = "1.2.0"
4
4
  __author__ = "Nexent"
5
5
  __license__ = "MIT"
@@ -0,0 +1,421 @@
1
+ import argparse
2
+ import os
3
+ import sys
4
+ import time
5
+ from colorama import Fore, Style, init
6
+ from ntc.utils.validation import is_valid_project_name
7
+
8
+ # Commands import their generators when they run, so `ntc --help` and the first question of
9
+ # `ntc init` appear without loading every template module first.
10
+
11
+ # Initialize colorama for cross-platform colored output
12
+ init(autoreset=True)
13
+
14
+ def print_banner():
15
+ """Display minimal welcome banner."""
16
+ print(f"\n{Fore.WHITE}{Style.BRIGHT} ntc{Style.RESET_ALL} {Fore.LIGHTBLACK_EX}— project scaffolding tool{Style.RESET_ALL}")
17
+ print()
18
+
19
+ def print_success(message):
20
+ """Print success message with green color and checkmark."""
21
+ print(f"{Fore.GREEN}✅ {message}{Style.RESET_ALL}")
22
+
23
+ def print_error(message):
24
+ """Print error message with red color and X mark."""
25
+ print(f"{Fore.RED}❌ {message}{Style.RESET_ALL}")
26
+
27
+ def print_warning(message):
28
+ """Print warning message with yellow color and warning sign."""
29
+ print(f"{Fore.YELLOW}⚠️ {message}{Style.RESET_ALL}")
30
+
31
+ def print_info(message):
32
+ """Print info message with blue color and info icon."""
33
+ print(f"{Fore.CYAN}ℹ️ {message}{Style.RESET_ALL}")
34
+
35
+ def animate_dependency_install(requirements_path=None, pip_command=None, env_type="system"):
36
+ """Show real dependency installation with progress animation."""
37
+ import subprocess
38
+ import threading
39
+
40
+ if not requirements_path or not os.path.exists(requirements_path):
41
+ # Fallback to simulation if no requirements file
42
+ dependencies = [
43
+ "Resolving dependencies",
44
+ "Downloading packages",
45
+ "Installing Django",
46
+ "Installing DRF",
47
+ "Installing Celery",
48
+ "Installing CORS headers",
49
+ "Configuring environment",
50
+ "Setting up database",
51
+ "Creating migrations",
52
+ "Finalizing setup"
53
+ ]
54
+
55
+ print(f"\n{Fore.MAGENTA}📦 Installing Dependencies{Style.RESET_ALL}")
56
+
57
+ for i, dep in enumerate(dependencies, 1):
58
+ progress = int((i / len(dependencies)) * 100)
59
+
60
+ # Show animation for each dependency
61
+ for j in range(5): # 5 animation cycles per dependency
62
+ frame = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"][j % 10]
63
+ # Clear line and print new content
64
+ print(f"\r{' ' * 80}\r{Fore.CYAN}{frame} {dep}... {Fore.YELLOW}[{progress}%]{Style.RESET_ALL}", end="", flush=True)
65
+ time.sleep(0.2)
66
+
67
+ print(f"\r{' ' * 80}\r{Fore.GREEN}✅ All dependencies installed successfully! {Fore.YELLOW}[100%]{Style.RESET_ALL}")
68
+ print()
69
+ return
70
+
71
+ # Real dependency installation with animation
72
+ print(f"\n{Fore.MAGENTA}📦 Installing Dependencies{Style.RESET_ALL}")
73
+
74
+ # Determine the pip command to use
75
+ if pip_command is None:
76
+ # Default to system pip
77
+ pip_command = [sys.executable, "-m", "pip", "install", "-r", requirements_path]
78
+
79
+ # Animation state
80
+ animation_running = True
81
+ install_complete = False
82
+ install_success = False
83
+ error_message = ""
84
+
85
+ def run_pip_install():
86
+ nonlocal install_complete, install_success, error_message
87
+ try:
88
+ # Run pip install with suppressed output
89
+ result = subprocess.run(
90
+ pip_command,
91
+ capture_output=True,
92
+ text=True,
93
+ check=True
94
+ )
95
+ install_success = True
96
+ except subprocess.CalledProcessError as e:
97
+ install_success = False
98
+ error_message = str(e)
99
+ finally:
100
+ install_complete = True
101
+
102
+ # Start installation in background thread
103
+ install_thread = threading.Thread(target=run_pip_install)
104
+ install_thread.start()
105
+
106
+ # Show animation while installation runs
107
+ frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
108
+ frame_index = 0
109
+
110
+ while not install_complete:
111
+ frame = frames[frame_index % len(frames)]
112
+ # Clear line completely before writing new content
113
+ env_msg = f" ({env_type} environment)" if env_type != "system" else ""
114
+ print(f"\r{' ' * 80}\r{Fore.CYAN}{frame} Installing packages{env_msg}...{Style.RESET_ALL}", end="", flush=True)
115
+ time.sleep(0.1)
116
+ frame_index += 1
117
+
118
+ # Wait for thread to complete
119
+ install_thread.join()
120
+
121
+ # Show final result
122
+ if install_success:
123
+ print(f"\r{' ' * 80}\r{Fore.GREEN}✅ All dependencies installed successfully!{Style.RESET_ALL}")
124
+ else:
125
+ print(f"\r{' ' * 80}\r{Fore.RED}❌ Failed to install dependencies: {error_message}{Style.RESET_ALL}")
126
+ print(f"{Fore.YELLOW}💡 You can manually install later with: pip install -r requirements.txt{Style.RESET_ALL}")
127
+
128
+ print()
129
+
130
+ def run_doctor():
131
+ """Check setup and fix common issues like PATH configuration."""
132
+ import shutil
133
+ import site
134
+
135
+ # Nexent brand palette
136
+ DIM = Fore.LIGHTBLACK_EX
137
+ ACCENT = Fore.WHITE
138
+ OK = Fore.GREEN
139
+ WARN = Fore.YELLOW
140
+ ERR = Fore.RED
141
+ BOLD = Style.BRIGHT
142
+ RESET = Style.RESET_ALL
143
+
144
+ def _ok(text):
145
+ print(f" {OK} {text}{RESET}")
146
+
147
+ def _err(text):
148
+ print(f" {ERR} {text}{RESET}")
149
+
150
+ def _warn(text):
151
+ print(f" {WARN} {text}{RESET}")
152
+
153
+ def _dim(text):
154
+ print(f" {DIM}{text}{RESET}")
155
+
156
+ # Minimal Nexent header
157
+ print(f"\n{BOLD}{Fore.WHITE} NEXENT{RESET}")
158
+ print(f" {DIM}Future Awaits{RESET}")
159
+ print(f" {DIM}{'─' * 50}{RESET}")
160
+ print(f" {Fore.WHITE}SETUP DIAGNOSTICS{RESET}\n")
161
+
162
+ issues_found = 0
163
+ issues_fixed = 0
164
+
165
+ # 1. Python
166
+ print(f" {Fore.WHITE}Python{RESET}")
167
+ py_version = sys.version_info
168
+ if py_version >= (3, 10):
169
+ _ok(f"{py_version.major}.{py_version.minor}.{py_version.micro}")
170
+ else:
171
+ _err(f"{py_version.major}.{py_version.minor} — >= 3.10 required")
172
+ issues_found += 1
173
+
174
+ # 2. Dependencies
175
+ print(f"\n {Fore.WHITE}Dependencies{RESET}")
176
+ deps_ok = True
177
+ for mod, name in [("colorama", "colorama"), ("yaml", "pyyaml")]:
178
+ try:
179
+ __import__(mod)
180
+ _ok(name)
181
+ except ImportError:
182
+ _err(name)
183
+ deps_ok = False
184
+ if not deps_ok:
185
+ issues_found += 1
186
+ _dim(" Run: pip install colorama pyyaml")
187
+
188
+ # 3. Command accessibility
189
+ print(f"\n {Fore.WHITE}Command{RESET}")
190
+ ntc_path = shutil.which("ntc")
191
+ if ntc_path:
192
+ _ok("ntc found")
193
+ _dim(f" {ntc_path}")
194
+ else:
195
+ _err("ntc not in PATH")
196
+ issues_found += 1
197
+
198
+ # 4. Scripts directory
199
+ print(f"\n {Fore.WHITE}Scripts Directory{RESET}")
200
+ scripts_dir = os.path.join(site.USER_BASE, "Scripts")
201
+ if os.path.exists(scripts_dir):
202
+ _ok(scripts_dir)
203
+ else:
204
+ _warn("missing — creating...")
205
+ os.makedirs(scripts_dir, exist_ok=True)
206
+ _ok("created")
207
+ issues_fixed += 1
208
+
209
+ # 5. PATH
210
+ if os.name == "nt":
211
+ print(f"\n {Fore.WHITE}PATH{RESET}")
212
+ current_path = os.environ.get("PATH", "")
213
+ if scripts_dir.lower() in current_path.lower():
214
+ _ok("Scripts directory in PATH")
215
+ else:
216
+ _warn("Scripts directory not in PATH")
217
+ try:
218
+ import winreg
219
+ with winreg.OpenKey(
220
+ winreg.HKEY_CURRENT_USER, "Environment", 0,
221
+ winreg.KEY_READ | winreg.KEY_WRITE,
222
+ ) as key:
223
+ existing, _ = winreg.QueryValueEx(key, "PATH")
224
+ if scripts_dir.lower() not in existing.lower():
225
+ new_path = f"{existing};{scripts_dir}"
226
+ winreg.SetValueEx(key, "PATH", 0, winreg.REG_EXPAND_SZ, new_path)
227
+ os.environ["PATH"] = new_path
228
+ _ok("added to registry")
229
+ issues_fixed += 1
230
+ else:
231
+ _ok("in registry (restart needed)")
232
+ except Exception as e:
233
+ _err(f"registry edit failed: {e}")
234
+ _dim(f" Add manually: {scripts_dir}")
235
+ issues_found += 1
236
+
237
+ # 6. Package version
238
+ print(f"\n {Fore.WHITE}Package{RESET}")
239
+ try:
240
+ import ntc
241
+ _ok(f"ntc-dev-kit {ntc.__version__}")
242
+ except (ImportError, AttributeError):
243
+ _err("ntc-dev-kit not installed")
244
+ issues_found += 1
245
+
246
+ # Summary
247
+ print(f"\n {DIM}{'─' * 50}{RESET}")
248
+ if issues_found == 0 and issues_fixed == 0:
249
+ print(f" {OK}Ready.{RESET}")
250
+ elif issues_fixed > 0:
251
+ print(f" {OK}Fixed {issues_fixed}.{RESET}")
252
+ if issues_found > 0:
253
+ print(f" {WARN}{issues_found} remaining.{RESET}")
254
+ else:
255
+ print(f" {DIM}Restart terminal for changes.{RESET}")
256
+ else:
257
+ print(f" {ERR}{issues_found} issue(s) found.{RESET}")
258
+ print(f" {DIM}Run 'ntc doctor' again after fixing.{RESET}")
259
+ print(f" {DIM}{'─' * 50}{RESET}\n")
260
+
261
+
262
+ def _use_utf8_console():
263
+ """Print emoji and box-drawing characters on any console.
264
+
265
+ A Windows console on cp1252 (the default, and what scripts, CI and editor terminals get)
266
+ can't encode them: the very first print raised UnicodeEncodeError and ntc init crashed.
267
+ Characters the console truly can't show are replaced instead of raising."""
268
+ for stream in (sys.stdout, sys.stderr):
269
+ try:
270
+ stream.reconfigure(encoding='utf-8', errors='replace')
271
+ except (AttributeError, ValueError):
272
+ pass # not a reconfigurable text stream (redirected to an object, Python < 3.7)
273
+
274
+
275
+ def main():
276
+ _use_utf8_console()
277
+ parser = argparse.ArgumentParser(
278
+ description="ntc — project scaffolding tool",
279
+ formatter_class=argparse.RawDescriptionHelpFormatter,
280
+ epilog="""
281
+ Examples:
282
+ ntc init # New project: a few questions, defaults pre-selected
283
+ ntc init -t django # Skip the "what are you building" question
284
+ ntc init -t django --name shop-api --with-auth --env venv --yes
285
+ # No questions at all (scripts, CI, AI agents)
286
+ ntc init -t nextjs --name site --install --yes
287
+ ntc compose myproject # Compose full-stack project with multiple components
288
+ ntc start # Start all services from ntc.yml configuration
289
+ ntc create app myapp # Create new Django app
290
+ ntc drf init path name # Legacy Django REST Framework initialization
291
+ """
292
+ )
293
+
294
+ subparsers = parser.add_subparsers(dest="command", help="Available commands")
295
+
296
+ # Enhanced init command
297
+ init_parser = subparsers.add_parser("init", help="Interactive project initialization")
298
+ init_parser.add_argument('--technology', '-t', type=str,
299
+ choices=['django', 'react', 'react-admin', 'nextjs', 'flutter'],
300
+ help='Technology to use (django, react, react-admin, nextjs, flutter)')
301
+ init_parser.add_argument("--backend",
302
+ choices=["django", "drf", "laravel"],
303
+ help="Backend technology")
304
+ init_parser.add_argument("--frontend",
305
+ choices=["react", "react-admin", "nextjs", "flutter"],
306
+ help="Frontend technology")
307
+ init_parser.add_argument("--name", help="Project name ('.' = the current directory's name)")
308
+ init_parser.add_argument("--path", help="Directory to create the project in (default: current directory)")
309
+ auth_group = init_parser.add_mutually_exclusive_group()
310
+ auth_group.add_argument("--with-auth", dest="with_auth", action="store_true", default=None,
311
+ help="Django: include the authentication app (custom User model, JWT endpoints)")
312
+ auth_group.add_argument("--no-auth", dest="with_auth", action="store_false",
313
+ help="Django: no authentication app")
314
+ init_parser.add_argument("--env", choices=["venv", "conda", "existing", "skip"],
315
+ help="Django: Python environment - create a venv/conda env, install into the "
316
+ "active one, or skip")
317
+ install_group = init_parser.add_mutually_exclusive_group()
318
+ install_group.add_argument("--install", dest="install", action="store_true", default=None,
319
+ help="Next.js/React/Flutter: install dependencies (npm install / flutter pub get)")
320
+ install_group.add_argument("--no-install", dest="install", action="store_false",
321
+ help="Next.js/React/Flutter: don't install dependencies")
322
+ init_parser.add_argument("--yes", "-y", action="store_true",
323
+ help="Don't ask: use the options given and defaults for the rest "
324
+ "(requires --name and --technology)")
325
+
326
+ # Create command for apps
327
+ create_parser = subparsers.add_parser("create", help="Create new components")
328
+ create_subparsers = create_parser.add_subparsers(dest="create_type", help="Type of component to create")
329
+
330
+ # Create app subcommand
331
+ app_parser = create_subparsers.add_parser("app", help="Create new Django app with NTC structure")
332
+ app_parser.add_argument("app_name", help="Name of the app to create")
333
+ url_group = app_parser.add_mutually_exclusive_group()
334
+ url_group.add_argument("--no-url", action="store_true",
335
+ help="Don't add the app's URLs anywhere; include them yourself")
336
+ url_group.add_argument("--url-prefix", default=None,
337
+ help="Add the app's URLs at the root urlpatterns under this prefix "
338
+ "(e.g. 'api/v2/'). Default: the project's api_v1 list (/api/v1/<app>/)")
339
+
340
+ # Legacy DRF command for backward compatibility
341
+ drf_parser = subparsers.add_parser("drf", help="Django REST Framework commands (legacy)")
342
+ drf_subparsers = drf_parser.add_subparsers(dest="drf_action")
343
+ drf_init_parser = drf_subparsers.add_parser("init", help="Initialize DRF project")
344
+ drf_init_parser.add_argument("path", help="Base path to create the project")
345
+ drf_init_parser.add_argument("name", help="Project name")
346
+
347
+ # Composer command for full-stack project composition
348
+ composer_parser = subparsers.add_parser("compose", help="Compose a full-stack project with multiple components")
349
+ composer_parser.add_argument("project_name", help="Name of the project")
350
+ composer_parser.add_argument("--path", help="Base path to create the project (default: current directory)")
351
+
352
+ # Start services command
353
+ start_parser = subparsers.add_parser("start", help="Start all services defined in ntc.yml")
354
+ start_parser.add_argument("--path", help="Path to project root directory (default: current directory)")
355
+
356
+ # Doctor command for setup diagnostics
357
+ doctor_parser = subparsers.add_parser("doctor", help="Check setup and fix common issues")
358
+
359
+ # TUI command for interactive terminal UI
360
+ tui_parser = subparsers.add_parser("tui", help="Launch interactive terminal UI")
361
+
362
+ args = parser.parse_args()
363
+
364
+ if args.command == "init":
365
+ technology = args.technology or args.frontend or args.backend
366
+ technology = {"drf": "django", "laravel": "django"}.get(technology, technology)
367
+ if args.yes and not (args.name and technology):
368
+ print_error("--yes needs --name and --technology, so there is nothing left to ask.")
369
+ sys.exit(2)
370
+ from ntc.wizard import run as run_wizard
371
+ created = run_wizard(technology=technology, name=args.name, path=args.path, with_auth=args.with_auth,
372
+ env_choice=args.env, install=args.install, assume_yes=args.yes)
373
+ sys.exit(0 if created else 1)
374
+ elif args.command == "create" and args.create_type == "app":
375
+ if not is_valid_project_name(args.app_name):
376
+ print_error("App name may only contain letters, numbers, underscores, and hyphens!")
377
+ sys.exit(1)
378
+ from ntc.app_creator import create_app_structure
379
+ create_app_structure(args.app_name, add_urls=not args.no_url, url_prefix=args.url_prefix)
380
+ elif args.command == "drf" and args.drf_action == "init":
381
+ # Legacy support
382
+ if not is_valid_project_name(args.name):
383
+ print_error("Project name may only contain letters, numbers, underscores, and hyphens!")
384
+ sys.exit(1)
385
+ from ntc.templates.drf_structure.main import init_drf_project
386
+ init_drf_project(args.path, args.name)
387
+ elif args.command == "compose":
388
+ # Composer for full-stack project composition
389
+ if not is_valid_project_name(args.project_name):
390
+ print_error("Project name may only contain letters, numbers, underscores, and hyphens!")
391
+ sys.exit(1)
392
+ from ntc.composer.main import compose_project
393
+ if args.path:
394
+ compose_project(args.project_name, args.path)
395
+ else:
396
+ compose_project(args.project_name)
397
+ elif args.command == "start":
398
+ # Start services from ntc.yml configuration
399
+ from ntc.composer.main import start_services
400
+ if args.path:
401
+ start_services(args.path)
402
+ else:
403
+ start_services()
404
+ elif args.command == "doctor":
405
+ run_doctor()
406
+ elif args.command == "tui":
407
+ from ntc.ui.app import run_tui
408
+ run_tui()
409
+ else:
410
+ # Show help if no command provided
411
+ print_banner()
412
+ print(f"\n {Fore.LIGHTBLACK_EX}Quick Start:{Style.RESET_ALL}")
413
+ print(f" {Fore.WHITE}ntc tui{Style.RESET_ALL} {Fore.LIGHTBLACK_EX}interactive terminal UI{Style.RESET_ALL}")
414
+ print(f" {Fore.WHITE}ntc init{Style.RESET_ALL} {Fore.LIGHTBLACK_EX}interactive setup{Style.RESET_ALL}")
415
+ print(f" {Fore.WHITE}ntc init -t django{Style.RESET_ALL} {Fore.LIGHTBLACK_EX}Django project{Style.RESET_ALL}")
416
+ print(f" {Fore.WHITE}ntc doctor{Style.RESET_ALL} {Fore.LIGHTBLACK_EX}check setup{Style.RESET_ALL}")
417
+ print()
418
+ parser.print_help()
419
+
420
+ if __name__ == "__main__":
421
+ main()
@@ -37,8 +37,8 @@ modules_to_register = [
37
37
  ("ntc.templates.flutter", os.path.join(this_dir, "templates", "flutter", "__init__.py")),
38
38
  ("ntc.templates.flutter.main", os.path.join(this_dir, "templates", "flutter", "main.py")),
39
39
  ("ntc.templates.auth_app", os.path.join(this_dir, "templates", "auth_app", "__init__.py")),
40
- ("ntc.ui", os.path.join(this_dir, "ui", "__init__.py")),
41
- ("ntc.ui.app", os.path.join(this_dir, "ui", "app.py")),
40
+ # Not ntc.ui / ntc.ui.app: they import textual (most of a second), and `ntc tui` imports
41
+ # them itself when it runs.
42
42
  ]
43
43
 
44
44
  for modname, file_path in modules_to_register:
@@ -0,0 +1,50 @@
1
+ # Generated by Django 5.2.7 on 2026-10-20 14:53
2
+
3
+ import django.contrib.auth.models
4
+ import django.contrib.auth.validators
5
+ import django.utils.timezone
6
+ from django.db import migrations, models
7
+
8
+
9
+ class Migration(migrations.Migration):
10
+
11
+ initial = True
12
+
13
+ dependencies = [
14
+ ('auth', '0012_alter_user_first_name_max_length'),
15
+ ]
16
+
17
+ operations = [
18
+ migrations.CreateModel(
19
+ name='User',
20
+ fields=[
21
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
22
+ ('password', models.CharField(max_length=128, verbose_name='password')),
23
+ ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
24
+ ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
25
+ ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
26
+ ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
27
+ ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
28
+ ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
29
+ ('email', models.EmailField(max_length=254, unique=True)),
30
+ ('first_name', models.CharField(blank=True, max_length=30)),
31
+ ('last_name', models.CharField(blank=True, max_length=30)),
32
+ ('phone_number', models.CharField(blank=True, max_length=15)),
33
+ ('date_of_birth', models.DateField(blank=True, null=True)),
34
+ ('profile_picture', models.ImageField(blank=True, null=True, upload_to='profile_pics/')),
35
+ ('is_verified', models.BooleanField(default=False)),
36
+ ('created_at', models.DateTimeField(auto_now_add=True)),
37
+ ('updated_at', models.DateTimeField(auto_now=True)),
38
+ ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
39
+ ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
40
+ ],
41
+ options={
42
+ 'verbose_name': 'User',
43
+ 'verbose_name_plural': 'Users',
44
+ 'db_table': 'auth_user',
45
+ },
46
+ managers=[
47
+ ('objects', django.contrib.auth.models.UserManager()),
48
+ ],
49
+ ),
50
+ ]
@@ -8,8 +8,13 @@ import platform
8
8
  from colorama import Fore, Style
9
9
  from ntc.utils.output import print_success, print_error, print_warning, print_info, print_progress, print_package, print_download
10
10
 
11
- def sanitize_project_name(name):
12
- """Sanitize project name by removing TLD and replacing dots with underscores."""
11
+ def sanitize_project_name(name, quiet=False):
12
+ """Sanitize project name by removing TLD and replacing dots with underscores.
13
+ quiet: don't print what changed (the setup wizard shows the resulting folder instead)."""
14
+ if quiet:
15
+ from ntc.utils import output
16
+ with output.silenced():
17
+ return sanitize_project_name(name)
13
18
  # Common TLDs to remove
14
19
  tlds = ['.com', '.org', '.net', '.io', '.co', '.app', '.dev', '.tech', '.ai', '.ly', '.me', '.tv', '.co.tz', '.tz', '.or.tz']
15
20
 
@@ -90,15 +95,6 @@ def activate_env(env_type, env_dir):
90
95
  print_success("Virtual environment created and dependencies installed!")
91
96
  print_info(f"To activate your environment, run: {activate_cmd}")
92
97
 
93
- # Optionally open a new terminal (non-blocking) for user convenience
94
- try:
95
- if platform.system() == "Windows":
96
- # No shell=True: passing args as a list lets Python quote each
97
- # argument correctly instead of interpolating into a shell string.
98
- subprocess.Popen(["cmd", "/c", "start", "cmd", "/k", activate_cmd])
99
- print_info("A new terminal window has been opened with the environment activated.")
100
- except Exception:
101
- pass
102
98
 
103
99
  def create_virtual_env(env_type, project_root):
104
100
  """
@@ -241,9 +237,10 @@ def install_requirements(env_type, env_dir, project_root):
241
237
  print("❌ Python not found in PATH. Cannot create venv.")
242
238
  sys.exit(1)
243
239
 
244
- print("📦 Creating virtual environment using venv...")
245
- subprocess.run([sys.executable, "-m", "venv", env_dir], check=True)
246
- print(f"✅ Virtual environment created at: {env_dir}")
240
+ # create_virtual_env() has normally made it already; making it again cost a few seconds.
241
+ if not os.path.exists(env_dir):
242
+ subprocess.run([sys.executable, "-m", "venv", env_dir], check=True)
243
+ print(f"✅ Virtual environment created at: {env_dir}")
247
244
 
248
245
  pip_path = os.path.join(env_dir, "Scripts" if os.name == "nt" else "bin", "pip")
249
246
 
@@ -251,8 +248,8 @@ def install_requirements(env_type, env_dir, project_root):
251
248
  from ntc.cli_enhanced import animate_dependency_install
252
249
  pip_command = [pip_path, "install", "-r", requirements_path]
253
250
  animate_dependency_install(requirements_path, pip_command, "venv")
254
-
255
- update_requirements_versioning(env_type, project_root)
251
+ # requirements.txt is already pinned: a pip freeze here would replace it with every
252
+ # transitive package. And no extra terminal window - the command is printed instead.
256
253
  activate_env(env_type, env_dir)
257
254
  return # Stop here after venv setup
258
255
 
@@ -260,14 +257,14 @@ def install_requirements(env_type, env_dir, project_root):
260
257
  if env_type == "conda":
261
258
  conda_executable = find_conda_executable()
262
259
  print("📦 Creating conda environment...")
263
- subprocess.run([conda_executable, "create", "-p", env_dir, "python=3.12", "-y"], check=True)
260
+ if not os.path.exists(env_dir): # create_virtual_env() usually made it already
261
+ subprocess.run([conda_executable, "create", "-p", env_dir, "python=3.12", "-y"], check=True)
264
262
  print("✅ Conda environment created successfully.")
265
263
 
266
264
  # Use animated dependency installer for conda
267
265
  from ntc.cli_enhanced import animate_dependency_install
268
266
  pip_command = [conda_executable, "run", "-p", env_dir, "pip", "install", "-r", requirements_path]
269
267
  animate_dependency_install(requirements_path, pip_command, "conda")
270
- update_requirements_versioning(env_type, project_root)
271
268
  activate_env(env_type, env_dir)
272
269
 
273
270
  def get_pip_path(env_dir):
@@ -294,7 +291,10 @@ def get_pip_path(env_dir):
294
291
  print("❌ pip still not found after ensurepip.")
295
292
  return None
296
293
 
297
- AUTH_APP_FILES = ('apps.py', 'models.py', 'serializers.py', 'views.py', 'urls.py', 'admin.py', 'tests.py')
294
+ # The initial migration ships with the app, so a new project's first `migrate` creates the users
295
+ # table - no makemigrations step to know about.
296
+ AUTH_APP_FILES = ('apps.py', 'models.py', 'serializers.py', 'views.py', 'urls.py', 'admin.py', 'tests.py',
297
+ os.path.join('migrations', '0001_initial.py'))
298
298
 
299
299
 
300
300
  def _auth_variables(with_auth):