ntc-dev-kit 1.0.3__tar.gz → 1.0.6__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.
- {ntc_dev_kit-1.0.3/ntc_dev_kit.egg-info → ntc_dev_kit-1.0.6}/PKG-INFO +2 -1
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/cli_enhanced.py +92 -90
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/composer/main.py +29 -6
- ntc_dev_kit-1.0.6/ntc/main.py +56 -0
- ntc_dev_kit-1.0.6/ntc/ui/__init__.py +1 -0
- ntc_dev_kit-1.0.6/ntc/ui/app.py +179 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6/ntc_dev_kit.egg-info}/PKG-INFO +2 -1
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc_dev_kit.egg-info/SOURCES.txt +3 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc_dev_kit.egg-info/requires.txt +1 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/pyproject.toml +2 -1
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/requirements.txt +1 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/setup.py +2 -1
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/LICENSE +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/MANIFEST.in +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/README.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/__init__.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/app_creator.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/cli.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/composer/__init__.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/deployment/__init__.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/__init__.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/auth_app/__init__.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/auth_app/admin.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/auth_app/apps.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/auth_app/models.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/auth_app/serializers.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/auth_app/urls.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/auth_app/views.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/__init__.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/drf_structure.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/main.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/structure.json +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/.entry/start_core_backend.sh +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/.entry/start_tasks_backend.sh +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/CLAUDE.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/README.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/apps/app_admin.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/apps/app_apps.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/apps/app_models.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/apps/app_urls.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/apps/app_views.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/apps/common_apps.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/apps/common_models.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/config/gunicorn_config.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/config/http.conf +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/core/base_model.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/core/formatter.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/core/logger.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/core/pagination.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/core/response_wrapper.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/core/services/azure/email/backend.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/core/services/azure/email/client.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/core/services/azure/email/notifier.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/core/services/object_storage.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/django_project/asgi.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/django_project/celery.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/django_project/dev_settings.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/django_project/django_settings.txt +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/django_project/management_command.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/django_project/prod_settings.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/django_project/schema.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/django_project/urls.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/django_project/wsgi.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/docker/docker-compose.yml +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/knowledge/knowledge_description.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/knowledge/knowledge_design_pattern.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/knowledge/knowledge_structure.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/root/README.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/root/django_env.txt +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/root/django_requirements.txt +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/root/gitignore.txt +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/drf_structure/templates/root/manage.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/flutter/.gitignore +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/flutter/.knowledge/knowledge_description.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/flutter/.knowledge/knowledge_design_pattern.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/flutter/.knowledge/knowledge_structure.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/flutter/CLAUDE.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/flutter/__init__.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/flutter/analysis_options.yaml +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/flutter/main.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/flutter/pubspec.yaml +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/flutter/structure.json +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/.env.example +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/.gitignore +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/CLAUDE.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/README.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/__init__.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/knowledge/knowledge_description.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/knowledge/knowledge_design_pattern.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/knowledge/knowledge_structure.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/main.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/package.json +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/src/app/globals.css +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/src/app/layout.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/src/app/page.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/src/components/Header.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/src/services/api.ts +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/src/utils/constants.ts +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/structure.json +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/nextjs/tsconfig.json +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/.env.example +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/.gitignore +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/CLAUDE.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/README.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/__init__.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/index.html +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/knowledge/knowledge_description.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/knowledge/knowledge_design_pattern.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/knowledge/knowledge_structure.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/main.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/package.json +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/src/App.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/src/components/ProtectedRoute.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/src/components/Sidebar.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/src/components/TopNav.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/src/context/AuthContext.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/src/context/ThemeContext.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/src/context/WorkspaceContext.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/src/hooks/useApi.ts +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/src/index.css +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/src/layouts/AuthLayout.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/src/layouts/DashboardLayout.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/src/main.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/src/pages/DashboardPage.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/src/pages/auth/LoginPage.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/src/pages/auth/RegisterPage.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/src/services/api.service.ts +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/src/services/base.service.ts +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/structure.json +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/tsconfig.app.json +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/tsconfig.json +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/tsconfig.node.json +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_admin/vite.config.ts +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/CLAUDE.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/__init__.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/index.css +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/index.html +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/knowledge/knowledge_description.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/knowledge/knowledge_design_pattern.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/knowledge/knowledge_structure.md +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/main.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/package.json +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/src/App.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/src/components/Header.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/src/main.tsx +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/src/services/api.ts +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/src/utils/constants.ts +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/structure.json +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/tsconfig.app.json +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/tsconfig.json +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/tsconfig.node.json +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/templates/react_structure/vite.config.ts +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/utils/__init__.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/utils/environment.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc/utils/output.py +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc_dev_kit.egg-info/dependency_links.txt +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc_dev_kit.egg-info/entry_points.txt +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/ntc_dev_kit.egg-info/top_level.txt +0 -0
- {ntc_dev_kit-1.0.3 → ntc_dev_kit-1.0.6}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ntc-dev-kit
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.6
|
|
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
|
|
@@ -26,6 +26,7 @@ Description-Content-Type: text/markdown
|
|
|
26
26
|
License-File: LICENSE
|
|
27
27
|
Requires-Dist: colorama>=0.4.6
|
|
28
28
|
Requires-Dist: pyyaml>=6.0
|
|
29
|
+
Requires-Dist: textual>=0.47.0
|
|
29
30
|
Provides-Extra: dev
|
|
30
31
|
Requires-Dist: build>=1.0; extra == "dev"
|
|
31
32
|
Requires-Dist: twine>=4.0; extra == "dev"
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import os
|
|
3
3
|
import sys
|
|
4
|
-
import msvcrt
|
|
5
4
|
import time
|
|
6
5
|
from colorama import Fore, Back, Style, init
|
|
7
6
|
from ntc.templates.drf_structure.main import init_drf_project, init_drf_project_in_current_dir
|
|
@@ -16,24 +15,8 @@ from ntc.app_creator import create_app_structure
|
|
|
16
15
|
init(autoreset=True)
|
|
17
16
|
|
|
18
17
|
def print_banner():
|
|
19
|
-
"""Display
|
|
20
|
-
print(f""
|
|
21
|
-
{Fore.CYAN}╔{'═' * 75}╗{Style.RESET_ALL}
|
|
22
|
-
{Fore.CYAN}║{' ' * 75}║{Style.RESET_ALL}
|
|
23
|
-
{Fore.CYAN}║{' ' * 25}{Fore.YELLOW}{Style.BRIGHT}███╗ ██╗████████╗ ██████╗{' ' * 23}{Fore.CYAN}║{Style.RESET_ALL}
|
|
24
|
-
{Fore.CYAN}║{' ' * 25}{Fore.YELLOW}{Style.BRIGHT}████╗ ██║╚══██╔══╝██╔════╝{' ' * 23}{Fore.CYAN}║{Style.RESET_ALL}
|
|
25
|
-
{Fore.CYAN}║{' ' * 25}{Fore.YELLOW}{Style.BRIGHT}██╔██╗ ██║ ██║ ██║ {' ' * 23}{Fore.CYAN}║{Style.RESET_ALL}
|
|
26
|
-
{Fore.CYAN}║{' ' * 25}{Fore.YELLOW}{Style.BRIGHT}██║╚██╗██║ ██║ ██║ {' ' * 23}{Fore.CYAN}║{Style.RESET_ALL}
|
|
27
|
-
{Fore.CYAN}║{' ' * 25}{Fore.YELLOW}{Style.BRIGHT}██║ ╚████║ ██║ ╚██████╗{' ' * 23}{Fore.CYAN}║{Style.RESET_ALL}
|
|
28
|
-
{Fore.CYAN}║{' ' * 25}{Fore.YELLOW}{Style.BRIGHT}╚═╝ ╚═══╝ ╚═╝ ╚═════╝{' ' * 23}{Fore.CYAN}║{Style.RESET_ALL}
|
|
29
|
-
{Fore.CYAN}║{' ' * 75}║{Style.RESET_ALL}
|
|
30
|
-
{Fore.CYAN}║{' ' * 24}{Fore.GREEN}{Style.BRIGHT}🚀 NEXENT TOOLKIT CONSOLE 🚀{' ' * 23}{Fore.CYAN}║{Style.RESET_ALL}
|
|
31
|
-
{Fore.CYAN}║{' ' * 75}║{Style.RESET_ALL}
|
|
32
|
-
{Fore.CYAN}║{' ' * 16}{Fore.WHITE}The ultimate toolkit for API-driven development{' ' * 12}{Fore.CYAN}║{Style.RESET_ALL}
|
|
33
|
-
{Fore.CYAN}║{' ' * 75}║{Style.RESET_ALL}
|
|
34
|
-
{Fore.CYAN}║{' ' * 10}{Fore.GREEN}Backend:{Fore.WHITE} Django/DRF, Laravel {Fore.BLUE}Frontend:{Fore.WHITE} React, Angular, Vue {Fore.CYAN}{' ' * 5}║{Style.RESET_ALL}
|
|
35
|
-
{Fore.CYAN}║{' ' * 75}║{Style.RESET_ALL}
|
|
36
|
-
{Fore.CYAN}╚{'═' * 75}╝{Style.RESET_ALL}""")
|
|
18
|
+
"""Display minimal welcome banner."""
|
|
19
|
+
print(f"\n{Fore.WHITE}{Style.BRIGHT} ntc{Style.RESET_ALL} {Fore.LIGHTBLACK_EX}— project scaffolding tool{Style.RESET_ALL}")
|
|
37
20
|
print()
|
|
38
21
|
|
|
39
22
|
def print_welcome_message():
|
|
@@ -229,6 +212,7 @@ def animate_dependency_install(requirements_path=None, pip_command=None, env_typ
|
|
|
229
212
|
def get_key():
|
|
230
213
|
"""Get a single keypress from user."""
|
|
231
214
|
if os.name == 'nt': # Windows
|
|
215
|
+
import msvcrt
|
|
232
216
|
key = msvcrt.getch()
|
|
233
217
|
if key == b'\xe0': # Arrow keys on Windows
|
|
234
218
|
key = msvcrt.getch()
|
|
@@ -703,82 +687,95 @@ def run_doctor():
|
|
|
703
687
|
"""Check setup and fix common issues like PATH configuration."""
|
|
704
688
|
import shutil
|
|
705
689
|
import site
|
|
706
|
-
|
|
690
|
+
|
|
691
|
+
# Nexent brand palette
|
|
692
|
+
DIM = Fore.LIGHTBLACK_EX
|
|
693
|
+
ACCENT = Fore.WHITE
|
|
694
|
+
OK = Fore.GREEN
|
|
695
|
+
WARN = Fore.YELLOW
|
|
696
|
+
ERR = Fore.RED
|
|
697
|
+
BOLD = Style.BRIGHT
|
|
698
|
+
RESET = Style.RESET_ALL
|
|
699
|
+
|
|
700
|
+
def _ok(text):
|
|
701
|
+
print(f" {OK} {text}{RESET}")
|
|
702
|
+
|
|
703
|
+
def _err(text):
|
|
704
|
+
print(f" {ERR} {text}{RESET}")
|
|
705
|
+
|
|
706
|
+
def _warn(text):
|
|
707
|
+
print(f" {WARN} {text}{RESET}")
|
|
708
|
+
|
|
709
|
+
def _dim(text):
|
|
710
|
+
print(f" {DIM}{text}{RESET}")
|
|
707
711
|
|
|
708
712
|
clear_screen()
|
|
709
|
-
|
|
710
|
-
|
|
713
|
+
|
|
714
|
+
# Minimal Nexent header
|
|
715
|
+
print(f"\n{BOLD}{Fore.WHITE} NEXENT{RESET}")
|
|
716
|
+
print(f" {DIM}Future Awaits{RESET}")
|
|
717
|
+
print(f" {DIM}{'─' * 50}{RESET}")
|
|
718
|
+
print(f" {Fore.WHITE}SETUP DIAGNOSTICS{RESET}\n")
|
|
711
719
|
|
|
712
720
|
issues_found = 0
|
|
713
721
|
issues_fixed = 0
|
|
714
722
|
|
|
715
|
-
# 1.
|
|
716
|
-
print(f"
|
|
723
|
+
# 1. Python
|
|
724
|
+
print(f" {Fore.WHITE}Python{RESET}")
|
|
717
725
|
py_version = sys.version_info
|
|
718
726
|
if py_version >= (3, 10):
|
|
719
|
-
|
|
727
|
+
_ok(f"{py_version.major}.{py_version.minor}.{py_version.micro}")
|
|
720
728
|
else:
|
|
721
|
-
|
|
729
|
+
_err(f"{py_version.major}.{py_version.minor} — >= 3.10 required")
|
|
722
730
|
issues_found += 1
|
|
723
731
|
|
|
724
|
-
# 2.
|
|
725
|
-
print(f"\n{Fore.
|
|
732
|
+
# 2. Dependencies
|
|
733
|
+
print(f"\n {Fore.WHITE}Dependencies{RESET}")
|
|
726
734
|
deps_ok = True
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
try:
|
|
735
|
-
import yaml
|
|
736
|
-
print_success("pyyaml installed")
|
|
737
|
-
except ImportError:
|
|
738
|
-
print_error("pyyaml not found")
|
|
739
|
-
deps_ok = False
|
|
740
|
-
|
|
735
|
+
for mod, name in [("colorama", "colorama"), ("yaml", "pyyaml")]:
|
|
736
|
+
try:
|
|
737
|
+
__import__(mod)
|
|
738
|
+
_ok(name)
|
|
739
|
+
except ImportError:
|
|
740
|
+
_err(name)
|
|
741
|
+
deps_ok = False
|
|
741
742
|
if not deps_ok:
|
|
742
743
|
issues_found += 1
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
# 3.
|
|
746
|
-
print(f"\n{Fore.
|
|
747
|
-
|
|
748
|
-
if
|
|
749
|
-
|
|
750
|
-
|
|
744
|
+
_dim(" Run: pip install colorama pyyaml")
|
|
745
|
+
|
|
746
|
+
# 3. Command accessibility
|
|
747
|
+
print(f"\n {Fore.WHITE}Command{RESET}")
|
|
748
|
+
ntc_path = shutil.which("ntc")
|
|
749
|
+
if ntc_path:
|
|
750
|
+
_ok("ntc found")
|
|
751
|
+
_dim(f" {ntc_path}")
|
|
751
752
|
else:
|
|
752
|
-
|
|
753
|
+
_err("ntc not in PATH")
|
|
753
754
|
issues_found += 1
|
|
754
755
|
|
|
755
|
-
# 4.
|
|
756
|
-
print(f"\n{Fore.
|
|
756
|
+
# 4. Scripts directory
|
|
757
|
+
print(f"\n {Fore.WHITE}Scripts Directory{RESET}")
|
|
757
758
|
scripts_dir = os.path.join(site.USER_BASE, "Scripts")
|
|
758
759
|
if os.path.exists(scripts_dir):
|
|
759
|
-
|
|
760
|
+
_ok(scripts_dir)
|
|
760
761
|
else:
|
|
761
|
-
|
|
762
|
-
print_info("Creating Scripts directory...")
|
|
762
|
+
_warn("missing — creating...")
|
|
763
763
|
os.makedirs(scripts_dir, exist_ok=True)
|
|
764
|
-
|
|
764
|
+
_ok("created")
|
|
765
765
|
issues_fixed += 1
|
|
766
766
|
|
|
767
|
-
# 5.
|
|
767
|
+
# 5. PATH
|
|
768
768
|
if os.name == "nt":
|
|
769
|
-
print(f"\n{Fore.
|
|
769
|
+
print(f"\n {Fore.WHITE}PATH{RESET}")
|
|
770
770
|
current_path = os.environ.get("PATH", "")
|
|
771
771
|
if scripts_dir.lower() in current_path.lower():
|
|
772
|
-
|
|
772
|
+
_ok("Scripts directory in PATH")
|
|
773
773
|
else:
|
|
774
|
-
|
|
775
|
-
print_info("Attempting to add to user PATH registry...")
|
|
774
|
+
_warn("Scripts directory not in PATH")
|
|
776
775
|
try:
|
|
777
776
|
import winreg
|
|
778
777
|
with winreg.OpenKey(
|
|
779
|
-
winreg.HKEY_CURRENT_USER,
|
|
780
|
-
"Environment",
|
|
781
|
-
0,
|
|
778
|
+
winreg.HKEY_CURRENT_USER, "Environment", 0,
|
|
782
779
|
winreg.KEY_READ | winreg.KEY_WRITE,
|
|
783
780
|
) as key:
|
|
784
781
|
existing, _ = winreg.QueryValueEx(key, "PATH")
|
|
@@ -786,42 +783,43 @@ def run_doctor():
|
|
|
786
783
|
new_path = f"{existing};{scripts_dir}"
|
|
787
784
|
winreg.SetValueEx(key, "PATH", 0, winreg.REG_EXPAND_SZ, new_path)
|
|
788
785
|
os.environ["PATH"] = new_path
|
|
789
|
-
|
|
786
|
+
_ok("added to registry")
|
|
790
787
|
issues_fixed += 1
|
|
791
788
|
else:
|
|
792
|
-
|
|
789
|
+
_ok("in registry (restart needed)")
|
|
793
790
|
except Exception as e:
|
|
794
|
-
|
|
795
|
-
|
|
791
|
+
_err(f"registry edit failed: {e}")
|
|
792
|
+
_dim(f" Add manually: {scripts_dir}")
|
|
796
793
|
issues_found += 1
|
|
797
794
|
|
|
798
|
-
# 6.
|
|
799
|
-
print(f"\n{Fore.
|
|
795
|
+
# 6. Package version
|
|
796
|
+
print(f"\n {Fore.WHITE}Package{RESET}")
|
|
800
797
|
try:
|
|
801
798
|
import ntc
|
|
802
|
-
|
|
799
|
+
_ok(f"ntc-dev-kit {ntc.__version__}")
|
|
803
800
|
except (ImportError, AttributeError):
|
|
804
|
-
|
|
801
|
+
_err("ntc-dev-kit not installed")
|
|
805
802
|
issues_found += 1
|
|
806
803
|
|
|
807
804
|
# Summary
|
|
808
|
-
print(f"\n{
|
|
805
|
+
print(f"\n {DIM}{'─' * 50}{RESET}")
|
|
809
806
|
if issues_found == 0 and issues_fixed == 0:
|
|
810
|
-
print(f"{
|
|
807
|
+
print(f" {OK}Ready.{RESET}")
|
|
811
808
|
elif issues_fixed > 0:
|
|
812
|
-
print(f"{
|
|
809
|
+
print(f" {OK}Fixed {issues_fixed}.{RESET}")
|
|
813
810
|
if issues_found > 0:
|
|
814
|
-
print(f"{
|
|
815
|
-
|
|
811
|
+
print(f" {WARN}{issues_found} remaining.{RESET}")
|
|
812
|
+
else:
|
|
813
|
+
print(f" {DIM}Restart terminal for changes.{RESET}")
|
|
816
814
|
else:
|
|
817
|
-
print(f"{
|
|
818
|
-
print(f"{
|
|
819
|
-
print(f"{
|
|
815
|
+
print(f" {ERR}{issues_found} issue(s) found.{RESET}")
|
|
816
|
+
print(f" {DIM}Run 'ntc doctor' again after fixing.{RESET}")
|
|
817
|
+
print(f" {DIM}{'─' * 50}{RESET}\n")
|
|
820
818
|
|
|
821
819
|
|
|
822
820
|
def main():
|
|
823
821
|
parser = argparse.ArgumentParser(
|
|
824
|
-
description="
|
|
822
|
+
description="ntc — project scaffolding tool",
|
|
825
823
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
826
824
|
epilog="""
|
|
827
825
|
Examples:
|
|
@@ -833,7 +831,7 @@ Examples:
|
|
|
833
831
|
ntc init --frontend react # Choose React frontend, ask for backend
|
|
834
832
|
ntc compose myproject # Compose full-stack project with multiple components
|
|
835
833
|
ntc start # Start all services from ntc.yml configuration
|
|
836
|
-
ntc create app myapp # Create new Django app
|
|
834
|
+
ntc create app myapp # Create new Django app
|
|
837
835
|
ntc drf init path name # Legacy Django REST Framework initialization
|
|
838
836
|
"""
|
|
839
837
|
)
|
|
@@ -879,6 +877,9 @@ Examples:
|
|
|
879
877
|
# Doctor command for setup diagnostics
|
|
880
878
|
doctor_parser = subparsers.add_parser("doctor", help="Check setup and fix common issues")
|
|
881
879
|
|
|
880
|
+
# TUI command for interactive terminal UI
|
|
881
|
+
tui_parser = subparsers.add_parser("tui", help="Launch interactive terminal UI")
|
|
882
|
+
|
|
882
883
|
args = parser.parse_args()
|
|
883
884
|
|
|
884
885
|
if args.command == "init":
|
|
@@ -928,16 +929,17 @@ Examples:
|
|
|
928
929
|
start_services()
|
|
929
930
|
elif args.command == "doctor":
|
|
930
931
|
run_doctor()
|
|
932
|
+
elif args.command == "tui":
|
|
933
|
+
from ntc.ui.app import run_tui
|
|
934
|
+
run_tui()
|
|
931
935
|
else:
|
|
932
936
|
# Show help if no command provided
|
|
933
937
|
print_banner()
|
|
934
|
-
print(f"{Fore.
|
|
935
|
-
print(f"
|
|
936
|
-
print(f"
|
|
937
|
-
print(f"
|
|
938
|
-
print(f"
|
|
939
|
-
print(f" {Fore.WHITE}• Run {Fore.GREEN}'ntc start'{Style.RESET_ALL} {Fore.WHITE}to start all services{Style.RESET_ALL}")
|
|
940
|
-
print(f" {Fore.WHITE}• Run {Fore.GREEN}'ntc create app <name>'{Style.RESET_ALL} {Fore.WHITE}to add Django apps{Style.RESET_ALL}")
|
|
938
|
+
print(f"\n {Fore.LIGHTBLACK_EX}Quick Start:{Style.RESET_ALL}")
|
|
939
|
+
print(f" {Fore.WHITE}ntc tui{Style.RESET_ALL} {Fore.LIGHTBLACK_EX}interactive terminal UI{Style.RESET_ALL}")
|
|
940
|
+
print(f" {Fore.WHITE}ntc init{Style.RESET_ALL} {Fore.LIGHTBLACK_EX}interactive setup{Style.RESET_ALL}")
|
|
941
|
+
print(f" {Fore.WHITE}ntc init django{Style.RESET_ALL} {Fore.LIGHTBLACK_EX}Django project{Style.RESET_ALL}")
|
|
942
|
+
print(f" {Fore.WHITE}ntc doctor{Style.RESET_ALL} {Fore.LIGHTBLACK_EX}check setup{Style.RESET_ALL}")
|
|
941
943
|
print()
|
|
942
944
|
parser.print_help()
|
|
943
945
|
|
|
@@ -1,11 +1,30 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import sys
|
|
3
3
|
import yaml
|
|
4
|
-
import msvcrt
|
|
5
4
|
import shutil
|
|
6
5
|
from colorama import Fore, Style
|
|
7
6
|
from ntc.utils.output import print_success, print_error, print_warning, print_info
|
|
8
7
|
|
|
8
|
+
|
|
9
|
+
def _getch():
|
|
10
|
+
"""Cross-platform single character input."""
|
|
11
|
+
if os.name == 'nt':
|
|
12
|
+
import msvcrt
|
|
13
|
+
return msvcrt.getch()
|
|
14
|
+
else:
|
|
15
|
+
import termios
|
|
16
|
+
import tty
|
|
17
|
+
fd = sys.stdin.fileno()
|
|
18
|
+
old = termios.tcgetattr(fd)
|
|
19
|
+
try:
|
|
20
|
+
tty.setraw(fd)
|
|
21
|
+
ch = sys.stdin.read(1)
|
|
22
|
+
if ch == '\x1b':
|
|
23
|
+
ch += sys.stdin.read(2)
|
|
24
|
+
return ch.encode('utf-8')
|
|
25
|
+
finally:
|
|
26
|
+
termios.tcsetattr(fd, termios.TCSADRAIN, old)
|
|
27
|
+
|
|
9
28
|
def is_directory_empty(directory):
|
|
10
29
|
"""Check if a directory is empty (ignoring hidden files)."""
|
|
11
30
|
if not os.path.exists(directory):
|
|
@@ -45,9 +64,9 @@ def get_project_choices():
|
|
|
45
64
|
print(f"{prefix}[{checkmark}] {label}")
|
|
46
65
|
|
|
47
66
|
# Get key press
|
|
48
|
-
key =
|
|
49
|
-
|
|
50
|
-
if key == b'\r': # Enter key
|
|
67
|
+
key = _getch()
|
|
68
|
+
|
|
69
|
+
if key == b'\r' or key == b'\n': # Enter key
|
|
51
70
|
selected_projects = []
|
|
52
71
|
for option in options:
|
|
53
72
|
if option["selected"]:
|
|
@@ -85,12 +104,16 @@ def get_project_choices():
|
|
|
85
104
|
elif all(options[i]["selected"] for i in range(len(options) - 1)):
|
|
86
105
|
options[-1]["selected"] = True
|
|
87
106
|
|
|
88
|
-
elif key == b'\x00' or key == b'\xe0': # Arrow key prefix
|
|
89
|
-
key =
|
|
107
|
+
elif key == b'\x00' or key == b'\xe0': # Arrow key prefix (Windows)
|
|
108
|
+
key = _getch()
|
|
90
109
|
if key == b'H': # Up arrow
|
|
91
110
|
current_index = (current_index - 1) % len(options)
|
|
92
111
|
elif key == b'P': # Down arrow
|
|
93
112
|
current_index = (current_index + 1) % len(options)
|
|
113
|
+
elif key == b'\x1b[A': # Up arrow (Unix)
|
|
114
|
+
current_index = (current_index - 1) % len(options)
|
|
115
|
+
elif key == b'\x1b[B': # Down arrow (Unix)
|
|
116
|
+
current_index = (current_index + 1) % len(options)
|
|
94
117
|
|
|
95
118
|
def create_ntc_yml(project_name, projects, root_dir):
|
|
96
119
|
"""Create ntc.yml configuration file."""
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Development launcher for ntc.
|
|
2
|
+
|
|
3
|
+
Run directly without pip install:
|
|
4
|
+
python ntc/main.py
|
|
5
|
+
python ntc/main.py doctor
|
|
6
|
+
"""
|
|
7
|
+
import sys
|
|
8
|
+
import os
|
|
9
|
+
import importlib.util
|
|
10
|
+
import pkgutil
|
|
11
|
+
|
|
12
|
+
this_dir = os.path.dirname(os.path.abspath(__file__))
|
|
13
|
+
|
|
14
|
+
# Register 'ntc' package pointing to this directory
|
|
15
|
+
spec = importlib.util.spec_from_file_location("ntc", os.path.join(this_dir, "__init__.py"))
|
|
16
|
+
ntc = importlib.util.module_from_spec(spec)
|
|
17
|
+
ntc.__path__ = [this_dir]
|
|
18
|
+
sys.modules["ntc"] = ntc
|
|
19
|
+
spec.loader.exec_module(ntc)
|
|
20
|
+
|
|
21
|
+
# Only register modules cli_enhanced actually imports
|
|
22
|
+
# Skip template directories — those .py files are project templates, not importable code
|
|
23
|
+
modules_to_register = [
|
|
24
|
+
("ntc.cli_enhanced", os.path.join(this_dir, "cli_enhanced.py")),
|
|
25
|
+
("ntc.cli", os.path.join(this_dir, "cli.py")),
|
|
26
|
+
("ntc.app_creator", os.path.join(this_dir, "app_creator.py")),
|
|
27
|
+
("ntc.utils.output", os.path.join(this_dir, "utils", "output.py")),
|
|
28
|
+
("ntc.utils.environment", os.path.join(this_dir, "utils", "environment.py")),
|
|
29
|
+
("ntc.templates.drf_structure", os.path.join(this_dir, "templates", "drf_structure", "__init__.py")),
|
|
30
|
+
("ntc.templates.drf_structure.main", os.path.join(this_dir, "templates", "drf_structure", "main.py")),
|
|
31
|
+
("ntc.templates.react_structure", os.path.join(this_dir, "templates", "react_structure", "__init__.py")),
|
|
32
|
+
("ntc.templates.react_structure.main", os.path.join(this_dir, "templates", "react_structure", "main.py")),
|
|
33
|
+
("ntc.templates.react_admin", os.path.join(this_dir, "templates", "react_admin", "__init__.py")),
|
|
34
|
+
("ntc.templates.react_admin.main", os.path.join(this_dir, "templates", "react_admin", "main.py")),
|
|
35
|
+
("ntc.templates.nextjs", os.path.join(this_dir, "templates", "nextjs", "__init__.py")),
|
|
36
|
+
("ntc.templates.nextjs.main", os.path.join(this_dir, "templates", "nextjs", "main.py")),
|
|
37
|
+
("ntc.templates.flutter", os.path.join(this_dir, "templates", "flutter", "__init__.py")),
|
|
38
|
+
("ntc.templates.flutter.main", os.path.join(this_dir, "templates", "flutter", "main.py")),
|
|
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")),
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
for modname, file_path in modules_to_register:
|
|
45
|
+
if not os.path.exists(file_path):
|
|
46
|
+
continue
|
|
47
|
+
spec = importlib.util.spec_from_file_location(modname, file_path)
|
|
48
|
+
mod = importlib.util.module_from_spec(spec)
|
|
49
|
+
sys.modules[modname] = mod
|
|
50
|
+
spec.loader.exec_module(mod)
|
|
51
|
+
|
|
52
|
+
# Run the CLI
|
|
53
|
+
from ntc.cli_enhanced import main
|
|
54
|
+
|
|
55
|
+
if __name__ == "__main__":
|
|
56
|
+
main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Terminal UI for ntc."""
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"""Textual TUI for ntc.
|
|
2
|
+
|
|
3
|
+
Run:
|
|
4
|
+
python -m ntc.ui.app
|
|
5
|
+
"""
|
|
6
|
+
from textual.app import App, ComposeResult
|
|
7
|
+
from textual.containers import Horizontal, Vertical
|
|
8
|
+
from textual.widgets import Static, ListView, ListItem, Header, Footer, Label
|
|
9
|
+
from textual.binding import Binding
|
|
10
|
+
from textual.screen import Screen
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class MenuScreen(Screen):
|
|
14
|
+
"""Main menu screen with sidebar navigation."""
|
|
15
|
+
|
|
16
|
+
BINDINGS = [
|
|
17
|
+
Binding("q", "quit", "Quit"),
|
|
18
|
+
Binding("escape", "quit", "Quit"),
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
CSS = """
|
|
22
|
+
Screen {
|
|
23
|
+
align: center middle;
|
|
24
|
+
}
|
|
25
|
+
#sidebar {
|
|
26
|
+
width: 24;
|
|
27
|
+
height: 100%;
|
|
28
|
+
background: $surface-darken-1;
|
|
29
|
+
padding: 1;
|
|
30
|
+
}
|
|
31
|
+
#content {
|
|
32
|
+
width: 1fr;
|
|
33
|
+
height: 100%;
|
|
34
|
+
padding: 2 4;
|
|
35
|
+
}
|
|
36
|
+
#title {
|
|
37
|
+
text-align: center;
|
|
38
|
+
height: auto;
|
|
39
|
+
padding: 1;
|
|
40
|
+
color: $text;
|
|
41
|
+
text-style: bold;
|
|
42
|
+
}
|
|
43
|
+
#tagline {
|
|
44
|
+
text-align: center;
|
|
45
|
+
height: auto;
|
|
46
|
+
padding-bottom: 1;
|
|
47
|
+
color: $text-muted;
|
|
48
|
+
}
|
|
49
|
+
ListView {
|
|
50
|
+
height: auto;
|
|
51
|
+
border: none;
|
|
52
|
+
background: transparent;
|
|
53
|
+
}
|
|
54
|
+
ListView > ListItem {
|
|
55
|
+
padding: 0 1;
|
|
56
|
+
height: auto;
|
|
57
|
+
}
|
|
58
|
+
ListView > ListItem.--highlight {
|
|
59
|
+
background: $primary-darken-2;
|
|
60
|
+
color: $text;
|
|
61
|
+
text-style: bold;
|
|
62
|
+
}
|
|
63
|
+
#info {
|
|
64
|
+
color: $text-muted;
|
|
65
|
+
text-style: dim;
|
|
66
|
+
margin-top: 1;
|
|
67
|
+
}
|
|
68
|
+
.label {
|
|
69
|
+
color: $text;
|
|
70
|
+
text-style: bold;
|
|
71
|
+
margin-top: 1;
|
|
72
|
+
}
|
|
73
|
+
.desc {
|
|
74
|
+
color: $text-muted;
|
|
75
|
+
margin-left: 2;
|
|
76
|
+
}
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
def compose(self) -> ComposeResult:
|
|
80
|
+
with Horizontal():
|
|
81
|
+
with Vertical(id="sidebar"):
|
|
82
|
+
yield Static("ntc", id="title")
|
|
83
|
+
yield Static("project scaffolding", id="tagline")
|
|
84
|
+
yield ListView(
|
|
85
|
+
ListItem(Label("init")),
|
|
86
|
+
ListItem(Label("create app")),
|
|
87
|
+
ListItem(Label("compose")),
|
|
88
|
+
ListItem(Label("start")),
|
|
89
|
+
ListItem(Label("doctor")),
|
|
90
|
+
ListItem(Label("quit")),
|
|
91
|
+
)
|
|
92
|
+
yield Static("↑↓ navigate enter run", id="info")
|
|
93
|
+
with Vertical(id="content"):
|
|
94
|
+
yield Static(id="detail")
|
|
95
|
+
|
|
96
|
+
def on_mount(self) -> None:
|
|
97
|
+
self.query_one(ListView).focus()
|
|
98
|
+
self._update_detail(0)
|
|
99
|
+
|
|
100
|
+
def on_list_view_highlighted(self, event: ListView.Highlighted) -> None:
|
|
101
|
+
list_view = self.query_one(ListView)
|
|
102
|
+
if list_view.highlighted_child is not None:
|
|
103
|
+
self._update_detail(list_view.index)
|
|
104
|
+
|
|
105
|
+
def on_list_view_selected(self, event: ListView.Selected) -> None:
|
|
106
|
+
list_view = self.query_one(ListView)
|
|
107
|
+
self._run_command(list_view.index)
|
|
108
|
+
|
|
109
|
+
def _update_detail(self, index: int) -> None:
|
|
110
|
+
details = [
|
|
111
|
+
("init", "Interactive project setup.\nChoose backend, frontend, and configure your stack."),
|
|
112
|
+
("create app", "Generate a new app inside an existing project.\nCreates models, views, serializers, and URLs."),
|
|
113
|
+
("compose", "Build a full-stack project from a YAML spec.\nOrchestrates multiple services."),
|
|
114
|
+
("start", "Start all services defined in ntc.yml.\nRuns docker-compose or local processes."),
|
|
115
|
+
("doctor", "Check setup and fix PATH issues.\nEnsures the CLI is properly configured."),
|
|
116
|
+
("quit", "Exit the TUI and return to the shell."),
|
|
117
|
+
]
|
|
118
|
+
label, desc = details[index]
|
|
119
|
+
self.query_one("#detail", Static).update(
|
|
120
|
+
f"[b]{label}[/b]\n\n{desc}"
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
def _run_command(self, index: int) -> None:
|
|
124
|
+
commands = ["init", "create_app", "compose", "start", "doctor", "quit"]
|
|
125
|
+
cmd = commands[index]
|
|
126
|
+
if cmd == "quit":
|
|
127
|
+
self.app.exit()
|
|
128
|
+
return
|
|
129
|
+
|
|
130
|
+
# Run the command and show result
|
|
131
|
+
detail = self.query_one("#detail", Static)
|
|
132
|
+
detail.update(f"[b]{cmd}[/b]\n\n[yellow]Running...[/yellow]")
|
|
133
|
+
|
|
134
|
+
try:
|
|
135
|
+
if cmd == "init":
|
|
136
|
+
from ntc.cli_enhanced import interactive_init
|
|
137
|
+
self.app.exit()
|
|
138
|
+
interactive_init()
|
|
139
|
+
elif cmd == "create_app":
|
|
140
|
+
from ntc.cli_enhanced import create_app_structure
|
|
141
|
+
# Would need input; show placeholder
|
|
142
|
+
detail.update("[b]create app[/b]\n\nRun from shell:\n ntc create app <name>")
|
|
143
|
+
elif cmd == "compose":
|
|
144
|
+
from ntc.cli_enhanced import compose_project
|
|
145
|
+
self.app.exit()
|
|
146
|
+
compose_project("myproject")
|
|
147
|
+
elif cmd == "start":
|
|
148
|
+
from ntc.cli_enhanced import start_services
|
|
149
|
+
self.app.exit()
|
|
150
|
+
start_services()
|
|
151
|
+
elif cmd == "doctor":
|
|
152
|
+
from ntc.cli_enhanced import run_doctor
|
|
153
|
+
self.app.exit()
|
|
154
|
+
run_doctor()
|
|
155
|
+
except Exception as e:
|
|
156
|
+
detail.update(f"[b]{cmd}[/b]\n\n[red]Error: {e}[/red]")
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class NtcTui(App):
|
|
160
|
+
"""Main TUI application."""
|
|
161
|
+
|
|
162
|
+
CSS = """
|
|
163
|
+
App {
|
|
164
|
+
background: $surface-darken-2;
|
|
165
|
+
}
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
def on_mount(self) -> None:
|
|
169
|
+
self.push_screen(MenuScreen())
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def run_tui() -> None:
|
|
173
|
+
"""Entry point for the TUI."""
|
|
174
|
+
app = NtcTui()
|
|
175
|
+
app.run()
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
if __name__ == "__main__":
|
|
179
|
+
run_tui()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ntc-dev-kit
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.6
|
|
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
|
|
@@ -26,6 +26,7 @@ Description-Content-Type: text/markdown
|
|
|
26
26
|
License-File: LICENSE
|
|
27
27
|
Requires-Dist: colorama>=0.4.6
|
|
28
28
|
Requires-Dist: pyyaml>=6.0
|
|
29
|
+
Requires-Dist: textual>=0.47.0
|
|
29
30
|
Provides-Extra: dev
|
|
30
31
|
Requires-Dist: build>=1.0; extra == "dev"
|
|
31
32
|
Requires-Dist: twine>=4.0; extra == "dev"
|
|
@@ -8,6 +8,7 @@ ntc/__init__.py
|
|
|
8
8
|
ntc/app_creator.py
|
|
9
9
|
ntc/cli.py
|
|
10
10
|
ntc/cli_enhanced.py
|
|
11
|
+
ntc/main.py
|
|
11
12
|
ntc/composer/__init__.py
|
|
12
13
|
ntc/composer/main.py
|
|
13
14
|
ntc/deployment/__init__.py
|
|
@@ -143,6 +144,8 @@ ntc/templates/react_structure/src/main.tsx
|
|
|
143
144
|
ntc/templates/react_structure/src/components/Header.tsx
|
|
144
145
|
ntc/templates/react_structure/src/services/api.ts
|
|
145
146
|
ntc/templates/react_structure/src/utils/constants.ts
|
|
147
|
+
ntc/ui/__init__.py
|
|
148
|
+
ntc/ui/app.py
|
|
146
149
|
ntc/utils/__init__.py
|
|
147
150
|
ntc/utils/environment.py
|
|
148
151
|
ntc/utils/output.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ntc-dev-kit"
|
|
7
|
-
version = "1.0.
|
|
7
|
+
version = "1.0.6"
|
|
8
8
|
description = "Nexent Toolkit Console - A CLI tool for scaffolding Django REST Framework, React, Next.js, and Flutter projects"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -27,6 +27,7 @@ requires-python = ">=3.10"
|
|
|
27
27
|
dependencies = [
|
|
28
28
|
"colorama>=0.4.6",
|
|
29
29
|
"pyyaml>=6.0",
|
|
30
|
+
"textual>=0.47.0",
|
|
30
31
|
]
|
|
31
32
|
|
|
32
33
|
[project.optional-dependencies]
|