createsonline 0.1.26__py3-none-any.whl

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 (152) hide show
  1. createsonline/__init__.py +46 -0
  2. createsonline/admin/__init__.py +7 -0
  3. createsonline/admin/content.py +526 -0
  4. createsonline/admin/crud.py +805 -0
  5. createsonline/admin/field_builder.py +559 -0
  6. createsonline/admin/integration.py +482 -0
  7. createsonline/admin/interface.py +2562 -0
  8. createsonline/admin/model_creator.py +513 -0
  9. createsonline/admin/model_manager.py +388 -0
  10. createsonline/admin/modern_dashboard.py +498 -0
  11. createsonline/admin/permissions.py +264 -0
  12. createsonline/admin/user_forms.py +594 -0
  13. createsonline/ai/__init__.py +202 -0
  14. createsonline/ai/fields.py +1226 -0
  15. createsonline/ai/orm.py +325 -0
  16. createsonline/ai/services.py +1244 -0
  17. createsonline/app.py +506 -0
  18. createsonline/auth/__init__.py +8 -0
  19. createsonline/auth/management.py +228 -0
  20. createsonline/auth/models.py +552 -0
  21. createsonline/cli/__init__.py +5 -0
  22. createsonline/cli/commands/__init__.py +122 -0
  23. createsonline/cli/commands/database.py +416 -0
  24. createsonline/cli/commands/info.py +173 -0
  25. createsonline/cli/commands/initdb.py +218 -0
  26. createsonline/cli/commands/project.py +545 -0
  27. createsonline/cli/commands/serve.py +173 -0
  28. createsonline/cli/commands/shell.py +93 -0
  29. createsonline/cli/commands/users.py +148 -0
  30. createsonline/cli/main.py +2041 -0
  31. createsonline/cli/manage.py +274 -0
  32. createsonline/config/__init__.py +9 -0
  33. createsonline/config/app.py +2577 -0
  34. createsonline/config/database.py +179 -0
  35. createsonline/config/docs.py +384 -0
  36. createsonline/config/errors.py +160 -0
  37. createsonline/config/orm.py +43 -0
  38. createsonline/config/request.py +93 -0
  39. createsonline/config/settings.py +176 -0
  40. createsonline/data/__init__.py +23 -0
  41. createsonline/data/dataframe.py +925 -0
  42. createsonline/data/io.py +453 -0
  43. createsonline/data/series.py +557 -0
  44. createsonline/database/__init__.py +60 -0
  45. createsonline/database/abstraction.py +440 -0
  46. createsonline/database/assistant.py +585 -0
  47. createsonline/database/fields.py +442 -0
  48. createsonline/database/migrations.py +132 -0
  49. createsonline/database/models.py +604 -0
  50. createsonline/database.py +438 -0
  51. createsonline/http/__init__.py +28 -0
  52. createsonline/http/client.py +535 -0
  53. createsonline/ml/__init__.py +55 -0
  54. createsonline/ml/classification.py +552 -0
  55. createsonline/ml/clustering.py +680 -0
  56. createsonline/ml/metrics.py +542 -0
  57. createsonline/ml/neural.py +560 -0
  58. createsonline/ml/preprocessing.py +784 -0
  59. createsonline/ml/regression.py +501 -0
  60. createsonline/performance/__init__.py +19 -0
  61. createsonline/performance/cache.py +444 -0
  62. createsonline/performance/compression.py +335 -0
  63. createsonline/performance/core.py +419 -0
  64. createsonline/project_init.py +789 -0
  65. createsonline/routing.py +528 -0
  66. createsonline/security/__init__.py +34 -0
  67. createsonline/security/core.py +811 -0
  68. createsonline/security/encryption.py +349 -0
  69. createsonline/server.py +295 -0
  70. createsonline/static/css/admin.css +263 -0
  71. createsonline/static/css/common.css +358 -0
  72. createsonline/static/css/dashboard.css +89 -0
  73. createsonline/static/favicon.ico +0 -0
  74. createsonline/static/icons/icon-128x128.png +0 -0
  75. createsonline/static/icons/icon-128x128.webp +0 -0
  76. createsonline/static/icons/icon-16x16.png +0 -0
  77. createsonline/static/icons/icon-16x16.webp +0 -0
  78. createsonline/static/icons/icon-180x180.png +0 -0
  79. createsonline/static/icons/icon-180x180.webp +0 -0
  80. createsonline/static/icons/icon-192x192.png +0 -0
  81. createsonline/static/icons/icon-192x192.webp +0 -0
  82. createsonline/static/icons/icon-256x256.png +0 -0
  83. createsonline/static/icons/icon-256x256.webp +0 -0
  84. createsonline/static/icons/icon-32x32.png +0 -0
  85. createsonline/static/icons/icon-32x32.webp +0 -0
  86. createsonline/static/icons/icon-384x384.png +0 -0
  87. createsonline/static/icons/icon-384x384.webp +0 -0
  88. createsonline/static/icons/icon-48x48.png +0 -0
  89. createsonline/static/icons/icon-48x48.webp +0 -0
  90. createsonline/static/icons/icon-512x512.png +0 -0
  91. createsonline/static/icons/icon-512x512.webp +0 -0
  92. createsonline/static/icons/icon-64x64.png +0 -0
  93. createsonline/static/icons/icon-64x64.webp +0 -0
  94. createsonline/static/image/android-chrome-192x192.png +0 -0
  95. createsonline/static/image/android-chrome-512x512.png +0 -0
  96. createsonline/static/image/apple-touch-icon.png +0 -0
  97. createsonline/static/image/favicon-16x16.png +0 -0
  98. createsonline/static/image/favicon-32x32.png +0 -0
  99. createsonline/static/image/favicon.ico +0 -0
  100. createsonline/static/image/favicon.svg +17 -0
  101. createsonline/static/image/icon-128x128.png +0 -0
  102. createsonline/static/image/icon-128x128.webp +0 -0
  103. createsonline/static/image/icon-16x16.png +0 -0
  104. createsonline/static/image/icon-16x16.webp +0 -0
  105. createsonline/static/image/icon-180x180.png +0 -0
  106. createsonline/static/image/icon-180x180.webp +0 -0
  107. createsonline/static/image/icon-192x192.png +0 -0
  108. createsonline/static/image/icon-192x192.webp +0 -0
  109. createsonline/static/image/icon-256x256.png +0 -0
  110. createsonline/static/image/icon-256x256.webp +0 -0
  111. createsonline/static/image/icon-32x32.png +0 -0
  112. createsonline/static/image/icon-32x32.webp +0 -0
  113. createsonline/static/image/icon-384x384.png +0 -0
  114. createsonline/static/image/icon-384x384.webp +0 -0
  115. createsonline/static/image/icon-48x48.png +0 -0
  116. createsonline/static/image/icon-48x48.webp +0 -0
  117. createsonline/static/image/icon-512x512.png +0 -0
  118. createsonline/static/image/icon-512x512.webp +0 -0
  119. createsonline/static/image/icon-64x64.png +0 -0
  120. createsonline/static/image/icon-64x64.webp +0 -0
  121. createsonline/static/image/logo-header-h100.png +0 -0
  122. createsonline/static/image/logo-header-h100.webp +0 -0
  123. createsonline/static/image/logo-header-h200@2x.png +0 -0
  124. createsonline/static/image/logo-header-h200@2x.webp +0 -0
  125. createsonline/static/image/logo.png +0 -0
  126. createsonline/static/js/admin.js +274 -0
  127. createsonline/static/site.webmanifest +35 -0
  128. createsonline/static/templates/admin/base.html +87 -0
  129. createsonline/static/templates/admin/dashboard.html +217 -0
  130. createsonline/static/templates/admin/model_form.html +270 -0
  131. createsonline/static/templates/admin/model_list.html +202 -0
  132. createsonline/static/test_script.js +15 -0
  133. createsonline/static/test_styles.css +59 -0
  134. createsonline/static_files.py +365 -0
  135. createsonline/templates/404.html +100 -0
  136. createsonline/templates/admin_login.html +169 -0
  137. createsonline/templates/base.html +102 -0
  138. createsonline/templates/index.html +151 -0
  139. createsonline/templates.py +205 -0
  140. createsonline/testing.py +322 -0
  141. createsonline/utils.py +448 -0
  142. createsonline/validation/__init__.py +49 -0
  143. createsonline/validation/fields.py +598 -0
  144. createsonline/validation/models.py +504 -0
  145. createsonline/validation/validators.py +561 -0
  146. createsonline/views.py +184 -0
  147. createsonline-0.1.26.dist-info/METADATA +46 -0
  148. createsonline-0.1.26.dist-info/RECORD +152 -0
  149. createsonline-0.1.26.dist-info/WHEEL +5 -0
  150. createsonline-0.1.26.dist-info/entry_points.txt +2 -0
  151. createsonline-0.1.26.dist-info/licenses/LICENSE +21 -0
  152. createsonline-0.1.26.dist-info/top_level.txt +1 -0
@@ -0,0 +1,2041 @@
1
+ # createsonline/cli/main.py
2
+ """
3
+ CREATESONLINE Dynamic CLI - Revolutionary Natural Language Interface
4
+
5
+ The world's first AI-native framework CLI that understands natural language.
6
+ No rigid commands - just express your intent naturally!
7
+
8
+ Examples:
9
+ createsonline "create new AI-powered project called myapp"
10
+ createsonline "start development server on port 8000"
11
+ createsonline "show comprehensive framework information"
12
+ createsonline "create superuser admin with full access"
13
+
14
+ Zero external dependencies - pure Python implementation.
15
+ """
16
+
17
+ import logging
18
+ import sys
19
+ import os
20
+ import re
21
+ import subprocess
22
+ import asyncio
23
+ from pathlib import Path
24
+ from typing import Dict, List, Any, Optional, Tuple
25
+
26
+ # Python 3.9-3.13 support check
27
+ if sys.version_info < (3, 9) or sys.version_info >= (3, 14):
28
+ logging.getLogger("createsonline.cli").error("Unsupported Python version")
29
+ sys.exit(1)
30
+
31
+ # Optional rich imports with internal fallbacks
32
+ try:
33
+ from rich.console import Console
34
+ from rich.panel import Panel
35
+ from rich.table import Table
36
+ from rich.progress import track
37
+ from rich.prompt import Prompt, Confirm
38
+ RICH_AVAILABLE = True
39
+ console = Console()
40
+ except ImportError:
41
+ RICH_AVAILABLE = False
42
+ console = None
43
+
44
+ # Optional typer import with internal fallback
45
+ try:
46
+ import typer
47
+ TYPER_AVAILABLE = True
48
+ except ImportError:
49
+ TYPER_AVAILABLE = False
50
+ # CRITICAL FIX: Create typer stub to prevent crashes
51
+ import types
52
+ typer = types.ModuleType("typer")
53
+
54
+ # Add stub attributes to prevent AttributeError
55
+ def _typer_stub(*args, **kwargs):
56
+ raise RuntimeError("Typer not installed. Install with: pip install typer")
57
+
58
+ typer.Typer = _typer_stub
59
+ typer.Argument = _typer_stub
60
+ typer.Option = _typer_stub
61
+ typer.Context = _typer_stub
62
+ typer.Exit = SystemExit
63
+
64
+
65
+ class CreatesonlineInternalConsole:
66
+ """Internal console implementation"""
67
+
68
+ def __init__(self):
69
+ self.width = 80
70
+
71
+ def print(self, text: str, style: str = ""):
72
+ """Print with optional styling"""
73
+ # Simple color codes for terminals that support them
74
+ colors = {
75
+ "red": "\033[91m",
76
+ "green": "\033[92m",
77
+ "yellow": "\033[93m",
78
+ "blue": "\033[94m",
79
+ "cyan": "\033[96m",
80
+ "white": "\033[97m",
81
+ "bold": "\033[1m",
82
+ "reset": "\033[0m"
83
+ }
84
+
85
+ if "red" in style:
86
+ print(f"{colors.get('red', '')}{text}{colors.get('reset', '')}")
87
+ elif "green" in style:
88
+ print(f"{colors.get('green', '')}{text}{colors.get('reset', '')}")
89
+ elif "yellow" in style:
90
+ print(f"{colors.get('yellow', '')}{text}{colors.get('reset', '')}")
91
+ elif "blue" in style:
92
+ print(f"{colors.get('blue', '')}{text}{colors.get('reset', '')}")
93
+ elif "cyan" in style:
94
+ print(f"{colors.get('cyan', '')}{text}{colors.get('reset', '')}")
95
+ elif "bold" in style:
96
+ print(f"{colors.get('bold', '')}{text}{colors.get('reset', '')}")
97
+ else:
98
+ print(text)
99
+
100
+ def panel(self, text: str, title: str = "", border_style: str = ""):
101
+ """Create a simple panel"""
102
+ lines = text.split('\n')
103
+ max_width = max(len(line) for line in lines) if lines else 0
104
+ panel_width = max(max_width + 4, len(title) + 4, 40)
105
+
106
+ # Top border
107
+ if title:
108
+ title_line = f"┌─ {title} " + "─" * (panel_width - len(title) - 4) + "┐"
109
+ else:
110
+ title_line = "┌" + "─" * (panel_width - 2) + "┐"
111
+
112
+ print(title_line)
113
+
114
+ # Content
115
+ for line in lines:
116
+ padded_line = f"│ {line:<{panel_width-4}} │"
117
+ print(padded_line)
118
+
119
+ # Bottom border
120
+ print("└" + "─" * (panel_width - 2) + "┘")
121
+
122
+ def table(self, data: List[List[str]], headers: List[str] = None):
123
+ """Create a simple table"""
124
+ if not data:
125
+ return
126
+
127
+ # Calculate column widths
128
+ if headers:
129
+ all_rows = [headers] + data
130
+ else:
131
+ all_rows = data
132
+
133
+ col_widths = []
134
+ for col_idx in range(len(all_rows[0])):
135
+ max_width = max(len(str(row[col_idx])) for row in all_rows if col_idx < len(row))
136
+ col_widths.append(max_width + 2)
137
+
138
+ # Print headers
139
+ if headers:
140
+ header_line = "|".join(f" {headers[i]:<{col_widths[i]-1}}" for i in range(len(headers)))
141
+ print(header_line)
142
+ print("-" * len(header_line))
143
+
144
+ # Print data
145
+ for row in data:
146
+ row_line = "|".join(f" {str(row[i]):<{col_widths[i]-1}}" if i < len(row) else f" {'':<{col_widths[i]-1}}" for i in range(len(col_widths)))
147
+ print(row_line)
148
+
149
+
150
+ class CreatesonlineNaturalLanguageCLI:
151
+ """
152
+ Revolutionary Natural Language CLI for CREATESONLINE
153
+
154
+ Understands user intent through natural language processing
155
+ without external NLP dependencies - pure Python pattern matching.
156
+ """
157
+
158
+ def __init__(self):
159
+ self.console = console if RICH_AVAILABLE else CreatesonlineInternalConsole()
160
+ self.commands_db = self._build_commands_database()
161
+ self.context = {
162
+ "last_command": None,
163
+ "current_directory": os.getcwd(),
164
+ "framework_version": "0.1.6"
165
+ }
166
+
167
+ def _build_commands_database(self) -> Dict[str, Dict[str, Any]]:
168
+ """Build natural language commands database"""
169
+ return {
170
+ # Project Management
171
+ "create_project": {
172
+ "patterns": [
173
+ r"create\s+(new\s+)?project\s+(called\s+|named\s+)?(\w+)",
174
+ r"new\s+project\s+(\w+)",
175
+ r"make\s+(a\s+)?project\s+(\w+)",
176
+ r"generate\s+project\s+(\w+)",
177
+ r"init\s+project\s+(\w+)"
178
+ ],
179
+ "handler": "handle_create_project",
180
+ "description": "Create a new CREATESONLINE project",
181
+ "examples": [
182
+ 'create new project called myapp',
183
+ 'new project blog',
184
+ 'make a project ecommerce'
185
+ ]
186
+ },
187
+
188
+ # Project Initialization
189
+ "init_project": {
190
+ "patterns": [
191
+ r"^init(ialize)?\s*$",
192
+ r"^init(ialize)?\s+project\s*$",
193
+ r"^setup\s+project\s*$",
194
+ r"^bootstrap\s+project\s*$"
195
+ ],
196
+ "handler": "handle_init_project",
197
+ "description": "Initialize project structure in current directory",
198
+ "examples": [
199
+ 'init',
200
+ 'initialize project',
201
+ 'setup project'
202
+ ]
203
+ },
204
+
205
+ # Server Management
206
+ "start_server": {
207
+ "patterns": [
208
+ # FIXED: Added word boundaries and more specific patterns
209
+ r"^start\s+(development|dev)\s+server(\s+on\s+port\s+(\d+))?\b",
210
+ r"^run\s+(dev|development)\s+server(\s+port\s+(\d+))?\b",
211
+ r"^serve\s+dev(elopment)?(\s+on\s+(\d+))?\b",
212
+ r"^dev\s+server(\s+port\s+(\d+))?\b"
213
+ ],
214
+ "handler": "handle_start_server",
215
+ "description": "Start development server",
216
+ "examples": [
217
+ 'start development server',
218
+ 'start server on port 8000',
219
+ 'run dev server with hot reload',
220
+ 'serve development on port 8080'
221
+ ]
222
+ },
223
+
224
+ # Production Server
225
+ "production_server": {
226
+ "patterns": [
227
+ # FIXED: More specific production patterns
228
+ r"^start\s+production\s+server(\s+with\s+(\d+)\s+workers)?\b",
229
+ r"^run\s+prod(uction)?\s+server(\s+(\d+)\s+workers)?\b",
230
+ r"^production\s+mode(\s+(\d+)\s+workers)?\b",
231
+ r"^serve\s+production(\s+(\d+)\s+workers)?\b"
232
+ ],
233
+ "handler": "handle_production_server",
234
+ "description": "Start production server",
235
+ "examples": [
236
+ 'start production server',
237
+ 'run prod server with 4 workers',
238
+ 'production mode'
239
+ ]
240
+ },
241
+
242
+ # Information Commands
243
+ "framework_info": {
244
+ "patterns": [
245
+ # FIXED: More specific info patterns to avoid conflicts
246
+ r"^show\s+(me\s+)?(framework\s+)?info(rmation)?\b",
247
+ r"^what\s+is\s+createsonline\b",
248
+ r"^framework\s+details\b",
249
+ r"^info\s*$", # Exact match for just "info"
250
+ r"^about\s+(createsonline|framework)\b"
251
+ ],
252
+ "handler": "handle_framework_info",
253
+ "description": "Show framework information",
254
+ "examples": [
255
+ 'show me framework info',
256
+ 'what is createsonline',
257
+ 'info'
258
+ ]
259
+ },
260
+
261
+ # Version Information
262
+ "version": {
263
+ "patterns": [
264
+ # FIXED: Exact version patterns to avoid matching "conversion" etc
265
+ r"^version\s*$",
266
+ r"^show\s+version\b",
267
+ r"^what\s+version\b",
268
+ r"^\-\-version\s*$",
269
+ r"^v\s*$" # Just "v" alone
270
+ ],
271
+ "handler": "handle_version",
272
+ "description": "Show version information",
273
+ "examples": [
274
+ 'version',
275
+ 'what version',
276
+ 'show version'
277
+ ]
278
+ },
279
+
280
+ # User Management
281
+ "create_superuser": {
282
+ "patterns": [
283
+ r"create\s+(super)?user(\s+(called\s+|named\s+)?(\w+))?",
284
+ r"add\s+(super)?user(\s+(\w+))?",
285
+ r"make\s+(super)?user(\s+(\w+))?",
286
+ r"new\s+(super)?user(\s+(\w+))?"
287
+ ],
288
+ "handler": "handle_create_superuser",
289
+ "description": "Create admin superuser",
290
+ "examples": [
291
+ 'create superuser',
292
+ 'add user admin',
293
+ 'create superuser called john'
294
+ ]
295
+ },
296
+
297
+ # Shell Access
298
+ "shell": {
299
+ "patterns": [
300
+ r"shell",
301
+ r"interactive\s+shell",
302
+ r"python\s+shell",
303
+ r"repl"
304
+ ],
305
+ "handler": "handle_shell",
306
+ "description": "Start interactive shell",
307
+ "examples": [
308
+ 'shell',
309
+ 'interactive shell',
310
+ 'python shell'
311
+ ]
312
+ },
313
+
314
+ # Help System
315
+ "help": {
316
+ "patterns": [
317
+ r"help",
318
+ r"what\s+can\s+(i|you)\s+do",
319
+ r"commands",
320
+ r"usage",
321
+ r"\?"
322
+ ],
323
+ "handler": "handle_help",
324
+ "description": "Show available commands",
325
+ "examples": [
326
+ 'help',
327
+ 'what can you do',
328
+ 'commands'
329
+ ]
330
+ },
331
+
332
+ # AI Features
333
+ "ai_Example": {
334
+ "patterns": [
335
+ r"show\s+ai\s+(Example|features|capabilities)",
336
+ r"ai\s+Example",
337
+ r"Examplenstrate\s+ai",
338
+ r"what\s+ai\s+features"
339
+ ],
340
+ "handler": "handle_ai_Example",
341
+ "description": "Examplenstrate AI capabilities",
342
+ "examples": [
343
+ 'show ai Example',
344
+ 'ai features',
345
+ 'Examplenstrate ai'
346
+ ]
347
+ },
348
+
349
+ # Database AI Query
350
+ "db_ai_query": {
351
+ "patterns": [
352
+ r"db\s+ai-query\s+(.+)",
353
+ r"database\s+query\s+(.+)",
354
+ r"ai\s+query\s+(.+)",
355
+ r"query\s+database\s+(.+)"
356
+ ],
357
+ "handler": "handle_db_ai_query",
358
+ "description": "Query database using natural language",
359
+ "examples": [
360
+ 'db ai-query "show last 10 users"',
361
+ 'database query "count all sessions"',
362
+ 'ai query "show errors"'
363
+ ]
364
+ },
365
+
366
+ # Database Rollback
367
+ "db_rollback": {
368
+ "patterns": [
369
+ r"db\s+rollback(\s+(\d+))?",
370
+ r"database\s+rollback(\s+(\d+))?",
371
+ r"rollback\s+database(\s+(\d+))?"
372
+ ],
373
+ "handler": "handle_db_rollback",
374
+ "description": "Rollback database operations",
375
+ "examples": [
376
+ 'db rollback',
377
+ 'database rollback 5',
378
+ 'rollback last 3 operations'
379
+ ]
380
+ },
381
+
382
+ # Database Audit Log
383
+ "db_audit_log": {
384
+ "patterns": [
385
+ r"db\s+audit-log(\s+(\d+))?",
386
+ r"database\s+audit(\s+(\d+))?",
387
+ r"show\s+audit\s+log(\s+(\d+))?",
388
+ r"audit\s+trail(\s+(\d+))?"
389
+ ],
390
+ "handler": "handle_db_audit_log",
391
+ "description": "Show database audit log",
392
+ "examples": [
393
+ 'db audit-log',
394
+ 'database audit 10',
395
+ 'show audit log'
396
+ ]
397
+ }
398
+ }
399
+
400
+ def parse_natural_language(self, input_text: str) -> Tuple[Optional[str], Dict[str, Any]]:
401
+ """
402
+ Parse natural language input and extract intent + parameters
403
+
404
+ Returns:
405
+ (command_name, parameters_dict)
406
+ """
407
+ input_text = input_text.lower().strip()
408
+
409
+ for command_name, command_data in self.commands_db.items():
410
+ for pattern in command_data["patterns"]:
411
+ match = re.search(pattern, input_text)
412
+ if match:
413
+ # Extract parameters from regex groups
414
+ params = self._extract_parameters(command_name, match, input_text)
415
+ return command_name, params
416
+
417
+ return None, {}
418
+
419
+ def _extract_parameters(self, command_name: str, match: re.Match, full_text: str) -> Dict[str, Any]:
420
+ """Extract parameters from regex match - FIXED: Improved stop-word filtering"""
421
+ params = {}
422
+ groups = match.groups()
423
+
424
+ # FIXED: Better stop words list with more specific filtering
425
+ STOP_WORDS = {
426
+ 'a', 'an', 'the', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of', 'with',
427
+ 'new', 'called', 'named', 'create', 'start', 'make', 'run', 'launch', 'serve',
428
+ 'super', 'admin', 'user', 'project', 'server', 'app', 'application'
429
+ }
430
+
431
+ if command_name == "create_project":
432
+ # Extract project name - FIXED: Better filtering
433
+ for group in groups:
434
+ if group and group.strip():
435
+ clean_name = group.strip().lower()
436
+ # FIXED: More strict validation - avoid common words
437
+ if (clean_name not in STOP_WORDS and
438
+ len(clean_name) > 2 and # Must be longer than 2 chars
439
+ not clean_name.isdigit() and # Not just numbers
440
+ clean_name.replace('_', '').replace('-', '').isalnum()): # Valid identifier chars
441
+ params['project_name'] = group.strip()
442
+ break
443
+
444
+ # Default fallback if no valid name found
445
+ if 'project_name' not in params:
446
+ params['project_name'] = 'my_project'
447
+
448
+ # Check for AI features
449
+ if 'ai' in full_text or 'artificial intelligence' in full_text:
450
+ params['ai_features'] = True
451
+ if 'admin' in full_text:
452
+ params['admin_enabled'] = True
453
+ if 'auth' in full_text or 'authentication' in full_text:
454
+ params['auth_enabled'] = True
455
+
456
+ elif command_name in ["start_server", "production_server"]:
457
+ # Extract port number
458
+ for group in groups:
459
+ if group and group.isdigit():
460
+ port_num = int(group)
461
+ # FIXED: Validate reasonable port range
462
+ if 1000 <= port_num <= 65535:
463
+ params['port'] = port_num
464
+ break
465
+
466
+ # FIXED: Better worker extraction for production
467
+ if command_name == "production_server":
468
+ # Look for explicit worker mentions, not just any number
469
+ for group in groups:
470
+ if group and group.isdigit():
471
+ worker_count = int(group)
472
+ if 1 <= worker_count <= 16: # Reasonable worker range
473
+ params['workers'] = worker_count
474
+ break
475
+
476
+ elif command_name == "db_ai_query":
477
+ # Extract the natural language query
478
+ for group in groups:
479
+ if group and group.strip():
480
+ # Clean up quotes and whitespace
481
+ query = group.strip().strip('"\'')
482
+ if query:
483
+ params['query'] = query
484
+ break
485
+
486
+ elif command_name == "db_rollback":
487
+ # Extract count for rollback
488
+ for group in groups:
489
+ if group and group.isdigit():
490
+ count = int(group)
491
+ if 1 <= count <= 100: # Reasonable limit
492
+ params['count'] = count
493
+ break
494
+ if 'count' not in params:
495
+ params['count'] = 1 # Default rollback count
496
+
497
+ elif command_name == "db_audit_log":
498
+ # Extract limit for audit log
499
+ for group in groups:
500
+ if group and group.isdigit():
501
+ limit = int(group)
502
+ if 1 <= limit <= 1000: # Reasonable limit
503
+ params['limit'] = limit
504
+ break
505
+ if 'limit' not in params:
506
+ params['limit'] = 10 # Default limit
507
+ if re.search(r'(\d+)\s*workers?', full_text, re.IGNORECASE):
508
+ worker_match = re.search(r'(\d+)\s*workers?', full_text, re.IGNORECASE)
509
+ if worker_match:
510
+ params['workers'] = int(worker_match.group(1))
511
+ else:
512
+ params['workers'] = 4 # Reasonable default for production
513
+
514
+ elif command_name == "create_superuser":
515
+ # Extract username - FIXED: Better validation
516
+ for group in groups:
517
+ if group and group.strip():
518
+ clean_username = group.strip().lower()
519
+ if (clean_username not in STOP_WORDS and
520
+ len(clean_username) >= 3 and
521
+ clean_username.replace('_', '').isalnum()):
522
+ params['username'] = group.strip()
523
+ break
524
+
525
+ # Default fallback
526
+ if 'username' not in params:
527
+ params['username'] = 'admin'
528
+
529
+ return params
530
+
531
+ async def execute_command(self, command_name: str, params: Dict[str, Any]) -> bool:
532
+ """Execute the parsed command"""
533
+
534
+ if command_name not in self.commands_db:
535
+ return False
536
+
537
+ handler_name = self.commands_db[command_name]["handler"]
538
+ handler = getattr(self, handler_name, None)
539
+
540
+ if handler:
541
+ try:
542
+ await handler(params)
543
+ self.context["last_command"] = command_name
544
+ return True
545
+ except Exception as e:
546
+ self._error(f"Command execution failed: {e}")
547
+ return False
548
+
549
+ return False
550
+
551
+ # ========================================
552
+ # COMMAND HANDLERS
553
+ # ========================================
554
+
555
+ async def handle_create_project(self, params: Dict[str, Any]):
556
+ """Handle project creation with natural language parameters"""
557
+ project_name = params.get('project_name', 'my_createsonline_app')
558
+ ai_features = params.get('ai_features', True) # Default to True for AI-native framework
559
+ admin_enabled = params.get('admin_enabled', True)
560
+ auth_enabled = params.get('auth_enabled', True)
561
+
562
+ self._info(f"Creating CREATESONLINE project: {project_name}")
563
+
564
+ # Show project configuration
565
+ config_data = [
566
+ ["Feature", "Status"],
567
+ ["AI Features", "✅ Enabled" if ai_features else "❌ Disabled"],
568
+ ["Admin Interface", "✅ Enabled" if admin_enabled else "❌ Disabled"],
569
+ ["Authentication", "✅ Enabled" if auth_enabled else "❌ Disabled"]
570
+ ]
571
+
572
+ if RICH_AVAILABLE:
573
+ table = Table(title="Project Configuration")
574
+ table.add_column("Feature", style="cyan")
575
+ table.add_column("Status", style="green")
576
+ for row in config_data[1:]:
577
+ table.add_row(row[0], row[1])
578
+ console.print(table)
579
+ else:
580
+ self.console.table(config_data[1:], config_data[0])
581
+
582
+ # Create project structure
583
+ await self._create_project_structure(project_name, ai_features, admin_enabled, auth_enabled)
584
+
585
+ # Show next steps
586
+ self._success(f"Project '{project_name}' created successfully!")
587
+ self._info("Next steps:")
588
+ self._info(f"1. cd {project_name}")
589
+ self._info("2. python -m venv venv")
590
+ self._info("3. source venv/bin/activate # Windows: venv\\Scripts\\activate")
591
+ self._info("4. pip install -r requirements.txt")
592
+ self._info("5. createsonline 'start development server'")
593
+
594
+ async def handle_init_project(self, params: Dict[str, Any]):
595
+ """Initialize project structure in current directory"""
596
+ try:
597
+ from createsonline.project_init import ProjectInitializer
598
+
599
+ self._info("Initializing CREATESONLINE project structure...")
600
+
601
+ # Get current directory
602
+ project_root = Path.cwd()
603
+ self._info(f"Project root: {project_root}")
604
+
605
+ # Initialize project with verbose output for CLI
606
+ initializer = ProjectInitializer(project_root)
607
+ result = initializer.initialize(verbose=True)
608
+
609
+ # Show results
610
+ if result.get("success"):
611
+ created_files = result.get("created_files", [])
612
+ skipped_files = result.get("user_files_skipped", [])
613
+ created_dirs = result.get("created_directories", [])
614
+
615
+ # Show created directories
616
+ for dir_path in created_dirs:
617
+ self._info(f" Created directory: {dir_path}")
618
+
619
+ # Show created files
620
+ for file_info in created_files:
621
+ self._info(f" Created {file_info['type']}: {file_info['path']}")
622
+
623
+ # Show skipped files (user customizations)
624
+ if skipped_files:
625
+ self._warning(f"\nSkipped {len(skipped_files)} existing file(s) to preserve your customizations:")
626
+ for filepath in skipped_files:
627
+ self._info(f" * {filepath}")
628
+
629
+ self._success(f"\nInitialization complete!")
630
+ self._info(f"Created {len(created_files)} new files")
631
+
632
+ if skipped_files:
633
+ self._info(f"Protected {len(skipped_files)} existing files")
634
+
635
+ # Show next steps
636
+ self._info("\nNext steps:")
637
+ self._info(" 1. Edit routes.py to add your custom routes")
638
+ self._info(" 2. Customize templates/ and static/ folders")
639
+ self._info(" 3. Run: python main.py")
640
+ self._success("\nHappy coding!")
641
+
642
+ else:
643
+ self._error("Initialization failed")
644
+ error_msg = result.get("error", "Unknown error")
645
+ self._error(f"Error: {error_msg}")
646
+
647
+ except ImportError:
648
+ self._error("ProjectInitializer not found. Please upgrade createsonline:")
649
+ self._info(" pip install --upgrade createsonline")
650
+ except Exception as e:
651
+ self._error(f"Initialization failed: {e}")
652
+ import traceback
653
+ self._error(traceback.format_exc())
654
+
655
+ async def handle_start_server(self, params: Dict[str, Any]):
656
+ """Handle development server startup"""
657
+ port = params.get('port', 8000)
658
+ host = params.get('host', '0.0.0.0')
659
+
660
+ # Check for application files
661
+ app_files = ["main.py", "app.py"]
662
+ app_file = None
663
+
664
+ for file in app_files:
665
+ if Path(file).exists():
666
+ app_file = file
667
+ break
668
+
669
+ if not app_file:
670
+ await self._create_basic_app()
671
+ app_file = "main.py"
672
+
673
+ try:
674
+ # Pass port and host as environment variables
675
+ env = os.environ.copy()
676
+ env['PORT'] = str(port)
677
+ env['HOST'] = host
678
+
679
+ # Use internal pure Python server - no uvicorn needed!
680
+ subprocess.run([
681
+ sys.executable, app_file
682
+ ], env=env)
683
+ except KeyboardInterrupt:
684
+ pass
685
+ except Exception as e:
686
+ self._error(f"Error: {e}")
687
+
688
+ async def handle_production_server(self, params: Dict[str, Any]):
689
+ """Handle production server startup"""
690
+ port = params.get('port', 8000)
691
+ workers = params.get('workers', 4)
692
+
693
+ self._info(f"Starting CREATESONLINE production server with {workers} workers")
694
+
695
+ # Production configuration
696
+ self._panel_info("Production Server", f"""
697
+ 🏭 CREATESONLINE Production Mode
698
+ âš¡ Workers: {workers}
699
+ 🌐 Port: {port}
700
+ 🔒 Security: Enabled
701
+ 📊 Monitoring: Active
702
+ """)
703
+
704
+ try:
705
+ # Use internal pure Python server - production mode
706
+ # Note: For true multi-worker support, consider using gunicorn with the internal server
707
+ subprocess.run([
708
+ sys.executable, "main.py"
709
+ ])
710
+ except Exception as e:
711
+ self._error(f"Production server failed: {e}")
712
+
713
+ async def handle_framework_info(self, params: Dict[str, Any]):
714
+ """Show comprehensive framework information"""
715
+
716
+ # Framework banner
717
+ banner = """
718
+ ╔══════════════════════════════════════════════════════════════╗
719
+ â•‘ CREATESONLINE â•‘
720
+ â•‘ The AI-Native Web Framework â•‘
721
+ â•‘ â•‘
722
+ â•‘ Build Intelligence Into Everything â•‘
723
+ â•‘ â•‘
724
+ â•‘ Version: 0.1.0 | Python: 3.9-3.13 â•‘
725
+ â•‘ Pure Framework | AI-First | Pure Python â•‘
726
+ ╚══════════════════════════════════════════════════════════════╝
727
+ """.strip()
728
+
729
+ self._info(banner)
730
+
731
+ # Features table
732
+ features_data = [
733
+ ["Feature", "Status", "Description"],
734
+ ["AI-Native Core", "✅ Active", "Built-in AI capabilities"],
735
+ ["Pure Python", "✅ Active", "Works with just Python"],
736
+ ["Dynamic CLI", "✅ Active", "Natural language commands"],
737
+ ["Admin Interface", "✅ Ready", "Built-in admin panel"],
738
+ ["User Management", "✅ Ready", "Built-in authentication"],
739
+ ["Vector Search", "✅ Ready", "Semantic similarity"],
740
+ ["LLM Integration", "🔄 Optional", "When API keys provided"],
741
+ ["Auto Templates", "✅ Active", "Internal template system"]
742
+ ]
743
+
744
+ if RICH_AVAILABLE:
745
+ table = Table(title="Framework Features")
746
+ table.add_column("Feature", style="cyan")
747
+ table.add_column("Status", style="green")
748
+ table.add_column("Description", style="white")
749
+ for row in features_data[1:]:
750
+ table.add_row(row[0], row[1], row[2])
751
+ console.print(table)
752
+ else:
753
+ self.console.table(features_data[1:], features_data[0])
754
+
755
+ # Natural language examples
756
+ self._panel_info("Natural Language CLI Examples", """
757
+ • "create new AI-powered project called blog"
758
+ • "start development server on port 8000"
759
+ • "launch production server with 4 workers"
760
+ • "create superuser admin with full permissions"
761
+ • "show available AI capabilities and features"
762
+ • "start server in development mode"
763
+ • "display framework information and status"
764
+ """)
765
+
766
+ async def handle_version(self, params: Dict[str, Any]):
767
+ """Show version information"""
768
+
769
+ # Reference to our logo files
770
+ logo_path = os.path.join(os.path.dirname(__file__), "..", "static", "image")
771
+ favicon_files = ["favicon.svg", "favicon.ico", "logo.png"]
772
+
773
+ version_info = f"""
774
+ C⎯● CREATESONLINE Framework v0.1.0 - Ultimate Pure Independence
775
+
776
+ 🐍 Python: {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}
777
+ 🖥️ Platform: {sys.platform}
778
+ 📁 Location: {os.path.dirname(__file__)}
779
+ 🎯 Mode: {'Enhanced' if RICH_AVAILABLE else 'Core'}
780
+ 🎨 Brand Assets: {logo_path}
781
+
782
+ Build Intelligence Into Everything
783
+ """.strip()
784
+
785
+ self._panel_info("Version Information", version_info)
786
+
787
+ async def handle_create_superuser(self, params: Dict[str, Any]):
788
+ """Handle superuser creation"""
789
+ username = params.get('username', 'admin')
790
+
791
+ self._info(f"Creating superuser: {username}")
792
+
793
+ # In a real implementation, this would create the user
794
+ # For now, show what would happen
795
+ self._panel_info("Superuser Creation", f"""
796
+ 👤 Username: {username}
797
+ 🔑 Password: [Interactive prompt would appear]
798
+ 🛡️ Permissions: Full admin access
799
+ 📧 Email: [Would be requested]
800
+ """)
801
+
802
+ self._success(f"Superuser '{username}' would be created!")
803
+ self._info("This feature requires the full CREATESONLINE installation.")
804
+
805
+ async def handle_shell(self, params: Dict[str, Any]):
806
+ """Start interactive shell"""
807
+ self._info("Starting CREATESONLINE interactive shell...")
808
+
809
+ try:
810
+ # Try to start Python shell with CREATESONLINE imports
811
+ code = '''
812
+ import sys
813
+ sys.path.insert(0, ".")
814
+
815
+ # Try to import CREATESONLINE
816
+ try:
817
+ import createsonline
818
+ print("✅ CREATESONLINE imported successfully")
819
+ print("Available: createsonline.create_app()")
820
+ except ImportError:
821
+ print("⚠️ CREATESONLINE not in Python path")
822
+
823
+ print("🐚 CREATESONLINE Interactive Shell")
824
+ logging.getLogger("createsonline.cli").info("Type exit() to quit")
825
+ '''
826
+
827
+ # Start Python with the code
828
+ subprocess.run([sys.executable, "-i", "-c", code])
829
+
830
+ except KeyboardInterrupt:
831
+ self._info("Shell session ended")
832
+
833
+ async def handle_help(self, params: Dict[str, Any]):
834
+ """Show help information"""
835
+
836
+ self._panel_info("C⎯● CREATESONLINE Natural Language CLI", """
837
+ 🎯 Express your intent naturally - no rigid commands needed!
838
+
839
+ Examples of what you can say:
840
+ """)
841
+
842
+ # Group commands by category
843
+ categories = {
844
+ "Project Management": ["create_project"],
845
+ "Server Operations": ["start_server", "production_server"],
846
+ "User Management": ["create_superuser"],
847
+ "Information": ["framework_info", "version", "help"],
848
+ "Development": ["shell", "ai_Example"]
849
+ }
850
+
851
+ for category, command_names in categories.items():
852
+ self._info(f"\n📂 {category}:")
853
+ for cmd_name in command_names:
854
+ if cmd_name in self.commands_db:
855
+ examples = self.commands_db[cmd_name]["examples"]
856
+ for example in examples[:2]: # Show first 2 examples
857
+ self._info(f" • createsonline \"{example}\"")
858
+
859
+ async def handle_ai_Example(self, params: Dict[str, Any]):
860
+ """Examplenstrate AI capabilities"""
861
+
862
+ self._panel_info("CREATESONLINE AI Capabilities", """
863
+ 🧠 Built-in AI Features:
864
+
865
+ • Hash-based Embeddings - Consistent vector representations
866
+ • Rule-based Generation - Smart text creation
867
+ • Similarity Search - Find related content
868
+ • AI Field Types - Database fields with intelligence
869
+ • Mock AI Services - Development-ready AI
870
+
871
+ 🔥 Enhanced AI (With API Keys):
872
+
873
+ • OpenAI Integration - GPT models for generation
874
+ • Anthropic Claude - Advanced reasoning
875
+ • Vector Databases - Production embeddings
876
+ • Real-time Learning - Adaptive algorithms
877
+ """)
878
+
879
+ # Show AI field examples
880
+ self._info("\n🎯 AI Field Examples:")
881
+ self._info(" • AIComputedField - Automatic ML predictions")
882
+ self._info(" • LLMField - Content generation")
883
+ self._info(" • VectorField - Semantic search")
884
+ self._info(" • SmartTextField - Text analysis")
885
+
886
+ async def handle_db_ai_query(self, params: Dict[str, Any]):
887
+ """Handle database AI query command"""
888
+ query = params.get('query', '')
889
+ if not query:
890
+ self._error("No query provided. Usage: db ai-query 'show last 10 users'")
891
+ return
892
+
893
+ try:
894
+ # Import the database AI query command
895
+ from createsonline.cli.commands.database import db_ai_query_command
896
+ db_ai_query_command(query) # Remove await - function is not async
897
+ except ImportError as e:
898
+ self._error(f"Database commands not available: {e}")
899
+ except Exception as e:
900
+ self._error(f"Query failed: {e}")
901
+
902
+ async def handle_db_rollback(self, params: Dict[str, Any]):
903
+ """Handle database rollback command"""
904
+ count = params.get('count', 1)
905
+
906
+ try:
907
+ # Import the database rollback command
908
+ from createsonline.cli.commands.database import db_rollback_command
909
+ db_rollback_command(count) # Remove await - function is not async
910
+ except ImportError as e:
911
+ self._error(f"Database commands not available: {e}")
912
+ except Exception as e:
913
+ self._error(f"Rollback failed: {e}")
914
+
915
+ async def handle_db_audit_log(self, params: Dict[str, Any]):
916
+ """Handle database audit log command"""
917
+ limit = params.get('limit', 10)
918
+
919
+ try:
920
+ # Import the database audit log command
921
+ from createsonline.cli.commands.database import db_audit_log_command
922
+ db_audit_log_command(limit) # Remove await - function is not async
923
+ except ImportError as e:
924
+ self._error(f"Database commands not available: {e}")
925
+ except Exception as e:
926
+ self._error(f"Audit log failed: {e}")
927
+
928
+ try:
929
+ # Import the database audit log command
930
+ from createsonline.cli.commands.database import db_audit_log_command
931
+ await db_audit_log_command(limit)
932
+ except ImportError as e:
933
+ self._error(f"Database commands not available: {e}")
934
+ except Exception as e:
935
+ self._error(f"Audit log failed: {e}")
936
+
937
+ # ========================================
938
+ # UTILITY METHODS
939
+ # ========================================
940
+
941
+ def _info(self, message: str):
942
+ """Print info message"""
943
+ if RICH_AVAILABLE:
944
+ console.print(message, style="blue")
945
+ else:
946
+ self.console.print(message, "blue")
947
+
948
+ def _success(self, message: str):
949
+ """Print success message"""
950
+ if RICH_AVAILABLE:
951
+ console.print(f"✅ {message}", style="green")
952
+ else:
953
+ self.console.print(f"✅ {message}", "green")
954
+
955
+ def _warning(self, message: str):
956
+ """Print warning message"""
957
+ if RICH_AVAILABLE:
958
+ console.print(f"⚠️ {message}", style="yellow")
959
+ else:
960
+ self.console.print(f"⚠️ {message}", "yellow")
961
+
962
+ def _error(self, message: str):
963
+ """Print error message"""
964
+ if RICH_AVAILABLE:
965
+ console.print(f"❌ {message}", style="red")
966
+ else:
967
+ self.console.print(f"❌ {message}", "red")
968
+
969
+ def _panel_info(self, title: str, content: str):
970
+ """Print panel with info"""
971
+ if RICH_AVAILABLE:
972
+ console.print(Panel(content.strip(), title=title, border_style="blue"))
973
+ else:
974
+ self.console.panel(content.strip(), title)
975
+
976
+ async def _create_project_structure(self, project_name: str, ai_features: bool, admin_enabled: bool, auth_enabled: bool):
977
+ """Create project directory structure"""
978
+
979
+ project_path = Path(project_name)
980
+ if project_path.exists():
981
+ self._warning(f"Directory '{project_name}' already exists")
982
+ return
983
+
984
+ # Create directories
985
+ project_path.mkdir()
986
+ (project_path / "static").mkdir()
987
+ (project_path / "templates").mkdir()
988
+ (project_path / "tests").mkdir()
989
+
990
+ # Generate main.py
991
+ main_content = self._generate_main_py(project_name, ai_features, admin_enabled, auth_enabled)
992
+ (project_path / "main.py").write_text(main_content)
993
+
994
+ # Generate requirements.txt - Pure CREATESONLINE, no external server needed!
995
+ requirements = "createsonline>=0.1.0"
996
+ if ai_features:
997
+ requirements += "\n# AI Features (optional)\n# openai>=1.0.0\n# numpy>=1.24.0"
998
+ (project_path / "requirements.txt").write_text(requirements)
999
+
1000
+ # Generate .env
1001
+ env_content = f"""# {project_name} Configuration
1002
+ DEBUG=true
1003
+ SECRET_KEY=your-secret-key-change-in-production
1004
+ DATABASE_URL=sqlite:///./app.db
1005
+ HOST=127.0.0.1
1006
+ PORT=8000
1007
+
1008
+ # AI Configuration (optional)
1009
+ # OPENAI_API_KEY=your-key-here
1010
+ """
1011
+ (project_path / ".env").write_text(env_content)
1012
+
1013
+ # Generate README.md
1014
+ readme_content = f"""# {project_name}
1015
+
1016
+ Built with **CREATESONLINE** - The AI-Native Web Framework
1017
+
1018
+ ## Quick Start
1019
+
1020
+ ```bash
1021
+ # Install dependencies
1022
+ pip install -r requirements.txt
1023
+
1024
+ # Start development server
1025
+ createsonline "start development server"
1026
+
1027
+ # Or traditionally
1028
+ python main.py
1029
+ ```
1030
+
1031
+ ## Natural Language CLI
1032
+
1033
+ ```bash
1034
+ createsonline "show comprehensive framework information"
1035
+ createsonline "create superuser admin with full permissions"
1036
+ createsonline "start development server on port 8000"
1037
+ ```
1038
+
1039
+ Built with Intelligence Into Everything C⎯●
1040
+ """
1041
+ (project_path / "README.md").write_text(readme_content)
1042
+
1043
+ def _generate_main_py(self, project_name: str, ai_features: bool, admin_enabled: bool, auth_enabled: bool) -> str:
1044
+ """Generate main.py content"""
1045
+
1046
+ ai_config = {}
1047
+ if ai_features:
1048
+ ai_config = {
1049
+ "enable_smart_fields": True,
1050
+ "default_llm": "internal"
1051
+ }
1052
+
1053
+ return f'''#!/usr/bin/env python3
1054
+ """
1055
+ {project_name} - CREATESONLINE Application
1056
+
1057
+ Built with CREATESONLINE - The AI-Native Web Framework
1058
+ Created with natural language: "create project {project_name}"
1059
+ """
1060
+ from createsonline import create_app
1061
+
1062
+ # Create CREATESONLINE application
1063
+ app = create_app(
1064
+ title="{project_name.title()}",
1065
+ description="AI-powered application built with CREATESONLINE",
1066
+ version="1.0.0",
1067
+ ai_config={ai_config},
1068
+ debug=False
1069
+ )
1070
+
1071
+ {f"# Enable AI features\\napp.enable_ai_features(['smart_query', 'content_generation', 'vector_search'])" if ai_features else ""}
1072
+
1073
+ @app.get("/")
1074
+ async def home(request):
1075
+ """Home page"""
1076
+ return {{
1077
+ "message": "Welcome to {project_name.title()}!",
1078
+ "framework": "CREATESONLINE",
1079
+ "ai_enabled": {str(ai_features).lower()},
1080
+ "admin_enabled": {str(admin_enabled).lower()},
1081
+ "auth_enabled": {str(auth_enabled).lower()},
1082
+ "status": "operational"
1083
+ }}
1084
+
1085
+ @app.get("/api/status")
1086
+ async def api_status(request):
1087
+ """API status"""
1088
+ return {{
1089
+ "service": "{project_name.title()} API",
1090
+ "status": "operational",
1091
+ "framework": "CREATESONLINE",
1092
+ "version": "1.0.0"
1093
+ }}
1094
+
1095
+ @app.get("/health")
1096
+ async def health(request):
1097
+ """Health check"""
1098
+ return {{"status": "healthy", "framework": "CREATESONLINE"}}
1099
+
1100
+ @app.get("/createsonline.spec.json")
1101
+ async def createsonline_spec(request):
1102
+ """CREATESONLINE API Specification - Pure Internal Implementation"""
1103
+ from datetime import datetime
1104
+ import platform
1105
+ import sys
1106
+
1107
+ return {{
1108
+ "createsonline": "0.1.0", # Framework version
1109
+ "spec_version": "1.0.0", # Spec format version
1110
+ "compatible_with": ["openapi-3.0"], # Compatible formats (for tools)
1111
+ "info": {{
1112
+ "title": "CREATESONLINE Framework API",
1113
+ "description": "AI-Native Web Framework - Complete API Specification",
1114
+ "version": "1.0.0",
1115
+ "framework": "CREATESONLINE",
1116
+ "framework_version": "0.1.0",
1117
+ "framework_type": "AI-Native",
1118
+ "spec_format": "createsonline-spec-v1"
1119
+ }},
1120
+ "servers": [
1121
+ {{
1122
+ "url": "/",
1123
+ "description": "CREATESONLINE Internal Pure Python Server",
1124
+ "x-server-type": "internal-asgi"
1125
+ }}
1126
+ ],
1127
+ "paths": {{
1128
+ "/": {{
1129
+ "get": {{
1130
+ "summary": "Home Page",
1131
+ "tags": ["CREATESONLINE-Core"],
1132
+ "responses": {{
1133
+ "200": {{
1134
+ "description": "Home page with framework information"
1135
+ }}
1136
+ }}
1137
+ }}
1138
+ }},
1139
+ "/health": {{
1140
+ "get": {{
1141
+ "summary": "Health Check",
1142
+ "tags": ["CREATESONLINE-Core"],
1143
+ "responses": {{
1144
+ "200": {{
1145
+ "description": "Service health status",
1146
+ "content": {{
1147
+ "application/json": {{
1148
+ "schema": {{
1149
+ "type": "object",
1150
+ "properties": {{
1151
+ "status": {{"type": "string"}},
1152
+ "framework": {{"type": "string"}}
1153
+ }}
1154
+ }}
1155
+ }}
1156
+ }}
1157
+ }}
1158
+ }}
1159
+ }}
1160
+ }},
1161
+ "/api/status": {{
1162
+ "get": {{
1163
+ "summary": "API Status",
1164
+ "tags": ["CREATESONLINE-Core"],
1165
+ "responses": {{
1166
+ "200": {{
1167
+ "description": "API operational status"
1168
+ }}
1169
+ }}
1170
+ }}
1171
+ }},
1172
+ "/createsonline.spec.json": {{
1173
+ "get": {{
1174
+ "summary": "CREATESONLINE API Specification",
1175
+ "tags": ["CREATESONLINE-Core"],
1176
+ "responses": {{
1177
+ "200": {{
1178
+ "description": "Complete API specification in CREATESONLINE format"
1179
+ }}
1180
+ }}
1181
+ }}
1182
+ }}
1183
+ }},
1184
+ "tags": [
1185
+ {{
1186
+ "name": "CREATESONLINE-Core",
1187
+ "description": "Core framework endpoints"
1188
+ }}
1189
+ ]
1190
+ }}
1191
+
1192
+ if __name__ == "__main__":
1193
+ import os
1194
+ from createsonline.server import run_server
1195
+
1196
+ # Load environment variables from .env file
1197
+ try:
1198
+ from dotenv import load_dotenv
1199
+ load_dotenv()
1200
+ except ImportError:
1201
+ pass
1202
+
1203
+ host = os.getenv("HOST", "127.0.0.1")
1204
+ port = int(os.getenv("PORT", "8000"))
1205
+
1206
+ run_server(app, host=host, port=port)
1207
+ '''
1208
+
1209
+ async def _create_basic_app(self):
1210
+ """Create basic application file if none exists or update if outdated"""
1211
+
1212
+ TEMPLATE_VERSION = "0.1.1"
1213
+
1214
+ # Check if main.py exists and has version marker
1215
+ if Path("main.py").exists():
1216
+ content = Path("main.py").read_text(encoding='utf-8')
1217
+ # Check if it's our auto-generated template
1218
+ if "Auto-generated by CREATESONLINE CLI" in content:
1219
+ # Extract version from existing file
1220
+ import re
1221
+ version_match = re.search(r'Template Version: ([\d.]+)', content)
1222
+ if version_match:
1223
+ existing_version = version_match.group(1)
1224
+ if existing_version == TEMPLATE_VERSION:
1225
+ # Already up to date, don't regenerate
1226
+ return
1227
+ else:
1228
+ self._info(f"Updating main.py from v{existing_version} to v{TEMPLATE_VERSION}")
1229
+ else:
1230
+ # Old template without version, update it
1231
+ self._info("Updating main.py to latest template")
1232
+ else:
1233
+ # User's custom main.py, don't touch it
1234
+ return
1235
+
1236
+ # Build template with version header
1237
+ version_header = f'''#!/usr/bin/env python3
1238
+ """
1239
+ Basic CREATESONLINE Application
1240
+
1241
+ Auto-generated by CREATESONLINE CLI
1242
+ Template Version: {TEMPLATE_VERSION}
1243
+ """
1244
+ '''
1245
+
1246
+ basic_app = version_header + '''from createsonline import create_app
1247
+
1248
+ # Create basic CREATESONLINE application
1249
+ app = create_app(
1250
+ title="CREATESONLINE Example",
1251
+ description="Basic CREATESONLINE application",
1252
+ version="1.0.0",
1253
+ debug=False
1254
+ )
1255
+
1256
+ @app.get("/")
1257
+ async def home(request):
1258
+ """Home page with beautiful UI"""
1259
+ html = """
1260
+ <!DOCTYPE html>
1261
+ <html lang="en">
1262
+ <head>
1263
+ <meta charset="UTF-8">
1264
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
1265
+ <title>CREATESONLINE Framework</title>
1266
+
1267
+ <!-- Favicons -->
1268
+ <link rel="icon" type="image/x-icon" href="/favicon.ico">
1269
+ <link rel="icon" type="image/png" sizes="32x32" href="/icons/icon-32x32.png">
1270
+ <link rel="icon" type="image/png" sizes="16x16" href="/icons/icon-16x16.png">
1271
+ <link rel="apple-touch-icon" sizes="180x180" href="/icons/icon-180x180.png">
1272
+ <link rel="manifest" href="/site.webmanifest">
1273
+
1274
+ <style>
1275
+ * {
1276
+ margin: 0;
1277
+ padding: 0;
1278
+ box-sizing: border-box;
1279
+ }}
1280
+
1281
+ body {{
1282
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
1283
+ background: linear-gradient(135deg, #000000 0%, #1a1a1a 50%, #000000 100%);
1284
+ min-height: 100vh;
1285
+ display: flex;
1286
+ justify-content: center;
1287
+ align-items: center;
1288
+ padding: 20px;
1289
+ position: relative;
1290
+ overflow: hidden;
1291
+ }}
1292
+
1293
+ body::before {{
1294
+ content: '';
1295
+ position: absolute;
1296
+ top: -50%;
1297
+ left: -50%;
1298
+ width: 200%;
1299
+ height: 200%;
1300
+ background: repeating-linear-gradient(
1301
+ 0deg,
1302
+ transparent,
1303
+ transparent 2px,
1304
+ rgba(255, 255, 255, 0.03) 2px,
1305
+ rgba(255, 255, 255, 0.03) 4px
1306
+ );
1307
+ animation: scan 8s linear infinite;
1308
+ pointer-events: none;
1309
+ }}
1310
+
1311
+ @keyframes scan {{
1312
+ 0% {{ transform: translateY(0); }}
1313
+ 100% {{ transform: translateY(50px); }}
1314
+ }}
1315
+
1316
+ .container {{
1317
+ background: rgba(255, 255, 255, 0.98);
1318
+ backdrop-filter: blur(10px);
1319
+ border: 1px solid rgba(0, 0, 0, 0.1);
1320
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
1321
+ padding: 80px 60px;
1322
+ max-width: 1000px;
1323
+ width: 100%;
1324
+ animation: slideUp 0.8s cubic-bezier(0.16, 1, 0.3, 1);
1325
+ position: relative;
1326
+ z-index: 1;
1327
+ }}
1328
+
1329
+ @keyframes slideUp {{
1330
+ from {{
1331
+ opacity: 0;
1332
+ transform: translateY(30px);
1333
+ }}
1334
+ to {{
1335
+ opacity: 1;
1336
+ transform: translateY(0);
1337
+ }}
1338
+ }}
1339
+
1340
+ .logo {{
1341
+ display: block;
1342
+ margin: 0 auto 50px;
1343
+ max-width: 280px;
1344
+ width: 100%;
1345
+ height: auto;
1346
+ filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.1));
1347
+ }}
1348
+
1349
+ h1 {{
1350
+ font-size: 2.8em;
1351
+ color: #000000;
1352
+ margin-bottom: 15px;
1353
+ text-align: center;
1354
+ font-weight: 300;
1355
+ letter-spacing: -1px;
1356
+ position: relative;
1357
+ }}
1358
+
1359
+ h1::after {{
1360
+ content: '';
1361
+ display: block;
1362
+ width: 60px;
1363
+ height: 3px;
1364
+ background: #000000;
1365
+ margin: 20px auto 0;
1366
+ }}
1367
+
1368
+ .subtitle {{
1369
+ text-align: center;
1370
+ color: #666666;
1371
+ font-size: 1.1em;
1372
+ margin-bottom: 50px;
1373
+ font-weight: 300;
1374
+ line-height: 1.6;
1375
+ }}
1376
+
1377
+ .links {{
1378
+ display: grid;
1379
+ grid-template-columns: repeat(2, 1fr);
1380
+ gap: 25px;
1381
+ margin: 50px 0;
1382
+ }}
1383
+
1384
+ .link-card {{
1385
+ background: #000000;
1386
+ padding: 40px 30px;
1387
+ text-decoration: none;
1388
+ color: white;
1389
+ transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1);
1390
+ border: 2px solid #000000;
1391
+ position: relative;
1392
+ overflow: hidden;
1393
+ }}
1394
+
1395
+ .link-card::before {{
1396
+ content: '';
1397
+ position: absolute;
1398
+ top: 0;
1399
+ left: -100%;
1400
+ width: 100%;
1401
+ height: 100%;
1402
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
1403
+ transition: left 0.5s;
1404
+ }}
1405
+
1406
+ .link-card:hover::before {{
1407
+ left: 100%;
1408
+ }}
1409
+
1410
+ .link-card:hover {{
1411
+ background: #ffffff;
1412
+ color: #000000;
1413
+ border: 2px solid #000000;
1414
+ transform: translateY(-8px);
1415
+ box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.3);
1416
+ }}
1417
+
1418
+ .link-card h3 {{
1419
+ margin-bottom: 12px;
1420
+ font-size: 1.3em;
1421
+ font-weight: 600;
1422
+ letter-spacing: -0.5px;
1423
+ }}
1424
+
1425
+ .link-card p {{
1426
+ opacity: 0.85;
1427
+ font-size: 0.95em;
1428
+ font-weight: 300;
1429
+ line-height: 1.6;
1430
+ }}
1431
+
1432
+ .link-card:hover p {{
1433
+ opacity: 0.7;
1434
+ }}
1435
+
1436
+ .version {{
1437
+ text-align: center;
1438
+ color: #999999;
1439
+ margin-top: 60px;
1440
+ font-size: 0.85em;
1441
+ font-weight: 300;
1442
+ padding-top: 40px;
1443
+ border-top: 1px solid #e0e0e0;
1444
+ }}
1445
+
1446
+ .version p {{
1447
+ margin: 5px 0;
1448
+ }}
1449
+
1450
+ @media (max-width: 768px) {{
1451
+ .links {{
1452
+ grid-template-columns: 1fr;
1453
+ }}
1454
+
1455
+ .container {{
1456
+ padding: 50px 30px;
1457
+ }}
1458
+
1459
+ h1 {{
1460
+ font-size: 2em;
1461
+ }}
1462
+ }}
1463
+ </style>
1464
+ </head>
1465
+ <body>
1466
+ <div class="container">
1467
+ <img src="/logo-header-h200@2x.png" alt="CREATESONLINE" class="logo">
1468
+ <h1>AI-Native Web Framework</h1>
1469
+
1470
+ <div class="links">
1471
+ <a href="https://createsonline.com/docs" class="link-card">
1472
+ <h3>Documentation</h3>
1473
+ <p>Complete guides and API reference</p>
1474
+ </a>
1475
+
1476
+ <a href="https://createsonline.com/guide" class="link-card">
1477
+ <h3>Quick Start</h3>
1478
+ <p>Get started in 5 minutes</p>
1479
+ </a>
1480
+
1481
+ <a href="https://createsonline.com/examples" class="link-card">
1482
+ <h3>Examples</h3>
1483
+ <p>Real-world code examples</p>
1484
+ </a>
1485
+
1486
+ <a href="https://github.com/meahmedh/createsonline" class="link-card">
1487
+ <h3>GitHub</h3>
1488
+ <p>View source and contribute</p>
1489
+ </a>
1490
+ </div>
1491
+
1492
+ <div class="version">
1493
+ <p>CREATESONLINE v0.1.0</p>
1494
+ <p>Built by the CREATESONLINE Team</p>
1495
+ </div>
1496
+ </div>
1497
+ </body>
1498
+ </html>
1499
+ """
1500
+
1501
+ # Return HTML directly as string
1502
+ return html
1503
+
1504
+ @app.get("/admin")
1505
+ async def admin_login(request):
1506
+ """Admin login page"""
1507
+ html = """
1508
+ <!DOCTYPE html>
1509
+ <html lang="en">
1510
+ <head>
1511
+ <meta charset="UTF-8">
1512
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
1513
+ <title>Admin Login - CREATESONLINE</title>
1514
+
1515
+ <!-- Favicons -->
1516
+ <link rel="icon" type="image/x-icon" href="/favicon.ico">
1517
+ <link rel="icon" type="image/png" sizes="32x32" href="/icons/icon-32x32.png">
1518
+
1519
+ <style>
1520
+ * {{
1521
+ margin: 0;
1522
+ padding: 0;
1523
+ box-sizing: border-box;
1524
+ }}
1525
+
1526
+ body {{
1527
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
1528
+ background: linear-gradient(135deg, #000000 0%, #1a1a1a 50%, #000000 100%);
1529
+ min-height: 100vh;
1530
+ display: flex;
1531
+ justify-content: center;
1532
+ align-items: center;
1533
+ padding: 20px;
1534
+ position: relative;
1535
+ overflow: hidden;
1536
+ }}
1537
+
1538
+ body::before {{
1539
+ content: '';
1540
+ position: absolute;
1541
+ top: -50%;
1542
+ left: -50%;
1543
+ width: 200%;
1544
+ height: 200%;
1545
+ background: repeating-linear-gradient(
1546
+ 0deg,
1547
+ transparent,
1548
+ transparent 2px,
1549
+ rgba(255, 255, 255, 0.03) 2px,
1550
+ rgba(255, 255, 255, 0.03) 4px
1551
+ );
1552
+ animation: scan 8s linear infinite;
1553
+ pointer-events: none;
1554
+ }}
1555
+
1556
+ @keyframes scan {{
1557
+ 0% {{ transform: translateY(0); }}
1558
+ 100% {{ transform: translateY(50px); }}
1559
+ }}
1560
+
1561
+ .login-container {{
1562
+ background: rgba(255, 255, 255, 0.98);
1563
+ backdrop-filter: blur(10px);
1564
+ border: 1px solid rgba(0, 0, 0, 0.1);
1565
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
1566
+ padding: 60px 50px;
1567
+ max-width: 480px;
1568
+ width: 100%;
1569
+ animation: slideUp 0.8s cubic-bezier(0.16, 1, 0.3, 1);
1570
+ position: relative;
1571
+ z-index: 1;
1572
+ }}
1573
+
1574
+ @keyframes slideUp {{
1575
+ from {{
1576
+ opacity: 0;
1577
+ transform: translateY(30px);
1578
+ }}
1579
+ to {{
1580
+ opacity: 1;
1581
+ transform: translateY(0);
1582
+ }}
1583
+ }}
1584
+
1585
+ .logo {{
1586
+ display: block;
1587
+ margin: 0 auto 40px;
1588
+ max-width: 280px;
1589
+ width: 100%;
1590
+ height: auto;
1591
+ filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.1));
1592
+ }}
1593
+
1594
+ h1 {{
1595
+ font-size: 2em;
1596
+ color: #000000;
1597
+ margin-bottom: 10px;
1598
+ text-align: center;
1599
+ font-weight: 300;
1600
+ letter-spacing: -0.5px;
1601
+ }}
1602
+
1603
+ h1::after {{
1604
+ content: '';
1605
+ display: block;
1606
+ width: 40px;
1607
+ height: 2px;
1608
+ background: #000000;
1609
+ margin: 15px auto 0;
1610
+ }}
1611
+
1612
+ .subtitle {{
1613
+ text-align: center;
1614
+ color: #666666;
1615
+ font-size: 0.95em;
1616
+ margin-bottom: 45px;
1617
+ font-weight: 300;
1618
+ line-height: 1.6;
1619
+ }}
1620
+
1621
+ .form-group {{
1622
+ margin-bottom: 30px;
1623
+ position: relative;
1624
+ }}
1625
+
1626
+ label {{
1627
+ display: block;
1628
+ color: #000000;
1629
+ font-size: 0.85em;
1630
+ margin-bottom: 10px;
1631
+ font-weight: 600;
1632
+ text-transform: uppercase;
1633
+ letter-spacing: 1px;
1634
+ }}
1635
+
1636
+ input[type="text"],
1637
+ input[type="password"] {{
1638
+ width: 100%;
1639
+ padding: 15px 18px;
1640
+ border: 2px solid #e0e0e0;
1641
+ background: #ffffff;
1642
+ font-size: 1em;
1643
+ transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
1644
+ font-family: inherit;
1645
+ color: #000000;
1646
+ }}
1647
+
1648
+ input[type="text"]:focus,
1649
+ input[type="password"]:focus {{
1650
+ outline: none;
1651
+ background: #fafafa;
1652
+ border-color: #000000;
1653
+ transform: translateY(-2px);
1654
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
1655
+ }}
1656
+
1657
+ button {{
1658
+ width: 100%;
1659
+ padding: 18px;
1660
+ background: #000000;
1661
+ color: white;
1662
+ border: 2px solid #000000;
1663
+ font-size: 1em;
1664
+ font-weight: 600;
1665
+ cursor: pointer;
1666
+ transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
1667
+ text-transform: uppercase;
1668
+ letter-spacing: 1.5px;
1669
+ font-family: inherit;
1670
+ margin-top: 10px;
1671
+ position: relative;
1672
+ overflow: hidden;
1673
+ }}
1674
+
1675
+ button::before {{
1676
+ content: '';
1677
+ position: absolute;
1678
+ top: 0;
1679
+ left: -100%;
1680
+ width: 100%;
1681
+ height: 100%;
1682
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
1683
+ transition: left 0.5s;
1684
+ }}
1685
+
1686
+ button:hover::before {{
1687
+ left: 100%;
1688
+ }}
1689
+
1690
+ button:hover {{
1691
+ background: #ffffff;
1692
+ color: #000000;
1693
+ transform: translateY(-2px);
1694
+ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
1695
+ }}
1696
+
1697
+ button:active {{
1698
+ transform: translateY(0);
1699
+ }}
1700
+
1701
+ .back-link {{
1702
+ text-align: center;
1703
+ margin-top: 35px;
1704
+ padding-top: 30px;
1705
+ border-top: 1px solid #e0e0e0;
1706
+ }}
1707
+
1708
+ .back-link a {{
1709
+ color: #666666;
1710
+ text-decoration: none;
1711
+ font-size: 0.9em;
1712
+ transition: all 0.3s ease;
1713
+ font-weight: 300;
1714
+ }}
1715
+
1716
+ .back-link a:hover {{
1717
+ color: #000000;
1718
+ }}
1719
+
1720
+ @media (max-width: 480px) {{
1721
+ .login-container {{
1722
+ padding: 40px 30px;
1723
+ }}
1724
+
1725
+ h1 {{
1726
+ font-size: 1.6em;
1727
+ }}
1728
+ }}
1729
+ </style>
1730
+ </head>
1731
+ <body>
1732
+ <div class="login-container">
1733
+ <img src="/logo-header-h200@2x.png" alt="CREATESONLINE" class="logo">
1734
+ <h1>Admin Login</h1>
1735
+ <p class="subtitle">Enter your credentials to access the admin panel</p>
1736
+
1737
+ <form method="POST" action="/admin/login">
1738
+ <div class="form-group">
1739
+ <label for="username">Username</label>
1740
+ <input type="text" id="username" name="username" required>
1741
+ </div>
1742
+
1743
+ <div class="form-group">
1744
+ <label for="password">Password</label>
1745
+ <input type="password" id="password" name="password" required>
1746
+ </div>
1747
+
1748
+ <button type="submit">Sign In</button>
1749
+ </form>
1750
+
1751
+ <div class="back-link">
1752
+ <a href="/">Back to Home</a>
1753
+ </div>
1754
+ </div>
1755
+ </body>
1756
+ </html>
1757
+ """
1758
+ return html
1759
+
1760
+ if __name__ == "__main__":
1761
+ import os
1762
+ from createsonline.server import run_server
1763
+
1764
+ # Load environment variables from .env file
1765
+ try:
1766
+ from dotenv import load_dotenv
1767
+ load_dotenv()
1768
+ except ImportError:
1769
+ pass
1770
+
1771
+ host = os.getenv("HOST", "127.0.0.1")
1772
+ port = int(os.getenv("PORT", "8000"))
1773
+
1774
+ run_server(app, host=host, port=port)
1775
+ '''
1776
+
1777
+ Path("main.py").write_text(basic_app, encoding='utf-8')
1778
+ self._success("Created basic main.py application file")
1779
+
1780
+
1781
+ # ========================================
1782
+ # MAIN CLI ENTRY POINTS
1783
+ # ========================================
1784
+
1785
+ async def main():
1786
+ """Main CLI entry point - handles natural language input"""
1787
+
1788
+ # Initialize CLI
1789
+ cli = CreatesonlineNaturalLanguageCLI()
1790
+
1791
+ # Handle command line arguments
1792
+ if len(sys.argv) == 1:
1793
+ # No arguments - show help
1794
+ await cli.handle_help({})
1795
+ return
1796
+
1797
+ # Join all arguments as natural language input
1798
+ user_input = " ".join(sys.argv[1:])
1799
+
1800
+ # Handle traditional CLI commands first
1801
+ first_arg = sys.argv[1].lower() if len(sys.argv) > 1 else ""
1802
+
1803
+ if first_arg == "serve":
1804
+ # Traditional serve command
1805
+ port = 8000
1806
+ if len(sys.argv) > 2 and sys.argv[2].isdigit():
1807
+ port = int(sys.argv[2])
1808
+ await cli.handle_start_server({"port": port})
1809
+ return
1810
+
1811
+ if first_arg == "dev":
1812
+ # Traditional dev command
1813
+ port = 8000
1814
+ if len(sys.argv) > 2 and sys.argv[2].isdigit():
1815
+ port = int(sys.argv[2])
1816
+ await cli.handle_start_server({"port": port})
1817
+ return
1818
+
1819
+ if first_arg == "prod":
1820
+ # Traditional production command
1821
+ workers = 4
1822
+ if len(sys.argv) > 2 and sys.argv[2].isdigit():
1823
+ workers = int(sys.argv[2])
1824
+ await cli.handle_production_server({"workers": workers})
1825
+ return
1826
+
1827
+ if first_arg == "new":
1828
+ # Traditional new project command
1829
+ project_name = sys.argv[2] if len(sys.argv) > 2 else "myproject"
1830
+ await cli.handle_create_project({"name": project_name})
1831
+ return
1832
+
1833
+ if first_arg == "init":
1834
+ # Initialize project structure
1835
+ await cli.handle_init_project({})
1836
+ return
1837
+
1838
+ if first_arg == "createsuperuser":
1839
+ # Traditional superuser command
1840
+ await cli.handle_create_superuser({})
1841
+ return
1842
+
1843
+ if first_arg == "shell":
1844
+ # Traditional shell command
1845
+ await cli.handle_shell({})
1846
+ return
1847
+
1848
+ # Handle special cases
1849
+ if user_input in ["--help", "-h", "help"]:
1850
+ await cli.handle_help({})
1851
+ return
1852
+
1853
+ if user_input in ["--version", "-v", "version"]:
1854
+ await cli.handle_version({})
1855
+ return
1856
+
1857
+ # Parse natural language
1858
+ command_name, params = cli.parse_natural_language(user_input)
1859
+
1860
+ if command_name:
1861
+ # Execute parsed command
1862
+ success = await cli.execute_command(command_name, params)
1863
+
1864
+ if success:
1865
+ cli._success("Command completed successfully!")
1866
+ else:
1867
+ cli._error("Command execution failed")
1868
+ sys.exit(1)
1869
+ else:
1870
+ # Unknown command - show suggestions
1871
+ cli._warning(f"I didn't understand: '{user_input}'")
1872
+ cli._info("Try something like:")
1873
+ cli._info(' createsonline "create new project called myapp"')
1874
+ cli._info(' createsonline "start development server"')
1875
+ cli._info(' createsonline "show framework info"')
1876
+ cli._info(' createsonline help')
1877
+ sys.exit(1)
1878
+
1879
+
1880
+ def run_cli():
1881
+ """Synchronous CLI runner"""
1882
+ try:
1883
+ if sys.version_info >= (3, 7):
1884
+ asyncio.run(main())
1885
+ else:
1886
+ # Fallback for older Python versions
1887
+ loop = asyncio.get_event_loop()
1888
+ loop.run_until_complete(main())
1889
+ except KeyboardInterrupt:
1890
+ print("\n⚠️ Operation cancelled by user")
1891
+ sys.exit(1)
1892
+ except Exception as e:
1893
+ print(f"❌ CLI Error: {e}")
1894
+ sys.exit(1)
1895
+
1896
+
1897
+ # ========================================
1898
+ # LEGACY COMMAND SUPPORT (Optional)
1899
+ # ========================================
1900
+
1901
+ def serve(
1902
+ port: int = 8000,
1903
+ host: str = "127.0.0.1",
1904
+ reload: bool = True,
1905
+ workers: int = 1
1906
+ ):
1907
+ """Legacy serve command for backward compatibility"""
1908
+ print("🔄 Converting to natural language...")
1909
+ cmd = f"start development server on port {port}"
1910
+ sys.argv = ["createsonline", cmd]
1911
+ run_cli()
1912
+
1913
+
1914
+ def dev(port: int = 8000, host: str = "127.0.0.1"):
1915
+ """Legacy dev command"""
1916
+ serve(port=port, host=host, reload=True)
1917
+
1918
+
1919
+ def prod(port: int = 8000, workers: int = 4):
1920
+ """Legacy production command"""
1921
+ cmd = f"start production server with {workers} workers"
1922
+ sys.argv = ["createsonline", cmd]
1923
+ run_cli()
1924
+
1925
+
1926
+ def new(project_name: str, ai: bool = True, admin: bool = True, auth: bool = True):
1927
+ """Legacy new project command"""
1928
+ features = []
1929
+ if ai:
1930
+ features.append("with ai features")
1931
+ if admin:
1932
+ features.append("with admin")
1933
+ if auth:
1934
+ features.append("with auth")
1935
+
1936
+ cmd = f"create new project called {project_name} {' '.join(features)}"
1937
+ sys.argv = ["createsonline", cmd]
1938
+ run_cli()
1939
+
1940
+
1941
+ def info():
1942
+ """Legacy info command"""
1943
+ sys.argv = ["createsonline", "show framework info"]
1944
+ run_cli()
1945
+
1946
+
1947
+ def version():
1948
+ """Legacy version command"""
1949
+ sys.argv = ["createsonline", "version"]
1950
+ run_cli()
1951
+
1952
+
1953
+ def shell():
1954
+ """Legacy shell command"""
1955
+ sys.argv = ["createsonline", "shell"]
1956
+ run_cli()
1957
+
1958
+
1959
+ def createsuperuser():
1960
+ """Legacy createsuperuser command"""
1961
+ sys.argv = ["createsonline", "create superuser"]
1962
+ run_cli()
1963
+
1964
+
1965
+ # ========================================
1966
+ # TYPER APP FALLBACK (If Available)
1967
+ # ========================================
1968
+
1969
+ if TYPER_AVAILABLE:
1970
+ # Create Typer app for advanced users who prefer traditional CLI
1971
+ typer_app = typer.Typer(
1972
+ name="createsonline",
1973
+ help="CREATESONLINE Framework - Natural Language CLI",
1974
+ add_completion=False,
1975
+ rich_markup_mode="rich",
1976
+ no_args_is_help=True
1977
+ )
1978
+
1979
+ # Add legacy commands to Typer app
1980
+ typer_app.command("serve")(serve)
1981
+ typer_app.command("dev")(dev)
1982
+ typer_app.command("prod")(prod)
1983
+ typer_app.command("new")(new)
1984
+ typer_app.command("info")(info)
1985
+ typer_app.command("version")(version)
1986
+ typer_app.command("shell")(shell)
1987
+ typer_app.command("createsuperuser")(createsuperuser)
1988
+
1989
+ # Main command that handles natural language
1990
+ @typer_app.callback(invoke_without_command=True)
1991
+ def main_callback(
1992
+ ctx, # FIXED: Remove type annotation to avoid stub issues
1993
+ natural_command: str = typer.Argument(None, help="Natural language command")
1994
+ ):
1995
+ """
1996
+ C⎯● CREATESONLINE Natural Language CLI
1997
+
1998
+ Express your intent naturally:
1999
+ createsonline "create new AI-powered project called blog"
2000
+ createsonline "start development server on port 8000"
2001
+ """
2002
+ if ctx.invoked_subcommand is None:
2003
+ if natural_command:
2004
+ sys.argv = ["createsonline", natural_command]
2005
+ run_cli()
2006
+ else:
2007
+ # Show help
2008
+ sys.argv = ["createsonline", "help"]
2009
+ run_cli()
2010
+
2011
+ # Export the Typer app
2012
+ app = typer_app
2013
+
2014
+ else:
2015
+ # No Typer available - use our internal implementation
2016
+ app = None
2017
+
2018
+
2019
+ # ========================================
2020
+ # MODULE EXPORTS
2021
+ # ========================================
2022
+
2023
+ __all__ = [
2024
+ 'main',
2025
+ 'run_cli',
2026
+ 'CreatesonlineNaturalLanguageCLI',
2027
+ 'serve',
2028
+ 'dev',
2029
+ 'prod',
2030
+ 'new',
2031
+ 'info',
2032
+ 'version',
2033
+ 'shell',
2034
+ 'createsuperuser'
2035
+ ]
2036
+
2037
+ # Entry point for console scripts
2038
+ if __name__ == "__main__":
2039
+ run_cli()
2040
+
2041
+