@parhelia/core 0.1.12477 → 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 -47
  161. package/dist/tour/Tour.js.map +1 -1
  162. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
3
- import { AlertCircle, ChevronDown, CopyPlus, CornerDownRight, GitBranch, Link2, Plus, RefreshCw, Search, Settings2, Shield, Trash2, X, } from "lucide-react";
3
+ import { AlertCircle, Bot, ChevronDown, ChevronLeft, CopyPlus, CornerDownRight, GitBranch, Link2, Plus, RefreshCw, Search, Settings2, Shield, Trash2, X, } from "lucide-react";
4
4
  import { toast } from "sonner";
5
5
  import { Button } from "../../../components/ui/button";
6
6
  import { Dialog, DialogContent, DialogFooter, } from "../../../components/ui/dialog";
@@ -26,7 +26,7 @@ import { AgentProfileEditorPanel, } from "./AgentProfileEditorPanel";
26
26
  import { ProjectTemplateAgentPanel } from "./ProjectTemplateAgentPanel";
27
27
  import { useSearchParams } from "next/navigation";
28
28
  import { ParheliaIconWhite } from "../../ui/ParheliaIconWhite";
29
- /** Query param for deep-linking the selected project template (settings reload). */
29
+ // Query param for deep-linking the selected project template (settings reload).
30
30
  const SELECTED_PROJECT_TEMPLATE_QUERY_PARAM = "projectTemplateId";
31
31
  const PRIORITY_OPTIONS = [
32
32
  { value: "", label: "No priority" },
@@ -45,7 +45,8 @@ function isProjectTemplateItemChange(changes, selectedTemplateId) {
45
45
  const normalizedSelectedTemplateId = selectedTemplateId?.toLowerCase() ?? null;
46
46
  return changes.some((change) => {
47
47
  const path = change.item?.path?.trim().toLowerCase();
48
- if (path && PROJECT_TEMPLATE_ROOT_PATHS.some((root) => path.startsWith(root))) {
48
+ if (path &&
49
+ PROJECT_TEMPLATE_ROOT_PATHS.some((root) => path.startsWith(root))) {
49
50
  return true;
50
51
  }
51
52
  const itemId = change.item?.id?.trim().toLowerCase();
@@ -74,7 +75,7 @@ function normalizeTaskTemplate(task) {
74
75
  parentTaskId: rawParentTaskId,
75
76
  };
76
77
  }
77
- if (assigneeType === "Human" || assigneeType === "Role") {
78
+ if (assigneeType === "user" || assigneeType === "Role") {
78
79
  return {
79
80
  ...task,
80
81
  disabled,
@@ -93,11 +94,20 @@ function normalizeTaskTemplate(task) {
93
94
  parentTaskId: rawParentTaskId,
94
95
  };
95
96
  }
97
+ function normalizeGraphOrientation(orientation) {
98
+ return orientation === "vertical" ? "vertical" : "horizontal";
99
+ }
96
100
  function normalizeProjectTemplate(template) {
97
101
  return {
98
102
  ...template,
99
103
  hideFromCreateDialog: template.hideFromCreateDialog === true,
100
104
  openInWizardMode: template.openInWizardMode === true,
105
+ graphLayout: template.graphLayout
106
+ ? {
107
+ ...template.graphLayout,
108
+ orientation: normalizeGraphOrientation(template.graphLayout.orientation),
109
+ }
110
+ : null,
101
111
  taskTemplates: (template.taskTemplates ?? []).map(normalizeTaskTemplate),
102
112
  };
103
113
  }
@@ -150,6 +160,7 @@ function buildUpsertTemplateRequest(template) {
150
160
  projectTemplateId: template.id,
151
161
  nodes: template.graphLayout.nodes ?? [],
152
162
  viewport: template.graphLayout.viewport ?? null,
163
+ orientation: normalizeGraphOrientation(template.graphLayout.orientation),
153
164
  }
154
165
  : null,
155
166
  taskTemplates: template.taskTemplates.map((task, index) => {
@@ -183,6 +194,7 @@ function mergeTemplateResponseWithRequest(serverTemplate, request) {
183
194
  projectTemplateId: serverTemplate.id,
184
195
  nodes: request.graphLayout.nodes ?? [],
185
196
  viewport: request.graphLayout.viewport ?? null,
197
+ orientation: normalizeGraphOrientation(request.graphLayout.orientation),
186
198
  };
187
199
  return normalizeProjectTemplate({
188
200
  ...serverTemplate,
@@ -324,6 +336,7 @@ function buildProjectTemplateAgentContext(template, selectedTaskTemplateId) {
324
336
  }
325
337
  export function ProjectTemplatesPanel() {
326
338
  const editContext = useEditContext();
339
+ const isMobile = editContext?.isMobile ?? false;
327
340
  const searchParams = useSearchParams();
328
341
  const [state, setState] = useState("loading");
329
342
  const [templates, setTemplates] = useState([]);
@@ -353,6 +366,9 @@ export function ProjectTemplatesPanel() {
353
366
  const [templateAgentResetting, setTemplateAgentResetting] = useState(false);
354
367
  const [templateAgentError, setTemplateAgentError] = useState(null);
355
368
  const [duplicatingAgentProfile, setDuplicatingAgentProfile] = useState(false);
369
+ const [mobileView, setMobileView] = useState("list");
370
+ // Desktop: hide splitter list + detail; show only the assistant column (full width).
371
+ const [desktopAssistantOnly, setDesktopAssistantOnly] = useState(false);
356
372
  const [editingAgentProfile, setEditingAgentProfile] = useState(null);
357
373
  const autosaveTimeoutRef = useRef(null);
358
374
  const lastPersistedSignatureRef = useRef(null);
@@ -361,6 +377,8 @@ export function ProjectTemplatesPanel() {
361
377
  const draftTemplateRef = useRef(null);
362
378
  const selectedTemplateIdRef = useRef(selectedTemplateId);
363
379
  const selectedTaskIdRef = useRef(selectedTaskId);
380
+ const isDirtyRef = useRef(isDirty);
381
+ const savingRef = useRef(saving);
364
382
  const templateAgentLoadRunIdRef = useRef(0);
365
383
  const externalRefreshTimeoutRef = useRef(null);
366
384
  const pendingExternalRefreshRef = useRef(false);
@@ -405,6 +423,7 @@ export function ProjectTemplatesPanel() {
405
423
  setSelectedTemplateId(template?.id ?? null);
406
424
  setDraftTemplate(clonedTemplate);
407
425
  setEditingAgentProfile(null);
426
+ setDesktopAssistantOnly(false);
408
427
  setSelectedTaskId(getSelectedTaskIdForTemplate(clonedTemplate, preferredTaskId));
409
428
  setIsDirty(false);
410
429
  setSaveError(null);
@@ -418,6 +437,27 @@ export function ProjectTemplatesPanel() {
418
437
  });
419
438
  }
420
439
  }, [editContext, searchParams]);
440
+ const handleMobileBackToList = useCallback(() => {
441
+ setMobileView("list");
442
+ selectTemplate(null);
443
+ }, [selectTemplate]);
444
+ const handleMobileBackFromAgent = useCallback(() => {
445
+ setEditingAgentProfile(null);
446
+ setMobileView("detail");
447
+ }, []);
448
+ useEffect(() => {
449
+ if (!isMobile) {
450
+ setMobileView("list");
451
+ }
452
+ else {
453
+ setDesktopAssistantOnly(false);
454
+ }
455
+ }, [isMobile]);
456
+ useEffect(() => {
457
+ if (!isMobile || !editingAgentProfile)
458
+ return;
459
+ setMobileView("agent");
460
+ }, [isMobile, editingAgentProfile]);
421
461
  const loadTemplates = useCallback(async (preferredTemplateId) => {
422
462
  try {
423
463
  setState("loading");
@@ -549,7 +589,7 @@ export function ProjectTemplatesPanel() {
549
589
  if (isDirty || saving) {
550
590
  return (_jsx("span", { "data-testid": "project-template-save-status", "data-state": "saving", className: "inline-flex min-w-[84px] justify-center rounded bg-amber-100 px-1.5 py-0.5 whitespace-nowrap text-amber-700", children: "Saving..." }));
551
591
  }
552
- return (_jsx("span", { "aria-hidden": "true", "data-testid": "project-template-save-status", "data-state": "saved", className: "inline-flex min-w-[84px] justify-center rounded px-1.5 py-0.5 whitespace-nowrap opacity-0", children: "Saving..." }));
592
+ return (_jsx("span", { "aria-hidden": "true", "data-testid": "project-template-save-status", "data-state": "saved", className: "pointer-events-none inline-flex min-w-[84px] justify-center rounded px-1.5 py-0.5 whitespace-nowrap opacity-0 select-none", children: "Saving..." }));
553
593
  }, [isDirty, saveError, saving]);
554
594
  const graphTasks = useMemo(() => buildTemplateTaskItems(draftTemplate, aiProfilesById), [aiProfilesById, draftTemplate]);
555
595
  const graphDependencies = useMemo(() => buildTemplateDependencies(draftTemplate), [draftTemplate]);
@@ -579,7 +619,10 @@ export function ProjectTemplatesPanel() {
579
619
  }, [selectedAgentProfile, selectedAgentProfileId, selectedTask?.title]);
580
620
  const handleCloseEditingAgentProfile = useCallback(() => {
581
621
  setEditingAgentProfile(null);
582
- }, []);
622
+ if (isMobile) {
623
+ setMobileView("detail");
624
+ }
625
+ }, [isMobile]);
583
626
  const syncProjectTemplateAgentContext = useCallback(async (agentId, template, selectedTaskTemplateId) => {
584
627
  try {
585
628
  await updateAgentContext(agentId, buildProjectTemplateAgentContext(template, selectedTaskTemplateId));
@@ -886,6 +929,12 @@ export function ProjectTemplatesPanel() {
886
929
  useEffect(() => {
887
930
  selectedTaskIdRef.current = selectedTaskId;
888
931
  }, [selectedTaskId]);
932
+ useEffect(() => {
933
+ isDirtyRef.current = isDirty;
934
+ }, [isDirty]);
935
+ useEffect(() => {
936
+ savingRef.current = saving;
937
+ }, [saving]);
889
938
  const queueExternalTemplateRefresh = useCallback(() => {
890
939
  if (saving || isDirty) {
891
940
  pendingExternalRefreshRef.current = true;
@@ -897,9 +946,23 @@ export function ProjectTemplatesPanel() {
897
946
  }
898
947
  externalRefreshTimeoutRef.current = window.setTimeout(() => {
899
948
  externalRefreshTimeoutRef.current = null;
949
+ if (savingRef.current || isDirtyRef.current) {
950
+ pendingExternalRefreshRef.current = true;
951
+ return;
952
+ }
900
953
  void loadTemplatesRef.current(selectedTemplateIdRef.current);
901
954
  }, PROJECT_TEMPLATE_EXTERNAL_REFRESH_DEBOUNCE_MS);
902
955
  }, [isDirty, saving]);
956
+ useEffect(() => {
957
+ if (!saving && !isDirty) {
958
+ return;
959
+ }
960
+ if (externalRefreshTimeoutRef.current !== null) {
961
+ window.clearTimeout(externalRefreshTimeoutRef.current);
962
+ externalRefreshTimeoutRef.current = null;
963
+ pendingExternalRefreshRef.current = true;
964
+ }
965
+ }, [isDirty, saving]);
903
966
  useEffect(() => {
904
967
  if (!editContext?.itemsRepository) {
905
968
  return;
@@ -977,8 +1040,11 @@ export function ProjectTemplatesPanel() {
977
1040
  editContext?.updateUrl({
978
1041
  [SELECTED_PROJECT_TEMPLATE_QUERY_PARAM]: nextTemplate.id,
979
1042
  });
1043
+ if (isMobile) {
1044
+ setMobileView("detail");
1045
+ }
980
1046
  await persistTemplate(request, signature, { showErrorToast: true });
981
- }, [editContext, flushPendingSave, persistTemplate, templates]);
1047
+ }, [editContext, flushPendingSave, isMobile, persistTemplate, templates]);
982
1048
  const handleDeleteTemplate = useCallback((templateToDelete) => {
983
1049
  const template = templateToDelete ?? draftTemplate;
984
1050
  if (!template || template.isSystem)
@@ -1009,8 +1075,7 @@ export function ProjectTemplatesPanel() {
1009
1075
  }
1010
1076
  toast.success("Project template deleted");
1011
1077
  const fallbackId = isDeletingSelectedTemplate
1012
- ? templates.find((currentTemplate) => currentTemplate.id !== templateId)
1013
- ?.id ?? null
1078
+ ? (templates.find((currentTemplate) => currentTemplate.id !== templateId)?.id ?? null)
1014
1079
  : selectedTemplateIdRef.current;
1015
1080
  await loadTemplates(fallbackId);
1016
1081
  }
@@ -1041,7 +1106,10 @@ export function ProjectTemplatesPanel() {
1041
1106
  return;
1042
1107
  }
1043
1108
  selectTemplate(template);
1044
- }, [flushPendingSave, selectTemplate]);
1109
+ if (isMobile) {
1110
+ setMobileView("detail");
1111
+ }
1112
+ }, [flushPendingSave, selectTemplate, isMobile]);
1045
1113
  const handleRefreshTemplates = useCallback(async () => {
1046
1114
  const canContinue = await flushPendingSave({ showErrorToast: true });
1047
1115
  if (!canContinue) {
@@ -1409,103 +1477,116 @@ export function ProjectTemplatesPanel() {
1409
1477
  handleDeleteTemplate(template);
1410
1478
  }, children: _jsx(Trash2, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }) }))] }, template.id));
1411
1479
  }) })) })] }) }));
1412
- const detailContent = draftTemplate ? (_jsxs("div", { className: "flex h-full flex-col bg-gray-50/40", "data-testid": "project-template-detail-pane", children: [_jsxs("div", { className: "flex items-center justify-between gap-3 border-b border-gray-200 bg-white px-5 py-3.5", children: [_jsx("div", { className: "min-w-0", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-8 w-8 items-center justify-center rounded-lg bg-gray-900 text-white", children: _jsx(GitBranch, { className: "h-4 w-4", strokeWidth: 1.5 }) }), _jsxs("div", { className: "min-w-0", children: [_jsx("h2", { className: "truncate text-xs font-semibold text-gray-900", children: draftTemplate.name || "Project Template" }), _jsxs("div", { className: "mt-0.5 flex min-h-[20px] items-center gap-2 text-[11px] text-gray-500", children: [_jsxs("span", { children: [draftTemplate.taskTemplates.length, " task templates"] }), headerStatusBadge] })] })] }) }), _jsx("div", { className: "flex shrink-0 items-center gap-2", children: !draftTemplate.isSystem && (_jsxs(Button, { variant: "outline", size: "sm", onClick: () => handleDeleteTemplate(), disabled: deleting, "data-testid": "project-template-delete-button", children: [_jsx(Trash2, { className: "h-4 w-4", strokeWidth: 1.5 }), deleting ? "Deleting..." : "Delete"] })) })] }), _jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-5 overflow-hidden p-5", children: [saveError && (_jsx("div", { className: "rounded border border-red-200 bg-red-50 px-4 py-3 text-xs text-red-700", children: saveError })), _jsxs("section", { className: "shrink-0 overflow-hidden rounded-lg border border-gray-200 bg-white shadow-sm", children: [_jsxs("button", { type: "button", className: "flex w-full items-center justify-between gap-3 px-4 py-3 text-left", onClick: () => setIsBasicSettingsExpanded((currentValue) => !currentValue), "aria-expanded": isBasicSettingsExpanded, "aria-controls": "project-template-basic-settings", "data-testid": "project-template-basic-settings-toggle", children: [_jsxs("div", { className: "flex items-center gap-2.5", children: [_jsx("span", { className: "flex h-6 w-6 items-center justify-center rounded-md bg-gray-100 text-gray-500", children: _jsx(Settings2, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }) }), _jsxs("div", { children: [_jsx("h3", { className: "text-xs font-semibold tracking-wide text-gray-800", children: "Basic Settings" }), _jsx("p", { className: "text-[11px] leading-tight text-gray-400", children: "Configure the shared defaults for this project template." })] })] }), _jsx(ChevronDown, { className: cn("h-4 w-4 shrink-0 text-gray-400 transition-transform", isBasicSettingsExpanded ? "rotate-180" : "rotate-0"), strokeWidth: 1.5 })] }), isBasicSettingsExpanded && (_jsxs("div", { id: "project-template-basic-settings", className: "grid gap-4 border-t border-gray-100 p-4 md:grid-cols-2", children: [_jsxs("div", { className: "grid gap-1.5 md:col-span-2", children: [_jsx(Label, { className: "text-xs", children: "Template name" }), _jsx(Input, { value: draftTemplate.name, onChange: (event) => applyDraftChange((currentTemplate) => ({
1413
- ...currentTemplate,
1414
- name: event.target.value,
1415
- })), placeholder: "Project template name", className: "text-xs md:text-xs", "data-testid": "project-template-name-input" })] }), _jsxs("div", { className: "grid gap-1.5 md:col-span-2", children: [_jsx(Label, { className: "text-xs", children: "Description" }), _jsx(Textarea, { className: "text-xs", value: draftTemplate.description ?? "", onChange: (event) => applyDraftChange((currentTemplate) => ({
1416
- ...currentTemplate,
1417
- description: event.target.value,
1418
- })), rows: 4, placeholder: "Describe when to use this template", "data-testid": "project-template-description-input" })] }), _jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { className: "text-xs", children: "Default cost limit" }), _jsx(Input, { type: "number", value: draftTemplate.defaultCostLimit ?? "", onChange: (event) => applyDraftChange((currentTemplate) => ({
1419
- ...currentTemplate,
1420
- defaultCostLimit: event.target.value.trim() === ""
1421
- ? null
1422
- : Number(event.target.value),
1423
- })), placeholder: "0", className: "text-xs md:text-xs", "data-testid": "project-template-default-cost-limit-input" })] }), _jsxs("div", { className: "flex items-center justify-between gap-4 md:col-span-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "text-xs font-medium text-zinc-900", children: "Disabled" }), _jsx("div", { className: "mt-0.5 text-xs text-zinc-500", children: "Makes the template unavailable for project creation and template resolution." })] }), _jsx(Switch, { checked: draftTemplate.disabled === true, onCheckedChange: (checked) => applyDraftChange((currentTemplate) => ({
1424
- ...currentTemplate,
1425
- disabled: checked,
1426
- })), className: "data-[state=checked]:bg-amber-600 data-[state=checked]:shadow-inner dark:data-[state=checked]:bg-amber-600", "aria-label": "Disable this project template", "data-testid": "project-template-disabled-switch" })] }), _jsxs("div", { className: "flex items-center justify-between gap-4 md:col-span-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "text-xs font-medium text-zinc-900", children: "Hide from create dialog" }), _jsx("div", { className: "mt-0.5 text-xs text-zinc-500", children: "Keeps the template active, but removes it from the create project dialog." })] }), _jsx(Switch, { checked: draftTemplate.hideFromCreateDialog === true, onCheckedChange: (checked) => applyDraftChange((currentTemplate) => ({
1427
- ...currentTemplate,
1428
- hideFromCreateDialog: checked,
1429
- })), "aria-label": "Hide this project template from the create dialog", "data-testid": "project-template-hide-from-create-dialog-switch" })] }), _jsxs("div", { className: "flex items-center justify-between gap-4 md:col-span-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "text-xs font-medium text-zinc-900", children: "Open in wizard mode" }), _jsx("div", { className: "mt-0.5 text-xs text-zinc-500", children: "New projects created from this template start in taskboard wizard mode." })] }), _jsx(Switch, { checked: draftTemplate.openInWizardMode === true, onCheckedChange: (checked) => applyDraftChange((currentTemplate) => ({
1430
- ...currentTemplate,
1431
- openInWizardMode: checked,
1432
- })), "aria-label": "Open new projects from this template in wizard mode", "data-testid": "project-template-open-in-wizard-mode-switch" })] })] }))] }), _jsxs("section", { className: "flex min-h-0 flex-1 flex-col overflow-hidden rounded-lg border border-gray-200 bg-white shadow-sm", children: [_jsxs("div", { className: "flex shrink-0 items-center justify-between gap-3 border-b border-gray-100 px-4 py-3", children: [_jsxs("div", { className: "flex items-center gap-2.5", children: [_jsx("span", { className: "flex h-6 w-6 items-center justify-center rounded-md bg-gray-100 text-gray-500", children: _jsx(GitBranch, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }) }), _jsxs("div", { children: [_jsx("h3", { className: "text-xs font-semibold tracking-wide text-gray-800", children: "Template Task Editor" }), _jsx("p", { className: "text-[11px] leading-tight text-gray-400", children: "Add task templates, arrange them in the graph, and define dependencies." })] })] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: () => void handleOpenCreateTaskDialog(), disabled: creatingTask, "data-testid": "project-template-add-task-button", children: [_jsx(Plus, { className: "h-4 w-4", strokeWidth: 1.5 }), "Add Task"] })] }), _jsx("div", { className: "min-h-[360px] flex-1 overflow-hidden border-b border-gray-100", children: _jsx(Splitter, { direction: "vertical", localStorageKey: "settings-project-template-graph-task-splitter-v1", className: "h-full", panels: [
1433
- {
1434
- name: "project-template-graph",
1435
- defaultSize: 400,
1436
- className: "min-h-0",
1437
- content: (_jsx("div", { className: "h-full min-h-0 overflow-hidden bg-slate-50/40", "data-testid": "project-template-graph", children: _jsx(DependencyGraphView, { projectId: draftTemplate.id, layoutKey: `project-template:${draftTemplate.id}`, tasks: graphTasks, dependencies: graphDependencies, miniMapWidth: 56, miniMapHeight: 42, orientation: "horizontal", autoLayoutStrategy: "hierarchy", savedLayout: draftTemplate.graphLayout, selectedTaskId: selectedTaskId, selectedDependencyId: selectedDependencyId, onSelectTask: handleSelectTask, onSelectDependency: handleSelectDependencyFromGraph, onClearDependencySelection: handleClearDependencySelection, onAddDependentTaskFromNode: (taskId) => {
1438
- void handleOpenCreateDependentTaskDialogForTask(taskId);
1439
- }, onAddChildTaskFromNode: (taskId) => {
1440
- void handleOpenAddChildTaskDialogForTask(taskId);
1441
- }, onRemoveTask: removeTaskTemplateById, allowDependencyConnect: true, onCreateDependency: handleCreateDependencyFromGraph, onCreateChildRelationship: handleCreateChildRelationshipFromGraph, canPersistLayout: true, layoutSaveDebounceMs: 0, highlightBlockedTasks: false, showExecutionStateBadges: false, emptyStateTitle: "No task templates yet", emptyStateDescription: "Add task templates to start designing the project flow.", onPersistLayout: async (layout) => {
1442
- const nextLayout = {
1443
- ...layout,
1444
- projectTemplateId: draftTemplate.id,
1445
- };
1446
- applyDraftChange((currentTemplate) => ({
1480
+ const renderTemplateTaskEditorMain = () => {
1481
+ if (!draftTemplate) {
1482
+ return null;
1483
+ }
1484
+ const graphView = (_jsx("div", { className: "h-full min-h-0 overflow-hidden bg-slate-50/40", "data-testid": "project-template-graph", children: _jsx(DependencyGraphView, { projectId: draftTemplate.id, layoutKey: `project-template:${draftTemplate.id}`, tasks: graphTasks, dependencies: graphDependencies, miniMapWidth: 56, miniMapHeight: 42, showMiniMap: !isMobile, orientation: "horizontal", showOrientationToggle: true, autoLayoutStrategy: "hierarchy", savedLayout: draftTemplate.graphLayout, selectedTaskId: selectedTaskId, selectedDependencyId: selectedDependencyId, onSelectTask: handleSelectTask, onSelectDependency: handleSelectDependencyFromGraph, onClearDependencySelection: handleClearDependencySelection, onAddDependentTaskFromNode: (taskId) => {
1485
+ void handleOpenCreateDependentTaskDialogForTask(taskId);
1486
+ }, onAddChildTaskFromNode: (taskId) => {
1487
+ void handleOpenAddChildTaskDialogForTask(taskId);
1488
+ }, onRemoveTask: removeTaskTemplateById, allowDependencyConnect: true, onCreateDependency: handleCreateDependencyFromGraph, onCreateChildRelationship: handleCreateChildRelationshipFromGraph, canPersistLayout: true, layoutSaveDebounceMs: 0, highlightBlockedTasks: false, showExecutionStateBadges: false, emptyStateTitle: "No task templates yet", emptyStateDescription: "Add task templates to start designing the project flow.", onPersistLayout: async (layout) => {
1489
+ const nextLayout = {
1490
+ ...layout,
1491
+ projectTemplateId: draftTemplate.id,
1492
+ };
1493
+ applyDraftChange((currentTemplate) => ({
1494
+ ...currentTemplate,
1495
+ graphLayout: nextLayout,
1496
+ }));
1497
+ return nextLayout;
1498
+ } }) }));
1499
+ const taskPane = (_jsx("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", "data-testid": "project-template-task-detail-pane", children: !selectedTask ? (_jsx("div", { className: "min-h-0 flex-1 overflow-y-auto p-4", children: _jsx("div", { className: "rounded-lg border border-dashed border-gray-200 bg-gray-50 p-6 text-center text-xs text-gray-500", children: "Select a task node to edit its details." }) })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "shrink-0 border-b border-gray-100 bg-white px-4 pt-4 pb-3", children: _jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "text-xs font-semibold text-gray-900", "data-testid": "project-template-selected-task-title", children: selectedTask.title || "Untitled Task" }), selectedTask.disabled ? (_jsx(Badge, { variant: "outline", className: "text-[10px] uppercase", children: "Disabled" })) : null] }), _jsx("div", { className: "text-xs text-gray-500", children: "Configure task details, assignment, and dependencies." })] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: handleDeleteSelectedTask, "data-testid": "project-template-remove-task-button", children: [_jsx(Trash2, { className: "h-4 w-4", strokeWidth: 1.5 }), "Remove Task"] })] }) }), _jsx("div", { className: "min-h-0 flex-1 overflow-y-auto px-4 pt-3 pb-4", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [_jsxs("div", { className: "grid gap-1.5 md:col-span-2", children: [_jsx(Label, { className: "text-xs", children: "Task title" }), _jsx(Input, { value: selectedTask.title, onChange: (event) => updateSelectedTask((currentTask) => ({
1500
+ ...currentTask,
1501
+ title: event.target.value,
1502
+ })), placeholder: "Task title", className: "text-xs md:text-xs", "data-testid": "project-template-task-title-input" })] }), _jsxs("div", { className: "grid gap-1.5 md:col-span-2", children: [_jsx(Label, { className: "text-xs", children: "Description" }), _jsx(Textarea, { className: "text-xs", value: selectedTask.description ?? "", onChange: (event) => updateSelectedTask((currentTask) => ({
1503
+ ...currentTask,
1504
+ description: event.target.value,
1505
+ })), rows: 4, placeholder: "Describe what this task should accomplish", "data-testid": "project-template-task-description-input" })] }), _jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { className: "text-xs", children: "Priority" }), _jsx(Select, { className: "text-xs", value: selectedTask.priority ?? "", onValueChange: (value) => updateSelectedTask((currentTask) => ({
1506
+ ...currentTask,
1507
+ priority: value || null,
1508
+ })), options: PRIORITY_OPTIONS, "data-testid": "project-template-task-priority-select" })] }), _jsxs("div", { className: "grid gap-1.5 md:col-span-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx(Label, { className: "text-xs", children: "Default assignee" }), selectedTask.assigneeType === "Agent" ? (_jsxs(Button, { type: "button", size: "sm", variant: "outline", className: "h-7 gap-1 px-2 text-xs", onClick: () => void handleEditAssignedAgentProfile(), disabled: !selectedAgentProfileId, "data-testid": "project-template-task-edit-agent-profile-button", children: [_jsx(Settings2, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }), "Edit Profile"] })) : null] }), _jsx(TaskAssigneePicker, { projectTemplateId: draftTemplate.id, assigneeType: selectedTask.assigneeType ?? null, value: selectedTask.assigneeId ?? null, displayValue: selectedTaskAssigneeDisplayValue, onChange: (next) => updateSelectedTask((currentTask) => ({
1509
+ ...currentTask,
1510
+ assigneeType: next?.assigneeType ?? null,
1511
+ assigneeId: next?.assigneeId ?? null,
1512
+ agentProfileId: next?.assigneeType === "Agent"
1513
+ ? next.assigneeId
1514
+ : null,
1515
+ })), placeholder: "Assign user or agent", buttonClassName: "h-8 w-full justify-between rounded-md bg-white text-xs font-medium", buttonTestId: "project-template-task-assignee-picker" }), profilesError ? (_jsx("div", { className: "text-xs text-amber-700", children: profilesError })) : null] })] }), _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "rounded-lg border border-gray-200 bg-gray-50 p-3", "data-testid": "project-template-dependencies-section", children: [_jsxs("div", { className: "mb-2 flex items-center justify-between gap-2", children: [_jsxs("div", { className: "flex items-center gap-2 text-xs font-medium text-gray-800", children: [_jsx(Shield, { className: "h-4 w-4 text-gray-500", strokeWidth: 1.5 }), "Dependencies"] }), _jsxs(Popover, { open: dependencyPickerOpen, onOpenChange: setDependencyPickerOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { type: "button", size: "sm", variant: "outline", className: "h-7 gap-1 px-2", disabled: dependencyAddCandidates.length === 0, "aria-label": "Add dependency", "data-testid": "project-template-add-dependency-button", children: _jsx(Plus, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }) }) }), _jsxs(PopoverContent, { align: "end", className: "w-72 p-0", sideOffset: 6, "data-testid": "project-template-dependency-popover", children: [_jsx("div", { className: "border-b border-gray-100 px-3 py-2 text-xs font-medium text-gray-700", children: "Depends on" }), _jsx("div", { className: "max-h-56 overflow-y-auto p-1", children: dependencyAddCandidates.length === 0 ? (_jsx("div", { className: "px-2 py-3 text-center text-xs text-gray-500", children: "All other tasks are already linked." })) : (dependencyAddCandidates.map((task) => (_jsxs("button", { type: "button", className: "flex w-full items-center gap-2 rounded-md px-2 py-2 text-left text-xs hover:bg-gray-100", onClick: () => handleAddDependency(task.id), "data-testid": `project-template-dependency-option-${task.id}`, children: [_jsx(Link2, { className: "h-3.5 w-3.5 shrink-0 text-gray-400", strokeWidth: 1.5 }), _jsx("span", { className: "min-w-0 truncate font-medium text-gray-900", children: task.title || "Untitled Task" })] }, task.id)))) })] })] })] }), _jsx("p", { className: "mb-2 text-[11px] leading-snug text-gray-500", children: "This task must wait for these tasks to finish first." }), dependencyTasks.length === 0 ? (_jsx("div", { className: "text-xs text-gray-500", children: draftTemplate.taskTemplates.filter((t) => t.id !== selectedTask.id).length === 0
1516
+ ? "Add more task templates to create dependencies."
1517
+ : "No dependencies yet. Use + to add one." })) : (_jsx("ul", { className: "space-y-1.5", children: dependencyTasks.map((task) => (_jsxs("li", { tabIndex: 0, className: cn("flex items-center justify-between gap-2 rounded-md border bg-white px-3 py-2 text-xs transition-colors outline-none", selectedDependencyId === task.id
1518
+ ? "border-amber-300 bg-amber-50 ring-1 ring-amber-200"
1519
+ : "border-gray-200"), "aria-selected": selectedDependencyId === task.id, onClick: () => setSelectedDependencyId(task.id), onFocus: () => setSelectedDependencyId(task.id), "data-testid": `project-template-dependency-row-${task.id}`, children: [_jsx("span", { className: "min-w-0 truncate font-medium text-gray-800", children: task.title || "Untitled Task" }), _jsx("button", { type: "button", className: "shrink-0 rounded p-0.5 text-gray-400 hover:bg-gray-100 hover:text-gray-700", "aria-label": `Remove dependency on ${task.title}`, onClick: () => handleRemoveDependency(task.id), "data-testid": `project-template-remove-dependency-${task.id}`, children: _jsx(X, { className: "h-4 w-4", strokeWidth: 1.5 }) })] }, task.id))) }))] }), _jsxs("div", { className: "rounded-lg border border-gray-200 bg-gray-50 p-3", "data-testid": "project-template-child-tasks-section", children: [_jsxs("div", { className: "mb-2 flex items-center justify-between gap-2", children: [_jsxs("div", { className: "flex items-center gap-2 text-xs font-medium text-gray-800", children: [_jsx(CornerDownRight, { className: "h-4 w-4 text-gray-500", strokeWidth: 1.5 }), "Child tasks"] }), _jsx(Button, { type: "button", size: "sm", variant: "outline", className: "h-7 gap-1 px-2", onClick: () => void handleOpenAddChildTaskDialog(), disabled: creatingChildTask, "aria-label": "Add child task", "data-testid": "project-template-add-child-task-button", children: _jsx(Plus, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }) })] }), _jsx("p", { className: "mb-2 text-[11px] leading-snug text-gray-500", children: "Tasks that run after this one (they depend on this task)." }), childTaskTemplates.length === 0 ? (_jsx("div", { className: "text-xs text-gray-500", children: "No child tasks yet. Use + to add one." })) : (_jsx("ul", { className: "space-y-1.5", children: childTaskTemplates.map((task) => (_jsxs("li", { className: "flex items-center justify-between gap-2 rounded-md border border-gray-200 bg-white px-3 py-2 text-xs", "data-testid": `project-template-child-task-row-${task.id}`, children: [_jsx("span", { className: "min-w-0 truncate font-medium text-gray-800", children: task.title || "Untitled Task" }), _jsx("button", { type: "button", className: "shrink-0 rounded p-0.5 text-gray-400 hover:bg-gray-100 hover:text-gray-700", "aria-label": `Unlink child task ${task.title}`, onClick: () => handleUnlinkChildTask(task.id), "data-testid": `project-template-unlink-child-task-${task.id}`, children: _jsx(X, { className: "h-4 w-4", strokeWidth: 1.5 }) })] }, task.id))) }))] })] })] }) })] })) }));
1520
+ if (isMobile) {
1521
+ return (_jsxs("div", { className: "flex shrink-0 flex-col border-b border-gray-100", children: [_jsx("div", { className: "h-[300px] shrink-0 overflow-hidden border-b border-gray-100", children: graphView }), taskPane] }));
1522
+ }
1523
+ return (_jsx("div", { className: "min-h-[360px] flex-1 overflow-hidden border-b border-gray-100", children: _jsx(Splitter, { direction: "vertical", localStorageKey: "settings-project-template-graph-task-splitter-v1", className: "h-full", panels: [
1524
+ {
1525
+ name: "project-template-graph",
1526
+ defaultSize: 400,
1527
+ className: "min-h-0",
1528
+ content: graphView,
1529
+ },
1530
+ {
1531
+ name: "project-template-task-details",
1532
+ defaultSize: "auto",
1533
+ className: "min-h-0",
1534
+ content: taskPane,
1535
+ },
1536
+ ] }) }));
1537
+ };
1538
+ const detailContent = draftTemplate ? (_jsxs("div", { className: "flex h-full flex-col bg-gray-50/40", "data-testid": "project-template-detail-pane", children: [_jsxs("div", { className: cn("gap-3 border-b border-gray-200 bg-white px-5 py-3.5", isMobile
1539
+ ? "grid grid-cols-[minmax(0,1fr)_auto] items-center gap-x-3"
1540
+ : "flex items-center justify-between"), children: [_jsx("div", { className: "min-w-0", children: _jsxs("div", { className: "flex items-center gap-2", children: [isMobile ? (_jsx("button", { type: "button", className: "shrink-0 rounded-md p-1.5 text-gray-700 hover:bg-gray-100 md:hidden", onClick: handleMobileBackToList, "aria-label": "Back to template list", "data-testid": "project-template-mobile-back-to-list", children: _jsx(ChevronLeft, { className: "h-5 w-5", strokeWidth: 1.5 }) })) : null, _jsx("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-gray-900 text-white", children: _jsx(GitBranch, { className: "h-4 w-4", strokeWidth: 1.5 }) }), _jsxs("div", { className: "min-w-0", children: [_jsx("h2", { className: "truncate text-xs font-semibold text-gray-900", children: draftTemplate.name || "Project Template" }), _jsxs("div", { className: "mt-0.5 flex min-h-[20px] items-center gap-2 text-[11px] text-gray-500", children: [_jsxs("span", { children: [draftTemplate.taskTemplates.length, " task templates"] }), headerStatusBadge] })] })] }) }), _jsxs("div", { className: "flex shrink-0 items-center gap-1.5 self-center bg-white pl-1", children: [isMobile ? (_jsx(Button, { type: "button", variant: "outline", size: "icon", className: "h-9 w-9 shrink-0 md:hidden", onClick: () => setMobileView("agent"), "aria-label": "Open template assistant", title: "Open template assistant", "data-testid": "project-template-mobile-open-assistant", children: _jsx(Bot, { className: "h-4 w-4", strokeWidth: 1.5 }) })) : null, !draftTemplate.isSystem &&
1541
+ (isMobile ? (_jsx(Button, { variant: "outline", size: "icon", className: "h-9 w-9 shrink-0", onClick: () => handleDeleteTemplate(), disabled: deleting, "aria-label": deleting ? "Deleting template" : "Delete template", title: deleting ? "Deleting…" : "Delete template", "data-testid": "project-template-delete-button", children: deleting ? (_jsx(RefreshCw, { className: "h-4 w-4 animate-spin", strokeWidth: 1.5 })) : (_jsx(Trash2, { className: "h-4 w-4", strokeWidth: 1.5 })) })) : (_jsxs(Button, { variant: "outline", size: "sm", onClick: () => handleDeleteTemplate(), disabled: deleting, "data-testid": "project-template-delete-button", children: [_jsx(Trash2, { className: "h-4 w-4", strokeWidth: 1.5 }), deleting ? "Deleting..." : "Delete"] })))] })] }), _jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-5 overflow-y-auto overscroll-y-contain p-5 md:overflow-hidden", children: [_jsxs("div", { className: "flex shrink-0 flex-col gap-5 md:max-h-[50vh] md:min-h-0 md:overflow-y-auto md:overscroll-y-contain", children: [saveError && (_jsx("div", { className: "rounded border border-red-200 bg-red-50 px-4 py-3 text-xs text-red-700", children: saveError })), _jsxs("section", { className: "shrink-0 rounded-lg border border-gray-200 bg-white shadow-sm md:overflow-hidden", children: [_jsxs("button", { type: "button", className: "flex w-full items-center justify-between gap-3 px-4 py-3 text-left", onClick: () => setIsBasicSettingsExpanded((currentValue) => !currentValue), "aria-expanded": isBasicSettingsExpanded, "aria-controls": "project-template-basic-settings", "data-testid": "project-template-basic-settings-toggle", children: [_jsxs("div", { className: "flex items-center gap-2.5", children: [_jsx("span", { className: "flex h-6 w-6 items-center justify-center rounded-md bg-gray-100 text-gray-500", children: _jsx(Settings2, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }) }), _jsxs("div", { children: [_jsx("h3", { className: "text-xs font-semibold tracking-wide text-gray-800", children: "Basic Settings" }), _jsx("p", { className: "text-[11px] leading-tight text-gray-400", children: "Configure the shared defaults for this project template." })] })] }), _jsx(ChevronDown, { className: cn("h-4 w-4 shrink-0 text-gray-400 transition-transform", isBasicSettingsExpanded ? "rotate-180" : "rotate-0"), strokeWidth: 1.5 })] }), isBasicSettingsExpanded && (_jsxs("div", { id: "project-template-basic-settings", className: "grid gap-4 border-t border-gray-100 p-4 md:grid-cols-2", children: [_jsxs("div", { className: "grid gap-1.5 md:col-span-2", children: [_jsx(Label, { className: "text-xs", children: "Template name" }), _jsx(Input, { value: draftTemplate.name, onChange: (event) => applyDraftChange((currentTemplate) => ({
1542
+ ...currentTemplate,
1543
+ name: event.target.value,
1544
+ })), placeholder: "Project template name", className: "text-xs md:text-xs", "data-testid": "project-template-name-input" })] }), _jsxs("div", { className: "grid gap-1.5 md:col-span-2", children: [_jsx(Label, { className: "text-xs", children: "Description" }), _jsx(Textarea, { className: "text-xs", value: draftTemplate.description ?? "", onChange: (event) => applyDraftChange((currentTemplate) => ({
1545
+ ...currentTemplate,
1546
+ description: event.target.value,
1547
+ })), rows: 4, placeholder: "Describe when to use this template", "data-testid": "project-template-description-input" })] }), _jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { className: "text-xs", children: "Default cost limit" }), _jsx(Input, { type: "number", value: draftTemplate.defaultCostLimit ?? "", onChange: (event) => applyDraftChange((currentTemplate) => ({
1548
+ ...currentTemplate,
1549
+ defaultCostLimit: event.target.value.trim() === ""
1550
+ ? null
1551
+ : Number(event.target.value),
1552
+ })), placeholder: "0", className: "text-xs md:text-xs", "data-testid": "project-template-default-cost-limit-input" })] }), _jsxs("div", { className: "flex items-center justify-between gap-4 md:col-span-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "text-xs font-medium text-zinc-900", children: "Disabled" }), _jsx("div", { className: "mt-0.5 text-xs text-zinc-500", children: "Makes the template unavailable for project creation and template resolution." })] }), _jsx(Switch, { checked: draftTemplate.disabled === true, onCheckedChange: (checked) => applyDraftChange((currentTemplate) => ({
1553
+ ...currentTemplate,
1554
+ disabled: checked,
1555
+ })), className: "data-[state=checked]:bg-amber-600 data-[state=checked]:shadow-inner dark:data-[state=checked]:bg-amber-600", "aria-label": "Disable this project template", "data-testid": "project-template-disabled-switch" })] }), _jsxs("div", { className: "flex items-center justify-between gap-4 md:col-span-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "text-xs font-medium text-zinc-900", children: "Hide from create dialog" }), _jsx("div", { className: "mt-0.5 text-xs text-zinc-500", children: "Keeps the template active, but removes it from the create project dialog." })] }), _jsx(Switch, { checked: draftTemplate.hideFromCreateDialog === true, onCheckedChange: (checked) => applyDraftChange((currentTemplate) => ({
1556
+ ...currentTemplate,
1557
+ hideFromCreateDialog: checked,
1558
+ })), "aria-label": "Hide this project template from the create dialog", "data-testid": "project-template-hide-from-create-dialog-switch" })] }), _jsxs("div", { className: "flex items-center justify-between gap-4 md:col-span-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "text-xs font-medium text-zinc-900", children: "Open in wizard mode" }), _jsx("div", { className: "mt-0.5 text-xs text-zinc-500", children: "New projects created from this template start in taskboard wizard mode." })] }), _jsx(Switch, { checked: draftTemplate.openInWizardMode === true, onCheckedChange: (checked) => applyDraftChange((currentTemplate) => ({
1447
1559
  ...currentTemplate,
1448
- graphLayout: nextLayout,
1449
- }));
1450
- return nextLayout;
1451
- } }) })),
1452
- },
1453
- {
1454
- name: "project-template-task-details",
1455
- defaultSize: "auto",
1456
- className: "min-h-0",
1457
- content: (_jsx("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", "data-testid": "project-template-task-detail-pane", children: !selectedTask ? (_jsx("div", { className: "min-h-0 flex-1 overflow-y-auto p-4", children: _jsx("div", { className: "rounded-lg border border-dashed border-gray-200 bg-gray-50 p-6 text-center text-xs text-gray-500", children: "Select a task node to edit its details." }) })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "shrink-0 border-b border-gray-100 bg-white px-4 pt-4 pb-3", children: _jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "text-xs font-semibold text-gray-900", "data-testid": "project-template-selected-task-title", children: selectedTask.title || "Untitled Task" }), selectedTask.disabled ? (_jsx(Badge, { variant: "outline", className: "text-[10px] uppercase", children: "Disabled" })) : null] }), _jsx("div", { className: "text-xs text-gray-500", children: "Configure task details, assignment, and dependencies." })] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: handleDeleteSelectedTask, "data-testid": "project-template-remove-task-button", children: [_jsx(Trash2, { className: "h-4 w-4", strokeWidth: 1.5 }), "Remove Task"] })] }) }), _jsx("div", { className: "min-h-0 flex-1 overflow-y-auto px-4 pt-3 pb-4", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [_jsxs("div", { className: "grid gap-1.5 md:col-span-2", children: [_jsx(Label, { className: "text-xs", children: "Task title" }), _jsx(Input, { value: selectedTask.title, onChange: (event) => updateSelectedTask((currentTask) => ({
1458
- ...currentTask,
1459
- title: event.target.value,
1460
- })), placeholder: "Task title", className: "text-xs md:text-xs", "data-testid": "project-template-task-title-input" })] }), _jsxs("div", { className: "grid gap-1.5 md:col-span-2", children: [_jsx(Label, { className: "text-xs", children: "Description" }), _jsx(Textarea, { className: "text-xs", value: selectedTask.description ?? "", onChange: (event) => updateSelectedTask((currentTask) => ({
1461
- ...currentTask,
1462
- description: event.target.value,
1463
- })), rows: 4, placeholder: "Describe what this task should accomplish", "data-testid": "project-template-task-description-input" })] }), _jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { className: "text-xs", children: "Priority" }), _jsx(Select, { className: "text-xs", value: selectedTask.priority ?? "", onValueChange: (value) => updateSelectedTask((currentTask) => ({
1464
- ...currentTask,
1465
- priority: value || null,
1466
- })), options: PRIORITY_OPTIONS, "data-testid": "project-template-task-priority-select" })] }), _jsxs("div", { className: "flex items-center justify-between gap-4 md:col-span-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx(Label, { htmlFor: `project-template-task-disabled-${selectedTask.id}`, className: "text-xs font-medium text-zinc-900", children: "Disabled" }), _jsx("div", { className: "mt-0.5 text-xs text-zinc-500", children: "Keep this task in the template, but skip it when projects are created." })] }), _jsx(Switch, { id: `project-template-task-disabled-${selectedTask.id}`, checked: selectedTask.disabled === true, onCheckedChange: (checked) => updateSelectedTask((currentTask) => ({
1467
- ...currentTask,
1468
- disabled: checked,
1469
- })), "aria-label": "Disable this task template", "data-testid": "project-template-task-disabled-switch" })] }), _jsxs("div", { className: "grid gap-1.5 md:col-span-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx(Label, { className: "text-xs", children: "Default assignee" }), selectedTask.assigneeType === "Agent" ? (_jsxs(Button, { type: "button", size: "sm", variant: "outline", className: "h-7 gap-1 px-2 text-xs", onClick: () => void handleEditAssignedAgentProfile(), disabled: !selectedAgentProfileId, "data-testid": "project-template-task-edit-agent-profile-button", children: [_jsx(Settings2, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }), "Edit Profile"] })) : null] }), _jsx(TaskAssigneePicker, { projectTemplateId: draftTemplate.id, assigneeType: selectedTask.assigneeType ?? null, value: selectedTask.assigneeId ?? null, displayValue: selectedTaskAssigneeDisplayValue, onChange: (next) => updateSelectedTask((currentTask) => ({
1470
- ...currentTask,
1471
- assigneeType: next?.assigneeType ?? null,
1472
- assigneeId: next?.assigneeId ?? null,
1473
- agentProfileId: next?.assigneeType === "Agent"
1474
- ? next.assigneeId
1475
- : null,
1476
- })), placeholder: "Assign user or agent", buttonClassName: "h-8 w-full justify-between rounded-md bg-white text-xs font-medium", buttonTestId: "project-template-task-assignee-picker" }), profilesError ? (_jsx("div", { className: "text-xs text-amber-700", children: profilesError })) : null] })] }), _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "rounded-lg border border-gray-200 bg-gray-50 p-3", "data-testid": "project-template-dependencies-section", children: [_jsxs("div", { className: "mb-2 flex items-center justify-between gap-2", children: [_jsxs("div", { className: "flex items-center gap-2 text-xs font-medium text-gray-800", children: [_jsx(Shield, { className: "h-4 w-4 text-gray-500", strokeWidth: 1.5 }), "Dependencies"] }), _jsxs(Popover, { open: dependencyPickerOpen, onOpenChange: setDependencyPickerOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { type: "button", size: "sm", variant: "outline", className: "h-7 gap-1 px-2", disabled: dependencyAddCandidates.length === 0, "aria-label": "Add dependency", "data-testid": "project-template-add-dependency-button", children: _jsx(Plus, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }) }) }), _jsxs(PopoverContent, { align: "end", className: "w-72 p-0", sideOffset: 6, "data-testid": "project-template-dependency-popover", children: [_jsx("div", { className: "border-b border-gray-100 px-3 py-2 text-xs font-medium text-gray-700", children: "Depends on" }), _jsx("div", { className: "max-h-56 overflow-y-auto p-1", children: dependencyAddCandidates.length ===
1477
- 0 ? (_jsx("div", { className: "px-2 py-3 text-center text-xs text-gray-500", children: "All other tasks are already linked." })) : (dependencyAddCandidates.map((task) => (_jsxs("button", { type: "button", className: "flex w-full items-center gap-2 rounded-md px-2 py-2 text-left text-xs hover:bg-gray-100", onClick: () => handleAddDependency(task.id), "data-testid": `project-template-dependency-option-${task.id}`, children: [_jsx(Link2, { className: "h-3.5 w-3.5 shrink-0 text-gray-400", strokeWidth: 1.5 }), _jsx("span", { className: "min-w-0 truncate font-medium text-gray-900", children: task.title ||
1478
- "Untitled Task" })] }, task.id)))) })] })] })] }), _jsx("p", { className: "mb-2 text-[11px] leading-snug text-gray-500", children: "This task must wait for these tasks to finish first." }), dependencyTasks.length === 0 ? (_jsx("div", { className: "text-xs text-gray-500", children: draftTemplate.taskTemplates.filter((t) => t.id !== selectedTask.id).length === 0
1479
- ? "Add more task templates to create dependencies."
1480
- : "No dependencies yet. Use + to add one." })) : (_jsx("ul", { className: "space-y-1.5", children: dependencyTasks.map((task) => (_jsxs("li", { tabIndex: 0, className: cn("flex items-center justify-between gap-2 rounded-md border bg-white px-3 py-2 text-xs outline-none transition-colors", selectedDependencyId === task.id
1481
- ? "border-amber-300 bg-amber-50 ring-1 ring-amber-200"
1482
- : "border-gray-200"), "aria-selected": selectedDependencyId === task.id, onClick: () => setSelectedDependencyId(task.id), onFocus: () => setSelectedDependencyId(task.id), "data-testid": `project-template-dependency-row-${task.id}`, children: [_jsx("span", { className: "min-w-0 truncate font-medium text-gray-800", children: task.title || "Untitled Task" }), _jsx("button", { type: "button", className: "shrink-0 rounded p-0.5 text-gray-400 hover:bg-gray-100 hover:text-gray-700", "aria-label": `Remove dependency on ${task.title}`, onClick: () => handleRemoveDependency(task.id), "data-testid": `project-template-remove-dependency-${task.id}`, children: _jsx(X, { className: "h-4 w-4", strokeWidth: 1.5 }) })] }, task.id))) }))] }), _jsxs("div", { className: "rounded-lg border border-gray-200 bg-gray-50 p-3", "data-testid": "project-template-child-tasks-section", children: [_jsxs("div", { className: "mb-2 flex items-center justify-between gap-2", children: [_jsxs("div", { className: "flex items-center gap-2 text-xs font-medium text-gray-800", children: [_jsx(CornerDownRight, { className: "h-4 w-4 text-gray-500", strokeWidth: 1.5 }), "Child tasks"] }), _jsx(Button, { type: "button", size: "sm", variant: "outline", className: "h-7 gap-1 px-2", onClick: () => void handleOpenAddChildTaskDialog(), disabled: creatingChildTask, "aria-label": "Add child task", "data-testid": "project-template-add-child-task-button", children: _jsx(Plus, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }) })] }), _jsx("p", { className: "mb-2 text-[11px] leading-snug text-gray-500", children: "Tasks that run after this one (they depend on this task)." }), childTaskTemplates.length === 0 ? (_jsx("div", { className: "text-xs text-gray-500", children: "No child tasks yet. Use + to add one." })) : (_jsx("ul", { className: "space-y-1.5", children: childTaskTemplates.map((task) => (_jsxs("li", { className: "flex items-center justify-between gap-2 rounded-md border border-gray-200 bg-white px-3 py-2 text-xs", "data-testid": `project-template-child-task-row-${task.id}`, children: [_jsx("span", { className: "min-w-0 truncate font-medium text-gray-800", children: task.title || "Untitled Task" }), _jsx("button", { type: "button", className: "shrink-0 rounded p-0.5 text-gray-400 hover:bg-gray-100 hover:text-gray-700", "aria-label": `Unlink child task ${task.title}`, onClick: () => handleUnlinkChildTask(task.id), "data-testid": `project-template-unlink-child-task-${task.id}`, children: _jsx(X, { className: "h-4 w-4", strokeWidth: 1.5 }) })] }, task.id))) }))] })] })] }) })] })) })),
1483
- },
1484
- ] }) })] })] })] })) : (_jsx("div", { className: "flex h-full items-center justify-center bg-gray-50/40", children: _jsxs("div", { className: "max-w-sm rounded-lg border border-dashed border-gray-300 bg-white p-8 text-center", children: [_jsx(GitBranch, { className: "mx-auto mb-3 h-10 w-10 text-gray-300", strokeWidth: 1.2 }), _jsx("h3", { className: "text-xs font-semibold text-gray-900", children: "Select a project template" }), _jsx("p", { className: "mt-1 text-xs text-gray-500", children: "Choose a template from the list or create a new one to start editing." })] }) }));
1485
- const agentPanelContent = (_jsx(ProjectTemplateAgentPanel, { templateName: draftTemplate?.name ?? null, agentId: templateAgentId, loading: templateAgentLoading, resetting: templateAgentResetting, error: templateAgentError, onStartOver: () => void handleResetTemplateAgent() }));
1560
+ openInWizardMode: checked,
1561
+ })), "aria-label": "Open new projects from this template in wizard mode", "data-testid": "project-template-open-in-wizard-mode-switch" })] })] }))] })] }), _jsxs("section", { className: "flex shrink-0 flex-col rounded-lg border border-gray-200 bg-white shadow-sm md:min-h-0 md:flex-1 md:overflow-hidden", children: [_jsxs("div", { className: "flex shrink-0 items-center justify-between gap-3 border-b border-gray-100 px-4 py-3", children: [_jsxs("div", { className: "flex items-center gap-2.5", children: [_jsx("span", { className: "flex h-6 w-6 items-center justify-center rounded-md bg-gray-100 text-gray-500", children: _jsx(GitBranch, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }) }), _jsxs("div", { children: [_jsx("h3", { className: "text-xs font-semibold tracking-wide text-gray-800", children: "Template Task Editor" }), _jsx("p", { className: "text-[11px] leading-tight text-gray-400", children: "Add task templates, arrange them in the graph, and define dependencies." })] })] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: () => void handleOpenCreateTaskDialog(), disabled: creatingTask, "data-testid": "project-template-add-task-button", children: [_jsx(Plus, { className: "h-4 w-4", strokeWidth: 1.5 }), "Add Task"] })] }), renderTemplateTaskEditorMain()] })] })] })) : (_jsx("div", { className: "flex h-full items-center justify-center bg-gray-50/40", children: _jsxs("div", { className: "max-w-sm rounded-lg border border-dashed border-gray-300 bg-white p-8 text-center", children: [_jsx(GitBranch, { className: "mx-auto mb-3 h-10 w-10 text-gray-300", strokeWidth: 1.2 }), _jsx("h3", { className: "text-xs font-semibold text-gray-900", children: "Select a project template" }), _jsx("p", { className: "mt-1 text-xs text-gray-500", children: "Choose a template from the list or create a new one to start editing." })] }) }));
1562
+ const agentPanelContent = (_jsx(ProjectTemplateAgentPanel, { templateName: draftTemplate?.name ?? null, agentId: templateAgentId, loading: templateAgentLoading, resetting: templateAgentResetting, error: templateAgentError, onStartOver: () => void handleResetTemplateAgent(), onExpandAssistant: () => setDesktopAssistantOnly(true), showExpandAssistant: !isMobile && !desktopAssistantOnly && !!draftTemplate, headerStart: isMobile ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "gap-1 px-2", onClick: handleMobileBackFromAgent, "data-testid": "project-template-mobile-back-from-agent", children: _jsx(ChevronLeft, { className: "h-5 w-5", strokeWidth: 1.5 }) })) : undefined }));
1486
1563
  const rightPanelContent = editingAgentProfile ? (_jsx(AgentProfileEditorPanel, { agent: editingAgentProfile, onClose: handleCloseEditingAgentProfile, actions: _jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: () => void handleDuplicateAssignedAgentProfile(), disabled: !selectedAgentProfileId ||
1487
1564
  !editContext ||
1488
1565
  duplicatingAgentProfile ||
1489
1566
  editingAgentProfile.id !== selectedAgentProfileId, "data-testid": "project-template-task-duplicate-agent-profile-button", children: [_jsx(CopyPlus, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }), duplicatingAgentProfile ? "Duplicating..." : "Duplicate"] }) })) : (agentPanelContent);
1567
+ const rightPanelForSplitter = !isMobile && desktopAssistantOnly ? (_jsxs("div", { className: "flex h-full min-h-0 flex-col bg-white", "data-testid": "project-template-desktop-assistant-only", children: [_jsx("div", { className: "flex shrink-0 items-center gap-2 border-b border-gray-200 bg-white px-2 py-2", children: _jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "gap-1 px-2", onClick: () => setDesktopAssistantOnly(false), "data-testid": "project-template-desktop-back-from-assistant-only", children: [_jsx(ChevronLeft, { className: "h-5 w-5", strokeWidth: 1.5 }), "Back to template editor"] }) }), _jsx("div", { className: "min-h-0 flex-1 overflow-hidden", children: rightPanelContent })] })) : (rightPanelContent);
1490
1568
  const panels = [
1491
1569
  {
1492
1570
  name: "project-template-list",
1493
1571
  defaultSize: 360,
1494
1572
  content: listContent,
1495
1573
  className: "overflow-hidden",
1574
+ hidden: desktopAssistantOnly || (isMobile && mobileView !== "list"),
1496
1575
  },
1497
1576
  {
1498
1577
  name: "project-template-detail",
1499
1578
  defaultSize: "auto",
1500
1579
  content: detailContent,
1501
1580
  className: "overflow-hidden",
1581
+ hidden: desktopAssistantOnly || (isMobile && mobileView !== "detail"),
1502
1582
  },
1503
1583
  {
1504
1584
  name: "project-template-agent",
1505
1585
  defaultSize: 460,
1506
- content: rightPanelContent,
1586
+ content: rightPanelForSplitter,
1507
1587
  className: "overflow-hidden",
1508
1588
  collapsible: true,
1589
+ hidden: isMobile && mobileView !== "agent",
1509
1590
  },
1510
1591
  ];
1511
1592
  return (_jsxs(_Fragment, { children: [_jsx("div", { className: "h-full", "data-testid": "project-template-editor", onKeyDownCapture: handleProjectTemplateEditorKeyDownCapture, children: _jsx(Splitter, { panels: panels, localStorageKey: "settings-project-templates-panel-splitter-v2", direction: "horizontal", className: "h-full" }) }), _jsx(Dialog, { open: isCreateTaskDialogOpen, onOpenChange: (open) => {