quantum-framework 0.9.0__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 (262) hide show
  1. quantum/__init__.py +1 -0
  2. quantum/cli/__init__.py +2 -0
  3. quantum/cli/commands/__init__.py +15 -0
  4. quantum/cli/commands/build.py +417 -0
  5. quantum/cli/commands/dev.py +185 -0
  6. quantum/cli/commands/docs.py +329 -0
  7. quantum/cli/commands/lint.py +523 -0
  8. quantum/cli/commands/migrate.py +527 -0
  9. quantum/cli/commands/new.py +622 -0
  10. quantum/cli/commands/serve.py +190 -0
  11. quantum/cli/commands/test.py +193 -0
  12. quantum/cli/deploy.py +810 -0
  13. quantum/cli/hot_reload.py +951 -0
  14. quantum/cli/jobs.py +356 -0
  15. quantum/cli/mq.py +582 -0
  16. quantum/cli/pkg.py +390 -0
  17. quantum/cli/runner.py +547 -0
  18. quantum/cli/server_process.py +159 -0
  19. quantum/cli/utils.py +334 -0
  20. quantum/compiler/__init__.py +30 -0
  21. quantum/compiler/base_generator.py +367 -0
  22. quantum/compiler/cli.py +295 -0
  23. quantum/compiler/expression_transformer.py +444 -0
  24. quantum/compiler/javascript/__init__.py +10 -0
  25. quantum/compiler/javascript/generator.py +659 -0
  26. quantum/compiler/optimizer.py +270 -0
  27. quantum/compiler/python/__init__.py +10 -0
  28. quantum/compiler/python/generator.py +883 -0
  29. quantum/compiler/python/runtime.py +863 -0
  30. quantum/compiler/transpiler.py +330 -0
  31. quantum/core/__init__.py +3 -0
  32. quantum/core/ast_nodes.py +2611 -0
  33. quantum/core/expression_diagnostics.py +87 -0
  34. quantum/core/expression_stdlib.py +148 -0
  35. quantum/core/expressions.py +591 -0
  36. quantum/core/features/agents/src/__init__.py +30 -0
  37. quantum/core/features/agents/src/ast_node.py +540 -0
  38. quantum/core/features/conditionals/src/__init__.py +8 -0
  39. quantum/core/features/conditionals/src/ast_node.py +68 -0
  40. quantum/core/features/data_fetching/src/__init__.py +21 -0
  41. quantum/core/features/data_fetching/src/ast_node.py +312 -0
  42. quantum/core/features/data_fetching/src/desktop_adapter.py +351 -0
  43. quantum/core/features/data_fetching/src/html_adapter.py +474 -0
  44. quantum/core/features/data_fetching/src/parser.py +225 -0
  45. quantum/core/features/data_import/src/__init__.py +0 -0
  46. quantum/core/features/data_import/src/ast_node.py +291 -0
  47. quantum/core/features/data_import/src/runtime.py +538 -0
  48. quantum/core/features/dump/src/__init__.py +12 -0
  49. quantum/core/features/dump/src/ast_node.py +106 -0
  50. quantum/core/features/dump/src/parser.py +61 -0
  51. quantum/core/features/dump/src/runtime.py +246 -0
  52. quantum/core/features/functions/src/__init__.py +8 -0
  53. quantum/core/features/functions/src/ast_node.py +149 -0
  54. quantum/core/features/game_engine_2d/src/__init__.py +19 -0
  55. quantum/core/features/game_engine_2d/src/ast_nodes.py +1719 -0
  56. quantum/core/features/game_engine_2d/src/parser.py +983 -0
  57. quantum/core/features/invocation/src/__init__.py +0 -0
  58. quantum/core/features/invocation/src/ast_node.py +146 -0
  59. quantum/core/features/invocation/src/runtime.py +327 -0
  60. quantum/core/features/knowledge_base/src/__init__.py +6 -0
  61. quantum/core/features/knowledge_base/src/ast_node.py +113 -0
  62. quantum/core/features/knowledge_base/src/parser.py +82 -0
  63. quantum/core/features/logging/src/__init__.py +12 -0
  64. quantum/core/features/logging/src/ast_node.py +111 -0
  65. quantum/core/features/logging/src/parser.py +50 -0
  66. quantum/core/features/logging/src/runtime.py +190 -0
  67. quantum/core/features/loops/src/__init__.py +8 -0
  68. quantum/core/features/loops/src/ast_node.py +60 -0
  69. quantum/core/features/query/src/__init__.py +0 -0
  70. quantum/core/features/query/src/database_service.py +322 -0
  71. quantum/core/features/query/src/query_validators.py +20 -0
  72. quantum/core/features/state_management/src/__init__.py +11 -0
  73. quantum/core/features/state_management/src/ast_node.py +228 -0
  74. quantum/core/features/terminal_engine/src/__init__.py +21 -0
  75. quantum/core/features/terminal_engine/src/ast_nodes.py +560 -0
  76. quantum/core/features/terminal_engine/src/parser.py +361 -0
  77. quantum/core/features/testing_engine/src/__init__.py +41 -0
  78. quantum/core/features/testing_engine/src/ast_nodes.py +1212 -0
  79. quantum/core/features/testing_engine/src/parser.py +604 -0
  80. quantum/core/features/theming/src/__init__.py +48 -0
  81. quantum/core/features/theming/src/ast_node.py +137 -0
  82. quantum/core/features/theming/src/presets.py +405 -0
  83. quantum/core/features/ui_engine/src/__init__.py +20 -0
  84. quantum/core/features/ui_engine/src/ast_nodes.py +1854 -0
  85. quantum/core/features/ui_engine/src/parser.py +1106 -0
  86. quantum/core/features/websocket/src/__init__.py +24 -0
  87. quantum/core/features/websocket/src/ast_node.py +247 -0
  88. quantum/core/html_compat.py +299 -0
  89. quantum/core/parser.py +1235 -0
  90. quantum/core/parser_registry.py +213 -0
  91. quantum/core/parsers/__init__.py +76 -0
  92. quantum/core/parsers/ai/__init__.py +12 -0
  93. quantum/core/parsers/ai/agent_parser.py +106 -0
  94. quantum/core/parsers/ai/knowledge_parser.py +86 -0
  95. quantum/core/parsers/ai/llm_parser.py +78 -0
  96. quantum/core/parsers/ai/team_parser.py +88 -0
  97. quantum/core/parsers/base.py +322 -0
  98. quantum/core/parsers/composition/__init__.py +10 -0
  99. quantum/core/parsers/composition/import_parser.py +50 -0
  100. quantum/core/parsers/composition/slot_parser.py +48 -0
  101. quantum/core/parsers/control_flow/__init__.py +11 -0
  102. quantum/core/parsers/control_flow/if_parser.py +68 -0
  103. quantum/core/parsers/control_flow/loop_parser.py +105 -0
  104. quantum/core/parsers/control_flow/set_parser.py +89 -0
  105. quantum/core/parsers/data/__init__.py +12 -0
  106. quantum/core/parsers/data/data_parser.py +217 -0
  107. quantum/core/parsers/data/invoke_parser.py +116 -0
  108. quantum/core/parsers/data/query_parser.py +188 -0
  109. quantum/core/parsers/data/transaction_parser.py +77 -0
  110. quantum/core/parsers/events/__init__.py +9 -0
  111. quantum/core/parsers/events/dispatch_event_parser.py +44 -0
  112. quantum/core/parsers/forms/__init__.py +11 -0
  113. quantum/core/parsers/forms/action_parser.py +54 -0
  114. quantum/core/parsers/forms/flash_parser.py +34 -0
  115. quantum/core/parsers/forms/redirect_parser.py +33 -0
  116. quantum/core/parsers/functions/__init__.py +11 -0
  117. quantum/core/parsers/functions/function_parser.py +137 -0
  118. quantum/core/parsers/functions/param_parser.py +66 -0
  119. quantum/core/parsers/functions/return_parser.py +31 -0
  120. quantum/core/parsers/html/__init__.py +10 -0
  121. quantum/core/parsers/html/component_call_parser.py +130 -0
  122. quantum/core/parsers/html/html_parser.py +115 -0
  123. quantum/core/parsers/jobs/__init__.py +11 -0
  124. quantum/core/parsers/jobs/job_parser.py +71 -0
  125. quantum/core/parsers/jobs/schedule_parser.py +62 -0
  126. quantum/core/parsers/jobs/thread_parser.py +57 -0
  127. quantum/core/parsers/messaging/__init__.py +17 -0
  128. quantum/core/parsers/messaging/message_ack_parser.py +30 -0
  129. quantum/core/parsers/messaging/message_nack_parser.py +30 -0
  130. quantum/core/parsers/messaging/message_parser.py +114 -0
  131. quantum/core/parsers/messaging/queue_parser.py +61 -0
  132. quantum/core/parsers/messaging/websocket_parser.py +121 -0
  133. quantum/core/parsers/persistence/__init__.py +9 -0
  134. quantum/core/parsers/persistence/persist_parser.py +64 -0
  135. quantum/core/parsers/routing/__init__.py +9 -0
  136. quantum/core/parsers/routing/route_parser.py +41 -0
  137. quantum/core/parsers/scripting/__init__.py +12 -0
  138. quantum/core/parsers/scripting/pyclass_parser.py +62 -0
  139. quantum/core/parsers/scripting/pydecorator_parser.py +68 -0
  140. quantum/core/parsers/scripting/pyimport_parser.py +52 -0
  141. quantum/core/parsers/scripting/python_parser.py +49 -0
  142. quantum/core/parsers/services/__init__.py +12 -0
  143. quantum/core/parsers/services/dump_parser.py +52 -0
  144. quantum/core/parsers/services/file_parser.py +48 -0
  145. quantum/core/parsers/services/log_parser.py +46 -0
  146. quantum/core/parsers/services/mail_parser.py +65 -0
  147. quantum/core/tiers.py +82 -0
  148. quantum/packages/__init__.py +28 -0
  149. quantum/packages/manager.py +413 -0
  150. quantum/packages/manifest.py +351 -0
  151. quantum/packages/registry.py +399 -0
  152. quantum/packages/resolver.py +336 -0
  153. quantum/plugins/__init__.py +33 -0
  154. quantum/plugins/hooks.py +329 -0
  155. quantum/plugins/loader.py +479 -0
  156. quantum/plugins/manifest.py +336 -0
  157. quantum/plugins/registry.py +371 -0
  158. quantum/runtime/__init__.py +28 -0
  159. quantum/runtime/action_handler.py +443 -0
  160. quantum/runtime/adapters/__init__.py +88 -0
  161. quantum/runtime/adapters/memory_adapter.py +690 -0
  162. quantum/runtime/adapters/rabbitmq_adapter.py +715 -0
  163. quantum/runtime/adapters/redis_adapter.py +582 -0
  164. quantum/runtime/adapters/sqlite_adapter.py +414 -0
  165. quantum/runtime/agent_service.py +1133 -0
  166. quantum/runtime/api_server.py +86 -0
  167. quantum/runtime/ast_cache.py +506 -0
  168. quantum/runtime/auth_service.py +267 -0
  169. quantum/runtime/component.py +990 -0
  170. quantum/runtime/component_composer.py +319 -0
  171. quantum/runtime/component_resolver.py +174 -0
  172. quantum/runtime/database_service.py +598 -0
  173. quantum/runtime/email_service.py +162 -0
  174. quantum/runtime/error_handler.py +295 -0
  175. quantum/runtime/execution_context.py +286 -0
  176. quantum/runtime/executor_registry.py +171 -0
  177. quantum/runtime/executors/__init__.py +71 -0
  178. quantum/runtime/executors/ai/__init__.py +12 -0
  179. quantum/runtime/executors/ai/agent_executor.py +217 -0
  180. quantum/runtime/executors/ai/knowledge_executor.py +114 -0
  181. quantum/runtime/executors/ai/llm_executor.py +153 -0
  182. quantum/runtime/executors/ai/team_executor.py +171 -0
  183. quantum/runtime/executors/base.py +262 -0
  184. quantum/runtime/executors/control_flow/__init__.py +11 -0
  185. quantum/runtime/executors/control_flow/if_executor.py +93 -0
  186. quantum/runtime/executors/control_flow/loop_executor.py +307 -0
  187. quantum/runtime/executors/control_flow/set_executor.py +412 -0
  188. quantum/runtime/executors/data/__init__.py +12 -0
  189. quantum/runtime/executors/data/data_executor.py +145 -0
  190. quantum/runtime/executors/data/invoke_executor.py +176 -0
  191. quantum/runtime/executors/data/query_executor.py +256 -0
  192. quantum/runtime/executors/data/transaction_executor.py +91 -0
  193. quantum/runtime/executors/jobs/__init__.py +11 -0
  194. quantum/runtime/executors/jobs/job_executor.py +190 -0
  195. quantum/runtime/executors/jobs/schedule_executor.py +132 -0
  196. quantum/runtime/executors/jobs/thread_executor.py +127 -0
  197. quantum/runtime/executors/messaging/__init__.py +17 -0
  198. quantum/runtime/executors/messaging/message_ack_executor.py +51 -0
  199. quantum/runtime/executors/messaging/message_executor.py +174 -0
  200. quantum/runtime/executors/messaging/queue_executor.py +103 -0
  201. quantum/runtime/executors/messaging/websocket_executor.py +197 -0
  202. quantum/runtime/executors/scripting/__init__.py +11 -0
  203. quantum/runtime/executors/scripting/pyclass_executor.py +90 -0
  204. quantum/runtime/executors/scripting/pyimport_executor.py +81 -0
  205. quantum/runtime/executors/scripting/python_executor.py +249 -0
  206. quantum/runtime/executors/services/__init__.py +12 -0
  207. quantum/runtime/executors/services/dump_executor.py +72 -0
  208. quantum/runtime/executors/services/file_executor.py +89 -0
  209. quantum/runtime/executors/services/log_executor.py +77 -0
  210. quantum/runtime/executors/services/mail_executor.py +81 -0
  211. quantum/runtime/expression_cache.py +498 -0
  212. quantum/runtime/file_upload_service.py +326 -0
  213. quantum/runtime/function_registry.py +118 -0
  214. quantum/runtime/game_builder.py +166 -0
  215. quantum/runtime/game_code_generator.py +2371 -0
  216. quantum/runtime/game_templates.py +2006 -0
  217. quantum/runtime/godot_code_generator.py +4681 -0
  218. quantum/runtime/godot_templates.py +1449 -0
  219. quantum/runtime/job_executor.py +1599 -0
  220. quantum/runtime/knowledge_service.py +500 -0
  221. quantum/runtime/llm_cache.py +100 -0
  222. quantum/runtime/llm_providers.py +704 -0
  223. quantum/runtime/llm_service.py +287 -0
  224. quantum/runtime/logging_setup.py +140 -0
  225. quantum/runtime/message_broker.py +364 -0
  226. quantum/runtime/message_queue_service.py +571 -0
  227. quantum/runtime/param_validation.py +184 -0
  228. quantum/runtime/pypy_compat.py +315 -0
  229. quantum/runtime/python_bridge.py +698 -0
  230. quantum/runtime/query_validators.py +304 -0
  231. quantum/runtime/renderer.py +733 -0
  232. quantum/runtime/service_container.py +444 -0
  233. quantum/runtime/terminal_builder.py +76 -0
  234. quantum/runtime/terminal_code_generator.py +607 -0
  235. quantum/runtime/terminal_templates.py +243 -0
  236. quantum/runtime/testing_builder.py +77 -0
  237. quantum/runtime/testing_code_generator.py +833 -0
  238. quantum/runtime/testing_templates.py +85 -0
  239. quantum/runtime/ui_builder.py +188 -0
  240. quantum/runtime/ui_desktop_adapter.py +1730 -0
  241. quantum/runtime/ui_desktop_templates.py +307 -0
  242. quantum/runtime/ui_html_adapter.py +2691 -0
  243. quantum/runtime/ui_html_templates.py +2297 -0
  244. quantum/runtime/ui_mobile_adapter.py +1832 -0
  245. quantum/runtime/ui_mobile_templates.py +1003 -0
  246. quantum/runtime/ui_textual_adapter.py +1866 -0
  247. quantum/runtime/ui_textual_templates.py +45 -0
  248. quantum/runtime/ui_tokens.py +465 -0
  249. quantum/runtime/ui_validator.py +365 -0
  250. quantum/runtime/validators.py +256 -0
  251. quantum/runtime/web_server.py +1766 -0
  252. quantum/runtime/websocket_adapter.py +501 -0
  253. quantum/runtime/websocket_service.py +585 -0
  254. quantum/runtime/websocket_transport.py +289 -0
  255. quantum/runtime/wsgi.py +101 -0
  256. quantum/utils/__init__.py +1 -0
  257. quantum_framework-0.9.0.dist-info/METADATA +244 -0
  258. quantum_framework-0.9.0.dist-info/RECORD +262 -0
  259. quantum_framework-0.9.0.dist-info/WHEEL +5 -0
  260. quantum_framework-0.9.0.dist-info/entry_points.txt +2 -0
  261. quantum_framework-0.9.0.dist-info/licenses/LICENSE +21 -0
  262. quantum_framework-0.9.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,162 @@
1
+ """
2
+ Phase I: Email Service
3
+
4
+ ColdFusion cfmail-inspired email sending with SMTP support.
5
+ """
6
+
7
+ import smtplib
8
+ import os
9
+ from email.mime.text import MIMEText
10
+ from email.mime.multipart import MIMEMultipart
11
+ from email.mime.base import MIMEBase
12
+ from email import encoders
13
+ from typing import List, Dict, Any, Optional
14
+ from pathlib import Path
15
+
16
+
17
+ class EmailError(Exception):
18
+ """Raised when email sending fails"""
19
+ pass
20
+
21
+
22
+ class EmailService:
23
+ """Service for sending emails via SMTP"""
24
+
25
+ def __init__(self):
26
+ """Initialize email service with config from environment"""
27
+ self.smtp_host = os.getenv('SMTP_HOST', 'localhost')
28
+ self.smtp_port = int(os.getenv('SMTP_PORT', '587'))
29
+ self.smtp_user = os.getenv('SMTP_USER', '')
30
+ self.smtp_password = os.getenv('SMTP_PASSWORD', '')
31
+ self.smtp_use_tls = os.getenv('SMTP_USE_TLS', 'true').lower() == 'true'
32
+ self.default_from = os.getenv('SMTP_FROM', 'noreply@quantum.dev')
33
+
34
+ def send_email(
35
+ self,
36
+ to: str,
37
+ subject: str,
38
+ body: str,
39
+ from_addr: Optional[str] = None,
40
+ cc: Optional[str] = None,
41
+ bcc: Optional[str] = None,
42
+ reply_to: Optional[str] = None,
43
+ email_type: str = "html",
44
+ attachments: Optional[List[str]] = None
45
+ ) -> Dict[str, Any]:
46
+ """
47
+ Send email via SMTP
48
+
49
+ Args:
50
+ to: Recipient email(s) (comma-separated)
51
+ subject: Email subject
52
+ body: Email body content
53
+ from_addr: Sender email (uses default if not provided)
54
+ cc: CC recipients (comma-separated)
55
+ bcc: BCC recipients (comma-separated)
56
+ reply_to: Reply-To address
57
+ email_type: 'html' or 'text'
58
+ attachments: List of file paths to attach
59
+
60
+ Returns:
61
+ Dict with send result
62
+
63
+ Raises:
64
+ EmailError: If sending fails
65
+ """
66
+ try:
67
+ # Create message
68
+ msg = MIMEMultipart()
69
+ msg['From'] = from_addr or self.default_from
70
+ msg['To'] = to
71
+ msg['Subject'] = subject
72
+
73
+ if cc:
74
+ msg['Cc'] = cc
75
+ if reply_to:
76
+ msg['Reply-To'] = reply_to
77
+
78
+ # Attach body
79
+ mime_type = 'html' if email_type == 'html' else 'plain'
80
+ msg.attach(MIMEText(body, mime_type, 'utf-8'))
81
+
82
+ # Attach files if provided
83
+ if attachments:
84
+ for file_path in attachments:
85
+ self._attach_file(msg, file_path)
86
+
87
+ # Prepare recipients
88
+ recipients = self._parse_recipients(to, cc, bcc)
89
+
90
+ # Send email
91
+ if os.getenv('EMAIL_MOCK', 'true').lower() == 'true':
92
+ # Mock mode for development (don't actually send)
93
+ print(f"[MOCK] Email sent to {to}")
94
+ print(f" Subject: {subject}")
95
+ print(f" From: {msg['From']}")
96
+ print(f" Type: {email_type}")
97
+ return {
98
+ 'success': True,
99
+ 'mock': True,
100
+ 'to': to,
101
+ 'subject': subject,
102
+ 'message': 'Email mock-sent successfully'
103
+ }
104
+ else:
105
+ # Real SMTP sending
106
+ with smtplib.SMTP(self.smtp_host, self.smtp_port) as server:
107
+ if self.smtp_use_tls:
108
+ server.starttls()
109
+
110
+ if self.smtp_user and self.smtp_password:
111
+ server.login(self.smtp_user, self.smtp_password)
112
+
113
+ server.sendmail(msg['From'], recipients, msg.as_string())
114
+
115
+ return {
116
+ 'success': True,
117
+ 'to': to,
118
+ 'subject': subject,
119
+ 'message': 'Email sent successfully'
120
+ }
121
+
122
+ except Exception as e:
123
+ raise EmailError(f"Failed to send email: {e}")
124
+
125
+ def _attach_file(self, msg: MIMEMultipart, file_path: str):
126
+ """Attach a file to email message"""
127
+ try:
128
+ path = Path(file_path)
129
+ if not path.exists():
130
+ raise EmailError(f"Attachment file not found: {file_path}")
131
+
132
+ with open(file_path, 'rb') as f:
133
+ part = MIMEBase('application', 'octet-stream')
134
+ part.set_payload(f.read())
135
+
136
+ encoders.encode_base64(part)
137
+ part.add_header(
138
+ 'Content-Disposition',
139
+ f'attachment; filename= {path.name}'
140
+ )
141
+
142
+ msg.attach(part)
143
+ except Exception as e:
144
+ raise EmailError(f"Failed to attach file {file_path}: {e}")
145
+
146
+ def _parse_recipients(
147
+ self,
148
+ to: str,
149
+ cc: Optional[str] = None,
150
+ bcc: Optional[str] = None
151
+ ) -> List[str]:
152
+ """Parse comma-separated email addresses into list"""
153
+ recipients = []
154
+
155
+ if to:
156
+ recipients.extend([email.strip() for email in to.split(',')])
157
+ if cc:
158
+ recipients.extend([email.strip() for email in cc.split(',')])
159
+ if bcc:
160
+ recipients.extend([email.strip() for email in bcc.split(',')])
161
+
162
+ return recipients
@@ -0,0 +1,295 @@
1
+ """
2
+ Enhanced Error Handler - Phase C: Developer Experience
3
+
4
+ Provides better error messages with:
5
+ - Context (line numbers, code snippets)
6
+ - Suggestions (did you mean...?)
7
+ - Helpful hints
8
+ - Color-coded output
9
+ """
10
+
11
+ import sys
12
+ from pathlib import Path
13
+ from typing import Optional, List
14
+ import difflib
15
+
16
+ class QuantumError(Exception):
17
+ """Base class for Quantum errors with enhanced context"""
18
+
19
+ def __init__(self, message: str, file_path: Optional[str] = None,
20
+ line: Optional[int] = None, column: Optional[int] = None,
21
+ suggestion: Optional[str] = None, hint: Optional[str] = None):
22
+ self.message = message
23
+ self.file_path = file_path
24
+ self.line = line
25
+ self.column = column
26
+ self.suggestion = suggestion
27
+ self.hint = hint
28
+ super().__init__(self.format_error())
29
+
30
+ def format_error(self) -> str:
31
+ """Format error message with context"""
32
+ parts = []
33
+
34
+ # Header
35
+ parts.append("=" * 60)
36
+ parts.append("❌ QUANTUM ERROR")
37
+ parts.append("=" * 60)
38
+
39
+ # Location
40
+ if self.file_path:
41
+ location = f"📂 File: {self.file_path}"
42
+ if self.line:
43
+ location += f":{self.line}"
44
+ if self.column:
45
+ location += f":{self.column}"
46
+ parts.append(location)
47
+
48
+ # Error message
49
+ parts.append(f"\n💥 {self.message}")
50
+
51
+ # Code context
52
+ if self.file_path and self.line:
53
+ context = self._get_code_context()
54
+ if context:
55
+ parts.append("\n📝 Code:")
56
+ parts.append(context)
57
+
58
+ # Suggestion
59
+ if self.suggestion:
60
+ parts.append(f"\n💡 Suggestion: {self.suggestion}")
61
+
62
+ # Hint
63
+ if self.hint:
64
+ parts.append(f"\n🔍 Hint: {self.hint}")
65
+
66
+ parts.append("=" * 60)
67
+
68
+ return "\n".join(parts)
69
+
70
+ def _get_code_context(self, context_lines: int = 3) -> Optional[str]:
71
+ """Get code context around error line"""
72
+ try:
73
+ file_path = Path(self.file_path)
74
+ if not file_path.exists():
75
+ return None
76
+
77
+ lines = file_path.read_text(encoding='utf-8').splitlines()
78
+
79
+ start = max(0, self.line - context_lines - 1)
80
+ end = min(len(lines), self.line + context_lines)
81
+
82
+ context_parts = []
83
+ for i in range(start, end):
84
+ line_num = i + 1
85
+ line_content = lines[i]
86
+
87
+ # Mark error line with arrow
88
+ if line_num == self.line:
89
+ context_parts.append(f" → {line_num:4d} | {line_content}")
90
+ # Add column pointer if available
91
+ if self.column:
92
+ pointer = " " * (self.column + 10) + "^"
93
+ context_parts.append(pointer)
94
+ else:
95
+ context_parts.append(f" {line_num:4d} | {line_content}")
96
+
97
+ return "\n".join(context_parts)
98
+
99
+ except Exception:
100
+ return None
101
+
102
+
103
+ class ComponentNotFoundError(QuantumError):
104
+ """Component import not found"""
105
+
106
+ def __init__(self, component_name: str, file_path: str, line: int,
107
+ available_components: List[str] = None):
108
+ # Find similar component names
109
+ suggestion = None
110
+ if available_components:
111
+ matches = difflib.get_close_matches(component_name, available_components, n=3, cutoff=0.6)
112
+ if matches:
113
+ if len(matches) == 1:
114
+ suggestion = f"Did you mean '{matches[0]}'?"
115
+ else:
116
+ suggestion = f"Did you mean one of: {', '.join(matches)}?"
117
+
118
+ hint = f"Add: <q:import component=\"{component_name}\" />"
119
+
120
+ super().__init__(
121
+ f"Component '{component_name}' not found",
122
+ file_path=file_path,
123
+ line=line,
124
+ suggestion=suggestion,
125
+ hint=hint
126
+ )
127
+
128
+
129
+ class ValidationErrorWithContext(QuantumError):
130
+ """Validation error with context"""
131
+
132
+ def __init__(self, field_name: str, validation_type: str,
133
+ value: any, file_path: str = None, line: int = None):
134
+ message = f"Validation failed for field '{field_name}' ({validation_type})"
135
+
136
+ if validation_type == "required":
137
+ suggestion = f"Field '{field_name}' is required but was not provided"
138
+ elif validation_type == "type":
139
+ suggestion = f"Expected type differs from provided value: {value}"
140
+ elif validation_type == "minlength":
141
+ suggestion = f"Value '{value}' is too short"
142
+ elif validation_type == "maxlength":
143
+ suggestion = f"Value '{value}' is too long"
144
+ elif validation_type == "pattern":
145
+ suggestion = f"Value '{value}' doesn't match required pattern"
146
+ else:
147
+ suggestion = f"Validation '{validation_type}' failed for value: {value}"
148
+
149
+ super().__init__(
150
+ message,
151
+ file_path=file_path,
152
+ line=line,
153
+ suggestion=suggestion
154
+ )
155
+
156
+
157
+ class QueryErrorWithContext(QuantumError):
158
+ """Query error with SQL context"""
159
+
160
+ def __init__(self, query_name: str, sql: str, error: str,
161
+ file_path: str = None, line: int = None):
162
+ message = f"Query '{query_name}' failed"
163
+
164
+ # Provide SQL-specific suggestions
165
+ suggestion = None
166
+ if "syntax error" in error.lower():
167
+ suggestion = "Check your SQL syntax"
168
+ elif "table" in error.lower() and "doesn't exist" in error.lower():
169
+ suggestion = "Table doesn't exist - check your database schema"
170
+ elif "column" in error.lower():
171
+ suggestion = "Column doesn't exist - check your table structure"
172
+ elif "duplicate" in error.lower():
173
+ suggestion = "Duplicate entry - check for unique constraints"
174
+
175
+ hint = f"SQL: {sql[:100]}..." if len(sql) > 100 else f"SQL: {sql}"
176
+
177
+ super().__init__(
178
+ f"{message}: {error}",
179
+ file_path=file_path,
180
+ line=line,
181
+ suggestion=suggestion,
182
+ hint=hint
183
+ )
184
+
185
+
186
+ class TransactionErrorWithContext(QuantumError):
187
+ """Transaction error with rollback info"""
188
+
189
+ def __init__(self, error: str, statements_executed: int,
190
+ file_path: str = None, line: int = None):
191
+ message = "Transaction failed and was rolled back"
192
+
193
+ suggestion = f"{statements_executed} statement(s) were executed before failure"
194
+ hint = "All changes have been rolled back. Check the error above and fix the issue."
195
+
196
+ super().__init__(
197
+ f"{message}: {error}",
198
+ file_path=file_path,
199
+ line=line,
200
+ suggestion=suggestion,
201
+ hint=hint
202
+ )
203
+
204
+
205
+ class FileUploadErrorWithContext(QuantumError):
206
+ """File upload error with details"""
207
+
208
+ def __init__(self, error: str, filename: str = None,
209
+ file_size: int = None, max_size: int = None,
210
+ file_path: str = None, line: int = None):
211
+ message = f"File upload failed"
212
+
213
+ suggestion = None
214
+ if "too large" in error.lower():
215
+ if file_size and max_size:
216
+ suggestion = f"File is {file_size} bytes but maximum is {max_size} bytes"
217
+ elif "type" in error.lower() or "extension" in error.lower():
218
+ suggestion = "File type not allowed - check allowed extensions"
219
+
220
+ hint = None
221
+ if filename:
222
+ hint = f"Filename: {filename}"
223
+
224
+ super().__init__(
225
+ f"{message}: {error}",
226
+ file_path=file_path,
227
+ line=line,
228
+ suggestion=suggestion,
229
+ hint=hint
230
+ )
231
+
232
+
233
+ class ErrorHandler:
234
+ """Central error handler for better error reporting"""
235
+
236
+ _logger = None
237
+
238
+ @classmethod
239
+ def _get_logger(cls):
240
+ if cls._logger is None:
241
+ import logging
242
+ cls._logger = logging.getLogger('quantum.errors')
243
+ return cls._logger
244
+
245
+ @staticmethod
246
+ def handle_parse_error(error: Exception, file_path: str) -> QuantumError:
247
+ """Convert parse errors to enhanced errors"""
248
+ error_msg = str(error)
249
+
250
+ # Extract line and column from XML parse errors
251
+ line = None
252
+ column = None
253
+ if "line" in error_msg:
254
+ import re
255
+ match = re.search(r'line (\d+)', error_msg)
256
+ if match:
257
+ line = int(match.group(1))
258
+ match = re.search(r'column (\d+)', error_msg)
259
+ if match:
260
+ column = int(match.group(1))
261
+
262
+ return QuantumError(
263
+ f"Parse error: {error_msg}",
264
+ file_path=file_path,
265
+ line=line,
266
+ column=column,
267
+ suggestion="Check your XML syntax",
268
+ hint="Make sure all tags are properly closed and attributes are quoted"
269
+ )
270
+
271
+ @staticmethod
272
+ def handle_runtime_error(error: Exception, component_name: str,
273
+ file_path: str = None) -> QuantumError:
274
+ """Convert runtime errors to enhanced errors"""
275
+ return QuantumError(
276
+ f"Runtime error in component '{component_name}': {error}",
277
+ file_path=file_path,
278
+ suggestion="Check your component logic and variable names",
279
+ hint="Use quantum inspect <component> to debug"
280
+ )
281
+
282
+ @classmethod
283
+ def print_warning(cls, message: str):
284
+ """Log formatted warning"""
285
+ cls._get_logger().warning(message)
286
+
287
+ @classmethod
288
+ def print_info(cls, message: str):
289
+ """Log formatted info"""
290
+ cls._get_logger().info(message)
291
+
292
+ @classmethod
293
+ def print_success(cls, message: str):
294
+ """Log formatted success"""
295
+ cls._get_logger().info(message)