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,399 @@
1
+ """
2
+ Enhanced App Layout - OpenCode-Style TUI.
3
+
4
+ This module provides an enhanced app layout that integrates all the new
5
+ TUI widgets for a competitive coding agent experience.
6
+
7
+ To use: Import EnhancedAppMixin and mix it into SuperQodeApp, or use
8
+ the compose_enhanced() method in your existing compose().
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from pathlib import Path
14
+ from typing import TYPE_CHECKING
15
+
16
+ from textual.app import ComposeResult
17
+ from textual.containers import Container, Horizontal, Vertical, ScrollableContainer
18
+ from textual.widgets import Static, Input, Footer
19
+ from textual.reactive import reactive
20
+
21
+ from rich.text import Text
22
+
23
+
24
+ class EnhancedLayout(Container):
25
+ """
26
+ Enhanced layout container with OpenCode-style UX.
27
+
28
+ Layout:
29
+ ┌─────────────────────────────────────────────────────────────────┐
30
+ │ [Enhanced Status Bar - connection, model, tokens, cost] │
31
+ ├──────────────────────┬──────────────────────────────────────────┤
32
+ │ │ [Tool Call Panel - collapsible] │
33
+ │ ├──────────────────────────────────────────┤
34
+ │ [Sidebar] │ [Thinking Panel - collapsible] │
35
+ │ - Files ├──────────────────────────────────────────┤
36
+ │ - Git Status │ │
37
+ │ - Context │ [Conversation / Response Area] │
38
+ │ │ │
39
+ │ │ │
40
+ │ ├──────────────────────────────────────────┤
41
+ │ │ [Prompt Input] │
42
+ └──────────────────────┴──────────────────────────────────────────┘
43
+ """
44
+
45
+ DEFAULT_CSS = """
46
+ EnhancedLayout {
47
+ height: 100%;
48
+ width: 100%;
49
+ }
50
+
51
+ EnhancedLayout #enhanced-main {
52
+ height: 100%;
53
+ }
54
+
55
+ EnhancedLayout #enhanced-sidebar {
56
+ width: 30;
57
+ border-right: solid #27272a;
58
+ background: #0a0a0a;
59
+ }
60
+
61
+ EnhancedLayout #enhanced-sidebar.collapsed {
62
+ width: 0;
63
+ display: none;
64
+ }
65
+
66
+ EnhancedLayout #enhanced-content {
67
+ width: 1fr;
68
+ }
69
+
70
+ EnhancedLayout #enhanced-status {
71
+ height: 1;
72
+ dock: top;
73
+ }
74
+
75
+ EnhancedLayout #enhanced-tools {
76
+ height: auto;
77
+ max-height: 30%;
78
+ }
79
+
80
+ EnhancedLayout #enhanced-tools.collapsed {
81
+ max-height: 3;
82
+ }
83
+
84
+ EnhancedLayout #enhanced-thinking {
85
+ height: auto;
86
+ max-height: 20%;
87
+ }
88
+
89
+ EnhancedLayout #enhanced-thinking.collapsed {
90
+ max-height: 2;
91
+ }
92
+
93
+ EnhancedLayout #enhanced-conversation {
94
+ height: 1fr;
95
+ overflow-y: auto;
96
+ }
97
+
98
+ EnhancedLayout #enhanced-prompt-area {
99
+ height: auto;
100
+ min-height: 3;
101
+ max-height: 10;
102
+ dock: bottom;
103
+ border-top: solid #27272a;
104
+ padding: 1;
105
+ }
106
+
107
+ EnhancedLayout #enhanced-prompt-input {
108
+ width: 100%;
109
+ }
110
+ """
111
+
112
+ # State
113
+ sidebar_visible: reactive[bool] = reactive(True)
114
+ tools_collapsed: reactive[bool] = reactive(True)
115
+ thinking_collapsed: reactive[bool] = reactive(True)
116
+
117
+ def __init__(self, **kwargs):
118
+ super().__init__(**kwargs)
119
+ self._tui_enhancer = None
120
+
121
+ def compose(self) -> ComposeResult:
122
+ """Compose the enhanced layout."""
123
+ # Import widgets
124
+ from superqode.widgets import (
125
+ get_rich_tool_display,
126
+ get_thinking_display,
127
+ get_connection_status,
128
+ get_enhanced_status_bar,
129
+ )
130
+
131
+ # Get classes
132
+ ToolCallPanel, *_ = get_rich_tool_display()
133
+ ThinkingPanel, *_ = get_thinking_display()
134
+ ConnectionIndicator, *_ = get_connection_status()
135
+ EnhancedStatusBar, *_ = get_enhanced_status_bar()
136
+
137
+ # Status bar at top
138
+ yield EnhancedStatusBar(id="enhanced-status")
139
+
140
+ # Main horizontal split
141
+ with Horizontal(id="enhanced-main"):
142
+ # Sidebar
143
+ with Container(id="enhanced-sidebar"):
144
+ yield Static(self._render_sidebar_header(), id="sidebar-header")
145
+ yield Static("", id="sidebar-content")
146
+
147
+ # Main content area
148
+ with Vertical(id="enhanced-content"):
149
+ # Tool calls panel (collapsible)
150
+ yield ToolCallPanel(id="enhanced-tools", classes="collapsed")
151
+
152
+ # Thinking panel (collapsible)
153
+ yield ThinkingPanel(id="enhanced-thinking", classes="collapsed")
154
+
155
+ # Conversation area
156
+ with ScrollableContainer(id="enhanced-conversation"):
157
+ yield Static("", id="conversation-content")
158
+
159
+ # Prompt area
160
+ with Container(id="enhanced-prompt-area"):
161
+ yield Static(self._render_prompt_prefix(), id="prompt-prefix")
162
+ yield Input(
163
+ placeholder="Ask anything... (type :help for commands)",
164
+ id="enhanced-prompt-input",
165
+ )
166
+
167
+ def _render_sidebar_header(self) -> Text:
168
+ """Render sidebar header."""
169
+ text = Text()
170
+ text.append("📁 ", style="#3b82f6")
171
+ text.append("Files", style="bold #e4e4e7")
172
+ return text
173
+
174
+ def _render_prompt_prefix(self) -> Text:
175
+ """Render prompt prefix."""
176
+ text = Text()
177
+ text.append("🖋️ ", style="#a855f7")
178
+ return text
179
+
180
+ def toggle_sidebar(self) -> None:
181
+ """Toggle sidebar visibility."""
182
+ self.sidebar_visible = not self.sidebar_visible
183
+ sidebar = self.query_one("#enhanced-sidebar")
184
+ if self.sidebar_visible:
185
+ sidebar.remove_class("collapsed")
186
+ else:
187
+ sidebar.add_class("collapsed")
188
+
189
+ def toggle_tools(self) -> None:
190
+ """Toggle tools panel."""
191
+ self.tools_collapsed = not self.tools_collapsed
192
+ tools = self.query_one("#enhanced-tools")
193
+ if self.tools_collapsed:
194
+ tools.add_class("collapsed")
195
+ else:
196
+ tools.remove_class("collapsed")
197
+
198
+ def toggle_thinking(self) -> None:
199
+ """Toggle thinking panel."""
200
+ self.thinking_collapsed = not self.thinking_collapsed
201
+ thinking = self.query_one("#enhanced-thinking")
202
+ if self.thinking_collapsed:
203
+ thinking.add_class("collapsed")
204
+ else:
205
+ thinking.remove_class("collapsed")
206
+
207
+ def get_status_bar(self):
208
+ """Get the status bar widget."""
209
+ try:
210
+ return self.query_one("#enhanced-status")
211
+ except Exception:
212
+ return None
213
+
214
+ def get_tool_panel(self):
215
+ """Get the tool panel widget."""
216
+ try:
217
+ return self.query_one("#enhanced-tools")
218
+ except Exception:
219
+ return None
220
+
221
+ def get_thinking_panel(self):
222
+ """Get the thinking panel widget."""
223
+ try:
224
+ return self.query_one("#enhanced-thinking")
225
+ except Exception:
226
+ return None
227
+
228
+
229
+ def create_enhanced_app_mixin():
230
+ """
231
+ Create a mixin class that adds enhanced TUI features to SuperQodeApp.
232
+
233
+ Usage:
234
+ from superqode.app_enhanced import create_enhanced_app_mixin
235
+
236
+ EnhancedMixin = create_enhanced_app_mixin()
237
+
238
+ class MyApp(EnhancedMixin, SuperQodeApp):
239
+ pass
240
+ """
241
+
242
+ class EnhancedAppMixin:
243
+ """Mixin that adds enhanced TUI features."""
244
+
245
+ def setup_enhanced_tui(self):
246
+ """Set up enhanced TUI components."""
247
+ from superqode.tui_integration import TUIEnhancer
248
+
249
+ self._tui_enhancer = TUIEnhancer(self)
250
+ self._tui_enhancer.setup()
251
+
252
+ @property
253
+ def tui(self):
254
+ """Get the TUI enhancer."""
255
+ if not hasattr(self, "_tui_enhancer"):
256
+ self.setup_enhanced_tui()
257
+ return self._tui_enhancer
258
+
259
+ # Tool call helpers
260
+ def _show_tool_start(self, tool_id, tool_name, tool_kind, arguments=None, file_path=None):
261
+ """Show tool start with enhanced display."""
262
+ self.tui.start_tool(tool_id, tool_name, tool_kind, arguments, file_path)
263
+
264
+ def _show_tool_complete(self, tool_id, result="", error=""):
265
+ """Show tool completion."""
266
+ self.tui.complete_tool(tool_id, result=result, error=error)
267
+
268
+ # Thinking helpers
269
+ def _show_thinking_start(self):
270
+ """Start thinking display."""
271
+ self.tui.start_thinking()
272
+
273
+ def _show_thinking_chunk(self, text):
274
+ """Add thinking chunk."""
275
+ self.tui.add_thought(text)
276
+
277
+ def _show_thinking_complete(self):
278
+ """Complete thinking."""
279
+ self.tui.complete_thinking()
280
+
281
+ # Response helpers
282
+ def _show_response_start(self, agent_name="", model_name=""):
283
+ """Start response streaming."""
284
+ self.tui.start_response(agent_name, model_name)
285
+
286
+ def _show_response_chunk(self, text):
287
+ """Add response chunk."""
288
+ self.tui.append_response(text)
289
+
290
+ def _show_response_complete(self, token_count=0):
291
+ """Complete response."""
292
+ self.tui.complete_response(token_count)
293
+
294
+ # Connection helpers
295
+ def _connect_agent_enhanced(
296
+ self, agent_name, model_name="", provider="", connection_type="byok"
297
+ ):
298
+ """Connect to agent with enhanced status."""
299
+ self.tui.connect_agent(agent_name, model_name, provider, connection_type)
300
+
301
+ def _disconnect_agent_enhanced(self):
302
+ """Disconnect agent."""
303
+ self.tui.disconnect_agent()
304
+
305
+ return EnhancedAppMixin
306
+
307
+
308
+ # ============================================================================
309
+ # EXAMPLE: How to integrate into app_main.py
310
+ # ============================================================================
311
+
312
+ INTEGRATION_EXAMPLE = '''
313
+ # In app_main.py, modify the SuperQodeApp class:
314
+
315
+ from superqode.app_enhanced import create_enhanced_app_mixin
316
+ from superqode.tui_integration import TUIEnhancer
317
+
318
+ EnhancedMixin = create_enhanced_app_mixin()
319
+
320
+ class SuperQodeApp(EnhancedMixin, App):
321
+ # ... existing code ...
322
+
323
+ def on_mount(self):
324
+ # Existing mount code...
325
+ self.query_one("#prompt-input", Input).focus()
326
+ self._load_welcome()
327
+
328
+ # NEW: Set up enhanced TUI
329
+ self.setup_enhanced_tui()
330
+
331
+ # In the ACP message handling, update to use enhanced widgets:
332
+
333
+ async def _handle_acp_tool_call(self, update):
334
+ """Handle tool call from ACP agent."""
335
+ tool_id = update.get("toolCallId", "")
336
+ title = update.get("title", "")
337
+ kind = update.get("kind", "other")
338
+ raw_input = update.get("rawInput", {})
339
+
340
+ # NEW: Use enhanced tool display
341
+ self._show_tool_start(tool_id, title, kind, raw_input)
342
+
343
+ # Track files
344
+ file_path = raw_input.get("path", "")
345
+ if file_path:
346
+ if kind in ("edit", "write"):
347
+ self.tui.track_file_modified(file_path)
348
+ elif kind == "read":
349
+ self.tui.track_file_read(file_path)
350
+
351
+ async def _handle_acp_tool_update(self, update):
352
+ """Handle tool update from ACP agent."""
353
+ tool_id = update.get("toolCallId", "")
354
+ status = update.get("status", "")
355
+ output = update.get("output", "")
356
+
357
+ if status == "completed":
358
+ # NEW: Use enhanced display
359
+ self._show_tool_complete(tool_id, result=output)
360
+ elif status == "failed":
361
+ self._show_tool_complete(tool_id, error=output)
362
+
363
+ async def _handle_acp_thought(self, update):
364
+ """Handle thought/reasoning from ACP agent."""
365
+ content = update.get("content", {})
366
+ text = content.get("text", "")
367
+
368
+ if text:
369
+ # NEW: Use enhanced thinking display
370
+ self._show_thinking_chunk(text)
371
+
372
+ async def _handle_acp_message(self, update):
373
+ """Handle message chunk from ACP agent."""
374
+ content = update.get("content", {})
375
+ text = content.get("text", "")
376
+
377
+ if text:
378
+ # NEW: Use enhanced response display
379
+ self._show_response_chunk(text)
380
+
381
+ # When connecting to an agent:
382
+
383
+ def _connect_to_opencode(self, model):
384
+ """Connect to OpenCode."""
385
+ # Existing connection code...
386
+
387
+ # NEW: Update enhanced status
388
+ self._connect_agent_enhanced(
389
+ agent_name="OpenCode",
390
+ model_name=model,
391
+ provider="opencode",
392
+ connection_type="acp",
393
+ )
394
+ '''
395
+
396
+
397
+ def get_integration_example() -> str:
398
+ """Get the integration example code."""
399
+ return INTEGRATION_EXAMPLE