@pennyfarthing/cyclist 10.4.0 → 11.0.0

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 (384) hide show
  1. package/dist/api/agent-load.d.ts +1 -2
  2. package/dist/api/agent-load.d.ts.map +1 -1
  3. package/dist/api/agent-load.js +2 -123
  4. package/dist/api/agent-load.js.map +1 -1
  5. package/dist/api/audit-log.d.ts +1 -17
  6. package/dist/api/audit-log.d.ts.map +1 -1
  7. package/dist/api/audit-log.js +2 -162
  8. package/dist/api/audit-log.js.map +1 -1
  9. package/dist/api/background-tasks.d.ts +1 -26
  10. package/dist/api/background-tasks.d.ts.map +1 -1
  11. package/dist/api/background-tasks.js +2 -55
  12. package/dist/api/background-tasks.js.map +1 -1
  13. package/dist/api/bell.d.ts +1 -18
  14. package/dist/api/bell.d.ts.map +1 -1
  15. package/dist/api/bell.js +2 -33
  16. package/dist/api/bell.js.map +1 -1
  17. package/dist/api/code-markers.d.ts +1 -8
  18. package/dist/api/code-markers.d.ts.map +1 -1
  19. package/dist/api/code-markers.js +2 -61
  20. package/dist/api/code-markers.js.map +1 -1
  21. package/dist/api/complexity.d.ts +1 -2
  22. package/dist/api/complexity.d.ts.map +1 -1
  23. package/dist/api/complexity.js +2 -46
  24. package/dist/api/complexity.js.map +1 -1
  25. package/dist/api/context.d.ts +1 -37
  26. package/dist/api/context.d.ts.map +1 -1
  27. package/dist/api/context.js +2 -143
  28. package/dist/api/context.js.map +1 -1
  29. package/dist/api/dead-code.d.ts +1 -2
  30. package/dist/api/dead-code.d.ts.map +1 -1
  31. package/dist/api/dead-code.js +2 -69
  32. package/dist/api/dead-code.js.map +1 -1
  33. package/dist/api/dependencies.d.ts +1 -2
  34. package/dist/api/dependencies.d.ts.map +1 -1
  35. package/dist/api/dependencies.js +2 -42
  36. package/dist/api/dependencies.js.map +1 -1
  37. package/dist/api/evaluation.d.ts +1 -19
  38. package/dist/api/evaluation.d.ts.map +1 -1
  39. package/dist/api/evaluation.js +2 -127
  40. package/dist/api/evaluation.js.map +1 -1
  41. package/dist/api/file-browser.d.ts +1 -8
  42. package/dist/api/file-browser.d.ts.map +1 -1
  43. package/dist/api/file-browser.js +2 -114
  44. package/dist/api/file-browser.js.map +1 -1
  45. package/dist/api/git.d.ts +1 -46
  46. package/dist/api/git.d.ts.map +1 -1
  47. package/dist/api/git.js +2 -354
  48. package/dist/api/git.js.map +1 -1
  49. package/dist/api/health-score.d.ts +1 -2
  50. package/dist/api/health-score.d.ts.map +1 -1
  51. package/dist/api/health-score.js +2 -46
  52. package/dist/api/health-score.js.map +1 -1
  53. package/dist/api/hook-request.d.ts +1 -40
  54. package/dist/api/hook-request.d.ts.map +1 -1
  55. package/dist/api/hook-request.js +2 -277
  56. package/dist/api/hook-request.js.map +1 -1
  57. package/dist/api/hotspots.d.ts +1 -2
  58. package/dist/api/hotspots.d.ts.map +1 -1
  59. package/dist/api/hotspots.js +2 -61
  60. package/dist/api/hotspots.js.map +1 -1
  61. package/dist/api/identity.d.ts +1 -16
  62. package/dist/api/identity.d.ts.map +1 -1
  63. package/dist/api/identity.js +2 -78
  64. package/dist/api/identity.js.map +1 -1
  65. package/dist/api/index.d.ts +1 -34
  66. package/dist/api/index.d.ts.map +1 -1
  67. package/dist/api/index.js +2 -44
  68. package/dist/api/index.js.map +1 -1
  69. package/dist/api/mode.d.ts +1 -22
  70. package/dist/api/mode.d.ts.map +1 -1
  71. package/dist/api/mode.js +2 -37
  72. package/dist/api/mode.js.map +1 -1
  73. package/dist/api/otlp.d.ts +1 -2
  74. package/dist/api/otlp.d.ts.map +1 -1
  75. package/dist/api/otlp.js +2 -46
  76. package/dist/api/otlp.js.map +1 -1
  77. package/dist/api/permissions.d.ts +1 -15
  78. package/dist/api/permissions.d.ts.map +1 -1
  79. package/dist/api/permissions.js +2 -66
  80. package/dist/api/permissions.js.map +1 -1
  81. package/dist/api/persona.d.ts +1 -8
  82. package/dist/api/persona.d.ts.map +1 -1
  83. package/dist/api/persona.js +2 -67
  84. package/dist/api/persona.js.map +1 -1
  85. package/dist/api/portrait.d.ts +1 -5
  86. package/dist/api/portrait.d.ts.map +1 -1
  87. package/dist/api/portrait.js +2 -27
  88. package/dist/api/portrait.js.map +1 -1
  89. package/dist/api/settings.d.ts +1 -53
  90. package/dist/api/settings.d.ts.map +1 -1
  91. package/dist/api/settings.js +2 -464
  92. package/dist/api/settings.js.map +1 -1
  93. package/dist/api/spans.d.ts +1 -16
  94. package/dist/api/spans.d.ts.map +1 -1
  95. package/dist/api/spans.js +2 -244
  96. package/dist/api/spans.js.map +1 -1
  97. package/dist/api/stats.d.ts +1 -12
  98. package/dist/api/stats.d.ts.map +1 -1
  99. package/dist/api/stats.js +2 -84
  100. package/dist/api/stats.js.map +1 -1
  101. package/dist/api/story.d.ts +1 -2
  102. package/dist/api/story.d.ts.map +1 -1
  103. package/dist/api/story.js +2 -14
  104. package/dist/api/story.js.map +1 -1
  105. package/dist/api/telemetry.d.ts +1 -18
  106. package/dist/api/telemetry.d.ts.map +1 -1
  107. package/dist/api/telemetry.js +2 -164
  108. package/dist/api/telemetry.js.map +1 -1
  109. package/dist/api/theme-agents.d.ts +1 -60
  110. package/dist/api/theme-agents.d.ts.map +1 -1
  111. package/dist/api/theme-agents.js +2 -213
  112. package/dist/api/theme-agents.js.map +1 -1
  113. package/dist/api/todos.d.ts +1 -32
  114. package/dist/api/todos.d.ts.map +1 -1
  115. package/dist/api/todos.js +2 -43
  116. package/dist/api/todos.js.map +1 -1
  117. package/dist/api/token-stats.d.ts +1 -7
  118. package/dist/api/token-stats.d.ts.map +1 -1
  119. package/dist/api/token-stats.js +2 -35
  120. package/dist/api/token-stats.js.map +1 -1
  121. package/dist/api/welcome.d.ts +1 -21
  122. package/dist/api/welcome.d.ts.map +1 -1
  123. package/dist/api/welcome.js +2 -34
  124. package/dist/api/welcome.js.map +1 -1
  125. package/dist/bikerack.js +2 -2
  126. package/dist/bikerack.js.map +1 -1
  127. package/dist/env.d.ts +6 -0
  128. package/dist/env.d.ts.map +1 -0
  129. package/dist/env.js +10 -0
  130. package/dist/env.js.map +1 -0
  131. package/dist/focus.d.ts +53 -0
  132. package/dist/focus.d.ts.map +1 -0
  133. package/dist/focus.js +122 -0
  134. package/dist/focus.js.map +1 -0
  135. package/dist/git-cache.d.ts +1 -0
  136. package/dist/git-cache.d.ts.map +1 -1
  137. package/dist/git-cache.js +3 -1
  138. package/dist/git-cache.js.map +1 -1
  139. package/dist/menu-builder.d.ts.map +1 -1
  140. package/dist/menu-builder.js +0 -1
  141. package/dist/menu-builder.js.map +1 -1
  142. package/dist/prime.d.ts +3 -3
  143. package/dist/prime.d.ts.map +1 -1
  144. package/dist/prime.js +38 -14
  145. package/dist/prime.js.map +1 -1
  146. package/dist/public/css/react.css +1 -1
  147. package/dist/public/js/react/react.js +53 -61
  148. package/dist/server.d.ts +18 -85
  149. package/dist/server.d.ts.map +1 -1
  150. package/dist/server.js +105 -405
  151. package/dist/server.js.map +1 -1
  152. package/dist/sprint-data.d.ts +1 -1
  153. package/dist/sprint-data.d.ts.map +1 -1
  154. package/dist/sprint-data.js +2 -2
  155. package/dist/sprint-data.js.map +1 -1
  156. package/dist/theme-metadata.d.ts +3 -3
  157. package/dist/theme-metadata.d.ts.map +1 -1
  158. package/dist/theme-metadata.js +4 -4
  159. package/dist/theme-metadata.js.map +1 -1
  160. package/dist/websocket.d.ts +2 -0
  161. package/dist/websocket.d.ts.map +1 -1
  162. package/dist/websocket.js +53 -75
  163. package/dist/websocket.js.map +1 -1
  164. package/package.json +2 -6
  165. package/portraits/hogans-heroes/large/burkhalter-35312.png +0 -0
  166. package/portraits/hogans-heroes/large/carter-34352.png +0 -0
  167. package/portraits/hogans-heroes/large/hochstetter-45314.png +0 -0
  168. package/portraits/hogans-heroes/large/hogan-44541.png +0 -0
  169. package/portraits/hogans-heroes/large/kinch-35241.png +0 -0
  170. package/portraits/hogans-heroes/large/klink-23434.png +0 -0
  171. package/portraits/hogans-heroes/large/lebeau-45443.png +0 -0
  172. package/portraits/hogans-heroes/large/marya-53543.png +0 -0
  173. package/portraits/hogans-heroes/large/newkirk-54432.png +0 -0
  174. package/portraits/hogans-heroes/large/schultz-42453.png +0 -0
  175. package/portraits/hogans-heroes/large/underground-55131.png +0 -0
  176. package/portraits/hogans-heroes/medium/burkhalter-35312.png +0 -0
  177. package/portraits/hogans-heroes/medium/carter-34352.png +0 -0
  178. package/portraits/hogans-heroes/medium/hochstetter-45314.png +0 -0
  179. package/portraits/hogans-heroes/medium/hogan-44541.png +0 -0
  180. package/portraits/hogans-heroes/medium/kinch-35241.png +0 -0
  181. package/portraits/hogans-heroes/medium/klink-23434.png +0 -0
  182. package/portraits/hogans-heroes/medium/lebeau-45443.png +0 -0
  183. package/portraits/hogans-heroes/medium/marya-53543.png +0 -0
  184. package/portraits/hogans-heroes/medium/newkirk-54432.png +0 -0
  185. package/portraits/hogans-heroes/medium/schultz-42453.png +0 -0
  186. package/portraits/hogans-heroes/medium/underground-55131.png +0 -0
  187. package/portraits/monty-python/large/announcer-44441.png +0 -0
  188. package/portraits/monty-python/large/arguer-35412.png +0 -0
  189. package/portraits/monty-python/large/bicycle-repair-man-35241.png +0 -0
  190. package/portraits/monty-python/large/colonel-35423.png +0 -0
  191. package/portraits/monty-python/large/counsellor-45341.png +0 -0
  192. package/portraits/monty-python/large/gumbys-23524.png +0 -0
  193. package/portraits/monty-python/large/nudge-43533.png +0 -0
  194. package/portraits/monty-python/large/praline-45413.png +0 -0
  195. package/portraits/monty-python/large/silly-walks-55322.png +0 -0
  196. package/portraits/monty-python/large/wensleydale-54451.png +0 -0
  197. package/portraits/monty-python/large/xim-nez-43534.png +0 -0
  198. package/portraits/monty-python/medium/announcer-44441.png +0 -0
  199. package/portraits/monty-python/medium/arguer-35412.png +0 -0
  200. package/portraits/monty-python/medium/bicycle-repair-man-35241.png +0 -0
  201. package/portraits/monty-python/medium/colonel-35423.png +0 -0
  202. package/portraits/monty-python/medium/counsellor-45341.png +0 -0
  203. package/portraits/monty-python/medium/gumbys-23524.png +0 -0
  204. package/portraits/monty-python/medium/nudge-43533.png +0 -0
  205. package/portraits/monty-python/medium/praline-45413.png +0 -0
  206. package/portraits/monty-python/medium/silly-walks-55322.png +0 -0
  207. package/portraits/monty-python/medium/wensleydale-54451.png +0 -0
  208. package/portraits/monty-python/medium/xim-nez-43534.png +0 -0
  209. package/portraits/stephen-king/large/andy-55231.png +0 -0
  210. package/portraits/stephen-king/large/christine-25112.png +0 -0
  211. package/portraits/stephen-king/large/danny-53243.png +0 -0
  212. package/portraits/stephen-king/large/flagg-55311.png +0 -0
  213. package/portraits/stephen-king/large/gaunt-54421.png +0 -0
  214. package/portraits/stephen-king/large/jack-44224.png +0 -0
  215. package/portraits/stephen-king/large/johnny-44353.png +0 -0
  216. package/portraits/stephen-king/large/margaret-15415.png +0 -0
  217. package/portraits/stephen-king/large/paul-45233.png +0 -0
  218. package/portraits/stephen-king/large/pennywise-54411.png +0 -0
  219. package/portraits/stephen-king/large/roland-35121.png +0 -0
  220. package/portraits/stephen-king/medium/andy-55231.png +0 -0
  221. package/portraits/stephen-king/medium/christine-25112.png +0 -0
  222. package/portraits/stephen-king/medium/danny-53243.png +0 -0
  223. package/portraits/stephen-king/medium/flagg-55311.png +0 -0
  224. package/portraits/stephen-king/medium/gaunt-54421.png +0 -0
  225. package/portraits/stephen-king/medium/jack-44224.png +0 -0
  226. package/portraits/stephen-king/medium/johnny-44353.png +0 -0
  227. package/portraits/stephen-king/medium/margaret-15415.png +0 -0
  228. package/portraits/stephen-king/medium/paul-45233.png +0 -0
  229. package/portraits/stephen-king/medium/pennywise-54411.png +0 -0
  230. package/portraits/stephen-king/medium/roland-35121.png +0 -0
  231. package/portraits/star-trek-tng/large/beverly-44352.png +0 -0
  232. package/portraits/star-trek-tng/large/data-55241.png +0 -0
  233. package/portraits/star-trek-tng/large/deanna-43353.png +0 -0
  234. package/portraits/star-trek-tng/large/geordi-54342.png +0 -0
  235. package/portraits/star-trek-tng/large/jean-luc-45342.png +0 -0
  236. package/portraits/star-trek-tng/large/kathryn-45332.png +0 -0
  237. package/portraits/star-trek-tng/large/miles-35342.png +0 -0
  238. package/portraits/star-trek-tng/large/q-53521.png +0 -0
  239. package/portraits/star-trek-tng/large/spock-45231.png +0 -0
  240. package/portraits/star-trek-tng/large/troi-44352.png +0 -0
  241. package/portraits/star-trek-tng/medium/beverly-44352.png +0 -0
  242. package/portraits/star-trek-tng/medium/data-55241.png +0 -0
  243. package/portraits/star-trek-tng/medium/deanna-43353.png +0 -0
  244. package/portraits/star-trek-tng/medium/geordi-54342.png +0 -0
  245. package/portraits/star-trek-tng/medium/jean-luc-45342.png +0 -0
  246. package/portraits/star-trek-tng/medium/kathryn-45332.png +0 -0
  247. package/portraits/star-trek-tng/medium/miles-35342.png +0 -0
  248. package/portraits/star-trek-tng/medium/q-53521.png +0 -0
  249. package/portraits/star-trek-tng/medium/spock-45231.png +0 -0
  250. package/portraits/star-trek-tng/medium/troi-44352.png +0 -0
  251. package/src/public/App.tsx +0 -340
  252. package/src/public/components/AgentLoadDialog.tsx +0 -202
  253. package/src/public/components/AgentPopup.tsx +0 -308
  254. package/src/public/components/ApprovalModal/ApprovalModal.css +0 -35
  255. package/src/public/components/ApprovalModal/index.tsx +0 -632
  256. package/src/public/components/BikeRackIndex.tsx +0 -54
  257. package/src/public/components/BikeRackWorkspace.tsx +0 -142
  258. package/src/public/components/CommandPalette.tsx +0 -555
  259. package/src/public/components/ConfirmDialog.tsx +0 -168
  260. package/src/public/components/ContextIndicator/ContextIndicator.css +0 -85
  261. package/src/public/components/ContextIndicator/index.tsx +0 -330
  262. package/src/public/components/ContextSparkline.tsx +0 -56
  263. package/src/public/components/ControlBar.tsx +0 -636
  264. package/src/public/components/DeadCodeDialog.tsx +0 -169
  265. package/src/public/components/DiffViewer.tsx +0 -585
  266. package/src/public/components/DockviewWorkspace.tsx +0 -737
  267. package/src/public/components/Editor.tsx +0 -630
  268. package/src/public/components/ErrorBoundary.tsx +0 -67
  269. package/src/public/components/FileTree.tsx +0 -379
  270. package/src/public/components/FontPicker/FontPicker.css +0 -276
  271. package/src/public/components/FontPicker/index.tsx +0 -430
  272. package/src/public/components/FullFileTree.tsx +0 -237
  273. package/src/public/components/HealthGauge.tsx +0 -181
  274. package/src/public/components/Message.tsx +0 -225
  275. package/src/public/components/MessageList.tsx +0 -98
  276. package/src/public/components/MessageView.tsx +0 -400
  277. package/src/public/components/ModeSwitch/ModeSwitch.css +0 -165
  278. package/src/public/components/ModeSwitch/index.tsx +0 -372
  279. package/src/public/components/PersonaHeader.tsx +0 -240
  280. package/src/public/components/QuickActions.tsx +0 -267
  281. package/src/public/components/SpanTimeline.tsx +0 -352
  282. package/src/public/components/StandalonePanel.tsx +0 -84
  283. package/src/public/components/StatsStrip.tsx +0 -162
  284. package/src/public/components/StreamingContent.tsx +0 -77
  285. package/src/public/components/SubagentSpan.tsx +0 -180
  286. package/src/public/components/TandemPortrait.tsx +0 -72
  287. package/src/public/components/ThemePalette/ThemePalette.css +0 -179
  288. package/src/public/components/ThemePalette/index.tsx +0 -326
  289. package/src/public/components/ToolCallBlock.tsx +0 -252
  290. package/src/public/components/ToolStack.tsx +0 -209
  291. package/src/public/components/ToolStatus.tsx +0 -57
  292. package/src/public/components/dialogs/CodeMarkersDialog.tsx +0 -169
  293. package/src/public/components/dialogs/ComplexityDialog.tsx +0 -163
  294. package/src/public/components/dialogs/DependenciesDialog.tsx +0 -120
  295. package/src/public/components/dialogs/HotspotsDialog.tsx +0 -451
  296. package/src/public/components/dialogs/ToolDialog.tsx +0 -43
  297. package/src/public/components/panel-registry.ts +0 -11
  298. package/src/public/components/panels/ACPanel.tsx +0 -93
  299. package/src/public/components/panels/AcceptanceCriteriaPanel.tsx +0 -104
  300. package/src/public/components/panels/AuditLogPanel.tsx +0 -465
  301. package/src/public/components/panels/BackgroundPanel.tsx +0 -115
  302. package/src/public/components/panels/BikeLanePanel.tsx +0 -214
  303. package/src/public/components/panels/ChangedPanel.tsx +0 -65
  304. package/src/public/components/panels/DebugPanel.tsx +0 -344
  305. package/src/public/components/panels/DiffsPanel.tsx +0 -155
  306. package/src/public/components/panels/GitPanel.tsx +0 -216
  307. package/src/public/components/panels/HotspotsPanel.tsx +0 -365
  308. package/src/public/components/panels/MessagePanel.tsx +0 -497
  309. package/src/public/components/panels/SettingsPanel.tsx +0 -453
  310. package/src/public/components/panels/SprintPanel.tsx +0 -670
  311. package/src/public/components/panels/TTYPanel.tsx +0 -299
  312. package/src/public/components/panels/TodoPanel.tsx +0 -142
  313. package/src/public/components/panels/WorkflowPanel.tsx +0 -224
  314. package/src/public/components/panels/index.ts +0 -24
  315. package/src/public/components/ui/alert-dialog.tsx +0 -139
  316. package/src/public/components/ui/badge.tsx +0 -36
  317. package/src/public/components/ui/button.tsx +0 -57
  318. package/src/public/components/ui/checkbox.tsx +0 -28
  319. package/src/public/components/ui/collapsible.tsx +0 -9
  320. package/src/public/components/ui/command.tsx +0 -151
  321. package/src/public/components/ui/dialog.tsx +0 -120
  322. package/src/public/components/ui/popover.tsx +0 -31
  323. package/src/public/components/ui/progress.tsx +0 -28
  324. package/src/public/components/ui/scroll-area.tsx +0 -46
  325. package/src/public/components/ui/select.tsx +0 -157
  326. package/src/public/components/ui/separator.tsx +0 -29
  327. package/src/public/components/ui/skeleton.tsx +0 -15
  328. package/src/public/components/ui/switch.tsx +0 -27
  329. package/src/public/components/ui/toggle-group.tsx +0 -59
  330. package/src/public/components/ui/toggle.tsx +0 -43
  331. package/src/public/components/ui/tooltip.tsx +0 -30
  332. package/src/public/contexts/ClaudeContext.tsx +0 -311
  333. package/src/public/contexts/MessageQueueContext.tsx +0 -143
  334. package/src/public/css/theme-browser.css +0 -550
  335. package/src/public/css/theme-system.css +0 -630
  336. package/src/public/hooks/index.ts +0 -49
  337. package/src/public/hooks/useAgentLoad.ts +0 -105
  338. package/src/public/hooks/useBackgroundTasks.ts +0 -131
  339. package/src/public/hooks/useClaude.ts +0 -234
  340. package/src/public/hooks/useCodeMarkers.ts +0 -101
  341. package/src/public/hooks/useColorScheme.ts +0 -42
  342. package/src/public/hooks/useCommandHistory.ts +0 -99
  343. package/src/public/hooks/useComplexity.ts +0 -80
  344. package/src/public/hooks/useDeadCode.ts +0 -99
  345. package/src/public/hooks/useDependencies.ts +0 -82
  346. package/src/public/hooks/useDiffs.ts +0 -143
  347. package/src/public/hooks/useFileBrowser.ts +0 -71
  348. package/src/public/hooks/useGitStatus.ts +0 -233
  349. package/src/public/hooks/useHealthScore.ts +0 -69
  350. package/src/public/hooks/useHotspots.ts +0 -123
  351. package/src/public/hooks/useLayoutPersistence.ts +0 -138
  352. package/src/public/hooks/useMarkdownParser.ts +0 -36
  353. package/src/public/hooks/useMarkerActions.ts +0 -234
  354. package/src/public/hooks/useMessageQueue.ts +0 -380
  355. package/src/public/hooks/useMessageStream.ts +0 -131
  356. package/src/public/hooks/usePersona.ts +0 -112
  357. package/src/public/hooks/usePlanModeExit.ts +0 -105
  358. package/src/public/hooks/useResponsiveLayout.ts +0 -173
  359. package/src/public/hooks/useSprint.ts +0 -147
  360. package/src/public/hooks/useStatsStrip.ts +0 -204
  361. package/src/public/hooks/useStory.ts +0 -135
  362. package/src/public/hooks/useSubagentHelper.ts +0 -64
  363. package/src/public/hooks/useSyntaxHighlighter.ts +0 -52
  364. package/src/public/hooks/useTabCompletion.ts +0 -124
  365. package/src/public/hooks/useTodos.ts +0 -93
  366. package/src/public/hooks/useUserAvatar.ts +0 -54
  367. package/src/public/index.tsx +0 -10
  368. package/src/public/lib/utils.ts +0 -6
  369. package/src/public/styles/dockview-theme.css +0 -459
  370. package/src/public/styles/tailwind.css +0 -4396
  371. package/src/public/types/electron.d.ts +0 -18
  372. package/src/public/types/message.ts +0 -51
  373. package/src/public/utils/avatar-service.ts +0 -73
  374. package/src/public/utils/color-presets.ts +0 -940
  375. package/src/public/utils/font-presets.ts +0 -362
  376. package/src/public/utils/formatDuration.ts +0 -14
  377. package/src/public/utils/markdown.ts +0 -249
  378. package/src/public/utils/messageFilters.ts +0 -128
  379. package/src/public/utils/slash-commands.ts +0 -353
  380. package/src/public/utils/subagent-display.ts +0 -146
  381. package/src/public/utils/syntax.ts +0 -219
  382. package/src/public/utils/toolIntentSummarizer.ts +0 -199
  383. package/src/public/utils/toolStackGrouper.ts +0 -106
  384. package/src/public/utils/toolTypeColors.ts +0 -45
@@ -1,737 +0,0 @@
1
- /**
2
- * DockviewWorkspace - Dockview-based panel management for Cyclist
3
- *
4
- * Story MSSCI-14001: Replace DockingWorkspace with Dockview
5
- * Epic: epic-76 (Dockview Panel Migration)
6
- *
7
- * Features:
8
- * - Three-region layout (left sidebar, center sacred, right sidebar)
9
- * - Message view is sacred (fixed center, cannot be closed or moved)
10
- * - Tabbed panels in sidebars with drag-and-drop
11
- * - Responsive breakpoints (auto-collapse at <1024px)
12
- * - Layout persistence via native Dockview toJSON/fromJSON
13
- * - Theme integration via CSS custom properties
14
- */
15
-
16
- import React, { useEffect, useRef, useCallback, useState, ComponentType } from 'react';
17
- import { Button } from '@/components/ui/button';
18
- import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
19
- import {
20
- DockviewReact,
21
- DockviewReadyEvent,
22
- IDockviewPanelProps,
23
- DockviewApi,
24
- IDockviewPanel,
25
- SerializedDockview,
26
- } from 'dockview-react';
27
- import 'dockview-react/dist/styles/dockview.css';
28
- import { ErrorBoundary } from './ErrorBoundary';
29
- import { panelRegistry } from './panel-registry';
30
- import { useResponsiveLayout, MIN_DIMENSIONS, SIDEBAR_WIDTHS } from '../hooks/useResponsiveLayout';
31
- import '../styles/dockview-theme.css';
32
-
33
- // =============================================================================
34
- // Panel Inventory - All available panels in Cyclist
35
- // =============================================================================
36
-
37
- export const PANEL_INVENTORY = {
38
- // Left sidebar panels
39
- CHANGED: 'changed',
40
- DIFFS: 'diffs',
41
- DEBUG: 'debug',
42
- AUDIT_LOG: 'audit-log',
43
- TTY: 'tty',
44
- // Center panel (sacred)
45
- MESSAGE: 'message',
46
- // Right sidebar panels
47
- SPRINT: 'sprint',
48
- WORKFLOW: 'workflow',
49
- AC: 'ac',
50
- TODO: 'todo',
51
- BACKGROUND: 'background',
52
- GIT: 'git',
53
- SETTINGS: 'settings',
54
- } as const;
55
-
56
- export type PanelId = typeof PANEL_INVENTORY[keyof typeof PANEL_INVENTORY];
57
-
58
- // =============================================================================
59
- // Panel Component Registry
60
- // =============================================================================
61
-
62
- /**
63
- * Register a panel component by ID
64
- */
65
- export function registerPanelComponent(id: string, component: ComponentType): void {
66
- panelRegistry.set(id, component);
67
- }
68
-
69
- // =============================================================================
70
- // Global API Reference
71
- // =============================================================================
72
-
73
- let dockviewApiRef: DockviewApi | null = null;
74
-
75
- /**
76
- * Get the Dockview API instance for external access
77
- */
78
- export function getDockviewApi(): DockviewApi | null {
79
- return dockviewApiRef;
80
- }
81
-
82
- // Panel group definitions (needed for restore logic)
83
- // Exported so layout persistence can merge missing panels
84
- export const LEFT_SIDEBAR_PANELS = [PANEL_INVENTORY.CHANGED, PANEL_INVENTORY.DIFFS, PANEL_INVENTORY.DEBUG, PANEL_INVENTORY.AUDIT_LOG, PANEL_INVENTORY.TTY] as const;
85
- export const RIGHT_SIDEBAR_PANELS = [
86
- PANEL_INVENTORY.SPRINT,
87
- PANEL_INVENTORY.WORKFLOW,
88
- PANEL_INVENTORY.AC,
89
- PANEL_INVENTORY.TODO,
90
- PANEL_INVENTORY.BACKGROUND,
91
- PANEL_INVENTORY.GIT,
92
- PANEL_INVENTORY.SETTINGS,
93
- ] as const;
94
-
95
- // Title Case display names for tab headers (AC4: Story 75-5)
96
- const PANEL_TITLES: Record<string, string> = {
97
- changed: 'Changed',
98
- diffs: 'Diffs',
99
- debug: 'Debug',
100
- 'audit-log': 'Audit Log',
101
- tty: 'Terminal',
102
- message: 'Message',
103
- sprint: 'Sprint',
104
- workflow: 'Workflow',
105
- ac: 'AC',
106
- todo: 'Todo',
107
- background: 'Subagents',
108
- git: 'Git',
109
- settings: 'Settings',
110
- };
111
-
112
- // Track closed panels for restoration
113
- const closedPanels: Set<string> = new Set();
114
-
115
- /**
116
- * Get list of closed panels that can be restored
117
- */
118
- export function getClosedPanels(): string[] {
119
- return Array.from(closedPanels);
120
- }
121
-
122
- /**
123
- * Restore a previously closed panel
124
- */
125
- export function restorePanel(panelId: string): boolean {
126
- const api = dockviewApiRef;
127
- if (!api) return false;
128
-
129
- // If panel already exists in Dockview, nothing to restore
130
- if (api.getPanel(panelId)) return false;
131
-
132
- // Determine which group to add it to
133
- const isLeftPanel = LEFT_SIDEBAR_PANELS.includes(panelId as any);
134
- const isRightPanel = RIGHT_SIDEBAR_PANELS.includes(panelId as any);
135
-
136
- // Find a reference panel in the appropriate group
137
- let referencePanel: IDockviewPanel | undefined;
138
-
139
- if (isLeftPanel) {
140
- for (const id of LEFT_SIDEBAR_PANELS) {
141
- const panel = api.getPanel(id);
142
- if (panel) {
143
- referencePanel = panel;
144
- break;
145
- }
146
- }
147
- } else if (isRightPanel) {
148
- for (const id of RIGHT_SIDEBAR_PANELS) {
149
- const panel = api.getPanel(id);
150
- if (panel) {
151
- referencePanel = panel;
152
- break;
153
- }
154
- }
155
- }
156
-
157
- // Add the panel back
158
- api.addPanel({
159
- id: panelId,
160
- component: 'PanelAdapter',
161
- params: { panelId },
162
- position: referencePanel ? { referencePanel: referencePanel.id } : undefined,
163
- title: PANEL_TITLES[panelId] || panelId,
164
- });
165
-
166
- closedPanels.delete(panelId);
167
- return true;
168
- }
169
-
170
- // =============================================================================
171
- // Panel Adapter - Wraps existing panels for Dockview
172
- // =============================================================================
173
-
174
- interface PanelAdapterParams {
175
- panelId: string;
176
- }
177
-
178
- export function PanelAdapter({ params }: IDockviewPanelProps<PanelAdapterParams>): React.ReactElement | null {
179
- const Component = panelRegistry.get(params.panelId);
180
-
181
- if (!Component) {
182
- console.warn(`[DockviewWorkspace] No component registered for panel: ${params.panelId}`);
183
- return null;
184
- }
185
-
186
- return (
187
- <div data-testid={`panel-${params.panelId}`} className="dockview-panel-content">
188
- <ErrorBoundary panelName={params.panelId}>
189
- <div className="error-boundary-wrapper">
190
- <Component />
191
- </div>
192
- </ErrorBoundary>
193
- </div>
194
- );
195
- }
196
-
197
- // =============================================================================
198
- // Types for Layout Persistence
199
- // =============================================================================
200
-
201
- // Re-export SerializedDockview for external use
202
- export type { SerializedDockview };
203
-
204
- /**
205
- * @deprecated Use SerializedDockview from dockview-react instead
206
- * Kept for backward compatibility during migration
207
- */
208
- export interface WorkspaceLayoutConfig {
209
- leftSidebar: {
210
- panels: string[];
211
- width: number;
212
- collapsed: boolean;
213
- activePanel?: string;
214
- };
215
- center: {
216
- panels: string[];
217
- locked: boolean;
218
- };
219
- rightSidebar: {
220
- panels: string[];
221
- width: number;
222
- collapsed: boolean;
223
- activePanel?: string;
224
- };
225
- }
226
-
227
- /**
228
- * Create default workspace layout using native Dockview format
229
- * This builds the initial three-region layout programmatically
230
- */
231
- export function createDefaultDockviewLayout(): SerializedDockview {
232
- // Build the default layout structure that matches what toJSON() produces
233
- // This creates: [left sidebar] | [center message] | [right sidebar]
234
- return {
235
- grid: {
236
- root: {
237
- type: 'branch',
238
- data: [
239
- // Left sidebar group
240
- {
241
- type: 'leaf',
242
- data: {
243
- views: LEFT_SIDEBAR_PANELS.map(id => id),
244
- activeView: LEFT_SIDEBAR_PANELS[0],
245
- id: 'left-sidebar',
246
- },
247
- size: SIDEBAR_WIDTHS.medium,
248
- },
249
- // Center (message) group
250
- {
251
- type: 'leaf',
252
- data: {
253
- views: [PANEL_INVENTORY.MESSAGE],
254
- activeView: PANEL_INVENTORY.MESSAGE,
255
- id: 'center',
256
- hideHeader: true,
257
- },
258
- size: 600, // Center takes remaining space
259
- },
260
- // Right sidebar group
261
- {
262
- type: 'leaf',
263
- data: {
264
- views: [...RIGHT_SIDEBAR_PANELS],
265
- activeView: RIGHT_SIDEBAR_PANELS[0],
266
- id: 'right-sidebar',
267
- },
268
- size: SIDEBAR_WIDTHS.medium,
269
- },
270
- ],
271
- size: 800, // Will be overridden by actual container height
272
- },
273
- width: 1200,
274
- height: 800,
275
- orientation: 'HORIZONTAL',
276
- },
277
- panels: {
278
- // Left sidebar panels
279
- ...Object.fromEntries(LEFT_SIDEBAR_PANELS.map(id => [id, {
280
- id,
281
- contentComponent: 'PanelAdapter',
282
- title: PANEL_TITLES[id] || id,
283
- params: { panelId: id },
284
- }])),
285
- // Center panel
286
- [PANEL_INVENTORY.MESSAGE]: {
287
- id: PANEL_INVENTORY.MESSAGE,
288
- contentComponent: 'PanelAdapter',
289
- title: PANEL_TITLES[PANEL_INVENTORY.MESSAGE],
290
- params: { panelId: PANEL_INVENTORY.MESSAGE },
291
- },
292
- // Right sidebar panels
293
- ...Object.fromEntries(RIGHT_SIDEBAR_PANELS.map(id => [id, {
294
- id,
295
- contentComponent: 'PanelAdapter',
296
- title: PANEL_TITLES[id] || id,
297
- params: { panelId: id },
298
- }])),
299
- },
300
- activeGroup: 'center',
301
- };
302
- }
303
-
304
- /**
305
- * @deprecated Use createDefaultDockviewLayout instead
306
- * Kept for backward compatibility
307
- */
308
- export function createWorkspaceLayout(): WorkspaceLayoutConfig {
309
- return {
310
- leftSidebar: {
311
- panels: [...LEFT_SIDEBAR_PANELS],
312
- width: SIDEBAR_WIDTHS.medium,
313
- collapsed: false,
314
- },
315
- center: {
316
- panels: [PANEL_INVENTORY.MESSAGE],
317
- locked: true,
318
- },
319
- rightSidebar: {
320
- panels: [...RIGHT_SIDEBAR_PANELS],
321
- width: SIDEBAR_WIDTHS.medium,
322
- collapsed: false,
323
- },
324
- };
325
- }
326
-
327
- // =============================================================================
328
- // Layout Migration (MSSCI-14188)
329
- // =============================================================================
330
-
331
- interface SimplifiedLayoutPanel {
332
- id: string;
333
- position?: string;
334
- }
335
-
336
- interface SimplifiedLayout {
337
- panels: SimplifiedLayoutPanel[];
338
- }
339
-
340
- /**
341
- * Migrate old layout format that had "progress" panel to new format with
342
- * separate workflow, ac, and todo panels.
343
- *
344
- * Story: MSSCI-14188 - Split Progress panel into Workflow, AC, and Todo panels
345
- */
346
- export function migrateLayout(layout: SimplifiedLayout | null | undefined): SimplifiedLayout {
347
- // Handle null/undefined gracefully
348
- if (!layout || !layout.panels) {
349
- return { panels: [] };
350
- }
351
-
352
- // Check if layout already has new panels (no migration needed)
353
- const hasNewPanels = layout.panels.some(
354
- (p) => p.id === 'workflow' || p.id === 'ac' || p.id === 'todo'
355
- );
356
- if (hasNewPanels) {
357
- // Already migrated, just filter out any stale 'progress' panel
358
- return {
359
- panels: layout.panels.filter((p) => p.id !== 'progress'),
360
- };
361
- }
362
-
363
- // Check if layout has old 'progress' panel that needs migration
364
- const progressIndex = layout.panels.findIndex((p) => p.id === 'progress');
365
- if (progressIndex === -1) {
366
- // No progress panel to migrate
367
- return layout;
368
- }
369
-
370
- // Get the position of the old progress panel
371
- const progressPanel = layout.panels[progressIndex];
372
- const position = progressPanel.position || 'right';
373
-
374
- // Build new panels array with progress replaced by workflow, ac, todo
375
- const newPanels: SimplifiedLayoutPanel[] = [];
376
-
377
- for (let i = 0; i < layout.panels.length; i++) {
378
- if (i === progressIndex) {
379
- // Replace progress with three new panels at the same position
380
- newPanels.push({ id: 'workflow', position });
381
- newPanels.push({ id: 'ac', position });
382
- newPanels.push({ id: 'todo', position });
383
- } else {
384
- newPanels.push(layout.panels[i]);
385
- }
386
- }
387
-
388
- return { panels: newPanels };
389
- }
390
-
391
- // =============================================================================
392
- // DockviewWorkspace Component
393
- // =============================================================================
394
-
395
- export interface DockviewWorkspaceProps {
396
- /** Native Dockview serialized layout (preferred) */
397
- initialLayout?: SerializedDockview;
398
- /** Callback when layout changes - receives native Dockview format */
399
- onLayoutChange?: (layout: SerializedDockview) => void;
400
- }
401
-
402
- export function DockviewWorkspace({
403
- initialLayout,
404
- onLayoutChange,
405
- }: DockviewWorkspaceProps): React.ReactElement {
406
- const apiRef = useRef<DockviewApi | null>(null);
407
- const { isSmall, isBelowMinimum, sidebarWidth } = useResponsiveLayout();
408
- const [isReady, setIsReady] = useState(false);
409
- const [closedPanelsList, setClosedPanelsList] = useState<string[]>([]);
410
- const [showRestoreMenu, setShowRestoreMenu] = useState(false);
411
- const saveTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
412
- // Track if responsive effect should apply - skip on initial load to respect saved collapsed state
413
- const hasAppliedInitialLayout = useRef(false);
414
- const previousIsSmall = useRef<boolean | null>(null);
415
-
416
- // Update closed panels list when panels change
417
- const updateClosedPanelsList = useCallback(() => {
418
- setClosedPanelsList(Array.from(closedPanels));
419
- }, []);
420
-
421
- // Handle Dockview ready event
422
- const onReady = useCallback((event: DockviewReadyEvent) => {
423
- const api = event.api;
424
- apiRef.current = api;
425
- dockviewApiRef = api;
426
-
427
- // Use native fromJSON if we have a saved layout, otherwise build default
428
- if (initialLayout && initialLayout.grid && initialLayout.panels) {
429
- // Restore from native Dockview serialized format
430
- try {
431
- api.fromJSON(initialLayout);
432
-
433
- // After restoring, lock the message panel's group and hide its tab bar
434
- const messagePanel = api.getPanel(PANEL_INVENTORY.MESSAGE);
435
- if (messagePanel?.group) {
436
- messagePanel.group.locked = 'no-drop-target';
437
- messagePanel.group.model.header.hidden = true;
438
- }
439
-
440
- setIsReady(true);
441
- return;
442
- } catch (err) {
443
- console.warn('[DockviewWorkspace] Failed to restore layout from JSON, building default:', err);
444
- // Fall through to build default layout
445
- }
446
- }
447
-
448
- // Build default layout programmatically (for first-time users or failed restore)
449
- // Add first panel to left sidebar (creates the first group)
450
- const leftFirstPanel = api.addPanel({
451
- id: LEFT_SIDEBAR_PANELS[0],
452
- component: 'PanelAdapter',
453
- params: { panelId: LEFT_SIDEBAR_PANELS[0] },
454
- title: PANEL_TITLES[LEFT_SIDEBAR_PANELS[0]],
455
- });
456
-
457
- // Add remaining left sidebar panels to the same group
458
- for (let i = 1; i < LEFT_SIDEBAR_PANELS.length; i++) {
459
- const panelId = LEFT_SIDEBAR_PANELS[i];
460
- if (panelRegistry.has(panelId)) {
461
- api.addPanel({
462
- id: panelId,
463
- component: 'PanelAdapter',
464
- params: { panelId },
465
- position: { referencePanel: leftFirstPanel.id },
466
- title: PANEL_TITLES[panelId],
467
- });
468
- }
469
- }
470
-
471
- // Add message panel to center (creates new group to the right)
472
- const messagePanel = api.addPanel({
473
- id: PANEL_INVENTORY.MESSAGE,
474
- component: 'PanelAdapter',
475
- params: { panelId: PANEL_INVENTORY.MESSAGE },
476
- position: { referencePanel: leftFirstPanel.id, direction: 'right' },
477
- title: PANEL_TITLES[PANEL_INVENTORY.MESSAGE],
478
- });
479
-
480
- // Add first right sidebar panel (creates new group to the right of center)
481
- const rightFirstPanel = api.addPanel({
482
- id: RIGHT_SIDEBAR_PANELS[0],
483
- component: 'PanelAdapter',
484
- params: { panelId: RIGHT_SIDEBAR_PANELS[0] },
485
- position: { referencePanel: messagePanel.id, direction: 'right' },
486
- title: PANEL_TITLES[RIGHT_SIDEBAR_PANELS[0]],
487
- });
488
-
489
- // Add remaining right sidebar panels to the same group
490
- for (let i = 1; i < RIGHT_SIDEBAR_PANELS.length; i++) {
491
- const panelId = RIGHT_SIDEBAR_PANELS[i];
492
- if (panelRegistry.has(panelId)) {
493
- api.addPanel({
494
- id: panelId,
495
- component: 'PanelAdapter',
496
- params: { panelId },
497
- position: { referencePanel: rightFirstPanel.id },
498
- title: PANEL_TITLES[panelId],
499
- });
500
- }
501
- }
502
-
503
- // Lock the center group - MessagePanel cannot be closed or moved
504
- // Hide the tab bar so users can't accidentally close the message tab
505
- if (messagePanel?.group) {
506
- messagePanel.group.locked = 'no-drop-target';
507
- messagePanel.group.model.header.hidden = true;
508
- }
509
-
510
- // Set initial sidebar sizes
511
- const leftGroup = leftFirstPanel.group;
512
- const rightGroup = rightFirstPanel.group;
513
-
514
- if (leftGroup) {
515
- leftGroup.api.setSize({ width: SIDEBAR_WIDTHS.medium });
516
- }
517
- if (rightGroup) {
518
- rightGroup.api.setSize({ width: SIDEBAR_WIDTHS.medium });
519
- }
520
-
521
- setIsReady(true);
522
- }, [initialLayout]);
523
-
524
- // Handle layout changes for persistence using native toJSON
525
- const handleLayoutChange = useCallback(() => {
526
- const api = apiRef.current;
527
- if (!api || !onLayoutChange) return;
528
-
529
- // Debounce saves
530
- if (saveTimeoutRef.current) {
531
- clearTimeout(saveTimeoutRef.current);
532
- }
533
-
534
- saveTimeoutRef.current = setTimeout(() => {
535
- // Use native Dockview toJSON for complete layout serialization
536
- const serializedLayout = api.toJSON();
537
- onLayoutChange(serializedLayout);
538
- }, 300);
539
- }, [onLayoutChange]);
540
-
541
- // Subscribe to layout changes and track closed panels
542
- useEffect(() => {
543
- const api = apiRef.current;
544
- if (!api || !isReady) return;
545
-
546
- const disposables = [
547
- api.onDidLayoutChange(() => handleLayoutChange()),
548
- api.onDidAddPanel((e) => {
549
- // Panel restored, remove from closed set
550
- const panelId = e?.panel?.id;
551
- if (panelId) {
552
- closedPanels.delete(panelId);
553
- }
554
- updateClosedPanelsList();
555
- handleLayoutChange();
556
- }),
557
- api.onDidRemovePanel((e) => {
558
- // Track closed panels for restoration
559
- const panelId = e?.panel?.id;
560
- if (panelId) {
561
- closedPanels.add(panelId);
562
- updateClosedPanelsList();
563
- }
564
- handleLayoutChange();
565
- }),
566
- ];
567
-
568
- return () => {
569
- disposables.forEach(d => d.dispose());
570
- };
571
- }, [isReady, handleLayoutChange]);
572
-
573
- // Handle responsive breakpoints - only on viewport changes, not initial load
574
- useEffect(() => {
575
- const api = apiRef.current;
576
- if (!api || !isReady) return;
577
-
578
- // On first run after layout is ready, just record current state without changing anything
579
- // This preserves the saved collapsed state from initialLayout
580
- if (!hasAppliedInitialLayout.current) {
581
- hasAppliedInitialLayout.current = true;
582
- previousIsSmall.current = isSmall;
583
- return;
584
- }
585
-
586
- // Only apply responsive changes when isSmall actually changes
587
- if (previousIsSmall.current === isSmall) {
588
- return;
589
- }
590
- previousIsSmall.current = isSmall;
591
-
592
- // Find groups by their panels (groups don't have fixed names)
593
- const changedPanel = api.getPanel(PANEL_INVENTORY.CHANGED);
594
- const sprintPanel = api.getPanel(PANEL_INVENTORY.SPRINT);
595
- const leftGroup = changedPanel?.group;
596
- const rightGroup = sprintPanel?.group;
597
-
598
- if (isSmall) {
599
- // Collapse sidebars at small viewport
600
- leftGroup?.api.setSize({ width: 0 });
601
- rightGroup?.api.setSize({ width: 0 });
602
- } else {
603
- // Restore sidebars to configured width when viewport expands
604
- leftGroup?.api.setSize({ width: sidebarWidth });
605
- rightGroup?.api.setSize({ width: sidebarWidth });
606
- }
607
- }, [isSmall, sidebarWidth, isReady]);
608
-
609
- // Handle restoring a closed panel
610
- const handleRestorePanel = useCallback((panelId: string) => {
611
- restorePanel(panelId);
612
- setShowRestoreMenu(false);
613
- }, []);
614
-
615
- // Cleanup on unmount
616
- useEffect(() => {
617
- return () => {
618
- if (saveTimeoutRef.current) {
619
- clearTimeout(saveTimeoutRef.current);
620
- }
621
- dockviewApiRef = null;
622
- };
623
- }, []);
624
-
625
- // Listen for panel toggle commands via WebSocket (View menu integration)
626
- useEffect(() => {
627
- const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
628
- const ws = new WebSocket(`${protocol}//${window.location.host}/ws/settings`);
629
-
630
- ws.onmessage = (event) => {
631
- try {
632
- const data = JSON.parse(event.data);
633
- if (data.type === 'panel:toggle' && data.panelId) {
634
- const api = dockviewApiRef;
635
- if (!api) return;
636
- const existing = api.getPanel(data.panelId);
637
- if (existing) {
638
- existing.api.close();
639
- } else {
640
- restorePanel(data.panelId);
641
- }
642
- }
643
- } catch {
644
- // ignore parse errors
645
- }
646
- };
647
-
648
- return () => ws.close();
649
- }, []);
650
-
651
- // Component map for Dockview
652
- const components = {
653
- PanelAdapter,
654
- };
655
-
656
- // Panel display names for the restore menu
657
- const panelDisplayNames: Record<string, string> = {
658
- changed: 'Changed Files',
659
- diffs: 'Diffs',
660
- debug: 'Debug',
661
- 'audit-log': 'Audit Log',
662
- tty: 'Terminal',
663
- sprint: 'Sprint',
664
- workflow: 'Workflow',
665
- ac: 'AC',
666
- todo: 'Todo',
667
- background: 'Subagents',
668
- git: 'Git',
669
- hotspots: 'Hotspots',
670
- settings: 'Settings',
671
- };
672
-
673
- return (
674
- <div className="cyclist-dockview" data-dockview-group="container">
675
- {/* Minimum dimension warning */}
676
- {isBelowMinimum && (
677
- <div
678
- data-testid="min-dimension-warning"
679
- className="min-dimension-warning"
680
- role="alert"
681
- >
682
- Window is below minimum size ({MIN_DIMENSIONS.width}x{MIN_DIMENSIONS.height})
683
- </div>
684
- )}
685
-
686
- {/* Panel restore button - shown when panels are closed */}
687
- {closedPanelsList.length > 0 && (
688
- <div className="panel-restore-container">
689
- <TooltipProvider delayDuration={300}>
690
- <Tooltip>
691
- <TooltipTrigger asChild>
692
- <Button
693
- variant="outline"
694
- size="sm"
695
- className="panel-restore-button"
696
- onClick={() => setShowRestoreMenu(!showRestoreMenu)}
697
- aria-expanded={showRestoreMenu}
698
- aria-haspopup="menu"
699
- >
700
- <span className="panel-restore-icon">+</span>
701
- <span className="panel-restore-count">{closedPanelsList.length}</span>
702
- </Button>
703
- </TooltipTrigger>
704
- <TooltipContent>Restore closed panels</TooltipContent>
705
- </Tooltip>
706
- </TooltipProvider>
707
-
708
- {showRestoreMenu && (
709
- <div className="panel-restore-menu" role="menu">
710
- <div className="panel-restore-header">Restore Panel</div>
711
- {closedPanelsList.map((panelId) => (
712
- <Button
713
- variant="ghost"
714
- key={panelId}
715
- className="panel-restore-item"
716
- onClick={() => handleRestorePanel(panelId)}
717
- role="menuitem"
718
- >
719
- {panelDisplayNames[panelId] || panelId}
720
- </Button>
721
- ))}
722
- </div>
723
- )}
724
- </div>
725
- )}
726
-
727
- <DockviewReact
728
- className="dockview-container"
729
- onReady={onReady}
730
- components={components}
731
- watermarkComponent={() => null}
732
- />
733
- </div>
734
- );
735
- }
736
-
737
- export default DockviewWorkspace;