superqode 0.1.5__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 (288) hide show
  1. superqode/__init__.py +33 -0
  2. superqode/acp/__init__.py +23 -0
  3. superqode/acp/client.py +913 -0
  4. superqode/acp/permission_screen.py +457 -0
  5. superqode/acp/types.py +480 -0
  6. superqode/acp_discovery.py +856 -0
  7. superqode/agent/__init__.py +22 -0
  8. superqode/agent/edit_strategies.py +334 -0
  9. superqode/agent/loop.py +892 -0
  10. superqode/agent/qe_report_templates.py +39 -0
  11. superqode/agent/system_prompts.py +353 -0
  12. superqode/agent_output.py +721 -0
  13. superqode/agent_stream.py +953 -0
  14. superqode/agents/__init__.py +59 -0
  15. superqode/agents/acp_registry.py +305 -0
  16. superqode/agents/client.py +249 -0
  17. superqode/agents/data/augmentcode.com.toml +51 -0
  18. superqode/agents/data/cagent.dev.toml +51 -0
  19. superqode/agents/data/claude.com.toml +60 -0
  20. superqode/agents/data/codeassistant.dev.toml +51 -0
  21. superqode/agents/data/codex.openai.com.toml +57 -0
  22. superqode/agents/data/fastagent.ai.toml +66 -0
  23. superqode/agents/data/geminicli.com.toml +77 -0
  24. superqode/agents/data/goose.block.xyz.toml +54 -0
  25. superqode/agents/data/junie.jetbrains.com.toml +56 -0
  26. superqode/agents/data/kimi.moonshot.cn.toml +57 -0
  27. superqode/agents/data/llmlingagent.dev.toml +51 -0
  28. superqode/agents/data/molt.bot.toml +49 -0
  29. superqode/agents/data/opencode.ai.toml +60 -0
  30. superqode/agents/data/stakpak.dev.toml +51 -0
  31. superqode/agents/data/vtcode.dev.toml +51 -0
  32. superqode/agents/discovery.py +266 -0
  33. superqode/agents/messaging.py +160 -0
  34. superqode/agents/persona.py +166 -0
  35. superqode/agents/registry.py +421 -0
  36. superqode/agents/schema.py +72 -0
  37. superqode/agents/unified.py +367 -0
  38. superqode/app/__init__.py +111 -0
  39. superqode/app/constants.py +314 -0
  40. superqode/app/css.py +366 -0
  41. superqode/app/models.py +118 -0
  42. superqode/app/suggester.py +125 -0
  43. superqode/app/widgets.py +1591 -0
  44. superqode/app_enhanced.py +399 -0
  45. superqode/app_main.py +17187 -0
  46. superqode/approval.py +312 -0
  47. superqode/atomic.py +296 -0
  48. superqode/commands/__init__.py +1 -0
  49. superqode/commands/acp.py +965 -0
  50. superqode/commands/agents.py +180 -0
  51. superqode/commands/auth.py +278 -0
  52. superqode/commands/config.py +374 -0
  53. superqode/commands/init.py +826 -0
  54. superqode/commands/providers.py +819 -0
  55. superqode/commands/qe.py +1145 -0
  56. superqode/commands/roles.py +380 -0
  57. superqode/commands/serve.py +172 -0
  58. superqode/commands/suggestions.py +127 -0
  59. superqode/commands/superqe.py +460 -0
  60. superqode/config/__init__.py +51 -0
  61. superqode/config/loader.py +812 -0
  62. superqode/config/schema.py +498 -0
  63. superqode/core/__init__.py +111 -0
  64. superqode/core/roles.py +281 -0
  65. superqode/danger.py +386 -0
  66. superqode/data/superqode-template.yaml +1522 -0
  67. superqode/design_system.py +1080 -0
  68. superqode/dialogs/__init__.py +6 -0
  69. superqode/dialogs/base.py +39 -0
  70. superqode/dialogs/model.py +130 -0
  71. superqode/dialogs/provider.py +870 -0
  72. superqode/diff_view.py +919 -0
  73. superqode/enterprise.py +21 -0
  74. superqode/evaluation/__init__.py +25 -0
  75. superqode/evaluation/adapters.py +93 -0
  76. superqode/evaluation/behaviors.py +89 -0
  77. superqode/evaluation/engine.py +209 -0
  78. superqode/evaluation/scenarios.py +96 -0
  79. superqode/execution/__init__.py +36 -0
  80. superqode/execution/linter.py +538 -0
  81. superqode/execution/modes.py +347 -0
  82. superqode/execution/resolver.py +283 -0
  83. superqode/execution/runner.py +642 -0
  84. superqode/file_explorer.py +811 -0
  85. superqode/file_viewer.py +471 -0
  86. superqode/flash.py +183 -0
  87. superqode/guidance/__init__.py +58 -0
  88. superqode/guidance/config.py +203 -0
  89. superqode/guidance/prompts.py +71 -0
  90. superqode/harness/__init__.py +54 -0
  91. superqode/harness/accelerator.py +291 -0
  92. superqode/harness/config.py +319 -0
  93. superqode/harness/validator.py +147 -0
  94. superqode/history.py +279 -0
  95. superqode/integrations/superopt_runner.py +124 -0
  96. superqode/logging/__init__.py +49 -0
  97. superqode/logging/adapters.py +219 -0
  98. superqode/logging/formatter.py +923 -0
  99. superqode/logging/integration.py +341 -0
  100. superqode/logging/sinks.py +170 -0
  101. superqode/logging/unified_log.py +417 -0
  102. superqode/lsp/__init__.py +26 -0
  103. superqode/lsp/client.py +544 -0
  104. superqode/main.py +1069 -0
  105. superqode/mcp/__init__.py +89 -0
  106. superqode/mcp/auth_storage.py +380 -0
  107. superqode/mcp/client.py +1236 -0
  108. superqode/mcp/config.py +319 -0
  109. superqode/mcp/integration.py +337 -0
  110. superqode/mcp/oauth.py +436 -0
  111. superqode/mcp/oauth_callback.py +385 -0
  112. superqode/mcp/types.py +290 -0
  113. superqode/memory/__init__.py +31 -0
  114. superqode/memory/feedback.py +342 -0
  115. superqode/memory/store.py +522 -0
  116. superqode/notifications.py +369 -0
  117. superqode/optimization/__init__.py +5 -0
  118. superqode/optimization/config.py +33 -0
  119. superqode/permissions/__init__.py +25 -0
  120. superqode/permissions/rules.py +488 -0
  121. superqode/plan.py +323 -0
  122. superqode/providers/__init__.py +33 -0
  123. superqode/providers/gateway/__init__.py +165 -0
  124. superqode/providers/gateway/base.py +228 -0
  125. superqode/providers/gateway/litellm_gateway.py +1170 -0
  126. superqode/providers/gateway/openresponses_gateway.py +436 -0
  127. superqode/providers/health.py +297 -0
  128. superqode/providers/huggingface/__init__.py +74 -0
  129. superqode/providers/huggingface/downloader.py +472 -0
  130. superqode/providers/huggingface/endpoints.py +442 -0
  131. superqode/providers/huggingface/hub.py +531 -0
  132. superqode/providers/huggingface/inference.py +394 -0
  133. superqode/providers/huggingface/transformers_runner.py +516 -0
  134. superqode/providers/local/__init__.py +100 -0
  135. superqode/providers/local/base.py +438 -0
  136. superqode/providers/local/discovery.py +418 -0
  137. superqode/providers/local/lmstudio.py +256 -0
  138. superqode/providers/local/mlx.py +457 -0
  139. superqode/providers/local/ollama.py +486 -0
  140. superqode/providers/local/sglang.py +268 -0
  141. superqode/providers/local/tgi.py +260 -0
  142. superqode/providers/local/tool_support.py +477 -0
  143. superqode/providers/local/vllm.py +258 -0
  144. superqode/providers/manager.py +1338 -0
  145. superqode/providers/models.py +1016 -0
  146. superqode/providers/models_dev.py +578 -0
  147. superqode/providers/openresponses/__init__.py +87 -0
  148. superqode/providers/openresponses/converters/__init__.py +17 -0
  149. superqode/providers/openresponses/converters/messages.py +343 -0
  150. superqode/providers/openresponses/converters/tools.py +268 -0
  151. superqode/providers/openresponses/schema/__init__.py +56 -0
  152. superqode/providers/openresponses/schema/models.py +585 -0
  153. superqode/providers/openresponses/streaming/__init__.py +5 -0
  154. superqode/providers/openresponses/streaming/parser.py +338 -0
  155. superqode/providers/openresponses/tools/__init__.py +21 -0
  156. superqode/providers/openresponses/tools/apply_patch.py +352 -0
  157. superqode/providers/openresponses/tools/code_interpreter.py +290 -0
  158. superqode/providers/openresponses/tools/file_search.py +333 -0
  159. superqode/providers/openresponses/tools/mcp_adapter.py +252 -0
  160. superqode/providers/registry.py +716 -0
  161. superqode/providers/usage.py +332 -0
  162. superqode/pure_mode.py +384 -0
  163. superqode/qr/__init__.py +23 -0
  164. superqode/qr/dashboard.py +781 -0
  165. superqode/qr/generator.py +1018 -0
  166. superqode/qr/templates.py +135 -0
  167. superqode/safety/__init__.py +41 -0
  168. superqode/safety/sandbox.py +413 -0
  169. superqode/safety/warnings.py +256 -0
  170. superqode/server/__init__.py +33 -0
  171. superqode/server/lsp_server.py +775 -0
  172. superqode/server/web.py +250 -0
  173. superqode/session/__init__.py +25 -0
  174. superqode/session/persistence.py +580 -0
  175. superqode/session/sharing.py +477 -0
  176. superqode/session.py +475 -0
  177. superqode/sidebar.py +2991 -0
  178. superqode/stream_view.py +648 -0
  179. superqode/styles/__init__.py +3 -0
  180. superqode/superqe/__init__.py +184 -0
  181. superqode/superqe/acp_runner.py +1064 -0
  182. superqode/superqe/constitution/__init__.py +62 -0
  183. superqode/superqe/constitution/evaluator.py +308 -0
  184. superqode/superqe/constitution/loader.py +432 -0
  185. superqode/superqe/constitution/schema.py +250 -0
  186. superqode/superqe/events.py +591 -0
  187. superqode/superqe/frameworks/__init__.py +65 -0
  188. superqode/superqe/frameworks/base.py +234 -0
  189. superqode/superqe/frameworks/e2e.py +263 -0
  190. superqode/superqe/frameworks/executor.py +237 -0
  191. superqode/superqe/frameworks/javascript.py +409 -0
  192. superqode/superqe/frameworks/python.py +373 -0
  193. superqode/superqe/frameworks/registry.py +92 -0
  194. superqode/superqe/mcp_tools/__init__.py +47 -0
  195. superqode/superqe/mcp_tools/core_tools.py +418 -0
  196. superqode/superqe/mcp_tools/registry.py +230 -0
  197. superqode/superqe/mcp_tools/testing_tools.py +167 -0
  198. superqode/superqe/noise.py +89 -0
  199. superqode/superqe/orchestrator.py +778 -0
  200. superqode/superqe/roles.py +609 -0
  201. superqode/superqe/session.py +713 -0
  202. superqode/superqe/skills/__init__.py +57 -0
  203. superqode/superqe/skills/base.py +106 -0
  204. superqode/superqe/skills/core_skills.py +899 -0
  205. superqode/superqe/skills/registry.py +90 -0
  206. superqode/superqe/verifier.py +101 -0
  207. superqode/superqe_cli.py +76 -0
  208. superqode/tool_call.py +358 -0
  209. superqode/tools/__init__.py +93 -0
  210. superqode/tools/agent_tools.py +496 -0
  211. superqode/tools/base.py +324 -0
  212. superqode/tools/batch_tool.py +133 -0
  213. superqode/tools/diagnostics.py +311 -0
  214. superqode/tools/edit_tools.py +653 -0
  215. superqode/tools/enhanced_base.py +515 -0
  216. superqode/tools/file_tools.py +269 -0
  217. superqode/tools/file_tracking.py +45 -0
  218. superqode/tools/lsp_tools.py +610 -0
  219. superqode/tools/network_tools.py +350 -0
  220. superqode/tools/permissions.py +400 -0
  221. superqode/tools/question_tool.py +324 -0
  222. superqode/tools/search_tools.py +598 -0
  223. superqode/tools/shell_tools.py +259 -0
  224. superqode/tools/todo_tools.py +121 -0
  225. superqode/tools/validation.py +80 -0
  226. superqode/tools/web_tools.py +639 -0
  227. superqode/tui.py +1152 -0
  228. superqode/tui_integration.py +875 -0
  229. superqode/tui_widgets/__init__.py +27 -0
  230. superqode/tui_widgets/widgets/__init__.py +18 -0
  231. superqode/tui_widgets/widgets/progress.py +185 -0
  232. superqode/tui_widgets/widgets/tool_display.py +188 -0
  233. superqode/undo_manager.py +574 -0
  234. superqode/utils/__init__.py +5 -0
  235. superqode/utils/error_handling.py +323 -0
  236. superqode/utils/fuzzy.py +257 -0
  237. superqode/widgets/__init__.py +477 -0
  238. superqode/widgets/agent_collab.py +390 -0
  239. superqode/widgets/agent_store.py +936 -0
  240. superqode/widgets/agent_switcher.py +395 -0
  241. superqode/widgets/animation_manager.py +284 -0
  242. superqode/widgets/code_context.py +356 -0
  243. superqode/widgets/command_palette.py +412 -0
  244. superqode/widgets/connection_status.py +537 -0
  245. superqode/widgets/conversation_history.py +470 -0
  246. superqode/widgets/diff_indicator.py +155 -0
  247. superqode/widgets/enhanced_status_bar.py +385 -0
  248. superqode/widgets/enhanced_toast.py +476 -0
  249. superqode/widgets/file_browser.py +809 -0
  250. superqode/widgets/file_reference.py +585 -0
  251. superqode/widgets/issue_timeline.py +340 -0
  252. superqode/widgets/leader_key.py +264 -0
  253. superqode/widgets/mode_switcher.py +445 -0
  254. superqode/widgets/model_picker.py +234 -0
  255. superqode/widgets/permission_preview.py +1205 -0
  256. superqode/widgets/prompt.py +358 -0
  257. superqode/widgets/provider_connect.py +725 -0
  258. superqode/widgets/pty_shell.py +587 -0
  259. superqode/widgets/qe_dashboard.py +321 -0
  260. superqode/widgets/resizable_sidebar.py +377 -0
  261. superqode/widgets/response_changes.py +218 -0
  262. superqode/widgets/response_display.py +528 -0
  263. superqode/widgets/rich_tool_display.py +613 -0
  264. superqode/widgets/sidebar_panels.py +1180 -0
  265. superqode/widgets/slash_complete.py +356 -0
  266. superqode/widgets/split_view.py +612 -0
  267. superqode/widgets/status_bar.py +273 -0
  268. superqode/widgets/superqode_display.py +786 -0
  269. superqode/widgets/thinking_display.py +815 -0
  270. superqode/widgets/throbber.py +87 -0
  271. superqode/widgets/toast.py +206 -0
  272. superqode/widgets/unified_output.py +1073 -0
  273. superqode/workspace/__init__.py +75 -0
  274. superqode/workspace/artifacts.py +472 -0
  275. superqode/workspace/coordinator.py +353 -0
  276. superqode/workspace/diff_tracker.py +429 -0
  277. superqode/workspace/git_guard.py +373 -0
  278. superqode/workspace/git_snapshot.py +526 -0
  279. superqode/workspace/manager.py +750 -0
  280. superqode/workspace/snapshot.py +357 -0
  281. superqode/workspace/watcher.py +535 -0
  282. superqode/workspace/worktree.py +440 -0
  283. superqode-0.1.5.dist-info/METADATA +204 -0
  284. superqode-0.1.5.dist-info/RECORD +288 -0
  285. superqode-0.1.5.dist-info/WHEEL +5 -0
  286. superqode-0.1.5.dist-info/entry_points.txt +3 -0
  287. superqode-0.1.5.dist-info/licenses/LICENSE +648 -0
  288. superqode-0.1.5.dist-info/top_level.txt +1 -0
@@ -0,0 +1,273 @@
1
+ """Status bar widget showing current state, connection, and shortcuts - High contrast design."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+ from typing import TYPE_CHECKING, Optional
7
+
8
+ from textual.app import ComposeResult
9
+ from textual.containers import Horizontal
10
+ from textual.reactive import reactive
11
+ from textual.widget import Widget
12
+ from textual.widgets import Static
13
+
14
+ if TYPE_CHECKING:
15
+ from superqode.app_main import SuperQodeApp
16
+
17
+
18
+ class StatusBar(Widget):
19
+ """
20
+ Bottom status bar showing:
21
+ - Current mode/role (HOME, DEV.FULLSTACK, QE.QUICK, etc.)
22
+ - Connected agent and status
23
+ - QE workspace status (ephemeral mode indicator)
24
+ - Current project directory
25
+ - Keyboard shortcut hints
26
+
27
+ High contrast, accessible design.
28
+ """
29
+
30
+ DEFAULT_CSS = """
31
+ StatusBar {
32
+ dock: bottom;
33
+ height: 2;
34
+ background: #001a33;
35
+ }
36
+
37
+ StatusBar > Horizontal {
38
+ width: 100%;
39
+ height: 2;
40
+ background: #001a33;
41
+ }
42
+
43
+ StatusBar .status-section {
44
+ height: 2;
45
+ padding: 0 2;
46
+ background: #001a33;
47
+ content-align: center middle;
48
+ }
49
+
50
+ StatusBar #mode-indicator {
51
+ color: #00ffff;
52
+ text-style: bold;
53
+ background: #003366;
54
+ min-width: 20;
55
+ }
56
+
57
+ StatusBar #mode-indicator.qe-mode {
58
+ color: #ff00ff;
59
+ background: #330033;
60
+ }
61
+
62
+ StatusBar #agent-indicator {
63
+ color: #00ff00;
64
+ text-style: bold;
65
+ min-width: 25;
66
+ }
67
+
68
+ StatusBar #agent-indicator.disconnected {
69
+ color: #ffaa00;
70
+ }
71
+
72
+ StatusBar #qe-indicator {
73
+ color: #ff00ff;
74
+ text-style: bold;
75
+ min-width: 18;
76
+ }
77
+
78
+ StatusBar #qe-indicator.active {
79
+ color: #00ff00;
80
+ background: #003300;
81
+ }
82
+
83
+ StatusBar #qe-indicator.inactive {
84
+ color: #666666;
85
+ }
86
+
87
+ StatusBar #project-indicator {
88
+ color: #ffffff;
89
+ min-width: 20;
90
+ }
91
+
92
+ StatusBar #shortcuts-indicator {
93
+ dock: right;
94
+ color: #00ff00;
95
+ text-style: bold;
96
+ }
97
+ """
98
+
99
+ # Reactive properties
100
+ mode: reactive[str] = reactive("HOME")
101
+ agent_name: reactive[str] = reactive("")
102
+ agent_connected: reactive[bool] = reactive(False)
103
+ project_path: reactive[str] = reactive("")
104
+ task_count: reactive[int] = reactive(0)
105
+ qe_active: reactive[bool] = reactive(False)
106
+ qe_mode: reactive[str] = reactive("") # "quick" or "deep"
107
+
108
+ def __init__(
109
+ self,
110
+ mode: str = "HOME",
111
+ agent_name: str = "",
112
+ agent_connected: bool = False,
113
+ project_path: str | None = None,
114
+ qe_active: bool = False,
115
+ qe_mode: str = "",
116
+ **kwargs,
117
+ ) -> None:
118
+ super().__init__(**kwargs)
119
+ self.mode = mode
120
+ self.agent_name = agent_name
121
+ self.agent_connected = agent_connected
122
+ self.project_path = project_path or Path.cwd().name
123
+ self.qe_active = qe_active
124
+ self.qe_mode = qe_mode
125
+
126
+ def compose(self) -> ComposeResult:
127
+ """Compose the status bar layout."""
128
+ with Horizontal():
129
+ yield Static(self._get_mode_text(), id="mode-indicator", classes="status-section")
130
+ yield Static(self._get_agent_text(), id="agent-indicator", classes="status-section")
131
+ yield Static(self._get_qe_text(), id="qe-indicator", classes="status-section")
132
+ yield Static(self._get_project_text(), id="project-indicator", classes="status-section")
133
+ yield Static(
134
+ self._get_shortcuts_text(), id="shortcuts-indicator", classes="status-section"
135
+ )
136
+
137
+ def _get_mode_text(self) -> str:
138
+ """Get the mode indicator text."""
139
+ mode_icons = {
140
+ "HOME": "๐Ÿ ",
141
+ "DEV": "๐Ÿ’ป",
142
+ "QA": "๐Ÿงช",
143
+ "QE": "๐Ÿ”ฌ",
144
+ "DEVOPS": "โš™๏ธ",
145
+ }
146
+ # Extract base mode for icon
147
+ base_mode = self.mode.split(".")[0].upper() if "." in self.mode else self.mode.upper()
148
+ icon = mode_icons.get(base_mode, "๐Ÿ”ง")
149
+ return f"{icon} {self.mode}"
150
+
151
+ def _get_qe_text(self) -> str:
152
+ """Get the QE status indicator text."""
153
+ if self.qe_active:
154
+ mode_emoji = "โšก" if self.qe_mode == "quick" else "๐Ÿ”ฌ"
155
+ mode_name = "QUICK" if self.qe_mode == "quick" else "DEEP"
156
+ return f"{mode_emoji} QE:{mode_name}"
157
+ else:
158
+ return "๐Ÿ›ก๏ธ QE:READY"
159
+
160
+ def _get_agent_text(self) -> str:
161
+ """Get the agent indicator text."""
162
+ if self.agent_connected and self.agent_name:
163
+ return f"๐ŸŸข {self.agent_name} CONNECTED"
164
+ elif self.agent_name:
165
+ return f"โšช {self.agent_name} READY"
166
+ else:
167
+ return "๐Ÿ”Œ No Agent"
168
+
169
+ def _get_project_text(self) -> str:
170
+ """Get the project indicator text."""
171
+ if self.task_count > 0:
172
+ return f"๐Ÿ“ {self.project_path} โ”‚ โฑ {self.task_count} tasks"
173
+ return f"๐Ÿ“ {self.project_path}"
174
+
175
+ def _get_shortcuts_text(self) -> str:
176
+ """Get the keyboard shortcuts hint text."""
177
+ return "Ctrl+K commands โ”‚ Ctrl+A agents โ”‚ / slash โ”‚ ? help"
178
+
179
+ def watch_mode(self, mode: str) -> None:
180
+ """React to mode changes."""
181
+ if not self.is_mounted:
182
+ return
183
+ try:
184
+ mode_widget = self.query_one("#mode-indicator", Static)
185
+ mode_widget.update(self._get_mode_text())
186
+ except Exception:
187
+ pass
188
+
189
+ def watch_agent_name(self, agent_name: str) -> None:
190
+ """React to agent name changes."""
191
+ if not self.is_mounted:
192
+ return
193
+ self._update_agent_indicator()
194
+
195
+ def watch_agent_connected(self, connected: bool) -> None:
196
+ """React to connection state changes."""
197
+ if not self.is_mounted:
198
+ return
199
+ self._update_agent_indicator()
200
+
201
+ def _update_agent_indicator(self) -> None:
202
+ """Update the agent indicator widget."""
203
+ try:
204
+ agent_widget = self.query_one("#agent-indicator", Static)
205
+ agent_widget.update(self._get_agent_text())
206
+ agent_widget.set_class(not self.agent_connected, "disconnected")
207
+ except Exception:
208
+ pass
209
+
210
+ def watch_project_path(self, path: str) -> None:
211
+ """React to project path changes."""
212
+ if not self.is_mounted:
213
+ return
214
+ try:
215
+ project_widget = self.query_one("#project-indicator", Static)
216
+ project_widget.update(self._get_project_text())
217
+ except Exception:
218
+ pass
219
+
220
+ def watch_task_count(self, count: int) -> None:
221
+ """React to task count changes."""
222
+ if not self.is_mounted:
223
+ return
224
+ try:
225
+ project_widget = self.query_one("#project-indicator", Static)
226
+ project_widget.update(self._get_project_text())
227
+ except Exception:
228
+ pass
229
+
230
+ def watch_qe_active(self, active: bool) -> None:
231
+ """React to QE active state changes."""
232
+ if not self.is_mounted:
233
+ return
234
+ self._update_qe_indicator()
235
+
236
+ def watch_qe_mode(self, mode: str) -> None:
237
+ """React to QE mode changes."""
238
+ if not self.is_mounted:
239
+ return
240
+ self._update_qe_indicator()
241
+
242
+ def _update_qe_indicator(self) -> None:
243
+ """Update the QE indicator widget."""
244
+ try:
245
+ qe_widget = self.query_one("#qe-indicator", Static)
246
+ qe_widget.update(self._get_qe_text())
247
+ qe_widget.set_class(self.qe_active, "active")
248
+ qe_widget.set_class(not self.qe_active, "inactive")
249
+
250
+ # Also update mode indicator class for QE mode
251
+ mode_widget = self.query_one("#mode-indicator", Static)
252
+ is_qe = self.mode.upper().startswith("QE")
253
+ mode_widget.set_class(is_qe, "qe-mode")
254
+ except Exception:
255
+ pass
256
+
257
+ def set_connected(self, agent_name: str, connected: bool = True) -> None:
258
+ """Set the connection state."""
259
+ self.agent_name = agent_name
260
+ self.agent_connected = connected
261
+
262
+ def set_mode(self, mode: str) -> None:
263
+ """Set the current mode."""
264
+ self.mode = mode
265
+
266
+ def set_tasks(self, count: int) -> None:
267
+ """Set the task count."""
268
+ self.task_count = count
269
+
270
+ def set_qe_status(self, active: bool, mode: str = "") -> None:
271
+ """Set the QE workspace status."""
272
+ self.qe_active = active
273
+ self.qe_mode = mode