@parhelia/core 0.1.12470 → 0.1.12479

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 (162) hide show
  1. package/dist/config/config.js +22 -3
  2. package/dist/config/config.js.map +1 -1
  3. package/dist/config/types.d.ts +2 -0
  4. package/dist/config/types.js.map +1 -1
  5. package/dist/editor/ConfirmationDialog.js +20 -4
  6. package/dist/editor/ConfirmationDialog.js.map +1 -1
  7. package/dist/editor/ContentTree.js +19 -7
  8. package/dist/editor/ContentTree.js.map +1 -1
  9. package/dist/editor/Editor.js.map +1 -1
  10. package/dist/editor/PictureCropper.js +45 -41
  11. package/dist/editor/PictureCropper.js.map +1 -1
  12. package/dist/editor/ai/AgentTerminal.js +97 -8
  13. package/dist/editor/ai/AgentTerminal.js.map +1 -1
  14. package/dist/editor/ai/AgentTerminalStatusBar.js +65 -0
  15. package/dist/editor/ai/AgentTerminalStatusBar.js.map +1 -1
  16. package/dist/editor/ai/Agents.js +19 -0
  17. package/dist/editor/ai/Agents.js.map +1 -1
  18. package/dist/editor/ai/AiResponseMessage.js +5 -0
  19. package/dist/editor/ai/AiResponseMessage.js.map +1 -1
  20. package/dist/editor/ai/ContentInspectorPopover.d.ts +1 -0
  21. package/dist/editor/ai/ContentInspectorPopover.js +22 -8
  22. package/dist/editor/ai/ContentInspectorPopover.js.map +1 -1
  23. package/dist/editor/ai/ToolCallDisplay.d.ts +2 -0
  24. package/dist/editor/ai/ToolCallDisplay.js +54 -11
  25. package/dist/editor/ai/ToolCallDisplay.js.map +1 -1
  26. package/dist/editor/ai/dialogs/AgentDialogHandler.js +32 -3
  27. package/dist/editor/ai/dialogs/AgentDialogHandler.js.map +1 -1
  28. package/dist/editor/ai/dialogs/QuestionnaireInline.js +55 -20
  29. package/dist/editor/ai/dialogs/QuestionnaireInline.js.map +1 -1
  30. package/dist/editor/ai/dialogs/agentDialogTypes.d.ts +7 -4
  31. package/dist/editor/ai/dialogs/agentDialogTypes.js.map +1 -1
  32. package/dist/editor/ai/types.d.ts +2 -0
  33. package/dist/editor/client/EditorShell.js +55 -10
  34. package/dist/editor/client/EditorShell.js.map +1 -1
  35. package/dist/editor/client/editContext.d.ts +2 -0
  36. package/dist/editor/client/editContext.js.map +1 -1
  37. package/dist/editor/client/ui/EditorChrome.d.ts +0 -2
  38. package/dist/editor/client/ui/EditorChrome.js +2 -13
  39. package/dist/editor/client/ui/EditorChrome.js.map +1 -1
  40. package/dist/editor/page-viewer/EditorForm.js +8 -1
  41. package/dist/editor/page-viewer/EditorForm.js.map +1 -1
  42. package/dist/editor/page-viewer/PageViewer.d.ts +3 -1
  43. package/dist/editor/page-viewer/PageViewer.js +23 -4
  44. package/dist/editor/page-viewer/PageViewer.js.map +1 -1
  45. package/dist/editor/page-viewer/PageViewerFrame.d.ts +2 -1
  46. package/dist/editor/page-viewer/PageViewerFrame.js +3 -4
  47. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
  48. package/dist/editor/services/agentService.d.ts +27 -0
  49. package/dist/editor/services/agentService.js +11 -2
  50. package/dist/editor/services/agentService.js.map +1 -1
  51. package/dist/editor/services/aiService.js +54 -3
  52. package/dist/editor/services/aiService.js.map +1 -1
  53. package/dist/editor/services/serviceHelper.js +5 -2
  54. package/dist/editor/services/serviceHelper.js.map +1 -1
  55. package/dist/editor/settings/About.js +40 -4
  56. package/dist/editor/settings/About.js.map +1 -1
  57. package/dist/editor/settings/panels/PersistentLogsPanel.d.ts +2 -0
  58. package/dist/editor/settings/panels/PersistentLogsPanel.js +244 -0
  59. package/dist/editor/settings/panels/PersistentLogsPanel.js.map +1 -0
  60. package/dist/editor/settings/panels/ProjectTemplateAgentPanel.d.ts +7 -1
  61. package/dist/editor/settings/panels/ProjectTemplateAgentPanel.js +3 -3
  62. package/dist/editor/settings/panels/ProjectTemplateAgentPanel.js.map +1 -1
  63. package/dist/editor/settings/panels/ProjectTemplatesPanel.js +165 -84
  64. package/dist/editor/settings/panels/ProjectTemplatesPanel.js.map +1 -1
  65. package/dist/editor/settings/panels/index.d.ts +1 -0
  66. package/dist/editor/settings/panels/index.js +1 -0
  67. package/dist/editor/settings/panels/index.js.map +1 -1
  68. package/dist/editor/sidebar/ComponentTree.d.ts +8 -1
  69. package/dist/editor/sidebar/ComponentTree.js +23 -15
  70. package/dist/editor/sidebar/ComponentTree.js.map +1 -1
  71. package/dist/editor/sidebar/NavigationPanelItem.js +1 -1
  72. package/dist/editor/sidebar/NavigationPanelItem.js.map +1 -1
  73. package/dist/editor/sidebar/WorkspaceButton.js +1 -1
  74. package/dist/editor/sidebar/WorkspaceButton.js.map +1 -1
  75. package/dist/editor/tree-indicators/GutterColumns.js +24 -4
  76. package/dist/editor/tree-indicators/GutterColumns.js.map +1 -1
  77. package/dist/editor/tree-indicators/types.d.ts +10 -0
  78. package/dist/editor/ui/Splitter.d.ts +1 -0
  79. package/dist/editor/ui/Splitter.js +7 -1
  80. package/dist/editor/ui/Splitter.js.map +1 -1
  81. package/dist/editor/utils.js +16 -4
  82. package/dist/editor/utils.js.map +1 -1
  83. package/dist/editor/views/CompareView.d.ts +3 -1
  84. package/dist/editor/views/CompareView.js +3 -3
  85. package/dist/editor/views/CompareView.js.map +1 -1
  86. package/dist/editor/views/EditorSlot.js +7 -6
  87. package/dist/editor/views/EditorSlot.js.map +1 -1
  88. package/dist/editor/views/SingleEditView.d.ts +2 -1
  89. package/dist/editor/views/SingleEditView.js +8 -8
  90. package/dist/editor/views/SingleEditView.js.map +1 -1
  91. package/dist/licensing/LicenseContext.js +40 -4
  92. package/dist/licensing/LicenseContext.js.map +1 -1
  93. package/dist/licensing/LicenseOverlay.js +1 -1
  94. package/dist/licensing/LicenseOverlay.js.map +1 -1
  95. package/dist/licensing/types.d.ts +3 -1
  96. package/dist/licensing/types.js.map +1 -1
  97. package/dist/revision.d.ts +2 -2
  98. package/dist/revision.js +2 -2
  99. package/dist/task-board/TaskBoardWorkspace.js +165 -354
  100. package/dist/task-board/TaskBoardWorkspace.js.map +1 -1
  101. package/dist/task-board/assigneeDisplay.js +1 -3
  102. package/dist/task-board/assigneeDisplay.js.map +1 -1
  103. package/dist/task-board/components/CreateProjectDialog.js +2 -1
  104. package/dist/task-board/components/CreateProjectDialog.js.map +1 -1
  105. package/dist/task-board/components/ProjectDashboard.js +2 -1
  106. package/dist/task-board/components/ProjectDashboard.js.map +1 -1
  107. package/dist/task-board/components/ProjectExecutionUserPicker.d.ts +14 -0
  108. package/dist/task-board/components/ProjectExecutionUserPicker.js +65 -0
  109. package/dist/task-board/components/ProjectExecutionUserPicker.js.map +1 -0
  110. package/dist/task-board/components/ProjectSettingsDialog.d.ts +1 -0
  111. package/dist/task-board/components/ProjectSettingsDialog.js +146 -12
  112. package/dist/task-board/components/ProjectSettingsDialog.js.map +1 -1
  113. package/dist/task-board/components/TaskAgentPanel.d.ts +1 -0
  114. package/dist/task-board/components/TaskAgentPanel.js +2 -2
  115. package/dist/task-board/components/TaskAgentPanel.js.map +1 -1
  116. package/dist/task-board/components/TaskAssigneePicker.js +2 -2
  117. package/dist/task-board/components/TaskAssigneePicker.js.map +1 -1
  118. package/dist/task-board/components/TaskBoardMyTasksSidebar.js +1 -1
  119. package/dist/task-board/components/TaskBoardMyTasksSidebar.js.map +1 -1
  120. package/dist/task-board/components/TaskDetailDialog.d.ts +1 -0
  121. package/dist/task-board/components/TaskDetailDialog.js +2 -2
  122. package/dist/task-board/components/TaskDetailDialog.js.map +1 -1
  123. package/dist/task-board/components/TaskDetailPanel.d.ts +1 -0
  124. package/dist/task-board/components/TaskDetailPanel.js +23 -8
  125. package/dist/task-board/components/TaskDetailPanel.js.map +1 -1
  126. package/dist/task-board/components/TaskRow.js +3 -2
  127. package/dist/task-board/components/TaskRow.js.map +1 -1
  128. package/dist/task-board/components/TaskboardPersistentLogPanel.d.ts +11 -0
  129. package/dist/task-board/components/TaskboardPersistentLogPanel.js +141 -0
  130. package/dist/task-board/components/TaskboardPersistentLogPanel.js.map +1 -0
  131. package/dist/task-board/components/WizardTaskDetailsPanel.js +2 -1
  132. package/dist/task-board/components/WizardTaskDetailsPanel.js.map +1 -1
  133. package/dist/task-board/persistentLogCopy.d.ts +7 -0
  134. package/dist/task-board/persistentLogCopy.js +80 -0
  135. package/dist/task-board/persistentLogCopy.js.map +1 -0
  136. package/dist/task-board/persistentLogLabels.d.ts +38 -0
  137. package/dist/task-board/persistentLogLabels.js +189 -0
  138. package/dist/task-board/persistentLogLabels.js.map +1 -0
  139. package/dist/task-board/services/taskService.d.ts +17 -1
  140. package/dist/task-board/services/taskService.js +56 -0
  141. package/dist/task-board/services/taskService.js.map +1 -1
  142. package/dist/task-board/taskExecutionRecords.js +2 -0
  143. package/dist/task-board/taskExecutionRecords.js.map +1 -1
  144. package/dist/task-board/types.d.ts +78 -1
  145. package/dist/task-board/useTaskBoardAgentPanelState.d.ts +34 -0
  146. package/dist/task-board/useTaskBoardAgentPanelState.js +283 -0
  147. package/dist/task-board/useTaskBoardAgentPanelState.js.map +1 -0
  148. package/dist/task-board/utils/taskDependencyOrdering.d.ts +6 -0
  149. package/dist/task-board/utils/taskDependencyOrdering.js +138 -1
  150. package/dist/task-board/utils/taskDependencyOrdering.js.map +1 -1
  151. package/dist/task-board/views/DependencyGraphView.d.ts +5 -2
  152. package/dist/task-board/views/DependencyGraphView.js +261 -69
  153. package/dist/task-board/views/DependencyGraphView.js.map +1 -1
  154. package/dist/task-board/views/KanbanView.js +8 -1
  155. package/dist/task-board/views/KanbanView.js.map +1 -1
  156. package/dist/task-board/views/ListView.js +1 -1
  157. package/dist/task-board/views/ListView.js.map +1 -1
  158. package/dist/task-board/views/WizardView.js +30 -24
  159. package/dist/task-board/views/WizardView.js.map +1 -1
  160. package/dist/tour/Tour.js +0 -32
  161. package/dist/tour/Tour.js.map +1 -1
  162. package/package.json +1 -1
@@ -4,7 +4,6 @@ import { toast } from "sonner";
4
4
  import { cn } from "../lib/utils";
5
5
  import { Splitter } from "../editor/ui/Splitter";
6
6
  import { deleteProject, getExecutionState, getGraphLayout, getProjects, getTasks, getDependencies, runOrchestrator, triggerPlanning, updateProject, updateTask, } from "./services/taskService";
7
- import { getAgent, } from "../editor/services/agentService";
8
7
  import { loadAiProfiles } from "../editor/services/aiService";
9
8
  import { useEditContext } from "../editor/client/editContext";
10
9
  import { KanbanView } from "./views/KanbanView";
@@ -13,7 +12,7 @@ import { DependencyGraphView } from "./views/DependencyGraphView";
13
12
  import { WizardView } from "./views/WizardView";
14
13
  import { SimpleTabs } from "../editor/ui/SimpleTabs";
15
14
  import { TaskDetailPanel } from "./components/TaskDetailPanel";
16
- import { TaskAgentPanel, } from "./components/TaskAgentPanel";
15
+ import { TaskAgentPanel } from "./components/TaskAgentPanel";
17
16
  import { ProjectDashboard, } from "./components/ProjectDashboard";
18
17
  import { CreateTaskDialog } from "./components/CreateTaskDialog";
19
18
  import { AssignAgentDialog } from "./components/AssignAgentDialog";
@@ -36,6 +35,7 @@ import { WizardCommunicationCenter } from "./components/WizardCommunicationCente
36
35
  import { Button } from "../components/ui/button";
37
36
  import { Loader2, Plus } from "lucide-react";
38
37
  import { MainContentTree } from "../editor/sidebar/MainContentTree";
38
+ import { useTaskBoardAgentPanelState } from "./useTaskBoardAgentPanelState";
39
39
  function TaskboardPreviewEditor({ itemDescriptor, }) {
40
40
  const slotContext = useEditorSlotContext({
41
41
  slotId: "taskboard-preview-slot",
@@ -50,6 +50,7 @@ const TASKBOARD_PROJECT_QUERY_KEY = "tbProjectId";
50
50
  const TASKBOARD_TASK_QUERY_KEY = "tbTaskId";
51
51
  const TASKBOARD_VIEW_QUERY_KEY = "tbView";
52
52
  const TASKBOARD_WIZARD_QUERY_KEY = "tbWizard";
53
+ const WS_REFRESH_DELAY_MS = 500;
53
54
  function getInitialQueryValue(queryKey) {
54
55
  if (typeof window === "undefined")
55
56
  return null;
@@ -161,11 +162,6 @@ export function TaskBoardWorkspace() {
161
162
  const [subprojectTasksByProjectId, setSubprojectTasksByProjectId] = useState({});
162
163
  const [subprojectExecutionRecordsByProjectId, setSubprojectExecutionRecordsByProjectId,] = useState({});
163
164
  const [subprojectCountsLoading, setSubprojectCountsLoading] = useState(false);
164
- const [previewItemName, setPreviewItemName] = useState("");
165
- const [previewItemPath, setPreviewItemPath] = useState("");
166
- const [agentContextItems, setAgentContextItems] = useState([]);
167
- const [contextItemNamesByKey, setContextItemNamesByKey] = useState({});
168
- const [contextItemPathsByKey, setContextItemPathsByKey] = useState({});
169
165
  const [wizardPinnedTaskId, setWizardPinnedTaskId] = useState(null);
170
166
  const [, setWizardPinnedTaskSource] = useState(null);
171
167
  const [wizardForceOverview, setWizardForceOverview] = useState(false);
@@ -183,6 +179,15 @@ export function TaskBoardWorkspace() {
183
179
  }, [setWizardPinnedTask]);
184
180
  const wsRefreshTimeoutRef = useRef(null);
185
181
  const wsSubprojectRefreshTimeoutRef = useRef(null);
182
+ const wsRefreshQueuedRef = useRef(false);
183
+ const wsRefreshRunningRef = useRef(false);
184
+ const wsRefreshNeedsTasksRef = useRef(false);
185
+ const wsRefreshNeedsExecutionStateRef = useRef(false);
186
+ const wsRefreshNeedsDependenciesRef = useRef(false);
187
+ const wsRefreshNeedsProjectsRef = useRef(false);
188
+ const wsSubprojectRefreshQueuedRef = useRef(false);
189
+ const wsSubprojectRefreshRunningRef = useRef(false);
190
+ const wsSubprojectRefreshNeedsProjectsRef = useRef(false);
186
191
  const wizardCloseTransitionTimeoutRef = useRef(null);
187
192
  const projectsRequestCountRef = useRef(0);
188
193
  const tasksRequestCountRef = useRef(0);
@@ -411,110 +416,16 @@ export function TaskBoardWorkspace() {
411
416
  return selectedProject;
412
417
  return (projects.find((project) => project.project.projectId === selectedTask.projectId) ?? selectedProject);
413
418
  }, [projects, selectedProject, selectedTask]);
414
- const selectedTaskIsPlan = useMemo(() => {
415
- const taskType = String(selectedTask?.taskType ?? "").toLowerCase();
416
- return taskType === "plan" || selectedTask?.title === "Project Plan";
417
- }, [selectedTask]);
418
- const selectedTaskIsBlocked = useMemo(() => {
419
- if (!selectedTask)
420
- return false;
421
- if (selectedTask.projectId !== selectedProjectId)
422
- return false;
423
- const blockerIds = dependencies
424
- .filter((dependency) => dependency.taskId === selectedTask.taskId &&
425
- dependency.dependencyType === "BlockedBy")
426
- .map((dependency) => dependency.dependsOnTaskId);
427
- if (blockerIds.length === 0)
428
- return false;
429
- const taskById = new Map(tasksWithDisplayAssignees.map((task) => [task.taskId, task]));
430
- return blockerIds.some((blockerId) => {
431
- const blockerTask = taskById.get(blockerId);
432
- return (!blockerTask ||
433
- normalizeTaskStatus(blockerTask.status, blockerTask.executionState) !==
434
- "Done");
435
- });
436
- }, [
437
- selectedTask,
438
- selectedProjectId,
439
- dependencies,
440
- tasksWithDisplayAssignees,
441
- ]);
442
- const selectedTaskHasAssignedAgentProfile = useMemo(() => {
443
- if (!selectedTask)
444
- return false;
445
- return selectedTask.assigneeType === "Agent" && !!selectedTask.assigneeId;
446
- }, [selectedTask]);
447
- const canRunAssignedAgent = useMemo(() => {
448
- return !selectedTaskIsBlocked;
449
- }, [selectedTaskIsBlocked]);
450
- const runAssignedAgentDisabledReason = useMemo(() => {
451
- if (selectedTaskIsBlocked) {
452
- return "This task is blocked by unfinished dependencies.";
453
- }
454
- return undefined;
455
- }, [selectedTaskIsBlocked]);
456
- // ── current agent ID and panel mode for the right panel ──
457
- const currentAgentId = useMemo(() => {
458
- return getLinkedAgentId(selectedTask);
459
- }, [selectedTask]);
460
- const selectedTaskStatus = useMemo(() => {
461
- if (!selectedTask)
462
- return null;
463
- return normalizeTaskStatus(selectedTask.status, selectedTask.executionState);
464
- }, [selectedTask]);
465
- const selectedTaskHasResultData = useMemo(() => {
466
- return !!selectedTask?.resultData?.trim();
467
- }, [selectedTask?.resultData]);
468
- const shouldHideAgentPanelForSelectedTask = useMemo(() => {
469
- return (!!selectedTask &&
470
- selectedTaskIsPlan &&
471
- selectedTaskStatus === "Done" &&
472
- selectedTaskHasResultData);
473
- }, [
419
+ const { agentPanelMode, canRunAssignedAgent, contextItemOptions, displayAgentId, handleSelectContextItem, hasMultipleContextItems, previewItemName, previewItemPath, previewItemVersion, runAssignedAgentDisabledReason, selectedContextItemValue, selectedTaskHasAssignedAgentProfile, selectedTaskIsBlocked, selectedTaskIsPlan, shouldHideAgentPanelForSelectedTask, } = useTaskBoardAgentPanelState({
420
+ currentItemDescriptor,
421
+ editContext,
422
+ isMobile,
423
+ mobileActiveTab,
474
424
  selectedTask,
475
- selectedTaskIsPlan,
476
- selectedTaskStatus,
477
- selectedTaskHasResultData,
478
- ]);
479
- const displayAgentId = useMemo(() => {
480
- return currentAgentId;
481
- }, [currentAgentId]);
482
- useEffect(() => {
483
- if (isMobile && selectedTaskId) {
484
- setMobileActiveTab(1); // Task tab
485
- }
486
- }, [selectedTaskId, isMobile]);
487
- useEffect(() => {
488
- if (isMobile && displayAgentId && !shouldHideAgentPanelForSelectedTask) {
489
- setMobileActiveTab(2); // Agent tab
490
- }
491
- }, [displayAgentId, isMobile, shouldHideAgentPanelForSelectedTask]);
492
- useEffect(() => {
493
- if (!isMobile)
494
- return;
495
- if (!shouldHideAgentPanelForSelectedTask)
496
- return;
497
- if (mobileActiveTab !== 2)
498
- return;
499
- setMobileActiveTab(1);
500
- }, [isMobile, mobileActiveTab, shouldHideAgentPanelForSelectedTask]);
501
- useEffect(() => {
502
- if (!showEditorPanel && mobileActiveTab === 3) {
503
- setMobileActiveTab(0);
504
- }
505
- }, [showEditorPanel, mobileActiveTab]);
506
- const currentItemKey = useMemo(() => {
507
- if (!currentItemDescriptor)
508
- return "";
509
- return `${currentItemDescriptor.id}|${currentItemDescriptor.language}|${currentItemDescriptor.version}`;
510
- }, [currentItemDescriptor]);
511
- const agentPanelMode = useMemo(() => {
512
- if (!selectedTask)
513
- return "no-task-selected";
514
- if (displayAgentId)
515
- return "agent";
516
- return "no-agent";
517
- }, [selectedTask, displayAgentId]);
425
+ selectedTaskId,
426
+ setMobileActiveTab,
427
+ showEditorPanel,
428
+ });
518
429
  const wizardAttentionState = useMemo(() => {
519
430
  const openTasks = orderedWizardTasks.filter((task) => normalizeTaskStatus(task.status, task.executionState) !== "Done");
520
431
  let runningCount = 0;
@@ -612,19 +523,6 @@ export function TaskBoardWorkspace() {
612
523
  wizardForceOverview,
613
524
  wizardPinnedTaskId,
614
525
  ]);
615
- useEffect(() => {
616
- if (!wizardDisplayedTask ||
617
- (wizardDisplayedExecutionDisplay?.label !== "Questions" &&
618
- wizardDisplayedTask.executionState !== "WaitingForInput" &&
619
- wizardDisplayedTask.executionState !== "WaitingForUser")) {
620
- return;
621
- }
622
- }, [
623
- wizardDisplayedTask,
624
- wizardDisplayedAgentId,
625
- wizardDisplayedExecutionDisplay?.label,
626
- selectedProjectId,
627
- ]);
628
526
  const clearWizardCloseTransitionTimeout = useCallback(() => {
629
527
  if (wizardCloseTransitionTimeoutRef.current !== null) {
630
528
  window.clearTimeout(wizardCloseTransitionTimeoutRef.current);
@@ -748,7 +646,8 @@ export function TaskBoardWorkspace() {
748
646
  toast.error(result.summary || "Failed to load tasks");
749
647
  return;
750
648
  }
751
- setTasks(result.data || []);
649
+ const nextTasks = result.data || [];
650
+ setTasks(nextTasks);
752
651
  }
753
652
  finally {
754
653
  tasksRequestCountRef.current = Math.max(0, tasksRequestCountRef.current - 1);
@@ -1033,6 +932,114 @@ export function TaskBoardWorkspace() {
1033
932
  directSubprojects,
1034
933
  taskSelectionUniverse,
1035
934
  ]);
935
+ const queueSelectedProjectRefresh = useCallback((options) => {
936
+ if (options?.refreshTasks) {
937
+ wsRefreshNeedsTasksRef.current = true;
938
+ }
939
+ if (options?.refreshExecutionState) {
940
+ wsRefreshNeedsExecutionStateRef.current = true;
941
+ }
942
+ if (options?.refreshDependencies) {
943
+ wsRefreshNeedsDependenciesRef.current = true;
944
+ }
945
+ if (options?.refreshProjects) {
946
+ wsRefreshNeedsProjectsRef.current = true;
947
+ }
948
+ wsRefreshQueuedRef.current = true;
949
+ if (wsRefreshTimeoutRef.current !== null || wsRefreshRunningRef.current) {
950
+ return;
951
+ }
952
+ wsRefreshTimeoutRef.current = window.setTimeout(() => {
953
+ wsRefreshTimeoutRef.current = null;
954
+ const projectId = selectedProjectIdRef.current;
955
+ const shouldRefreshTasks = wsRefreshNeedsTasksRef.current;
956
+ const shouldRefreshExecutionState = wsRefreshNeedsExecutionStateRef.current;
957
+ const shouldRefreshDependencies = wsRefreshNeedsDependenciesRef.current;
958
+ const shouldRefreshProjects = wsRefreshNeedsProjectsRef.current;
959
+ wsRefreshQueuedRef.current = false;
960
+ wsRefreshNeedsTasksRef.current = false;
961
+ wsRefreshNeedsExecutionStateRef.current = false;
962
+ wsRefreshNeedsDependenciesRef.current = false;
963
+ wsRefreshNeedsProjectsRef.current = false;
964
+ const work = [];
965
+ if (shouldRefreshProjects) {
966
+ const refreshProjectsFn = refreshProjectsRef.current;
967
+ if (refreshProjectsFn) {
968
+ work.push(refreshProjectsFn());
969
+ }
970
+ }
971
+ if (projectId) {
972
+ if (shouldRefreshTasks) {
973
+ const refreshTasksFn = refreshTasksRef.current;
974
+ if (refreshTasksFn) {
975
+ work.push(refreshTasksFn(projectId));
976
+ }
977
+ }
978
+ if (shouldRefreshExecutionState) {
979
+ const refreshExecutionStateFn = refreshExecutionStateRef.current;
980
+ if (refreshExecutionStateFn) {
981
+ work.push(refreshExecutionStateFn(projectId));
982
+ }
983
+ }
984
+ if (shouldRefreshDependencies) {
985
+ const refreshDependenciesFn = refreshDependenciesRef.current;
986
+ if (refreshDependenciesFn) {
987
+ work.push(refreshDependenciesFn(projectId));
988
+ }
989
+ }
990
+ }
991
+ if (work.length === 0) {
992
+ return;
993
+ }
994
+ wsRefreshRunningRef.current = true;
995
+ void Promise.all(work).finally(() => {
996
+ wsRefreshRunningRef.current = false;
997
+ if (wsRefreshQueuedRef.current ||
998
+ wsRefreshNeedsTasksRef.current ||
999
+ wsRefreshNeedsExecutionStateRef.current ||
1000
+ wsRefreshNeedsDependenciesRef.current ||
1001
+ wsRefreshNeedsProjectsRef.current) {
1002
+ queueSelectedProjectRefresh();
1003
+ }
1004
+ });
1005
+ }, WS_REFRESH_DELAY_MS);
1006
+ }, []);
1007
+ const queueSubprojectRefresh = useCallback((options) => {
1008
+ if (options?.refreshProjects) {
1009
+ wsSubprojectRefreshNeedsProjectsRef.current = true;
1010
+ }
1011
+ wsSubprojectRefreshQueuedRef.current = true;
1012
+ if (wsSubprojectRefreshTimeoutRef.current !== null ||
1013
+ wsSubprojectRefreshRunningRef.current) {
1014
+ return;
1015
+ }
1016
+ wsSubprojectRefreshTimeoutRef.current = window.setTimeout(() => {
1017
+ wsSubprojectRefreshTimeoutRef.current = null;
1018
+ const shouldRefreshProjects = wsSubprojectRefreshNeedsProjectsRef.current;
1019
+ wsSubprojectRefreshQueuedRef.current = false;
1020
+ wsSubprojectRefreshNeedsProjectsRef.current = false;
1021
+ const refreshSubprojectsFn = refreshSubprojectTaskCountsRef.current;
1022
+ const refreshProjectsFn = refreshProjectsRef.current;
1023
+ const work = [];
1024
+ if (refreshSubprojectsFn) {
1025
+ work.push(refreshSubprojectsFn());
1026
+ }
1027
+ if (shouldRefreshProjects && refreshProjectsFn) {
1028
+ work.push(refreshProjectsFn());
1029
+ }
1030
+ if (work.length === 0) {
1031
+ return;
1032
+ }
1033
+ wsSubprojectRefreshRunningRef.current = true;
1034
+ void Promise.all(work).finally(() => {
1035
+ wsSubprojectRefreshRunningRef.current = false;
1036
+ if (wsSubprojectRefreshQueuedRef.current ||
1037
+ wsSubprojectRefreshNeedsProjectsRef.current) {
1038
+ queueSubprojectRefresh();
1039
+ }
1040
+ });
1041
+ }, WS_REFRESH_DELAY_MS);
1042
+ }, []);
1036
1043
  const handleRunOrchestrator = useCallback(async (options) => {
1037
1044
  if (!selectedProjectId)
1038
1045
  return;
@@ -1439,34 +1446,16 @@ export function TaskBoardWorkspace() {
1439
1446
  const payload = message?.payload;
1440
1447
  const projectId = payload?.projectId ?? payload?.ProjectId;
1441
1448
  const currentProjectId = selectedProjectIdRef.current;
1442
- const refreshProjectsFn = refreshProjectsRef.current;
1443
1449
  if (!projectId ||
1444
1450
  !currentProjectId ||
1445
- !refreshProjectsFn ||
1446
1451
  !isProjectWithinSelectedTree(projectId, currentProjectId)) {
1447
1452
  return;
1448
1453
  }
1449
- if (wsRefreshTimeoutRef.current !== null) {
1450
- window.clearTimeout(wsRefreshTimeoutRef.current);
1451
- wsRefreshTimeoutRef.current = null;
1454
+ if (projectId === currentProjectId) {
1455
+ queueSelectedProjectRefresh({ refreshProjects: true });
1456
+ return;
1452
1457
  }
1453
- wsRefreshTimeoutRef.current = window.setTimeout(() => {
1454
- wsRefreshTimeoutRef.current = null;
1455
- const selectedId = selectedProjectIdRef.current;
1456
- const refreshProjectsFn = refreshProjectsRef.current;
1457
- if (!selectedId || !refreshProjectsFn)
1458
- return;
1459
- void refreshProjectsFn();
1460
- if (projectId === selectedId) {
1461
- const refreshExecutionStateFn = refreshExecutionStateRef.current;
1462
- if (refreshExecutionStateFn)
1463
- void refreshExecutionStateFn(selectedId);
1464
- return;
1465
- }
1466
- const refreshSubprojectsFn = refreshSubprojectTaskCountsRef.current;
1467
- if (refreshSubprojectsFn)
1468
- void refreshSubprojectsFn();
1469
- }, 250);
1458
+ queueSubprojectRefresh({ refreshProjects: true });
1470
1459
  return;
1471
1460
  }
1472
1461
  if (messageType === "task:state-changed") {
@@ -1516,16 +1505,7 @@ export function TaskBoardWorkspace() {
1516
1505
  },
1517
1506
  };
1518
1507
  });
1519
- if (wsSubprojectRefreshTimeoutRef.current !== null) {
1520
- window.clearTimeout(wsSubprojectRefreshTimeoutRef.current);
1521
- wsSubprojectRefreshTimeoutRef.current = null;
1522
- }
1523
- wsSubprojectRefreshTimeoutRef.current = window.setTimeout(() => {
1524
- wsSubprojectRefreshTimeoutRef.current = null;
1525
- const refreshSubprojectsFn = refreshSubprojectTaskCountsRef.current;
1526
- if (refreshSubprojectsFn)
1527
- void refreshSubprojectsFn();
1528
- }, 250);
1508
+ queueSubprojectRefresh();
1529
1509
  }
1530
1510
  return;
1531
1511
  }
@@ -1537,49 +1517,23 @@ export function TaskBoardWorkspace() {
1537
1517
  const payload = message?.payload;
1538
1518
  const projectId = payload?.projectId ?? payload?.ProjectId;
1539
1519
  const currentProjectId = selectedProjectIdRef.current;
1520
+ const isDirectSubproject = !!projectId && directSubprojectIdsRef.current.has(projectId);
1540
1521
  if (!projectId || !currentProjectId)
1541
1522
  return;
1542
1523
  if (projectId !== currentProjectId) {
1543
- if (!directSubprojectIdsRef.current.has(projectId))
1524
+ if (!isDirectSubproject)
1544
1525
  return;
1545
- if (wsSubprojectRefreshTimeoutRef.current !== null) {
1546
- window.clearTimeout(wsSubprojectRefreshTimeoutRef.current);
1547
- wsSubprojectRefreshTimeoutRef.current = null;
1548
- }
1549
- wsSubprojectRefreshTimeoutRef.current = window.setTimeout(() => {
1550
- wsSubprojectRefreshTimeoutRef.current = null;
1551
- const refreshSubprojectsFn = refreshSubprojectTaskCountsRef.current;
1552
- const refreshProjectsFn = refreshProjectsRef.current;
1553
- if (!refreshSubprojectsFn)
1554
- return;
1555
- void refreshSubprojectsFn();
1556
- if (refreshProjectsFn)
1557
- void refreshProjectsFn();
1558
- }, 250);
1526
+ queueSubprojectRefresh({
1527
+ refreshProjects: messageType !== "task:updated",
1528
+ });
1559
1529
  return;
1560
1530
  }
1561
- if (wsRefreshTimeoutRef.current !== null) {
1562
- window.clearTimeout(wsRefreshTimeoutRef.current);
1563
- wsRefreshTimeoutRef.current = null;
1564
- }
1565
- wsRefreshTimeoutRef.current = window.setTimeout(() => {
1566
- wsRefreshTimeoutRef.current = null;
1567
- const pid = selectedProjectIdRef.current;
1568
- const refreshProjectsFn = refreshProjectsRef.current;
1569
- const refreshTasksFn = refreshTasksRef.current;
1570
- const refreshExecutionStateFn = refreshExecutionStateRef.current;
1571
- const refreshDepsFn = refreshDependenciesRef.current;
1572
- if (!pid ||
1573
- !refreshTasksFn ||
1574
- !refreshDepsFn ||
1575
- !refreshExecutionStateFn)
1576
- return;
1577
- void refreshTasksFn(pid);
1578
- void refreshExecutionStateFn(pid);
1579
- void refreshDepsFn(pid);
1580
- if (refreshProjectsFn)
1581
- void refreshProjectsFn();
1582
- }, 250);
1531
+ queueSelectedProjectRefresh({
1532
+ refreshTasks: true,
1533
+ refreshExecutionState: messageType !== "task:updated",
1534
+ refreshDependencies: true,
1535
+ refreshProjects: messageType !== "task:updated",
1536
+ });
1583
1537
  });
1584
1538
  return () => {
1585
1539
  unsubscribe();
@@ -1588,7 +1542,7 @@ export function TaskBoardWorkspace() {
1588
1542
  // Clearing it here was the bug: editContext changes caused cleanup to
1589
1543
  // cancel the pending debounced refresh before it could fire.
1590
1544
  };
1591
- }, [editContext]);
1545
+ }, [editContext, isProjectWithinSelectedTree, queueSelectedProjectRefresh, queueSubprojectRefresh]);
1592
1546
  // Keep project dropdown in sync when projects are created elsewhere (e.g. by agents).
1593
1547
  useEffect(() => {
1594
1548
  const addListener = editContext?.addSocketMessageListener;
@@ -1612,6 +1566,15 @@ export function TaskBoardWorkspace() {
1612
1566
  window.clearTimeout(wsSubprojectRefreshTimeoutRef.current);
1613
1567
  wsSubprojectRefreshTimeoutRef.current = null;
1614
1568
  }
1569
+ wsRefreshQueuedRef.current = false;
1570
+ wsRefreshRunningRef.current = false;
1571
+ wsRefreshNeedsTasksRef.current = false;
1572
+ wsRefreshNeedsExecutionStateRef.current = false;
1573
+ wsRefreshNeedsDependenciesRef.current = false;
1574
+ wsRefreshNeedsProjectsRef.current = false;
1575
+ wsSubprojectRefreshQueuedRef.current = false;
1576
+ wsSubprojectRefreshRunningRef.current = false;
1577
+ wsSubprojectRefreshNeedsProjectsRef.current = false;
1615
1578
  if (wizardCloseTransitionTimeoutRef.current !== null) {
1616
1579
  window.clearTimeout(wizardCloseTransitionTimeoutRef.current);
1617
1580
  wizardCloseTransitionTimeoutRef.current = null;
@@ -1707,7 +1670,7 @@ export function TaskBoardWorkspace() {
1707
1670
  return (_jsx("div", { className: "flex h-full min-h-[240px] items-center justify-center rounded-lg border border-dashed border-slate-200 bg-slate-50/70", "data-testid": "taskboard-project-loading-state", children: _jsxs("div", { className: "text-muted-foreground flex flex-col items-center gap-3 text-sm", children: [_jsx(Loader2, { className: "h-6 w-6 animate-spin" }), _jsx("div", { children: "Loading project..." })] }) }));
1708
1671
  }
1709
1672
  if (!selectedProjectId || (!selectedProject && !isProjectsLoading)) {
1710
- return (_jsx("div", { className: "flex min-h-full w-full flex-col p-4 md:p-8", children: _jsx("div", { className: "mx-auto flex h-full w-full max-w-7xl flex-1 min-h-0", children: _jsx(ProjectOverviewContent, { nav: nav }) }) }));
1673
+ return (_jsx("div", { className: "flex min-h-full w-full flex-col p-4 md:p-8", children: _jsx("div", { className: "mx-auto flex h-full min-h-0 w-full max-w-7xl flex-1", children: _jsx(ProjectOverviewContent, { nav: nav }) }) }));
1711
1674
  }
1712
1675
  if (isWizardMode) {
1713
1676
  return (_jsx(WizardView, { projectId: selectedProjectId, tasks: tasksWithDisplayAssignees, projectTasksLoading: isTasksLoading, dependencies: dependencies, subprojectTaskLists: wizardSubprojectTaskLists, subprojectTasksLoading: subprojectCountsLoading, selectedTaskId: wizardDisplayedTask?.taskId ?? null, onSelectTask: (id) => {
@@ -1721,7 +1684,7 @@ export function TaskBoardWorkspace() {
1721
1684
  }, projectId: selectedProjectId, permission: selectedProject?.permission })] }));
1722
1685
  }
1723
1686
  if (isGraphView) {
1724
- 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
1687
+ 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", autoLayoutStrategy: "hierarchy", showOrientationToggle: true, savedLayout: graphLayout, selectedTaskId: selectedTaskId, onSelectTask: (id) => setTaskSelection(id, { source: "user" }), permission: selectedProject?.permission, onLayoutSaved: (layout) => setGraphLayout(layout && selectedProjectId
1725
1688
  ? {
1726
1689
  projectId: selectedProjectId,
1727
1690
  ...layout,
@@ -1763,7 +1726,7 @@ export function TaskBoardWorkspace() {
1763
1726
  setTaskSelection,
1764
1727
  refreshVisibleTaskData,
1765
1728
  ]);
1766
- const taskDetailPanel = useMemo(() => (_jsx(TaskDetailPanel, { project: selectedTaskProject, task: selectedTask, allTasks: taskSelectionUniverse, dependencies: dependencies, onTaskChanged: () => {
1729
+ const taskDetailPanel = useMemo(() => (_jsx(TaskDetailPanel, { project: selectedTaskProject, projects: projects, task: selectedTask, allTasks: taskSelectionUniverse, dependencies: dependencies, onTaskChanged: () => {
1767
1730
  void refreshVisibleTaskData();
1768
1731
  }, onSelectTask: (taskId) => setTaskSelection(taskId, { source: "user" }), onClose: () => setTaskSelection(null), variant: "panel" })), [
1769
1732
  selectedTaskProject,
@@ -1805,161 +1768,6 @@ export function TaskBoardWorkspace() {
1805
1768
  selectedTask,
1806
1769
  handleReopenSelectedTask,
1807
1770
  ]);
1808
- const previewItemVersion = useMemo(() => {
1809
- if (!currentItemDescriptor)
1810
- return null;
1811
- return currentItemDescriptor.version === 0
1812
- ? (editContext?.item?.version ?? null)
1813
- : currentItemDescriptor.version;
1814
- }, [currentItemDescriptor, editContext?.item?.version]);
1815
- const contextItemOptions = useMemo(() => {
1816
- return agentContextItems.map((contextItem) => {
1817
- const key = `${contextItem.id}|${contextItem.language}|${contextItem.version}`;
1818
- const name = contextItemNamesByKey[key] || contextItem.name || contextItem.id;
1819
- const path = contextItemPathsByKey[key] || contextItem.path || "";
1820
- return {
1821
- value: key,
1822
- label: name,
1823
- description: `${path || contextItem.id} (${contextItem.language}/v${contextItem.version})`,
1824
- };
1825
- });
1826
- }, [agentContextItems, contextItemNamesByKey, contextItemPathsByKey]);
1827
- const selectedContextItemValue = useMemo(() => {
1828
- if (currentItemKey)
1829
- return currentItemKey;
1830
- const first = agentContextItems[0];
1831
- if (!first)
1832
- return "";
1833
- return `${first.id}|${first.language}|${first.version}`;
1834
- }, [currentItemKey, agentContextItems]);
1835
- const hasMultipleContextItems = contextItemOptions.length > 1;
1836
- useEffect(() => {
1837
- if (!currentAgentId) {
1838
- setAgentContextItems([]);
1839
- return;
1840
- }
1841
- let cancelled = false;
1842
- getAgent(currentAgentId)
1843
- .then((agent) => {
1844
- if (cancelled)
1845
- return;
1846
- const rawContext = agent?.agentContext;
1847
- if (!rawContext) {
1848
- setAgentContextItems([]);
1849
- return;
1850
- }
1851
- let parsed = null;
1852
- try {
1853
- parsed = JSON.parse(rawContext);
1854
- }
1855
- catch {
1856
- parsed = null;
1857
- }
1858
- const items = (parsed?.items || []).filter((x) => !!x?.id && !!x?.language && typeof x?.version === "number");
1859
- setAgentContextItems(items);
1860
- })
1861
- .catch(() => {
1862
- if (cancelled)
1863
- return;
1864
- setAgentContextItems([]);
1865
- });
1866
- return () => {
1867
- cancelled = true;
1868
- };
1869
- }, [currentAgentId]);
1870
- useEffect(() => {
1871
- if (!editContext || agentContextItems.length === 0) {
1872
- setContextItemNamesByKey({});
1873
- setContextItemPathsByKey({});
1874
- return;
1875
- }
1876
- let cancelled = false;
1877
- Promise.all(agentContextItems.map(async (contextItem) => {
1878
- const key = `${contextItem.id}|${contextItem.language}|${contextItem.version}`;
1879
- const descriptor = {
1880
- id: contextItem.id,
1881
- language: contextItem.language,
1882
- version: contextItem.version,
1883
- };
1884
- const item = await editContext.itemsRepository.getItem(descriptor);
1885
- return {
1886
- key,
1887
- name: item?.name || contextItem.name || "",
1888
- path: item?.path || contextItem.path || "",
1889
- };
1890
- }))
1891
- .then((results) => {
1892
- if (cancelled)
1893
- return;
1894
- const nextNames = {};
1895
- const nextPaths = {};
1896
- for (const result of results) {
1897
- nextNames[result.key] = result.name;
1898
- nextPaths[result.key] = result.path;
1899
- }
1900
- setContextItemNamesByKey(nextNames);
1901
- setContextItemPathsByKey(nextPaths);
1902
- })
1903
- .catch(() => {
1904
- if (cancelled)
1905
- return;
1906
- setContextItemNamesByKey({});
1907
- setContextItemPathsByKey({});
1908
- });
1909
- return () => {
1910
- cancelled = true;
1911
- };
1912
- }, [editContext, agentContextItems]);
1913
- const handleSelectContextItem = useCallback((value) => {
1914
- const [id, language, versionText] = value.split("|");
1915
- const version = Number(versionText);
1916
- if (!id || !language || Number.isNaN(version) || !editContext?.loadItem)
1917
- return;
1918
- void editContext.loadItem({ id, language, version });
1919
- }, [editContext]);
1920
- useEffect(() => {
1921
- if (!editContext || !currentItemDescriptor) {
1922
- setPreviewItemName("");
1923
- setPreviewItemPath("");
1924
- return;
1925
- }
1926
- const activeItem = editContext.item;
1927
- const itemMatchesDescriptor = activeItem?.id === currentItemDescriptor.id &&
1928
- activeItem?.language === currentItemDescriptor.language;
1929
- if (itemMatchesDescriptor) {
1930
- setPreviewItemName(activeItem?.name || "");
1931
- setPreviewItemPath(activeItem?.path || "");
1932
- return;
1933
- }
1934
- let cancelled = false;
1935
- editContext.itemsRepository
1936
- .getItem(currentItemDescriptor)
1937
- .then((item) => {
1938
- if (cancelled)
1939
- return;
1940
- setPreviewItemName(item?.name || "");
1941
- setPreviewItemPath(item?.path || "");
1942
- })
1943
- .catch(() => {
1944
- if (cancelled)
1945
- return;
1946
- setPreviewItemName("");
1947
- setPreviewItemPath("");
1948
- });
1949
- return () => {
1950
- cancelled = true;
1951
- };
1952
- }, [
1953
- editContext,
1954
- currentItemDescriptor,
1955
- currentItemDescriptor?.id,
1956
- currentItemDescriptor?.language,
1957
- currentItemDescriptor?.version,
1958
- editContext?.item?.id,
1959
- editContext?.item?.language,
1960
- editContext?.item?.name,
1961
- editContext?.item?.path,
1962
- ]);
1963
1771
  const itemPreviewPanel = useMemo(() => {
1964
1772
  const hasCurrentItem = !!currentItemDescriptor;
1965
1773
  const previewSidebar = (_jsx("div", { className: "relative z-10 flex h-full min-h-0 flex-col bg-white", children: _jsx("div", { className: "min-h-0 flex-1", children: _jsx(MainContentTree, { mode: "normal" }) }) }));
@@ -2132,7 +1940,7 @@ export function TaskBoardWorkspace() {
2132
1940
  id: "agent",
2133
1941
  label: "Agent",
2134
1942
  content: null,
2135
- disabled: !currentAgentId || shouldHideAgentPanelForSelectedTask,
1943
+ disabled: !displayAgentId || shouldHideAgentPanelForSelectedTask,
2136
1944
  },
2137
1945
  ...(showEditorPanel
2138
1946
  ? [{ id: "editor", label: "Editor", content: null }]
@@ -2158,7 +1966,10 @@ export function TaskBoardWorkspace() {
2158
1966
  } }), _jsx(ProjectSettingsDialog, { open: !!settingsProjectId, onOpenChange: (open) => {
2159
1967
  if (!open)
2160
1968
  setSettingsProjectId(null);
2161
- }, projectId: settingsProjectId, selectedProject: settingsProject, onChanged: refreshProjects }), _jsx(AssignAgentDialog, { open: assignAgentDialogOpen, task: selectedTask, onOpenChange: setAssignAgentDialogOpen, onAssigned: async () => {
1969
+ }, projectId: settingsProjectId, selectedProject: settingsProject, projects: projects, onChanged: async () => {
1970
+ await refreshProjects();
1971
+ await refreshVisibleTaskData();
1972
+ } }), _jsx(AssignAgentDialog, { open: assignAgentDialogOpen, task: selectedTask, onOpenChange: setAssignAgentDialogOpen, onAssigned: async () => {
2162
1973
  if (!selectedProjectId)
2163
1974
  return;
2164
1975
  await refreshTasks(selectedProjectId);