@taskforcehq/taskforce 0.3.306 → 0.3.307

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 (215) hide show
  1. package/README.md +0 -2
  2. package/dist/Taskforce.module.css +317 -27
  3. package/dist/TaskforceCore.js +1 -0
  4. package/dist/TaskforceCore.test.js +178 -0
  5. package/dist/components/activity/EntityActivityTimeline.d.ts +34 -0
  6. package/dist/components/activity/EntityActivityTimeline.js +81 -0
  7. package/dist/components/context/ContextAttachmentManager.js +15 -3
  8. package/dist/components/features/AgentsModule.d.ts +5 -1
  9. package/dist/components/features/AgentsModule.js +142 -39
  10. package/dist/components/features/AgentsModule.test.js +260 -11
  11. package/dist/components/features/AnnotatedAttachmentWorkspace.d.ts +3 -1
  12. package/dist/components/features/AnnotatedAttachmentWorkspace.js +118 -4
  13. package/dist/components/features/AnnotatedAttachmentWorkspace.test.js +52 -0
  14. package/dist/components/features/DocumentIndex.d.ts +2 -2
  15. package/dist/components/features/DocumentIndex.js +3 -4
  16. package/dist/components/features/DocumentViewer.d.ts +3 -1
  17. package/dist/components/features/DocumentViewer.js +6 -5
  18. package/dist/components/features/DocumentWorkspace.d.ts +10 -2
  19. package/dist/components/features/DocumentWorkspace.js +15 -4
  20. package/dist/components/features/DocumentWorkspace.test.js +20 -3
  21. package/dist/components/features/TaskSettings.d.ts +2 -0
  22. package/dist/components/features/TaskSettings.js +83 -78
  23. package/dist/components/features/TaskSettings.test.js +171 -82
  24. package/dist/components/task/TaskActionHeader.js +11 -5
  25. package/dist/components/task/TaskActionHeader.test.js +10 -0
  26. package/dist/components/task/TaskCard.js +6 -2
  27. package/dist/components/task/TaskContextUpload.test.js +3 -3
  28. package/dist/components/task/TaskForm.js +14 -64
  29. package/dist/components/task/TaskKanban.js +0 -8
  30. package/dist/components/task/TaskList.js +5 -1
  31. package/dist/components/task/TaskList.test.js +4 -0
  32. package/dist/components/ui/HierarchyActionBadge.d.ts +10 -0
  33. package/dist/components/ui/HierarchyActionBadge.js +5 -0
  34. package/dist/components/views/AppShellHeader.d.ts +3 -1
  35. package/dist/components/views/AppShellHeader.js +27 -11
  36. package/dist/components/views/AppShellHeader.test.js +18 -1
  37. package/dist/components/views/PlanComparisonPage.js +9 -1
  38. package/dist/components/views/PlanComparisonPage.test.js +19 -0
  39. package/dist/components/views/PlansPage.js +1 -1
  40. package/dist/components/views/StandaloneLayout.js +256 -69
  41. package/dist/components/views/WidgetView.js +10 -8
  42. package/dist/components/views/panels/PlanningDrawer.d.ts +19 -6
  43. package/dist/components/views/panels/PlanningDrawer.js +259 -51
  44. package/dist/components/views/panels/PlanningDrawer.test.js +392 -4
  45. package/dist/config/envSchema.js +1 -0
  46. package/dist/core/AiProfileService.d.ts +7 -0
  47. package/dist/core/AiProfileService.js +460 -35
  48. package/dist/core/AiProfiles.test.js +648 -2
  49. package/dist/core/AttachmentLinkService.d.ts +3 -0
  50. package/dist/core/AttachmentLinkService.js +58 -13
  51. package/dist/core/GlobalSettingsService.js +12 -0
  52. package/dist/core/McpTokenService.d.ts +12 -0
  53. package/dist/core/McpTokenService.js +44 -1
  54. package/dist/core/PlanningEntities.test.js +366 -4
  55. package/dist/core/TaskActivityService.d.ts +28 -1
  56. package/dist/core/TaskActivityService.js +227 -46
  57. package/dist/core/TaskActivitySync.test.d.ts +1 -0
  58. package/dist/core/TaskActivitySync.test.js +90 -0
  59. package/dist/core/TaskAuditTimeline.test.js +96 -0
  60. package/dist/core/Taskforce.d.ts +190 -26
  61. package/dist/core/Taskforce.ids.test.js +58 -0
  62. package/dist/core/Taskforce.js +775 -71
  63. package/dist/core/Taskforce.mcpAuth.test.js +109 -0
  64. package/dist/core/types.d.ts +7 -0
  65. package/dist/hooks/auth/useTaskforceAuthBootstrap.js +2 -1
  66. package/dist/hooks/bootstrapTimeouts.d.ts +4 -0
  67. package/dist/hooks/bootstrapTimeouts.js +8 -0
  68. package/dist/hooks/bootstrapTimeouts.test.d.ts +1 -0
  69. package/dist/hooks/bootstrapTimeouts.test.js +12 -0
  70. package/dist/hooks/sync/orchestratorShared.d.ts +3 -3
  71. package/dist/hooks/sync/orchestratorShared.js +61 -1
  72. package/dist/hooks/sync/recovery.js +8 -0
  73. package/dist/hooks/sync/recovery.test.js +5 -5
  74. package/dist/hooks/sync/transfers.d.ts +2 -1
  75. package/dist/hooks/sync/transfers.js +36 -9
  76. package/dist/hooks/sync/transfers.test.js +534 -2
  77. package/dist/hooks/useFilterSort.js +13 -13
  78. package/dist/hooks/useFilterSort.test.js +87 -1
  79. package/dist/hooks/useSyncOrchestrator.js +50 -5
  80. package/dist/hooks/useTaskforce.d.ts +85 -50
  81. package/dist/hooks/useTaskforce.js +44 -14
  82. package/dist/hooks/useTaskforce.runtime-routing.test.js +94 -0
  83. package/dist/hooks/useTaskforce.sync-behavior.test.js +99 -0
  84. package/dist/hooks/useWorkspaceSyncController.js +7 -1
  85. package/dist/hooks/useWorkspaceSyncController.test.js +48 -0
  86. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +14 -7
  87. package/dist/mcp/canonicalAssetHelpers.d.ts +16 -4
  88. package/dist/mcp/canonicalAssetHelpers.js +18 -10
  89. package/dist/mcp/canonicalAssetHelpers.test.d.ts +1 -0
  90. package/dist/mcp/canonicalAssetHelpers.test.js +67 -0
  91. package/dist/mcp/clientIntegrations.d.ts +1 -0
  92. package/dist/mcp/clientIntegrations.js +25 -0
  93. package/dist/mcp/clientIntegrations.test.js +14 -3
  94. package/dist/mcp/clientProfileDefaults.js +3 -3
  95. package/dist/mcp/collaborationRegistrar.js +7 -7
  96. package/dist/mcp/documentAssetRegistrar.js +113 -7
  97. package/dist/mcp/runtime.d.ts +1 -0
  98. package/dist/mcp/runtime.js +969 -122
  99. package/dist/mcp/runtime.test.js +1083 -11
  100. package/dist/mcp/taskAttachmentTypes.d.ts +1 -1
  101. package/dist/mcp/taskPlanningRegistrar.js +48 -0
  102. package/dist/mcp/toolRegistry.d.ts +56 -0
  103. package/dist/mcp/toolRegistry.js +8 -0
  104. package/dist/mcp/toolRegistry.test.js +4 -0
  105. package/dist/migrations/taskSchemaMigrations.js +21 -0
  106. package/dist/server/aiProfileAvatarAssets.d.ts +49 -0
  107. package/dist/server/aiProfileAvatarAssets.js +319 -0
  108. package/dist/server/aiProfileAvatarAssets.test.d.ts +1 -0
  109. package/dist/server/aiProfileAvatarAssets.test.js +213 -0
  110. package/dist/server/annotatedAttachmentsRoutes.test.js +66 -7
  111. package/dist/server/index.js +4 -0
  112. package/dist/server/index.test.js +6 -1
  113. package/dist/server/routes/admin.js +187 -9
  114. package/dist/server/routes/annotatedAttachments.js +51 -0
  115. package/dist/server/routes/auth.d.ts +11 -0
  116. package/dist/server/routes/auth.js +189 -27
  117. package/dist/server/routes/authSupport.d.ts +4 -0
  118. package/dist/server/routes/authSupport.js +12 -1
  119. package/dist/server/routes/billing.js +11 -0
  120. package/dist/server/routes/billing.test.js +3 -0
  121. package/dist/server/routes/documents.js +10 -0
  122. package/dist/server/routes/shared.js +0 -10
  123. package/dist/server/routes/sync.integration.test.js +221 -0
  124. package/dist/server/routes/sync.js +13 -3
  125. package/dist/server/routes/syncSnapshotRoutes.js +2 -0
  126. package/dist/server/routes/tasks.js +12 -9
  127. package/dist/server/routes.js +87 -8
  128. package/dist/server/routes.test.js +890 -22
  129. package/dist/shared/aiProfileSurfaceType.d.ts +1 -1
  130. package/dist/shared/aiProfileSurfaceType.js +10 -8
  131. package/dist/storage/objectStorage.d.ts +1 -0
  132. package/dist/storage/objectStorage.js +2 -1
  133. package/dist/storage/objectStorageClient.d.ts +1 -0
  134. package/dist/storage/objectStorageClient.js +41 -8
  135. package/dist/storage/objectStorageClient.test.js +26 -1
  136. package/dist/storage/objectStorageConfig.js +3 -1
  137. package/dist/storage/objectStorageConfig.test.js +13 -1
  138. package/dist/sync/collaborationSyncPayload.js +2 -0
  139. package/dist/sync/collaborationSyncPayload.test.js +1 -0
  140. package/dist/sync/collaborationSyncState.d.ts +3 -3
  141. package/dist/sync/collaborationSyncState.js +19 -12
  142. package/dist/sync/contentSyncPayload.d.ts +5 -1
  143. package/dist/sync/contentSyncPayload.js +9 -0
  144. package/dist/sync/contentSyncPayload.test.js +39 -0
  145. package/dist/sync/contentSyncState.d.ts +5 -1
  146. package/dist/sync/contentSyncState.js +231 -37
  147. package/dist/sync/planningSyncPayload.js +5 -0
  148. package/dist/sync/planningSyncPayload.test.js +24 -0
  149. package/dist/sync/syncApplyHandlers.d.ts +4 -4
  150. package/dist/sync/syncApplyHandlers.js +89 -31
  151. package/dist/sync/syncApplyHandlers.test.js +184 -4
  152. package/dist/sync/syncResourceAdapters.d.ts +2 -0
  153. package/dist/sync/syncResourceAdapters.js +2 -0
  154. package/dist/sync/syncService.d.ts +1 -0
  155. package/dist/sync/syncService.js +13 -1
  156. package/dist/sync/syncService.test.js +39 -0
  157. package/dist/sync/workspacePullFeed.d.ts +4 -0
  158. package/dist/sync/workspacePullFeed.js +129 -70
  159. package/dist/sync/workspacePullFeed.test.js +49 -0
  160. package/dist/sync/workspaceSyncModel.d.ts +28 -6
  161. package/dist/sync/workspaceSyncModel.js +159 -45
  162. package/dist/sync/workspaceSyncModel.test.js +269 -3
  163. package/dist/types.d.ts +33 -2
  164. package/dist/ui/assets/AgentsModule-2y82_3DO.js +1 -0
  165. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BTLZZCiQ.js +3 -0
  166. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BVKew-mH.css +1 -0
  167. package/dist/ui/assets/ContextAttachmentManager-D2epuNnG.js +3 -0
  168. package/dist/ui/assets/DocumentWorkspace-D4rJKXzd.css +1 -0
  169. package/dist/ui/assets/DocumentWorkspace-sVa-3Do6.js +252 -0
  170. package/dist/ui/assets/EntityActivityTimeline-DyqvvhuF.css +1 -0
  171. package/dist/ui/assets/EntityActivityTimeline-Zods27y_.js +1 -0
  172. package/dist/ui/assets/{InitiativesModule-9E6ParrY.js → InitiativesModule-D4XseTwW.js} +1 -1
  173. package/dist/ui/assets/PlansPage-D5AcbO0L.js +1 -0
  174. package/dist/ui/assets/PlansPage-Dvqsz5zc.css +1 -0
  175. package/dist/ui/assets/TaskContextUpload-uC5qx4Bv.js +1 -0
  176. package/dist/ui/assets/TaskSettings-CqvPAsTv.js +9 -0
  177. package/dist/ui/assets/{WorkflowsModule-BA7jcEpH.js → WorkflowsModule-oOA9bcdK.js} +4 -4
  178. package/dist/ui/assets/documentReferences-DPZuTgHh.js +1 -0
  179. package/dist/ui/assets/index-607WPo_X.js +4 -0
  180. package/dist/ui/assets/index-CYyodXsg.css +1 -0
  181. package/dist/ui/assets/{vendor-icons-DuEd_65c.js → vendor-icons-B32hGuF2.js} +1 -1
  182. package/dist/ui/index.html +3 -3
  183. package/dist/ui/product/agent manager.png +0 -0
  184. package/dist/ui/product/agent_manager_02.png +0 -0
  185. package/dist/utils/aiProfileEvents.d.ts +7 -0
  186. package/dist/utils/aiProfileEvents.js +6 -0
  187. package/dist/utils/assignees.d.ts +6 -0
  188. package/dist/utils/assignees.js +8 -1
  189. package/dist/utils/assignees.test.d.ts +1 -0
  190. package/dist/utils/assignees.test.js +25 -0
  191. package/dist/utils/avatarDisplay.d.ts +1 -0
  192. package/dist/utils/avatarDisplay.js +15 -0
  193. package/dist/utils/contextFiles.d.ts +3 -1
  194. package/dist/utils/contextFiles.js +2 -1
  195. package/dist/utils/taskActivity.d.ts +7 -1
  196. package/dist/utils/taskActivity.js +63 -1
  197. package/dist/utils/taskActivity.test.js +23 -1
  198. package/dist/utils/taskSearch.d.ts +22 -0
  199. package/dist/utils/taskSearch.js +87 -0
  200. package/dist/utils/taskSearch.test.d.ts +1 -0
  201. package/dist/utils/taskSearch.test.js +69 -0
  202. package/dist/utils/taskUtils.js +10 -3
  203. package/dist/utils/taskUtils.test.d.ts +1 -0
  204. package/dist/utils/taskUtils.test.js +19 -0
  205. package/package.json +1 -1
  206. package/dist/ui/assets/AgentsModule-DrLawwNl.js +0 -1
  207. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BaS2VwIr.css +0 -1
  208. package/dist/ui/assets/AnnotatedAttachmentWorkspace-Z9_whf7F.js +0 -3
  209. package/dist/ui/assets/DocumentWorkspace-B03MaSkw.js +0 -252
  210. package/dist/ui/assets/DocumentWorkspace-Dhdso07p.css +0 -1
  211. package/dist/ui/assets/PlansPage-CvfnMiWq.css +0 -1
  212. package/dist/ui/assets/PlansPage-DRXscYxH.js +0 -1
  213. package/dist/ui/assets/TaskSettings-DZX4jk7e.js +0 -9
  214. package/dist/ui/assets/index-9eT8e0Lu.css +0 -1
  215. package/dist/ui/assets/index-C6k75jr8.js +0 -6
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import React, { useMemo, useCallback, useState, useEffect, useRef, Suspense } from 'react';
3
3
  import { createPortal } from 'react-dom';
4
4
  import { useLocation, useNavigate } from 'react-router-dom';
5
- import { Settings, Plus, Filter, Layers, User, Maximize2, Minimize2, Check, ChevronLeft, ArrowUp, ArrowDown, ArrowUpDown, AlertTriangle, Save, Loader2, Folder, FileText, LogOut, NotebookTabs, ClipboardCheck, Cloud, CloudOff, Users, ClockAlert, ChevronsUp, ChevronsDown, EyeOff, Zap, HelpCircle, Bot, Image, Workflow } from 'lucide-react';
5
+ import { Settings, Plus, Filter, Layers, User, Maximize2, Minimize2, Check, ChevronLeft, ArrowUp, ArrowDown, ArrowUpDown, AlertTriangle, Save, Loader2, Folder, FileText, LogOut, NotebookTabs, ClipboardCheck, Cloud, CloudOff, Users, ClockAlert, ChevronsUp, ChevronsDown, EyeOff, Zap, HelpCircle, Bot, Image, Workflow, Plug } from 'lucide-react';
6
6
  import { STATUS_OPTIONS, getStatusDefinition } from '../../utils/constants';
7
7
  import styles from '../../Taskforce.module.css';
8
8
  import shellStyles from './WorkspaceShell.module.css';
@@ -29,6 +29,7 @@ import { resolveDraftDefaultsForGrouping } from '../../utils/taskDraftDefaults';
29
29
  import { formatDate } from '../../utils/formatting';
30
30
  import { resolveHeaderWorkspaceSyncPresentation } from '../../utils/workspaceSyncPresentation';
31
31
  import { getTaskReferenceLabel, parseTaskReference } from '../../utils/taskReferences';
32
+ import { normalizeTaskSearchQuery, taskMatchesSearch } from '../../utils/taskSearch';
32
33
  import { formatInitiativeReference, formatWorkstreamReference, parseWorkstreamReference, resolveInitiativeReference } from '../../utils/planningReferences';
33
34
  import { DEFAULT_TYPE_VALUE } from '../../shared/taxonomyDefaults.js';
34
35
  import { getImageReferenceLabel } from '../../utils/imageReferences';
@@ -211,6 +212,9 @@ export function StandaloneLayout(props) {
211
212
  const [showFilters, setShowFilters] = useState(false);
212
213
  const [taskModalFullscreen, setTaskModalFullscreen] = useState(false);
213
214
  const [planningDrawerOpen, setPlanningDrawerOpen] = useState(false);
215
+ const [documentTrayOpen, setDocumentTrayOpen] = useState(true);
216
+ const [imageTrayOpen, setImageTrayOpen] = useState(true);
217
+ const [agentTrayOpen, setAgentTrayOpen] = useState(true);
214
218
  const [planningTreeCollapsed, setPlanningTreeCollapsed] = useState(false);
215
219
  const [planningPrimaryCollapsed, setPlanningPrimaryCollapsed] = useState(false);
216
220
  const [planningSecondaryCollapsed, setPlanningSecondaryCollapsed] = useState(false);
@@ -226,6 +230,10 @@ export function StandaloneLayout(props) {
226
230
  const [planningDraftOwner, setPlanningDraftOwner] = useState('');
227
231
  const [planningDraftInitiativeId, setPlanningDraftInitiativeId] = useState('');
228
232
  const [isSubmittingPlanningEditor, setIsSubmittingPlanningEditor] = useState(false);
233
+ const taskContextAttachmentDraftRef = useRef({
234
+ taskId: null,
235
+ attachments: [],
236
+ });
229
237
  const planningContextAttachmentDraftsRef = useRef(new Map());
230
238
  const planningContextAttachmentUpdateQueueRef = useRef(new Map());
231
239
  const [documentTypeFilters, setDocumentTypeFilters] = useState(() => DOCUMENT_TYPE_FILTER_OPTIONS.map((option) => option.value));
@@ -242,6 +250,27 @@ export function StandaloneLayout(props) {
242
250
  const requestedAnnotatedTargetRef = useRef(null);
243
251
  const requestedAnnotatedSessionIdRef = useRef(null);
244
252
  const annotatedImageReferenceFetchesRef = useRef(new Set());
253
+ useEffect(() => {
254
+ taskContextAttachmentDraftRef.current = {
255
+ taskId: editingTaskId || null,
256
+ attachments,
257
+ };
258
+ }, [editingTaskId, attachments]);
259
+ const updateTaskContextAttachments = useCallback((getNextAttachments) => {
260
+ const taskId = editingTaskId || null;
261
+ const draft = taskContextAttachmentDraftRef.current;
262
+ const currentAttachments = draft.taskId === taskId ? draft.attachments : attachments;
263
+ const nextAttachments = getNextAttachments(currentAttachments);
264
+ taskContextAttachmentDraftRef.current = {
265
+ taskId,
266
+ attachments: nextAttachments,
267
+ };
268
+ setAttachments(nextAttachments);
269
+ setAttachmentsDirty(true);
270
+ if (taskId) {
271
+ void handleUpdateTask(taskId, { attachments: nextAttachments });
272
+ }
273
+ }, [attachments, editingTaskId, handleUpdateTask, setAttachments, setAttachmentsDirty]);
245
274
  const workspaceUiStateHeaders = useMemo(() => {
246
275
  const headers = {};
247
276
  const workspaceIdHeader = String(currentWorkspaceId || '').trim();
@@ -252,7 +281,33 @@ export function StandaloneLayout(props) {
252
281
  }, [runtimeMode, currentWorkspaceId]);
253
282
  const layoutStateWorkspaceKey = useMemo(() => `${runtimeMode}:${String(currentWorkspaceId || 'default').trim() || 'default'}`, [runtimeMode, currentWorkspaceId]);
254
283
  const annotatedLayoutCacheKey = useMemo(() => `taskforce:annotate-layout:${layoutStateWorkspaceKey}`, [layoutStateWorkspaceKey]);
284
+ const taskOriginWorkspaceModuleKey = useMemo(() => `taskforce:task-origin-workspace-module:${layoutStateWorkspaceKey}`, [layoutStateWorkspaceKey]);
255
285
  const annotatedWorkspaceReady = useMemo(() => (runtimeMode === 'cloud' ? authSessionResolved : configLoaded), [authSessionResolved, configLoaded, runtimeMode]);
286
+ const openedTaskOriginWorkspaceModuleRef = useRef(false);
287
+ const taskOriginWorkspaceModuleRestoreHandledRef = useRef(false);
288
+ const rememberTaskOriginWorkspaceModule = useCallback((taskId) => {
289
+ const normalizedTaskId = String(taskId || '').trim();
290
+ if (!normalizedTaskId || typeof window === 'undefined')
291
+ return;
292
+ openedTaskOriginWorkspaceModuleRef.current = true;
293
+ try {
294
+ window.sessionStorage.setItem(taskOriginWorkspaceModuleKey, normalizedTaskId);
295
+ }
296
+ catch {
297
+ // ignore cache write failure
298
+ }
299
+ }, [taskOriginWorkspaceModuleKey]);
300
+ const clearTaskOriginWorkspaceModule = useCallback(() => {
301
+ openedTaskOriginWorkspaceModuleRef.current = false;
302
+ if (typeof window === 'undefined')
303
+ return;
304
+ try {
305
+ window.sessionStorage.removeItem(taskOriginWorkspaceModuleKey);
306
+ }
307
+ catch {
308
+ // ignore cache clear failure
309
+ }
310
+ }, [taskOriginWorkspaceModuleKey]);
256
311
  useEffect(() => {
257
312
  requestedAnnotatedTargetRef.current = requestedAnnotatedTarget;
258
313
  }, [requestedAnnotatedTarget]);
@@ -299,6 +354,7 @@ export function StandaloneLayout(props) {
299
354
  pushNotice(documentsWorkspaceUnavailableMessage, 'error');
300
355
  return;
301
356
  }
357
+ rememberTaskOriginWorkspaceModule(customEvent.detail?.taskId);
302
358
  setRequestedDocPath(fsPath || null);
303
359
  setRequestedDocAssetId(assetId);
304
360
  setActiveWorkspaceModule('docs');
@@ -307,7 +363,7 @@ export function StandaloneLayout(props) {
307
363
  return () => {
308
364
  window.removeEventListener('taskforce:open-markdown-document', handleOpenMarkdownDocument);
309
365
  };
310
- }, [documentsWorkspaceEnabled, documentsWorkspaceUnavailableMessage, pushNotice, setActiveWorkspaceModule]);
366
+ }, [documentsWorkspaceEnabled, documentsWorkspaceUnavailableMessage, pushNotice, rememberTaskOriginWorkspaceModule, setActiveWorkspaceModule]);
311
367
  useEffect(() => {
312
368
  if (resolvedWorkspaceModule !== activeWorkspaceModule) {
313
369
  setActiveWorkspaceModule(resolvedWorkspaceModule);
@@ -338,6 +394,29 @@ export function StandaloneLayout(props) {
338
394
  // ignore cache read failure
339
395
  }
340
396
  }, [annotatedLayoutCacheKey]);
397
+ useEffect(() => {
398
+ if (taskOriginWorkspaceModuleRestoreHandledRef.current)
399
+ return;
400
+ if (resolvedWorkspaceModule !== 'docs' && resolvedWorkspaceModule !== 'annotate')
401
+ return;
402
+ taskOriginWorkspaceModuleRestoreHandledRef.current = true;
403
+ if (openedTaskOriginWorkspaceModuleRef.current || typeof window === 'undefined')
404
+ return;
405
+ try {
406
+ const taskId = String(window.sessionStorage.getItem(taskOriginWorkspaceModuleKey) || '').trim();
407
+ if (!taskId)
408
+ return;
409
+ window.sessionStorage.removeItem(taskOriginWorkspaceModuleKey);
410
+ setActiveWorkspaceModule('tasks');
411
+ }
412
+ catch {
413
+ // ignore cache read failure
414
+ }
415
+ }, [resolvedWorkspaceModule, setActiveWorkspaceModule, taskOriginWorkspaceModuleKey]);
416
+ useEffect(() => {
417
+ taskOriginWorkspaceModuleRestoreHandledRef.current = false;
418
+ openedTaskOriginWorkspaceModuleRef.current = false;
419
+ }, [taskOriginWorkspaceModuleKey]);
341
420
  useEffect(() => {
342
421
  if (loadedLayoutStateWorkspaceRef.current === layoutStateWorkspaceKey)
343
422
  return;
@@ -387,6 +466,15 @@ export function StandaloneLayout(props) {
387
466
  if (typeof state.planningDrawerOpen === 'boolean') {
388
467
  setPlanningDrawerOpen(state.planningDrawerOpen);
389
468
  }
469
+ if (typeof state.documentTrayOpen === 'boolean') {
470
+ setDocumentTrayOpen(state.documentTrayOpen);
471
+ }
472
+ if (typeof state.imageTrayOpen === 'boolean') {
473
+ setImageTrayOpen(state.imageTrayOpen);
474
+ }
475
+ if (typeof state.agentTrayOpen === 'boolean') {
476
+ setAgentTrayOpen(state.agentTrayOpen);
477
+ }
390
478
  if (typeof state.planningTreeCollapsed === 'boolean') {
391
479
  setPlanningTreeCollapsed(state.planningTreeCollapsed);
392
480
  }
@@ -462,6 +550,9 @@ export function StandaloneLayout(props) {
462
550
  showFilters,
463
551
  documentTypeFilters,
464
552
  documentAttachmentFilters,
553
+ documentTrayOpen,
554
+ imageTrayOpen,
555
+ agentTrayOpen,
465
556
  planningDrawerOpen,
466
557
  planningTreeCollapsed,
467
558
  planningPrimaryCollapsed,
@@ -491,6 +582,9 @@ export function StandaloneLayout(props) {
491
582
  showFilters,
492
583
  documentTypeFilters,
493
584
  documentAttachmentFilters,
585
+ documentTrayOpen,
586
+ imageTrayOpen,
587
+ agentTrayOpen,
494
588
  planningDrawerOpen,
495
589
  planningTreeCollapsed,
496
590
  planningPrimaryCollapsed,
@@ -568,6 +662,7 @@ export function StandaloneLayout(props) {
568
662
  setRequestedAnnotatedTarget(detail);
569
663
  setRequestedAnnotatedSessionId(null);
570
664
  setRequestedAnnotatedOpenVersion((current) => current + 1);
665
+ rememberTaskOriginWorkspaceModule(detail.taskId);
571
666
  setActiveWorkspaceModule('annotate');
572
667
  };
573
668
  window.addEventListener('taskforce:open-annotated-attachment', handleOpenAnnotatedAttachment);
@@ -579,6 +674,7 @@ export function StandaloneLayout(props) {
579
674
  annotatedAttachmentsWorkspaceEnabled,
580
675
  annotatedAttachmentsWorkspaceUnavailableMessage,
581
676
  pushNotice,
677
+ rememberTaskOriginWorkspaceModule,
582
678
  setActiveWorkspaceModule
583
679
  ]);
584
680
  useEffect(() => {
@@ -674,7 +770,14 @@ export function StandaloneLayout(props) {
674
770
  }, [props.deletedTasks]);
675
771
  const filteredDeletedTasks = useMemo(() => {
676
772
  const deletedTasks = deletedScopeAllTasks;
677
- const searchNeedle = searchQuery.trim().toLowerCase();
773
+ const normalizedSearch = normalizeTaskSearchQuery(searchQuery);
774
+ const searchContext = {
775
+ categories: activeCategories,
776
+ types: activeTypes,
777
+ priorities,
778
+ assigneeOptions: props.assigneeOptions,
779
+ taxonomies
780
+ };
678
781
  const allCategoriesSelected = activeCategories.every((taskCategory) => filterCategories.includes(taskCategory.value));
679
782
  const allTypesSelected = activeTypes.every((taskType) => filterTypes.includes(taskType.value));
680
783
  const selectedPriorities = new Set(filterPriorities.map((value) => String(value)));
@@ -682,12 +785,7 @@ export function StandaloneLayout(props) {
682
785
  const selectedStatuses = new Set(filterStatus.map((value) => String(value)));
683
786
  const allStatusesSelected = STATUS_OPTIONS.every((statusOption) => selectedStatuses.has(String(statusOption.value)));
684
787
  return deletedTasks.filter((task) => {
685
- const referenceLabel = (getTaskReferenceLabel(task) || task.id).toLowerCase();
686
- const matchesSearch = !searchNeedle
687
- || task.title.toLowerCase().includes(searchNeedle)
688
- || String(task.description || '').toLowerCase().includes(searchNeedle)
689
- || task.id.toLowerCase().includes(searchNeedle)
690
- || referenceLabel.includes(searchNeedle);
788
+ const matchesSearch = taskMatchesSearch(task, normalizedSearch, searchContext);
691
789
  const matchesCategory = allCategoriesSelected || filterCategories.includes(task.category);
692
790
  const matchesType = allTypesSelected || filterTypes.includes(task.type || DEFAULT_TYPE_VALUE);
693
791
  const matchesPriority = allPrioritiesSelected || selectedPriorities.has(String(task.priority));
@@ -781,6 +879,11 @@ export function StandaloneLayout(props) {
781
879
  : taskScope === 'deleted'
782
880
  ? deletedScopeAllTasks
783
881
  : props.tasks.filter((task) => !task.isArchived);
882
+ const planningPreviewTasks = taskScope === 'deleted'
883
+ ? deletedScopeAllTasks
884
+ : Array.from([...props.tasks, ...archivedScopeAllTasks]
885
+ .reduce((map, task) => map.set(task.id, task), new Map())
886
+ .values());
784
887
  const summarizeTaskCounts = (taskCount, completedTaskCount) => {
785
888
  return {
786
889
  progressPercent: taskCount > 0 ? Math.round((completedTaskCount / taskCount) * 100) : 0,
@@ -792,9 +895,11 @@ export function StandaloneLayout(props) {
792
895
  && props.planningBootstrapTaskSummaries.length > 0
793
896
  && (props.loadingTasks || props.tasks.length === 0);
794
897
  const workstreamTaskSummaryById = new Map();
898
+ const workstreamTaskPreviewsById = new Map();
795
899
  if (useBootstrapTaskSummaries) {
796
900
  props.planningBootstrapTaskSummaries.forEach((summary) => {
797
901
  workstreamTaskSummaryById.set(summary.workstreamId, summary);
902
+ workstreamTaskPreviewsById.set(summary.workstreamId, summary.tasks || []);
798
903
  });
799
904
  }
800
905
  else {
@@ -812,13 +917,21 @@ export function StandaloneLayout(props) {
812
917
  if (task.isArchived || task.status === 'done' || task.status === 'cancelled') {
813
918
  current.completedTaskCount += 1;
814
919
  }
815
- current.tasks.push({
920
+ workstreamTaskSummaryById.set(workstreamId, current);
921
+ });
922
+ planningPreviewTasks.forEach((task) => {
923
+ const workstreamId = String(task.workstreamId || '').trim();
924
+ if (!workstreamId)
925
+ return;
926
+ const current = workstreamTaskPreviewsById.get(workstreamId) || [];
927
+ current.push({
816
928
  id: task.id,
817
929
  referenceNumber: task.referenceNumber ?? null,
818
930
  title: task.title,
819
931
  status: task.status || null,
932
+ isArchived: Boolean(task.isArchived),
820
933
  });
821
- workstreamTaskSummaryById.set(workstreamId, current);
934
+ workstreamTaskPreviewsById.set(workstreamId, current);
822
935
  });
823
936
  }
824
937
  const workstreamTaskIds = new Map();
@@ -827,12 +940,13 @@ export function StandaloneLayout(props) {
827
940
  const workstreamsByInitiativeId = new Map();
828
941
  const buildWorkstreamSummary = (workstream) => {
829
942
  const taskSummary = workstreamTaskSummaryById.get(workstream.id);
830
- const taskPreviews = taskSummary?.tasks || [];
943
+ const taskPreviews = workstreamTaskPreviewsById.get(workstream.id) || taskSummary?.tasks || [];
831
944
  const summary = {
832
945
  id: workstream.id,
833
946
  referenceNumber: workstream.referenceNumber ?? null,
834
947
  title: workstream.title,
835
948
  description: String(workstream.description || '').trim() || undefined,
949
+ ownerId: workstream.ownerId ? String(workstream.ownerId) : null,
836
950
  ownerLabel: workstream.ownerId ? assigneeLabelByValue.get(String(workstream.ownerId)) || String(workstream.ownerId) : null,
837
951
  ...summarizeTaskCounts(taskSummary?.taskCount || 0, taskSummary?.completedTaskCount || 0),
838
952
  initiativeId: workstream.initiativeId || null,
@@ -854,7 +968,8 @@ export function StandaloneLayout(props) {
854
968
  const allWorkstreamSummaries = props.workstreams.map(buildWorkstreamSummary);
855
969
  const scopedWorkstreamSummaries = allWorkstreamSummaries.filter((workstream) => (isPlanningEntityVisibleForScope(taskScope, Boolean(workstream.isArchived))));
856
970
  const allInitiatives = props.initiatives.map((initiative) => {
857
- const workstreams = (workstreamsByInitiativeId.get(initiative.id) || [])
971
+ const allWorkstreamsForInitiative = workstreamsByInitiativeId.get(initiative.id) || [];
972
+ const workstreams = allWorkstreamsForInitiative
858
973
  .filter((workstream) => isPlanningEntityVisibleForScope(taskScope, Boolean(workstream.isArchived)));
859
974
  const taskCount = workstreams.reduce((sum, workstream) => sum + workstream.taskCount, 0);
860
975
  const completedTaskCount = workstreams.reduce((sum, workstream) => sum + workstream.completedTaskCount, 0);
@@ -863,10 +978,12 @@ export function StandaloneLayout(props) {
863
978
  referenceNumber: initiative.referenceNumber ?? null,
864
979
  title: initiative.title,
865
980
  description: String(initiative.description || '').trim() || undefined,
981
+ ownerId: initiative.ownerId ? String(initiative.ownerId) : null,
866
982
  ownerLabel: initiative.ownerId ? assigneeLabelByValue.get(String(initiative.ownerId)) || String(initiative.ownerId) : null,
867
983
  ...summarizeTaskCounts(taskCount, completedTaskCount),
868
984
  workstreamCount: workstreams.length,
869
985
  workstreams,
986
+ allWorkstreams: allWorkstreamsForInitiative,
870
987
  commentCount: Array.isArray(initiative.comments) ? initiative.comments.length : 0,
871
988
  attachmentCount: Array.isArray(initiative.attachments) ? initiative.attachments.length : 0,
872
989
  attachments: Array.isArray(initiative.attachments) ? initiative.attachments : [],
@@ -875,12 +992,14 @@ export function StandaloneLayout(props) {
875
992
  return initiativeSummary;
876
993
  });
877
994
  const { initiatives, standaloneWorkstreams, visibleWorkstreams, initiativeById, workstreamById, } = scopePlanningSummaries(allInitiatives, scopedWorkstreamSummaries, taskScope);
995
+ const allStandaloneWorkstreams = allWorkstreamSummaries.filter((workstream) => !workstream.initiativeId);
878
996
  initiatives.forEach((initiative) => {
879
997
  initiativeTaskIds.set(initiative.id, initiative.workstreams.flatMap((workstream) => (workstream.tasks || []).map((task) => task.id)));
880
998
  });
881
999
  return {
882
1000
  initiatives,
883
1001
  standaloneWorkstreams,
1002
+ allStandaloneWorkstreams,
884
1003
  workstreamTaskIds,
885
1004
  workstreamInitiativeIds,
886
1005
  initiativeTaskIds,
@@ -1829,6 +1948,39 @@ export function StandaloneLayout(props) {
1829
1948
  props,
1830
1949
  pushNotice
1831
1950
  ]);
1951
+ const handleOpenKanbanFromBrand = useCallback(() => {
1952
+ if (isPlansScreen) {
1953
+ void handlePlansBack();
1954
+ return;
1955
+ }
1956
+ handleNavigation(() => {
1957
+ clearTaskOriginWorkspaceModule();
1958
+ setActiveWorkspaceModule('tasks');
1959
+ setPlanningDrawerOpen(false);
1960
+ setPlanningDrawerDetail(null);
1961
+ setPlanningNestedWorkstreamDetailId(null);
1962
+ setPlanningEditor(null);
1963
+ setTaskModalFullscreen(false);
1964
+ if (activeTab === 'add')
1965
+ resetForm();
1966
+ setActiveTab('tasks');
1967
+ if (location.pathname !== '/' || location.search) {
1968
+ navigate('/');
1969
+ }
1970
+ });
1971
+ }, [
1972
+ activeTab,
1973
+ clearTaskOriginWorkspaceModule,
1974
+ handleNavigation,
1975
+ handlePlansBack,
1976
+ isPlansScreen,
1977
+ location.pathname,
1978
+ location.search,
1979
+ navigate,
1980
+ resetForm,
1981
+ setActiveTab,
1982
+ setActiveWorkspaceModule,
1983
+ ]);
1832
1984
  const handleSwitchWorkspace = useCallback(async (workspaceId) => {
1833
1985
  if (!workspaceId || workspaceActionBusy)
1834
1986
  return;
@@ -2495,13 +2647,6 @@ export function StandaloneLayout(props) {
2495
2647
  setPlanningSecondaryCollapsed(false);
2496
2648
  setPlanningNestedWorkstreamDetailId(workstreamId);
2497
2649
  }, []);
2498
- const ownerValueByLabel = useMemo(() => {
2499
- const map = new Map();
2500
- assigneeOptions.forEach((option) => {
2501
- map.set(option.label, String(option.value));
2502
- });
2503
- return map;
2504
- }, [assigneeOptions]);
2505
2650
  const openPlanningCreateEditor = useCallback((type, initiativeId) => {
2506
2651
  if (type === 'workstream' && initiativeId) {
2507
2652
  openPlanningSecondaryEditor({ mode: 'create', entityType: 'workstream' }, initiativeId);
@@ -2523,7 +2668,7 @@ export function StandaloneLayout(props) {
2523
2668
  setPlanningEditor({ mode: 'edit', entityType: 'initiative', targetId: id });
2524
2669
  setPlanningDraftTitle(item.title);
2525
2670
  setPlanningDraftDescription(item.description || '');
2526
- setPlanningDraftOwner(item.ownerLabel ? (ownerValueByLabel.get(item.ownerLabel) || '') : '');
2671
+ setPlanningDraftOwner(item.ownerId ? String(item.ownerId) : '');
2527
2672
  setPlanningDraftInitiativeId('');
2528
2673
  }
2529
2674
  else {
@@ -2534,12 +2679,12 @@ export function StandaloneLayout(props) {
2534
2679
  setPlanningEditor({ mode: 'edit', entityType: 'workstream', targetId: id });
2535
2680
  setPlanningDraftTitle(item.title);
2536
2681
  setPlanningDraftDescription(item.description || '');
2537
- setPlanningDraftOwner(item.ownerLabel ? (ownerValueByLabel.get(item.ownerLabel) || '') : '');
2682
+ setPlanningDraftOwner(item.ownerId ? String(item.ownerId) : '');
2538
2683
  const initiative = item.initiativeId ? planningStructure.initiativeById.get(item.initiativeId) || null : null;
2539
2684
  setPlanningDraftInitiativeId(initiative ? formatInitiativeReference(initiative) : '');
2540
2685
  }
2541
2686
  setPlanningNestedWorkstreamDetailId(null);
2542
- }, [ownerValueByLabel, planningStructure.initiativeById, planningStructure.standaloneWorkstreams, planningStructure.workstreamById]);
2687
+ }, [planningStructure.initiativeById, planningStructure.standaloneWorkstreams, planningStructure.workstreamById]);
2543
2688
  const handleAssignInitiativeToWorkstream = useCallback(async (workstreamId, initiativeReferenceOverride) => {
2544
2689
  const workstream = props.workstreams.find((item) => item.id === workstreamId);
2545
2690
  if (!workstream) {
@@ -2710,8 +2855,10 @@ export function StandaloneLayout(props) {
2710
2855
  pushNotice(`${unavailableLabel} is not available in this build yet.`, 'error');
2711
2856
  return;
2712
2857
  }
2858
+ clearTaskOriginWorkspaceModule();
2713
2859
  setActiveWorkspaceModule(nextModule);
2714
2860
  }, [
2861
+ clearTaskOriginWorkspaceModule,
2715
2862
  pushNotice,
2716
2863
  setActiveWorkspaceModule,
2717
2864
  workspaceModules,
@@ -2731,10 +2878,40 @@ export function StandaloneLayout(props) {
2731
2878
  }
2732
2879
  setPlanningDrawerOpen((current) => !current);
2733
2880
  }, [planningDrawerOpen, resolvedWorkspaceModule, setActiveWorkspaceModule]);
2881
+ const handleDocumentTrayToggle = useCallback(() => {
2882
+ if (resolvedWorkspaceModule !== 'docs') {
2883
+ setActiveWorkspaceModule('docs');
2884
+ setDocumentTrayOpen(true);
2885
+ return;
2886
+ }
2887
+ setDocumentTrayOpen((current) => !current);
2888
+ }, [resolvedWorkspaceModule, setActiveWorkspaceModule]);
2889
+ const handleImageTrayToggle = useCallback(() => {
2890
+ if (resolvedWorkspaceModule !== 'annotate') {
2891
+ setActiveWorkspaceModule('annotate');
2892
+ setImageTrayOpen(true);
2893
+ return;
2894
+ }
2895
+ setImageTrayOpen((current) => !current);
2896
+ }, [resolvedWorkspaceModule, setActiveWorkspaceModule]);
2897
+ const handleAgentTrayToggle = useCallback(() => {
2898
+ if (resolvedWorkspaceModule !== 'agents') {
2899
+ setActiveWorkspaceModule('agents');
2900
+ setAgentTrayOpen(true);
2901
+ return;
2902
+ }
2903
+ setAgentTrayOpen((current) => !current);
2904
+ }, [resolvedWorkspaceModule, setActiveWorkspaceModule]);
2734
2905
  const handleBackToTaskFromAnnotatedAttachment = useCallback((taskId) => {
2906
+ clearTaskOriginWorkspaceModule();
2907
+ setActiveWorkspaceModule('tasks');
2908
+ handleOpenTaskById(taskId);
2909
+ }, [clearTaskOriginWorkspaceModule, handleOpenTaskById, setActiveWorkspaceModule]);
2910
+ const handleBackToTaskFromDocument = useCallback((taskId) => {
2911
+ clearTaskOriginWorkspaceModule();
2735
2912
  setActiveWorkspaceModule('tasks');
2736
2913
  handleOpenTaskById(taskId);
2737
- }, [handleOpenTaskById, setActiveWorkspaceModule]);
2914
+ }, [clearTaskOriginWorkspaceModule, handleOpenTaskById, setActiveWorkspaceModule]);
2738
2915
  const handleAnnotatedAttachmentOpenTarget = useCallback((target, options) => {
2739
2916
  setRequestedAnnotatedTarget(target);
2740
2917
  setRequestedAnnotatedSessionId(options?.sessionId ?? null);
@@ -2925,18 +3102,45 @@ export function StandaloneLayout(props) {
2925
3102
  workflows: _jsx(Workflow, { size: 18 }),
2926
3103
  agents: _jsx(Bot, { size: 18 }),
2927
3104
  };
2928
- return (_jsxs("aside", { className: shellStyles.workspaceToolRail, "aria-label": "Workspace tools", children: [_jsxs("div", { className: shellStyles.workspaceToolRailMain, children: [_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${(resolvedWorkspaceModule === 'tasks' && planningDrawerOpen) ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: handlePlanningToolToggle, title: resolvedWorkspaceModule === 'tasks' && planningDrawerOpen ? 'Collapse planning trays' : 'Planning', "aria-label": resolvedWorkspaceModule === 'tasks' && planningDrawerOpen ? 'Collapse planning trays' : 'Planning', children: resolvedWorkspaceModule === 'tasks' && planningDrawerOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(NotebookTabs, { size: 18 }) }), _jsx("div", { className: shellStyles.workspaceToolRailDivider }), workspaceToolModules.map((module) => (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${resolvedWorkspaceModule === module.id ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: () => handleModuleChange(module.id), title: module.label, "aria-label": module.label, children: moduleIcons[module.id] }, module.id)))] }), _jsxs("div", { className: shellStyles.workspaceToolRailBottom, children: [_jsx("div", { className: shellStyles.workspaceToolRailDivider }), _jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${activeTab === 'settings' ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: () => {
3105
+ const trayButtonDisabledClass = shellStyles.workspaceToolButtonDisabled || '';
3106
+ const workspaceTrayButton = (() => {
3107
+ if (resolvedWorkspaceModule === 'docs') {
3108
+ return (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${documentTrayOpen ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: handleDocumentTrayToggle, title: documentTrayOpen ? 'Collapse document tray' : 'Document tray', "aria-label": documentTrayOpen ? 'Collapse document tray' : 'Document tray', children: documentTrayOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(Folder, { size: 18 }) }));
3109
+ }
3110
+ if (resolvedWorkspaceModule === 'annotate') {
3111
+ return (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${imageTrayOpen ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: handleImageTrayToggle, title: imageTrayOpen ? 'Collapse image tray' : 'Image tray', "aria-label": imageTrayOpen ? 'Collapse image tray' : 'Image tray', children: imageTrayOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(Folder, { size: 18 }) }));
3112
+ }
3113
+ if (resolvedWorkspaceModule === 'agents') {
3114
+ return (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${agentTrayOpen ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: handleAgentTrayToggle, title: agentTrayOpen ? 'Collapse agent tray' : 'MCP settings tray', "aria-label": agentTrayOpen ? 'Collapse agent tray' : 'MCP settings tray', children: agentTrayOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(Plug, { size: 18 }) }));
3115
+ }
3116
+ if (resolvedWorkspaceModule === 'workflows') {
3117
+ return (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${trayButtonDisabledClass}`.trim(), title: "Workflow tray coming soon", "aria-label": "Workflow tray coming soon", disabled: true, children: _jsx(Workflow, { size: 18 }) }));
3118
+ }
3119
+ return (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${(resolvedWorkspaceModule === 'tasks' && planningDrawerOpen) ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: handlePlanningToolToggle, title: resolvedWorkspaceModule === 'tasks' && planningDrawerOpen ? 'Collapse planning trays' : 'Planning', "aria-label": resolvedWorkspaceModule === 'tasks' && planningDrawerOpen ? 'Collapse planning trays' : 'Planning', children: resolvedWorkspaceModule === 'tasks' && planningDrawerOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(NotebookTabs, { size: 18 }) }));
3120
+ })();
3121
+ return (_jsxs("aside", { className: shellStyles.workspaceToolRail, "aria-label": "Workspace tools", children: [_jsxs("div", { className: shellStyles.workspaceToolRailMain, children: [workspaceTrayButton, _jsx("div", { className: shellStyles.workspaceToolRailDivider }), workspaceToolModules.map((module) => (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${resolvedWorkspaceModule === module.id ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: () => handleModuleChange(module.id), title: module.label, "aria-label": module.label, children: moduleIcons[module.id] }, module.id)))] }), _jsxs("div", { className: shellStyles.workspaceToolRailBottom, children: [_jsx("div", { className: shellStyles.workspaceToolRailDivider }), _jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${activeTab === 'settings' ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: () => {
2929
3122
  setSettingsSection('general');
2930
3123
  setActiveTab('settings');
2931
3124
  }, title: "Workspace Settings", "aria-label": "Workspace Settings", children: _jsx(Settings, { size: 18 }) })] })] }));
2932
- }, [activeTab, handleModuleChange, handlePlanningToolToggle, planningDrawerOpen, resolvedWorkspaceModule, setSettingsSection, setActiveTab, workspaceToolModules]);
2933
- const planningDrawerPortalRef = useRef(null);
2934
- const planningDrawerNode = (_jsx(PlanningDrawer, { open: planningDrawerOpen, leftOffset: WORKSPACE_TOOL_RAIL_WIDTH, initiatives: planningStructure.initiatives, standaloneWorkstreams: planningStructure.standaloneWorkstreams, activeInitiativeId: selectedPlanningInitiativeId, activeWorkstreamId: selectedPlanningWorkstreamId, expandedInitiativeIds: expandedPlanningInitiativeIds, detail: planningDrawerItem, editor: planningEditor, secondaryPane: planningSecondaryPane, currentWorkspaceId: currentWorkspaceId, assigneeOptions: assigneeOptions.map((option) => ({ value: String(option.value), label: option.label })), draftInitiativeSummary: planningDraftInitiativeSummary, draftTitle: planningDraftTitle, draftDescription: planningDraftDescription, draftOwner: planningDraftOwner, draftInitiativeId: planningDraftInitiativeId, onChangeDraftTitle: setPlanningDraftTitle, onChangeDraftDescription: setPlanningDraftDescription, onChangeDraftOwner: setPlanningDraftOwner, onChangeDraftInitiativeId: setPlanningDraftInitiativeId, onCollapseTreePane: () => setPlanningTreeCollapsed(true), onExpandTreePane: () => setPlanningTreeCollapsed(false), onCollapsePrimaryPane: () => setPlanningPrimaryCollapsed(true), onExpandPrimaryPane: () => setPlanningPrimaryCollapsed(false), onCollapseSecondaryPane: () => setPlanningSecondaryCollapsed(true), onExpandSecondaryPane: () => setPlanningSecondaryCollapsed(false), onBackFromSecondary: () => {
3125
+ }, [activeTab, agentTrayOpen, documentTrayOpen, handleAgentTrayToggle, handleDocumentTrayToggle, handleImageTrayToggle, handleModuleChange, handlePlanningToolToggle, imageTrayOpen, planningDrawerOpen, resolvedWorkspaceModule, setSettingsSection, setActiveTab, workspaceToolModules]);
3126
+ const [planningDrawerPortalElement, setPlanningDrawerPortalElement] = useState(null);
3127
+ const setPlanningDrawerPortalRef = useCallback((node) => {
3128
+ setPlanningDrawerPortalElement(node);
3129
+ }, []);
3130
+ const planningDrawerNode = (_jsx(PlanningDrawer, { open: planningDrawerOpen, leftOffset: WORKSPACE_TOOL_RAIL_WIDTH, initiatives: planningStructure.initiatives, standaloneWorkstreams: planningStructure.standaloneWorkstreams, allStandaloneWorkstreams: planningStructure.allStandaloneWorkstreams, activeInitiativeId: selectedPlanningInitiativeId, activeWorkstreamId: selectedPlanningWorkstreamId, expandedInitiativeIds: expandedPlanningInitiativeIds, detail: planningDrawerItem, editor: planningEditor, secondaryPane: planningSecondaryPane, currentWorkspaceId: currentWorkspaceId, assigneeOptions: assigneeOptions.map((option) => ({
3131
+ value: String(option.value),
3132
+ label: option.label,
3133
+ kind: option.kind,
3134
+ username: option.username ?? null,
3135
+ archivedAt: option.archivedAt ?? null
3136
+ })), draftInitiativeSummary: planningDraftInitiativeSummary, draftTitle: planningDraftTitle, draftDescription: planningDraftDescription, draftOwner: planningDraftOwner, draftInitiativeId: planningDraftInitiativeId, onChangeDraftTitle: setPlanningDraftTitle, onChangeDraftDescription: setPlanningDraftDescription, onChangeDraftOwner: setPlanningDraftOwner, onChangeDraftInitiativeId: setPlanningDraftInitiativeId, onCollapseTreePane: () => setPlanningTreeCollapsed(true), onExpandTreePane: () => setPlanningTreeCollapsed(false), onCollapsePrimaryPane: () => setPlanningPrimaryCollapsed(true), onExpandPrimaryPane: () => setPlanningPrimaryCollapsed(false), onCollapseSecondaryPane: () => setPlanningSecondaryCollapsed(true), onExpandSecondaryPane: () => setPlanningSecondaryCollapsed(false), onBackFromSecondary: () => {
2935
3137
  planningEditorSubmitInFlightRef.current = false;
2936
3138
  setIsSubmittingPlanningEditor(false);
2937
3139
  setPlanningSecondaryEditor(null);
2938
3140
  setPlanningNestedWorkstreamDetailId(null);
2939
- }, treeCollapsed: planningTreeCollapsed, primaryCollapsed: planningPrimaryCollapsed, secondaryCollapsed: planningSecondaryCollapsed, onCancelEditor: closePlanningEditor, onSubmitEditor: submitPlanningEditor, isSubmittingEditor: isSubmittingPlanningEditor, onCreateInitiative: () => openPlanningCreateEditor('initiative'), onCreateWorkstream: () => openPlanningCreateEditor('workstream'), onCreateTaskInWorkstream: openAddTaskModalForWorkstream, onCreateWorkstreamInInitiative: (initiativeId) => openPlanningCreateEditor('workstream', initiativeId), onAssignInitiativeToWorkstream: handleAssignInitiativeToWorkstream, onOpenTaskById: handleOpenTaskById, onAttachTaskToWorkstreamByReference: handleAttachTaskToWorkstreamByReference, onAttachWorkstreamToInitiativeByReference: handleAttachWorkstreamToInitiativeByReference, onAddPlanningContextFile: handleAddPlanningContextFile, onRemovePlanningContextFile: handleRemovePlanningContextFile, onUpdatePlanningContextCaption: handleUpdatePlanningContextCaption, onToggleInitiative: togglePlanningInitiative, onSelectInitiative: selectPlanningInitiative, onSelectWorkstream: selectPlanningWorkstream, onOpenInitiativeDetails: openInitiativeDetails, onOpenWorkstreamDetails: openWorkstreamDetails, onOpenNestedWorkstreamDetails: openNestedWorkstreamDetails, onEditInitiative: (initiativeId) => openPlanningEditDialog('initiative', initiativeId), onEditWorkstream: (workstreamId) => openPlanningEditDialog('workstream', workstreamId), onArchiveInitiative: (initiativeId) => {
3141
+ }, treeCollapsed: planningTreeCollapsed, primaryCollapsed: planningPrimaryCollapsed, secondaryCollapsed: planningSecondaryCollapsed, onCancelEditor: closePlanningEditor, onSubmitEditor: submitPlanningEditor, isSubmittingEditor: isSubmittingPlanningEditor, onCreateInitiative: () => openPlanningCreateEditor('initiative'), onCreateWorkstream: () => openPlanningCreateEditor('workstream'), onCreateTaskInWorkstream: openAddTaskModalForWorkstream, onCreateWorkstreamInInitiative: (initiativeId) => openPlanningCreateEditor('workstream', initiativeId), onAssignInitiativeToWorkstream: handleAssignInitiativeToWorkstream, onOpenTaskById: handleOpenTaskById, onRemoveTaskFromWorkstream: (taskId) => {
3142
+ void handleAssignTaskToWorkstream(taskId, null);
3143
+ }, onAttachTaskToWorkstreamByReference: handleAttachTaskToWorkstreamByReference, onAttachWorkstreamToInitiativeByReference: handleAttachWorkstreamToInitiativeByReference, onAddPlanningContextFile: handleAddPlanningContextFile, onRemovePlanningContextFile: handleRemovePlanningContextFile, onUpdatePlanningContextCaption: handleUpdatePlanningContextCaption, onToggleInitiative: togglePlanningInitiative, onSelectInitiative: selectPlanningInitiative, onSelectWorkstream: selectPlanningWorkstream, onOpenInitiativeDetails: openInitiativeDetails, onOpenWorkstreamDetails: openWorkstreamDetails, onOpenNestedWorkstreamDetails: openNestedWorkstreamDetails, onEditInitiative: (initiativeId) => openPlanningEditDialog('initiative', initiativeId), onEditWorkstream: (workstreamId) => openPlanningEditDialog('workstream', workstreamId), onArchiveInitiative: (initiativeId) => {
2940
3144
  void props.archiveInitiative(initiativeId).then(() => {
2941
3145
  pushNotice('Initiative archived', 'success');
2942
3146
  }).catch((error) => {
@@ -2971,7 +3175,7 @@ export function StandaloneLayout(props) {
2971
3175
  const workspacePrimaryAction = workspaceChromeDefinition.primaryAction
2972
3176
  ? primaryActionRegistry[workspaceChromeDefinition.primaryAction]
2973
3177
  : null;
2974
- return (_jsxs("div", { className: `${shellStyles.standaloneWrapper} ${zenMode ? styles.zenModeEnabled : ''}`, "data-theme": currentTheme, children: [_jsx(AppShellHeader, { projectName: projectName, currentWorkspaceId: currentWorkspaceId, runtimeMode: runtimeMode, theme: currentTheme, meta: (_jsxs(_Fragment, { children: [_jsx("span", { className: styles.taskCountBadge, title: activeCountTitle, children: activeCountLabel }), normalizedAuthUserId && normalizedAuthUserId !== 'anonymous' && (_jsxs(_Fragment, { children: [_jsxs("span", { className: styles.taskCountBadge, title: "Tasks assigned to me", children: [_jsx(User, { size: 13, className: styles.taskCountBadgeIcon, "aria-hidden": "true" }), assignedTaskCount] }), _jsxs("span", { className: `${styles.taskCountBadge} ${assignedOverdueTaskCount > 0 ? styles.taskCountBadgeAlert : ''}`.trim(), title: "Tasks overdue", children: [_jsx(ClockAlert, { size: 13, className: styles.taskCountBadgeIcon, "aria-hidden": "true" }), assignedOverdueTaskCount] })] })), shouldShowSyncStatus && (_jsx("button", { className: "tf-control-icon", onClick: openSyncStatusModal, title: `Sync manager: ${syncStatusMeta.label} | Last success: ${formattedLastSyncTime}`, style: {
3178
+ return (_jsxs("div", { className: `${shellStyles.standaloneWrapper} ${zenMode ? styles.zenModeEnabled : ''}`, "data-theme": currentTheme, children: [_jsx(AppShellHeader, { projectName: projectName, currentWorkspaceId: currentWorkspaceId, runtimeMode: runtimeMode, theme: currentTheme, onBrandClick: handleOpenKanbanFromBrand, meta: (_jsxs(_Fragment, { children: [_jsx("span", { className: styles.taskCountBadge, title: activeCountTitle, children: activeCountLabel }), normalizedAuthUserId && normalizedAuthUserId !== 'anonymous' && (_jsxs(_Fragment, { children: [_jsxs("span", { className: styles.taskCountBadge, title: "Tasks assigned to me", children: [_jsx(User, { size: 13, className: styles.taskCountBadgeIcon, "aria-hidden": "true" }), assignedTaskCount] }), _jsxs("span", { className: `${styles.taskCountBadge} ${assignedOverdueTaskCount > 0 ? styles.taskCountBadgeAlert : ''}`.trim(), title: "Tasks overdue", children: [_jsx(ClockAlert, { size: 13, className: styles.taskCountBadgeIcon, "aria-hidden": "true" }), assignedOverdueTaskCount] })] })), shouldShowSyncStatus && (_jsx("button", { className: "tf-control-icon", onClick: openSyncStatusModal, title: `Sync manager: ${syncStatusMeta.label} | Last success: ${formattedLastSyncTime}`, style: {
2975
3179
  marginLeft: '6px',
2976
3180
  height: '24px',
2977
3181
  width: '24px',
@@ -2998,10 +3202,14 @@ export function StandaloneLayout(props) {
2998
3202
  overflowX: 'hidden',
2999
3203
  scrollbarGutter: 'stable',
3000
3204
  background: 'var(--surface-page)'
3001
- }, children: _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(PlansPage, { ...props, currentTheme: currentTheme, projectName: projectName, currentWorkspaceId: currentWorkspaceId, authUserId: authUserId, apiBaseUrl: apiBaseUrl, connectedEnvironmentSource: props.config?.cloudAuthBaseUrl || props.config?.apiBaseUrl || '', resolveCloudAuthUrl: resolveCloudAuthUrl, embedded: true, shellOwnsScroll: true, onAccountProfileSummaryChange: applyPlansAccountProfileSummary, onContinueToTaskforce: handlePlansBack, continueBusy: plansNavigationBusy }) }) })) : resolvedWorkspaceModule === 'docs' && documentsWorkspaceEnabled ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(DocumentWorkspaceShell, { tasks: tasks, runtimeMode: runtimeMode, apiBaseUrl: props.config?.apiBaseUrl || '', cloudAuthBaseUrl: props.config?.cloudAuthBaseUrl || '', typeFilters: documentTypeFilters, attachmentFilters: documentAttachmentFilters, onTypeFiltersChange: setDocumentTypeFilters, onAttachmentFiltersChange: setDocumentAttachmentFilters, requestedDocPath: requestedDocPath, requestedDocAssetId: requestedDocAssetId, onRequestedDocHandled: () => {
3205
+ }, children: _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(PlansPage, { ...props, currentTheme: currentTheme, projectName: projectName, currentWorkspaceId: currentWorkspaceId, authUserId: authUserId, apiBaseUrl: apiBaseUrl, connectedEnvironmentSource: props.config?.cloudAuthBaseUrl || props.config?.apiBaseUrl || '', resolveCloudAuthUrl: resolveCloudAuthUrl, embedded: true, shellOwnsScroll: true, onAccountProfileSummaryChange: applyPlansAccountProfileSummary, onContinueToTaskforce: handlePlansBack, continueBusy: plansNavigationBusy }) }) })) : resolvedWorkspaceModule === 'docs' && documentsWorkspaceEnabled ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(DocumentWorkspaceShell, { tasks: tasks, runtimeMode: runtimeMode, apiBaseUrl: props.config?.apiBaseUrl || '', cloudAuthBaseUrl: props.config?.cloudAuthBaseUrl || '', typeFilters: documentTypeFilters, attachmentFilters: documentAttachmentFilters, onTypeFiltersChange: setDocumentTypeFilters, onAttachmentFiltersChange: setDocumentAttachmentFilters, documentTrayOpen: documentTrayOpen, onCloseDocumentTray: () => setDocumentTrayOpen(false), requestedDocPath: requestedDocPath, requestedDocAssetId: requestedDocAssetId, onRequestedDocHandled: () => {
3002
3206
  setRequestedDocPath(null);
3003
3207
  setRequestedDocAssetId(null);
3004
- }, enableTaskGeneration: true }) })] })) : resolvedWorkspaceModule === 'annotate' && annotatedAttachmentsWorkspaceEnabled ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AnnotatedAttachmentWorkspaceShell, { runtimeMode: runtimeMode, apiBaseUrl: props.config?.apiBaseUrl || '', cloudAuthBaseUrl: props.config?.cloudAuthBaseUrl || '', workspaceId: currentWorkspaceId, sessionLoadReady: annotatedWorkspaceReady, requestedTarget: requestedAnnotatedTarget, requestedSessionId: requestedAnnotatedSessionId, requestedOpenVersion: requestedAnnotatedOpenVersion, resolveTaskReferenceLabel: resolveAnnotatedTaskReferenceLabel, resolveImageReferenceLabel: resolveAnnotatedImageReferenceLabel, onOpenTarget: handleAnnotatedAttachmentOpenTarget, onContextChange: handleAnnotatedAttachmentContextChange, onBackToTask: handleBackToTaskFromAnnotatedAttachment }) })] })) : resolvedWorkspaceModule === 'workflows' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(WorkflowsModule, { availableWorkflows: availableWorkflows, availableEnvironments: availableEnvironments, exportEnvironment: exportEnvironment, exportWorkflowsPath: props.exportWorkflowsPath, exportingResource: exportingResource, exportResult: exportResult, onExportEnvironmentChange: props.setExportEnvironment, onExportWorkflows: onExportWorkflows, onRefreshWorkflows: fetchWorkflows, onFetchWorkflowTemplate: props.fetchWorkflowTemplate, onFetchWorkflowOverrideNames: props.fetchWorkflowOverrideNames, onSaveWorkflowTemplateDraft: props.saveWorkflowTemplateDraft, onResetWorkflowTemplateDraft: props.resetWorkflowTemplateDraft }) })] })) : resolvedWorkspaceModule === 'agents' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AgentsModule, { workspaceId: currentWorkspaceId, cloudAuthConfigured: cloudAuthConfigured, authSessionResolved: authSessionResolved, isAuthenticated: isAuthenticated, cloudAiProfileSeatUsage: accountProfileSummary?.aiProfileSeatUsage ?? null }) })] })) : (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent} `, style: {
3208
+ }, onBackToTask: handleBackToTaskFromDocument, enableTaskGeneration: true }) })] })) : resolvedWorkspaceModule === 'annotate' && annotatedAttachmentsWorkspaceEnabled ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AnnotatedAttachmentWorkspaceShell, { runtimeMode: runtimeMode, apiBaseUrl: props.config?.apiBaseUrl || '', cloudAuthBaseUrl: props.config?.cloudAuthBaseUrl || '', workspaceId: currentWorkspaceId, sessionLoadReady: annotatedWorkspaceReady, requestedTarget: requestedAnnotatedTarget, requestedSessionId: requestedAnnotatedSessionId, requestedOpenVersion: requestedAnnotatedOpenVersion, imageTrayOpen: imageTrayOpen, onCloseImageTray: () => setImageTrayOpen(false), resolveTaskReferenceLabel: resolveAnnotatedTaskReferenceLabel, resolveImageReferenceLabel: resolveAnnotatedImageReferenceLabel, onOpenTarget: handleAnnotatedAttachmentOpenTarget, onContextChange: handleAnnotatedAttachmentContextChange, onBackToTask: handleBackToTaskFromAnnotatedAttachment }) })] })) : resolvedWorkspaceModule === 'workflows' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(WorkflowsModule, { availableWorkflows: availableWorkflows, availableEnvironments: availableEnvironments, exportEnvironment: exportEnvironment, exportWorkflowsPath: props.exportWorkflowsPath, exportingResource: exportingResource, exportResult: exportResult, onExportEnvironmentChange: props.setExportEnvironment, onExportWorkflows: onExportWorkflows, onRefreshWorkflows: fetchWorkflows, onFetchWorkflowTemplate: props.fetchWorkflowTemplate, onFetchWorkflowOverrideNames: props.fetchWorkflowOverrideNames, onSaveWorkflowTemplateDraft: props.saveWorkflowTemplateDraft, onResetWorkflowTemplateDraft: props.resetWorkflowTemplateDraft }) })] })) : resolvedWorkspaceModule === 'agents' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AgentsModule, { workspaceId: currentWorkspaceId, cloudAuthConfigured: cloudAuthConfigured, authSessionResolved: authSessionResolved, isAuthenticated: isAuthenticated, cloudAiProfileSeatUsage: accountProfileSummary?.aiProfileSeatUsage ?? null, agentTrayOpen: agentTrayOpen, onCloseAgentTray: () => setAgentTrayOpen(false), mcpSettingsNode: _jsx(TaskSettings, { settingsModel: {
3209
+ ...settingsModel,
3210
+ initialSection: 'mcp',
3211
+ onOpenCloudAuth: openSharedLoginRoute
3212
+ }, renderMode: "mcp-only" }) }) })] })) : (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent} `, style: {
3005
3213
  position: 'relative',
3006
3214
  opacity: props.loadingTasks ? 0.7 : 1,
3007
3215
  transition: 'opacity 0.2s ease, padding 220ms cubic-bezier(0.4, 0, 0.2, 1)',
@@ -3012,7 +3220,7 @@ export function StandaloneLayout(props) {
3012
3220
  ? `${WORKSPACE_TOOL_RAIL_WIDTH + planningDrawerWidthPx + WORKSPACE_CONTENT_GUTTER}px`
3013
3221
  : `${WORKSPACE_TOOL_RAIL_WIDTH + WORKSPACE_CONTENT_GUTTER}px`,
3014
3222
  paddingRight: (groupBy === 'schedule' && scheduleSidebarOpen) ? `${SCHEDULE_SIDEBAR_WIDTH_PX}px` : 0
3015
- }, children: [workspaceToolRail, _jsx("div", { ref: planningDrawerPortalRef, style: {
3223
+ }, children: [workspaceToolRail, _jsx("div", { ref: setPlanningDrawerPortalRef, style: {
3016
3224
  position: 'absolute',
3017
3225
  inset: 0,
3018
3226
  zIndex: 35,
@@ -3027,8 +3235,8 @@ export function StandaloneLayout(props) {
3027
3235
  if (groupBy !== 'schedule')
3028
3236
  return;
3029
3237
  setScheduleScrollLeft(scrollLeft);
3030
- }, emptyColumnMode: emptyColumnMode, categories: activeCategories, compressed: compressedCards, readOnlyMode: taskScope === 'deleted' ? 'deleted' : taskScope === 'archived' ? 'archived' : null, recentlyChangedTaskIds: props.recentlyChangedTaskIds, sortBy: sortBy, sortOrder: props.sortOrder, planningDropTargets: planningDrawerPortalRef.current
3031
- ? createPortal(planningDrawerNode, planningDrawerPortalRef.current)
3238
+ }, emptyColumnMode: emptyColumnMode, categories: activeCategories, compressed: compressedCards, readOnlyMode: taskScope === 'deleted' ? 'deleted' : taskScope === 'archived' ? 'archived' : null, recentlyChangedTaskIds: props.recentlyChangedTaskIds, sortBy: sortBy, sortOrder: props.sortOrder, planningDropTargets: planningDrawerPortalElement
3239
+ ? createPortal(planningDrawerNode, planningDrawerPortalElement)
3032
3240
  : null, onAssignTaskToWorkstream: handleAssignTaskToWorkstream, onAssignWorkstreamToInitiative: handleAssignInitiativeToWorkstream, workstreams: props.workstreams, initiatives: props.initiatives, onUnarchive: (taskId) => {
3033
3241
  if (taskScope === 'deleted') {
3034
3242
  const deletedRecord = deletedTaskRecordByTaskId.get(taskId);
@@ -3084,41 +3292,17 @@ export function StandaloneLayout(props) {
3084
3292
  setSettingsSection(section);
3085
3293
  setActiveTab('settings');
3086
3294
  }, onSubmit: handleSubmit, commentsEndRef: commentsEndRef, onAddComment: () => handleAddComment(newCommentText), onOpenTaskById: handleOpenTaskById, onAddContextFile: (file) => {
3087
- let nextAttachments = attachments;
3088
- setAttachments((prev) => {
3089
- nextAttachments = [...prev, file];
3090
- return nextAttachments;
3091
- });
3092
- setAttachmentsDirty(true);
3093
- if (editingTaskId) {
3094
- void handleUpdateTask(editingTaskId, { attachments: nextAttachments });
3095
- }
3295
+ updateTaskContextAttachments((current) => [...current, file]);
3096
3296
  }, onRemoveContextFile: async (index) => {
3097
- let nextAttachments = attachments;
3098
- setAttachments((prev) => {
3099
- nextAttachments = prev.filter((_, i) => i !== index);
3100
- return nextAttachments;
3101
- });
3102
- setAttachmentsDirty(true);
3103
- if (editingTaskId) {
3104
- void handleUpdateTask(editingTaskId, { attachments: nextAttachments });
3105
- }
3297
+ updateTaskContextAttachments((current) => current.filter((_, i) => i !== index));
3106
3298
  }, onUpdateContextCaption: (index, caption) => {
3107
- let nextAttachments = attachments;
3108
- setAttachments((prev) => {
3109
- nextAttachments = prev.map((s, i) => {
3110
- if (i !== index)
3111
- return s;
3112
- if (typeof s === 'string')
3113
- return { path: s, caption, timestamp: new Date().toISOString() };
3114
- return { ...s, caption };
3115
- });
3116
- return nextAttachments;
3117
- });
3118
- setAttachmentsDirty(true);
3119
- if (editingTaskId) {
3120
- void handleUpdateTask(editingTaskId, { attachments: nextAttachments });
3121
- }
3299
+ updateTaskContextAttachments((current) => current.map((s, i) => {
3300
+ if (i !== index)
3301
+ return s;
3302
+ if (typeof s === 'string')
3303
+ return { path: s, caption, timestamp: new Date().toISOString() };
3304
+ return { ...s, caption };
3305
+ }));
3122
3306
  }, onCopyId: handleCopyId, onToggleInProgress: handleToggleInProgress, onToggleReview: handleToggleReview, onToggleComplete: handleToggleComplete, onToggleCancel: handleToggleCancel, onSetStatus: handleSetStatus, onArchiveTask: handleArchiveTask, onUnarchive: (taskId) => {
3123
3307
  if (currentTask?.isDeleted) {
3124
3308
  const deletedRecord = deletedTaskRecordByTaskId.get(taskId);
@@ -3128,7 +3312,10 @@ export function StandaloneLayout(props) {
3128
3312
  return;
3129
3313
  }
3130
3314
  void handleUnarchive(taskId);
3131
- }, currentTask: currentTask })] }), _jsx(Modal, { isOpen: activeTab === 'settings', onClose: handleCloseModal, title: "Settings", size: "xl", theme: currentTheme, draggable: true, isSettings: true, closeOnOverlayClick: false, children: _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '2rem' }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(TaskSettings, { settingsModel: settingsModel, onSectionChange: setSettingsSection }) }) }), _jsx(ScheduleWarningModal, { prompt: scheduleWarningPrompt, theme: currentTheme, onClose: cancelScheduleWarning, onConfirm: confirmScheduleWarning }), _jsx(SyncEnableWarningModal, { isOpen: showSyncEnableWarning, theme: currentTheme, onClose: cancelSyncEnableWarning, onConfirm: confirmSyncEnableWarning }), _jsx(HelpModal, { isOpen: showHelpModal, theme: currentTheme, onClose: () => setShowHelpModal(false), onOpenSettings: () => {
3315
+ }, currentTask: currentTask })] }), _jsx(Modal, { isOpen: activeTab === 'settings', onClose: handleCloseModal, title: "Settings", size: "xl", theme: currentTheme, draggable: true, isSettings: true, closeOnOverlayClick: false, children: _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '2rem' }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(TaskSettings, { settingsModel: {
3316
+ ...settingsModel,
3317
+ onOpenCloudAuth: openSharedLoginRoute
3318
+ }, onSectionChange: setSettingsSection }) }) }), _jsx(ScheduleWarningModal, { prompt: scheduleWarningPrompt, theme: currentTheme, onClose: cancelScheduleWarning, onConfirm: confirmScheduleWarning }), _jsx(SyncEnableWarningModal, { isOpen: showSyncEnableWarning, theme: currentTheme, onClose: cancelSyncEnableWarning, onConfirm: confirmSyncEnableWarning }), _jsx(HelpModal, { isOpen: showHelpModal, theme: currentTheme, onClose: () => setShowHelpModal(false), onOpenSettings: () => {
3132
3319
  setShowHelpModal(false);
3133
3320
  setActiveTab('settings');
3134
3321
  setSettingsSection('general');