@parhelia/core 0.1.12347 → 0.1.12368

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 (51) hide show
  1. package/dist/config/config.js +3 -0
  2. package/dist/config/config.js.map +1 -1
  3. package/dist/editor/FieldListField.js +6 -4
  4. package/dist/editor/FieldListField.js.map +1 -1
  5. package/dist/editor/menubar/toolbar-sections/UtilityControls.js +10 -1
  6. package/dist/editor/menubar/toolbar-sections/UtilityControls.js.map +1 -1
  7. package/dist/editor/settings/panels/ModelsPanel.js +20 -3
  8. package/dist/editor/settings/panels/ModelsPanel.js.map +1 -1
  9. package/dist/editor/sidebar/WorkspaceRailMobile.d.ts +1 -3
  10. package/dist/editor/sidebar/WorkspaceRailMobile.js +3 -5
  11. package/dist/editor/sidebar/WorkspaceRailMobile.js.map +1 -1
  12. package/dist/revision.d.ts +2 -2
  13. package/dist/revision.js +2 -2
  14. package/dist/setup/services/setupWizardService.d.ts +5 -0
  15. package/dist/setup/services/setupWizardService.js.map +1 -1
  16. package/dist/setup/wizard/steps/ImportModelDialog.js +15 -2
  17. package/dist/setup/wizard/steps/ImportModelDialog.js.map +1 -1
  18. package/dist/splash-screen/ParheliaLogo.js +87 -37
  19. package/dist/splash-screen/ParheliaLogo.js.map +1 -1
  20. package/dist/task-board/TaskBoardWorkspace.js +132 -64
  21. package/dist/task-board/TaskBoardWorkspace.js.map +1 -1
  22. package/dist/task-board/components/ProjectPropertiesPanel.js +3 -3
  23. package/dist/task-board/components/ProjectPropertiesPanel.js.map +1 -1
  24. package/dist/task-board/components/TaskAttachmentsSection.js +1 -1
  25. package/dist/task-board/components/TaskAttachmentsSection.js.map +1 -1
  26. package/dist/task-board/components/TaskBoardTitlebar.js +1 -1
  27. package/dist/task-board/components/TaskBoardTitlebar.js.map +1 -1
  28. package/dist/task-board/components/WizardCommunicationCenter.d.ts +2 -0
  29. package/dist/task-board/components/WizardCommunicationCenter.js +9 -4
  30. package/dist/task-board/components/WizardCommunicationCenter.js.map +1 -1
  31. package/dist/task-board/components/WizardTaskDetailsPanel.js +1 -1
  32. package/dist/task-board/components/WizardTaskDetailsPanel.js.map +1 -1
  33. package/dist/task-board/index.d.ts +1 -0
  34. package/dist/task-board/index.js +1 -0
  35. package/dist/task-board/index.js.map +1 -1
  36. package/dist/task-board/services/taskService.d.ts +3 -1
  37. package/dist/task-board/services/taskService.js +6 -0
  38. package/dist/task-board/services/taskService.js.map +1 -1
  39. package/dist/task-board/types.d.ts +21 -0
  40. package/dist/task-board/views/DependencyGraphView.d.ts +12 -0
  41. package/dist/task-board/views/DependencyGraphView.js +383 -0
  42. package/dist/task-board/views/DependencyGraphView.js.map +1 -0
  43. package/dist/task-board/views/KanbanView.d.ts +0 -4
  44. package/dist/task-board/views/KanbanView.js +4 -10
  45. package/dist/task-board/views/KanbanView.js.map +1 -1
  46. package/dist/task-board/views/ListView.d.ts +0 -4
  47. package/dist/task-board/views/ListView.js +3 -9
  48. package/dist/task-board/views/ListView.js.map +1 -1
  49. package/dist/task-board/views/WizardView.js +4 -4
  50. package/dist/task-board/views/WizardView.js.map +1 -1
  51. package/package.json +5 -2
@@ -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,11 +187,13 @@ 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);
189
198
  const selectedProjectIdRef = useRef(null);
190
199
  const directSubprojectIdsRef = useRef(new Set());
@@ -345,8 +354,15 @@ export function TaskBoardWorkspace() {
345
354
  const canCreate = selectedProject?.permission === "Owner" ||
346
355
  selectedProject?.permission === "Editor";
347
356
  const canEditTasks = canCreate;
348
- const viewTabIds = useMemo(() => ["kanban", "list"], []);
357
+ const viewTabs = useMemo(() => [
358
+ { id: "kanban", label: "Kanban", content: null },
359
+ { id: "list", label: "List", content: null },
360
+ { id: "graph", label: "Graph", content: null },
361
+ ], []);
362
+ const viewTabIds = useMemo(() => ["kanban", "list", "graph"], []);
349
363
  const isListView = viewTabIds[activeTab] === "list";
364
+ const isGraphView = viewTabIds[activeTab] === "graph";
365
+ 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
366
  const handleSelectProject = useCallback((projectId) => {
351
367
  setSelectedProjectId((previousProjectId) => {
352
368
  if (previousProjectId !== projectId) {
@@ -359,6 +375,7 @@ export function TaskBoardWorkspace() {
359
375
  const clearSelectedProjectData = useCallback(() => {
360
376
  setTasks([]);
361
377
  setDependencies([]);
378
+ setGraphLayout(null);
362
379
  setExecutionRecordsByTaskId({});
363
380
  setSubprojectTaskCounts({});
364
381
  setSubprojectTasksByProjectId({});
@@ -374,9 +391,6 @@ export function TaskBoardWorkspace() {
374
391
  return selectedProject;
375
392
  return (projects.find((project) => project.project.projectId === selectedTask.projectId) ?? selectedProject);
376
393
  }, [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
394
  const selectedTaskIsPlan = useMemo(() => {
381
395
  const taskType = String(selectedTask?.taskType ?? "").toLowerCase();
382
396
  return taskType === "plan" || selectedTask?.title === "Project Plan";
@@ -673,7 +687,7 @@ export function TaskBoardWorkspace() {
673
687
  if (typeof window === "undefined")
674
688
  return;
675
689
  const current = new URLSearchParams(window.location.search);
676
- const view = activeTab === 1 ? "list" : "kanban";
690
+ const view = viewTabIds[activeTab] ?? "kanban";
677
691
  if (selectedProjectId) {
678
692
  current.set(TASKBOARD_PROJECT_QUERY_KEY, selectedProjectId);
679
693
  }
@@ -702,7 +716,7 @@ export function TaskBoardWorkspace() {
702
716
  if (newUrl !== oldUrl) {
703
717
  window.history.replaceState(null, "", newUrl);
704
718
  }
705
- }, [selectedProjectId, selectedTaskId, activeTab, isWizardMode]);
719
+ }, [selectedProjectId, selectedTaskId, activeTab, isWizardMode, viewTabIds]);
706
720
  useEffect(() => {
707
721
  const handlePopState = () => {
708
722
  syncTaskBoardStateFromUrl();
@@ -743,6 +757,19 @@ export function TaskBoardWorkspace() {
743
757
  const indexed = indexTaskExecutionRecords(records);
744
758
  setExecutionRecordsByTaskId(indexed);
745
759
  }, []);
760
+ const refreshGraphLayout = useCallback(async (projectId) => {
761
+ latestGraphLayoutProjectIdRef.current = projectId;
762
+ const requestProjectId = projectId;
763
+ const result = await getGraphLayout(projectId);
764
+ if (latestGraphLayoutProjectIdRef.current !== requestProjectId) {
765
+ return;
766
+ }
767
+ if (result.type !== "success") {
768
+ toast.error(result.summary || "Failed to load graph layout");
769
+ return;
770
+ }
771
+ setGraphLayout(result.data ?? null);
772
+ }, []);
746
773
  const refreshSubprojectTaskCounts = useCallback(async () => {
747
774
  const requestProjectId = selectedProjectId;
748
775
  latestSubprojectCountsProjectIdRef.current = requestProjectId;
@@ -978,6 +1005,7 @@ export function TaskBoardWorkspace() {
978
1005
  refreshTasksRef.current = refreshTasks;
979
1006
  refreshExecutionStateRef.current = refreshExecutionState;
980
1007
  refreshDependenciesRef.current = refreshDependencies;
1008
+ refreshGraphLayoutRef.current = refreshGraphLayout;
981
1009
  refreshSubprojectTaskCountsRef.current = refreshSubprojectTaskCounts;
982
1010
  selectedProjectIdRef.current = selectedProjectId;
983
1011
  directSubprojectIdsRef.current = new Set(directSubprojects.map((subproject) => subproject.project.projectId));
@@ -987,6 +1015,7 @@ export function TaskBoardWorkspace() {
987
1015
  refreshTasks,
988
1016
  refreshExecutionState,
989
1017
  refreshDependencies,
1018
+ refreshGraphLayout,
990
1019
  refreshSubprojectTaskCounts,
991
1020
  selectedProjectId,
992
1021
  directSubprojects,
@@ -1236,7 +1265,7 @@ export function TaskBoardWorkspace() {
1236
1265
  if (editContext?.confirm) {
1237
1266
  editContext.confirm({
1238
1267
  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.`,
1268
+ 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
1269
  acceptLabel: "Delete",
1241
1270
  showCancel: true,
1242
1271
  accept: () => {
@@ -1275,6 +1304,7 @@ export function TaskBoardWorkspace() {
1275
1304
  handleSelectMyTask,
1276
1305
  handleSelectProject,
1277
1306
  handleRunOrchestrator,
1307
+ selectedProject,
1278
1308
  ]);
1279
1309
  useEffect(() => {
1280
1310
  return () => {
@@ -1296,10 +1326,12 @@ export function TaskBoardWorkspace() {
1296
1326
  const refreshTasksFn = refreshTasksRef.current;
1297
1327
  const refreshExecutionStateFn = refreshExecutionStateRef.current;
1298
1328
  const refreshDependenciesFn = refreshDependenciesRef.current;
1329
+ const refreshGraphLayoutFn = refreshGraphLayoutRef.current;
1299
1330
  void Promise.all([
1300
1331
  refreshTasksFn?.(selectedProjectId),
1301
1332
  refreshExecutionStateFn?.(selectedProjectId),
1302
1333
  refreshDependenciesFn?.(selectedProjectId),
1334
+ refreshGraphLayoutFn?.(selectedProjectId),
1303
1335
  ]).finally(() => {
1304
1336
  if (cancelled)
1305
1337
  return;
@@ -1369,6 +1401,19 @@ export function TaskBoardWorkspace() {
1369
1401
  return;
1370
1402
  const unsubscribe = addListener((message) => {
1371
1403
  const messageType = message?.type;
1404
+ if (messageType === "project:properties:updated") {
1405
+ const payload = message?.payload;
1406
+ const projectId = payload?.projectId ?? payload?.ProjectId;
1407
+ const currentProjectId = selectedProjectIdRef.current;
1408
+ const refreshGraphLayoutFn = refreshGraphLayoutRef.current;
1409
+ if (projectId &&
1410
+ currentProjectId &&
1411
+ projectId === currentProjectId &&
1412
+ refreshGraphLayoutFn) {
1413
+ void refreshGraphLayoutFn(projectId);
1414
+ }
1415
+ return;
1416
+ }
1372
1417
  if (messageType === "task:state-changed") {
1373
1418
  const payload = message?.payload;
1374
1419
  const projectId = payload?.projectId ??
@@ -1578,21 +1623,20 @@ export function TaskBoardWorkspace() {
1578
1623
  clearWizardCloseTransitionTimeout();
1579
1624
  setWizardForceOverview(false);
1580
1625
  setTaskSelection(taskId, { source: "user", pinInWizard: true });
1581
- } })), [
1582
- wizardAttentionState,
1626
+ }, onOpenAgentTab: isMobile ? () => setMobileActiveTab(2) : undefined })), [
1583
1627
  wizardDisplayedTask,
1584
1628
  wizardDisplayedAgentId,
1585
1629
  wizardDisplayedExecutionDisplay,
1630
+ wizardAttentionState.summaryState,
1631
+ wizardAttentionState.stats,
1632
+ wizardTasksWithDisplayAssignees,
1633
+ dependencies,
1586
1634
  canEditTasks,
1587
- selectedProjectId,
1588
- directSubprojects,
1635
+ isMobile,
1589
1636
  refreshVisibleTaskData,
1590
- clearWizardCloseTransitionTimeout,
1591
1637
  handleCloseWizardTask,
1592
- selectedTaskId,
1593
- wizardPinnedTaskId,
1594
- selectedProject?.project.title,
1595
- selectedProject?.project.description,
1638
+ clearWizardCloseTransitionTimeout,
1639
+ setTaskSelection,
1596
1640
  ]);
1597
1641
  const isProjectViewLoading = !!selectedProjectId && projectViewLoadingId === selectedProjectId;
1598
1642
  const taskBoardContent = useMemo(() => {
@@ -1609,58 +1653,47 @@ export function TaskBoardWorkspace() {
1609
1653
  }, 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
1654
  }
1611
1655
  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: () => {
1656
+ 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
1657
  void refreshVisibleTaskData();
1614
- }, projectId: selectedProjectId, permission: selectedProject?.permission, activeTab: activeTab, onSetActiveTab: setActiveTab, canCreateTask: canEditTasks, onCreateTask: () => setCreateDialogOpen(true) })] }));
1658
+ }, projectId: selectedProjectId, permission: selectedProject?.permission })] }));
1659
+ }
1660
+ if (isGraphView) {
1661
+ 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, savedLayout: graphLayout, selectedTaskId: selectedTaskId, onSelectTask: (id) => setTaskSelection(id, { source: "user" }), permission: selectedProject?.permission, onLayoutSaved: setGraphLayout }) })] }));
1615
1662
  }
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: () => {
1663
+ 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
1664
  void refreshVisibleTaskData();
1618
- }, projectId: selectedProjectId, permission: selectedProject?.permission, activeTab: activeTab, onSetActiveTab: setActiveTab, canCreateTask: canEditTasks, onCreateTask: () => setCreateDialogOpen(true) })] }));
1665
+ }, projectId: selectedProjectId, permission: selectedProject?.permission })] }));
1619
1666
  }, [
1620
1667
  isProjectViewLoading,
1621
1668
  selectedProjectId,
1622
1669
  selectedProject,
1623
- nav,
1670
+ isProjectsLoading,
1624
1671
  isWizardMode,
1625
1672
  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,
1673
+ isGraphView,
1637
1674
  selectedProjectCumulativeCostUsed,
1638
- dependencies,
1639
- directSubprojects,
1640
- parentProject?.project.projectId,
1641
- parentProject?.project.title,
1642
- selectedProject?.project.title,
1675
+ savingProjectStatus,
1676
+ handleProjectStatusChange,
1643
1677
  selectedProjectTaskCounts,
1678
+ directSubprojects,
1644
1679
  subprojectTaskCounts,
1645
1680
  subprojectCountsLoading,
1646
- wizardCommunicationPanel,
1647
- savingProjectStatus,
1648
- handleProjectStatusChange,
1649
- activeTab,
1681
+ parentProject?.project.projectId,
1682
+ parentProject?.project.title,
1650
1683
  handleSelectProject,
1651
- currentAgentId,
1652
- agentPanelMode,
1653
- selectedTaskIsPlan,
1654
- selectedTaskHasAssignedAgentProfile,
1655
- canRunAssignedAgent,
1656
- runAssignedAgentDisabledReason,
1657
- handleRunSelectedTaskAgent,
1658
- isPlanning,
1659
- handleStartPlanning,
1660
- selectedTaskIsBlocked,
1684
+ sharedViewSwitcher,
1685
+ tasksWithDisplayAssignees,
1686
+ dependencies,
1687
+ selectedTaskId,
1688
+ activeTab,
1661
1689
  canEditTasks,
1662
- selectedTask?.assigneeDisplayName,
1663
- selectedTask?.assigneeId,
1690
+ nav,
1691
+ isTasksLoading,
1692
+ wizardSubprojectTaskLists,
1693
+ wizardDisplayedTask?.taskId,
1694
+ wizardCommunicationPanel,
1695
+ setTaskSelection,
1696
+ refreshVisibleTaskData,
1664
1697
  ]);
1665
1698
  const taskDetailPanel = useMemo(() => (_jsx(TaskDetailPanel, { project: selectedTaskProject, task: selectedTask, allTasks: taskSelectionUniverse, dependencies: dependencies, onTaskChanged: () => {
1666
1699
  void refreshVisibleTaskData();
@@ -1670,6 +1703,7 @@ export function TaskBoardWorkspace() {
1670
1703
  taskSelectionUniverse,
1671
1704
  dependencies,
1672
1705
  refreshVisibleTaskData,
1706
+ setTaskSelection,
1673
1707
  ]);
1674
1708
  const agentTerminalPanel = useMemo(() => (_jsx(TaskAgentPanel, { agentId: displayAgentId, mode: agentPanelMode, label: selectedTaskIsPlan ? "Planner" : "Task Agent", hasAssignedAgentProfile: !selectedTaskIsPlan && selectedTaskHasAssignedAgentProfile, assignedAgentProfileName: !selectedTaskIsPlan && selectedTaskHasAssignedAgentProfile
1675
1709
  ? selectedTask?.assigneeDisplayName ||
@@ -1872,20 +1906,21 @@ export function TaskBoardWorkspace() {
1872
1906
  defaultSize: "auto",
1873
1907
  content: (_jsx("div", { className: "h-full min-h-0 min-w-0 overflow-hidden bg-gray-50", children: editorContent })),
1874
1908
  },
1875
- ], splitterClassName: "bg-gray-200 hover:bg-gray-300 w-[6px]", className: "h-full" }));
1909
+ ], splitterClassName: "bg-gray-200 hover:bg-gray-300 w-[6px]", className: "h-full", direction: isMobile ? "vertical" : "horizontal" }));
1876
1910
  if (!currentItemDescriptor) {
1877
1911
  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
1912
  }
1879
1913
  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
1914
  }, [
1881
1915
  currentItemDescriptor,
1882
- contextItemOptions,
1883
1916
  hasMultipleContextItems,
1884
- handleSelectContextItem,
1885
1917
  selectedContextItemValue,
1918
+ handleSelectContextItem,
1919
+ contextItemOptions,
1886
1920
  previewItemName,
1887
1921
  previewItemPath,
1888
1922
  previewItemVersion,
1923
+ isMobile,
1889
1924
  ]);
1890
1925
  useEffect(() => {
1891
1926
  if (!assignAgentDialogOpen)
@@ -1924,7 +1959,7 @@ export function TaskBoardWorkspace() {
1924
1959
  {
1925
1960
  name: "task-list",
1926
1961
  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 })),
1962
+ 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
1963
  },
1929
1964
  {
1930
1965
  name: "task-details",
@@ -1948,6 +1983,35 @@ export function TaskBoardWorkspace() {
1948
1983
  }
1949
1984
  return listPanels;
1950
1985
  }
1986
+ if (isGraphView) {
1987
+ const graphPanels = [
1988
+ {
1989
+ name: "task-list",
1990
+ defaultSize: "auto",
1991
+ 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 })),
1992
+ },
1993
+ {
1994
+ name: "task-details",
1995
+ defaultSize: 420,
1996
+ content: taskDetailPanel,
1997
+ hidden: !selectedProjectId || !selectedTask,
1998
+ },
1999
+ {
2000
+ name: "agent-terminal",
2001
+ defaultSize: 560,
2002
+ content: agentTerminalPanel,
2003
+ hidden: !selectedProjectId || shouldHideAgentPanelForSelectedTask,
2004
+ },
2005
+ ];
2006
+ if (showEditorPanel) {
2007
+ graphPanels.push({
2008
+ name: "editor-preview",
2009
+ defaultSize: 500,
2010
+ content: (_jsx("div", { className: "h-full overflow-hidden border-l border-gray-200 bg-gray-50", children: itemPreviewPanel })),
2011
+ });
2012
+ }
2013
+ return graphPanels;
2014
+ }
1951
2015
  const kanbanPanels = [
1952
2016
  {
1953
2017
  name: "task-list",
@@ -1978,13 +2042,15 @@ export function TaskBoardWorkspace() {
1978
2042
  }, [
1979
2043
  isWizardMode,
1980
2044
  isListView,
2045
+ isGraphView,
2046
+ selectedProjectId,
1981
2047
  taskBoardContent,
1982
2048
  taskDetailPanel,
1983
- agentTerminalPanel,
1984
2049
  selectedTask,
2050
+ agentTerminalPanel,
2051
+ shouldHideAgentPanelForSelectedTask,
1985
2052
  showEditorPanel,
1986
2053
  itemPreviewPanel,
1987
- shouldHideAgentPanelForSelectedTask,
1988
2054
  ]);
1989
2055
  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
2056
  { id: "project", label: "Project", content: null },
@@ -2003,7 +2069,9 @@ export function TaskBoardWorkspace() {
2003
2069
  ...(showEditorPanel
2004
2070
  ? [{ id: "editor", label: "Editor", content: null }]
2005
2071
  : []),
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
2072
+ ], 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 &&
2073
+ !isWizardMode &&
2074
+ "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
2075
  ? taskDetailPanel
2008
2076
  : 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
2077
  ? "task-board-wizard-splitter-v2"