@polderlabs/bizar 7.0.2 → 8.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 (490) hide show
  1. package/.claude/settings.local.json +8 -0
  2. package/bizar-dash/DESIGN.md +729 -969
  3. package/bizar-dash/GLYPH.md +418 -0
  4. package/bizar-dash/PLAN.md +1135 -0
  5. package/bizar-dash/dist/assets/ActivityFeed-BRBtQOHB.js +6 -0
  6. package/bizar-dash/dist/assets/ActivityFeed-BRBtQOHB.js.map +1 -0
  7. package/bizar-dash/dist/assets/ActivityView-CwqhxBfh.js +1 -0
  8. package/bizar-dash/dist/assets/ActivityView-CwqhxBfh.js.map +1 -0
  9. package/bizar-dash/dist/assets/AgentActivity-6MxU-a9F.js +1 -0
  10. package/bizar-dash/dist/assets/AgentActivity-6MxU-a9F.js.map +1 -0
  11. package/bizar-dash/dist/assets/AgentsView-BYrOFdwl.js +8 -0
  12. package/bizar-dash/dist/assets/AgentsView-BYrOFdwl.js.map +1 -0
  13. package/bizar-dash/dist/assets/Badge-Cd61wsBa.js +1 -0
  14. package/bizar-dash/dist/assets/Badge-Cd61wsBa.js.map +1 -0
  15. package/bizar-dash/dist/assets/Card-C_bvqXdQ.js +1 -0
  16. package/bizar-dash/dist/assets/Card-C_bvqXdQ.js.map +1 -0
  17. package/bizar-dash/dist/assets/EmptyState-BWQuKnk9.js +1 -0
  18. package/bizar-dash/dist/assets/EmptyState-BWQuKnk9.js.map +1 -0
  19. package/bizar-dash/dist/assets/GoalsView-Dok0yt9S.js +11 -0
  20. package/bizar-dash/dist/assets/GoalsView-Dok0yt9S.js.map +1 -0
  21. package/bizar-dash/dist/assets/Grid-C62gCPqt.js +1 -0
  22. package/bizar-dash/dist/assets/Grid-C62gCPqt.js.map +1 -0
  23. package/bizar-dash/dist/assets/KanbanCard-CtTKP6ZX.js +21 -0
  24. package/bizar-dash/dist/assets/KanbanCard-CtTKP6ZX.js.map +1 -0
  25. package/bizar-dash/dist/assets/LibrariesView-BcyBQXiY.js +67 -0
  26. package/bizar-dash/dist/assets/LibrariesView-BcyBQXiY.js.map +1 -0
  27. package/bizar-dash/dist/assets/MemoryView-49wR4u-y.js +13 -0
  28. package/bizar-dash/dist/assets/MemoryView-49wR4u-y.js.map +1 -0
  29. package/bizar-dash/dist/assets/OverviewView-BtQ_UWYj.js +1 -0
  30. package/bizar-dash/dist/assets/OverviewView-BtQ_UWYj.js.map +1 -0
  31. package/bizar-dash/dist/assets/ProgressBar-CpvDeq9F.js +1 -0
  32. package/bizar-dash/dist/assets/ProgressBar-CpvDeq9F.js.map +1 -0
  33. package/bizar-dash/dist/assets/SettingsRow-DmIe5OUu.js +30 -0
  34. package/bizar-dash/dist/assets/SettingsRow-DmIe5OUu.js.map +1 -0
  35. package/bizar-dash/dist/assets/SettingsView-D1KmGWbi.js +48 -0
  36. package/bizar-dash/dist/assets/SettingsView-D1KmGWbi.js.map +1 -0
  37. package/bizar-dash/dist/assets/StatTile-BkIP32gG.js +11 -0
  38. package/bizar-dash/dist/assets/StatTile-BkIP32gG.js.map +1 -0
  39. package/bizar-dash/dist/assets/TasksView-Cba3GJ42.js +1 -0
  40. package/bizar-dash/dist/assets/TasksView-Cba3GJ42.js.map +1 -0
  41. package/bizar-dash/dist/assets/ViewHeader-D6c2cw1b.js +6 -0
  42. package/bizar-dash/dist/assets/ViewHeader-D6c2cw1b.js.map +1 -0
  43. package/bizar-dash/dist/assets/brain-DeoXNDE2.js +6 -0
  44. package/bizar-dash/dist/assets/brain-DeoXNDE2.js.map +1 -0
  45. package/bizar-dash/dist/assets/calendar-DRlQkGJc.js +6 -0
  46. package/bizar-dash/dist/assets/calendar-DRlQkGJc.js.map +1 -0
  47. package/bizar-dash/dist/assets/circle-check-DmYQ3vGp.js +6 -0
  48. package/bizar-dash/dist/assets/circle-check-DmYQ3vGp.js.map +1 -0
  49. package/bizar-dash/dist/assets/cmdk-BwN8hcKQ.js +80 -0
  50. package/bizar-dash/dist/assets/cmdk-BwN8hcKQ.js.map +1 -0
  51. package/bizar-dash/dist/assets/dnd-kit-DR2Qzzxk.js +5 -0
  52. package/bizar-dash/dist/assets/dnd-kit-DR2Qzzxk.js.map +1 -0
  53. package/bizar-dash/dist/assets/git-merge-OoqBKQer.js +6 -0
  54. package/bizar-dash/dist/assets/git-merge-OoqBKQer.js.map +1 -0
  55. package/bizar-dash/dist/assets/git-pull-request-CXBQTR2f.js +6 -0
  56. package/bizar-dash/dist/assets/git-pull-request-CXBQTR2f.js.map +1 -0
  57. package/bizar-dash/dist/assets/main-COdgjqbZ.css +1 -0
  58. package/bizar-dash/dist/assets/main-Cw6gybzS.js +109 -0
  59. package/bizar-dash/dist/assets/main-Cw6gybzS.js.map +1 -0
  60. package/bizar-dash/dist/assets/message-square-DUTeIQAR.js +6 -0
  61. package/bizar-dash/dist/assets/message-square-DUTeIQAR.js.map +1 -0
  62. package/bizar-dash/dist/assets/minus-CrStJTZ7.js +6 -0
  63. package/bizar-dash/dist/assets/minus-CrStJTZ7.js.map +1 -0
  64. package/bizar-dash/dist/assets/wrench-BJ1WIC4u.js +6 -0
  65. package/bizar-dash/dist/assets/wrench-BJ1WIC4u.js.map +1 -0
  66. package/bizar-dash/dist/{mobile.html → v8.html} +6 -9
  67. package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  68. package/bizar-dash/src/server/server.mjs +1 -57
  69. package/bizar-dash/src/web/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  70. package/bizar-dash/src/web/v8/App.tsx +188 -0
  71. package/bizar-dash/src/web/v8/__tests__/App.test.tsx +102 -0
  72. package/bizar-dash/src/web/v8/__tests__/AppShell.test.tsx +79 -0
  73. package/bizar-dash/src/web/v8/__tests__/PageSkeleton.test.tsx +12 -0
  74. package/bizar-dash/src/web/v8/__tests__/SettingsView.test.tsx +84 -0
  75. package/bizar-dash/src/web/v8/__tests__/Sidebar.test.tsx +95 -0
  76. package/bizar-dash/src/web/v8/__tests__/activity.test.tsx +63 -0
  77. package/bizar-dash/src/web/v8/__tests__/agents.test.tsx +90 -0
  78. package/bizar-dash/src/web/v8/__tests__/controls.test.tsx +135 -0
  79. package/bizar-dash/src/web/v8/__tests__/cx.test.ts +25 -0
  80. package/bizar-dash/src/web/v8/__tests__/data.test.tsx +293 -0
  81. package/bizar-dash/src/web/v8/__tests__/feedback.test.tsx +213 -0
  82. package/bizar-dash/src/web/v8/__tests__/goals.test.tsx +105 -0
  83. package/bizar-dash/src/web/v8/__tests__/kanban.test.tsx +176 -0
  84. package/bizar-dash/src/web/v8/__tests__/libraries.test.tsx +70 -0
  85. package/bizar-dash/src/web/v8/__tests__/memory.test.tsx +60 -0
  86. package/bizar-dash/src/web/v8/__tests__/navigation.test.tsx +137 -0
  87. package/bizar-dash/src/web/v8/__tests__/settings.test.tsx +104 -0
  88. package/bizar-dash/src/web/v8/__tests__/theme.test.tsx +98 -0
  89. package/bizar-dash/src/web/v8/__tests__/views.test.tsx +112 -0
  90. package/bizar-dash/src/web/v8/main.tsx +28 -0
  91. package/bizar-dash/src/web/v8/shell/AppShell.tsx +90 -0
  92. package/bizar-dash/src/web/v8/shell/PageSkeleton.tsx +29 -0
  93. package/bizar-dash/src/web/v8/shell/Sidebar.tsx +361 -0
  94. package/bizar-dash/src/web/v8/shell/StatusBar.tsx +63 -0
  95. package/bizar-dash/src/web/v8/shell/Topbar.tsx +113 -0
  96. package/bizar-dash/src/web/v8/shell/index.ts +15 -0
  97. package/bizar-dash/src/web/v8/ui/activity/ActivityFeed.tsx +137 -0
  98. package/bizar-dash/src/web/v8/ui/agents/AgentActivity.tsx +101 -0
  99. package/bizar-dash/src/web/v8/ui/agents/AgentCard.tsx +158 -0
  100. package/bizar-dash/src/web/v8/ui/controls/Button.tsx +141 -0
  101. package/bizar-dash/src/web/v8/ui/controls/ButtonGroup.tsx +32 -0
  102. package/bizar-dash/src/web/v8/ui/controls/Checkbox.tsx +49 -0
  103. package/bizar-dash/src/web/v8/ui/controls/Field.tsx +78 -0
  104. package/bizar-dash/src/web/v8/ui/controls/Form.tsx +23 -0
  105. package/bizar-dash/src/web/v8/ui/controls/IconButton.tsx +112 -0
  106. package/bizar-dash/src/web/v8/ui/controls/Input.tsx +94 -0
  107. package/bizar-dash/src/web/v8/ui/controls/RadioGroup.tsx +74 -0
  108. package/bizar-dash/src/web/v8/ui/controls/Select.tsx +171 -0
  109. package/bizar-dash/src/web/v8/ui/controls/Slider.tsx +68 -0
  110. package/bizar-dash/src/web/v8/ui/controls/Switch.tsx +56 -0
  111. package/bizar-dash/src/web/v8/ui/controls/Textarea.tsx +64 -0
  112. package/bizar-dash/src/web/v8/ui/controls/Toggle.tsx +36 -0
  113. package/bizar-dash/src/web/v8/ui/controls/ToggleGroup.tsx +85 -0
  114. package/bizar-dash/src/web/v8/ui/data/Accordion.tsx +134 -0
  115. package/bizar-dash/src/web/v8/ui/data/Avatar.tsx +175 -0
  116. package/bizar-dash/src/web/v8/ui/data/Badge.tsx +93 -0
  117. package/bizar-dash/src/web/v8/ui/data/BarList.tsx +101 -0
  118. package/bizar-dash/src/web/v8/ui/data/Card.tsx +140 -0
  119. package/bizar-dash/src/web/v8/ui/data/Chip.tsx +96 -0
  120. package/bizar-dash/src/web/v8/ui/data/Kbd.tsx +42 -0
  121. package/bizar-dash/src/web/v8/ui/data/ProgressBar.tsx +93 -0
  122. package/bizar-dash/src/web/v8/ui/data/Sparkline.tsx +98 -0
  123. package/bizar-dash/src/web/v8/ui/data/StatTile.tsx +150 -0
  124. package/bizar-dash/src/web/v8/ui/data/Table.tsx +170 -0
  125. package/bizar-dash/src/web/v8/ui/data/Timeline.tsx +130 -0
  126. package/bizar-dash/src/web/v8/ui/data/ViewHeader.tsx +122 -0
  127. package/bizar-dash/src/web/v8/ui/feedback/Alert.tsx +95 -0
  128. package/bizar-dash/src/web/v8/ui/feedback/Banner.tsx +39 -0
  129. package/bizar-dash/src/web/v8/ui/feedback/ContextMenu.tsx +143 -0
  130. package/bizar-dash/src/web/v8/ui/feedback/Dialog.tsx +149 -0
  131. package/bizar-dash/src/web/v8/ui/feedback/Drawer.tsx +8 -0
  132. package/bizar-dash/src/web/v8/ui/feedback/DropdownMenu.tsx +231 -0
  133. package/bizar-dash/src/web/v8/ui/feedback/EmptyState.tsx +48 -0
  134. package/bizar-dash/src/web/v8/ui/feedback/Popover.tsx +56 -0
  135. package/bizar-dash/src/web/v8/ui/feedback/Sheet.tsx +103 -0
  136. package/bizar-dash/src/web/v8/ui/feedback/Skeleton.tsx +67 -0
  137. package/bizar-dash/src/web/v8/ui/feedback/Spinner.tsx +30 -0
  138. package/bizar-dash/src/web/v8/ui/feedback/Toast.tsx +66 -0
  139. package/bizar-dash/src/web/v8/ui/feedback/Tooltip.tsx +89 -0
  140. package/bizar-dash/src/web/v8/ui/goals/GoalCard.tsx +176 -0
  141. package/bizar-dash/src/web/v8/ui/goals/KeyResult.tsx +115 -0
  142. package/bizar-dash/src/web/v8/ui/index.ts +322 -0
  143. package/bizar-dash/src/web/v8/ui/kanban/KanbanBoard.tsx +80 -0
  144. package/bizar-dash/src/web/v8/ui/kanban/KanbanCard.tsx +247 -0
  145. package/bizar-dash/src/web/v8/ui/kanban/KanbanColumn.tsx +181 -0
  146. package/bizar-dash/src/web/v8/ui/kanban/KanbanContextMenu.tsx +122 -0
  147. package/bizar-dash/src/web/v8/ui/kanban/KanbanQuickAdd.tsx +141 -0
  148. package/bizar-dash/src/web/v8/ui/libraries/LibraryGrid.tsx +30 -0
  149. package/bizar-dash/src/web/v8/ui/libraries/LibraryItem.tsx +161 -0
  150. package/bizar-dash/src/web/v8/ui/memory/MemoryVault.tsx +144 -0
  151. package/bizar-dash/src/web/v8/ui/navigation/CommandPalette.tsx +224 -0
  152. package/bizar-dash/src/web/v8/ui/navigation/NavLink.tsx +81 -0
  153. package/bizar-dash/src/web/v8/ui/navigation/Pagination.tsx +164 -0
  154. package/bizar-dash/src/web/v8/ui/navigation/Tabs.tsx +128 -0
  155. package/bizar-dash/src/web/v8/ui/navigation/useCommandPaletteHotkey.test.ts +79 -0
  156. package/bizar-dash/src/web/v8/ui/primitives/Box.tsx +144 -0
  157. package/bizar-dash/src/web/v8/ui/primitives/Center.tsx +40 -0
  158. package/bizar-dash/src/web/v8/ui/primitives/Cluster.tsx +67 -0
  159. package/bizar-dash/src/web/v8/ui/primitives/Grid.tsx +104 -0
  160. package/bizar-dash/src/web/v8/ui/primitives/Inline.tsx +77 -0
  161. package/bizar-dash/src/web/v8/ui/primitives/Portal.tsx +33 -0
  162. package/bizar-dash/src/web/v8/ui/primitives/ScrollArea.tsx +62 -0
  163. package/bizar-dash/src/web/v8/ui/primitives/Separator.tsx +42 -0
  164. package/bizar-dash/src/web/v8/ui/primitives/Stack.tsx +73 -0
  165. package/bizar-dash/src/web/v8/ui/primitives/VisuallyHidden.tsx +49 -0
  166. package/bizar-dash/src/web/v8/ui/settings/SettingsNav.tsx +91 -0
  167. package/bizar-dash/src/web/v8/ui/settings/SettingsRow.tsx +88 -0
  168. package/bizar-dash/src/web/v8/ui/settings/SettingsSection.tsx +109 -0
  169. package/bizar-dash/src/web/v8/ui/styles/globals.css +220 -0
  170. package/bizar-dash/src/web/v8/ui/styles/reset.css +57 -0
  171. package/bizar-dash/src/web/v8/ui/styles/tokens.css +217 -0
  172. package/bizar-dash/src/web/v8/ui/theme/DensityProvider.test.tsx +74 -0
  173. package/bizar-dash/src/web/v8/ui/theme/DensityProvider.tsx +66 -0
  174. package/bizar-dash/src/web/v8/ui/theme/ThemeProvider.test.tsx +86 -0
  175. package/bizar-dash/src/web/v8/ui/theme/ThemeProvider.tsx +94 -0
  176. package/bizar-dash/src/web/v8/ui/theme/ThemeToggle.tsx +88 -0
  177. package/bizar-dash/src/web/v8/ui/theme/useDensity.ts +15 -0
  178. package/bizar-dash/src/web/v8/ui/theme/useTheme.ts +16 -0
  179. package/bizar-dash/src/web/v8/ui/utils/cx.ts +19 -0
  180. package/bizar-dash/src/web/v8/views/Activity/ActivityView.tsx +33 -0
  181. package/bizar-dash/src/web/v8/views/Agents/AgentsView.tsx +108 -0
  182. package/bizar-dash/src/web/v8/views/CommandPalette/AppCommandPalette.test.tsx +142 -0
  183. package/bizar-dash/src/web/v8/views/CommandPalette/AppCommandPalette.tsx +144 -0
  184. package/bizar-dash/src/web/v8/views/Goals/GoalsView.tsx +84 -0
  185. package/bizar-dash/src/web/v8/views/Libraries/LibrariesView.tsx +41 -0
  186. package/bizar-dash/src/web/v8/views/Memory/MemoryView.tsx +61 -0
  187. package/bizar-dash/src/web/v8/views/Overview/OverviewView.tsx +92 -0
  188. package/bizar-dash/src/web/v8/views/Router.tsx +96 -0
  189. package/bizar-dash/src/web/v8/views/Settings/SettingsView.tsx +305 -0
  190. package/bizar-dash/src/web/v8/views/Tasks/CommandPalettePlaceholder.tsx +106 -0
  191. package/bizar-dash/src/web/v8/views/Tasks/TasksKanbanPlaceholder.tsx +62 -0
  192. package/bizar-dash/src/web/v8/views/Tasks/TasksView.tsx +74 -0
  193. package/bizar-dash/src/web/v8/vite-env.d.ts +15 -0
  194. package/bizar-dash/src/web/{mobile.html → v8.html} +4 -7
  195. package/bizar-dash/tests/settings-layout.test.tsx +2 -2
  196. package/bizar-dash/tests/settings-nav.test.tsx +6 -6
  197. package/bizar-dash/tests/setup.ts +26 -0
  198. package/bizar-dash/vite.config.ts +26 -2
  199. package/bizar-dash/vitest.config.ts +5 -3
  200. package/cli/provision-claude.mjs +108 -5
  201. package/package.json +36 -3
  202. package/bizar-dash/dist/assets/EnvVarsSection-BfhAz3ax.js +0 -114
  203. package/bizar-dash/dist/assets/EnvVarsSection-BfhAz3ax.js.map +0 -1
  204. package/bizar-dash/dist/assets/MobileChat-DLWdv6tQ.js +0 -1
  205. package/bizar-dash/dist/assets/MobileChat-DLWdv6tQ.js.map +0 -1
  206. package/bizar-dash/dist/assets/MobileSettings-Bxv62uPY.js +0 -1
  207. package/bizar-dash/dist/assets/MobileSettings-Bxv62uPY.js.map +0 -1
  208. package/bizar-dash/dist/assets/Toast-ATSAmbdi.js +0 -26
  209. package/bizar-dash/dist/assets/Toast-ATSAmbdi.js.map +0 -1
  210. package/bizar-dash/dist/assets/__vite-browser-external-BIHI7g3E.js +0 -1
  211. package/bizar-dash/dist/assets/__vite-browser-external-BIHI7g3E.js.map +0 -1
  212. package/bizar-dash/dist/assets/main-306CZfn6.js +0 -430
  213. package/bizar-dash/dist/assets/main-306CZfn6.js.map +0 -1
  214. package/bizar-dash/dist/assets/main-G3bNDpY3.css +0 -1
  215. package/bizar-dash/dist/assets/mobile-C_naUN91.js +0 -1
  216. package/bizar-dash/dist/assets/mobile-C_naUN91.js.map +0 -1
  217. package/bizar-dash/dist/assets/mobile-layout-BWLtwtfQ.css +0 -1
  218. package/bizar-dash/dist/assets/mobile-layout-GZ3bE8L6.js +0 -211
  219. package/bizar-dash/dist/assets/mobile-layout-GZ3bE8L6.js.map +0 -1
  220. package/bizar-dash/dist/assets/useSlashCommands-BOwD7lNb.js +0 -65
  221. package/bizar-dash/dist/assets/useSlashCommands-BOwD7lNb.js.map +0 -1
  222. package/bizar-dash/dist/index.html +0 -43
  223. package/bizar-dash/src/web/App.tsx +0 -915
  224. package/bizar-dash/src/web/MobileApp.tsx +0 -414
  225. package/bizar-dash/src/web/components/ArtifactCreateDialog.tsx +0 -95
  226. package/bizar-dash/src/web/components/ArtifactListDialog.tsx +0 -55
  227. package/bizar-dash/src/web/components/ArtifactViewer.tsx +0 -144
  228. package/bizar-dash/src/web/components/AuditDialog.tsx +0 -79
  229. package/bizar-dash/src/web/components/AutosaveField.tsx +0 -50
  230. package/bizar-dash/src/web/components/BackupRestore.tsx +0 -330
  231. package/bizar-dash/src/web/components/BgStatusBadge.tsx +0 -32
  232. package/bizar-dash/src/web/components/Button.tsx +0 -56
  233. package/bizar-dash/src/web/components/CanvasContextMenu.tsx +0 -68
  234. package/bizar-dash/src/web/components/Card.tsx +0 -40
  235. package/bizar-dash/src/web/components/CollapsibleSection.tsx +0 -72
  236. package/bizar-dash/src/web/components/CommandDialog.tsx +0 -66
  237. package/bizar-dash/src/web/components/DoctorPanel.tsx +0 -160
  238. package/bizar-dash/src/web/components/EmptyState.tsx +0 -30
  239. package/bizar-dash/src/web/components/EnvVarManager.tsx +0 -430
  240. package/bizar-dash/src/web/components/EvalDiff.tsx +0 -157
  241. package/bizar-dash/src/web/components/EvalExportButton.tsx +0 -27
  242. package/bizar-dash/src/web/components/EvalRunCard.tsx +0 -78
  243. package/bizar-dash/src/web/components/FileBrowser.tsx +0 -633
  244. package/bizar-dash/src/web/components/HeadroomSettings.tsx +0 -418
  245. package/bizar-dash/src/web/components/HeadroomStatus.tsx +0 -158
  246. package/bizar-dash/src/web/components/HelpDialog.tsx +0 -55
  247. package/bizar-dash/src/web/components/InviteDialog.tsx +0 -205
  248. package/bizar-dash/src/web/components/KillConfirmDialog.tsx +0 -88
  249. package/bizar-dash/src/web/components/MobileBottomNav.tsx +0 -38
  250. package/bizar-dash/src/web/components/MobileDrawer.tsx +0 -68
  251. package/bizar-dash/src/web/components/MobileHeader.tsx +0 -50
  252. package/bizar-dash/src/web/components/MobileLayout.tsx +0 -63
  253. package/bizar-dash/src/web/components/Modal.tsx +0 -215
  254. package/bizar-dash/src/web/components/Notifications.tsx +0 -242
  255. package/bizar-dash/src/web/components/ScheduleTemplateCard.tsx +0 -72
  256. package/bizar-dash/src/web/components/ScreenshotCapture.tsx +0 -138
  257. package/bizar-dash/src/web/components/ScreenshotOCR.tsx +0 -42
  258. package/bizar-dash/src/web/components/SearchModal.tsx +0 -227
  259. package/bizar-dash/src/web/components/SettingsNav.tsx +0 -112
  260. package/bizar-dash/src/web/components/SettingsSearch.tsx +0 -328
  261. package/bizar-dash/src/web/components/Sidebar.tsx +0 -89
  262. package/bizar-dash/src/web/components/Spinner.tsx +0 -19
  263. package/bizar-dash/src/web/components/StatusBadge.tsx +0 -56
  264. package/bizar-dash/src/web/components/Tag.tsx +0 -41
  265. package/bizar-dash/src/web/components/TailscaleSettings.tsx +0 -161
  266. package/bizar-dash/src/web/components/TaskCard.tsx +0 -69
  267. package/bizar-dash/src/web/components/TaskCreateSheet.tsx +0 -76
  268. package/bizar-dash/src/web/components/Toast.tsx +0 -150
  269. package/bizar-dash/src/web/components/Toggle.tsx +0 -31
  270. package/bizar-dash/src/web/components/Topbar.tsx +0 -410
  271. package/bizar-dash/src/web/components/UsageChart.tsx +0 -250
  272. package/bizar-dash/src/web/components/UsageTable.tsx +0 -90
  273. package/bizar-dash/src/web/components/VirtualList.tsx +0 -53
  274. package/bizar-dash/src/web/components/VisualPlanDialog.tsx +0 -58
  275. package/bizar-dash/src/web/components/VoiceNotesPanel.tsx +0 -211
  276. package/bizar-dash/src/web/components/VoiceRecorder.tsx +0 -105
  277. package/bizar-dash/src/web/components/WorkspaceSelector.tsx +0 -158
  278. package/bizar-dash/src/web/components/agents/CommunicationLog.tsx +0 -126
  279. package/bizar-dash/src/web/components/agents/DependencyGraph.tsx +0 -163
  280. package/bizar-dash/src/web/components/agents/QualityGates.tsx +0 -123
  281. package/bizar-dash/src/web/components/agents/RealTimeEventLog.tsx +0 -127
  282. package/bizar-dash/src/web/components/agents/RoutingDecisions.test.tsx +0 -148
  283. package/bizar-dash/src/web/components/agents/RoutingDecisions.tsx +0 -160
  284. package/bizar-dash/src/web/components/background/AttachButton.tsx +0 -96
  285. package/bizar-dash/src/web/components/background/TmuxAttachCard.tsx +0 -122
  286. package/bizar-dash/src/web/components/chat/AgentChip.tsx +0 -68
  287. package/bizar-dash/src/web/components/chat/AgentNode.tsx +0 -127
  288. package/bizar-dash/src/web/components/chat/AgentTree.tsx +0 -80
  289. package/bizar-dash/src/web/components/chat/ChatBubble.tsx +0 -60
  290. package/bizar-dash/src/web/components/chat/ChatComposer.tsx +0 -72
  291. package/bizar-dash/src/web/components/chat/ChatInfoPanel.tsx +0 -370
  292. package/bizar-dash/src/web/components/chat/ChatRail.tsx +0 -387
  293. package/bizar-dash/src/web/components/chat/ChatThread.tsx +0 -127
  294. package/bizar-dash/src/web/components/chat/ChatTopBar.tsx +0 -50
  295. package/bizar-dash/src/web/components/chat/Composer.tsx +0 -166
  296. package/bizar-dash/src/web/components/chat/ConfirmModal.tsx +0 -54
  297. package/bizar-dash/src/web/components/chat/EmptyState.tsx +0 -21
  298. package/bizar-dash/src/web/components/chat/FirstRunGreeting.tsx +0 -18
  299. package/bizar-dash/src/web/components/chat/FloatingComposer.tsx +0 -38
  300. package/bizar-dash/src/web/components/chat/InfoPanel.tsx +0 -184
  301. package/bizar-dash/src/web/components/chat/JumpToLatest.tsx +0 -58
  302. package/bizar-dash/src/web/components/chat/LoadingSkeleton.tsx +0 -19
  303. package/bizar-dash/src/web/components/chat/MessageBlock.tsx +0 -260
  304. package/bizar-dash/src/web/components/chat/MessageBubble.tsx +0 -60
  305. package/bizar-dash/src/web/components/chat/SessionList.tsx +0 -163
  306. package/bizar-dash/src/web/components/chat/SessionRowMenu.tsx +0 -206
  307. package/bizar-dash/src/web/components/chat/StreamingIndicator.tsx +0 -37
  308. package/bizar-dash/src/web/components/chat/SuggestionCards.tsx +0 -55
  309. package/bizar-dash/src/web/components/chat/WelcomeScreen.tsx +0 -36
  310. package/bizar-dash/src/web/components/chat/_legacy.ts +0 -30
  311. package/bizar-dash/src/web/components/chat/index.ts +0 -31
  312. package/bizar-dash/src/web/components/chat/useAutoGrowTextarea.ts +0 -18
  313. package/bizar-dash/src/web/components/chat/useChat.ts +0 -1190
  314. package/bizar-dash/src/web/components/chat/useSlashCommands.ts +0 -47
  315. package/bizar-dash/src/web/components/goals/GoalInput.tsx +0 -86
  316. package/bizar-dash/src/web/components/goals/PlanVisualization.tsx +0 -111
  317. package/bizar-dash/src/web/components/tasks/BacklogPanel.css +0 -109
  318. package/bizar-dash/src/web/components/tasks/BacklogPanel.tsx +0 -209
  319. package/bizar-dash/src/web/hooks/useAutosave.ts +0 -107
  320. package/bizar-dash/src/web/hooks/useI18n.ts +0 -13
  321. package/bizar-dash/src/web/index.html +0 -37
  322. package/bizar-dash/src/web/lib/api.ts +0 -237
  323. package/bizar-dash/src/web/lib/goapPlanner.ts +0 -614
  324. package/bizar-dash/src/web/lib/i18n.ts +0 -25
  325. package/bizar-dash/src/web/lib/logger.ts +0 -30
  326. package/bizar-dash/src/web/lib/markdown.tsx +0 -59
  327. package/bizar-dash/src/web/lib/search.ts +0 -115
  328. package/bizar-dash/src/web/lib/types.ts +0 -894
  329. package/bizar-dash/src/web/lib/utils.ts +0 -114
  330. package/bizar-dash/src/web/lib/ws.ts +0 -177
  331. package/bizar-dash/src/web/locales/en.json +0 -52
  332. package/bizar-dash/src/web/main.tsx +0 -43
  333. package/bizar-dash/src/web/mobile/MobileApp.tsx +0 -309
  334. package/bizar-dash/src/web/mobile/MobileBottomNav.tsx +0 -38
  335. package/bizar-dash/src/web/mobile/MobileChat.tsx +0 -138
  336. package/bizar-dash/src/web/mobile/MobileDoctor.tsx +0 -80
  337. package/bizar-dash/src/web/mobile/MobileEval.tsx +0 -167
  338. package/bizar-dash/src/web/mobile/MobileMemory.tsx +0 -108
  339. package/bizar-dash/src/web/mobile/MobileOverview.tsx +0 -213
  340. package/bizar-dash/src/web/mobile/MobileSettings.tsx +0 -251
  341. package/bizar-dash/src/web/mobile/MobileTasks.tsx +0 -94
  342. package/bizar-dash/src/web/mobile/MobileTopbar.tsx +0 -115
  343. package/bizar-dash/src/web/mobile/components/MobileBottomSheet.tsx +0 -182
  344. package/bizar-dash/src/web/mobile/components/MobileListItem.tsx +0 -64
  345. package/bizar-dash/src/web/mobile/components/MobileModal.tsx +0 -123
  346. package/bizar-dash/src/web/mobile/views/MobileActivity.tsx +0 -273
  347. package/bizar-dash/src/web/mobile/views/MobileAgents.tsx +0 -374
  348. package/bizar-dash/src/web/mobile/views/MobileArtifactCanvas.tsx +0 -439
  349. package/bizar-dash/src/web/mobile/views/MobileArtifacts.tsx +0 -143
  350. package/bizar-dash/src/web/mobile/views/MobileChat.tsx +0 -257
  351. package/bizar-dash/src/web/mobile/views/MobileConfig.tsx +0 -175
  352. package/bizar-dash/src/web/mobile/views/MobileHistory.tsx +0 -191
  353. package/bizar-dash/src/web/mobile/views/MobileMods.tsx +0 -149
  354. package/bizar-dash/src/web/mobile/views/MobileMore.tsx +0 -121
  355. package/bizar-dash/src/web/mobile/views/MobileNotifications.tsx +0 -137
  356. package/bizar-dash/src/web/mobile/views/MobilePlans.tsx +0 -26
  357. package/bizar-dash/src/web/mobile/views/MobileSchedules.tsx +0 -685
  358. package/bizar-dash/src/web/mobile/views/MobileSearchModal.tsx +0 -172
  359. package/bizar-dash/src/web/mobile/views/MobileSettings.tsx +0 -363
  360. package/bizar-dash/src/web/mobile/views/MobileSkills.tsx +0 -153
  361. package/bizar-dash/src/web/mobile/views/MobileTasks.tsx +0 -564
  362. package/bizar-dash/src/web/mobile/views/QrCodePanel.tsx +0 -69
  363. package/bizar-dash/src/web/mobile.tsx +0 -14
  364. package/bizar-dash/src/web/styles/agents-redesign.css +0 -311
  365. package/bizar-dash/src/web/styles/chat.css +0 -1740
  366. package/bizar-dash/src/web/styles/glyphs.css +0 -960
  367. package/bizar-dash/src/web/styles/main.css +0 -10391
  368. package/bizar-dash/src/web/styles/memory.css +0 -1182
  369. package/bizar-dash/src/web/styles/minimax-usage.css +0 -842
  370. package/bizar-dash/src/web/styles/mobile-chat.css +0 -5
  371. package/bizar-dash/src/web/styles/mobile-layout.css +0 -233
  372. package/bizar-dash/src/web/styles/mobile.css +0 -2181
  373. package/bizar-dash/src/web/styles/settings.css +0 -795
  374. package/bizar-dash/src/web/styles/skills.css +0 -302
  375. package/bizar-dash/src/web/styles/tasks-redesign.css +0 -253
  376. package/bizar-dash/src/web/styles/tasks.css +0 -605
  377. package/bizar-dash/src/web/ui/controls/Button.tsx +0 -77
  378. package/bizar-dash/src/web/ui/controls/Checkbox.tsx +0 -95
  379. package/bizar-dash/src/web/ui/controls/IconButton.tsx +0 -66
  380. package/bizar-dash/src/web/ui/controls/Kbd.tsx +0 -24
  381. package/bizar-dash/src/web/ui/controls/NumberInput.tsx +0 -77
  382. package/bizar-dash/src/web/ui/controls/RadioGroup.tsx +0 -109
  383. package/bizar-dash/src/web/ui/controls/SearchInput.tsx +0 -91
  384. package/bizar-dash/src/web/ui/controls/Select.tsx +0 -92
  385. package/bizar-dash/src/web/ui/controls/Slider.tsx +0 -70
  386. package/bizar-dash/src/web/ui/controls/TextInput.tsx +0 -67
  387. package/bizar-dash/src/web/ui/controls/Textarea.tsx +0 -56
  388. package/bizar-dash/src/web/ui/controls/Toggle.tsx +0 -79
  389. package/bizar-dash/src/web/ui/controls/controls.css +0 -476
  390. package/bizar-dash/src/web/ui/controls/index.ts +0 -35
  391. package/bizar-dash/src/web/ui/data/BarChart.tsx +0 -60
  392. package/bizar-dash/src/web/ui/data/DataTable.tsx +0 -216
  393. package/bizar-dash/src/web/ui/data/EmptyState.tsx +0 -60
  394. package/bizar-dash/src/web/ui/data/ErrorState.tsx +0 -56
  395. package/bizar-dash/src/web/ui/data/KeyValueList.tsx +0 -106
  396. package/bizar-dash/src/web/ui/data/LoadingState.tsx +0 -65
  397. package/bizar-dash/src/web/ui/data/Sparkline.tsx +0 -87
  398. package/bizar-dash/src/web/ui/data/StatTile.tsx +0 -87
  399. package/bizar-dash/src/web/ui/data/data.css +0 -535
  400. package/bizar-dash/src/web/ui/data/index.ts +0 -31
  401. package/bizar-dash/src/web/ui/feedback/Badge.tsx +0 -49
  402. package/bizar-dash/src/web/ui/feedback/Dialog.tsx +0 -209
  403. package/bizar-dash/src/web/ui/feedback/ProgressBar.tsx +0 -69
  404. package/bizar-dash/src/web/ui/feedback/StatusDot.tsx +0 -50
  405. package/bizar-dash/src/web/ui/feedback/Toast.tsx +0 -200
  406. package/bizar-dash/src/web/ui/feedback/Tooltip.tsx +0 -126
  407. package/bizar-dash/src/web/ui/feedback/feedback.css +0 -314
  408. package/bizar-dash/src/web/ui/feedback/index.ts +0 -43
  409. package/bizar-dash/src/web/ui/index.ts +0 -56
  410. package/bizar-dash/src/web/ui/layout/AppShell.tsx +0 -51
  411. package/bizar-dash/src/web/ui/layout/Breadcrumbs.tsx +0 -97
  412. package/bizar-dash/src/web/ui/layout/Panel.tsx +0 -73
  413. package/bizar-dash/src/web/ui/layout/PanelHeader.tsx +0 -39
  414. package/bizar-dash/src/web/ui/layout/Sidebar.tsx +0 -131
  415. package/bizar-dash/src/web/ui/layout/Tabs.tsx +0 -133
  416. package/bizar-dash/src/web/ui/layout/Topbar.tsx +0 -42
  417. package/bizar-dash/src/web/ui/layout/ViewHeader.tsx +0 -48
  418. package/bizar-dash/src/web/ui/layout/index.ts +0 -34
  419. package/bizar-dash/src/web/ui/layout/layout.css +0 -464
  420. package/bizar-dash/src/web/ui/navigation/CommandPalette.tsx +0 -199
  421. package/bizar-dash/src/web/ui/navigation/NavGroup.tsx +0 -95
  422. package/bizar-dash/src/web/ui/navigation/NavLink.tsx +0 -93
  423. package/bizar-dash/src/web/ui/navigation/index.ts +0 -17
  424. package/bizar-dash/src/web/ui/navigation/navigation.css +0 -343
  425. package/bizar-dash/src/web/ui/primitives/Box.tsx +0 -91
  426. package/bizar-dash/src/web/ui/primitives/Grid.tsx +0 -49
  427. package/bizar-dash/src/web/ui/primitives/Inline.tsx +0 -55
  428. package/bizar-dash/src/web/ui/primitives/Separator.tsx +0 -46
  429. package/bizar-dash/src/web/ui/primitives/Stack.tsx +0 -54
  430. package/bizar-dash/src/web/ui/primitives/VisuallyHidden.tsx +0 -26
  431. package/bizar-dash/src/web/ui/primitives/index.ts +0 -23
  432. package/bizar-dash/src/web/ui/primitives/primitives.css +0 -183
  433. package/bizar-dash/src/web/ui/styles/globals.css +0 -86
  434. package/bizar-dash/src/web/ui/styles/reset.css +0 -125
  435. package/bizar-dash/src/web/ui/styles/tokens.css +0 -208
  436. package/bizar-dash/src/web/ui/theme/ThemeProvider.tsx +0 -142
  437. package/bizar-dash/src/web/ui/theme/tokens.ts +0 -131
  438. package/bizar-dash/src/web/ui/theme/useTheme.ts +0 -22
  439. package/bizar-dash/src/web/ui/utils/cx.ts +0 -42
  440. package/bizar-dash/src/web/views/Activity.tsx +0 -1221
  441. package/bizar-dash/src/web/views/Agents.tsx +0 -964
  442. package/bizar-dash/src/web/views/Artifacts.tsx +0 -1494
  443. package/bizar-dash/src/web/views/BackgroundAgents.tsx +0 -822
  444. package/bizar-dash/src/web/views/Chat.tsx +0 -532
  445. package/bizar-dash/src/web/views/Config.tsx +0 -3
  446. package/bizar-dash/src/web/views/Doctor.tsx +0 -317
  447. package/bizar-dash/src/web/views/Eval.tsx +0 -372
  448. package/bizar-dash/src/web/views/EvalReport.tsx +0 -353
  449. package/bizar-dash/src/web/views/GoalPlanner.tsx +0 -158
  450. package/bizar-dash/src/web/views/Harness.tsx +0 -306
  451. package/bizar-dash/src/web/views/History.tsx +0 -353
  452. package/bizar-dash/src/web/views/Memory.tsx +0 -161
  453. package/bizar-dash/src/web/views/MiniMaxUsage.tsx +0 -942
  454. package/bizar-dash/src/web/views/ModView.tsx +0 -207
  455. package/bizar-dash/src/web/views/Mods.tsx +0 -706
  456. package/bizar-dash/src/web/views/Overview.tsx +0 -1364
  457. package/bizar-dash/src/web/views/Providers.tsx +0 -302
  458. package/bizar-dash/src/web/views/Schedules.tsx +0 -902
  459. package/bizar-dash/src/web/views/Settings.tsx +0 -308
  460. package/bizar-dash/src/web/views/Skills.tsx +0 -383
  461. package/bizar-dash/src/web/views/SpawnAgentModal.tsx +0 -221
  462. package/bizar-dash/src/web/views/Tasks.tsx +0 -789
  463. package/bizar-dash/src/web/views/Workspace.tsx +0 -294
  464. package/bizar-dash/src/web/views/glyphs/GlyphRenderer.tsx +0 -844
  465. package/bizar-dash/src/web/views/glyphs/components.tsx +0 -1098
  466. package/bizar-dash/src/web/views/memory/ConfigPanel.tsx +0 -426
  467. package/bizar-dash/src/web/views/memory/FromScreenshotPanel.tsx +0 -23
  468. package/bizar-dash/src/web/views/memory/GitSyncPanel.tsx +0 -220
  469. package/bizar-dash/src/web/views/memory/LightragPanel.tsx +0 -310
  470. package/bizar-dash/src/web/views/memory/MemoryGraphLegend.tsx +0 -29
  471. package/bizar-dash/src/web/views/memory/MemoryGraphPanel.tsx +0 -192
  472. package/bizar-dash/src/web/views/memory/MemoryGraphView.tsx +0 -336
  473. package/bizar-dash/src/web/views/memory/MemoryOverview.tsx +0 -367
  474. package/bizar-dash/src/web/views/memory/MemoryStatusCard.tsx +0 -160
  475. package/bizar-dash/src/web/views/memory/ObsidianPanel.tsx +0 -650
  476. package/bizar-dash/src/web/views/memory/SemanticSearchPanel.tsx +0 -197
  477. package/bizar-dash/src/web/views/memory/VaultFromClipboardPanel.tsx +0 -101
  478. package/bizar-dash/src/web/views/settings/ActivitySection.tsx +0 -205
  479. package/bizar-dash/src/web/views/settings/AgentSection.tsx +0 -305
  480. package/bizar-dash/src/web/views/settings/AuthSection.tsx +0 -159
  481. package/bizar-dash/src/web/views/settings/EnvVarsSection.tsx +0 -15
  482. package/bizar-dash/src/web/views/settings/GeneralSection.tsx +0 -128
  483. package/bizar-dash/src/web/views/settings/HeadroomSection.tsx +0 -39
  484. package/bizar-dash/src/web/views/settings/MemorySection.tsx +0 -154
  485. package/bizar-dash/src/web/views/settings/NetworkSection.tsx +0 -87
  486. package/bizar-dash/src/web/views/settings/NotificationsSection.tsx +0 -34
  487. package/bizar-dash/src/web/views/settings/SystemLlmSection.tsx +0 -81
  488. package/bizar-dash/src/web/views/settings/ThemeSection.tsx +0 -168
  489. package/bizar-dash/src/web/views/settings/UpdatesSection.tsx +0 -256
  490. package/bizar-dash/src/web/views/settings/WorkspacesSection.tsx +0 -189
@@ -1,789 +0,0 @@
1
- /*
2
- * Tasks.tsx — Wave 3 redesigned kanban board (Supabase-style simplicity).
3
- *
4
- * The view groups tasks into 5 columns by API status (queued | doing | done
5
- * | blocked | backlog) and renders each column as a `Panel` from the new
6
- * design system. Task rows are compact (~76px) cards with a left-edge
7
- * priority accent (3px) derived from the priority token. The redesign
8
- * intentionally uses only design-system primitives (Panel, Grid, Stack,
9
- * Inline, Badge, StatusDot, Button, IconButton, SearchInput, Select,
10
- * EmptyState, LoadingState) — no legacy `.task-card` / `.kanban-column`
11
- * classes from main.css.
12
- *
13
- * Hard constraints preserved from the previous implementation:
14
- * - Same export name (`Tasks`) and same `Props` shape so App.tsx keeps
15
- * importing without changes.
16
- * - Same API contracts (`api.get('/tasks')`, `api.patch(.../status)`, etc).
17
- * - Same WS subscriptions (`tasks:change`, `tasks:delete`).
18
- * - Same COLUMNS array — the API status enum is the public contract.
19
- * - BacklogPanel is still imported from `components/tasks/BacklogPanel`
20
- * and receives the same props (out-of-scope for this redesign).
21
- * - Legacy `Modal` is reused for the create/edit dialogs (out-of-scope).
22
- * - 30s tick for relative-time labels.
23
- *
24
- * What changed:
25
- * - Columns are now `Panel`s with a StatusDot + count in the header.
26
- * - Task rows render with `Badge` for status/priority/agent and
27
- * `IconButton` for actions (edit, submit-to-odin, retry, delete).
28
- * - The whole task row is clickable (delegates to the edit modal) —
29
- * action buttons stop propagation so they keep their dedicated path.
30
- * - Toolbar uses `SearchInput` + `Select` (priority) instead of raw
31
- * inputs.
32
- */
33
- import React, { useEffect, useMemo, useState } from 'react';
34
- import {
35
- CheckSquare,
36
- Plus,
37
- Trash2,
38
- RefreshCw,
39
- Tag as TagIcon,
40
- ArchiveRestore,
41
- RotateCw,
42
- Send,
43
- Inbox,
44
- Edit2,
45
- Bot,
46
- } from 'lucide-react';
47
- import { Button } from '../components/Button';
48
- import { Card, CardTitle, CardMeta } from '../components/Card';
49
- import { useModal } from '../components/Modal';
50
- import { useToast } from '../components/Toast';
51
- import { api, enhancePrompt } from '../lib/api';
52
- import { formatRelative } from '../lib/utils';
53
- import type { Settings, Snapshot, Task } from '../lib/types';
54
- import { BacklogPanel } from '../components/tasks/BacklogPanel';
55
- import {
56
- Badge,
57
- cx,
58
- Grid,
59
- IconButton,
60
- Inline,
61
- LoadingState,
62
- Panel,
63
- SearchInput,
64
- Select,
65
- Stack,
66
- StatusDot,
67
- type BadgeVariant,
68
- } from '../ui';
69
-
70
- import '../styles/tasks-redesign.css';
71
-
72
- type Props = {
73
- snapshot: Snapshot;
74
- settings: Settings;
75
- activeTab: string;
76
- setActiveTab: (id: string) => void;
77
- refreshSnapshot: () => Promise<void>;
78
- };
79
-
80
- type StatusKind = 'info' | 'accent' | 'success' | 'warning' | 'error';
81
- type PriorityKind = 'low' | 'normal' | 'high';
82
-
83
- /**
84
- * UI <-> API status mapping. We keep the existing API enum
85
- * (queued | doing | done | blocked | archived | backlog) and only
86
- * rename the labels here so the dashboard, server, and tests stay in
87
- * sync. Switch back if you need to expose the raw API value.
88
- */
89
- const COLUMNS: {
90
- id: Task['status'];
91
- label: string;
92
- kind: StatusKind;
93
- dotVariant: 'info' | 'success' | 'warning' | 'danger';
94
- }[] = [
95
- { id: 'queued', label: 'Todo', kind: 'info', dotVariant: 'info' },
96
- { id: 'doing', label: 'In progress', kind: 'accent', dotVariant: 'info' },
97
- { id: 'done', label: 'Done', kind: 'success', dotVariant: 'success' },
98
- { id: 'blocked', label: 'Failed', kind: 'error', dotVariant: 'danger' },
99
- ];
100
-
101
- const PRIORITIES: readonly PriorityKind[] = ['low', 'normal', 'high'];
102
-
103
- const PRIORITY_OPTIONS = [
104
- { value: '', label: 'All' },
105
- ...PRIORITIES.map((p) => ({ value: p, label: p })),
106
- ];
107
-
108
- const STATUS_BADGE: Record<StatusKind, BadgeVariant> = {
109
- info: 'info',
110
- accent: 'accent',
111
- success: 'success',
112
- warning: 'warning',
113
- error: 'danger',
114
- };
115
-
116
- const PRIORITY_BADGE: Record<PriorityKind, BadgeVariant> = {
117
- high: 'danger',
118
- normal: 'info',
119
- low: 'neutral',
120
- };
121
-
122
- function TasksInner({
123
- snapshot,
124
- refreshSnapshot,
125
- }: Props) {
126
- const toast = useToast();
127
- const modal = useModal();
128
- const [tasks, setTasks] = useState<Task[]>(snapshot.tasks || []);
129
- const [loading, setLoading] = useState(!snapshot.tasks);
130
- const [filter, setFilter] = useState('');
131
- const [priorityFilter, setPriorityFilter] = useState<string>('');
132
- const [showBacklog, setShowBacklog] = useState(false);
133
- const [tick, setTick] = useState(0); // for live timer re-render
134
- const [statusAnnouncement, setStatusAnnouncement] = useState('');
135
-
136
- const reload = async () => {
137
- try {
138
- const data = await api.get<Task[]>('/tasks');
139
- setTasks(Array.isArray(data) ? data : []);
140
- } catch (err) {
141
- toast.error(`Tasks load failed: ${(err as Error).message}`);
142
- } finally {
143
- setLoading(false);
144
- }
145
- };
146
-
147
- useEffect(() => {
148
- if (snapshot.tasks) {
149
- setTasks(snapshot.tasks);
150
- setLoading(false);
151
- }
152
- }, [snapshot.tasks]);
153
-
154
- // Periodic tick keeps relative-time labels fresh without a full reload.
155
- useEffect(() => {
156
- const id = setInterval(() => setTick((t) => t + 1), 30_000);
157
- return () => clearInterval(id);
158
- }, []);
159
-
160
- const filtered = useMemo(() => {
161
- let out = tasks.filter((t) => t.status !== 'backlog');
162
- if (priorityFilter) {
163
- out = out.filter((t) => (t.priority || 'normal') === priorityFilter);
164
- }
165
- if (filter.trim()) {
166
- const q = filter.toLowerCase();
167
- out = out.filter((t) =>
168
- (t.title || '').toLowerCase().includes(q) ||
169
- (t.description || '').toLowerCase().includes(q),
170
- );
171
- }
172
- return out;
173
- }, [tasks, filter, priorityFilter]);
174
-
175
- const sorted = useMemo(() => {
176
- const priorityWeight = { high: 0, normal: 1, low: 2 } as Record<string, number>;
177
- return [...filtered].sort((a, b) => {
178
- const pa = priorityWeight[a.priority] ?? 1;
179
- const pb = priorityWeight[b.priority] ?? 1;
180
- if (pa !== pb) return pa - pb;
181
- return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();
182
- });
183
- }, [filtered]);
184
-
185
- const backlogCount = tasks.filter((t) => t.status === 'backlog').length;
186
-
187
- // ─── Actions ─────────────────────────────────────────────────────────────
188
-
189
- const moveTask = async (taskId: string, newStatus: string) => {
190
- const t = tasks.find((x) => x.id === taskId);
191
- if (!t) return;
192
- const prev = t.status;
193
- setTasks((cur) =>
194
- cur.map((x) => (x.id === taskId ? { ...x, status: newStatus } : x)),
195
- );
196
- setStatusAnnouncement(`Task ${t.title} moved to ${newStatus}.`);
197
- try {
198
- await api.patch(`/tasks/${encodeURIComponent(taskId)}/status`, {
199
- status: newStatus,
200
- });
201
- toast.success(`Moved to ${newStatus}.`, 1200);
202
- } catch (err) {
203
- setTasks((cur) =>
204
- cur.map((x) => (x.id === taskId ? { ...x, status: prev } : x)),
205
- );
206
- setStatusAnnouncement(`Failed to move task ${t.title}: ${(err as Error).message}`);
207
- toast.error(`Move failed: ${(err as Error).message}`);
208
- }
209
- };
210
-
211
- const deleteTask = async (taskId: string) => {
212
- if (!confirm('Delete this task?')) return;
213
- try {
214
- await api.del(`/tasks/${encodeURIComponent(taskId)}`);
215
- setTasks((cur) => cur.filter((t) => t.id !== taskId));
216
- toast.success('Task deleted.', 1200);
217
- } catch (err) {
218
- toast.error(`Delete failed: ${(err as Error).message}`);
219
- }
220
- };
221
-
222
- const retryTask = async (taskId: string) => {
223
- try {
224
- // Re-dispatch via the existing /tasks/:id/start endpoint. The
225
- // server returns 202 on accept; failures surface as 502/404.
226
- const r = await api.post<{ ok: boolean; task: Task }>(
227
- `/tasks/${encodeURIComponent(taskId)}/start`,
228
- );
229
- if (r && r.task) {
230
- setTasks((cur) => cur.map((t) => (t.id === taskId ? r.task : t)));
231
- }
232
- toast.success('Retry dispatched.', 1200);
233
- } catch (err) {
234
- toast.error(`Retry failed: ${(err as Error).message}`);
235
- }
236
- };
237
-
238
- const submitToOdin = async (taskId: string) => {
239
- const t = tasks.find((x) => x.id === taskId);
240
- if (!t) return;
241
- try {
242
- // The /tasks/submit endpoint takes a title + description and
243
- // hands the bundle to Odin for delegation. We re-use the task's
244
- // existing fields.
245
- const r = await api.post<{ main: Task; subtasks: Task[] }>('/tasks/submit', {
246
- title: t.title,
247
- description: t.description,
248
- priority: t.priority,
249
- tags: t.tags,
250
- });
251
- const count = (r.subtasks || []).length;
252
- toast.success(
253
- count > 1
254
- ? `Odin split it into ${count} subtasks.`
255
- : 'Sent to Odin.',
256
- 1500,
257
- );
258
- if (r.subtasks && r.subtasks.length > 0) {
259
- setTasks((cur) => [r.main, ...r.subtasks, ...cur.filter((x) => x.id !== t.id)]);
260
- }
261
- await refreshSnapshot();
262
- } catch (err) {
263
- toast.error(`Submit failed: ${(err as Error).message}`);
264
- }
265
- };
266
-
267
- const handleTaskClick = (task: Task) => {
268
- openEditTaskModal(modal, toast, task, setTasks, reload, refreshSnapshot);
269
- };
270
-
271
- return (
272
- <div className="view view-tasks tasks-wave3">
273
- {/* Hidden live region for screen-reader announcements of status changes. */}
274
- <div className="sr-only" role="status" aria-live="polite">
275
- {statusAnnouncement}
276
- </div>
277
- <header className="tasks-wave3__header">
278
- <div>
279
- <h2 className="tasks-wave3__title-row">
280
- <CheckSquare size={18} aria-hidden /> Tasks ({sorted.length})
281
- </h2>
282
- <p className="tasks-wave3__subtitle">
283
- Add a task — title and description is all you need. Odin picks the agent and priority.
284
- </p>
285
- </div>
286
- </header>
287
-
288
- {/* Toolbar: search, priority filter, refresh, backlog toggle, new task */}
289
- <div className="tasks-wave3__toolbar" role="toolbar" aria-label="Task filters">
290
- <div className="tasks-wave3__toolbar-group">
291
- <SearchInput
292
- inputSize="sm"
293
- value={filter}
294
- onChange={((v: unknown) => setFilter(String(v))) as unknown as React.ComponentProps<typeof SearchInput>['onChange']}
295
- placeholder="Search…"
296
- aria-label="Search tasks"
297
- />
298
- </div>
299
-
300
- <div className="tasks-wave3__toolbar-group">
301
- <span className="tasks-wave3__toolbar-label" id="tasks-priority-filter-label">
302
- Priority
303
- </span>
304
- <Select
305
- inputSize="sm"
306
- aria-labelledby="tasks-priority-filter-label"
307
- options={PRIORITY_OPTIONS}
308
- value={priorityFilter}
309
- onChange={(e) => setPriorityFilter((e.target as HTMLSelectElement).value)}
310
- />
311
- </div>
312
-
313
- <div className="tasks-wave3__toolbar-spacer" />
314
-
315
- <div className="tasks-wave3__toolbar-group">
316
- <Button
317
- variant="ghost"
318
- size="sm"
319
- onClick={reload}
320
- title="Refresh"
321
- aria-label="Refresh tasks"
322
- >
323
- <RefreshCw size={14} aria-hidden />
324
- </Button>
325
- {backlogCount > 0 && (
326
- <Button
327
- variant={showBacklog ? 'accent' : 'ghost'}
328
- size="sm"
329
- onClick={() => setShowBacklog((v) => !v)}
330
- title={showBacklog ? 'Hide backlog' : 'Show backlog'}
331
- >
332
- <Inbox size={14} aria-hidden />
333
- Backlog
334
- <span className="tasks-wave3__column-count" aria-label={`${backlogCount} items`}>
335
- {backlogCount}
336
- </span>
337
- </Button>
338
- )}
339
- <Button
340
- variant="primary"
341
- size="sm"
342
- onClick={() => openCreateTaskModal(modal, toast, setTasks, reload, refreshSnapshot)}
343
- >
344
- <Plus size={14} aria-hidden /> New task
345
- </Button>
346
- </div>
347
- </div>
348
-
349
- {showBacklog && backlogCount > 0 && (
350
- <BacklogPanel
351
- agents={snapshot.agents || []}
352
- onRefresh={refreshSnapshot}
353
- />
354
- )}
355
-
356
- {loading ? (
357
- <LoadingState label="Loading tasks…" />
358
- ) : (
359
- <Grid cols={5} gap={3} className="tasks-wave3__kanban">
360
- {COLUMNS.map((col) => {
361
- const columnTasks = sorted.filter((t) => t.status === col.id);
362
- return (
363
- <Panel
364
- key={col.id}
365
- padding={3}
366
- className="tasks-wave3__column"
367
- title={
368
- <span className="tasks-wave3__column-title">
369
- <StatusDot variant={col.dotVariant} size="sm" label={col.label} />
370
- {col.label}
371
- </span>
372
- }
373
- actions={
374
- <span
375
- className="tasks-wave3__column-count"
376
- aria-label={`${columnTasks.length} tasks`}
377
- >
378
- {columnTasks.length}
379
- </span>
380
- }
381
- >
382
- <Stack gap={2} className="tasks-wave3__column-body">
383
- {columnTasks.length === 0 ? (
384
- <div className="tasks-wave3__column-empty">No tasks</div>
385
- ) : (
386
- columnTasks.map((t) => (
387
- <TaskRow
388
- key={t.id}
389
- task={t}
390
- column={col}
391
- onTaskClick={handleTaskClick}
392
- onEdit={() => openEditTaskModal(modal, toast, t, setTasks, reload, refreshSnapshot)}
393
- onDelete={() => deleteTask(t.id)}
394
- onRetry={() => retryTask(t.id)}
395
- onSubmitToOdin={() => submitToOdin(t.id)}
396
- tick={tick}
397
- />
398
- ))
399
- )}
400
- </Stack>
401
- </Panel>
402
- );
403
- })}
404
- </Grid>
405
- )}
406
- </div>
407
- );
408
- }
409
-
410
- // ─── Row ─────────────────────────────────────────────────────────────────
411
-
412
- type RowProps = {
413
- task: Task;
414
- column: (typeof COLUMNS)[number];
415
- onTaskClick: (task: Task) => void;
416
- onEdit: () => void;
417
- onDelete: () => void;
418
- onRetry: () => void;
419
- onSubmitToOdin: () => void;
420
- tick: number;
421
- };
422
-
423
- function TaskRow({
424
- task,
425
- column,
426
- onTaskClick,
427
- onEdit,
428
- onDelete,
429
- onRetry,
430
- onSubmitToOdin,
431
- tick,
432
- }: RowProps) {
433
- const assignedAgent = task.workedBy || task.assignee || null;
434
- const priority: PriorityKind = (PRIORITIES as readonly string[]).includes(task.priority as string)
435
- ? (task.priority as PriorityKind)
436
- : 'normal';
437
- return (
438
- <div
439
- className={cx('tasks-wave3__row')}
440
- data-task-id={task.id}
441
- data-tick={tick}
442
- role="button"
443
- tabIndex={0}
444
- onClick={() => onTaskClick(task)}
445
- onKeyDown={(e) => {
446
- if (e.key === 'Enter' || e.key === ' ') {
447
- e.preventDefault();
448
- onTaskClick(task);
449
- }
450
- }}
451
- >
452
- <div className="tasks-wave3__row-title-row">
453
- <div className="tasks-wave3__row-title" title={task.title}>
454
- {task.title}
455
- </div>
456
- <Badge variant={STATUS_BADGE[column.kind]} size="sm" aria-label={`Status ${column.label}`}>
457
- {column.label}
458
- </Badge>
459
- </div>
460
-
461
- <Inline gap={1} align="center" className="tasks-wave3__row-badges">
462
- <Badge variant={PRIORITY_BADGE[priority]} size="sm">
463
- {priority}
464
- </Badge>
465
- {assignedAgent && (
466
- <Badge variant="neutral" size="sm">
467
- <Bot size={10} aria-hidden /> @{assignedAgent}
468
- </Badge>
469
- )}
470
- {(task.tags || []).slice(0, 2).map((tag) => (
471
- <Badge key={tag} variant="neutral" size="sm">
472
- #{tag}
473
- </Badge>
474
- ))}
475
- </Inline>
476
-
477
- <div className="tasks-wave3__row-footer">
478
- <span className="tasks-wave3__row-time">{formatRelative(task.createdAt)}</span>
479
- <Inline
480
- gap={1}
481
- align="center"
482
- className="tasks-wave3__row-actions"
483
- onClick={(e) => e.stopPropagation()}
484
- >
485
- <IconButton
486
- variant="ghost"
487
- size="sm"
488
- icon={<Edit2 size={12} aria-hidden />}
489
- aria-label="Edit task"
490
- title="Edit"
491
- onClick={onEdit}
492
- />
493
- <IconButton
494
- variant="ghost"
495
- size="sm"
496
- icon={<Send size={12} aria-hidden />}
497
- aria-label="Submit to Odin"
498
- title="Re-delegate to Odin"
499
- onClick={onSubmitToOdin}
500
- />
501
- <IconButton
502
- variant="ghost"
503
- size="sm"
504
- icon={<RotateCw size={12} aria-hidden />}
505
- aria-label="Retry task"
506
- title="Retry"
507
- onClick={onRetry}
508
- />
509
- <IconButton
510
- variant="danger"
511
- size="sm"
512
- icon={<Trash2 size={12} aria-hidden />}
513
- aria-label="Delete task"
514
- title="Delete"
515
- onClick={onDelete}
516
- />
517
- </Inline>
518
- </div>
519
- </div>
520
- );
521
- }
522
-
523
- // ─── Create / Edit modal ───────────────────────────────────────────────────
524
- //
525
- // Simplified: title, description, priority hint, optional tags. NO
526
- // agent dropdown. The store will default `assignee` and `workedBy` to
527
- // null; the orchestrator sets them when it picks the task up.
528
-
529
- function openCreateTaskModal(
530
- modal: ReturnType<typeof useModal>,
531
- toast: ReturnType<typeof useToast>,
532
- setTasks: (updater: (cur: Task[]) => Task[]) => void,
533
- reload: () => Promise<void>,
534
- refreshSnapshot: () => Promise<void>,
535
- ) {
536
- let titleEl: HTMLInputElement | null = null;
537
- let descEl: HTMLTextAreaElement | null = null;
538
- let tagsEl: HTMLInputElement | null = null;
539
- let priorityEl: HTMLSelectElement | null = null;
540
-
541
- const submit = async (e?: React.SyntheticEvent) => {
542
- if (e && typeof e.preventDefault === 'function') e.preventDefault();
543
- const title = (titleEl?.value || '').trim();
544
- const description = (descEl?.value || '').trim();
545
- if (!title) {
546
- toast.warning('Title is required.');
547
- titleEl?.focus();
548
- return;
549
- }
550
- const priority = (priorityEl?.value || 'normal') as PriorityKind;
551
- const tags = (tagsEl?.value || '')
552
- .split(',')
553
- .map((s) => s.trim())
554
- .filter(Boolean);
555
-
556
- try {
557
- const created = await api.post<Task>('/tasks', {
558
- title,
559
- description,
560
- priority,
561
- tags,
562
- // No assignee / agent — Odin decides.
563
- });
564
- modal.close();
565
- // Synthetic mousedown is intentional: it signals any open outside-
566
- // click listeners (e.g. WorkspaceSelector, Notifications popover)
567
- // that another surface has just stolen focus, so they collapse
568
- // before the toast overlays the layout. The event carries no
569
- // coordinates by design — those listeners only check the dispatch.
570
- if (typeof window !== 'undefined') {
571
- window.dispatchEvent(new MouseEvent('mousedown'));
572
- }
573
- setTasks((cur) => [created, ...cur]);
574
- toast.success('Task created.', 1200);
575
- await refreshSnapshot();
576
- } catch (err) {
577
- toast.error(`Create failed: ${(err as Error).message}`);
578
- }
579
- };
580
-
581
- const onTitleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
582
- if (e.key === 'Enter' && !e.shiftKey) {
583
- e.preventDefault();
584
- submit(e);
585
- }
586
- };
587
-
588
- modal.open({
589
- title: 'New task',
590
- width: 520,
591
- children: (
592
- <div className="task-form">
593
- <label className="field-label" htmlFor="task-title">Title *</label>
594
- <input
595
- ref={(el) => { titleEl = el; }}
596
- id="task-title"
597
- className="input"
598
- type="text"
599
- maxLength={200}
600
- placeholder="What needs to be done?"
601
- autoFocus
602
- onKeyDown={onTitleKeyDown}
603
- />
604
- <label className="field-label" htmlFor="task-desc">Description</label>
605
- <div style={{ display: 'flex', gap: 6, alignItems: 'flex-start' }}>
606
- <textarea
607
- ref={(el) => { descEl = el; }}
608
- id="task-desc"
609
- className="textarea"
610
- rows={4}
611
- placeholder="Add any context Odin might need (markdown ok)…"
612
- style={{ flex: 1 }}
613
- />
614
- <button
615
- type="button"
616
- className="btn btn-ghost btn-icon"
617
- title="Enhance with AI"
618
- onClick={async () => {
619
- if (!descEl?.value?.trim()) return;
620
- const enhanced = await enhancePrompt(descEl.value);
621
- if (enhanced !== descEl.value) descEl.value = enhanced;
622
- }}
623
- >
624
-
625
- </button>
626
- </div>
627
- <div className="task-form-row">
628
- <label htmlFor="task-priority" className="task-form-field">
629
- Priority hint
630
- <select
631
- ref={(el) => { priorityEl = el; }}
632
- id="task-priority"
633
- className="select"
634
- defaultValue="normal"
635
- >
636
- {PRIORITIES.map((p) => (
637
- <option key={p} value={p}>{p}</option>
638
- ))}
639
- </select>
640
- </label>
641
- <label htmlFor="task-tags" className="task-form-field" style={{ flex: 2 }}>
642
- Tags <span className="field-hint">(comma-separated)</span>
643
- <input
644
- ref={(el) => { tagsEl = el; }}
645
- id="task-tags"
646
- className="input"
647
- type="text"
648
- placeholder="bug, frontend, urgent"
649
- />
650
- </label>
651
- </div>
652
- <p className="muted text-sm" style={{ marginTop: 8 }}>
653
- The agent and final priority are decided by Odin after you submit.
654
- </p>
655
- </div>
656
- ),
657
- footer: (
658
- <div className="modal-footer-actions">
659
- <Button variant="ghost" onClick={() => modal.close()}>Cancel</Button>
660
- <Button variant="primary" type="button" onClick={(e) => submit(e)}>
661
- <Plus size={14} /> Create task
662
- </Button>
663
- </div>
664
- ),
665
- });
666
- }
667
-
668
- function openEditTaskModal(
669
- modal: ReturnType<typeof useModal>,
670
- toast: ReturnType<typeof useToast>,
671
- task: Task,
672
- setTasks: (updater: (cur: Task[]) => Task[]) => void,
673
- reload: () => Promise<void>,
674
- refreshSnapshot: () => Promise<void>,
675
- ) {
676
- let titleEl: HTMLInputElement | null = null;
677
- let descEl: HTMLTextAreaElement | null = null;
678
- let tagsEl: HTMLInputElement | null = null;
679
- let priorityEl: HTMLSelectElement | null = null;
680
-
681
- const submit = async () => {
682
- const title = (titleEl?.value || '').trim();
683
- const description = (descEl?.value || '').trim();
684
- if (!title) {
685
- toast.warning('Title is required.');
686
- titleEl?.focus();
687
- return;
688
- }
689
- const priority = (priorityEl?.value || 'normal') as PriorityKind;
690
- const tags = (tagsEl?.value || '')
691
- .split(',')
692
- .map((s) => s.trim())
693
- .filter(Boolean);
694
-
695
- try {
696
- const updated = await api.put<Task>(`/tasks/${encodeURIComponent(task.id)}`, {
697
- title,
698
- description,
699
- priority,
700
- tags,
701
- });
702
- modal.close();
703
- // Synthetic mousedown is intentional: it signals any open outside-
704
- // click listeners (e.g. WorkspaceSelector, Notifications popover)
705
- // that another surface has just stolen focus, so they collapse
706
- // before the toast overlays the layout. The event carries no
707
- // coordinates by design — those listeners only check the dispatch.
708
- if (typeof window !== 'undefined') {
709
- window.dispatchEvent(new MouseEvent('mousedown'));
710
- }
711
- setTasks((cur) => cur.map((x) => (x.id === task.id ? updated : x)));
712
- toast.success('Task updated.', 1200);
713
- await refreshSnapshot();
714
- } catch (err) {
715
- toast.error(`Save failed: ${(err as Error).message}`);
716
- }
717
- };
718
-
719
- modal.open({
720
- title: 'Edit task',
721
- width: 520,
722
- children: (
723
- <div className="task-form">
724
- <label className="field-label" htmlFor="edit-task-title">Title *</label>
725
- <input
726
- ref={(el) => { titleEl = el; }}
727
- id="edit-task-title"
728
- className="input"
729
- type="text"
730
- maxLength={200}
731
- defaultValue={task.title}
732
- autoFocus
733
- />
734
- <label className="field-label" htmlFor="edit-task-desc">Description</label>
735
- <textarea
736
- ref={(el) => { descEl = el; }}
737
- id="edit-task-desc"
738
- className="textarea"
739
- rows={4}
740
- defaultValue={task.description || ''}
741
- />
742
- <div className="task-form-row">
743
- <label htmlFor="edit-task-priority" className="task-form-field">
744
- Priority hint
745
- <select
746
- ref={(el) => { priorityEl = el; }}
747
- id="edit-task-priority"
748
- className="select"
749
- defaultValue={task.priority || 'normal'}
750
- >
751
- {PRIORITIES.map((p) => (
752
- <option key={p} value={p}>{p}</option>
753
- ))}
754
- </select>
755
- </label>
756
- <label htmlFor="edit-task-tags" className="task-form-field" style={{ flex: 2 }}>
757
- Tags
758
- <input
759
- ref={(el) => { tagsEl = el; }}
760
- id="edit-task-tags"
761
- className="input"
762
- type="text"
763
- defaultValue={(task.tags || []).join(', ')}
764
- placeholder="comma-separated"
765
- />
766
- </label>
767
- </div>
768
- <Card>
769
- <CardTitle><TagIcon size={12} /> Status</CardTitle>
770
- <CardMeta>
771
- Current: <strong>{task.status}</strong>
772
- {task.workedBy && <> · Worked by @{task.workedBy}</>}
773
- {task.assignee && !task.workedBy && <> · Assigned @{task.assignee}</>}
774
- </CardMeta>
775
- </Card>
776
- </div>
777
- ),
778
- footer: (
779
- <div className="modal-footer-actions">
780
- <Button variant="ghost" onClick={() => modal.close()}>Cancel</Button>
781
- <Button variant="primary" onClick={submit}>
782
- <ArchiveRestore size={14} /> Save
783
- </Button>
784
- </div>
785
- ),
786
- });
787
- }
788
-
789
- export const Tasks = React.memo(TasksInner);