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.
- quantum/__init__.py +1 -0
- quantum/cli/__init__.py +2 -0
- quantum/cli/commands/__init__.py +15 -0
- quantum/cli/commands/build.py +417 -0
- quantum/cli/commands/dev.py +185 -0
- quantum/cli/commands/docs.py +329 -0
- quantum/cli/commands/lint.py +523 -0
- quantum/cli/commands/migrate.py +527 -0
- quantum/cli/commands/new.py +622 -0
- quantum/cli/commands/serve.py +190 -0
- quantum/cli/commands/test.py +193 -0
- quantum/cli/deploy.py +810 -0
- quantum/cli/hot_reload.py +951 -0
- quantum/cli/jobs.py +356 -0
- quantum/cli/mq.py +582 -0
- quantum/cli/pkg.py +390 -0
- quantum/cli/runner.py +547 -0
- quantum/cli/server_process.py +159 -0
- quantum/cli/utils.py +334 -0
- quantum/compiler/__init__.py +30 -0
- quantum/compiler/base_generator.py +367 -0
- quantum/compiler/cli.py +295 -0
- quantum/compiler/expression_transformer.py +444 -0
- quantum/compiler/javascript/__init__.py +10 -0
- quantum/compiler/javascript/generator.py +659 -0
- quantum/compiler/optimizer.py +270 -0
- quantum/compiler/python/__init__.py +10 -0
- quantum/compiler/python/generator.py +883 -0
- quantum/compiler/python/runtime.py +863 -0
- quantum/compiler/transpiler.py +330 -0
- quantum/core/__init__.py +3 -0
- quantum/core/ast_nodes.py +2611 -0
- quantum/core/expression_diagnostics.py +87 -0
- quantum/core/expression_stdlib.py +148 -0
- quantum/core/expressions.py +591 -0
- quantum/core/features/agents/src/__init__.py +30 -0
- quantum/core/features/agents/src/ast_node.py +540 -0
- quantum/core/features/conditionals/src/__init__.py +8 -0
- quantum/core/features/conditionals/src/ast_node.py +68 -0
- quantum/core/features/data_fetching/src/__init__.py +21 -0
- quantum/core/features/data_fetching/src/ast_node.py +312 -0
- quantum/core/features/data_fetching/src/desktop_adapter.py +351 -0
- quantum/core/features/data_fetching/src/html_adapter.py +474 -0
- quantum/core/features/data_fetching/src/parser.py +225 -0
- quantum/core/features/data_import/src/__init__.py +0 -0
- quantum/core/features/data_import/src/ast_node.py +291 -0
- quantum/core/features/data_import/src/runtime.py +538 -0
- quantum/core/features/dump/src/__init__.py +12 -0
- quantum/core/features/dump/src/ast_node.py +106 -0
- quantum/core/features/dump/src/parser.py +61 -0
- quantum/core/features/dump/src/runtime.py +246 -0
- quantum/core/features/functions/src/__init__.py +8 -0
- quantum/core/features/functions/src/ast_node.py +149 -0
- quantum/core/features/game_engine_2d/src/__init__.py +19 -0
- quantum/core/features/game_engine_2d/src/ast_nodes.py +1719 -0
- quantum/core/features/game_engine_2d/src/parser.py +983 -0
- quantum/core/features/invocation/src/__init__.py +0 -0
- quantum/core/features/invocation/src/ast_node.py +146 -0
- quantum/core/features/invocation/src/runtime.py +327 -0
- quantum/core/features/knowledge_base/src/__init__.py +6 -0
- quantum/core/features/knowledge_base/src/ast_node.py +113 -0
- quantum/core/features/knowledge_base/src/parser.py +82 -0
- quantum/core/features/logging/src/__init__.py +12 -0
- quantum/core/features/logging/src/ast_node.py +111 -0
- quantum/core/features/logging/src/parser.py +50 -0
- quantum/core/features/logging/src/runtime.py +190 -0
- quantum/core/features/loops/src/__init__.py +8 -0
- quantum/core/features/loops/src/ast_node.py +60 -0
- quantum/core/features/query/src/__init__.py +0 -0
- quantum/core/features/query/src/database_service.py +322 -0
- quantum/core/features/query/src/query_validators.py +20 -0
- quantum/core/features/state_management/src/__init__.py +11 -0
- quantum/core/features/state_management/src/ast_node.py +228 -0
- quantum/core/features/terminal_engine/src/__init__.py +21 -0
- quantum/core/features/terminal_engine/src/ast_nodes.py +560 -0
- quantum/core/features/terminal_engine/src/parser.py +361 -0
- quantum/core/features/testing_engine/src/__init__.py +41 -0
- quantum/core/features/testing_engine/src/ast_nodes.py +1212 -0
- quantum/core/features/testing_engine/src/parser.py +604 -0
- quantum/core/features/theming/src/__init__.py +48 -0
- quantum/core/features/theming/src/ast_node.py +137 -0
- quantum/core/features/theming/src/presets.py +405 -0
- quantum/core/features/ui_engine/src/__init__.py +20 -0
- quantum/core/features/ui_engine/src/ast_nodes.py +1854 -0
- quantum/core/features/ui_engine/src/parser.py +1106 -0
- quantum/core/features/websocket/src/__init__.py +24 -0
- quantum/core/features/websocket/src/ast_node.py +247 -0
- quantum/core/html_compat.py +299 -0
- quantum/core/parser.py +1235 -0
- quantum/core/parser_registry.py +213 -0
- quantum/core/parsers/__init__.py +76 -0
- quantum/core/parsers/ai/__init__.py +12 -0
- quantum/core/parsers/ai/agent_parser.py +106 -0
- quantum/core/parsers/ai/knowledge_parser.py +86 -0
- quantum/core/parsers/ai/llm_parser.py +78 -0
- quantum/core/parsers/ai/team_parser.py +88 -0
- quantum/core/parsers/base.py +322 -0
- quantum/core/parsers/composition/__init__.py +10 -0
- quantum/core/parsers/composition/import_parser.py +50 -0
- quantum/core/parsers/composition/slot_parser.py +48 -0
- quantum/core/parsers/control_flow/__init__.py +11 -0
- quantum/core/parsers/control_flow/if_parser.py +68 -0
- quantum/core/parsers/control_flow/loop_parser.py +105 -0
- quantum/core/parsers/control_flow/set_parser.py +89 -0
- quantum/core/parsers/data/__init__.py +12 -0
- quantum/core/parsers/data/data_parser.py +217 -0
- quantum/core/parsers/data/invoke_parser.py +116 -0
- quantum/core/parsers/data/query_parser.py +188 -0
- quantum/core/parsers/data/transaction_parser.py +77 -0
- quantum/core/parsers/events/__init__.py +9 -0
- quantum/core/parsers/events/dispatch_event_parser.py +44 -0
- quantum/core/parsers/forms/__init__.py +11 -0
- quantum/core/parsers/forms/action_parser.py +54 -0
- quantum/core/parsers/forms/flash_parser.py +34 -0
- quantum/core/parsers/forms/redirect_parser.py +33 -0
- quantum/core/parsers/functions/__init__.py +11 -0
- quantum/core/parsers/functions/function_parser.py +137 -0
- quantum/core/parsers/functions/param_parser.py +66 -0
- quantum/core/parsers/functions/return_parser.py +31 -0
- quantum/core/parsers/html/__init__.py +10 -0
- quantum/core/parsers/html/component_call_parser.py +130 -0
- quantum/core/parsers/html/html_parser.py +115 -0
- quantum/core/parsers/jobs/__init__.py +11 -0
- quantum/core/parsers/jobs/job_parser.py +71 -0
- quantum/core/parsers/jobs/schedule_parser.py +62 -0
- quantum/core/parsers/jobs/thread_parser.py +57 -0
- quantum/core/parsers/messaging/__init__.py +17 -0
- quantum/core/parsers/messaging/message_ack_parser.py +30 -0
- quantum/core/parsers/messaging/message_nack_parser.py +30 -0
- quantum/core/parsers/messaging/message_parser.py +114 -0
- quantum/core/parsers/messaging/queue_parser.py +61 -0
- quantum/core/parsers/messaging/websocket_parser.py +121 -0
- quantum/core/parsers/persistence/__init__.py +9 -0
- quantum/core/parsers/persistence/persist_parser.py +64 -0
- quantum/core/parsers/routing/__init__.py +9 -0
- quantum/core/parsers/routing/route_parser.py +41 -0
- quantum/core/parsers/scripting/__init__.py +12 -0
- quantum/core/parsers/scripting/pyclass_parser.py +62 -0
- quantum/core/parsers/scripting/pydecorator_parser.py +68 -0
- quantum/core/parsers/scripting/pyimport_parser.py +52 -0
- quantum/core/parsers/scripting/python_parser.py +49 -0
- quantum/core/parsers/services/__init__.py +12 -0
- quantum/core/parsers/services/dump_parser.py +52 -0
- quantum/core/parsers/services/file_parser.py +48 -0
- quantum/core/parsers/services/log_parser.py +46 -0
- quantum/core/parsers/services/mail_parser.py +65 -0
- quantum/core/tiers.py +82 -0
- quantum/packages/__init__.py +28 -0
- quantum/packages/manager.py +413 -0
- quantum/packages/manifest.py +351 -0
- quantum/packages/registry.py +399 -0
- quantum/packages/resolver.py +336 -0
- quantum/plugins/__init__.py +33 -0
- quantum/plugins/hooks.py +329 -0
- quantum/plugins/loader.py +479 -0
- quantum/plugins/manifest.py +336 -0
- quantum/plugins/registry.py +371 -0
- quantum/runtime/__init__.py +28 -0
- quantum/runtime/action_handler.py +443 -0
- quantum/runtime/adapters/__init__.py +88 -0
- quantum/runtime/adapters/memory_adapter.py +690 -0
- quantum/runtime/adapters/rabbitmq_adapter.py +715 -0
- quantum/runtime/adapters/redis_adapter.py +582 -0
- quantum/runtime/adapters/sqlite_adapter.py +414 -0
- quantum/runtime/agent_service.py +1133 -0
- quantum/runtime/api_server.py +86 -0
- quantum/runtime/ast_cache.py +506 -0
- quantum/runtime/auth_service.py +267 -0
- quantum/runtime/component.py +990 -0
- quantum/runtime/component_composer.py +319 -0
- quantum/runtime/component_resolver.py +174 -0
- quantum/runtime/database_service.py +598 -0
- quantum/runtime/email_service.py +162 -0
- quantum/runtime/error_handler.py +295 -0
- quantum/runtime/execution_context.py +286 -0
- quantum/runtime/executor_registry.py +171 -0
- quantum/runtime/executors/__init__.py +71 -0
- quantum/runtime/executors/ai/__init__.py +12 -0
- quantum/runtime/executors/ai/agent_executor.py +217 -0
- quantum/runtime/executors/ai/knowledge_executor.py +114 -0
- quantum/runtime/executors/ai/llm_executor.py +153 -0
- quantum/runtime/executors/ai/team_executor.py +171 -0
- quantum/runtime/executors/base.py +262 -0
- quantum/runtime/executors/control_flow/__init__.py +11 -0
- quantum/runtime/executors/control_flow/if_executor.py +93 -0
- quantum/runtime/executors/control_flow/loop_executor.py +307 -0
- quantum/runtime/executors/control_flow/set_executor.py +412 -0
- quantum/runtime/executors/data/__init__.py +12 -0
- quantum/runtime/executors/data/data_executor.py +145 -0
- quantum/runtime/executors/data/invoke_executor.py +176 -0
- quantum/runtime/executors/data/query_executor.py +256 -0
- quantum/runtime/executors/data/transaction_executor.py +91 -0
- quantum/runtime/executors/jobs/__init__.py +11 -0
- quantum/runtime/executors/jobs/job_executor.py +190 -0
- quantum/runtime/executors/jobs/schedule_executor.py +132 -0
- quantum/runtime/executors/jobs/thread_executor.py +127 -0
- quantum/runtime/executors/messaging/__init__.py +17 -0
- quantum/runtime/executors/messaging/message_ack_executor.py +51 -0
- quantum/runtime/executors/messaging/message_executor.py +174 -0
- quantum/runtime/executors/messaging/queue_executor.py +103 -0
- quantum/runtime/executors/messaging/websocket_executor.py +197 -0
- quantum/runtime/executors/scripting/__init__.py +11 -0
- quantum/runtime/executors/scripting/pyclass_executor.py +90 -0
- quantum/runtime/executors/scripting/pyimport_executor.py +81 -0
- quantum/runtime/executors/scripting/python_executor.py +249 -0
- quantum/runtime/executors/services/__init__.py +12 -0
- quantum/runtime/executors/services/dump_executor.py +72 -0
- quantum/runtime/executors/services/file_executor.py +89 -0
- quantum/runtime/executors/services/log_executor.py +77 -0
- quantum/runtime/executors/services/mail_executor.py +81 -0
- quantum/runtime/expression_cache.py +498 -0
- quantum/runtime/file_upload_service.py +326 -0
- quantum/runtime/function_registry.py +118 -0
- quantum/runtime/game_builder.py +166 -0
- quantum/runtime/game_code_generator.py +2371 -0
- quantum/runtime/game_templates.py +2006 -0
- quantum/runtime/godot_code_generator.py +4681 -0
- quantum/runtime/godot_templates.py +1449 -0
- quantum/runtime/job_executor.py +1599 -0
- quantum/runtime/knowledge_service.py +500 -0
- quantum/runtime/llm_cache.py +100 -0
- quantum/runtime/llm_providers.py +704 -0
- quantum/runtime/llm_service.py +287 -0
- quantum/runtime/logging_setup.py +140 -0
- quantum/runtime/message_broker.py +364 -0
- quantum/runtime/message_queue_service.py +571 -0
- quantum/runtime/param_validation.py +184 -0
- quantum/runtime/pypy_compat.py +315 -0
- quantum/runtime/python_bridge.py +698 -0
- quantum/runtime/query_validators.py +304 -0
- quantum/runtime/renderer.py +733 -0
- quantum/runtime/service_container.py +444 -0
- quantum/runtime/terminal_builder.py +76 -0
- quantum/runtime/terminal_code_generator.py +607 -0
- quantum/runtime/terminal_templates.py +243 -0
- quantum/runtime/testing_builder.py +77 -0
- quantum/runtime/testing_code_generator.py +833 -0
- quantum/runtime/testing_templates.py +85 -0
- quantum/runtime/ui_builder.py +188 -0
- quantum/runtime/ui_desktop_adapter.py +1730 -0
- quantum/runtime/ui_desktop_templates.py +307 -0
- quantum/runtime/ui_html_adapter.py +2691 -0
- quantum/runtime/ui_html_templates.py +2297 -0
- quantum/runtime/ui_mobile_adapter.py +1832 -0
- quantum/runtime/ui_mobile_templates.py +1003 -0
- quantum/runtime/ui_textual_adapter.py +1866 -0
- quantum/runtime/ui_textual_templates.py +45 -0
- quantum/runtime/ui_tokens.py +465 -0
- quantum/runtime/ui_validator.py +365 -0
- quantum/runtime/validators.py +256 -0
- quantum/runtime/web_server.py +1766 -0
- quantum/runtime/websocket_adapter.py +501 -0
- quantum/runtime/websocket_service.py +585 -0
- quantum/runtime/websocket_transport.py +289 -0
- quantum/runtime/wsgi.py +101 -0
- quantum/utils/__init__.py +1 -0
- quantum_framework-0.9.0.dist-info/METADATA +244 -0
- quantum_framework-0.9.0.dist-info/RECORD +262 -0
- quantum_framework-0.9.0.dist-info/WHEEL +5 -0
- quantum_framework-0.9.0.dist-info/entry_points.txt +2 -0
- quantum_framework-0.9.0.dist-info/licenses/LICENSE +21 -0
- quantum_framework-0.9.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AST Nodes for Terminal Engine (qt: namespace)
|
|
3
|
+
|
|
4
|
+
All terminal-specific AST nodes for the Quantum Terminal UI engine.
|
|
5
|
+
These represent TUI widgets, layouts, and interactions
|
|
6
|
+
that compile to Python Textual applications.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Dict, Any, List, Optional
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
import sys
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from quantum.core.ast_nodes import QuantumNode
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# ============================================
|
|
17
|
+
# CORE TERMINAL NODES
|
|
18
|
+
# ============================================
|
|
19
|
+
|
|
20
|
+
class ScreenNode(QuantumNode):
|
|
21
|
+
"""Represents <qt:screen> - A full terminal screen (Textual Screen)."""
|
|
22
|
+
|
|
23
|
+
def __init__(self, name: str):
|
|
24
|
+
self.name = name
|
|
25
|
+
self.title: Optional[str] = None
|
|
26
|
+
self.children: List[QuantumNode] = []
|
|
27
|
+
|
|
28
|
+
def add_child(self, child: QuantumNode):
|
|
29
|
+
self.children.append(child)
|
|
30
|
+
|
|
31
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
32
|
+
return {
|
|
33
|
+
"type": "terminal_screen",
|
|
34
|
+
"name": self.name,
|
|
35
|
+
"title": self.title,
|
|
36
|
+
"children_count": len(self.children),
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
def validate(self) -> List[str]:
|
|
40
|
+
errors = []
|
|
41
|
+
if not self.name:
|
|
42
|
+
errors.append("Screen name is required")
|
|
43
|
+
for child in self.children:
|
|
44
|
+
if hasattr(child, 'validate'):
|
|
45
|
+
errors.extend(child.validate())
|
|
46
|
+
return errors
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class PanelNode(QuantumNode):
|
|
50
|
+
"""Represents <qt:panel> - Container with border and title (Vertical + border CSS)."""
|
|
51
|
+
|
|
52
|
+
def __init__(self):
|
|
53
|
+
self.panel_id: Optional[str] = None
|
|
54
|
+
self.title: Optional[str] = None
|
|
55
|
+
self.children: List[QuantumNode] = []
|
|
56
|
+
|
|
57
|
+
def add_child(self, child: QuantumNode):
|
|
58
|
+
self.children.append(child)
|
|
59
|
+
|
|
60
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
61
|
+
return {
|
|
62
|
+
"type": "terminal_panel",
|
|
63
|
+
"id": self.panel_id,
|
|
64
|
+
"title": self.title,
|
|
65
|
+
"children_count": len(self.children),
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
def validate(self) -> List[str]:
|
|
69
|
+
errors = []
|
|
70
|
+
for child in self.children:
|
|
71
|
+
if hasattr(child, 'validate'):
|
|
72
|
+
errors.extend(child.validate())
|
|
73
|
+
return errors
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class LayoutNode(QuantumNode):
|
|
77
|
+
"""Represents <qt:layout> - Horizontal/Vertical layout container."""
|
|
78
|
+
|
|
79
|
+
def __init__(self):
|
|
80
|
+
self.layout_id: Optional[str] = None
|
|
81
|
+
self.direction: str = "vertical" # horizontal, vertical
|
|
82
|
+
self.children: List[QuantumNode] = []
|
|
83
|
+
|
|
84
|
+
def add_child(self, child: QuantumNode):
|
|
85
|
+
self.children.append(child)
|
|
86
|
+
|
|
87
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
88
|
+
return {
|
|
89
|
+
"type": "terminal_layout",
|
|
90
|
+
"id": self.layout_id,
|
|
91
|
+
"direction": self.direction,
|
|
92
|
+
"children_count": len(self.children),
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
def validate(self) -> List[str]:
|
|
96
|
+
errors = []
|
|
97
|
+
if self.direction not in ('horizontal', 'vertical'):
|
|
98
|
+
errors.append(f"Invalid layout direction: {self.direction}")
|
|
99
|
+
for child in self.children:
|
|
100
|
+
if hasattr(child, 'validate'):
|
|
101
|
+
errors.extend(child.validate())
|
|
102
|
+
return errors
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class TableNode(QuantumNode):
|
|
106
|
+
"""Represents <qt:table> - Data table (Textual DataTable)."""
|
|
107
|
+
|
|
108
|
+
def __init__(self):
|
|
109
|
+
self.table_id: Optional[str] = None
|
|
110
|
+
self.data_source: Optional[str] = None
|
|
111
|
+
self.zebra: bool = False
|
|
112
|
+
self.columns: List['ColumnNode'] = []
|
|
113
|
+
|
|
114
|
+
def add_column(self, col: 'ColumnNode'):
|
|
115
|
+
self.columns.append(col)
|
|
116
|
+
|
|
117
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
118
|
+
return {
|
|
119
|
+
"type": "terminal_table",
|
|
120
|
+
"id": self.table_id,
|
|
121
|
+
"data_source": self.data_source,
|
|
122
|
+
"zebra": self.zebra,
|
|
123
|
+
"columns_count": len(self.columns),
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
def validate(self) -> List[str]:
|
|
127
|
+
errors = []
|
|
128
|
+
for col in self.columns:
|
|
129
|
+
errors.extend(col.validate())
|
|
130
|
+
return errors
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class ColumnNode(QuantumNode):
|
|
134
|
+
"""Represents <qt:column> - Table column definition."""
|
|
135
|
+
|
|
136
|
+
def __init__(self):
|
|
137
|
+
self.name: str = ""
|
|
138
|
+
self.key: str = ""
|
|
139
|
+
self.width: Optional[int] = None
|
|
140
|
+
self.align: str = "left" # left, center, right
|
|
141
|
+
|
|
142
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
143
|
+
return {
|
|
144
|
+
"type": "terminal_column",
|
|
145
|
+
"name": self.name,
|
|
146
|
+
"key": self.key,
|
|
147
|
+
"width": self.width,
|
|
148
|
+
"align": self.align,
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
def validate(self) -> List[str]:
|
|
152
|
+
errors = []
|
|
153
|
+
if not self.name:
|
|
154
|
+
errors.append("Column name is required")
|
|
155
|
+
if not self.key:
|
|
156
|
+
errors.append("Column key is required")
|
|
157
|
+
return errors
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class TerminalInputNode(QuantumNode):
|
|
161
|
+
"""Represents <qt:input> - Text input field (Textual Input)."""
|
|
162
|
+
|
|
163
|
+
def __init__(self):
|
|
164
|
+
self.input_id: Optional[str] = None
|
|
165
|
+
self.placeholder: Optional[str] = None
|
|
166
|
+
self.on_submit: Optional[str] = None
|
|
167
|
+
self.password: bool = False
|
|
168
|
+
|
|
169
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
170
|
+
return {
|
|
171
|
+
"type": "terminal_input",
|
|
172
|
+
"id": self.input_id,
|
|
173
|
+
"placeholder": self.placeholder,
|
|
174
|
+
"on_submit": self.on_submit,
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
def validate(self) -> List[str]:
|
|
178
|
+
return []
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class ButtonNode(QuantumNode):
|
|
182
|
+
"""Represents <qt:button> - Clickable button (Textual Button)."""
|
|
183
|
+
|
|
184
|
+
def __init__(self):
|
|
185
|
+
self.button_id: Optional[str] = None
|
|
186
|
+
self.label: str = ""
|
|
187
|
+
self.variant: str = "default" # default, primary, success, warning, error
|
|
188
|
+
self.on_click: Optional[str] = None
|
|
189
|
+
|
|
190
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
191
|
+
return {
|
|
192
|
+
"type": "terminal_button",
|
|
193
|
+
"id": self.button_id,
|
|
194
|
+
"label": self.label,
|
|
195
|
+
"variant": self.variant,
|
|
196
|
+
"on_click": self.on_click,
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
def validate(self) -> List[str]:
|
|
200
|
+
errors = []
|
|
201
|
+
if not self.label:
|
|
202
|
+
errors.append("Button label is required")
|
|
203
|
+
return errors
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class MenuNode(QuantumNode):
|
|
207
|
+
"""Represents <qt:menu> - Selection menu (Textual OptionList)."""
|
|
208
|
+
|
|
209
|
+
def __init__(self):
|
|
210
|
+
self.menu_id: Optional[str] = None
|
|
211
|
+
self.on_select: Optional[str] = None
|
|
212
|
+
self.options: List['OptionNode'] = []
|
|
213
|
+
|
|
214
|
+
def add_option(self, opt: 'OptionNode'):
|
|
215
|
+
self.options.append(opt)
|
|
216
|
+
|
|
217
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
218
|
+
return {
|
|
219
|
+
"type": "terminal_menu",
|
|
220
|
+
"id": self.menu_id,
|
|
221
|
+
"on_select": self.on_select,
|
|
222
|
+
"options_count": len(self.options),
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
def validate(self) -> List[str]:
|
|
226
|
+
return []
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
class OptionNode(QuantumNode):
|
|
230
|
+
"""Represents <qt:option> - Menu option item."""
|
|
231
|
+
|
|
232
|
+
def __init__(self):
|
|
233
|
+
self.value: str = ""
|
|
234
|
+
self.label: str = ""
|
|
235
|
+
|
|
236
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
237
|
+
return {
|
|
238
|
+
"type": "terminal_option",
|
|
239
|
+
"value": self.value,
|
|
240
|
+
"label": self.label,
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
def validate(self) -> List[str]:
|
|
244
|
+
errors = []
|
|
245
|
+
if not self.label:
|
|
246
|
+
errors.append("Option label is required")
|
|
247
|
+
return errors
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
class TextNode_Terminal(QuantumNode):
|
|
251
|
+
"""Represents <qt:text> - Styled text display (Textual Static with Rich markup)."""
|
|
252
|
+
|
|
253
|
+
def __init__(self):
|
|
254
|
+
self.text_id: Optional[str] = None
|
|
255
|
+
self.content: str = ""
|
|
256
|
+
|
|
257
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
258
|
+
return {
|
|
259
|
+
"type": "terminal_text",
|
|
260
|
+
"id": self.text_id,
|
|
261
|
+
"content": self.content,
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
def validate(self) -> List[str]:
|
|
265
|
+
return []
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
class ProgressNode(QuantumNode):
|
|
269
|
+
"""Represents <qt:progress> - Progress bar (Textual ProgressBar)."""
|
|
270
|
+
|
|
271
|
+
def __init__(self):
|
|
272
|
+
self.progress_id: Optional[str] = None
|
|
273
|
+
self.total: float = 100
|
|
274
|
+
self.value_var: Optional[str] = None
|
|
275
|
+
|
|
276
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
277
|
+
return {
|
|
278
|
+
"type": "terminal_progress",
|
|
279
|
+
"id": self.progress_id,
|
|
280
|
+
"total": self.total,
|
|
281
|
+
"value_var": self.value_var,
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
def validate(self) -> List[str]:
|
|
285
|
+
return []
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
class TreeNode(QuantumNode):
|
|
289
|
+
"""Represents <qt:tree> - Tree view (Textual Tree/DirectoryTree)."""
|
|
290
|
+
|
|
291
|
+
def __init__(self):
|
|
292
|
+
self.tree_id: Optional[str] = None
|
|
293
|
+
self.label: str = ""
|
|
294
|
+
self.on_select: Optional[str] = None
|
|
295
|
+
|
|
296
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
297
|
+
return {
|
|
298
|
+
"type": "terminal_tree",
|
|
299
|
+
"id": self.tree_id,
|
|
300
|
+
"label": self.label,
|
|
301
|
+
"on_select": self.on_select,
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
def validate(self) -> List[str]:
|
|
305
|
+
return []
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
class TabsNode(QuantumNode):
|
|
309
|
+
"""Represents <qt:tabs> - Tabbed content container (Textual TabbedContent)."""
|
|
310
|
+
|
|
311
|
+
def __init__(self):
|
|
312
|
+
self.tabs_id: Optional[str] = None
|
|
313
|
+
self.tabs: List['TabNode'] = []
|
|
314
|
+
|
|
315
|
+
def add_tab(self, tab: 'TabNode'):
|
|
316
|
+
self.tabs.append(tab)
|
|
317
|
+
|
|
318
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
319
|
+
return {
|
|
320
|
+
"type": "terminal_tabs",
|
|
321
|
+
"id": self.tabs_id,
|
|
322
|
+
"tabs_count": len(self.tabs),
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
def validate(self) -> List[str]:
|
|
326
|
+
errors = []
|
|
327
|
+
for tab in self.tabs:
|
|
328
|
+
errors.extend(tab.validate())
|
|
329
|
+
return errors
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
class TabNode(QuantumNode):
|
|
333
|
+
"""Represents <qt:tab> - Individual tab pane (Textual TabPane)."""
|
|
334
|
+
|
|
335
|
+
def __init__(self):
|
|
336
|
+
self.tab_id: Optional[str] = None
|
|
337
|
+
self.title: str = ""
|
|
338
|
+
self.children: List[QuantumNode] = []
|
|
339
|
+
|
|
340
|
+
def add_child(self, child: QuantumNode):
|
|
341
|
+
self.children.append(child)
|
|
342
|
+
|
|
343
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
344
|
+
return {
|
|
345
|
+
"type": "terminal_tab",
|
|
346
|
+
"id": self.tab_id,
|
|
347
|
+
"title": self.title,
|
|
348
|
+
"children_count": len(self.children),
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
def validate(self) -> List[str]:
|
|
352
|
+
errors = []
|
|
353
|
+
if not self.title:
|
|
354
|
+
errors.append("Tab title is required")
|
|
355
|
+
for child in self.children:
|
|
356
|
+
if hasattr(child, 'validate'):
|
|
357
|
+
errors.extend(child.validate())
|
|
358
|
+
return errors
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
class LogNode_Terminal(QuantumNode):
|
|
362
|
+
"""Represents <qt:log> - Scrollable log output (Textual RichLog)."""
|
|
363
|
+
|
|
364
|
+
def __init__(self):
|
|
365
|
+
self.log_id: Optional[str] = None
|
|
366
|
+
self.auto_scroll: bool = True
|
|
367
|
+
self.markup: bool = True
|
|
368
|
+
self.max_lines: Optional[int] = None
|
|
369
|
+
|
|
370
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
371
|
+
return {
|
|
372
|
+
"type": "terminal_log",
|
|
373
|
+
"id": self.log_id,
|
|
374
|
+
"auto_scroll": self.auto_scroll,
|
|
375
|
+
"markup": self.markup,
|
|
376
|
+
"max_lines": self.max_lines,
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
def validate(self) -> List[str]:
|
|
380
|
+
return []
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
class HeaderNode_Terminal(QuantumNode):
|
|
384
|
+
"""Represents <qt:header> - Fixed header bar (Textual Header)."""
|
|
385
|
+
|
|
386
|
+
def __init__(self):
|
|
387
|
+
self.title: Optional[str] = None
|
|
388
|
+
self.show_clock: bool = False
|
|
389
|
+
|
|
390
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
391
|
+
return {
|
|
392
|
+
"type": "terminal_header",
|
|
393
|
+
"title": self.title,
|
|
394
|
+
"show_clock": self.show_clock,
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
def validate(self) -> List[str]:
|
|
398
|
+
return []
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
class FooterNode(QuantumNode):
|
|
402
|
+
"""Represents <qt:footer> - Fixed footer bar (Textual Footer)."""
|
|
403
|
+
|
|
404
|
+
def __init__(self):
|
|
405
|
+
pass
|
|
406
|
+
|
|
407
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
408
|
+
return {
|
|
409
|
+
"type": "terminal_footer",
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
def validate(self) -> List[str]:
|
|
413
|
+
return []
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
class StatusNode(QuantumNode):
|
|
417
|
+
"""Represents <qt:status> - Status bar (Textual Static)."""
|
|
418
|
+
|
|
419
|
+
def __init__(self):
|
|
420
|
+
self.status_id: Optional[str] = None
|
|
421
|
+
self.content: str = ""
|
|
422
|
+
|
|
423
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
424
|
+
return {
|
|
425
|
+
"type": "terminal_status",
|
|
426
|
+
"id": self.status_id,
|
|
427
|
+
"content": self.content,
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
def validate(self) -> List[str]:
|
|
431
|
+
return []
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
class KeybindingNode(QuantumNode):
|
|
435
|
+
"""Represents <qt:keybinding> - Keyboard shortcut (Textual Binding)."""
|
|
436
|
+
|
|
437
|
+
def __init__(self):
|
|
438
|
+
self.key: str = ""
|
|
439
|
+
self.action: str = ""
|
|
440
|
+
self.description: Optional[str] = None
|
|
441
|
+
|
|
442
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
443
|
+
return {
|
|
444
|
+
"type": "terminal_keybinding",
|
|
445
|
+
"key": self.key,
|
|
446
|
+
"action": self.action,
|
|
447
|
+
"description": self.description,
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
def validate(self) -> List[str]:
|
|
451
|
+
errors = []
|
|
452
|
+
if not self.key:
|
|
453
|
+
errors.append("Keybinding key is required")
|
|
454
|
+
if not self.action:
|
|
455
|
+
errors.append("Keybinding action is required")
|
|
456
|
+
return errors
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
class TimerNode_Terminal(QuantumNode):
|
|
460
|
+
"""Represents <qt:timer> - Periodic timer (set_interval)."""
|
|
461
|
+
|
|
462
|
+
def __init__(self):
|
|
463
|
+
self.timer_id: Optional[str] = None
|
|
464
|
+
self.interval: float = 1.0
|
|
465
|
+
self.action: str = ""
|
|
466
|
+
|
|
467
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
468
|
+
return {
|
|
469
|
+
"type": "terminal_timer",
|
|
470
|
+
"id": self.timer_id,
|
|
471
|
+
"interval": self.interval,
|
|
472
|
+
"action": self.action,
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
def validate(self) -> List[str]:
|
|
476
|
+
errors = []
|
|
477
|
+
if not self.action:
|
|
478
|
+
errors.append("Timer action is required")
|
|
479
|
+
if self.interval <= 0:
|
|
480
|
+
errors.append("Timer interval must be positive")
|
|
481
|
+
return errors
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
class ServiceNode(QuantumNode):
|
|
485
|
+
"""Represents <qt:service> - Background async worker."""
|
|
486
|
+
|
|
487
|
+
def __init__(self):
|
|
488
|
+
self.service_id: Optional[str] = None
|
|
489
|
+
self.handler: str = ""
|
|
490
|
+
|
|
491
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
492
|
+
return {
|
|
493
|
+
"type": "terminal_service",
|
|
494
|
+
"id": self.service_id,
|
|
495
|
+
"handler": self.handler,
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
def validate(self) -> List[str]:
|
|
499
|
+
errors = []
|
|
500
|
+
if not self.handler:
|
|
501
|
+
errors.append("Service handler is required")
|
|
502
|
+
return errors
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
class CssNode(QuantumNode):
|
|
506
|
+
"""Represents <qt:css> - Textual CSS (TCSS) block."""
|
|
507
|
+
|
|
508
|
+
def __init__(self):
|
|
509
|
+
self.content: str = ""
|
|
510
|
+
|
|
511
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
512
|
+
return {
|
|
513
|
+
"type": "terminal_css",
|
|
514
|
+
"content_length": len(self.content),
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
def validate(self) -> List[str]:
|
|
518
|
+
return []
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
class OnEventNode_Terminal(QuantumNode):
|
|
522
|
+
"""Represents <qt:on> - Event handler mapping."""
|
|
523
|
+
|
|
524
|
+
def __init__(self):
|
|
525
|
+
self.event: str = ""
|
|
526
|
+
self.action: str = ""
|
|
527
|
+
|
|
528
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
529
|
+
return {
|
|
530
|
+
"type": "terminal_on_event",
|
|
531
|
+
"event": self.event,
|
|
532
|
+
"action": self.action,
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
def validate(self) -> List[str]:
|
|
536
|
+
errors = []
|
|
537
|
+
if not self.event:
|
|
538
|
+
errors.append("Event type is required")
|
|
539
|
+
if not self.action:
|
|
540
|
+
errors.append("Event action is required")
|
|
541
|
+
return errors
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
class RawCodeNode_Terminal(QuantumNode):
|
|
545
|
+
"""Represents raw Python code inside a q:function in terminal context."""
|
|
546
|
+
|
|
547
|
+
def __init__(self, code: str):
|
|
548
|
+
self.code = code
|
|
549
|
+
|
|
550
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
551
|
+
return {
|
|
552
|
+
"type": "raw_code",
|
|
553
|
+
"code": self.code,
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
def validate(self) -> List[str]:
|
|
557
|
+
errors = []
|
|
558
|
+
if not self.code or not self.code.strip():
|
|
559
|
+
errors.append("RawCodeNode code is empty")
|
|
560
|
+
return errors
|