@parhelia/core 0.1.12468 → 0.1.12477

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 (134) hide show
  1. package/dist/config/config.js +2 -21
  2. package/dist/config/config.js.map +1 -1
  3. package/dist/config/types.d.ts +0 -2
  4. package/dist/config/types.js.map +1 -1
  5. package/dist/editor/ConfirmationDialog.js +4 -20
  6. package/dist/editor/ConfirmationDialog.js.map +1 -1
  7. package/dist/editor/ContentTree.js +7 -19
  8. package/dist/editor/ContentTree.js.map +1 -1
  9. package/dist/editor/Editor.js.map +1 -1
  10. package/dist/editor/PictureCropper.js +41 -45
  11. package/dist/editor/PictureCropper.js.map +1 -1
  12. package/dist/editor/ai/AgentTerminal.js +8 -97
  13. package/dist/editor/ai/AgentTerminal.js.map +1 -1
  14. package/dist/editor/ai/AgentTerminalStatusBar.js +0 -65
  15. package/dist/editor/ai/AgentTerminalStatusBar.js.map +1 -1
  16. package/dist/editor/ai/Agents.js +0 -19
  17. package/dist/editor/ai/Agents.js.map +1 -1
  18. package/dist/editor/ai/AiResponseMessage.js +0 -5
  19. package/dist/editor/ai/AiResponseMessage.js.map +1 -1
  20. package/dist/editor/ai/ContentInspectorPopover.d.ts +0 -1
  21. package/dist/editor/ai/ContentInspectorPopover.js +8 -22
  22. package/dist/editor/ai/ContentInspectorPopover.js.map +1 -1
  23. package/dist/editor/ai/ToolCallDisplay.d.ts +0 -2
  24. package/dist/editor/ai/ToolCallDisplay.js +11 -54
  25. package/dist/editor/ai/ToolCallDisplay.js.map +1 -1
  26. package/dist/editor/ai/dialogs/AgentDialogHandler.js +3 -32
  27. package/dist/editor/ai/dialogs/AgentDialogHandler.js.map +1 -1
  28. package/dist/editor/ai/dialogs/QuestionnaireInline.js +20 -55
  29. package/dist/editor/ai/dialogs/QuestionnaireInline.js.map +1 -1
  30. package/dist/editor/ai/dialogs/agentDialogTypes.d.ts +4 -7
  31. package/dist/editor/ai/dialogs/agentDialogTypes.js.map +1 -1
  32. package/dist/editor/ai/types.d.ts +0 -2
  33. package/dist/editor/services/agentService.d.ts +0 -27
  34. package/dist/editor/services/agentService.js +2 -11
  35. package/dist/editor/services/agentService.js.map +1 -1
  36. package/dist/editor/services/aiService.js +3 -54
  37. package/dist/editor/services/aiService.js.map +1 -1
  38. package/dist/editor/services/serviceHelper.js +2 -5
  39. package/dist/editor/services/serviceHelper.js.map +1 -1
  40. package/dist/editor/settings/About.js +4 -40
  41. package/dist/editor/settings/About.js.map +1 -1
  42. package/dist/editor/settings/panels/ProjectTemplateAgentPanel.d.ts +1 -7
  43. package/dist/editor/settings/panels/ProjectTemplateAgentPanel.js +3 -3
  44. package/dist/editor/settings/panels/ProjectTemplateAgentPanel.js.map +1 -1
  45. package/dist/editor/settings/panels/ProjectTemplatesPanel.js +84 -165
  46. package/dist/editor/settings/panels/ProjectTemplatesPanel.js.map +1 -1
  47. package/dist/editor/settings/panels/index.d.ts +0 -1
  48. package/dist/editor/settings/panels/index.js +0 -1
  49. package/dist/editor/settings/panels/index.js.map +1 -1
  50. package/dist/editor/sidebar/NavigationPanelItem.js +1 -1
  51. package/dist/editor/sidebar/NavigationPanelItem.js.map +1 -1
  52. package/dist/editor/sidebar/WorkspaceButton.js +1 -1
  53. package/dist/editor/sidebar/WorkspaceButton.js.map +1 -1
  54. package/dist/editor/tree-indicators/GutterColumns.js +4 -24
  55. package/dist/editor/tree-indicators/GutterColumns.js.map +1 -1
  56. package/dist/editor/tree-indicators/types.d.ts +0 -10
  57. package/dist/editor/ui/Splitter.d.ts +0 -1
  58. package/dist/editor/ui/Splitter.js +1 -7
  59. package/dist/editor/ui/Splitter.js.map +1 -1
  60. package/dist/licensing/LicenseContext.js +4 -40
  61. package/dist/licensing/LicenseContext.js.map +1 -1
  62. package/dist/licensing/LicenseOverlay.js +1 -1
  63. package/dist/licensing/LicenseOverlay.js.map +1 -1
  64. package/dist/licensing/types.d.ts +1 -3
  65. package/dist/licensing/types.js.map +1 -1
  66. package/dist/revision.d.ts +2 -2
  67. package/dist/revision.js +2 -2
  68. package/dist/task-board/TaskBoardWorkspace.js +354 -165
  69. package/dist/task-board/TaskBoardWorkspace.js.map +1 -1
  70. package/dist/task-board/assigneeDisplay.js +3 -1
  71. package/dist/task-board/assigneeDisplay.js.map +1 -1
  72. package/dist/task-board/components/CreateProjectDialog.js +1 -2
  73. package/dist/task-board/components/CreateProjectDialog.js.map +1 -1
  74. package/dist/task-board/components/ProjectDashboard.js +1 -2
  75. package/dist/task-board/components/ProjectDashboard.js.map +1 -1
  76. package/dist/task-board/components/ProjectSettingsDialog.d.ts +0 -1
  77. package/dist/task-board/components/ProjectSettingsDialog.js +12 -146
  78. package/dist/task-board/components/ProjectSettingsDialog.js.map +1 -1
  79. package/dist/task-board/components/TaskAgentPanel.d.ts +0 -1
  80. package/dist/task-board/components/TaskAgentPanel.js +2 -2
  81. package/dist/task-board/components/TaskAgentPanel.js.map +1 -1
  82. package/dist/task-board/components/TaskAssigneePicker.js +2 -2
  83. package/dist/task-board/components/TaskAssigneePicker.js.map +1 -1
  84. package/dist/task-board/components/TaskBoardMyTasksSidebar.js +1 -1
  85. package/dist/task-board/components/TaskBoardMyTasksSidebar.js.map +1 -1
  86. package/dist/task-board/components/TaskDetailDialog.d.ts +0 -1
  87. package/dist/task-board/components/TaskDetailDialog.js +2 -2
  88. package/dist/task-board/components/TaskDetailDialog.js.map +1 -1
  89. package/dist/task-board/components/TaskDetailPanel.d.ts +0 -1
  90. package/dist/task-board/components/TaskDetailPanel.js +8 -23
  91. package/dist/task-board/components/TaskDetailPanel.js.map +1 -1
  92. package/dist/task-board/components/TaskRow.js +2 -3
  93. package/dist/task-board/components/TaskRow.js.map +1 -1
  94. package/dist/task-board/components/WizardTaskDetailsPanel.js +1 -2
  95. package/dist/task-board/components/WizardTaskDetailsPanel.js.map +1 -1
  96. package/dist/task-board/services/taskService.d.ts +1 -17
  97. package/dist/task-board/services/taskService.js +0 -56
  98. package/dist/task-board/services/taskService.js.map +1 -1
  99. package/dist/task-board/taskExecutionRecords.js +0 -2
  100. package/dist/task-board/taskExecutionRecords.js.map +1 -1
  101. package/dist/task-board/types.d.ts +1 -78
  102. package/dist/task-board/utils/taskDependencyOrdering.d.ts +0 -6
  103. package/dist/task-board/utils/taskDependencyOrdering.js +1 -138
  104. package/dist/task-board/utils/taskDependencyOrdering.js.map +1 -1
  105. package/dist/task-board/views/DependencyGraphView.d.ts +2 -5
  106. package/dist/task-board/views/DependencyGraphView.js +69 -261
  107. package/dist/task-board/views/DependencyGraphView.js.map +1 -1
  108. package/dist/task-board/views/KanbanView.js +1 -8
  109. package/dist/task-board/views/KanbanView.js.map +1 -1
  110. package/dist/task-board/views/ListView.js +1 -1
  111. package/dist/task-board/views/ListView.js.map +1 -1
  112. package/dist/task-board/views/WizardView.js +24 -30
  113. package/dist/task-board/views/WizardView.js.map +1 -1
  114. package/dist/tour/Tour.js +47 -0
  115. package/dist/tour/Tour.js.map +1 -1
  116. package/package.json +1 -1
  117. package/dist/editor/settings/panels/PersistentLogsPanel.d.ts +0 -2
  118. package/dist/editor/settings/panels/PersistentLogsPanel.js +0 -244
  119. package/dist/editor/settings/panels/PersistentLogsPanel.js.map +0 -1
  120. package/dist/task-board/components/ProjectExecutionUserPicker.d.ts +0 -14
  121. package/dist/task-board/components/ProjectExecutionUserPicker.js +0 -65
  122. package/dist/task-board/components/ProjectExecutionUserPicker.js.map +0 -1
  123. package/dist/task-board/components/TaskboardPersistentLogPanel.d.ts +0 -11
  124. package/dist/task-board/components/TaskboardPersistentLogPanel.js +0 -141
  125. package/dist/task-board/components/TaskboardPersistentLogPanel.js.map +0 -1
  126. package/dist/task-board/persistentLogCopy.d.ts +0 -7
  127. package/dist/task-board/persistentLogCopy.js +0 -80
  128. package/dist/task-board/persistentLogCopy.js.map +0 -1
  129. package/dist/task-board/persistentLogLabels.d.ts +0 -38
  130. package/dist/task-board/persistentLogLabels.js +0 -189
  131. package/dist/task-board/persistentLogLabels.js.map +0 -1
  132. package/dist/task-board/useTaskBoardAgentPanelState.d.ts +0 -34
  133. package/dist/task-board/useTaskBoardAgentPanelState.js +0 -283
  134. package/dist/task-board/useTaskBoardAgentPanelState.js.map +0 -1
@@ -1,10 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useMemo, useState } from "react";
3
- import { Bot, Maximize2, RefreshCw, RotateCcw } from "lucide-react";
3
+ import { Bot, RefreshCw, RotateCcw } from "lucide-react";
4
4
  import { Button } from "../../../components/ui/button";
5
5
  import { AgentTerminal } from "../../ai/AgentTerminal";
6
6
  import { getAiProfilesErrorMessage, loadAiProfiles, } from "../../services/aiService";
7
- export function ProjectTemplateAgentPanel({ templateName, agentId, loading, resetting, error, onStartOver, onExpandAssistant, showExpandAssistant, headerStart, }) {
7
+ export function ProjectTemplateAgentPanel({ templateName, agentId, loading, resetting, error, onStartOver, }) {
8
8
  const [profiles, setProfiles] = useState([]);
9
9
  const [profilesError, setProfilesError] = useState(null);
10
10
  useEffect(() => {
@@ -40,7 +40,7 @@ export function ProjectTemplateAgentPanel({ templateName, agentId, loading, rese
40
40
  const headerTitle = templateName?.trim()
41
41
  ? `${templateName} Assistant`
42
42
  : "Template Assistant";
43
- return (_jsxs("div", { className: "flex h-full min-h-0 flex-col bg-white", "data-testid": "project-template-agent-panel", children: [_jsxs("div", { className: "flex items-center justify-between gap-2 border-b px-4 py-3", children: [_jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [headerStart ? (_jsx("div", { className: "shrink-0", children: headerStart })) : null, _jsx(Bot, { className: "h-5 w-5 shrink-0 text-muted-foreground" }), _jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate text-sm font-semibold", children: headerTitle }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Ask about task-project structure, dependencies, and template design." })] })] }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [showExpandAssistant && onExpandAssistant ? (_jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: onExpandAssistant, title: "Show only the assistant (hide template list and editor)", "data-testid": "project-template-agent-expand-button", children: [_jsx(Maximize2, { className: "h-4 w-4", strokeWidth: 1.5 }), _jsx("span", { className: "hidden sm:inline", children: "Expand" })] })) : null, _jsxs(Button, { variant: "outline", size: "sm", onClick: onStartOver, disabled: !templateName || loading || resetting, title: "Create a fresh assistant conversation for this template", "data-testid": "project-template-agent-reset-button", children: [resetting ? (_jsx(RefreshCw, { className: "h-4 w-4 animate-spin", strokeWidth: 1.5 })) : (_jsx(RotateCcw, { className: "h-4 w-4", strokeWidth: 1.5 })), "Start Over"] })] })] }), profilesError ? (_jsx("div", { className: "border-b border-amber-200 bg-amber-50 px-4 py-2 text-xs text-amber-700", children: profilesError })) : null, error ? (_jsx("div", { className: "border-b border-red-200 bg-red-50 px-4 py-2 text-xs text-red-700", children: error })) : null, _jsx("div", { className: "min-h-0 flex-1", children: loading ? (_jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-3 p-6 text-center", children: [_jsx(RefreshCw, { className: "h-8 w-8 animate-spin text-muted-foreground/60" }), _jsx("div", { className: "text-sm text-muted-foreground", children: "Loading template assistant..." })] })) : !templateName ? (_jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-3 p-6 text-center", children: [_jsx(Bot, { className: "h-10 w-10 text-muted-foreground/40" }), _jsxs("div", { className: "grid gap-1", children: [_jsx("div", { className: "text-sm font-medium text-muted-foreground", children: "No template selected" }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Select a project template to open its dedicated assistant." })] })] })) : !agentStub ? (_jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-3 p-6 text-center", children: [_jsx(Bot, { className: "h-10 w-10 text-muted-foreground/40" }), _jsxs("div", { className: "grid gap-1", children: [_jsx("div", { className: "text-sm font-medium text-muted-foreground", children: "Assistant unavailable" }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Try selecting the template again or use Start Over to create a fresh session." })] })] })) : (_jsx(AgentTerminal, { agentStub: agentStub, profiles: profiles, isActive: true, compact: true, hideGreeting: true, displayMode: "full", showSummaryInput: false, className: "h-full" })) })] }));
43
+ return (_jsxs("div", { className: "flex h-full min-h-0 flex-col bg-white", "data-testid": "project-template-agent-panel", children: [_jsxs("div", { className: "flex items-center justify-between gap-2 border-b px-4 py-3", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(Bot, { className: "h-5 w-5 text-muted-foreground" }), _jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate text-sm font-semibold", children: headerTitle }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Ask about task-project structure, dependencies, and template design." })] })] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: onStartOver, disabled: !templateName || loading || resetting, title: "Create a fresh assistant conversation for this template", "data-testid": "project-template-agent-reset-button", children: [resetting ? (_jsx(RefreshCw, { className: "h-4 w-4 animate-spin", strokeWidth: 1.5 })) : (_jsx(RotateCcw, { className: "h-4 w-4", strokeWidth: 1.5 })), "Start Over"] })] }), profilesError ? (_jsx("div", { className: "border-b border-amber-200 bg-amber-50 px-4 py-2 text-xs text-amber-700", children: profilesError })) : null, error ? (_jsx("div", { className: "border-b border-red-200 bg-red-50 px-4 py-2 text-xs text-red-700", children: error })) : null, _jsx("div", { className: "min-h-0 flex-1", children: loading ? (_jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-3 p-6 text-center", children: [_jsx(RefreshCw, { className: "h-8 w-8 animate-spin text-muted-foreground/60" }), _jsx("div", { className: "text-sm text-muted-foreground", children: "Loading template assistant..." })] })) : !templateName ? (_jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-3 p-6 text-center", children: [_jsx(Bot, { className: "h-10 w-10 text-muted-foreground/40" }), _jsxs("div", { className: "grid gap-1", children: [_jsx("div", { className: "text-sm font-medium text-muted-foreground", children: "No template selected" }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Select a project template to open its dedicated assistant." })] })] })) : !agentStub ? (_jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-3 p-6 text-center", children: [_jsx(Bot, { className: "h-10 w-10 text-muted-foreground/40" }), _jsxs("div", { className: "grid gap-1", children: [_jsx("div", { className: "text-sm font-medium text-muted-foreground", children: "Assistant unavailable" }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Try selecting the template again or use Start Over to create a fresh session." })] })] })) : (_jsx(AgentTerminal, { agentStub: agentStub, profiles: profiles, isActive: true, compact: true, hideGreeting: true, displayMode: "full", showSummaryInput: false, className: "h-full" })) })] }));
44
44
  }
45
45
  export default ProjectTemplateAgentPanel;
46
46
  //# sourceMappingURL=ProjectTemplateAgentPanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectTemplateAgentPanel.js","sourceRoot":"","sources":["../../../../src/editor/settings/panels/ProjectTemplateAgentPanel.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ProjectTemplateAgentPanel.js","sourceRoot":"","sources":["../../../../src/editor/settings/panels/ProjectTemplateAgentPanel.tsx"],"names":[],"mappings":"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"}
@@ -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, Bot, ChevronDown, ChevronLeft, CopyPlus, CornerDownRight, GitBranch, Link2, Plus, RefreshCw, Search, Settings2, Shield, Trash2, X, } from "lucide-react";
3
+ import { AlertCircle, ChevronDown, 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,8 +45,7 @@ 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 &&
49
- PROJECT_TEMPLATE_ROOT_PATHS.some((root) => path.startsWith(root))) {
48
+ if (path && PROJECT_TEMPLATE_ROOT_PATHS.some((root) => path.startsWith(root))) {
50
49
  return true;
51
50
  }
52
51
  const itemId = change.item?.id?.trim().toLowerCase();
@@ -75,7 +74,7 @@ function normalizeTaskTemplate(task) {
75
74
  parentTaskId: rawParentTaskId,
76
75
  };
77
76
  }
78
- if (assigneeType === "user" || assigneeType === "Role") {
77
+ if (assigneeType === "Human" || assigneeType === "Role") {
79
78
  return {
80
79
  ...task,
81
80
  disabled,
@@ -94,20 +93,11 @@ function normalizeTaskTemplate(task) {
94
93
  parentTaskId: rawParentTaskId,
95
94
  };
96
95
  }
97
- function normalizeGraphOrientation(orientation) {
98
- return orientation === "vertical" ? "vertical" : "horizontal";
99
- }
100
96
  function normalizeProjectTemplate(template) {
101
97
  return {
102
98
  ...template,
103
99
  hideFromCreateDialog: template.hideFromCreateDialog === true,
104
100
  openInWizardMode: template.openInWizardMode === true,
105
- graphLayout: template.graphLayout
106
- ? {
107
- ...template.graphLayout,
108
- orientation: normalizeGraphOrientation(template.graphLayout.orientation),
109
- }
110
- : null,
111
101
  taskTemplates: (template.taskTemplates ?? []).map(normalizeTaskTemplate),
112
102
  };
113
103
  }
@@ -160,7 +150,6 @@ function buildUpsertTemplateRequest(template) {
160
150
  projectTemplateId: template.id,
161
151
  nodes: template.graphLayout.nodes ?? [],
162
152
  viewport: template.graphLayout.viewport ?? null,
163
- orientation: normalizeGraphOrientation(template.graphLayout.orientation),
164
153
  }
165
154
  : null,
166
155
  taskTemplates: template.taskTemplates.map((task, index) => {
@@ -194,7 +183,6 @@ function mergeTemplateResponseWithRequest(serverTemplate, request) {
194
183
  projectTemplateId: serverTemplate.id,
195
184
  nodes: request.graphLayout.nodes ?? [],
196
185
  viewport: request.graphLayout.viewport ?? null,
197
- orientation: normalizeGraphOrientation(request.graphLayout.orientation),
198
186
  };
199
187
  return normalizeProjectTemplate({
200
188
  ...serverTemplate,
@@ -336,7 +324,6 @@ function buildProjectTemplateAgentContext(template, selectedTaskTemplateId) {
336
324
  }
337
325
  export function ProjectTemplatesPanel() {
338
326
  const editContext = useEditContext();
339
- const isMobile = editContext?.isMobile ?? false;
340
327
  const searchParams = useSearchParams();
341
328
  const [state, setState] = useState("loading");
342
329
  const [templates, setTemplates] = useState([]);
@@ -366,9 +353,6 @@ export function ProjectTemplatesPanel() {
366
353
  const [templateAgentResetting, setTemplateAgentResetting] = useState(false);
367
354
  const [templateAgentError, setTemplateAgentError] = useState(null);
368
355
  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);
372
356
  const [editingAgentProfile, setEditingAgentProfile] = useState(null);
373
357
  const autosaveTimeoutRef = useRef(null);
374
358
  const lastPersistedSignatureRef = useRef(null);
@@ -377,8 +361,6 @@ export function ProjectTemplatesPanel() {
377
361
  const draftTemplateRef = useRef(null);
378
362
  const selectedTemplateIdRef = useRef(selectedTemplateId);
379
363
  const selectedTaskIdRef = useRef(selectedTaskId);
380
- const isDirtyRef = useRef(isDirty);
381
- const savingRef = useRef(saving);
382
364
  const templateAgentLoadRunIdRef = useRef(0);
383
365
  const externalRefreshTimeoutRef = useRef(null);
384
366
  const pendingExternalRefreshRef = useRef(false);
@@ -423,7 +405,6 @@ export function ProjectTemplatesPanel() {
423
405
  setSelectedTemplateId(template?.id ?? null);
424
406
  setDraftTemplate(clonedTemplate);
425
407
  setEditingAgentProfile(null);
426
- setDesktopAssistantOnly(false);
427
408
  setSelectedTaskId(getSelectedTaskIdForTemplate(clonedTemplate, preferredTaskId));
428
409
  setIsDirty(false);
429
410
  setSaveError(null);
@@ -437,27 +418,6 @@ export function ProjectTemplatesPanel() {
437
418
  });
438
419
  }
439
420
  }, [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]);
461
421
  const loadTemplates = useCallback(async (preferredTemplateId) => {
462
422
  try {
463
423
  setState("loading");
@@ -589,7 +549,7 @@ export function ProjectTemplatesPanel() {
589
549
  if (isDirty || saving) {
590
550
  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..." }));
591
551
  }
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..." }));
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..." }));
593
553
  }, [isDirty, saveError, saving]);
594
554
  const graphTasks = useMemo(() => buildTemplateTaskItems(draftTemplate, aiProfilesById), [aiProfilesById, draftTemplate]);
595
555
  const graphDependencies = useMemo(() => buildTemplateDependencies(draftTemplate), [draftTemplate]);
@@ -619,10 +579,7 @@ export function ProjectTemplatesPanel() {
619
579
  }, [selectedAgentProfile, selectedAgentProfileId, selectedTask?.title]);
620
580
  const handleCloseEditingAgentProfile = useCallback(() => {
621
581
  setEditingAgentProfile(null);
622
- if (isMobile) {
623
- setMobileView("detail");
624
- }
625
- }, [isMobile]);
582
+ }, []);
626
583
  const syncProjectTemplateAgentContext = useCallback(async (agentId, template, selectedTaskTemplateId) => {
627
584
  try {
628
585
  await updateAgentContext(agentId, buildProjectTemplateAgentContext(template, selectedTaskTemplateId));
@@ -929,12 +886,6 @@ export function ProjectTemplatesPanel() {
929
886
  useEffect(() => {
930
887
  selectedTaskIdRef.current = selectedTaskId;
931
888
  }, [selectedTaskId]);
932
- useEffect(() => {
933
- isDirtyRef.current = isDirty;
934
- }, [isDirty]);
935
- useEffect(() => {
936
- savingRef.current = saving;
937
- }, [saving]);
938
889
  const queueExternalTemplateRefresh = useCallback(() => {
939
890
  if (saving || isDirty) {
940
891
  pendingExternalRefreshRef.current = true;
@@ -946,23 +897,9 @@ export function ProjectTemplatesPanel() {
946
897
  }
947
898
  externalRefreshTimeoutRef.current = window.setTimeout(() => {
948
899
  externalRefreshTimeoutRef.current = null;
949
- if (savingRef.current || isDirtyRef.current) {
950
- pendingExternalRefreshRef.current = true;
951
- return;
952
- }
953
900
  void loadTemplatesRef.current(selectedTemplateIdRef.current);
954
901
  }, PROJECT_TEMPLATE_EXTERNAL_REFRESH_DEBOUNCE_MS);
955
902
  }, [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]);
966
903
  useEffect(() => {
967
904
  if (!editContext?.itemsRepository) {
968
905
  return;
@@ -1040,11 +977,8 @@ export function ProjectTemplatesPanel() {
1040
977
  editContext?.updateUrl({
1041
978
  [SELECTED_PROJECT_TEMPLATE_QUERY_PARAM]: nextTemplate.id,
1042
979
  });
1043
- if (isMobile) {
1044
- setMobileView("detail");
1045
- }
1046
980
  await persistTemplate(request, signature, { showErrorToast: true });
1047
- }, [editContext, flushPendingSave, isMobile, persistTemplate, templates]);
981
+ }, [editContext, flushPendingSave, persistTemplate, templates]);
1048
982
  const handleDeleteTemplate = useCallback((templateToDelete) => {
1049
983
  const template = templateToDelete ?? draftTemplate;
1050
984
  if (!template || template.isSystem)
@@ -1075,7 +1009,8 @@ export function ProjectTemplatesPanel() {
1075
1009
  }
1076
1010
  toast.success("Project template deleted");
1077
1011
  const fallbackId = isDeletingSelectedTemplate
1078
- ? (templates.find((currentTemplate) => currentTemplate.id !== templateId)?.id ?? null)
1012
+ ? templates.find((currentTemplate) => currentTemplate.id !== templateId)
1013
+ ?.id ?? null
1079
1014
  : selectedTemplateIdRef.current;
1080
1015
  await loadTemplates(fallbackId);
1081
1016
  }
@@ -1106,10 +1041,7 @@ export function ProjectTemplatesPanel() {
1106
1041
  return;
1107
1042
  }
1108
1043
  selectTemplate(template);
1109
- if (isMobile) {
1110
- setMobileView("detail");
1111
- }
1112
- }, [flushPendingSave, selectTemplate, isMobile]);
1044
+ }, [flushPendingSave, selectTemplate]);
1113
1045
  const handleRefreshTemplates = useCallback(async () => {
1114
1046
  const canContinue = await flushPendingSave({ showErrorToast: true });
1115
1047
  if (!canContinue) {
@@ -1477,116 +1409,103 @@ export function ProjectTemplatesPanel() {
1477
1409
  handleDeleteTemplate(template);
1478
1410
  }, children: _jsx(Trash2, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }) }))] }, template.id));
1479
1411
  }) })) })] }) }));
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) => ({
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) => ({
1559
1447
  ...currentTemplate,
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 }));
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() }));
1563
1486
  const rightPanelContent = editingAgentProfile ? (_jsx(AgentProfileEditorPanel, { agent: editingAgentProfile, onClose: handleCloseEditingAgentProfile, actions: _jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: () => void handleDuplicateAssignedAgentProfile(), disabled: !selectedAgentProfileId ||
1564
1487
  !editContext ||
1565
1488
  duplicatingAgentProfile ||
1566
1489
  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);
1568
1490
  const panels = [
1569
1491
  {
1570
1492
  name: "project-template-list",
1571
1493
  defaultSize: 360,
1572
1494
  content: listContent,
1573
1495
  className: "overflow-hidden",
1574
- hidden: desktopAssistantOnly || (isMobile && mobileView !== "list"),
1575
1496
  },
1576
1497
  {
1577
1498
  name: "project-template-detail",
1578
1499
  defaultSize: "auto",
1579
1500
  content: detailContent,
1580
1501
  className: "overflow-hidden",
1581
- hidden: desktopAssistantOnly || (isMobile && mobileView !== "detail"),
1582
1502
  },
1583
1503
  {
1584
1504
  name: "project-template-agent",
1585
1505
  defaultSize: 460,
1586
- content: rightPanelForSplitter,
1506
+ content: rightPanelContent,
1587
1507
  className: "overflow-hidden",
1588
1508
  collapsible: true,
1589
- hidden: isMobile && mobileView !== "agent",
1590
1509
  },
1591
1510
  ];
1592
1511
  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) => {