cct-cli 0.7.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 (325) hide show
  1. calc_terminal/__init__.py +14 -0
  2. calc_terminal/__main__.py +14 -0
  3. calc_terminal/activity.py +1334 -0
  4. calc_terminal/agent.py +3387 -0
  5. calc_terminal/agent_runtime.py +519 -0
  6. calc_terminal/ai_context.py +447 -0
  7. calc_terminal/ai_modes.py +752 -0
  8. calc_terminal/ai_personalization.py +286 -0
  9. calc_terminal/ai_preview_feedback.py +213 -0
  10. calc_terminal/aicore.py +2572 -0
  11. calc_terminal/anim.py +367 -0
  12. calc_terminal/app.py +3685 -0
  13. calc_terminal/art.py +639 -0
  14. calc_terminal/atomsim.py +368 -0
  15. calc_terminal/attachments.py +743 -0
  16. calc_terminal/benchmark_system.py +414 -0
  17. calc_terminal/browser/__init__.py +36 -0
  18. calc_terminal/browser/browser_state.py +346 -0
  19. calc_terminal/browser/devserver.py +176 -0
  20. calc_terminal/browser/engine.py +494 -0
  21. calc_terminal/browser/navigation.py +84 -0
  22. calc_terminal/browser/preview.py +429 -0
  23. calc_terminal/browser/preview_entry.py +95 -0
  24. calc_terminal/browser/project_detector.py +144 -0
  25. calc_terminal/browser/server.py +449 -0
  26. calc_terminal/browser/state.py +75 -0
  27. calc_terminal/browser/watcher.py +99 -0
  28. calc_terminal/browser_gui/__init__.py +1 -0
  29. calc_terminal/browser_gui/__main__.py +3 -0
  30. calc_terminal/browser_gui/launcher.py +173 -0
  31. calc_terminal/browser_gui/playwright_browser.py +117 -0
  32. calc_terminal/browser_gui/qt_browser.py +1501 -0
  33. calc_terminal/browser_gui/webview_browser.py +57 -0
  34. calc_terminal/capabilities/__init__.py +35 -0
  35. calc_terminal/capabilities/adapters/__init__.py +33 -0
  36. calc_terminal/capabilities/adapters/bioinformatics.py +204 -0
  37. calc_terminal/capabilities/adapters/browser_adapter.py +205 -0
  38. calc_terminal/capabilities/adapters/filesystem.py +206 -0
  39. calc_terminal/capabilities/adapters/git_adapter.py +202 -0
  40. calc_terminal/capabilities/adapters/jupyter_adapter.py +138 -0
  41. calc_terminal/capabilities/adapters/ml_frameworks.py +158 -0
  42. calc_terminal/capabilities/adapters/platforms.py +200 -0
  43. calc_terminal/capabilities/adapters/python_exec.py +93 -0
  44. calc_terminal/capabilities/adapters/quantum_adapter.py +150 -0
  45. calc_terminal/capabilities/adapters/scientific_comp.py +123 -0
  46. calc_terminal/capabilities/adapters/structural_bio.py +161 -0
  47. calc_terminal/capabilities/adapters/terminal.py +99 -0
  48. calc_terminal/capabilities/bus.py +178 -0
  49. calc_terminal/capabilities/discovery.py +207 -0
  50. calc_terminal/capabilities/schema.py +221 -0
  51. calc_terminal/cat.ico +0 -0
  52. calc_terminal/cat_browser.py +2018 -0
  53. calc_terminal/chat_store.py +703 -0
  54. calc_terminal/cli.py +1178 -0
  55. calc_terminal/code_editor.py +640 -0
  56. calc_terminal/collaboration.py +723 -0
  57. calc_terminal/commands_data.py +139 -0
  58. calc_terminal/compatibility_engine.py +352 -0
  59. calc_terminal/compute/__init__.py +31 -0
  60. calc_terminal/compute/fabric.py +350 -0
  61. calc_terminal/config.py +227 -0
  62. calc_terminal/core/__init__.py +41 -0
  63. calc_terminal/core/checkpoint.py +156 -0
  64. calc_terminal/core/input/__init__.py +45 -0
  65. calc_terminal/core/mode_registry.py +300 -0
  66. calc_terminal/core/project_graph.py +172 -0
  67. calc_terminal/core/recovery.py +129 -0
  68. calc_terminal/core/security_layer.py +112 -0
  69. calc_terminal/core/task_graph.py +202 -0
  70. calc_terminal/core/unified_runtime.py +184 -0
  71. calc_terminal/core/verification.py +257 -0
  72. calc_terminal/customization.py +1566 -0
  73. calc_terminal/derivations.py +153 -0
  74. calc_terminal/device_control.py +263 -0
  75. calc_terminal/diagnostics/__init__.py +27 -0
  76. calc_terminal/diagnostics/doctor_engine.py +382 -0
  77. calc_terminal/diagnostics/self_test.py +247 -0
  78. calc_terminal/doctor.py +519 -0
  79. calc_terminal/easter_eggs.py +274 -0
  80. calc_terminal/editor/__init__.py +1 -0
  81. calc_terminal/editor/actions.py +263 -0
  82. calc_terminal/editor/commands.py +160 -0
  83. calc_terminal/editor/shortcuts.py +226 -0
  84. calc_terminal/engine.py +259 -0
  85. calc_terminal/errors.py +120 -0
  86. calc_terminal/event_stream.py +146 -0
  87. calc_terminal/eventbus.py +133 -0
  88. calc_terminal/extensions.py +733 -0
  89. calc_terminal/fallback_cli.py +1321 -0
  90. calc_terminal/first_run.py +265 -0
  91. calc_terminal/fomoji_auth.py +1043 -0
  92. calc_terminal/formulas.py +82 -0
  93. calc_terminal/fs_cache.py +121 -0
  94. calc_terminal/fs_watcher.py +277 -0
  95. calc_terminal/game.py +193 -0
  96. calc_terminal/gen1.py +5 -0
  97. calc_terminal/generators.py +245 -0
  98. calc_terminal/gestures/__init__.py +42 -0
  99. calc_terminal/gestures/bindings.py +175 -0
  100. calc_terminal/gestures/manager.py +477 -0
  101. calc_terminal/goodbye.py +363 -0
  102. calc_terminal/gpu3d.py +290 -0
  103. calc_terminal/graphs.py +358 -0
  104. calc_terminal/hardware_analyzer.py +440 -0
  105. calc_terminal/host/__init__.py +30 -0
  106. calc_terminal/host/browser_manager.py +187 -0
  107. calc_terminal/host/desktop.py +1386 -0
  108. calc_terminal/host/launcher.py +395 -0
  109. calc_terminal/host/terminal.py +279 -0
  110. calc_terminal/identity.py +216 -0
  111. calc_terminal/input/__init__.py +54 -0
  112. calc_terminal/input/capabilities.py +258 -0
  113. calc_terminal/input/focus.py +87 -0
  114. calc_terminal/input/gestures.py +64 -0
  115. calc_terminal/input/pointer.py +114 -0
  116. calc_terminal/input/touch.py +345 -0
  117. calc_terminal/keys.py +84 -0
  118. calc_terminal/live_automation.py +165 -0
  119. calc_terminal/mathtext.py +433 -0
  120. calc_terminal/mcp.py +386 -0
  121. calc_terminal/memory.py +337 -0
  122. calc_terminal/memory_v2.py +479 -0
  123. calc_terminal/metrics.py +333 -0
  124. calc_terminal/mode_detection.py +146 -0
  125. calc_terminal/model.py +2431 -0
  126. calc_terminal/model_router.py +665 -0
  127. calc_terminal/models/__init__.py +0 -0
  128. calc_terminal/models/active_state.py +187 -0
  129. calc_terminal/models/dynamic_registry.py +584 -0
  130. calc_terminal/models/manager.py +781 -0
  131. calc_terminal/models/model_metadata.json +3526 -0
  132. calc_terminal/models/profiles.py +194 -0
  133. calc_terminal/models/registry.py +265 -0
  134. calc_terminal/models/schema.py +197 -0
  135. calc_terminal/models/validator.py +287 -0
  136. calc_terminal/models/verification_engine.py +368 -0
  137. calc_terminal/native_picker.py +215 -0
  138. calc_terminal/ollama_catalog.py +279 -0
  139. calc_terminal/ollama_download.py +233 -0
  140. calc_terminal/orchestrator.py +304 -0
  141. calc_terminal/package_research.py +322 -0
  142. calc_terminal/packages.py +1024 -0
  143. calc_terminal/pc_specs.py +116 -0
  144. calc_terminal/permissions.py +334 -0
  145. calc_terminal/pet.py +106 -0
  146. calc_terminal/pipeline.py +505 -0
  147. calc_terminal/platform/__init__.py +491 -0
  148. calc_terminal/platform/desktop.py +491 -0
  149. calc_terminal/platform/web.py +781 -0
  150. calc_terminal/preview/__init__.py +1 -0
  151. calc_terminal/preview/dev_server.py +303 -0
  152. calc_terminal/preview/diagnostics.py +131 -0
  153. calc_terminal/preview/live_reload.py +66 -0
  154. calc_terminal/preview/manager.py +129 -0
  155. calc_terminal/project_stats.py +209 -0
  156. calc_terminal/projects.py +328 -0
  157. calc_terminal/providers/__init__.py +0 -0
  158. calc_terminal/providers/adapters/__init__.py +80 -0
  159. calc_terminal/providers/adapters/anthropic_adapter.py +127 -0
  160. calc_terminal/providers/adapters/base.py +106 -0
  161. calc_terminal/providers/adapters/chinese_adapters.py +420 -0
  162. calc_terminal/providers/adapters/gemini_adapter.py +101 -0
  163. calc_terminal/providers/adapters/ollama_adapter.py +83 -0
  164. calc_terminal/providers/adapters/openai_adapter.py +159 -0
  165. calc_terminal/providers/adapters/other_adapters.py +246 -0
  166. calc_terminal/providers/anthropic_provider.py +172 -0
  167. calc_terminal/providers/auto_update.py +416 -0
  168. calc_terminal/providers/base_provider.py +105 -0
  169. calc_terminal/providers/discovery_manager.py +207 -0
  170. calc_terminal/providers/gemini_provider.py +178 -0
  171. calc_terminal/providers/lifecycle.py +767 -0
  172. calc_terminal/providers/ollama_adapter.py +707 -0
  173. calc_terminal/providers/openai_provider.py +254 -0
  174. calc_terminal/providers/provider_manager.py +1827 -0
  175. calc_terminal/providers/providers.json +4075 -0
  176. calc_terminal/reactionsim.py +279 -0
  177. calc_terminal/registry.py +337 -0
  178. calc_terminal/report.py +162 -0
  179. calc_terminal/research/__init__.py +45 -0
  180. calc_terminal/research/artifact_intel.py +126 -0
  181. calc_terminal/research/data_lineage.py +123 -0
  182. calc_terminal/research/experiment_ledger.py +303 -0
  183. calc_terminal/research/reproducibility.py +131 -0
  184. calc_terminal/resilience/__init__.py +47 -0
  185. calc_terminal/resilience/agent_state.py +121 -0
  186. calc_terminal/resilience/capability_matcher.py +174 -0
  187. calc_terminal/resilience/circuit_breaker.py +158 -0
  188. calc_terminal/resilience/failover_engine.py +230 -0
  189. calc_terminal/resilience/health_monitor.py +192 -0
  190. calc_terminal/resilience/ollama_adapter.py +125 -0
  191. calc_terminal/resilience/orchestrator.py +312 -0
  192. calc_terminal/resilience/types.py +134 -0
  193. calc_terminal/sandbox.py +98 -0
  194. calc_terminal/scires.py +558 -0
  195. calc_terminal/security_scanner.py +126 -0
  196. calc_terminal/session.py +294 -0
  197. calc_terminal/sim3d.py +206 -0
  198. calc_terminal/solver.py +276 -0
  199. calc_terminal/sound.py +127 -0
  200. calc_terminal/task_reports.py +287 -0
  201. calc_terminal/terminal_host.py +201 -0
  202. calc_terminal/terminal_identity.py +411 -0
  203. calc_terminal/test_ai_mode_reliability.py +344 -0
  204. calc_terminal/test_browser.py +368 -0
  205. calc_terminal/test_code_editor_upgrade.py +485 -0
  206. calc_terminal/test_customization.py +1148 -0
  207. calc_terminal/test_customization_ui.py +612 -0
  208. calc_terminal/test_dynamic_registry.py +304 -0
  209. calc_terminal/test_extensions.py +436 -0
  210. calc_terminal/test_overhaul.py +557 -0
  211. calc_terminal/test_project_detect.py +255 -0
  212. calc_terminal/test_root_cause_fix.py +527 -0
  213. calc_terminal/test_stability.py +532 -0
  214. calc_terminal/test_terminal_identity.py +132 -0
  215. calc_terminal/test_v079_speed.py +460 -0
  216. calc_terminal/theme.py +1107 -0
  217. calc_terminal/timeline.py +139 -0
  218. calc_terminal/todos.py +246 -0
  219. calc_terminal/tool_call_normalizer.py +419 -0
  220. calc_terminal/tui.py +104 -0
  221. calc_terminal/ui/__init__.py +8 -0
  222. calc_terminal/ui/activity_panel.py +231 -0
  223. calc_terminal/ui/activity_stream_panel.py +238 -0
  224. calc_terminal/ui/animations.py +122 -0
  225. calc_terminal/ui/app.py +7271 -0
  226. calc_terminal/ui/attach_panel.py +597 -0
  227. calc_terminal/ui/attachments.py +424 -0
  228. calc_terminal/ui/backup_panel.py +810 -0
  229. calc_terminal/ui/browser_shell.py +887 -0
  230. calc_terminal/ui/cat_agent.py +357 -0
  231. calc_terminal/ui/chats_panel.py +899 -0
  232. calc_terminal/ui/command_palette.py +125 -0
  233. calc_terminal/ui/command_palette_modal.py +166 -0
  234. calc_terminal/ui/composer.py +1141 -0
  235. calc_terminal/ui/context_menu.py +197 -0
  236. calc_terminal/ui/conversation.py +1435 -0
  237. calc_terminal/ui/customization_panel.py +1229 -0
  238. calc_terminal/ui/dashboard.py +404 -0
  239. calc_terminal/ui/design_system.py +557 -0
  240. calc_terminal/ui/diff_panel.py +213 -0
  241. calc_terminal/ui/editor.py +2102 -0
  242. calc_terminal/ui/empty_state.py +302 -0
  243. calc_terminal/ui/events.py +487 -0
  244. calc_terminal/ui/extensions_panel.py +815 -0
  245. calc_terminal/ui/footer.py +166 -0
  246. calc_terminal/ui/gestures_panel.py +383 -0
  247. calc_terminal/ui/goodbye_screen.py +100 -0
  248. calc_terminal/ui/header.py +1034 -0
  249. calc_terminal/ui/help_panel.py +254 -0
  250. calc_terminal/ui/live_activities.py +914 -0
  251. calc_terminal/ui/mcp_panel.py +570 -0
  252. calc_terminal/ui/memory_center.py +524 -0
  253. calc_terminal/ui/mode_colors_panel.py +525 -0
  254. calc_terminal/ui/nav_screens.py +747 -0
  255. calc_terminal/ui/ollama_panel.py +536 -0
  256. calc_terminal/ui/palette.py +221 -0
  257. calc_terminal/ui/permission_panel.py +269 -0
  258. calc_terminal/ui/personalization_panel.py +517 -0
  259. calc_terminal/ui/personalize_center.py +1568 -0
  260. calc_terminal/ui/preview_panel.py +441 -0
  261. calc_terminal/ui/resizers.py +402 -0
  262. calc_terminal/ui/sidebar.py +1285 -0
  263. calc_terminal/ui/statusbar.py +168 -0
  264. calc_terminal/ui/theme_css.py +1396 -0
  265. calc_terminal/ui/thinking.py +226 -0
  266. calc_terminal/ui/timeline_panel.py +102 -0
  267. calc_terminal/ui/todo_panel.py +193 -0
  268. calc_terminal/ui/viewport.py +136 -0
  269. calc_terminal/ui/vision_panel.py +489 -0
  270. calc_terminal/ui/welcome_modal.py +343 -0
  271. calc_terminal/ui/widgets.py +160 -0
  272. calc_terminal/ui/workspace.py +831 -0
  273. calc_terminal/viewers/__init__.py +1 -0
  274. calc_terminal/viewers/document_viewer.py +252 -0
  275. calc_terminal/viewers/image_viewer.py +241 -0
  276. calc_terminal/viewers/pdf_viewer.py +203 -0
  277. calc_terminal/viewers/presentation_viewer.py +164 -0
  278. calc_terminal/viewers/registry.py +120 -0
  279. calc_terminal/viewers/spreadsheet_viewer.py +204 -0
  280. calc_terminal/vision/__init__.py +89 -0
  281. calc_terminal/vision/analysis.py +194 -0
  282. calc_terminal/vision/annotations.py +297 -0
  283. calc_terminal/vision/capture.py +171 -0
  284. calc_terminal/vision/context.py +231 -0
  285. calc_terminal/vision/correlation.py +169 -0
  286. calc_terminal/vision/cursor.py +258 -0
  287. calc_terminal/vision/events.py +66 -0
  288. calc_terminal/vision/frame_pipeline.py +259 -0
  289. calc_terminal/vision/priority.py +218 -0
  290. calc_terminal/vision/provider.py +180 -0
  291. calc_terminal/vision/safety.py +149 -0
  292. calc_terminal/vision/session.py +281 -0
  293. calc_terminal/vision/verify.py +162 -0
  294. calc_terminal/vision.py +514 -0
  295. calc_terminal/vscode_integration.py +113 -0
  296. calc_terminal/web/__init__.py +8 -0
  297. calc_terminal/web/cat_runtime.py +710 -0
  298. calc_terminal/web/server.py +2891 -0
  299. calc_terminal/web/static/css/app.css +3152 -0
  300. calc_terminal/web/static/icons/badge-72.png +0 -0
  301. calc_terminal/web/static/icons/cat.ico +0 -0
  302. calc_terminal/web/static/icons/icon-128.png +0 -0
  303. calc_terminal/web/static/icons/icon-144.png +0 -0
  304. calc_terminal/web/static/icons/icon-152.png +0 -0
  305. calc_terminal/web/static/icons/icon-192.png +0 -0
  306. calc_terminal/web/static/icons/icon-384.png +0 -0
  307. calc_terminal/web/static/icons/icon-512.png +0 -0
  308. calc_terminal/web/static/icons/icon-72.png +0 -0
  309. calc_terminal/web/static/icons/icon-96.png +0 -0
  310. calc_terminal/web/static/icons/icon.svg +34 -0
  311. calc_terminal/web/static/icons/new-project.png +0 -0
  312. calc_terminal/web/static/icons/open-project.png +0 -0
  313. calc_terminal/web/static/index.html +734 -0
  314. calc_terminal/web/static/js/app.js +2403 -0
  315. calc_terminal/web/static/manifest.json +88 -0
  316. calc_terminal/web/static/sw.js +230 -0
  317. calc_terminal/workflow_engine.py +769 -0
  318. calc_terminal/workspace.py +593 -0
  319. calc_terminal/workspace_index.py +385 -0
  320. cct_cli-0.7.9.0.dist-info/METADATA +210 -0
  321. cct_cli-0.7.9.0.dist-info/RECORD +325 -0
  322. cct_cli-0.7.9.0.dist-info/WHEEL +5 -0
  323. cct_cli-0.7.9.0.dist-info/entry_points.txt +4 -0
  324. cct_cli-0.7.9.0.dist-info/licenses/LICENSE +21 -0
  325. cct_cli-0.7.9.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,254 @@
1
+ """
2
+ CCT UI — help_panel.py: Help Center panel with categorized topics,
3
+ quick reference, and keyboard shortcuts.
4
+ """
5
+
6
+ if __name__ == "__main__":
7
+ print("This is a library file and is not meant to be run directly.")
8
+ import sys
9
+ sys.exit(1)
10
+
11
+ TEXTUAL_AVAILABLE = True
12
+ try:
13
+ from textual.containers import Vertical, Horizontal, ScrollableContainer
14
+ from textual.screen import Screen
15
+ from textual.widgets import Static, Button
16
+ from textual.binding import Binding
17
+ except Exception:
18
+ TEXTUAL_AVAILABLE = False
19
+
20
+
21
+ _HELP_TOPICS = [
22
+ ("Getting Started", [
23
+ ("Open a Folder", "Menu \u2192 Open Folder or Ctrl+O"),
24
+ ("Start a Chat", "Type a message and press Enter"),
25
+ ("Switch Models", "Menu \u2192 User \u2192 Model"),
26
+ ("Change Permissions", "Click the permission pill in the header"),
27
+ ]),
28
+ ("Navigation", [
29
+ ("Main Menu", "Click the \u2261 button or press Ctrl+M"),
30
+ ("Dashboard", "Menu \u2192 Dashboard"),
31
+ ("Recent Workspaces", "Menu \u2192 Recent Workspaces"),
32
+ ("Chat History", "Menu \u2192 Chats"),
33
+ ("Explorer Sidebar", "Ctrl+B to toggle"),
34
+ ]),
35
+ ("AI Features", [
36
+ ("Agent Mode", "Type /agent followed by your task"),
37
+ ("Chat Mode", "Just type your message directly"),
38
+ ("Personalize AI", "Menu \u2192 Personalize"),
39
+ ("MCP Servers", "Menu \u2192 MCP Servers"),
40
+ ]),
41
+ ("File Operations", [
42
+ ("Open File", "Click file in Explorer or Ctrl+O"),
43
+ ("Save File", "Ctrl+S"),
44
+ ("New File", "Ctrl+N in Explorer"),
45
+ ("Search Files", "Ctrl+Shift+F"),
46
+ ]),
47
+ ("View Controls", [
48
+ ("Toggle Sidebar", "Ctrl+B"),
49
+ ("Toggle Fullscreen", "F11"),
50
+ ("Zoom In/Out", "Ctrl+= / Ctrl+-"),
51
+ ("Reset Zoom", "Ctrl+0"),
52
+ ]),
53
+ ("Account", [
54
+ ("Sign In", "Run: cat --auth login"),
55
+ ("Sign Out", "Menu \u2192 User \u2192 Sign Out"),
56
+ ("View Profile", "Menu \u2192 User"),
57
+ ("Chat History", "Menu \u2192 Chats"),
58
+ ]),
59
+ ]
60
+
61
+ _KEYBOARD_SHORTCUTS = [
62
+ ("Ctrl+M", "Open/close main menu"),
63
+ ("Ctrl+B", "Toggle Explorer sidebar"),
64
+ ("Ctrl+O", "Open folder"),
65
+ ("Ctrl+S", "Save current file"),
66
+ ("Ctrl+N", "New file"),
67
+ ("Ctrl+Shift+F", "Search in files"),
68
+ ("Ctrl+/", "Toggle comment"),
69
+ ("Ctrl+Z", "Undo"),
70
+ ("Ctrl+Shift+Z", "Redo"),
71
+ ("F11", "Toggle fullscreen"),
72
+ ("Ctrl+=", "Zoom in"),
73
+ ("Ctrl+-", "Zoom out"),
74
+ ("Ctrl+0", "Reset zoom"),
75
+ ("Escape", "Close panel / cancel"),
76
+ ("Tab", "Next field / autocomplete"),
77
+ ("Shift+Tab", "Previous field"),
78
+ ("Enter", "Submit / confirm"),
79
+ ("Up/Down", "Navigate history / options"),
80
+ ]
81
+
82
+
83
+ if TEXTUAL_AVAILABLE:
84
+
85
+ class HelpCenterPanel(Screen):
86
+ """Help Center with categorized topics and quick reference."""
87
+
88
+ CSS = """
89
+ HelpCenterPanel { align: center middle; background: $app-background 60%; }
90
+ #hc-box {
91
+ width: 82; max-width: 95%; height: 34; max-height: 88%;
92
+ background: $surface; border: tall $border-active $border;
93
+ padding: 0 0 1 0;
94
+ opacity: 0; offset-y: 1;
95
+ transition: opacity 120ms, offset 150ms;
96
+ layout: vertical;
97
+ }
98
+ #hc-box.open { opacity: 1; offset-y: 0; }
99
+ #hc-titlebar {
100
+ height: 3; min-height: 3; padding: 0 2;
101
+ border-bottom: solid $border;
102
+ align-vertical: middle;
103
+ }
104
+ #hc-title { text-style: bold; width: 1fr; }
105
+ #hc-close, Button#hc-close, Button.cct-popup-close {
106
+ width: 3; min-width: 3; max-width: 3;
107
+ height: 1; min-height: 1; max-height: 1;
108
+ padding: 0; margin: 0;
109
+ background: transparent; color: $text-faint; border: none;
110
+ content-align: center middle;
111
+ }
112
+ #hc-close:hover, Button#hc-close:hover, Button.cct-popup-close:hover {
113
+ color: $error; background: transparent; border: none;
114
+ }
115
+ #hc-body { height: 1fr; min-height: 0; }
116
+ #hc-topics { width: 30; min-width: 30; height: 100%; padding: 1 1;
117
+ border-right: solid $border; background: transparent; }
118
+ #hc-topic-list { width: 100%; height: 100%; overflow-y: auto;
119
+ scrollbar-size: 1 1;
120
+ scrollbar-color: $border $surface;
121
+ scrollbar-gutter: stable; background: transparent; }
122
+ .hc-topic { height: 2; color: $text-muted; padding: 0 1;
123
+ background: transparent;
124
+ border-left: thick transparent; }
125
+ .hc-topic:hover { color: $accent; text-style: bold; }
126
+ .hc-topic-sel { color: $accent; border-left: thick $accent; text-style: bold; background: transparent; }
127
+ #hc-detail { width: 1fr; height: 100%; padding: 0 2; overflow-y: auto;
128
+ scrollbar-size: 1 1;
129
+ scrollbar-color: $border $surface;
130
+ scrollbar-gutter: stable; }
131
+ .hc-section { color: $text-faint; height: auto; padding-top: 1;
132
+ border-top: solid $border; margin-top: 1; }
133
+ .hc-row { height: 1; color: $text-muted; padding: 0 0; }
134
+ #hc-close-bar {
135
+ height: 4; min-height: 4; padding: 0 2;
136
+ border-top: solid $border;
137
+ align-horizontal: right; align-vertical: middle;
138
+ }
139
+ #hc-close-bar Button {
140
+ margin-left: 1;
141
+ border: tall $border-active $border;
142
+ }
143
+ #hc-close-bar Button:hover {
144
+ border: tall $accent-highlight $accent;
145
+ color: $text;
146
+ }
147
+ #hc-close-bar Button.-primary {
148
+ border: tall #c4b5fd #4c1d95;
149
+ background: #7c3aed;
150
+ color: #ffffff;
151
+ text-style: bold;
152
+ }
153
+ #hc-close-bar Button.-primary:hover {
154
+ border: tall #ddd6fe #5b21b6;
155
+ background: #8b5cf6;
156
+ color: #ffffff;
157
+ }
158
+ #hc-close-bar Button.-active {
159
+ offset-y: 1;
160
+ }
161
+ """
162
+
163
+ BINDINGS = [
164
+ Binding("escape", "cancel", "Close"),
165
+ ]
166
+
167
+ def __init__(self):
168
+ super().__init__()
169
+ self._selected = 0
170
+
171
+ def compose(self):
172
+ from textual.containers import Horizontal as H
173
+ with Vertical(id="hc-box"):
174
+ with H(id="hc-titlebar"):
175
+ yield Static("? Help Center", id="hc-title")
176
+ yield Button("\u2715", id="hc-close", classes="cct-popup-close cct-ctrl")
177
+ with H(id="hc-body"):
178
+ with Vertical(id="hc-topics"):
179
+ with ScrollableContainer(id="hc-topic-list"):
180
+ for i, (cat, _) in enumerate(_HELP_TOPICS):
181
+ yield Static(f" {cat}", classes="hc-topic",
182
+ id=f"hc-topic-{i}")
183
+ with ScrollableContainer(id="hc-detail"):
184
+ yield from self._detail_lines(0)
185
+ with H(id="hc-close-bar"):
186
+ yield Button(" \u2328 Shortcuts ", id="hc-shortcuts", classes="cct-btn cct-btn-sm")
187
+ yield Button(" Done ", id="hc-done", variant="primary", classes="cct-btn")
188
+
189
+ def _detail_lines(self, index):
190
+ """Yield widgets for the detail pane of topic `index`."""
191
+ if index < 0 or index >= len(_HELP_TOPICS):
192
+ return
193
+ cat, items = _HELP_TOPICS[index]
194
+ yield Static(cat, classes="hc-section")
195
+ for label, desc in items:
196
+ yield Static(f" [b]{label}[/b] \u2014 {desc}", classes="hc-row")
197
+
198
+ def _rebuild_detail(self, index):
199
+ try:
200
+ detail = self.query_one("#hc-detail", ScrollableContainer)
201
+ except Exception:
202
+ return
203
+ detail.remove_children()
204
+ for widget in self._detail_lines(index):
205
+ detail.mount(widget)
206
+
207
+ def on_mount(self):
208
+ self.call_after_refresh(
209
+ lambda: self.query_one("#hc-box").add_class("open"))
210
+ self._sync_selection()
211
+
212
+ def _sync_selection(self):
213
+ for i, _ in enumerate(_HELP_TOPICS):
214
+ try:
215
+ row = self.query_one(f"#hc-topic-{i}", Static)
216
+ row.set_class(i == self._selected, "hc-topic-sel")
217
+ except Exception:
218
+ pass
219
+
220
+ def on_click(self, event):
221
+ if getattr(event, "widget", None) in (self, None):
222
+ self.dismiss(None)
223
+ return
224
+ # Check if a topic was clicked
225
+ target = getattr(event, "widget", None)
226
+ if target and hasattr(target, "id") and target.id and target.id.startswith("hc-topic-"):
227
+ try:
228
+ idx = int(target.id.split("-")[-1])
229
+ self._selected = idx
230
+ self._sync_selection()
231
+ self._rebuild_detail(idx)
232
+ except (ValueError, IndexError):
233
+ pass
234
+
235
+ def on_button_pressed(self, event):
236
+ if event.button.id == "hc-close" or event.button.id == "hc-done":
237
+ self.dismiss(None)
238
+ elif event.button.id == "hc-shortcuts":
239
+ self.dismiss("shortcuts")
240
+
241
+ def on_key(self, event):
242
+ if event.key == "escape":
243
+ self.dismiss(None)
244
+ elif event.key in ("down", "tab"):
245
+ self._selected = (self._selected + 1) % len(_HELP_TOPICS)
246
+ self._sync_selection()
247
+ self._rebuild_detail(self._selected)
248
+ elif event.key in ("up", "shift+tab"):
249
+ self._selected = (self._selected - 1) % len(_HELP_TOPICS)
250
+ self._sync_selection()
251
+ self._rebuild_detail(self._selected)
252
+
253
+ else:
254
+ HelpCenterPanel = None