@parhelia/core 0.1.12350 → 0.1.12390

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 (252) hide show
  1. package/dist/agents-view/AgentsView.js +1 -1
  2. package/dist/agents-view/AgentsView.js.map +1 -1
  3. package/dist/components/ui/LanguageSelector.js +1 -3
  4. package/dist/components/ui/LanguageSelector.js.map +1 -1
  5. package/dist/components/ui/dialog.js +1 -1
  6. package/dist/components/ui/dialog.js.map +1 -1
  7. package/dist/config/config.js +56 -16
  8. package/dist/config/config.js.map +1 -1
  9. package/dist/config/notificationRoutes.js +10 -0
  10. package/dist/config/notificationRoutes.js.map +1 -1
  11. package/dist/config/types/workspace.d.ts +6 -0
  12. package/dist/config/types.d.ts +2 -5
  13. package/dist/editor/Editor.js +11 -4
  14. package/dist/editor/Editor.js.map +1 -1
  15. package/dist/editor/FieldListField.js +6 -4
  16. package/dist/editor/FieldListField.js.map +1 -1
  17. package/dist/editor/ai/AgentCostDisplay.d.ts +1 -0
  18. package/dist/editor/ai/AgentCostDisplay.js +1 -1
  19. package/dist/editor/ai/AgentCostDisplay.js.map +1 -1
  20. package/dist/editor/ai/AgentTerminal.js +144 -36
  21. package/dist/editor/ai/AgentTerminal.js.map +1 -1
  22. package/dist/editor/ai/AgentTerminalStatusBar.d.ts +2 -0
  23. package/dist/editor/ai/AgentTerminalStatusBar.js +22 -37
  24. package/dist/editor/ai/AgentTerminalStatusBar.js.map +1 -1
  25. package/dist/editor/ai/AiResponseMessage.js +0 -1
  26. package/dist/editor/ai/AiResponseMessage.js.map +1 -1
  27. package/dist/editor/ai/ContentInspectorPopover.d.ts +17 -0
  28. package/dist/editor/ai/ContentInspectorPopover.js +136 -0
  29. package/dist/editor/ai/ContentInspectorPopover.js.map +1 -0
  30. package/dist/editor/ai/ContextInfoBar.js +55 -2
  31. package/dist/editor/ai/ContextInfoBar.js.map +1 -1
  32. package/dist/editor/ai/InlineAiDialog.js +1 -7
  33. package/dist/editor/ai/InlineAiDialog.js.map +1 -1
  34. package/dist/editor/ai/ToolCallDisplay.d.ts +4 -0
  35. package/dist/editor/ai/ToolCallDisplay.js +43 -8
  36. package/dist/editor/ai/ToolCallDisplay.js.map +1 -1
  37. package/dist/editor/ai/dialogs/AgentDialogHandler.js +46 -22
  38. package/dist/editor/ai/dialogs/AgentDialogHandler.js.map +1 -1
  39. package/dist/editor/client/EditorShell.js +69 -26
  40. package/dist/editor/client/EditorShell.js.map +1 -1
  41. package/dist/editor/client/editContext.d.ts +3 -2
  42. package/dist/editor/client/hooks/useQuota.d.ts +2 -1
  43. package/dist/editor/client/hooks/useQuota.js.map +1 -1
  44. package/dist/editor/client/hooks/useSocketMessageHandler.js +28 -0
  45. package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -1
  46. package/dist/editor/client/operations.d.ts +1 -0
  47. package/dist/editor/client/operations.js +67 -15
  48. package/dist/editor/client/operations.js.map +1 -1
  49. package/dist/editor/client/waitForEditOperationTerminal.d.ts +11 -0
  50. package/dist/editor/client/waitForEditOperationTerminal.js +40 -0
  51. package/dist/editor/client/waitForEditOperationTerminal.js.map +1 -0
  52. package/dist/editor/commands/commands.d.ts +11 -1
  53. package/dist/editor/commands/commands.js +12 -1
  54. package/dist/editor/commands/commands.js.map +1 -1
  55. package/dist/editor/commands/customCommandConverter.d.ts +8 -1
  56. package/dist/editor/commands/customCommandConverter.js +33 -4
  57. package/dist/editor/commands/customCommandConverter.js.map +1 -1
  58. package/dist/editor/commands/handlers/uiActionHandlers.d.ts +6 -0
  59. package/dist/editor/commands/handlers/uiActionHandlers.js +84 -0
  60. package/dist/editor/commands/handlers/uiActionHandlers.js.map +1 -0
  61. package/dist/editor/commands/itemCommands.js +6 -2
  62. package/dist/editor/commands/itemCommands.js.map +1 -1
  63. package/dist/editor/commands/keyboardCommands.d.ts +10 -0
  64. package/dist/editor/commands/keyboardCommands.js +142 -0
  65. package/dist/editor/commands/keyboardCommands.js.map +1 -0
  66. package/dist/editor/commands/undo.d.ts +9 -15
  67. package/dist/editor/commands/undo.js +24 -0
  68. package/dist/editor/commands/undo.js.map +1 -1
  69. package/dist/editor/menubar/PageSelector.js +1 -3
  70. package/dist/editor/menubar/PageSelector.js.map +1 -1
  71. package/dist/editor/menubar/VersionSelector.js +1 -3
  72. package/dist/editor/menubar/VersionSelector.js.map +1 -1
  73. package/dist/editor/menubar/toolbar-sections/CustomCommandsToolbar.js +7 -36
  74. package/dist/editor/menubar/toolbar-sections/CustomCommandsToolbar.js.map +1 -1
  75. package/dist/editor/menubar/toolbar-sections/UtilityControls.js +10 -1
  76. package/dist/editor/menubar/toolbar-sections/UtilityControls.js.map +1 -1
  77. package/dist/editor/notifications/notificationRoutes.js +1 -0
  78. package/dist/editor/notifications/notificationRoutes.js.map +1 -1
  79. package/dist/editor/page-editor-chrome/InlineEditor.js +53 -36
  80. package/dist/editor/page-editor-chrome/InlineEditor.js.map +1 -1
  81. package/dist/editor/page-viewer/PageViewer.js +60 -6
  82. package/dist/editor/page-viewer/PageViewer.js.map +1 -1
  83. package/dist/editor/reviews/Comment.js +12 -10
  84. package/dist/editor/reviews/Comment.js.map +1 -1
  85. package/dist/editor/reviews/CommentDisplayPopover.js +1 -3
  86. package/dist/editor/reviews/CommentDisplayPopover.js.map +1 -1
  87. package/dist/editor/reviews/PreviewInfo.js +1 -4
  88. package/dist/editor/reviews/PreviewInfo.js.map +1 -1
  89. package/dist/editor/reviews/reviewCommands.js +4 -1
  90. package/dist/editor/reviews/reviewCommands.js.map +1 -1
  91. package/dist/editor/reviews/useReviews.d.ts +2 -2
  92. package/dist/editor/reviews/useReviews.js +12 -30
  93. package/dist/editor/reviews/useReviews.js.map +1 -1
  94. package/dist/editor/services/agentService.d.ts +26 -0
  95. package/dist/editor/services/agentService.js +41 -0
  96. package/dist/editor/services/agentService.js.map +1 -1
  97. package/dist/editor/services/aiService.d.ts +7 -1
  98. package/dist/editor/services/aiService.js +13 -1
  99. package/dist/editor/services/aiService.js.map +1 -1
  100. package/dist/editor/services/notificationService.d.ts +1 -0
  101. package/dist/editor/services/notificationService.js +1 -0
  102. package/dist/editor/services/notificationService.js.map +1 -1
  103. package/dist/editor/services/reviewsService.d.ts +2 -5
  104. package/dist/editor/services/reviewsService.js +0 -10
  105. package/dist/editor/services/reviewsService.js.map +1 -1
  106. package/dist/editor/services/systemService.d.ts +2 -1
  107. package/dist/editor/services/systemService.js +3 -0
  108. package/dist/editor/services/systemService.js.map +1 -1
  109. package/dist/editor/settings/QuotaInfo.js +15 -7
  110. package/dist/editor/settings/QuotaInfo.js.map +1 -1
  111. package/dist/editor/settings/index/useIndexStatus.js +1 -1
  112. package/dist/editor/settings/index/useIndexStatus.js.map +1 -1
  113. package/dist/editor/settings/panels/AgentProfileConfigPanel.d.ts +10 -0
  114. package/dist/editor/settings/panels/AgentProfileConfigPanel.js +61 -0
  115. package/dist/editor/settings/panels/AgentProfileConfigPanel.js.map +1 -0
  116. package/dist/editor/settings/panels/AgentsPanel.d.ts +0 -4
  117. package/dist/editor/settings/panels/AgentsPanel.js +101 -109
  118. package/dist/editor/settings/panels/AgentsPanel.js.map +1 -1
  119. package/dist/editor/settings/panels/CreateAgentProfileDialog.d.ts +7 -0
  120. package/dist/editor/settings/panels/CreateAgentProfileDialog.js +48 -0
  121. package/dist/editor/settings/panels/CreateAgentProfileDialog.js.map +1 -0
  122. package/dist/editor/settings/panels/GroupedFieldConfigPanel.d.ts +33 -0
  123. package/dist/editor/settings/panels/GroupedFieldConfigPanel.js +91 -0
  124. package/dist/editor/settings/panels/GroupedFieldConfigPanel.js.map +1 -0
  125. package/dist/editor/settings/panels/ModelConfigPanel.d.ts +10 -0
  126. package/dist/editor/settings/panels/ModelConfigPanel.js +51 -0
  127. package/dist/editor/settings/panels/ModelConfigPanel.js.map +1 -0
  128. package/dist/editor/settings/panels/ModelsPanel.js +201 -70
  129. package/dist/editor/settings/panels/ModelsPanel.js.map +1 -1
  130. package/dist/editor/settings/panels/ProjectTemplateAgentPanel.d.ts +10 -0
  131. package/dist/editor/settings/panels/ProjectTemplateAgentPanel.js +46 -0
  132. package/dist/editor/settings/panels/ProjectTemplateAgentPanel.js.map +1 -0
  133. package/dist/editor/settings/panels/ProjectTemplatesPanel.d.ts +2 -0
  134. package/dist/editor/settings/panels/ProjectTemplatesPanel.js +1340 -0
  135. package/dist/editor/settings/panels/ProjectTemplatesPanel.js.map +1 -0
  136. package/dist/editor/settings/panels/ProviderConfigPanel.d.ts +10 -0
  137. package/dist/editor/settings/panels/ProviderConfigPanel.js +32 -0
  138. package/dist/editor/settings/panels/ProviderConfigPanel.js.map +1 -0
  139. package/dist/editor/settings/panels/ProvidersPanel.js +46 -4
  140. package/dist/editor/settings/panels/ProvidersPanel.js.map +1 -1
  141. package/dist/editor/settings/panels/SearchConfigPanel.js +3 -3
  142. package/dist/editor/settings/panels/SearchConfigPanel.js.map +1 -1
  143. package/dist/editor/settings/panels/index.d.ts +1 -2
  144. package/dist/editor/settings/panels/index.js +1 -2
  145. package/dist/editor/settings/panels/index.js.map +1 -1
  146. package/dist/editor/sidebar/WorkspaceRailMobile.d.ts +1 -3
  147. package/dist/editor/sidebar/WorkspaceRailMobile.js +3 -5
  148. package/dist/editor/sidebar/WorkspaceRailMobile.js.map +1 -1
  149. package/dist/editor/ui/ItemNameDialogNew.js +15 -9
  150. package/dist/editor/ui/ItemNameDialogNew.js.map +1 -1
  151. package/dist/editor/utils/keyboardNavigation.d.ts +6 -20
  152. package/dist/editor/utils/keyboardNavigation.js +48 -139
  153. package/dist/editor/utils/keyboardNavigation.js.map +1 -1
  154. package/dist/revision.d.ts +2 -2
  155. package/dist/revision.js +2 -2
  156. package/dist/setup/services/setupWizardService.d.ts +8 -10
  157. package/dist/setup/services/setupWizardService.js +4 -17
  158. package/dist/setup/services/setupWizardService.js.map +1 -1
  159. package/dist/splash-screen/ModernSplashScreen.js +100 -18
  160. package/dist/splash-screen/ModernSplashScreen.js.map +1 -1
  161. package/dist/splash-screen/ParheliaAssistantChat.js +3 -22
  162. package/dist/splash-screen/ParheliaAssistantChat.js.map +1 -1
  163. package/dist/splash-screen/ParheliaLogo.js +87 -37
  164. package/dist/splash-screen/ParheliaLogo.js.map +1 -1
  165. package/dist/task-board/TaskBoardWorkspace.js +201 -66
  166. package/dist/task-board/TaskBoardWorkspace.js.map +1 -1
  167. package/dist/task-board/components/AssignAgentDialog.js +9 -4
  168. package/dist/task-board/components/AssignAgentDialog.js.map +1 -1
  169. package/dist/task-board/components/CreateProjectDialog.js +32 -34
  170. package/dist/task-board/components/CreateProjectDialog.js.map +1 -1
  171. package/dist/task-board/components/CreateTaskDialog.d.ts +2 -0
  172. package/dist/task-board/components/CreateTaskDialog.js +35 -11
  173. package/dist/task-board/components/CreateTaskDialog.js.map +1 -1
  174. package/dist/task-board/components/ProjectPropertiesPanel.js +7 -4
  175. package/dist/task-board/components/ProjectPropertiesPanel.js.map +1 -1
  176. package/dist/task-board/components/TaskAgentPanel.js +13 -4
  177. package/dist/task-board/components/TaskAgentPanel.js.map +1 -1
  178. package/dist/task-board/components/TaskAssigneePicker.d.ts +2 -2
  179. package/dist/task-board/components/TaskAssigneePicker.js +12 -4
  180. package/dist/task-board/components/TaskAssigneePicker.js.map +1 -1
  181. package/dist/task-board/components/TaskAttachmentsSection.js +1 -1
  182. package/dist/task-board/components/TaskAttachmentsSection.js.map +1 -1
  183. package/dist/task-board/components/TaskBoardProjectListSidebar.js.map +1 -1
  184. package/dist/task-board/components/TaskBoardTitlebar.js +1 -1
  185. package/dist/task-board/components/TaskBoardTitlebar.js.map +1 -1
  186. package/dist/task-board/components/TaskCard.js +2 -2
  187. package/dist/task-board/components/TaskCard.js.map +1 -1
  188. package/dist/task-board/components/TaskDetailPanel.js +2 -2
  189. package/dist/task-board/components/TaskDetailPanel.js.map +1 -1
  190. package/dist/task-board/components/TaskRow.js +2 -2
  191. package/dist/task-board/components/TaskRow.js.map +1 -1
  192. package/dist/task-board/components/WizardCommunicationCenter.d.ts +2 -0
  193. package/dist/task-board/components/WizardCommunicationCenter.js +19 -8
  194. package/dist/task-board/components/WizardCommunicationCenter.js.map +1 -1
  195. package/dist/task-board/components/WizardTaskDetailsPanel.js +1 -1
  196. package/dist/task-board/components/WizardTaskDetailsPanel.js.map +1 -1
  197. package/dist/task-board/index.d.ts +1 -0
  198. package/dist/task-board/index.js +1 -0
  199. package/dist/task-board/index.js.map +1 -1
  200. package/dist/task-board/services/taskService.d.ts +13 -2
  201. package/dist/task-board/services/taskService.js +26 -2
  202. package/dist/task-board/services/taskService.js.map +1 -1
  203. package/dist/task-board/types.d.ts +71 -5
  204. package/dist/task-board/views/DependencyGraphView.d.ts +39 -0
  205. package/dist/task-board/views/DependencyGraphView.js +702 -0
  206. package/dist/task-board/views/DependencyGraphView.js.map +1 -0
  207. package/dist/task-board/views/KanbanView.d.ts +0 -4
  208. package/dist/task-board/views/KanbanView.js +4 -10
  209. package/dist/task-board/views/KanbanView.js.map +1 -1
  210. package/dist/task-board/views/ListView.d.ts +0 -4
  211. package/dist/task-board/views/ListView.js +3 -9
  212. package/dist/task-board/views/ListView.js.map +1 -1
  213. package/dist/task-board/views/WizardView.js +4 -4
  214. package/dist/task-board/views/WizardView.js.map +1 -1
  215. package/dist/types.d.ts +23 -15
  216. package/package.json +11 -8
  217. package/dist/editor/settings/Setup.d.ts +0 -1
  218. package/dist/editor/settings/Setup.js +0 -211
  219. package/dist/editor/settings/Setup.js.map +0 -1
  220. package/dist/editor/settings/panels/DatabasePanel.d.ts +0 -6
  221. package/dist/editor/settings/panels/DatabasePanel.js +0 -50
  222. package/dist/editor/settings/panels/DatabasePanel.js.map +0 -1
  223. package/dist/editor/settings/setup-steps/AiSetupStep/EmbeddingsModelSection.d.ts +0 -2
  224. package/dist/editor/settings/setup-steps/AiSetupStep/EmbeddingsModelSection.js +0 -195
  225. package/dist/editor/settings/setup-steps/AiSetupStep/EmbeddingsModelSection.js.map +0 -1
  226. package/dist/editor/settings/setup-steps/AiSetupStep/index.d.ts +0 -2
  227. package/dist/editor/settings/setup-steps/AiSetupStep/index.js +0 -21
  228. package/dist/editor/settings/setup-steps/AiSetupStep/index.js.map +0 -1
  229. package/dist/editor/settings/setup-steps/AiSetupStep/provider/ProviderSection.d.ts +0 -1
  230. package/dist/editor/settings/setup-steps/AiSetupStep/provider/ProviderSection.js +0 -233
  231. package/dist/editor/settings/setup-steps/AiSetupStep/provider/ProviderSection.js.map +0 -1
  232. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersList.d.ts +0 -15
  233. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersList.js +0 -14
  234. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersList.js.map +0 -1
  235. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.d.ts +0 -1
  236. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.js +0 -94
  237. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.js.map +0 -1
  238. package/dist/editor/settings/setup-steps/AiSetupStep/types.d.ts +0 -1
  239. package/dist/editor/settings/setup-steps/AiSetupStep/types.js +0 -2
  240. package/dist/editor/settings/setup-steps/AiSetupStep/types.js.map +0 -1
  241. package/dist/editor/settings/setup-steps/AiSetupStep/utils.d.ts +0 -5
  242. package/dist/editor/settings/setup-steps/AiSetupStep/utils.js +0 -44
  243. package/dist/editor/settings/setup-steps/AiSetupStep/utils.js.map +0 -1
  244. package/dist/editor/settings/setup-steps/IndexSetupStep.d.ts +0 -2
  245. package/dist/editor/settings/setup-steps/IndexSetupStep.js +0 -36
  246. package/dist/editor/settings/setup-steps/IndexSetupStep.js.map +0 -1
  247. package/dist/editor/settings/setup-steps/SettingsSetupStep.d.ts +0 -2
  248. package/dist/editor/settings/setup-steps/SettingsSetupStep.js +0 -111
  249. package/dist/editor/settings/setup-steps/SettingsSetupStep.js.map +0 -1
  250. package/dist/editor/settings/setup-steps/SetupOverview.d.ts +0 -14
  251. package/dist/editor/settings/setup-steps/SetupOverview.js +0 -38
  252. package/dist/editor/settings/setup-steps/SetupOverview.js.map +0 -1
@@ -3,12 +3,13 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
3
3
  import { toast } from "sonner";
4
4
  import { cn } from "../lib/utils";
5
5
  import { Splitter } from "../editor/ui/Splitter";
6
- import { deleteProject, getExecutionState, getProjects, getTasks, getDependencies, runOrchestrator, triggerPlanning, updateProject, updateTask, } from "./services/taskService";
6
+ import { deleteProject, getExecutionState, getGraphLayout, getProjects, getTasks, getDependencies, runOrchestrator, triggerPlanning, updateProject, updateTask, } from "./services/taskService";
7
7
  import { getAgent, } from "../editor/services/agentService";
8
8
  import { loadAiProfiles } from "../editor/services/aiService";
9
9
  import { useEditContext } from "../editor/client/editContext";
10
10
  import { KanbanView } from "./views/KanbanView";
11
11
  import { ListView } from "./views/ListView";
12
+ import { DependencyGraphView } from "./views/DependencyGraphView";
12
13
  import { WizardView } from "./views/WizardView";
13
14
  import { SimpleTabs } from "../editor/ui/SimpleTabs";
14
15
  import { TaskDetailPanel } from "./components/TaskDetailPanel";
@@ -31,7 +32,8 @@ import { normalizeTaskStatus } from "./taskStatus";
31
32
  import { getTaskExecutionDisplay, } from "./taskExecutionStatus";
32
33
  import { indexTaskExecutionRecords, overlayTaskExecutionList, } from "./taskExecutionRecords";
33
34
  import { WizardCommunicationCenter } from "./components/WizardCommunicationCenter";
34
- import { Loader2 } from "lucide-react";
35
+ import { Button } from "../components/ui/button";
36
+ import { Loader2, Plus } from "lucide-react";
35
37
  import { MainContentTree } from "../editor/sidebar/MainContentTree";
36
38
  function TaskboardPreviewEditor({ itemDescriptor, }) {
37
39
  const slotContext = useEditorSlotContext({
@@ -55,7 +57,11 @@ function getInitialQueryValue(queryKey) {
55
57
  }
56
58
  function getInitialViewTabIndex() {
57
59
  const view = getInitialQueryValue(TASKBOARD_VIEW_QUERY_KEY)?.toLowerCase();
58
- return view === "list" ? 1 : 0;
60
+ if (view === "list")
61
+ return 1;
62
+ if (view === "graph")
63
+ return 2;
64
+ return 0;
59
65
  }
60
66
  function getInitialWizardMode() {
61
67
  const value = getInitialQueryValue(TASKBOARD_WIZARD_QUERY_KEY)?.toLowerCase();
@@ -134,6 +140,7 @@ export function TaskBoardWorkspace() {
134
140
  const [tasks, setTasks] = useState([]);
135
141
  const [isTasksLoading, setIsTasksLoading] = useState(false);
136
142
  const [dependencies, setDependencies] = useState([]);
143
+ const [graphLayout, setGraphLayout] = useState(null);
137
144
  const [executionRecordsByTaskId, setExecutionRecordsByTaskId] = useState({});
138
145
  const [selectedTaskId, setSelectedTaskId] = useState(() => getInitialQueryValue(TASKBOARD_TASK_QUERY_KEY));
139
146
  const [selectedTaskSource, setSelectedTaskSource] = useState(() => getInitialQueryValue(TASKBOARD_TASK_QUERY_KEY) ? "system" : null);
@@ -159,7 +166,7 @@ export function TaskBoardWorkspace() {
159
166
  const [contextItemNamesByKey, setContextItemNamesByKey] = useState({});
160
167
  const [contextItemPathsByKey, setContextItemPathsByKey] = useState({});
161
168
  const [wizardPinnedTaskId, setWizardPinnedTaskId] = useState(null);
162
- const [wizardPinnedTaskSource, setWizardPinnedTaskSource] = useState(null);
169
+ const [, setWizardPinnedTaskSource] = useState(null);
163
170
  const [wizardForceOverview, setWizardForceOverview] = useState(false);
164
171
  const setWizardPinnedTask = useCallback((taskId, source = null) => {
165
172
  setWizardPinnedTaskId(taskId);
@@ -180,12 +187,15 @@ export function TaskBoardWorkspace() {
180
187
  const tasksRequestCountRef = useRef(0);
181
188
  const latestTasksProjectIdRef = useRef(null);
182
189
  const latestDependenciesProjectIdRef = useRef(null);
190
+ const latestGraphLayoutProjectIdRef = useRef(null);
183
191
  const latestSubprojectCountsProjectIdRef = useRef(null);
184
192
  const refreshProjectsRef = useRef(null);
185
193
  const refreshTasksRef = useRef(null);
186
194
  const refreshExecutionStateRef = useRef(null);
187
195
  const refreshDependenciesRef = useRef(null);
196
+ const refreshGraphLayoutRef = useRef(null);
188
197
  const refreshSubprojectTaskCountsRef = useRef(null);
198
+ const projectsRef = useRef([]);
189
199
  const selectedProjectIdRef = useRef(null);
190
200
  const directSubprojectIdsRef = useRef(new Set());
191
201
  const tasksRef = useRef([]);
@@ -200,6 +210,23 @@ export function TaskBoardWorkspace() {
200
210
  setIsWizardMode(nextState.isWizardMode);
201
211
  setWizardForceOverview(false);
202
212
  }, [setTaskSelection]);
213
+ const isProjectWithinSelectedTree = useCallback((projectId, currentProjectId) => {
214
+ if (projectId === currentProjectId)
215
+ return true;
216
+ const parentByProjectId = new Map();
217
+ for (const project of projectsRef.current) {
218
+ parentByProjectId.set(project.project.projectId, project.project.parentProjectId ?? null);
219
+ }
220
+ const visited = new Set();
221
+ let cursor = parentByProjectId.get(projectId) ?? null;
222
+ while (cursor && !visited.has(cursor)) {
223
+ if (cursor === currentProjectId)
224
+ return true;
225
+ visited.add(cursor);
226
+ cursor = parentByProjectId.get(cursor) ?? null;
227
+ }
228
+ return false;
229
+ }, []);
203
230
  useEffect(() => {
204
231
  let cancelled = false;
205
232
  loadAiProfiles()
@@ -345,8 +372,15 @@ export function TaskBoardWorkspace() {
345
372
  const canCreate = selectedProject?.permission === "Owner" ||
346
373
  selectedProject?.permission === "Editor";
347
374
  const canEditTasks = canCreate;
348
- const viewTabIds = useMemo(() => ["kanban", "list"], []);
375
+ const viewTabs = useMemo(() => [
376
+ { id: "kanban", label: "Kanban", content: null },
377
+ { id: "list", label: "List", content: null },
378
+ { id: "graph", label: "Graph", content: null },
379
+ ], []);
380
+ const viewTabIds = useMemo(() => ["kanban", "list", "graph"], []);
349
381
  const isListView = viewTabIds[activeTab] === "list";
382
+ const isGraphView = viewTabIds[activeTab] === "graph";
383
+ const sharedViewSwitcher = useMemo(() => (_jsxs("div", { className: "flex items-center justify-end gap-2", children: [_jsx(SimpleTabs, { tabs: viewTabs, activeTab: activeTab, setActiveTab: setActiveTab, hideContent: true, className: "rounded-lg border-0 bg-slate-100/50 p-1" }), _jsxs(Button, { size: "sm", onClick: () => setCreateDialogOpen(true), disabled: !canEditTasks, className: "h-8 px-3", "data-testid": "taskboard-create-task-button", children: [_jsx(Plus, { className: "h-4 w-4 sm:mr-1.5" }), _jsx("span", { className: "hidden sm:inline", children: "New Task" })] })] })), [activeTab, canEditTasks, viewTabs]);
350
384
  const handleSelectProject = useCallback((projectId) => {
351
385
  setSelectedProjectId((previousProjectId) => {
352
386
  if (previousProjectId !== projectId) {
@@ -359,6 +393,7 @@ export function TaskBoardWorkspace() {
359
393
  const clearSelectedProjectData = useCallback(() => {
360
394
  setTasks([]);
361
395
  setDependencies([]);
396
+ setGraphLayout(null);
362
397
  setExecutionRecordsByTaskId({});
363
398
  setSubprojectTaskCounts({});
364
399
  setSubprojectTasksByProjectId({});
@@ -374,9 +409,6 @@ export function TaskBoardWorkspace() {
374
409
  return selectedProject;
375
410
  return (projects.find((project) => project.project.projectId === selectedTask.projectId) ?? selectedProject);
376
411
  }, [projects, selectedProject, selectedTask]);
377
- const planningTask = useMemo(() => tasksWithDisplayAssignees.find((t) => String(t.taskType ?? "").toLowerCase() === "plan") ??
378
- tasksWithDisplayAssignees.find((t) => t.title === "Project Plan") ??
379
- null, [tasksWithDisplayAssignees]);
380
412
  const selectedTaskIsPlan = useMemo(() => {
381
413
  const taskType = String(selectedTask?.taskType ?? "").toLowerCase();
382
414
  return taskType === "plan" || selectedTask?.title === "Project Plan";
@@ -673,7 +705,7 @@ export function TaskBoardWorkspace() {
673
705
  if (typeof window === "undefined")
674
706
  return;
675
707
  const current = new URLSearchParams(window.location.search);
676
- const view = activeTab === 1 ? "list" : "kanban";
708
+ const view = viewTabIds[activeTab] ?? "kanban";
677
709
  if (selectedProjectId) {
678
710
  current.set(TASKBOARD_PROJECT_QUERY_KEY, selectedProjectId);
679
711
  }
@@ -702,7 +734,7 @@ export function TaskBoardWorkspace() {
702
734
  if (newUrl !== oldUrl) {
703
735
  window.history.replaceState(null, "", newUrl);
704
736
  }
705
- }, [selectedProjectId, selectedTaskId, activeTab, isWizardMode]);
737
+ }, [selectedProjectId, selectedTaskId, activeTab, isWizardMode, viewTabIds]);
706
738
  useEffect(() => {
707
739
  const handlePopState = () => {
708
740
  syncTaskBoardStateFromUrl();
@@ -743,6 +775,19 @@ export function TaskBoardWorkspace() {
743
775
  const indexed = indexTaskExecutionRecords(records);
744
776
  setExecutionRecordsByTaskId(indexed);
745
777
  }, []);
778
+ const refreshGraphLayout = useCallback(async (projectId) => {
779
+ latestGraphLayoutProjectIdRef.current = projectId;
780
+ const requestProjectId = projectId;
781
+ const result = await getGraphLayout(projectId);
782
+ if (latestGraphLayoutProjectIdRef.current !== requestProjectId) {
783
+ return;
784
+ }
785
+ if (result.type !== "success") {
786
+ toast.error(result.summary || "Failed to load graph layout");
787
+ return;
788
+ }
789
+ setGraphLayout(result.data ?? null);
790
+ }, []);
746
791
  const refreshSubprojectTaskCounts = useCallback(async () => {
747
792
  const requestProjectId = selectedProjectId;
748
793
  latestSubprojectCountsProjectIdRef.current = requestProjectId;
@@ -978,7 +1023,9 @@ export function TaskBoardWorkspace() {
978
1023
  refreshTasksRef.current = refreshTasks;
979
1024
  refreshExecutionStateRef.current = refreshExecutionState;
980
1025
  refreshDependenciesRef.current = refreshDependencies;
1026
+ refreshGraphLayoutRef.current = refreshGraphLayout;
981
1027
  refreshSubprojectTaskCountsRef.current = refreshSubprojectTaskCounts;
1028
+ projectsRef.current = projects;
982
1029
  selectedProjectIdRef.current = selectedProjectId;
983
1030
  directSubprojectIdsRef.current = new Set(directSubprojects.map((subproject) => subproject.project.projectId));
984
1031
  tasksRef.current = taskSelectionUniverse;
@@ -987,7 +1034,9 @@ export function TaskBoardWorkspace() {
987
1034
  refreshTasks,
988
1035
  refreshExecutionState,
989
1036
  refreshDependencies,
1037
+ refreshGraphLayout,
990
1038
  refreshSubprojectTaskCounts,
1039
+ projects,
991
1040
  selectedProjectId,
992
1041
  directSubprojects,
993
1042
  taskSelectionUniverse,
@@ -1236,7 +1285,7 @@ export function TaskBoardWorkspace() {
1236
1285
  if (editContext?.confirm) {
1237
1286
  editContext.confirm({
1238
1287
  header: "Delete project",
1239
- message: `Are you sure you want to delete \"${title}\"?\n\nAny subprojects under this project will also be deleted. This action cannot be undone.`,
1288
+ message: `Are you sure you want to delete "${title}"?\n\nAny subprojects under this project will also be deleted. This action cannot be undone.`,
1240
1289
  acceptLabel: "Delete",
1241
1290
  showCancel: true,
1242
1291
  accept: () => {
@@ -1275,6 +1324,7 @@ export function TaskBoardWorkspace() {
1275
1324
  handleSelectMyTask,
1276
1325
  handleSelectProject,
1277
1326
  handleRunOrchestrator,
1327
+ selectedProject,
1278
1328
  ]);
1279
1329
  useEffect(() => {
1280
1330
  return () => {
@@ -1296,10 +1346,12 @@ export function TaskBoardWorkspace() {
1296
1346
  const refreshTasksFn = refreshTasksRef.current;
1297
1347
  const refreshExecutionStateFn = refreshExecutionStateRef.current;
1298
1348
  const refreshDependenciesFn = refreshDependenciesRef.current;
1349
+ const refreshGraphLayoutFn = refreshGraphLayoutRef.current;
1299
1350
  void Promise.all([
1300
1351
  refreshTasksFn?.(selectedProjectId),
1301
1352
  refreshExecutionStateFn?.(selectedProjectId),
1302
1353
  refreshDependenciesFn?.(selectedProjectId),
1354
+ refreshGraphLayoutFn?.(selectedProjectId),
1303
1355
  ]).finally(() => {
1304
1356
  if (cancelled)
1305
1357
  return;
@@ -1369,6 +1421,53 @@ export function TaskBoardWorkspace() {
1369
1421
  return;
1370
1422
  const unsubscribe = addListener((message) => {
1371
1423
  const messageType = message?.type;
1424
+ if (messageType === "project:properties:updated") {
1425
+ const payload = message?.payload;
1426
+ const projectId = payload?.projectId ?? payload?.ProjectId;
1427
+ const currentProjectId = selectedProjectIdRef.current;
1428
+ const refreshGraphLayoutFn = refreshGraphLayoutRef.current;
1429
+ if (projectId &&
1430
+ currentProjectId &&
1431
+ projectId === currentProjectId &&
1432
+ refreshGraphLayoutFn) {
1433
+ void refreshGraphLayoutFn(projectId);
1434
+ }
1435
+ return;
1436
+ }
1437
+ if (messageType === "project:updated") {
1438
+ const payload = message?.payload;
1439
+ const projectId = payload?.projectId ?? payload?.ProjectId;
1440
+ const currentProjectId = selectedProjectIdRef.current;
1441
+ const refreshProjectsFn = refreshProjectsRef.current;
1442
+ if (!projectId ||
1443
+ !currentProjectId ||
1444
+ !refreshProjectsFn ||
1445
+ !isProjectWithinSelectedTree(projectId, currentProjectId)) {
1446
+ return;
1447
+ }
1448
+ if (wsRefreshTimeoutRef.current !== null) {
1449
+ window.clearTimeout(wsRefreshTimeoutRef.current);
1450
+ wsRefreshTimeoutRef.current = null;
1451
+ }
1452
+ wsRefreshTimeoutRef.current = window.setTimeout(() => {
1453
+ wsRefreshTimeoutRef.current = null;
1454
+ const selectedId = selectedProjectIdRef.current;
1455
+ const refreshProjectsFn = refreshProjectsRef.current;
1456
+ if (!selectedId || !refreshProjectsFn)
1457
+ return;
1458
+ void refreshProjectsFn();
1459
+ if (projectId === selectedId) {
1460
+ const refreshExecutionStateFn = refreshExecutionStateRef.current;
1461
+ if (refreshExecutionStateFn)
1462
+ void refreshExecutionStateFn(selectedId);
1463
+ return;
1464
+ }
1465
+ const refreshSubprojectsFn = refreshSubprojectTaskCountsRef.current;
1466
+ if (refreshSubprojectsFn)
1467
+ void refreshSubprojectsFn();
1468
+ }, 250);
1469
+ return;
1470
+ }
1372
1471
  if (messageType === "task:state-changed") {
1373
1472
  const payload = message?.payload;
1374
1473
  const projectId = payload?.projectId ??
@@ -1522,10 +1621,18 @@ export function TaskBoardWorkspace() {
1522
1621
  useEffect(() => {
1523
1622
  if (!selectedTaskId)
1524
1623
  return;
1624
+ if (selectedTaskSource === "system")
1625
+ return;
1525
1626
  if (!taskSelectionUniverse.some((t) => t.taskId === selectedTaskId)) {
1526
1627
  setTaskSelection(null);
1527
1628
  }
1528
- }, [isWizardMode, selectedTaskId, setTaskSelection, taskSelectionUniverse]);
1629
+ }, [
1630
+ isWizardMode,
1631
+ selectedTaskId,
1632
+ selectedTaskSource,
1633
+ setTaskSelection,
1634
+ taskSelectionUniverse,
1635
+ ]);
1529
1636
  // No special auto-selection by project status — the agent panel is driven by
1530
1637
  // whichever task the user selects.
1531
1638
  // The backend now creates the Plan task and triggers the planner agent
@@ -1578,21 +1685,20 @@ export function TaskBoardWorkspace() {
1578
1685
  clearWizardCloseTransitionTimeout();
1579
1686
  setWizardForceOverview(false);
1580
1687
  setTaskSelection(taskId, { source: "user", pinInWizard: true });
1581
- } })), [
1582
- wizardAttentionState,
1688
+ }, onOpenAgentTab: isMobile ? () => setMobileActiveTab(2) : undefined })), [
1583
1689
  wizardDisplayedTask,
1584
1690
  wizardDisplayedAgentId,
1585
1691
  wizardDisplayedExecutionDisplay,
1692
+ wizardAttentionState.summaryState,
1693
+ wizardAttentionState.stats,
1694
+ wizardTasksWithDisplayAssignees,
1695
+ dependencies,
1586
1696
  canEditTasks,
1587
- selectedProjectId,
1588
- directSubprojects,
1697
+ isMobile,
1589
1698
  refreshVisibleTaskData,
1590
- clearWizardCloseTransitionTimeout,
1591
1699
  handleCloseWizardTask,
1592
- selectedTaskId,
1593
- wizardPinnedTaskId,
1594
- selectedProject?.project.title,
1595
- selectedProject?.project.description,
1700
+ clearWizardCloseTransitionTimeout,
1701
+ setTaskSelection,
1596
1702
  ]);
1597
1703
  const isProjectViewLoading = !!selectedProjectId && projectViewLoadingId === selectedProjectId;
1598
1704
  const taskBoardContent = useMemo(() => {
@@ -1609,58 +1715,52 @@ export function TaskBoardWorkspace() {
1609
1715
  }, projectTitle: selectedProject?.project.title ?? "No project selected", projectDescription: selectedProject?.project.description, projectCostUsed: selectedProjectCumulativeCostUsed, projectCostLimit: selectedProject?.project.costLimit ?? null, canEditProperties: selectedProject?.permission === "Owner", communicationPanel: wizardCommunicationPanel }));
1610
1716
  }
1611
1717
  if (isListView) {
1612
- return (_jsxs("div", { className: "grid gap-3", children: [_jsx(ProjectDashboard, { projectId: selectedProjectId, selectedProjectTitle: selectedProject?.project.title ?? "No project selected", selectedProjectDescription: selectedProject?.project.description, selectedProjectStatus: selectedProject?.project.status, selectedProjectCostUsed: selectedProjectCumulativeCostUsed, selectedProjectCostLimit: selectedProject?.project.costLimit ?? null, canEditProjectStatus: selectedProject?.permission === "Owner", savingProjectStatus: savingProjectStatus, onStatusChange: handleProjectStatusChange, selectedProjectTaskCounts: selectedProjectTaskCounts, subprojects: directSubprojects, taskCountsByProjectId: subprojectTaskCounts, loading: subprojectCountsLoading, parentProjectId: parentProject?.project.projectId ?? null, parentProjectTitle: parentProject?.project.title ?? null, onSelectProject: handleSelectProject, canEditProperties: selectedProject?.permission === "Owner" }), _jsx(ListView, { tasks: tasksWithDisplayAssignees, onSelectTask: (id) => setTaskSelection(id, { source: "user" }), selectedTaskId: selectedTaskId, onTasksChanged: () => {
1718
+ return (_jsxs("div", { className: "grid gap-3", children: [_jsx(ProjectDashboard, { projectId: selectedProjectId, selectedProjectTitle: selectedProject?.project.title ?? "No project selected", selectedProjectDescription: selectedProject?.project.description, selectedProjectStatus: selectedProject?.project.status, selectedProjectCostUsed: selectedProjectCumulativeCostUsed, selectedProjectCostLimit: selectedProject?.project.costLimit ?? null, canEditProjectStatus: selectedProject?.permission === "Owner", savingProjectStatus: savingProjectStatus, onStatusChange: handleProjectStatusChange, selectedProjectTaskCounts: selectedProjectTaskCounts, subprojects: directSubprojects, taskCountsByProjectId: subprojectTaskCounts, loading: subprojectCountsLoading, parentProjectId: parentProject?.project.projectId ?? null, parentProjectTitle: parentProject?.project.title ?? null, onSelectProject: handleSelectProject, canEditProperties: selectedProject?.permission === "Owner" }), sharedViewSwitcher, _jsx(ListView, { tasks: tasksWithDisplayAssignees, onSelectTask: (id) => setTaskSelection(id, { source: "user" }), selectedTaskId: selectedTaskId, onTasksChanged: () => {
1613
1719
  void refreshVisibleTaskData();
1614
- }, projectId: selectedProjectId, permission: selectedProject?.permission, activeTab: activeTab, onSetActiveTab: setActiveTab, canCreateTask: canEditTasks, onCreateTask: () => setCreateDialogOpen(true) })] }));
1720
+ }, projectId: selectedProjectId, permission: selectedProject?.permission })] }));
1615
1721
  }
1616
- return (_jsxs("div", { className: "flex h-full min-h-0 min-w-0 flex-col gap-3", children: [_jsx(ProjectDashboard, { projectId: selectedProjectId, selectedProjectTitle: selectedProject?.project.title ?? "No project selected", selectedProjectDescription: selectedProject?.project.description, selectedProjectStatus: selectedProject?.project.status, selectedProjectCostUsed: selectedProjectCumulativeCostUsed, selectedProjectCostLimit: selectedProject?.project.costLimit ?? null, canEditProjectStatus: selectedProject?.permission === "Owner", savingProjectStatus: savingProjectStatus, onStatusChange: handleProjectStatusChange, selectedProjectTaskCounts: selectedProjectTaskCounts, subprojects: directSubprojects, taskCountsByProjectId: subprojectTaskCounts, loading: subprojectCountsLoading, parentProjectId: parentProject?.project.projectId ?? null, parentProjectTitle: parentProject?.project.title ?? null, onSelectProject: handleSelectProject, canEditProperties: selectedProject?.permission === "Owner" }), _jsx(KanbanView, { tasks: tasksWithDisplayAssignees, dependencies: dependencies, onSelectTask: (id) => setTaskSelection(id, { source: "user" }), selectedTaskId: selectedTaskId, onTasksChanged: () => {
1722
+ if (isGraphView) {
1723
+ return (_jsxs("div", { className: "flex h-full min-h-0 min-w-0 flex-col gap-3", children: [_jsx(ProjectDashboard, { projectId: selectedProjectId, selectedProjectTitle: selectedProject?.project.title ?? "No project selected", selectedProjectDescription: selectedProject?.project.description, selectedProjectStatus: selectedProject?.project.status, selectedProjectCostUsed: selectedProjectCumulativeCostUsed, selectedProjectCostLimit: selectedProject?.project.costLimit ?? null, canEditProjectStatus: selectedProject?.permission === "Owner", savingProjectStatus: savingProjectStatus, onStatusChange: handleProjectStatusChange, selectedProjectTaskCounts: selectedProjectTaskCounts, subprojects: directSubprojects, taskCountsByProjectId: subprojectTaskCounts, loading: subprojectCountsLoading, parentProjectId: parentProject?.project.projectId ?? null, parentProjectTitle: parentProject?.project.title ?? null, onSelectProject: handleSelectProject, canEditProperties: selectedProject?.permission === "Owner" }), sharedViewSwitcher, _jsx("div", { className: "min-h-0 flex-1", children: _jsx(DependencyGraphView, { projectId: selectedProjectId, tasks: tasksWithDisplayAssignees, dependencies: dependencies, orientation: "horizontal", savedLayout: graphLayout, selectedTaskId: selectedTaskId, onSelectTask: (id) => setTaskSelection(id, { source: "user" }), permission: selectedProject?.permission, onLayoutSaved: (layout) => setGraphLayout(layout && selectedProjectId
1724
+ ? {
1725
+ projectId: selectedProjectId,
1726
+ ...layout,
1727
+ }
1728
+ : null) }) })] }));
1729
+ }
1730
+ return (_jsxs("div", { className: "flex h-full min-h-0 min-w-0 flex-col gap-3", children: [_jsx(ProjectDashboard, { projectId: selectedProjectId, selectedProjectTitle: selectedProject?.project.title ?? "No project selected", selectedProjectDescription: selectedProject?.project.description, selectedProjectStatus: selectedProject?.project.status, selectedProjectCostUsed: selectedProjectCumulativeCostUsed, selectedProjectCostLimit: selectedProject?.project.costLimit ?? null, canEditProjectStatus: selectedProject?.permission === "Owner", savingProjectStatus: savingProjectStatus, onStatusChange: handleProjectStatusChange, selectedProjectTaskCounts: selectedProjectTaskCounts, subprojects: directSubprojects, taskCountsByProjectId: subprojectTaskCounts, loading: subprojectCountsLoading, parentProjectId: parentProject?.project.projectId ?? null, parentProjectTitle: parentProject?.project.title ?? null, onSelectProject: handleSelectProject, canEditProperties: selectedProject?.permission === "Owner" }), sharedViewSwitcher, _jsx(KanbanView, { tasks: tasksWithDisplayAssignees, dependencies: dependencies, onSelectTask: (id) => setTaskSelection(id, { source: "user" }), selectedTaskId: selectedTaskId, onTasksChanged: () => {
1617
1731
  void refreshVisibleTaskData();
1618
- }, projectId: selectedProjectId, permission: selectedProject?.permission, activeTab: activeTab, onSetActiveTab: setActiveTab, canCreateTask: canEditTasks, onCreateTask: () => setCreateDialogOpen(true) })] }));
1732
+ }, projectId: selectedProjectId, permission: selectedProject?.permission })] }));
1619
1733
  }, [
1620
1734
  isProjectViewLoading,
1621
1735
  selectedProjectId,
1622
1736
  selectedProject,
1623
- nav,
1737
+ isProjectsLoading,
1624
1738
  isWizardMode,
1625
1739
  isListView,
1626
- isTasksLoading,
1627
- isProjectsLoading,
1628
- tasksWithDisplayAssignees,
1629
- wizardSubprojectTaskLists,
1630
- selectedTaskId,
1631
- wizardDisplayedTask?.taskId,
1632
- refreshVisibleTaskData,
1633
- selectedProject?.permission,
1634
- selectedProject?.project.description,
1635
- selectedProject?.project.status,
1636
- selectedProject?.project.costLimit,
1740
+ isGraphView,
1637
1741
  selectedProjectCumulativeCostUsed,
1638
- dependencies,
1639
- directSubprojects,
1640
- parentProject?.project.projectId,
1641
- parentProject?.project.title,
1642
- selectedProject?.project.title,
1742
+ savingProjectStatus,
1743
+ handleProjectStatusChange,
1643
1744
  selectedProjectTaskCounts,
1745
+ directSubprojects,
1644
1746
  subprojectTaskCounts,
1645
1747
  subprojectCountsLoading,
1646
- wizardCommunicationPanel,
1647
- savingProjectStatus,
1648
- handleProjectStatusChange,
1649
- activeTab,
1748
+ parentProject?.project.projectId,
1749
+ parentProject?.project.title,
1650
1750
  handleSelectProject,
1651
- currentAgentId,
1652
- agentPanelMode,
1653
- selectedTaskIsPlan,
1654
- selectedTaskHasAssignedAgentProfile,
1655
- canRunAssignedAgent,
1656
- runAssignedAgentDisabledReason,
1657
- handleRunSelectedTaskAgent,
1658
- isPlanning,
1659
- handleStartPlanning,
1660
- selectedTaskIsBlocked,
1751
+ sharedViewSwitcher,
1752
+ tasksWithDisplayAssignees,
1753
+ dependencies,
1754
+ selectedTaskId,
1755
+ activeTab,
1661
1756
  canEditTasks,
1662
- selectedTask?.assigneeDisplayName,
1663
- selectedTask?.assigneeId,
1757
+ nav,
1758
+ isTasksLoading,
1759
+ wizardSubprojectTaskLists,
1760
+ wizardDisplayedTask?.taskId,
1761
+ wizardCommunicationPanel,
1762
+ setTaskSelection,
1763
+ refreshVisibleTaskData,
1664
1764
  ]);
1665
1765
  const taskDetailPanel = useMemo(() => (_jsx(TaskDetailPanel, { project: selectedTaskProject, task: selectedTask, allTasks: taskSelectionUniverse, dependencies: dependencies, onTaskChanged: () => {
1666
1766
  void refreshVisibleTaskData();
@@ -1670,6 +1770,7 @@ export function TaskBoardWorkspace() {
1670
1770
  taskSelectionUniverse,
1671
1771
  dependencies,
1672
1772
  refreshVisibleTaskData,
1773
+ setTaskSelection,
1673
1774
  ]);
1674
1775
  const agentTerminalPanel = useMemo(() => (_jsx(TaskAgentPanel, { agentId: displayAgentId, mode: agentPanelMode, label: selectedTaskIsPlan ? "Planner" : "Task Agent", hasAssignedAgentProfile: !selectedTaskIsPlan && selectedTaskHasAssignedAgentProfile, assignedAgentProfileName: !selectedTaskIsPlan && selectedTaskHasAssignedAgentProfile
1675
1776
  ? selectedTask?.assigneeDisplayName ||
@@ -1872,20 +1973,21 @@ export function TaskBoardWorkspace() {
1872
1973
  defaultSize: "auto",
1873
1974
  content: (_jsx("div", { className: "h-full min-h-0 min-w-0 overflow-hidden bg-gray-50", children: editorContent })),
1874
1975
  },
1875
- ], splitterClassName: "bg-gray-200 hover:bg-gray-300 w-[6px]", className: "h-full" }));
1976
+ ], splitterClassName: "bg-gray-200 hover:bg-gray-300 w-[6px]", className: "h-full", direction: isMobile ? "vertical" : "horizontal" }));
1876
1977
  if (!currentItemDescriptor) {
1877
1978
  return (_jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [_jsx("div", { className: "border-b border-gray-200 bg-white px-3 py-2", children: hasCurrentItem ? (_jsxs("div", { className: "min-w-0", children: [hasMultipleContextItems ? (_jsx(Select, { value: selectedContextItemValue, onValueChange: handleSelectContextItem, options: contextItemOptions, placeholder: "Select context item", size: "xs", searchable: true, className: "h-7 rounded-md bg-white", maxWidth: 420, "data-testid": "taskboard-context-item-selector" })) : (_jsx("div", { className: "truncate text-sm font-medium text-slate-900", children: previewItemName || "Loading item..." })), _jsxs("div", { className: "mt-0.5 flex items-center gap-2", children: [_jsx("span", { className: "truncate text-xs text-slate-500", children: previewItemPath || "Path unavailable" }), _jsx("span", { className: "shrink-0 rounded bg-slate-100 px-1.5 py-0.5 text-[10px] font-medium text-slate-600", children: selectedContextItemValue.split("|")[1] || "" }), previewItemVersion != null && (_jsxs("span", { className: "shrink-0 rounded bg-slate-100 px-1.5 py-0.5 text-[10px] font-medium text-slate-600", children: ["v", previewItemVersion] }))] })] })) : (_jsx("div", { className: "text-xs text-slate-500", children: "No item loaded" })) }), _jsx("div", { className: "min-h-0 flex-1 overflow-hidden bg-gray-50", children: renderPreviewSplit(_jsxs("div", { className: "flex h-full min-h-0 flex-col items-center justify-center gap-3 p-6 text-center", children: [_jsx("div", { className: "text-muted-foreground text-sm font-medium", children: "Editor preview unavailable" }), _jsx("div", { className: "text-muted-foreground text-xs", children: "Open the editor context item to preview and edit it here." })] })) })] }));
1878
1979
  }
1879
1980
  return (_jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [_jsx("div", { className: "border-b border-gray-200 bg-white px-3 py-2", children: hasCurrentItem ? (_jsxs("div", { className: "min-w-0", children: [hasMultipleContextItems ? (_jsx(Select, { value: selectedContextItemValue, onValueChange: handleSelectContextItem, options: contextItemOptions, placeholder: "Select context item", size: "xs", searchable: true, className: "h-7 rounded-md bg-white", maxWidth: 420, "data-testid": "taskboard-context-item-selector" })) : (_jsx("div", { className: "truncate text-sm font-medium text-slate-900", children: previewItemName || "Loading item..." })), _jsxs("div", { className: "mt-0.5 flex items-center gap-2", children: [_jsx("span", { className: "truncate text-xs text-slate-500", children: previewItemPath || "Path unavailable" }), _jsx("span", { className: "shrink-0 rounded bg-slate-100 px-1.5 py-0.5 text-[10px] font-medium text-slate-600", children: currentItemDescriptor?.language }), previewItemVersion != null && (_jsxs("span", { className: "shrink-0 rounded bg-slate-100 px-1.5 py-0.5 text-[10px] font-medium text-slate-600", children: ["v", previewItemVersion] }))] })] })) : (_jsx("div", { className: "text-xs text-slate-500", children: "No item loaded" })) }), _jsx("div", { className: "min-h-0 flex-1 overflow-hidden bg-gray-50", children: renderPreviewSplit(_jsx(TaskboardPreviewEditor, { itemDescriptor: currentItemDescriptor })) })] }));
1880
1981
  }, [
1881
1982
  currentItemDescriptor,
1882
- contextItemOptions,
1883
1983
  hasMultipleContextItems,
1884
- handleSelectContextItem,
1885
1984
  selectedContextItemValue,
1985
+ handleSelectContextItem,
1986
+ contextItemOptions,
1886
1987
  previewItemName,
1887
1988
  previewItemPath,
1888
1989
  previewItemVersion,
1990
+ isMobile,
1889
1991
  ]);
1890
1992
  useEffect(() => {
1891
1993
  if (!assignAgentDialogOpen)
@@ -1924,7 +2026,7 @@ export function TaskBoardWorkspace() {
1924
2026
  {
1925
2027
  name: "task-list",
1926
2028
  defaultSize: "auto",
1927
- content: (_jsx("div", { className: "h-full overflow-x-auto overflow-y-auto bg-slate-50/50 p-2 pt-2 sm:p-4 sm:pt-3", children: taskBoardContent })),
2029
+ content: (_jsx("div", { className: "h-full overflow-x-auto overflow-y-auto bg-slate-50/50 p-2 pt-2 md:p-4 md:pt-3", children: taskBoardContent })),
1928
2030
  },
1929
2031
  {
1930
2032
  name: "task-details",
@@ -1948,6 +2050,35 @@ export function TaskBoardWorkspace() {
1948
2050
  }
1949
2051
  return listPanels;
1950
2052
  }
2053
+ if (isGraphView) {
2054
+ const graphPanels = [
2055
+ {
2056
+ name: "task-list",
2057
+ defaultSize: "auto",
2058
+ content: (_jsx("div", { className: cn("flex h-full min-h-0 flex-col overflow-x-hidden overflow-y-auto bg-slate-50/50", selectedProjectId && "p-4 pt-3"), children: taskBoardContent })),
2059
+ },
2060
+ {
2061
+ name: "task-details",
2062
+ defaultSize: 420,
2063
+ content: taskDetailPanel,
2064
+ hidden: !selectedProjectId || !selectedTask,
2065
+ },
2066
+ {
2067
+ name: "agent-terminal",
2068
+ defaultSize: 560,
2069
+ content: agentTerminalPanel,
2070
+ hidden: !selectedProjectId || shouldHideAgentPanelForSelectedTask,
2071
+ },
2072
+ ];
2073
+ if (showEditorPanel) {
2074
+ graphPanels.push({
2075
+ name: "editor-preview",
2076
+ defaultSize: 500,
2077
+ content: (_jsx("div", { className: "h-full overflow-hidden border-l border-gray-200 bg-gray-50", children: itemPreviewPanel })),
2078
+ });
2079
+ }
2080
+ return graphPanels;
2081
+ }
1951
2082
  const kanbanPanels = [
1952
2083
  {
1953
2084
  name: "task-list",
@@ -1978,13 +2109,15 @@ export function TaskBoardWorkspace() {
1978
2109
  }, [
1979
2110
  isWizardMode,
1980
2111
  isListView,
2112
+ isGraphView,
2113
+ selectedProjectId,
1981
2114
  taskBoardContent,
1982
2115
  taskDetailPanel,
1983
- agentTerminalPanel,
1984
2116
  selectedTask,
2117
+ agentTerminalPanel,
2118
+ shouldHideAgentPanelForSelectedTask,
1985
2119
  showEditorPanel,
1986
2120
  itemPreviewPanel,
1987
- shouldHideAgentPanelForSelectedTask,
1988
2121
  ]);
1989
2122
  return (_jsxs("div", { className: "text-foreground flex h-full w-full flex-col bg-white select-text", children: [_jsx("div", { className: "min-h-0 flex-1", children: isMobile ? (_jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [selectedProjectId && (_jsx("div", { className: "shrink-0 border-b border-gray-100 bg-white px-4 shadow-[0_1px_2px_rgba(0,0,0,0.03)]", children: _jsx(SimpleTabs, { tabs: [
1990
2123
  { id: "project", label: "Project", content: null },
@@ -2003,11 +2136,13 @@ export function TaskBoardWorkspace() {
2003
2136
  ...(showEditorPanel
2004
2137
  ? [{ id: "editor", label: "Editor", content: null }]
2005
2138
  : []),
2006
- ], activeTab: mobileActiveTab, setActiveTab: setMobileActiveTab, hideContent: true, variant: "elegant", className: "gap-6" }) })), _jsxs("div", { className: "min-h-0 flex-1 overflow-hidden", children: [mobileActiveTab === 0 && (_jsx("div", { className: cn("flex h-full overflow-y-auto bg-slate-50/50", selectedProjectId && "p-2 pt-2 sm:p-4 sm:pt-3"), children: taskBoardContent })), mobileActiveTab === 1 && (_jsx("div", { className: "h-full overflow-y-auto bg-white", children: taskDetailPanel })), mobileActiveTab === 2 && (_jsx("div", { className: "h-full overflow-hidden bg-white", children: shouldHideAgentPanelForSelectedTask
2139
+ ], activeTab: mobileActiveTab, setActiveTab: setMobileActiveTab, hideContent: true, variant: "elegant", className: "gap-6" }) })), _jsxs("div", { className: "min-h-0 flex-1 overflow-hidden", children: [mobileActiveTab === 0 && (_jsx("div", { className: cn("flex h-full overflow-y-auto bg-slate-50/50", selectedProjectId &&
2140
+ !isWizardMode &&
2141
+ "p-2 pt-2 md:p-4 md:pt-3"), children: taskBoardContent })), mobileActiveTab === 1 && (_jsx("div", { className: "h-full overflow-y-auto bg-white", children: taskDetailPanel })), mobileActiveTab === 2 && (_jsx("div", { className: "h-full overflow-hidden bg-white", children: shouldHideAgentPanelForSelectedTask
2007
2142
  ? taskDetailPanel
2008
2143
  : agentTerminalPanel })), mobileActiveTab === 3 && showEditorPanel && (_jsx("div", { className: "h-full overflow-hidden bg-gray-50", children: itemPreviewPanel }))] })] })) : (_jsx(Splitter, { panels: panels, direction: "horizontal", localStorageKey: isWizardMode
2009
2144
  ? "task-board-wizard-splitter-v2"
2010
- : "task-board-main-splitter" })) }), selectedProjectId && (_jsx(CreateTaskDialog, { open: createDialogOpen, onOpenChange: setCreateDialogOpen, projectId: selectedProjectId, onCreated: () => {
2145
+ : "task-board-main-splitter" })) }), selectedProjectId && (_jsx(CreateTaskDialog, { open: createDialogOpen, onOpenChange: setCreateDialogOpen, projectId: selectedProjectId, availableParentTasks: tasks, onCreated: () => {
2011
2146
  void refreshTasks(selectedProjectId);
2012
2147
  void refreshExecutionState(selectedProjectId);
2013
2148
  void refreshDependencies(selectedProjectId);