@taskforcehq/taskforce 0.3.326 → 0.3.328

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 (1382) hide show
  1. package/LICENSE.md +68 -0
  2. package/README.md +19 -0
  3. package/dist/Taskforce.module.css +2168 -585
  4. package/dist/TaskforceCore.d.ts +1 -0
  5. package/dist/TaskforceCore.js +65 -22
  6. package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.d.ts +1 -0
  7. package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.js +3 -2
  8. package/dist/annotatedAttachments/commandService.d.ts +68 -0
  9. package/dist/annotatedAttachments/commandService.js +348 -0
  10. package/dist/annotatedAttachments/service.d.ts +2 -0
  11. package/dist/annotatedAttachments/service.js +13 -12
  12. package/dist/cli.js +158 -9
  13. package/dist/cliOpenPort.d.ts +1 -0
  14. package/dist/cliOpenPort.js +4 -0
  15. package/dist/compat/taskforceAgentDefinitionCompat.d.ts +12 -0
  16. package/dist/compat/taskforceAgentDefinitionCompat.js +25 -0
  17. package/dist/compat/workspaceSyncCompat.js +6 -2
  18. package/dist/compat/workspaceSyncV3CombinedCoverageCompat.d.ts +6 -0
  19. package/dist/compat/workspaceSyncV3CombinedCoverageCompat.js +22 -0
  20. package/dist/compat/workspaceSyncV3OperationCompat.d.ts +7 -0
  21. package/dist/compat/workspaceSyncV3OperationCompat.js +30 -0
  22. package/dist/components/activity/EntityActivityTimeline.d.ts +10 -2
  23. package/dist/components/activity/EntityActivityTimeline.js +83 -35
  24. package/dist/components/context/AttachmentPreviewHost.d.ts +6 -0
  25. package/dist/components/context/AttachmentPreviewHost.js +222 -0
  26. package/dist/components/context/ContextAttachmentManager.d.ts +7 -0
  27. package/dist/components/context/ContextAttachmentManager.js +514 -208
  28. package/dist/components/features/AiProfilesModule.d.ts +24 -0
  29. package/dist/components/features/AiProfilesModule.js +744 -0
  30. package/dist/components/features/AnnotatedAttachmentWorkspace.d.ts +4 -1
  31. package/dist/components/features/AnnotatedAttachmentWorkspace.js +351 -79
  32. package/dist/components/features/DocumentGenerateModal.js +23 -5
  33. package/dist/components/features/DocumentIndex.d.ts +19 -1
  34. package/dist/components/features/DocumentIndex.js +104 -15
  35. package/dist/components/features/DocumentViewer.d.ts +9 -1
  36. package/dist/components/features/DocumentViewer.js +721 -100
  37. package/dist/components/features/DocumentWorkspace.d.ts +37 -2
  38. package/dist/components/features/DocumentWorkspace.js +21 -6
  39. package/dist/components/features/TaskSettings.d.ts +6 -27
  40. package/dist/components/features/TaskSettings.js +232 -143
  41. package/dist/components/features/TaskforceAgentsModule.d.ts +36 -0
  42. package/dist/components/features/TaskforceAgentsModule.js +1782 -0
  43. package/dist/components/features/agentBehavior/AgentBehaviorManagerShared.d.ts +94 -0
  44. package/dist/components/features/agentBehavior/AgentBehaviorManagerShared.js +70 -0
  45. package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.d.ts +65 -0
  46. package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.js +115 -0
  47. package/dist/components/features/agentRoles/RoleManagerPanel.d.ts +4 -0
  48. package/dist/components/features/agentRoles/RoleManagerPanel.js +382 -0
  49. package/dist/components/features/agentSkills/SkillManagerPanel.d.ts +5 -0
  50. package/dist/components/features/agentSkills/SkillManagerPanel.js +355 -0
  51. package/dist/components/features/documentWorkspaceModel.d.ts +16 -4
  52. package/dist/components/features/documentWorkspaceModel.js +30 -5
  53. package/dist/components/features/planning/PlanningArchiveConfirmation.d.ts +9 -0
  54. package/dist/components/features/planning/PlanningArchiveConfirmation.js +19 -0
  55. package/dist/components/features/planning/PlanningCardIdentity.d.ts +12 -0
  56. package/dist/components/features/planning/PlanningCardIdentity.js +44 -0
  57. package/dist/components/features/planning/PlanningEntityDetails.d.ts +36 -0
  58. package/dist/components/features/planning/PlanningEntityDetails.js +131 -0
  59. package/dist/components/features/planning/PlanningEntitySummary.d.ts +46 -0
  60. package/dist/components/features/planning/PlanningEntitySummary.js +98 -0
  61. package/dist/components/features/planning/PlanningLinkPicker.d.ts +11 -0
  62. package/dist/components/features/planning/PlanningLinkPicker.js +28 -0
  63. package/dist/components/features/planning/PlanningModule.d.ts +6 -0
  64. package/dist/components/features/planning/PlanningModule.js +588 -0
  65. package/dist/components/features/planning/PlanningOwnerDropdown.d.ts +27 -0
  66. package/dist/components/features/planning/PlanningOwnerDropdown.js +80 -0
  67. package/dist/components/features/planning/PlanningTaskArrangeControl.d.ts +5 -0
  68. package/dist/components/features/planning/PlanningTaskArrangeControl.js +11 -0
  69. package/dist/components/features/planning/PlanningTaskCard.d.ts +20 -0
  70. package/dist/components/features/planning/PlanningTaskCard.js +26 -0
  71. package/dist/components/features/planning/PlanningTaskOrderList.d.ts +10 -0
  72. package/dist/components/features/planning/PlanningTaskOrderList.js +52 -0
  73. package/dist/components/features/planning/PlanningUnlinkConfirmation.d.ts +15 -0
  74. package/dist/components/features/planning/PlanningUnlinkConfirmation.js +7 -0
  75. package/dist/components/features/planning/PlanningVisualIdentity.d.ts +14 -0
  76. package/dist/components/features/planning/PlanningVisualIdentity.js +106 -0
  77. package/dist/components/features/planning/planningCreateIntent.d.ts +10 -0
  78. package/dist/components/features/planning/planningCreateIntent.js +16 -0
  79. package/dist/components/features/planning/planningNavigator.d.ts +33 -0
  80. package/dist/components/features/planning/planningNavigator.js +96 -0
  81. package/dist/components/features/planning/planningTaskArrangement.d.ts +18 -0
  82. package/dist/components/features/planning/planningTaskArrangement.js +106 -0
  83. package/dist/components/features/planning/planningWorkspaceModel.d.ts +132 -0
  84. package/dist/components/features/planning/planningWorkspaceModel.js +5 -0
  85. package/dist/components/features/settings/CategoryManager.js +2 -2
  86. package/dist/components/features/settings/TaxonomyEditor.js +1 -1
  87. package/dist/components/features/settings/TaxonomyManager.js +1 -1
  88. package/dist/components/features/settings/TypeManager.js +1 -1
  89. package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.d.ts +10 -0
  90. package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +175 -0
  91. package/dist/components/features/taskforceAgentAssignments/agentBehaviorCatalogApi.d.ts +27 -0
  92. package/dist/components/features/taskforceAgentAssignments/agentBehaviorCatalogApi.js +24 -0
  93. package/dist/components/features/taskforceAgentEditorModel.d.ts +109 -0
  94. package/dist/components/features/taskforceAgentEditorModel.js +145 -0
  95. package/dist/components/features/useDocumentWorkspaceController.d.ts +20 -1
  96. package/dist/components/features/useDocumentWorkspaceController.js +106 -21
  97. package/dist/components/features/workflowManager/WorkflowManagerModule.d.ts +11 -0
  98. package/dist/components/features/workflowManager/WorkflowManagerModule.js +313 -0
  99. package/dist/components/features/workflowManager/WorkflowPublishDialog.d.ts +11 -0
  100. package/dist/components/features/workflowManager/WorkflowPublishDialog.js +8 -0
  101. package/dist/components/features/workflowManager/types.d.ts +74 -0
  102. package/dist/components/features/workflowManager/types.js +1 -0
  103. package/dist/components/features/workflowManager/useWorkflowManager.d.ts +30 -0
  104. package/dist/components/features/workflowManager/useWorkflowManager.js +213 -0
  105. package/dist/components/features/workflowManager/workflowManagerApi.d.ts +52 -0
  106. package/dist/components/features/workflowManager/workflowManagerApi.js +142 -0
  107. package/dist/components/task/TaskActionHeader.d.ts +7 -3
  108. package/dist/components/task/TaskActionHeader.js +46 -53
  109. package/dist/components/task/TaskCard.d.ts +10 -2
  110. package/dist/components/task/TaskCard.js +138 -56
  111. package/dist/components/task/TaskContextUpload.d.ts +4 -0
  112. package/dist/components/task/TaskContextUpload.js +3 -2
  113. package/dist/components/task/TaskForm.d.ts +16 -17
  114. package/dist/components/task/TaskForm.js +569 -199
  115. package/dist/components/task/TaskImageReviews.d.ts +8 -0
  116. package/dist/components/task/TaskImageReviews.js +47 -0
  117. package/dist/components/task/TaskKanban.d.ts +9 -10
  118. package/dist/components/task/TaskKanban.js +70 -18
  119. package/dist/components/task/TaskList.d.ts +9 -8
  120. package/dist/components/task/TaskList.js +46 -32
  121. package/dist/components/task/TaskReferenceBadge.d.ts +2 -1
  122. package/dist/components/task/TaskReferenceBadge.js +3 -2
  123. package/dist/components/task/TaskStatusActions.d.ts +3 -1
  124. package/dist/components/task/TaskStatusActions.js +27 -7
  125. package/dist/components/task/TaskWorkflowAssignmentField.d.ts +18 -0
  126. package/dist/components/task/TaskWorkflowAssignmentField.js +362 -0
  127. package/dist/components/task/TaskWorkstreamPicker.d.ts +8 -0
  128. package/dist/components/task/TaskWorkstreamPicker.js +25 -0
  129. package/dist/components/task/TrashRestoreControls.d.ts +18 -0
  130. package/dist/components/task/TrashRestoreControls.js +71 -0
  131. package/dist/components/ui/AiIdentityRosterCard.d.ts +20 -0
  132. package/dist/components/ui/AiIdentityRosterCard.js +5 -0
  133. package/dist/components/ui/AssetTraySortControl.d.ts +10 -0
  134. package/dist/components/ui/AssetTraySortControl.js +38 -0
  135. package/dist/components/ui/AssigneeIdentity.d.ts +12 -0
  136. package/dist/components/ui/AssigneeIdentity.js +41 -0
  137. package/dist/components/ui/DiscardChangesDialog.d.ts +10 -0
  138. package/dist/components/ui/DiscardChangesDialog.js +7 -0
  139. package/dist/components/ui/DisclosureSectionHeader.d.ts +4 -1
  140. package/dist/components/ui/DisclosureSectionHeader.js +2 -2
  141. package/dist/components/ui/DocumentTypeIcon.d.ts +7 -0
  142. package/dist/components/ui/DocumentTypeIcon.js +8 -0
  143. package/dist/components/ui/EditableAvatarButton.d.ts +6 -1
  144. package/dist/components/ui/EditableAvatarButton.js +6 -5
  145. package/dist/components/ui/HierarchyActionBadge.d.ts +2 -1
  146. package/dist/components/ui/HierarchyActionBadge.js +2 -2
  147. package/dist/components/ui/Markdown.d.ts +13 -3
  148. package/dist/components/ui/Markdown.fixture.d.ts +1 -0
  149. package/dist/components/ui/Markdown.fixture.js +23 -0
  150. package/dist/components/ui/Markdown.js +158 -68
  151. package/dist/components/ui/Modal.d.ts +3 -1
  152. package/dist/components/ui/Modal.js +85 -19
  153. package/dist/components/ui/MultiSelectFilter.d.ts +9 -2
  154. package/dist/components/ui/MultiSelectFilter.js +26 -5
  155. package/dist/components/ui/ReferenceBadgeButton.js +2 -3
  156. package/dist/components/ui/TaxonomyDropdown.d.ts +18 -1
  157. package/dist/components/ui/TaxonomyDropdown.js +177 -59
  158. package/dist/components/ui/TopNoticeLayer.d.ts +2 -1
  159. package/dist/components/ui/TopNoticeLayer.js +5 -2
  160. package/dist/components/ui/useFallbackImageUrl.d.ts +4 -0
  161. package/dist/components/ui/useFallbackImageUrl.js +20 -0
  162. package/dist/components/views/AppShellHeader.js +2 -2
  163. package/dist/components/views/StandaloneLayout.d.ts +1 -0
  164. package/dist/components/views/StandaloneLayout.js +1717 -600
  165. package/dist/components/views/WidgetView.d.ts +1 -0
  166. package/dist/components/views/WidgetView.js +99 -31
  167. package/dist/components/views/chrome/WorkspaceChromeSections.d.ts +4 -2
  168. package/dist/components/views/chrome/WorkspaceChromeSections.js +3 -6
  169. package/dist/components/views/chrome/workspaceChrome.d.ts +5 -8
  170. package/dist/components/views/chrome/workspaceChrome.js +62 -27
  171. package/dist/components/views/panels/FilterToolbar.d.ts +4 -3
  172. package/dist/components/views/panels/FilterToolbar.js +8 -5
  173. package/dist/components/views/panels/FilterToolbarControls.d.ts +11 -2
  174. package/dist/components/views/panels/FilterToolbarControls.js +35 -20
  175. package/dist/components/views/panels/PlanningDrawer.d.ts +66 -49
  176. package/dist/components/views/panels/PlanningDrawer.js +983 -314
  177. package/dist/components/views/planningScope.js +7 -1
  178. package/dist/components/views/standalone/modals/AccountSettingsModal.d.ts +62 -0
  179. package/dist/components/views/standalone/modals/AccountSettingsModal.js +197 -0
  180. package/dist/components/views/standalone/modals/AvatarImageManagerModal.d.ts +7 -2
  181. package/dist/components/views/standalone/modals/AvatarImageManagerModal.js +56 -9
  182. package/dist/components/views/standalone/modals/HelpModal.d.ts +1 -2
  183. package/dist/components/views/standalone/modals/HelpModal.js +3 -4
  184. package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +8 -9
  185. package/dist/components/views/standalone/modals/SyncStatusModal.js +85 -25
  186. package/dist/components/views/standalone/modals/TeamManagementModal.js +1 -1
  187. package/dist/config/applicationBaseUrl.d.ts +2 -0
  188. package/dist/config/applicationBaseUrl.js +23 -0
  189. package/dist/config/envSchema.d.ts +1 -1
  190. package/dist/config/envSchema.js +167 -5
  191. package/dist/config/localServiceCloudTarget.d.ts +10 -0
  192. package/dist/config/localServiceCloudTarget.js +76 -0
  193. package/dist/core/AdminAuditRetentionService.d.ts +43 -0
  194. package/dist/core/AdminAuditRetentionService.js +126 -0
  195. package/dist/core/AiProfileService.d.ts +35 -0
  196. package/dist/core/AiProfileService.js +511 -251
  197. package/dist/core/AttachmentLinkService.d.ts +10 -2
  198. package/dist/core/AttachmentLinkService.js +50 -15
  199. package/dist/core/AuthIdentityService.d.ts +6 -0
  200. package/dist/core/AuthIdentityService.js +38 -0
  201. package/dist/core/AuthTokenService.d.ts +1 -0
  202. package/dist/core/AuthTokenService.js +13 -0
  203. package/dist/core/DeletedTaskLifecycleService.d.ts +8 -2
  204. package/dist/core/DeletedTaskLifecycleService.js +145 -38
  205. package/dist/core/GlobalSettingsService.d.ts +3 -1
  206. package/dist/core/GlobalSettingsService.js +30 -4
  207. package/dist/core/InitiativeDurableMutationService.d.ts +89 -0
  208. package/dist/core/InitiativeDurableMutationService.js +187 -0
  209. package/dist/core/McpTokenService.d.ts +5 -0
  210. package/dist/core/McpTokenService.js +91 -13
  211. package/dist/core/PlanningCommandPreparationService.d.ts +60 -0
  212. package/dist/core/PlanningCommandPreparationService.js +149 -0
  213. package/dist/core/ScheduleCommandService.d.ts +76 -0
  214. package/dist/core/ScheduleCommandService.js +165 -0
  215. package/dist/core/SyncReconciliationService.d.ts +29 -6
  216. package/dist/core/SyncReconciliationService.js +256 -84
  217. package/dist/core/TaskActivityService.d.ts +22 -2
  218. package/dist/core/TaskActivityService.js +177 -29
  219. package/dist/core/TaskAttachmentLinksDurableMutationService.d.ts +36 -0
  220. package/dist/core/TaskAttachmentLinksDurableMutationService.js +240 -0
  221. package/dist/core/TaskChecklistCommandService.d.ts +50 -0
  222. package/dist/core/TaskChecklistCommandService.js +111 -0
  223. package/dist/core/TaskDurableCreateMutationService.d.ts +38 -0
  224. package/dist/core/TaskDurableCreateMutationService.js +85 -0
  225. package/dist/core/TaskDurableDeleteMutationService.d.ts +47 -0
  226. package/dist/core/TaskDurableDeleteMutationService.js +54 -0
  227. package/dist/core/TaskDurableLifecycleMutationService.d.ts +38 -0
  228. package/dist/core/TaskDurableLifecycleMutationService.js +42 -0
  229. package/dist/core/TaskDurableRelationshipMutationService.d.ts +58 -0
  230. package/dist/core/TaskDurableRelationshipMutationService.js +66 -0
  231. package/dist/core/TaskDurableRestoreMutationService.d.ts +31 -0
  232. package/dist/core/TaskDurableRestoreMutationService.js +33 -0
  233. package/dist/core/TaskDurableStatusMutationService.d.ts +74 -0
  234. package/dist/core/TaskDurableStatusMutationService.js +247 -0
  235. package/dist/core/TaskDurableSyncMutationService.d.ts +34 -0
  236. package/dist/core/TaskDurableSyncMutationService.js +70 -0
  237. package/dist/core/TaskDurableWorkflowMutationService.d.ts +48 -0
  238. package/dist/core/TaskDurableWorkflowMutationService.js +59 -0
  239. package/dist/core/TaskLifecycleCommandService.d.ts +101 -0
  240. package/dist/core/TaskLifecycleCommandService.js +161 -0
  241. package/dist/core/TaskRootCommandPreparationService.d.ts +35 -0
  242. package/dist/core/TaskRootCommandPreparationService.js +103 -0
  243. package/dist/core/Taskforce.d.ts +542 -60
  244. package/dist/core/Taskforce.js +4220 -905
  245. package/dist/core/WorkflowAssignmentService.d.ts +40 -0
  246. package/dist/core/WorkflowAssignmentService.js +158 -0
  247. package/dist/core/WorkflowExecutionService.d.ts +69 -0
  248. package/dist/core/WorkflowExecutionService.js +342 -0
  249. package/dist/core/WorkflowTaskActivationService.d.ts +32 -0
  250. package/dist/core/WorkflowTaskActivationService.js +63 -0
  251. package/dist/core/WorkflowTemplateService.d.ts +64 -0
  252. package/dist/core/WorkflowTemplateService.js +223 -0
  253. package/dist/core/WorkspaceLifecycleService.d.ts +1 -0
  254. package/dist/core/WorkspaceLifecycleService.js +18 -0
  255. package/dist/core/WorkstreamDurableMutationService.d.ts +90 -0
  256. package/dist/core/WorkstreamDurableMutationService.js +184 -0
  257. package/dist/core/planningReferencePolicy.d.ts +14 -0
  258. package/dist/core/planningReferencePolicy.js +53 -0
  259. package/dist/core/taskReferencePolicy.js +24 -3
  260. package/dist/core/types.d.ts +12 -11
  261. package/dist/documentReviews/DocumentReviewCommentStore.d.ts +33 -2
  262. package/dist/documentReviews/DocumentReviewCommentStore.js +125 -8
  263. package/dist/documentReviews/commandService.d.ts +51 -0
  264. package/dist/documentReviews/commandService.js +63 -0
  265. package/dist/documentReviews/service.d.ts +24 -1
  266. package/dist/documentReviews/service.js +354 -49
  267. package/dist/documentReviews/types.d.ts +18 -1
  268. package/dist/hooks/sync/bootstrap.d.ts +3 -7
  269. package/dist/hooks/sync/bootstrap.js +6 -14
  270. package/dist/hooks/sync/browserSyncAuthority.d.ts +21 -0
  271. package/dist/hooks/sync/browserSyncAuthority.js +70 -0
  272. package/dist/hooks/sync/browserSyncRemoteServices.d.ts +29 -0
  273. package/dist/hooks/sync/browserSyncRemoteServices.js +58 -0
  274. package/dist/hooks/sync/controlPlane.d.ts +1 -37
  275. package/dist/hooks/sync/controlPlane.js +1 -78
  276. package/dist/hooks/sync/lifecyclePolicy.d.ts +1 -45
  277. package/dist/hooks/sync/lifecyclePolicy.js +1 -93
  278. package/dist/hooks/sync/orchestratorShared.d.ts +9 -3
  279. package/dist/hooks/sync/orchestratorShared.js +70 -96
  280. package/dist/hooks/sync/pullLifecycle.d.ts +1 -31
  281. package/dist/hooks/sync/pullLifecycle.js +1 -24
  282. package/dist/hooks/sync/realtime.d.ts +4 -1
  283. package/dist/hooks/sync/realtime.js +103 -3
  284. package/dist/hooks/sync/recovery.d.ts +1 -84
  285. package/dist/hooks/sync/recovery.js +1 -245
  286. package/dist/hooks/sync/transfers.d.ts +8 -129
  287. package/dist/hooks/sync/transfers.js +19 -581
  288. package/dist/hooks/sync/useDataVersionRefresh.d.ts +6 -1
  289. package/dist/hooks/sync/useDataVersionRefresh.js +127 -12
  290. package/dist/hooks/sync/useDurableLocalOutboxDrain.d.ts +14 -0
  291. package/dist/hooks/sync/useDurableLocalOutboxDrain.js +208 -0
  292. package/dist/hooks/sync/useDurableTaskCreateMutation.d.ts +15 -0
  293. package/dist/hooks/sync/useDurableTaskCreateMutation.js +152 -0
  294. package/dist/hooks/sync/useDurableTaskDeleteMutation.d.ts +11 -0
  295. package/dist/hooks/sync/useDurableTaskDeleteMutation.js +21 -0
  296. package/dist/hooks/sync/useDurableTaskLifecycleMutation.d.ts +12 -0
  297. package/dist/hooks/sync/useDurableTaskLifecycleMutation.js +22 -0
  298. package/dist/hooks/sync/useDurableTaskMetadataMutation.d.ts +14 -0
  299. package/dist/hooks/sync/useDurableTaskMetadataMutation.js +24 -0
  300. package/dist/hooks/sync/useDurableTaskRestoreMutation.d.ts +12 -0
  301. package/dist/hooks/sync/useDurableTaskRestoreMutation.js +24 -0
  302. package/dist/hooks/sync/useDurableTaskStatusMutation.d.ts +18 -0
  303. package/dist/hooks/sync/useDurableTaskStatusMutation.js +23 -0
  304. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.d.ts +23 -0
  305. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.js +414 -0
  306. package/dist/hooks/sync/useSyncStatusActions.d.ts +2 -1
  307. package/dist/hooks/sync/useSyncStatusActions.js +8 -3
  308. package/dist/hooks/tasks/taskHttpMutation.d.ts +25 -0
  309. package/dist/hooks/tasks/taskHttpMutation.js +134 -0
  310. package/dist/hooks/tasks/useCurrentTaskRelations.d.ts +6 -1
  311. package/dist/hooks/tasks/useCurrentTaskRelations.js +32 -6
  312. package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +4 -3
  313. package/dist/hooks/tasks/useTaskEditorNavigation.js +9 -13
  314. package/dist/hooks/tasks/useTaskFormActions.d.ts +20 -2
  315. package/dist/hooks/tasks/useTaskFormActions.js +339 -59
  316. package/dist/hooks/tasks/useTaskReferenceContract.d.ts +5 -0
  317. package/dist/hooks/tasks/useTaskReferenceContract.js +17 -0
  318. package/dist/hooks/tasks/useTaskRelationships.d.ts +1 -3
  319. package/dist/hooks/tasks/useTaskRelationships.js +5 -25
  320. package/dist/hooks/tasks/useTrashSelection.d.ts +12 -0
  321. package/dist/hooks/tasks/useTrashSelection.js +49 -0
  322. package/dist/hooks/ui/useInitiativeTemplates.d.ts +24 -0
  323. package/dist/hooks/ui/useInitiativeTemplates.js +22 -0
  324. package/dist/hooks/ui/useSettingsModel.d.ts +5 -29
  325. package/dist/hooks/ui/useSettingsModel.js +31 -15
  326. package/dist/hooks/ui/useSettingsPersistence.d.ts +0 -1
  327. package/dist/hooks/ui/useSettingsPersistence.js +4 -8
  328. package/dist/hooks/ui/useSettingsTaxonomyManagement.js +31 -0
  329. package/dist/hooks/useFilterSort.d.ts +2 -2
  330. package/dist/hooks/useFilterSort.js +19 -15
  331. package/dist/hooks/useRealtimeSync.d.ts +10 -0
  332. package/dist/hooks/useRealtimeSync.js +57 -4
  333. package/dist/hooks/useSyncOrchestrator.d.ts +32 -1
  334. package/dist/hooks/useSyncOrchestrator.js +963 -287
  335. package/dist/hooks/useTaskData.d.ts +11 -2
  336. package/dist/hooks/useTaskData.js +59 -26
  337. package/dist/hooks/useTaskMutations.d.ts +42 -5
  338. package/dist/hooks/useTaskMutations.js +750 -125
  339. package/dist/hooks/useTaskforce.d.ts +79 -74
  340. package/dist/hooks/useTaskforce.js +1205 -450
  341. package/dist/hooks/useUiNotice.d.ts +5 -1
  342. package/dist/hooks/useUiNotice.js +13 -2
  343. package/dist/hooks/useWorkspaceSyncController.d.ts +9 -0
  344. package/dist/hooks/useWorkspaceSyncController.js +159 -17
  345. package/dist/hooks/workspace/usePersistedAppUiState.d.ts +74 -0
  346. package/dist/hooks/workspace/usePersistedAppUiState.js +325 -0
  347. package/dist/hooks/workspace/usePersistedLayoutUiState.d.ts +76 -0
  348. package/dist/hooks/workspace/usePersistedLayoutUiState.js +479 -0
  349. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.d.ts +2 -7
  350. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +42 -31
  351. package/dist/hooks/workspace/workspaceLocalState.d.ts +17 -6
  352. package/dist/hooks/workspace/workspaceLocalState.js +175 -5
  353. package/dist/hooks/workstreams/workstreamHttpMutation.d.ts +23 -0
  354. package/dist/hooks/workstreams/workstreamHttpMutation.js +134 -0
  355. package/dist/localization/locales/en-US.d.ts +3 -3
  356. package/dist/localization/locales/en-US.js +3 -3
  357. package/dist/localization/locales/es-419.js +3 -3
  358. package/dist/localization/locales/pt-BR.js +3 -3
  359. package/dist/mcp/adminWorkspaceRegistrar.js +2 -30
  360. package/dist/mcp/aiProfileBootstrap.d.ts +3 -0
  361. package/dist/mcp/aiProfileBootstrap.js +4 -0
  362. package/dist/mcp/canonicalAssetHelpers.d.ts +29 -4
  363. package/dist/mcp/canonicalAssetHelpers.js +138 -35
  364. package/dist/mcp/clientIntegrations.d.ts +4 -2
  365. package/dist/mcp/clientIntegrations.js +58 -57
  366. package/dist/mcp/clientRegistry.d.ts +30 -0
  367. package/dist/mcp/clientRegistry.js +134 -0
  368. package/dist/mcp/collaborationRegistrar.js +31 -15
  369. package/dist/mcp/documentAssetRegistrar.js +231 -56
  370. package/dist/mcp/documentContentCommand.d.ts +94 -0
  371. package/dist/mcp/documentContentCommand.js +226 -0
  372. package/dist/mcp/documentHelpers.d.ts +13 -65
  373. package/dist/mcp/documentHelpers.js +49 -62
  374. package/dist/mcp/durableTaskMutationRouter.d.ts +65 -0
  375. package/dist/mcp/durableTaskMutationRouter.js +217 -0
  376. package/dist/mcp/durableTaskRelationshipMutationRouter.d.ts +38 -0
  377. package/dist/mcp/durableTaskRelationshipMutationRouter.js +168 -0
  378. package/dist/mcp/durableTaskRootMutationRouter.d.ts +64 -0
  379. package/dist/mcp/durableTaskRootMutationRouter.js +226 -0
  380. package/dist/mcp/gitWorktreeRoots.d.ts +2 -0
  381. package/dist/mcp/gitWorktreeRoots.js +19 -0
  382. package/dist/mcp/legacyServer.d.ts +1 -0
  383. package/dist/mcp/legacyServer.js +42 -0
  384. package/dist/mcp/localCliHealth.d.ts +56 -0
  385. package/dist/mcp/localCliHealth.js +170 -0
  386. package/dist/mcp/localServiceProxy.d.ts +23 -0
  387. package/dist/mcp/localServiceProxy.js +258 -0
  388. package/dist/mcp/mcpInputValidator.d.ts +17 -0
  389. package/dist/mcp/mcpInputValidator.js +58 -0
  390. package/dist/mcp/planningAttachmentCommandAdapter.d.ts +127 -0
  391. package/dist/mcp/planningAttachmentCommandAdapter.js +188 -0
  392. package/dist/mcp/programScaffoldCommandAdapter.d.ts +6 -0
  393. package/dist/mcp/programScaffoldCommandAdapter.js +39 -0
  394. package/dist/mcp/proxyServer.d.ts +1 -0
  395. package/dist/mcp/proxyServer.js +2 -0
  396. package/dist/mcp/runtime.d.ts +98 -1
  397. package/dist/mcp/runtime.js +4682 -1927
  398. package/dist/mcp/server.js +29 -2
  399. package/dist/mcp/sharedLocalServiceGateD.d.ts +115 -0
  400. package/dist/mcp/sharedLocalServiceGateD.js +344 -0
  401. package/dist/mcp/stdioLifecycle.d.ts +22 -0
  402. package/dist/mcp/stdioLifecycle.js +54 -0
  403. package/dist/mcp/taskAttachmentCommandAdapter.d.ts +192 -0
  404. package/dist/mcp/taskAttachmentCommandAdapter.js +470 -0
  405. package/dist/mcp/taskAttachmentHelpers.d.ts +8 -6
  406. package/dist/mcp/taskAttachmentHelpers.js +74 -2
  407. package/dist/mcp/taskAttachmentTypes.d.ts +26 -5
  408. package/dist/mcp/taskPlanCommand.d.ts +64 -0
  409. package/dist/mcp/taskPlanCommand.js +98 -0
  410. package/dist/mcp/taskPlanningRegistrar.js +240 -44
  411. package/dist/mcp/toolCallCompatibility.d.ts +6 -0
  412. package/dist/mcp/toolCallCompatibility.js +16 -0
  413. package/dist/mcp/toolCatalog.d.ts +3 -1
  414. package/dist/mcp/toolProfiles.d.ts +12 -1
  415. package/dist/mcp/toolProfiles.js +43 -0
  416. package/dist/mcp/toolRegistry.d.ts +17 -2
  417. package/dist/mcp/toolRegistry.js +26 -11
  418. package/dist/mcp/workflowExecutionRegistrar.d.ts +2 -0
  419. package/dist/mcp/workflowExecutionRegistrar.js +51 -0
  420. package/dist/migrations/taskSchemaMigrations.d.ts +35 -0
  421. package/dist/migrations/taskSchemaMigrations.js +1892 -64
  422. package/dist/migrations/taskUpdatedAtSyncDriftMigration.d.ts +20 -0
  423. package/dist/migrations/taskUpdatedAtSyncDriftMigration.js +153 -0
  424. package/dist/migrations/taskforceAgentDefinitionMigration.d.ts +26 -0
  425. package/dist/migrations/taskforceAgentDefinitionMigration.js +116 -0
  426. package/dist/plugins/vite.js +48 -17
  427. package/dist/public/Taskforce_Van.webp +0 -0
  428. package/dist/runtime/appGateDefinitions.d.ts +16 -10
  429. package/dist/runtime/appGateDefinitions.js +16 -10
  430. package/dist/runtime/appGates.d.ts +5 -4
  431. package/dist/runtime/appGates.js +4 -3
  432. package/dist/server/aiProfileAvatarAssets.d.ts +11 -8
  433. package/dist/server/aiProfileAvatarAssets.js +159 -70
  434. package/dist/server/appAccess.d.ts +12 -0
  435. package/dist/server/appAccess.js +21 -0
  436. package/dist/server/auth.js +15 -1
  437. package/dist/server/authorizedWorkspaceAccess.d.ts +12 -0
  438. package/dist/server/authorizedWorkspaceAccess.js +40 -0
  439. package/dist/server/cloudCollectionRead.d.ts +25 -0
  440. package/dist/server/cloudCollectionRead.js +120 -0
  441. package/dist/server/cloudCollectionReadPool.d.ts +52 -0
  442. package/dist/server/cloudCollectionReadPool.js +140 -0
  443. package/dist/server/cloudCollectionReadWorker.d.ts +1 -0
  444. package/dist/server/cloudCollectionReadWorker.js +36 -0
  445. package/dist/server/cors.d.ts +2 -1
  446. package/dist/server/cors.js +45 -8
  447. package/dist/server/email.d.ts +3 -1
  448. package/dist/server/email.js +46 -8
  449. package/dist/server/index.d.ts +27 -12
  450. package/dist/server/index.js +395 -86
  451. package/dist/server/localDataOwnerPermit.d.ts +18 -0
  452. package/dist/server/localDataOwnerPermit.js +58 -0
  453. package/dist/server/localDatabaseIdentity.d.ts +14 -0
  454. package/dist/server/localDatabaseIdentity.js +69 -0
  455. package/dist/server/localRealtimeFileInvalidation.d.ts +1 -0
  456. package/dist/server/localRealtimeFileInvalidation.js +7 -0
  457. package/dist/server/localServiceLease.d.ts +65 -0
  458. package/dist/server/localServiceLease.js +485 -0
  459. package/dist/server/localServiceOwnershipBootstrap.d.ts +19 -0
  460. package/dist/server/localServiceOwnershipBootstrap.js +84 -0
  461. package/dist/server/localServiceSessions.d.ts +87 -0
  462. package/dist/server/localServiceSessions.js +309 -0
  463. package/dist/server/localServiceWindowsAcl.d.ts +8 -0
  464. package/dist/server/localServiceWindowsAcl.js +60 -0
  465. package/dist/server/localSyncProcessLockBootstrap.d.ts +3 -0
  466. package/dist/server/localSyncProcessLockBootstrap.js +16 -0
  467. package/dist/server/localWorkspaceSyncServerComposition.d.ts +59 -0
  468. package/dist/server/localWorkspaceSyncServerComposition.js +91 -0
  469. package/dist/server/localWorkspaceSyncServerRuntime.d.ts +119 -0
  470. package/dist/server/localWorkspaceSyncServerRuntime.js +1163 -0
  471. package/dist/server/rateLimit.d.ts +1 -0
  472. package/dist/server/rateLimit.js +16 -0
  473. package/dist/server/routes/admin.d.ts +2 -4
  474. package/dist/server/routes/admin.js +199 -337
  475. package/dist/server/routes/agentRoles.d.ts +13 -0
  476. package/dist/server/routes/agentRoles.js +273 -0
  477. package/dist/server/routes/agentSkills.d.ts +16 -0
  478. package/dist/server/routes/agentSkills.js +291 -0
  479. package/dist/server/routes/agents.d.ts +49 -0
  480. package/dist/server/routes/agents.js +1455 -0
  481. package/dist/server/routes/annotatedAttachments.js +46 -9
  482. package/dist/server/routes/assetAccess.d.ts +36 -0
  483. package/dist/server/routes/assetAccess.js +93 -0
  484. package/dist/server/routes/auth.d.ts +4 -3
  485. package/dist/server/routes/auth.js +236 -21
  486. package/dist/server/routes/authSupport.d.ts +3 -1
  487. package/dist/server/routes/authSupport.js +22 -8
  488. package/dist/server/routes/documentReviews.d.ts +2 -0
  489. package/dist/server/routes/documentReviews.js +155 -15
  490. package/dist/server/routes/documents.d.ts +6 -2
  491. package/dist/server/routes/documents.js +492 -151
  492. package/dist/server/routes/durableTaskHttpRouters.d.ts +167 -0
  493. package/dist/server/routes/durableTaskHttpRouters.js +89 -0
  494. package/dist/server/routes/localMcpHealth.d.ts +11 -0
  495. package/dist/server/routes/localMcpHealth.js +29 -0
  496. package/dist/server/routes/localService.d.ts +13 -0
  497. package/dist/server/routes/localService.js +446 -0
  498. package/dist/server/routes/localUpdate.d.ts +11 -0
  499. package/dist/server/routes/localUpdate.js +154 -0
  500. package/dist/server/routes/primitives.d.ts +29 -0
  501. package/dist/server/routes/primitives.js +18 -0
  502. package/dist/server/routes/resources.d.ts +1 -10
  503. package/dist/server/routes/resources.js +1 -153
  504. package/dist/server/routes/shared.d.ts +55 -2
  505. package/dist/server/routes/shared.js +506 -16
  506. package/dist/server/routes/sync.d.ts +2 -0
  507. package/dist/server/routes/sync.js +206 -272
  508. package/dist/server/routes/syncAuxRoutes.d.ts +3 -1
  509. package/dist/server/routes/syncAuxRoutes.js +9 -4
  510. package/dist/server/routes/syncCoordinatorLocalRoutes.d.ts +6 -0
  511. package/dist/server/routes/syncCoordinatorLocalRoutes.js +867 -0
  512. package/dist/server/routes/syncPullApplyRoutes.d.ts +29 -1
  513. package/dist/server/routes/syncPullApplyRoutes.js +520 -17
  514. package/dist/server/routes/syncPushRoutes.d.ts +33 -4
  515. package/dist/server/routes/syncPushRoutes.js +251 -62
  516. package/dist/server/routes/syncRouteTypes.d.ts +1 -1
  517. package/dist/server/routes/syncSnapshotRoutes.d.ts +15 -7
  518. package/dist/server/routes/syncSnapshotRoutes.js +95 -17
  519. package/dist/server/routes/syncV3DiagnosticsRoutes.d.ts +14 -0
  520. package/dist/server/routes/syncV3DiagnosticsRoutes.js +72 -0
  521. package/dist/server/routes/syncV3FeedRoutes.d.ts +20 -0
  522. package/dist/server/routes/syncV3FeedRoutes.js +464 -0
  523. package/dist/server/routes/syncV3LocalCaptureRoutes.d.ts +37 -0
  524. package/dist/server/routes/syncV3LocalCaptureRoutes.js +915 -0
  525. package/dist/server/routes/syncV3LocalDispatchRoutes.d.ts +17 -0
  526. package/dist/server/routes/syncV3LocalDispatchRoutes.js +280 -0
  527. package/dist/server/routes/syncV3LocalFeedApplyRoutes.d.ts +17 -0
  528. package/dist/server/routes/syncV3LocalFeedApplyRoutes.js +493 -0
  529. package/dist/server/routes/syncV3LocalOwnershipRoutes.d.ts +10 -0
  530. package/dist/server/routes/syncV3LocalOwnershipRoutes.js +51 -0
  531. package/dist/server/routes/syncV3LocalRecoveryRoutes.d.ts +12 -0
  532. package/dist/server/routes/syncV3LocalRecoveryRoutes.js +78 -0
  533. package/dist/server/routes/syncV3OperationRoutes.d.ts +35 -0
  534. package/dist/server/routes/syncV3OperationRoutes.js +1151 -0
  535. package/dist/server/routes/tasks.d.ts +0 -2
  536. package/dist/server/routes/tasks.js +1083 -236
  537. package/dist/server/routes/workflows.d.ts +26 -0
  538. package/dist/server/routes/workflows.js +500 -0
  539. package/dist/server/routes.d.ts +1 -6
  540. package/dist/server/routes.js +179 -342
  541. package/dist/server/smtpTransport.d.ts +11 -3
  542. package/dist/server/smtpTransport.js +9 -2
  543. package/dist/server/start.js +42 -10
  544. package/dist/service/localServiceCli.d.ts +33 -0
  545. package/dist/service/localServiceCli.js +376 -0
  546. package/dist/service/localServiceClientLifecycle.d.ts +25 -0
  547. package/dist/service/localServiceClientLifecycle.js +189 -0
  548. package/dist/service/localServiceOpen.d.ts +17 -0
  549. package/dist/service/localServiceOpen.js +27 -0
  550. package/dist/services/agentRoleResolver.d.ts +4 -0
  551. package/dist/services/agentRoleResolver.js +7 -0
  552. package/dist/services/aiProfileAvatarGenerationService.d.ts +41 -0
  553. package/dist/services/aiProfileAvatarGenerationService.js +158 -0
  554. package/dist/services/avatarImageProvider.d.ts +33 -0
  555. package/dist/services/avatarImageProvider.js +140 -0
  556. package/dist/services/bedrockAnthropicMessagesModelGateway.d.ts +24 -0
  557. package/dist/services/bedrockAnthropicMessagesModelGateway.js +95 -0
  558. package/dist/services/bedrockMantleModelGateway.d.ts +43 -0
  559. package/dist/services/bedrockMantleModelGateway.js +81 -0
  560. package/dist/services/bedrockModelGateway.d.ts +26 -0
  561. package/dist/services/bedrockModelGateway.js +94 -0
  562. package/dist/services/modelGateway.d.ts +82 -0
  563. package/dist/services/modelGateway.js +61 -0
  564. package/dist/services/taskforceAgentAvatarImageProvider.d.ts +8 -0
  565. package/dist/services/taskforceAgentAvatarImageProvider.js +24 -0
  566. package/dist/services/taskforceAgentMcpBridge.d.ts +77 -0
  567. package/dist/services/taskforceAgentMcpBridge.js +527 -0
  568. package/dist/shared/agentRoleDefinition.d.ts +34 -0
  569. package/dist/shared/agentRoleDefinition.js +207 -0
  570. package/dist/shared/aiProfileAvatarEligibility.d.ts +10 -0
  571. package/dist/shared/aiProfileAvatarEligibility.js +27 -0
  572. package/dist/shared/aiProfileColors.d.ts +7 -0
  573. package/dist/shared/aiProfileColors.js +33 -0
  574. package/dist/shared/colorPalette.d.ts +3 -0
  575. package/dist/shared/colorPalette.js +20 -0
  576. package/dist/shared/commentProvenance.d.ts +4 -0
  577. package/dist/shared/commentProvenance.js +6 -0
  578. package/dist/shared/deletedTaskRetention.d.ts +2 -0
  579. package/dist/shared/deletedTaskRetention.js +7 -0
  580. package/dist/shared/passwordPolicy.d.ts +2 -1
  581. package/dist/shared/passwordPolicy.js +9 -0
  582. package/dist/shared/planningIdentity.d.ts +20 -0
  583. package/dist/shared/planningIdentity.js +79 -0
  584. package/dist/shared/taskDeepLinks.d.ts +28 -0
  585. package/dist/shared/taskDeepLinks.js +48 -0
  586. package/dist/shared/taskRestoreDestination.d.ts +2 -0
  587. package/dist/shared/taskRestoreDestination.js +5 -0
  588. package/dist/shared/taskforceAgentDefinition.d.ts +88 -0
  589. package/dist/shared/taskforceAgentDefinition.js +434 -0
  590. package/dist/shared/taskforceAgentExecutionSnapshot.d.ts +50 -0
  591. package/dist/shared/taskforceAgentExecutionSnapshot.js +68 -0
  592. package/dist/shared/taskforceAgentModels.d.ts +56 -0
  593. package/dist/shared/taskforceAgentModels.js +314 -0
  594. package/dist/shared/taskforceAgentRunContext.d.ts +23 -0
  595. package/dist/shared/taskforceAgentRunContext.js +21 -0
  596. package/dist/shared/taskforceAgentRuntimeResolution.d.ts +31 -0
  597. package/dist/shared/taskforceAgentRuntimeResolution.js +72 -0
  598. package/dist/shared/taskforceAgentSkill.d.ts +33 -0
  599. package/dist/shared/taskforceAgentSkill.js +149 -0
  600. package/dist/storage/agentRoleStore.d.ts +91 -0
  601. package/dist/storage/agentRoleStore.js +385 -0
  602. package/dist/storage/databaseAdapter.d.ts +1 -0
  603. package/dist/storage/databaseAdapter.js +7 -1
  604. package/dist/storage/documentIntegrity.d.ts +12 -3
  605. package/dist/storage/documentIntegrity.js +105 -27
  606. package/dist/storage/objectStorageClient.d.ts +10 -4
  607. package/dist/storage/objectStorageClient.js +73 -43
  608. package/dist/storage/postgresAdapter.d.ts +2 -1
  609. package/dist/storage/postgresAdapter.js +42 -6
  610. package/dist/storage/postgresRequestDiagnostics.d.ts +8 -0
  611. package/dist/storage/postgresRequestDiagnostics.js +24 -0
  612. package/dist/storage/postgresWorker.js +65 -1
  613. package/dist/storage/sqliteAdapter.d.ts +1 -1
  614. package/dist/storage/sqliteAdapter.js +7 -1
  615. package/dist/storage/sqliteWalHealth.d.ts +71 -0
  616. package/dist/storage/sqliteWalHealth.js +176 -0
  617. package/dist/storage/taskDataPath.d.ts +1 -0
  618. package/dist/storage/taskDataPath.js +20 -0
  619. package/dist/storage/taskforceAgentConversationStore.d.ts +66 -0
  620. package/dist/storage/taskforceAgentConversationStore.js +264 -0
  621. package/dist/storage/taskforceAgentSkillStore.d.ts +93 -0
  622. package/dist/storage/taskforceAgentSkillStore.js +355 -0
  623. package/dist/storage/taskforceAgentStore.d.ts +105 -0
  624. package/dist/storage/taskforceAgentStore.js +549 -0
  625. package/dist/storage/workflowStore.d.ts +223 -0
  626. package/dist/storage/workflowStore.js +1032 -0
  627. package/dist/storage/workspaceAssetStore.d.ts +102 -0
  628. package/dist/storage/workspaceAssetStore.js +488 -25
  629. package/dist/sync/aiProfileAvatarSyncPaths.d.ts +14 -0
  630. package/dist/sync/aiProfileAvatarSyncPaths.js +56 -0
  631. package/dist/sync/cloudSyncApi.d.ts +329 -0
  632. package/dist/sync/cloudSyncApi.js +574 -1
  633. package/dist/sync/collaborationSyncPayload.d.ts +5 -1
  634. package/dist/sync/collaborationSyncPayload.js +213 -1
  635. package/dist/sync/collaborationSyncState.d.ts +23 -3
  636. package/dist/sync/collaborationSyncState.js +92 -3
  637. package/dist/sync/contentSyncPayload.d.ts +9 -0
  638. package/dist/sync/contentSyncPayload.js +29 -0
  639. package/dist/sync/contentSyncState.d.ts +79 -4
  640. package/dist/sync/contentSyncState.js +1113 -313
  641. package/dist/sync/coordinator/localSyncBrowserApplyPermitContext.d.ts +39 -0
  642. package/dist/sync/coordinator/localSyncBrowserApplyPermitContext.js +234 -0
  643. package/dist/sync/coordinator/localSyncBrowserAuthorityCapability.d.ts +7 -0
  644. package/dist/sync/coordinator/localSyncBrowserAuthorityCapability.js +10 -0
  645. package/dist/sync/coordinator/localSyncCommittedApplyPolicy.d.ts +7 -0
  646. package/dist/sync/coordinator/localSyncCommittedApplyPolicy.js +41 -0
  647. package/dist/sync/coordinator/localSyncCoordinatorBrowserClient.d.ts +178 -0
  648. package/dist/sync/coordinator/localSyncCoordinatorBrowserClient.js +131 -0
  649. package/dist/sync/coordinator/localSyncCoordinatorCommandLifecycle.d.ts +25 -0
  650. package/dist/sync/coordinator/localSyncCoordinatorCommandLifecycle.js +200 -0
  651. package/dist/sync/coordinator/localSyncCoordinatorHost.d.ts +84 -0
  652. package/dist/sync/coordinator/localSyncCoordinatorHost.js +435 -0
  653. package/dist/sync/coordinator/localSyncCoordinatorRouteServices.d.ts +33 -0
  654. package/dist/sync/coordinator/localSyncCoordinatorRouteServices.js +1 -0
  655. package/dist/sync/coordinator/localSyncCoordinatorStore.d.ts +122 -0
  656. package/dist/sync/coordinator/localSyncCoordinatorStore.js +1039 -0
  657. package/dist/sync/coordinator/localSyncCoordinatorTypes.d.ts +82 -0
  658. package/dist/sync/coordinator/localSyncCoordinatorTypes.js +9 -0
  659. package/dist/sync/coordinator/localSyncDispatchTracker.d.ts +15 -0
  660. package/dist/sync/coordinator/localSyncDispatchTracker.js +68 -0
  661. package/dist/sync/coordinator/localSyncExecutionPermitStore.d.ts +216 -0
  662. package/dist/sync/coordinator/localSyncExecutionPermitStore.js +1436 -0
  663. package/dist/sync/coordinator/localSyncExecutionPermitTypes.d.ts +52 -0
  664. package/dist/sync/coordinator/localSyncExecutionPermitTypes.js +8 -0
  665. package/dist/sync/coordinator/localSyncOwnershipDrainBarrier.d.ts +33 -0
  666. package/dist/sync/coordinator/localSyncOwnershipDrainBarrier.js +83 -0
  667. package/dist/sync/coordinator/localSyncPermitTransactionHooks.d.ts +9 -0
  668. package/dist/sync/coordinator/localSyncPermitTransactionHooks.js +27 -0
  669. package/dist/sync/coordinator/localSyncProcessLock.d.ts +12 -0
  670. package/dist/sync/coordinator/localSyncProcessLock.js +212 -0
  671. package/dist/sync/coordinator/localSyncV3DispatchRecoveryReconciler.d.ts +17 -0
  672. package/dist/sync/coordinator/localSyncV3DispatchRecoveryReconciler.js +82 -0
  673. package/dist/sync/coordinator/localWorkspaceSyncRunner.d.ts +134 -0
  674. package/dist/sync/coordinator/localWorkspaceSyncRunner.js +981 -0
  675. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.d.ts +189 -0
  676. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.js +961 -0
  677. package/dist/sync/coordinator/workspaceSyncCloudCredentialValidator.d.ts +19 -0
  678. package/dist/sync/coordinator/workspaceSyncCloudCredentialValidator.js +83 -0
  679. package/dist/sync/coordinator/workspaceSyncCredentialBroker.d.ts +117 -0
  680. package/dist/sync/coordinator/workspaceSyncCredentialBroker.js +323 -0
  681. package/dist/sync/coordinator/workspaceSyncLocalAccessBootstrap.d.ts +11 -0
  682. package/dist/sync/coordinator/workspaceSyncLocalAccessBootstrap.js +51 -0
  683. package/dist/sync/coordinator/workspaceSyncTransportGateway.d.ts +139 -0
  684. package/dist/sync/coordinator/workspaceSyncTransportGateway.js +740 -0
  685. package/dist/sync/engine/localWorkspaceContentManifestService.d.ts +21 -0
  686. package/dist/sync/engine/localWorkspaceContentManifestService.js +44 -0
  687. package/dist/sync/engine/workspaceSyncAtomicLocalPublisher.d.ts +36 -0
  688. package/dist/sync/engine/workspaceSyncAtomicLocalPublisher.js +203 -0
  689. package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.d.ts +21 -0
  690. package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.js +13 -0
  691. package/dist/sync/engine/workspaceSyncContentPullObligationStore.d.ts +65 -0
  692. package/dist/sync/engine/workspaceSyncContentPullObligationStore.js +160 -0
  693. package/dist/sync/engine/workspaceSyncContentVersionStore.d.ts +216 -0
  694. package/dist/sync/engine/workspaceSyncContentVersionStore.js +1068 -0
  695. package/dist/sync/engine/workspaceSyncEngineBrowserGatewayRemoteServices.d.ts +28 -0
  696. package/dist/sync/engine/workspaceSyncEngineBrowserGatewayRemoteServices.js +543 -0
  697. package/dist/sync/engine/workspaceSyncEngineContracts.d.ts +78 -0
  698. package/dist/sync/engine/workspaceSyncEngineContracts.js +1 -0
  699. package/dist/sync/engine/workspaceSyncEngineControlPlane.d.ts +37 -0
  700. package/dist/sync/engine/workspaceSyncEngineControlPlane.js +79 -0
  701. package/dist/sync/engine/workspaceSyncEngineIdentity.d.ts +1 -0
  702. package/dist/sync/engine/workspaceSyncEngineIdentity.js +4 -0
  703. package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.d.ts +68 -0
  704. package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +180 -0
  705. package/dist/sync/engine/workspaceSyncEngineLocalApply.d.ts +72 -0
  706. package/dist/sync/engine/workspaceSyncEngineLocalApply.js +132 -0
  707. package/dist/sync/engine/workspaceSyncEngineLocalServices.d.ts +70 -0
  708. package/dist/sync/engine/workspaceSyncEngineLocalServices.js +25 -0
  709. package/dist/sync/engine/workspaceSyncEngineParity.d.ts +8 -0
  710. package/dist/sync/engine/workspaceSyncEngineParity.js +7 -0
  711. package/dist/sync/engine/workspaceSyncEnginePullPolicy.d.ts +32 -0
  712. package/dist/sync/engine/workspaceSyncEnginePullPolicy.js +27 -0
  713. package/dist/sync/engine/workspaceSyncEnginePushCompletion.d.ts +20 -0
  714. package/dist/sync/engine/workspaceSyncEnginePushCompletion.js +87 -0
  715. package/dist/sync/engine/workspaceSyncEngineRecovery.d.ts +56 -0
  716. package/dist/sync/engine/workspaceSyncEngineRecovery.js +288 -0
  717. package/dist/sync/engine/workspaceSyncEngineRemoteServices.d.ts +109 -0
  718. package/dist/sync/engine/workspaceSyncEngineRemoteServices.js +21 -0
  719. package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +61 -0
  720. package/dist/sync/engine/workspaceSyncEngineRuntime.js +59 -0
  721. package/dist/sync/engine/workspaceSyncEngineServerApplyBoundary.d.ts +28 -0
  722. package/dist/sync/engine/workspaceSyncEngineServerApplyBoundary.js +86 -0
  723. package/dist/sync/engine/workspaceSyncEngineServerLocalServices.d.ts +73 -0
  724. package/dist/sync/engine/workspaceSyncEngineServerLocalServices.js +452 -0
  725. package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.d.ts +23 -0
  726. package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.js +466 -0
  727. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.d.ts +125 -0
  728. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +1147 -0
  729. package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.d.ts +63 -0
  730. package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +276 -0
  731. package/dist/sync/engine/workspaceSyncEngineTransferCompletion.d.ts +20 -0
  732. package/dist/sync/engine/workspaceSyncEngineTransferCompletion.js +37 -0
  733. package/dist/sync/engine/workspaceSyncEngineTransferTypes.d.ts +7 -0
  734. package/dist/sync/engine/workspaceSyncEngineTransferTypes.js +1 -0
  735. package/dist/sync/engine/workspaceSyncEngineTransfers.d.ts +240 -0
  736. package/dist/sync/engine/workspaceSyncEngineTransfers.js +1184 -0
  737. package/dist/sync/engine/workspaceSyncEngineV3LocalFeedApply.d.ts +39 -0
  738. package/dist/sync/engine/workspaceSyncEngineV3LocalFeedApply.js +39 -0
  739. package/dist/sync/engine/workspaceSyncImmutableContentGcRunner.d.ts +25 -0
  740. package/dist/sync/engine/workspaceSyncImmutableContentGcRunner.js +83 -0
  741. package/dist/sync/engine/workspaceSyncImmutableContentProvider.d.ts +71 -0
  742. package/dist/sync/engine/workspaceSyncImmutableContentProvider.js +209 -0
  743. package/dist/sync/engine/workspaceSyncImmutableContentStager.d.ts +32 -0
  744. package/dist/sync/engine/workspaceSyncImmutableContentStager.js +202 -0
  745. package/dist/sync/engine/workspaceSyncPublishedContentResolver.d.ts +43 -0
  746. package/dist/sync/engine/workspaceSyncPublishedContentResolver.js +142 -0
  747. package/dist/sync/engine/workspaceSyncServerContentRuntime.d.ts +26 -0
  748. package/dist/sync/engine/workspaceSyncServerContentRuntime.js +41 -0
  749. package/dist/sync/engine/workspaceSyncServerDataServices.d.ts +44 -0
  750. package/dist/sync/engine/workspaceSyncServerDataServices.js +143 -0
  751. package/dist/sync/engine/workspaceSyncTransferEvidence.d.ts +39 -0
  752. package/dist/sync/engine/workspaceSyncTransferEvidence.js +45 -0
  753. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.d.ts +44 -0
  754. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +992 -0
  755. package/dist/sync/engine/workspaceSyncV2PreparedContent.d.ts +82 -0
  756. package/dist/sync/engine/workspaceSyncV2PreparedContent.js +219 -0
  757. package/dist/sync/planningCanonicalFields.d.ts +41 -0
  758. package/dist/sync/planningCanonicalFields.js +211 -0
  759. package/dist/sync/planningSyncPayload.d.ts +5 -1
  760. package/dist/sync/planningSyncPayload.js +88 -4
  761. package/dist/sync/syncApplyHandlers.d.ts +100 -8
  762. package/dist/sync/syncApplyHandlers.js +845 -78
  763. package/dist/sync/syncResourceAdapters.d.ts +10 -0
  764. package/dist/sync/syncResourceAdapters.js +21 -1
  765. package/dist/sync/syncService.d.ts +57 -1
  766. package/dist/sync/syncService.js +1094 -138
  767. package/dist/sync/taskNestedContent.d.ts +2 -0
  768. package/dist/sync/taskNestedContent.js +8 -0
  769. package/dist/sync/taskSyncChangeKey.js +0 -1
  770. package/dist/sync/taskSyncPayload.d.ts +1 -1
  771. package/dist/sync/taskSyncPayload.js +20 -3
  772. package/dist/sync/v3/canonicalWorkspaceSyncJson.d.ts +2 -0
  773. package/dist/sync/v3/canonicalWorkspaceSyncJson.js +26 -0
  774. package/dist/sync/v3/combinedFeedCapability.d.ts +21 -0
  775. package/dist/sync/v3/combinedFeedCapability.js +80 -0
  776. package/dist/sync/v3/combinedFeedPrerequisites.d.ts +18 -0
  777. package/dist/sync/v3/combinedFeedPrerequisites.js +184 -0
  778. package/dist/sync/v3/durableInitiativeMutationRouter.d.ts +61 -0
  779. package/dist/sync/v3/durableInitiativeMutationRouter.js +287 -0
  780. package/dist/sync/v3/durableOperationReplay.d.ts +36 -0
  781. package/dist/sync/v3/durableOperationReplay.js +103 -0
  782. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.d.ts +50 -0
  783. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +216 -0
  784. package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +47 -0
  785. package/dist/sync/v3/durableTaskChecklistMutationRouter.js +182 -0
  786. package/dist/sync/v3/durableTaskCommentMutationRouter.d.ts +47 -0
  787. package/dist/sync/v3/durableTaskCommentMutationRouter.js +191 -0
  788. package/dist/sync/v3/durableTaskHttpBulkMutationRouter.d.ts +60 -0
  789. package/dist/sync/v3/durableTaskHttpBulkMutationRouter.js +333 -0
  790. package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +40 -0
  791. package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +518 -0
  792. package/dist/sync/v3/durableTaxonomyMutationRouter.d.ts +63 -0
  793. package/dist/sync/v3/durableTaxonomyMutationRouter.js +289 -0
  794. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.d.ts +77 -0
  795. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +361 -0
  796. package/dist/sync/v3/durableWorkstreamMutationRouter.d.ts +61 -0
  797. package/dist/sync/v3/durableWorkstreamMutationRouter.js +287 -0
  798. package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.d.ts +42 -0
  799. package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.js +122 -0
  800. package/dist/sync/v3/entityEventLegacyAdoptionContract.d.ts +6 -0
  801. package/dist/sync/v3/entityEventLegacyAdoptionContract.js +6 -0
  802. package/dist/sync/v3/entityEventLegacyAdoptionService.d.ts +62 -0
  803. package/dist/sync/v3/entityEventLegacyAdoptionService.js +180 -0
  804. package/dist/sync/v3/initiativeActivityAuthoritativeRevision.d.ts +11 -0
  805. package/dist/sync/v3/initiativeActivityAuthoritativeRevision.js +23 -0
  806. package/dist/sync/v3/initiativeActivityIdentity.d.ts +8 -0
  807. package/dist/sync/v3/initiativeActivityIdentity.js +14 -0
  808. package/dist/sync/v3/initiativeCoexistence.d.ts +26 -0
  809. package/dist/sync/v3/initiativeCoexistence.js +148 -0
  810. package/dist/sync/v3/initiativeFeedActivationCapability.d.ts +6 -0
  811. package/dist/sync/v3/initiativeFeedActivationCapability.js +16 -0
  812. package/dist/sync/v3/initiativeMutationPayload.d.ts +26 -0
  813. package/dist/sync/v3/initiativeMutationPayload.js +144 -0
  814. package/dist/sync/v3/initiativeMutationService.d.ts +62 -0
  815. package/dist/sync/v3/initiativeMutationService.js +206 -0
  816. package/dist/sync/v3/localEntityEventLegacyAdoption.d.ts +31 -0
  817. package/dist/sync/v3/localEntityEventLegacyAdoption.js +607 -0
  818. package/dist/sync/v3/localInitiativeOutboxHandler.d.ts +8 -0
  819. package/dist/sync/v3/localInitiativeOutboxHandler.js +88 -0
  820. package/dist/sync/v3/localInitiativeOutboxService.d.ts +50 -0
  821. package/dist/sync/v3/localInitiativeOutboxService.js +497 -0
  822. package/dist/sync/v3/localOperationIdentityStore.d.ts +81 -0
  823. package/dist/sync/v3/localOperationIdentityStore.js +388 -0
  824. package/dist/sync/v3/localOutboxDispatchCapability.d.ts +7 -0
  825. package/dist/sync/v3/localOutboxDispatchCapability.js +13 -0
  826. package/dist/sync/v3/localOutboxDispatchRuntime.d.ts +16 -0
  827. package/dist/sync/v3/localOutboxDispatchRuntime.js +269 -0
  828. package/dist/sync/v3/localOutboxDispatcher.d.ts +53 -0
  829. package/dist/sync/v3/localOutboxDispatcher.js +366 -0
  830. package/dist/sync/v3/localOutboxDrainClient.d.ts +50 -0
  831. package/dist/sync/v3/localOutboxDrainClient.js +250 -0
  832. package/dist/sync/v3/localOutboxOperationHandler.d.ts +31 -0
  833. package/dist/sync/v3/localOutboxOperationHandler.js +10 -0
  834. package/dist/sync/v3/localOutboxRecoveryClient.d.ts +14 -0
  835. package/dist/sync/v3/localOutboxRecoveryClient.js +45 -0
  836. package/dist/sync/v3/localOutboxRecoveryPreparationService.d.ts +12 -0
  837. package/dist/sync/v3/localOutboxRecoveryPreparationService.js +151 -0
  838. package/dist/sync/v3/localSyncIdentityStore.d.ts +9 -0
  839. package/dist/sync/v3/localSyncIdentityStore.js +43 -0
  840. package/dist/sync/v3/localTaskAttachmentLinksOutboxHandler.d.ts +10 -0
  841. package/dist/sync/v3/localTaskAttachmentLinksOutboxHandler.js +80 -0
  842. package/dist/sync/v3/localTaskAttachmentLinksOutboxService.d.ts +46 -0
  843. package/dist/sync/v3/localTaskAttachmentLinksOutboxService.js +303 -0
  844. package/dist/sync/v3/localTaskChecklistOutboxHandler.d.ts +10 -0
  845. package/dist/sync/v3/localTaskChecklistOutboxHandler.js +54 -0
  846. package/dist/sync/v3/localTaskChecklistOutboxService.d.ts +47 -0
  847. package/dist/sync/v3/localTaskChecklistOutboxService.js +221 -0
  848. package/dist/sync/v3/localTaskCommentOutboxHandler.d.ts +10 -0
  849. package/dist/sync/v3/localTaskCommentOutboxHandler.js +94 -0
  850. package/dist/sync/v3/localTaskCommentOutboxService.d.ts +75 -0
  851. package/dist/sync/v3/localTaskCommentOutboxService.js +391 -0
  852. package/dist/sync/v3/localTaskCreateClient.d.ts +27 -0
  853. package/dist/sync/v3/localTaskCreateClient.js +209 -0
  854. package/dist/sync/v3/localTaskCreateOutboxHandler.d.ts +8 -0
  855. package/dist/sync/v3/localTaskCreateOutboxHandler.js +147 -0
  856. package/dist/sync/v3/localTaskCreateOutboxService.d.ts +77 -0
  857. package/dist/sync/v3/localTaskCreateOutboxService.js +397 -0
  858. package/dist/sync/v3/localTaskDeleteClient.d.ts +10 -0
  859. package/dist/sync/v3/localTaskDeleteClient.js +23 -0
  860. package/dist/sync/v3/localTaskDeleteOutboxHandler.d.ts +8 -0
  861. package/dist/sync/v3/localTaskDeleteOutboxHandler.js +54 -0
  862. package/dist/sync/v3/localTaskDeleteOutboxService.d.ts +38 -0
  863. package/dist/sync/v3/localTaskDeleteOutboxService.js +235 -0
  864. package/dist/sync/v3/localTaskLegacyRootAdoption.d.ts +28 -0
  865. package/dist/sync/v3/localTaskLegacyRootAdoption.js +219 -0
  866. package/dist/sync/v3/localTaskLifecycleClient.d.ts +49 -0
  867. package/dist/sync/v3/localTaskLifecycleClient.js +57 -0
  868. package/dist/sync/v3/localTaskLifecycleOutboxHandler.d.ts +8 -0
  869. package/dist/sync/v3/localTaskLifecycleOutboxHandler.js +94 -0
  870. package/dist/sync/v3/localTaskLifecycleOutboxService.d.ts +60 -0
  871. package/dist/sync/v3/localTaskLifecycleOutboxService.js +304 -0
  872. package/dist/sync/v3/localTaskMetadataClient.d.ts +13 -0
  873. package/dist/sync/v3/localTaskMetadataClient.js +30 -0
  874. package/dist/sync/v3/localTaskMetadataOutboxHandler.d.ts +8 -0
  875. package/dist/sync/v3/localTaskMetadataOutboxHandler.js +70 -0
  876. package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +48 -0
  877. package/dist/sync/v3/localTaskMetadataOutboxService.js +229 -0
  878. package/dist/sync/v3/localTaskOperationClient.d.ts +72 -0
  879. package/dist/sync/v3/localTaskOperationClient.js +195 -0
  880. package/dist/sync/v3/localTaskRelationshipOutboxHandler.d.ts +8 -0
  881. package/dist/sync/v3/localTaskRelationshipOutboxHandler.js +114 -0
  882. package/dist/sync/v3/localTaskRelationshipOutboxService.d.ts +45 -0
  883. package/dist/sync/v3/localTaskRelationshipOutboxService.js +192 -0
  884. package/dist/sync/v3/localTaskRestoreClient.d.ts +13 -0
  885. package/dist/sync/v3/localTaskRestoreClient.js +32 -0
  886. package/dist/sync/v3/localTaskRestoreOutboxHandler.d.ts +8 -0
  887. package/dist/sync/v3/localTaskRestoreOutboxHandler.js +41 -0
  888. package/dist/sync/v3/localTaskRestoreOutboxService.d.ts +56 -0
  889. package/dist/sync/v3/localTaskRestoreOutboxService.js +323 -0
  890. package/dist/sync/v3/localTaskStatusClient.d.ts +17 -0
  891. package/dist/sync/v3/localTaskStatusClient.js +35 -0
  892. package/dist/sync/v3/localTaskStatusOutboxHandler.d.ts +8 -0
  893. package/dist/sync/v3/localTaskStatusOutboxHandler.js +75 -0
  894. package/dist/sync/v3/localTaskStatusOutboxService.d.ts +53 -0
  895. package/dist/sync/v3/localTaskStatusOutboxService.js +422 -0
  896. package/dist/sync/v3/localTaxonomyCompositeOutboxService.d.ts +34 -0
  897. package/dist/sync/v3/localTaxonomyCompositeOutboxService.js +290 -0
  898. package/dist/sync/v3/localTaxonomyOutboxHandler.d.ts +9 -0
  899. package/dist/sync/v3/localTaxonomyOutboxHandler.js +106 -0
  900. package/dist/sync/v3/localTaxonomyOutboxService.d.ts +30 -0
  901. package/dist/sync/v3/localTaxonomyOutboxService.js +181 -0
  902. package/dist/sync/v3/localWorkflowRuntimeOutboxHandler.d.ts +8 -0
  903. package/dist/sync/v3/localWorkflowRuntimeOutboxHandler.js +113 -0
  904. package/dist/sync/v3/localWorkflowRuntimeOutboxService.d.ts +37 -0
  905. package/dist/sync/v3/localWorkflowRuntimeOutboxService.js +330 -0
  906. package/dist/sync/v3/localWorkspaceSyncServerOutboxDispatcher.d.ts +63 -0
  907. package/dist/sync/v3/localWorkspaceSyncServerOutboxDispatcher.js +264 -0
  908. package/dist/sync/v3/localWorkstreamOutboxHandler.d.ts +8 -0
  909. package/dist/sync/v3/localWorkstreamOutboxHandler.js +102 -0
  910. package/dist/sync/v3/localWorkstreamOutboxService.d.ts +52 -0
  911. package/dist/sync/v3/localWorkstreamOutboxService.js +581 -0
  912. package/dist/sync/v3/localWorkstreamTaskOrderOutboxHandler.d.ts +10 -0
  913. package/dist/sync/v3/localWorkstreamTaskOrderOutboxHandler.js +57 -0
  914. package/dist/sync/v3/localWorkstreamTaskOrderOutboxService.d.ts +30 -0
  915. package/dist/sync/v3/localWorkstreamTaskOrderOutboxService.js +128 -0
  916. package/dist/sync/v3/planningActivation.d.ts +13 -0
  917. package/dist/sync/v3/planningActivation.js +33 -0
  918. package/dist/sync/v3/planningAttachmentActivityValidation.d.ts +9 -0
  919. package/dist/sync/v3/planningAttachmentActivityValidation.js +87 -0
  920. package/dist/sync/v3/programScaffoldService.d.ts +143 -0
  921. package/dist/sync/v3/programScaffoldService.js +478 -0
  922. package/dist/sync/v3/syncDurabilityStore.d.ts +781 -0
  923. package/dist/sync/v3/syncDurabilityStore.js +4773 -0
  924. package/dist/sync/v3/taskActivityAuthoritativeRevision.d.ts +16 -0
  925. package/dist/sync/v3/taskActivityAuthoritativeRevision.js +67 -0
  926. package/dist/sync/v3/taskActivityJournal.d.ts +20 -0
  927. package/dist/sync/v3/taskActivityJournal.js +195 -0
  928. package/dist/sync/v3/taskAttachmentLinksActivityIdentity.d.ts +6 -0
  929. package/dist/sync/v3/taskAttachmentLinksActivityIdentity.js +14 -0
  930. package/dist/sync/v3/taskAttachmentLinksMutationService.d.ts +112 -0
  931. package/dist/sync/v3/taskAttachmentLinksMutationService.js +218 -0
  932. package/dist/sync/v3/taskChecklistActivityIdentity.d.ts +6 -0
  933. package/dist/sync/v3/taskChecklistActivityIdentity.js +14 -0
  934. package/dist/sync/v3/taskChecklistMutationService.d.ts +92 -0
  935. package/dist/sync/v3/taskChecklistMutationService.js +156 -0
  936. package/dist/sync/v3/taskCommentActivityIdentity.d.ts +7 -0
  937. package/dist/sync/v3/taskCommentActivityIdentity.js +15 -0
  938. package/dist/sync/v3/taskCommentMutationService.d.ts +150 -0
  939. package/dist/sync/v3/taskCommentMutationService.js +392 -0
  940. package/dist/sync/v3/taskCommentReconcileProvenance.d.ts +58 -0
  941. package/dist/sync/v3/taskCommentReconcileProvenance.js +170 -0
  942. package/dist/sync/v3/taskCreateActivation.d.ts +19 -0
  943. package/dist/sync/v3/taskCreateActivation.js +84 -0
  944. package/dist/sync/v3/taskCreateActivityIdentity.d.ts +7 -0
  945. package/dist/sync/v3/taskCreateActivityIdentity.js +18 -0
  946. package/dist/sync/v3/taskCreateMutationService.d.ts +103 -0
  947. package/dist/sync/v3/taskCreateMutationService.js +283 -0
  948. package/dist/sync/v3/taskDeleteActivation.d.ts +7 -0
  949. package/dist/sync/v3/taskDeleteActivation.js +14 -0
  950. package/dist/sync/v3/taskDeleteMutationService.d.ts +35 -0
  951. package/dist/sync/v3/taskDeleteMutationService.js +133 -0
  952. package/dist/sync/v3/taskLegacyRootAdoptionService.d.ts +78 -0
  953. package/dist/sync/v3/taskLegacyRootAdoptionService.js +175 -0
  954. package/dist/sync/v3/taskLifecycleActivityIdentity.d.ts +9 -0
  955. package/dist/sync/v3/taskLifecycleActivityIdentity.js +18 -0
  956. package/dist/sync/v3/taskLifecycleMutationPayload.d.ts +5 -0
  957. package/dist/sync/v3/taskLifecycleMutationPayload.js +28 -0
  958. package/dist/sync/v3/taskLifecycleMutationService.d.ts +66 -0
  959. package/dist/sync/v3/taskLifecycleMutationService.js +92 -0
  960. package/dist/sync/v3/taskMetadataActivation.d.ts +12 -0
  961. package/dist/sync/v3/taskMetadataActivation.js +38 -0
  962. package/dist/sync/v3/taskMetadataActivityIdentity.d.ts +7 -0
  963. package/dist/sync/v3/taskMetadataActivityIdentity.js +18 -0
  964. package/dist/sync/v3/taskMetadataCoexistence.d.ts +37 -0
  965. package/dist/sync/v3/taskMetadataCoexistence.js +138 -0
  966. package/dist/sync/v3/taskMetadataMutationService.d.ts +71 -0
  967. package/dist/sync/v3/taskMetadataMutationService.js +199 -0
  968. package/dist/sync/v3/taskRelationshipLegacyAdoptionService.d.ts +48 -0
  969. package/dist/sync/v3/taskRelationshipLegacyAdoptionService.js +164 -0
  970. package/dist/sync/v3/taskRelationshipMutationService.d.ts +50 -0
  971. package/dist/sync/v3/taskRelationshipMutationService.js +148 -0
  972. package/dist/sync/v3/taskRestoreMutationService.d.ts +90 -0
  973. package/dist/sync/v3/taskRestoreMutationService.js +179 -0
  974. package/dist/sync/v3/taskStatusActivation.d.ts +7 -0
  975. package/dist/sync/v3/taskStatusActivation.js +15 -0
  976. package/dist/sync/v3/taskStatusMutationService.d.ts +76 -0
  977. package/dist/sync/v3/taskStatusMutationService.js +308 -0
  978. package/dist/sync/v3/taskWorkflowMutationPayload.d.ts +4 -0
  979. package/dist/sync/v3/taskWorkflowMutationPayload.js +22 -0
  980. package/dist/sync/v3/taskWorkflowMutationService.d.ts +64 -0
  981. package/dist/sync/v3/taskWorkflowMutationService.js +102 -0
  982. package/dist/sync/v3/taxonomyCoexistence.d.ts +10 -0
  983. package/dist/sync/v3/taxonomyCoexistence.js +19 -0
  984. package/dist/sync/v3/taxonomyCompositeMutationService.d.ts +110 -0
  985. package/dist/sync/v3/taxonomyCompositeMutationService.js +304 -0
  986. package/dist/sync/v3/taxonomyMutationService.d.ts +57 -0
  987. package/dist/sync/v3/taxonomyMutationService.js +106 -0
  988. package/dist/sync/v3/taxonomyStateMutation.d.ts +22 -0
  989. package/dist/sync/v3/taxonomyStateMutation.js +49 -0
  990. package/dist/sync/v3/taxonomySyncPayload.d.ts +9 -0
  991. package/dist/sync/v3/taxonomySyncPayload.js +199 -0
  992. package/dist/sync/v3/workflowAssignmentSync.d.ts +22 -0
  993. package/dist/sync/v3/workflowAssignmentSync.js +213 -0
  994. package/dist/sync/v3/workflowRuntimeMutationService.d.ts +89 -0
  995. package/dist/sync/v3/workflowRuntimeMutationService.js +359 -0
  996. package/dist/sync/v3/workflowRuntimeOperationIdentity.d.ts +13 -0
  997. package/dist/sync/v3/workflowRuntimeOperationIdentity.js +35 -0
  998. package/dist/sync/v3/workflowRuntimeSync.d.ts +141 -0
  999. package/dist/sync/v3/workflowRuntimeSync.js +485 -0
  1000. package/dist/sync/v3/workspaceSyncJournalReader.d.ts +43 -0
  1001. package/dist/sync/v3/workspaceSyncJournalReader.js +45 -0
  1002. package/dist/sync/v3/workspaceSyncLocalOwnershipSnapshot.d.ts +28 -0
  1003. package/dist/sync/v3/workspaceSyncLocalOwnershipSnapshot.js +81 -0
  1004. package/dist/sync/v3/workspaceSyncPayloadFingerprint.d.ts +1 -0
  1005. package/dist/sync/v3/workspaceSyncPayloadFingerprint.js +5 -0
  1006. package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.d.ts +16 -0
  1007. package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.js +153 -0
  1008. package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.d.ts +83 -0
  1009. package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.js +161 -0
  1010. package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.d.ts +16 -0
  1011. package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.js +90 -0
  1012. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +65 -0
  1013. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +357 -0
  1014. package/dist/sync/v3/workspaceSyncV3CombinedCoverage.d.ts +51 -0
  1015. package/dist/sync/v3/workspaceSyncV3CombinedCoverage.js +171 -0
  1016. package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.d.ts +43 -0
  1017. package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.js +541 -0
  1018. package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.d.ts +50 -0
  1019. package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +1161 -0
  1020. package/dist/sync/v3/workspaceSyncV3CombinedProjectionState.d.ts +96 -0
  1021. package/dist/sync/v3/workspaceSyncV3CombinedProjectionState.js +672 -0
  1022. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +46 -0
  1023. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +621 -0
  1024. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +66 -0
  1025. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +527 -0
  1026. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +78 -0
  1027. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +566 -0
  1028. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +45 -0
  1029. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +125 -0
  1030. package/dist/sync/v3/workspaceSyncV3CoverageRegistry.d.ts +13 -0
  1031. package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +34 -0
  1032. package/dist/sync/v3/workspaceSyncV3CursorEncoding.d.ts +1 -0
  1033. package/dist/sync/v3/workspaceSyncV3CursorEncoding.js +6 -0
  1034. package/dist/sync/v3/workspaceSyncV3DomainAdmission.d.ts +43 -0
  1035. package/dist/sync/v3/workspaceSyncV3DomainAdmission.js +118 -0
  1036. package/dist/sync/v3/workspaceSyncV3Feed.d.ts +95 -0
  1037. package/dist/sync/v3/workspaceSyncV3Feed.js +243 -0
  1038. package/dist/sync/v3/workspaceSyncV3FeedApply.d.ts +13 -0
  1039. package/dist/sync/v3/workspaceSyncV3FeedApply.js +67 -0
  1040. package/dist/sync/v3/workspaceSyncV3FeedClientContract.d.ts +3 -0
  1041. package/dist/sync/v3/workspaceSyncV3FeedClientContract.js +46 -0
  1042. package/dist/sync/v3/workspaceSyncV3FeedCursorKeys.d.ts +10 -0
  1043. package/dist/sync/v3/workspaceSyncV3FeedCursorKeys.js +58 -0
  1044. package/dist/sync/v3/workspaceSyncV3FeedOrchestrator.d.ts +31 -0
  1045. package/dist/sync/v3/workspaceSyncV3FeedOrchestrator.js +228 -0
  1046. package/dist/sync/v3/workspaceSyncV3FeedProfile.d.ts +32 -0
  1047. package/dist/sync/v3/workspaceSyncV3FeedProfile.js +21 -0
  1048. package/dist/sync/v3/workspaceSyncV3InitiativeLocalApply.d.ts +36 -0
  1049. package/dist/sync/v3/workspaceSyncV3InitiativeLocalApply.js +163 -0
  1050. package/dist/sync/v3/workspaceSyncV3InitiativeRepair.d.ts +33 -0
  1051. package/dist/sync/v3/workspaceSyncV3InitiativeRepair.js +118 -0
  1052. package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.d.ts +10 -0
  1053. package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.js +45 -0
  1054. package/dist/sync/v3/workspaceSyncV3LocalOutboxStatus.d.ts +27 -0
  1055. package/dist/sync/v3/workspaceSyncV3LocalOutboxStatus.js +83 -0
  1056. package/dist/sync/v3/workspaceSyncV3NestedCoverage.d.ts +10 -0
  1057. package/dist/sync/v3/workspaceSyncV3NestedCoverage.js +40 -0
  1058. package/dist/sync/v3/workspaceSyncV3NestedTaskApply.d.ts +83 -0
  1059. package/dist/sync/v3/workspaceSyncV3NestedTaskApply.js +325 -0
  1060. package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.d.ts +59 -0
  1061. package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.js +302 -0
  1062. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +47 -0
  1063. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +329 -0
  1064. package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.d.ts +19 -0
  1065. package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.js +41 -0
  1066. package/dist/sync/v3/workspaceSyncV3NestedWireContract.d.ts +6 -0
  1067. package/dist/sync/v3/workspaceSyncV3NestedWireContract.js +16 -0
  1068. package/dist/sync/v3/workspaceSyncV3OperationProjection.d.ts +8 -0
  1069. package/dist/sync/v3/workspaceSyncV3OperationProjection.js +52 -0
  1070. package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +230 -0
  1071. package/dist/sync/v3/workspaceSyncV3OperationProtocol.js +1 -0
  1072. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +165 -0
  1073. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +414 -0
  1074. package/dist/sync/v3/workspaceSyncV3OriginActor.d.ts +36 -0
  1075. package/dist/sync/v3/workspaceSyncV3OriginActor.js +61 -0
  1076. package/dist/sync/v3/workspaceSyncV3OriginAssertion.d.ts +46 -0
  1077. package/dist/sync/v3/workspaceSyncV3OriginAssertion.js +121 -0
  1078. package/dist/sync/v3/workspaceSyncV3OriginAssertionHeader.d.ts +1 -0
  1079. package/dist/sync/v3/workspaceSyncV3OriginAssertionHeader.js +1 -0
  1080. package/dist/sync/v3/workspaceSyncV3PlanningOrderCoverage.d.ts +10 -0
  1081. package/dist/sync/v3/workspaceSyncV3PlanningOrderCoverage.js +34 -0
  1082. package/dist/sync/v3/workspaceSyncV3PlanningOrderWireContract.d.ts +6 -0
  1083. package/dist/sync/v3/workspaceSyncV3PlanningOrderWireContract.js +10 -0
  1084. package/dist/sync/v3/workspaceSyncV3ProjectionState.d.ts +105 -0
  1085. package/dist/sync/v3/workspaceSyncV3ProjectionState.js +467 -0
  1086. package/dist/sync/v3/workspaceSyncV3RepairSqlBatching.d.ts +2 -0
  1087. package/dist/sync/v3/workspaceSyncV3RepairSqlBatching.js +10 -0
  1088. package/dist/sync/v3/workspaceSyncV3TaskCommentAudit.d.ts +56 -0
  1089. package/dist/sync/v3/workspaceSyncV3TaskCommentAudit.js +250 -0
  1090. package/dist/sync/v3/workspaceSyncV3TaskRelationshipProjection.d.ts +30 -0
  1091. package/dist/sync/v3/workspaceSyncV3TaskRelationshipProjection.js +142 -0
  1092. package/dist/sync/v3/workspaceSyncV3TaskRootProjection.d.ts +40 -0
  1093. package/dist/sync/v3/workspaceSyncV3TaskRootProjection.js +246 -0
  1094. package/dist/sync/v3/workspaceSyncV3TaxonomyFeedProjection.d.ts +39 -0
  1095. package/dist/sync/v3/workspaceSyncV3TaxonomyFeedProjection.js +185 -0
  1096. package/dist/sync/v3/workspaceSyncV3WorkflowCoverage.d.ts +10 -0
  1097. package/dist/sync/v3/workspaceSyncV3WorkflowCoverage.js +36 -0
  1098. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.d.ts +17 -0
  1099. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.js +143 -0
  1100. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeProjection.d.ts +9 -0
  1101. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeProjection.js +195 -0
  1102. package/dist/sync/v3/workspaceSyncV3WorkflowWireContract.d.ts +11 -0
  1103. package/dist/sync/v3/workspaceSyncV3WorkflowWireContract.js +12 -0
  1104. package/dist/sync/v3/workspaceSyncV3WorkstreamProjection.d.ts +4 -0
  1105. package/dist/sync/v3/workspaceSyncV3WorkstreamProjection.js +98 -0
  1106. package/dist/sync/v3/workspaceSyncV3WorkstreamTaskOrderProjection.d.ts +9 -0
  1107. package/dist/sync/v3/workspaceSyncV3WorkstreamTaskOrderProjection.js +72 -0
  1108. package/dist/sync/v3/workstreamActivityAuthoritativeRevision.d.ts +11 -0
  1109. package/dist/sync/v3/workstreamActivityAuthoritativeRevision.js +23 -0
  1110. package/dist/sync/v3/workstreamActivityIdentity.d.ts +8 -0
  1111. package/dist/sync/v3/workstreamActivityIdentity.js +14 -0
  1112. package/dist/sync/v3/workstreamCoexistence.d.ts +19 -0
  1113. package/dist/sync/v3/workstreamCoexistence.js +64 -0
  1114. package/dist/sync/v3/workstreamMutationPayload.d.ts +27 -0
  1115. package/dist/sync/v3/workstreamMutationPayload.js +147 -0
  1116. package/dist/sync/v3/workstreamMutationService.d.ts +72 -0
  1117. package/dist/sync/v3/workstreamMutationService.js +256 -0
  1118. package/dist/sync/v3/workstreamTaskOrderMutationService.d.ts +55 -0
  1119. package/dist/sync/v3/workstreamTaskOrderMutationService.js +110 -0
  1120. package/dist/sync/v3/workstreamTaskOrderSync.d.ts +14 -0
  1121. package/dist/sync/v3/workstreamTaskOrderSync.js +25 -0
  1122. package/dist/sync/workspaceContentManifest.d.ts +86 -0
  1123. package/dist/sync/workspaceContentManifest.js +123 -0
  1124. package/dist/sync/workspacePullFeed.d.ts +191 -2
  1125. package/dist/sync/workspacePullFeed.js +523 -135
  1126. package/dist/sync/workspacePushPreparedPlan.d.ts +21 -0
  1127. package/dist/sync/workspacePushPreparedPlan.js +1 -0
  1128. package/dist/sync/workspaceRepair.d.ts +17 -25
  1129. package/dist/sync/workspaceRepair.js +348 -25
  1130. package/dist/sync/workspaceSyncContentDecryption.d.ts +6 -0
  1131. package/dist/sync/workspaceSyncContentDecryption.js +11 -0
  1132. package/dist/sync/workspaceSyncModel.d.ts +227 -5
  1133. package/dist/sync/workspaceSyncModel.js +398 -37
  1134. package/dist/sync/workspaceSyncSnapshotProjection.d.ts +11 -0
  1135. package/dist/sync/workspaceSyncSnapshotProjection.js +101 -0
  1136. package/dist/sync/workspaceSyncState.d.ts +13 -0
  1137. package/dist/sync/workspaceSyncState.js +36 -0
  1138. package/dist/sync/workspaceSyncV2SnapshotBuilder.d.ts +106 -0
  1139. package/dist/sync/workspaceSyncV2SnapshotBuilder.js +193 -0
  1140. package/dist/types.d.ts +31 -15
  1141. package/dist/types.js +1 -3
  1142. package/dist/ui/ai-profile-clients/amazon-nova.svg +1 -0
  1143. package/dist/ui/ai-profile-clients/antigravity.png +0 -0
  1144. package/dist/ui/ai-profile-clients/chatgpt.svg +10 -0
  1145. package/dist/ui/ai-profile-clients/claude-chat.svg +1 -0
  1146. package/dist/ui/ai-profile-clients/claude-code.svg +15 -0
  1147. package/dist/ui/ai-profile-clients/cline-app-icon-light.png +0 -0
  1148. package/dist/ui/ai-profile-clients/cline.svg +16 -0
  1149. package/dist/ui/ai-profile-clients/codex.svg +1 -0
  1150. package/dist/ui/ai-profile-clients/copilot.png +0 -0
  1151. package/dist/ui/ai-profile-clients/cursor.svg +1 -0
  1152. package/dist/ui/ai-profile-clients/deepseek.svg +1 -0
  1153. package/dist/ui/ai-profile-clients/gemini-cli-icon.png +0 -0
  1154. package/dist/ui/ai-profile-clients/gemini.svg +10 -0
  1155. package/dist/ui/ai-profile-clients/grok.svg +31 -0
  1156. package/dist/ui/ai-profile-clients/kiro.svg +11 -0
  1157. package/dist/ui/ai-profile-clients/llama.svg +1 -0
  1158. package/dist/ui/ai-profile-clients/mistral.svg +1 -0
  1159. package/dist/ui/ai-profile-clients/ms_copilot.jpeg +0 -0
  1160. package/dist/ui/ai-profile-clients/openclaw.png +0 -0
  1161. package/dist/ui/ai-profile-clients/perplexity.svg +1 -0
  1162. package/dist/ui/ai-profile-clients/vscode.svg +41 -0
  1163. package/dist/ui/ai-profile-clients/windsurf.svg +11 -0
  1164. package/dist/ui/assets/AiIdentityRosterCard-MZs7lVED.js +1 -0
  1165. package/dist/ui/assets/AiProfilesModule-C3i0LOxe.js +1 -0
  1166. package/dist/ui/assets/AnnotatedAttachmentWorkspace-CBRZ8rca.css +1 -0
  1167. package/dist/ui/assets/AnnotatedAttachmentWorkspace-DVZk5Tln.js +3 -0
  1168. package/dist/ui/assets/AssetTraySortControl-B9k5caQW.css +1 -0
  1169. package/dist/ui/assets/AssetTraySortControl-Kf1pelSy.js +1 -0
  1170. package/dist/ui/assets/ContextAttachmentManager-B8boOs6Q.js +3 -0
  1171. package/dist/ui/assets/DocumentWorkspace-BIBGBfd7.css +1 -0
  1172. package/dist/ui/assets/DocumentWorkspace-DXH4XUsB.js +261 -0
  1173. package/dist/ui/assets/EntityActivityTimeline-BfJbZRdl.css +1 -0
  1174. package/dist/ui/assets/EntityActivityTimeline-BtSTq0ON.js +1 -0
  1175. package/dist/ui/assets/PlanningModule-BPVyEa-f.js +1 -0
  1176. package/dist/ui/assets/PlanningModule-CoIR9hbV.css +1 -0
  1177. package/dist/ui/assets/PlansPage-C2nkK2Bp.css +1 -0
  1178. package/dist/ui/assets/PlansPage-ChqgxALc.js +1 -0
  1179. package/dist/ui/assets/TaskContextUpload-CB3ol0sN.js +1 -0
  1180. package/dist/ui/assets/TaskContextUpload-qmBeUw3u.css +1 -0
  1181. package/dist/ui/assets/TaskSettings-g4ECKNOz.js +12 -0
  1182. package/dist/ui/assets/TaskforceAgentsModule-BazdUwxZ.js +21 -0
  1183. package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +1 -0
  1184. package/dist/ui/assets/WorkflowManagerModule-DF10XENz.css +1 -0
  1185. package/dist/ui/assets/WorkflowManagerModule-DWFspC-o.js +1 -0
  1186. package/dist/ui/assets/antigravity-DRKQga2U.png +0 -0
  1187. package/dist/ui/assets/cursor-BM_3k4Y4.svg +1 -0
  1188. package/dist/ui/assets/gemini-cli-icon-dBAVjCcn.png +0 -0
  1189. package/dist/ui/assets/grok-BuodbWaG.svg +31 -0
  1190. package/dist/ui/assets/index-BUplSsv_.js +7 -0
  1191. package/dist/ui/assets/index-gz2EXuoK.css +1 -0
  1192. package/dist/ui/assets/{vendor-dnd-DRzYolkg.js → vendor-dnd-CJ-AjP-Y.js} +1 -1
  1193. package/dist/ui/assets/{vendor-icons-CLnehDTw.js → vendor-icons-BkFLXavV.js} +1 -1
  1194. package/dist/ui/assets/{vendor-markdown-BUxTU7dS.js → vendor-markdown-_lhNCyq-.js} +9 -9
  1195. package/dist/ui/assets/vendor-router-AqJMU8Lz.js +3 -0
  1196. package/dist/ui/assets/vscode-C_7wk1WI.svg +41 -0
  1197. package/dist/ui/branding/logos/logo_dark_bg.png +0 -0
  1198. package/dist/ui/branding/logos/logo_favicon_dark.png +0 -0
  1199. package/dist/ui/branding/logos/logo_favicon_dark.svg +56 -0
  1200. package/dist/ui/branding/logos/logo_favicon_light.png +0 -0
  1201. package/dist/ui/branding/logos/logo_light_bg.png +0 -0
  1202. package/dist/ui/images/Taskforce_Van.webp +0 -0
  1203. package/dist/ui/index.html +6 -6
  1204. package/dist/update/uiUpdateService.d.ts +43 -0
  1205. package/dist/update/uiUpdateService.js +149 -0
  1206. package/dist/update/updateCli.d.ts +15 -0
  1207. package/dist/update/updateCli.js +76 -0
  1208. package/dist/update/updateExecutor.d.ts +40 -0
  1209. package/dist/update/updateExecutor.js +474 -0
  1210. package/dist/update/updateStatus.d.ts +83 -0
  1211. package/dist/update/updateStatus.js +703 -0
  1212. package/dist/utils/aiProfileAvatarPaths.d.ts +14 -0
  1213. package/dist/utils/aiProfileAvatarPaths.js +52 -0
  1214. package/dist/utils/aiProfileDefaultLogo.d.ts +7 -0
  1215. package/dist/utils/aiProfileDefaultLogo.js +84 -0
  1216. package/dist/utils/aiProfileEvents.d.ts +9 -1
  1217. package/dist/utils/annotatedAttachments.d.ts +8 -0
  1218. package/dist/utils/annotatedAttachments.js +17 -1
  1219. package/dist/utils/assetTraySorting.d.ts +25 -0
  1220. package/dist/utils/assetTraySorting.js +83 -0
  1221. package/dist/utils/assignees.d.ts +5 -0
  1222. package/dist/utils/assignees.js +14 -9
  1223. package/dist/utils/authLogin.d.ts +10 -0
  1224. package/dist/utils/authLogin.js +8 -0
  1225. package/dist/utils/authSessionEvents.d.ts +2 -0
  1226. package/dist/utils/authSessionEvents.js +6 -0
  1227. package/dist/utils/avatarUpload.js +5 -5
  1228. package/dist/utils/canonicalReferenceAttachments.d.ts +12 -0
  1229. package/dist/utils/canonicalReferenceAttachments.js +42 -0
  1230. package/dist/utils/cloudAssetDisplay.d.ts +2 -0
  1231. package/dist/utils/cloudAssetDisplay.js +8 -0
  1232. package/dist/utils/constants.d.ts +4 -11
  1233. package/dist/utils/constants.js +6 -65
  1234. package/dist/utils/contextAttachmentPreview.d.ts +11 -0
  1235. package/dist/utils/contextAttachmentPreview.js +8 -0
  1236. package/dist/utils/contextAttachmentUpload.d.ts +10 -0
  1237. package/dist/utils/contextAttachmentUpload.js +151 -0
  1238. package/dist/utils/contextFiles.d.ts +1 -1
  1239. package/dist/utils/contextFiles.js +4 -4
  1240. package/dist/utils/documentNames.js +6 -4
  1241. package/dist/utils/entityReferences.d.ts +14 -0
  1242. package/dist/utils/entityReferences.js +21 -0
  1243. package/dist/utils/httpSetCookie.d.ts +3 -0
  1244. package/dist/utils/httpSetCookie.js +22 -0
  1245. package/dist/utils/imageNoteStoragePaths.d.ts +3 -0
  1246. package/dist/utils/imageNoteStoragePaths.js +19 -0
  1247. package/dist/utils/imageReferences.d.ts +6 -0
  1248. package/dist/utils/imageReferences.js +1 -0
  1249. package/dist/utils/planningArchiveOrchestrator.d.ts +23 -0
  1250. package/dist/utils/planningArchiveOrchestrator.js +37 -0
  1251. package/dist/utils/planningArchivePresentation.d.ts +20 -0
  1252. package/dist/utils/planningArchivePresentation.js +23 -0
  1253. package/dist/utils/planningArchiveReadiness.d.ts +26 -0
  1254. package/dist/utils/planningArchiveReadiness.js +30 -0
  1255. package/dist/utils/planningFavorites.d.ts +7 -0
  1256. package/dist/utils/planningFavorites.js +34 -0
  1257. package/dist/utils/syncEventPresentation.js +53 -0
  1258. package/dist/utils/syncStatusPresentation.d.ts +25 -0
  1259. package/dist/utils/syncStatusPresentation.js +86 -5
  1260. package/dist/utils/taskActivity.d.ts +9 -2
  1261. package/dist/utils/taskActivity.js +61 -0
  1262. package/dist/utils/taskDraftDefaults.d.ts +0 -8
  1263. package/dist/utils/taskDraftDefaults.js +0 -4
  1264. package/dist/utils/taskEvents.d.ts +11 -0
  1265. package/dist/utils/taskEvents.js +6 -0
  1266. package/dist/utils/taskHeaderQuickFilter.d.ts +14 -0
  1267. package/dist/utils/taskHeaderQuickFilter.js +32 -0
  1268. package/dist/utils/taskInvalidation.d.ts +23 -0
  1269. package/dist/utils/taskInvalidation.js +67 -0
  1270. package/dist/utils/taskNormalization.d.ts +2 -1
  1271. package/dist/utils/taskNormalization.js +44 -18
  1272. package/dist/utils/taskReferences.d.ts +16 -0
  1273. package/dist/utils/taskReferences.js +63 -0
  1274. package/dist/utils/taskforceAgentEvents.d.ts +8 -0
  1275. package/dist/utils/taskforceAgentEvents.js +6 -0
  1276. package/dist/utils/taskforceAgentSkillEvents.d.ts +7 -0
  1277. package/dist/utils/taskforceAgentSkillEvents.js +8 -0
  1278. package/dist/utils/uiNotice.d.ts +3 -0
  1279. package/dist/utils/uiNotice.js +1 -1
  1280. package/dist/utils/workspaceResourceEvents.d.ts +7 -0
  1281. package/dist/utils/workspaceResourceEvents.js +6 -0
  1282. package/dist/utils/workspaceSyncPresentation.d.ts +24 -0
  1283. package/dist/utils/workspaceSyncPresentation.js +243 -6
  1284. package/package.json +74 -21
  1285. package/dist/components/features/AgentsModule.d.ts +0 -18
  1286. package/dist/components/features/AgentsModule.js +0 -479
  1287. package/dist/components/features/InitiativesModule.d.ts +0 -22
  1288. package/dist/components/features/InitiativesModule.js +0 -33
  1289. package/dist/components/features/WorkflowsModule.d.ts +0 -27
  1290. package/dist/components/features/WorkflowsModule.js +0 -21
  1291. package/dist/components/features/settings/WorkflowEditor.d.ts +0 -15
  1292. package/dist/components/features/settings/WorkflowEditor.js +0 -245
  1293. package/dist/components/views/panels/DocumentFilterToolbar.d.ts +0 -10
  1294. package/dist/components/views/panels/DocumentFilterToolbar.js +0 -7
  1295. package/dist/components/views/standalone/modals/AccountHubModal.d.ts +0 -61
  1296. package/dist/components/views/standalone/modals/AccountHubModal.js +0 -108
  1297. package/dist/components/views/standalone/modals/EditProfileModal.d.ts +0 -19
  1298. package/dist/components/views/standalone/modals/EditProfileModal.js +0 -11
  1299. package/dist/hooks/ui/useResourceExport.d.ts +0 -21
  1300. package/dist/hooks/ui/useResourceExport.js +0 -87
  1301. package/dist/hooks/ui/useWorkflowTemplates.d.ts +0 -37
  1302. package/dist/hooks/ui/useWorkflowTemplates.js +0 -116
  1303. package/dist/mcp/clientProfileDefaults.d.ts +0 -12
  1304. package/dist/mcp/clientProfileDefaults.js +0 -41
  1305. package/dist/resources/templates/WORKFLOW_V2_POLICY.md +0 -55
  1306. package/dist/resources/templates/environments/aider.yaml +0 -14
  1307. package/dist/resources/templates/environments/antigravity.yaml +0 -10
  1308. package/dist/resources/templates/environments/claude.yaml +0 -10
  1309. package/dist/resources/templates/environments/cline.yaml +0 -10
  1310. package/dist/resources/templates/environments/codex.yaml +0 -13
  1311. package/dist/resources/templates/environments/copilot.yaml +0 -10
  1312. package/dist/resources/templates/environments/cursor.yaml +0 -9
  1313. package/dist/resources/templates/environments/gemini.yaml +0 -9
  1314. package/dist/resources/templates/environments/windsurf.yaml +0 -10
  1315. package/dist/resources/templates/workflow-sources/README.md +0 -9
  1316. package/dist/resources/templates/workflow-sources/workflowDocs.mjs +0 -530
  1317. package/dist/resources/templates/workflow-sources/workflowEditorOverrides.json +0 -1
  1318. package/dist/resources/templates/workflows/collaborate.yaml +0 -109
  1319. package/dist/resources/templates/workflows/do.yaml +0 -87
  1320. package/dist/resources/templates/workflows/evaluate.yaml +0 -116
  1321. package/dist/resources/templates/workflows/execute.yaml +0 -156
  1322. package/dist/resources/templates/workflows/plan.yaml +0 -118
  1323. package/dist/resources/templates/workflows/review.yaml +0 -114
  1324. package/dist/services/formatTransformers.d.ts +0 -29
  1325. package/dist/services/formatTransformers.js +0 -56
  1326. package/dist/services/templateEngine.d.ts +0 -46
  1327. package/dist/services/templateEngine.js +0 -148
  1328. package/dist/shared/workflowDefaults.d.ts +0 -9
  1329. package/dist/shared/workflowDefaults.js +0 -11
  1330. package/dist/ui/agent-logos/Gemini CLI.jpeg +0 -0
  1331. package/dist/ui/agent-logos/antigravity.jpeg +0 -0
  1332. package/dist/ui/agent-logos/chatgpt.png +0 -0
  1333. package/dist/ui/agent-logos/claude-code.jpeg +0 -0
  1334. package/dist/ui/agent-logos/codex.jpeg +0 -0
  1335. package/dist/ui/agent-logos/cursor.png +0 -0
  1336. package/dist/ui/agent-logos/openclaw.jpeg +0 -0
  1337. package/dist/ui/agent-logos/windsurf.png +0 -0
  1338. package/dist/ui/assets/AgentsModule-C4LcqhcZ.js +0 -1
  1339. package/dist/ui/assets/AnnotatedAttachmentWorkspace-B-Dq22d2.js +0 -3
  1340. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BVKew-mH.css +0 -1
  1341. package/dist/ui/assets/ContextAttachmentManager-DsXPTvi-.js +0 -3
  1342. package/dist/ui/assets/DocumentWorkspace-CxA1wO3U.js +0 -252
  1343. package/dist/ui/assets/DocumentWorkspace-D4rJKXzd.css +0 -1
  1344. package/dist/ui/assets/EntityActivityTimeline-B8nSe8l3.js +0 -1
  1345. package/dist/ui/assets/EntityActivityTimeline-DyqvvhuF.css +0 -1
  1346. package/dist/ui/assets/InitiativesModule-VY95v38E.js +0 -1
  1347. package/dist/ui/assets/PlansPage-CQbKDv1a.js +0 -1
  1348. package/dist/ui/assets/PlansPage-DeAzWYTb.css +0 -1
  1349. package/dist/ui/assets/TaskContextUpload-DvDlNpHC.js +0 -1
  1350. package/dist/ui/assets/TaskSettings-CUWbYYtP.js +0 -12
  1351. package/dist/ui/assets/WorkflowsModule-CgM3Jako.js +0 -5
  1352. package/dist/ui/assets/documentReferences-Do9YjrS3.js +0 -1
  1353. package/dist/ui/assets/index--mh3pktj.js +0 -5
  1354. package/dist/ui/assets/index-BawaaEXS.css +0 -1
  1355. package/dist/ui/assets/vendor-router-BbWMxlnO.js +0 -3
  1356. package/dist/ui/branding/logos/logo_black_01.png +0 -0
  1357. package/dist/ui/branding/logos/logo_black_02.png +0 -0
  1358. package/dist/ui/branding/logos/logo_white_01.png +0 -0
  1359. package/dist/ui/branding/logos/logo_white_02.png +0 -0
  1360. package/scripts/generate-workflow-templates.mjs +0 -134
  1361. package/src/resources/templates/WORKFLOW_V2_POLICY.md +0 -55
  1362. package/src/resources/templates/environments/aider.yaml +0 -14
  1363. package/src/resources/templates/environments/antigravity.yaml +0 -10
  1364. package/src/resources/templates/environments/claude.yaml +0 -10
  1365. package/src/resources/templates/environments/cline.yaml +0 -10
  1366. package/src/resources/templates/environments/codex.yaml +0 -13
  1367. package/src/resources/templates/environments/copilot.yaml +0 -10
  1368. package/src/resources/templates/environments/cursor.yaml +0 -9
  1369. package/src/resources/templates/environments/gemini.yaml +0 -9
  1370. package/src/resources/templates/environments/windsurf.yaml +0 -10
  1371. package/src/resources/templates/workflow-sources/README.md +0 -9
  1372. package/src/resources/templates/workflow-sources/workflowDocs.mjs +0 -530
  1373. package/src/resources/templates/workflow-sources/workflowEditorOverrides.json +0 -1
  1374. package/src/resources/templates/workflows/collaborate.yaml +0 -109
  1375. package/src/resources/templates/workflows/do.yaml +0 -87
  1376. package/src/resources/templates/workflows/evaluate.yaml +0 -116
  1377. package/src/resources/templates/workflows/execute.yaml +0 -156
  1378. package/src/resources/templates/workflows/plan.yaml +0 -118
  1379. package/src/resources/templates/workflows/review.yaml +0 -114
  1380. /package/dist/ui/branding/logos/{logo_dark.svg → logo_dark_no_bg.svg} +0 -0
  1381. /package/dist/ui/branding/logos/{logo_favicon.svg → logo_favicon_light.svg} +0 -0
  1382. /package/dist/ui/branding/logos/{logo_light.svg → logo_light_no_bg.svg} +0 -0
@@ -1,20 +1,17 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import React, { useState, useEffect, useCallback, useRef } from 'react';
3
- import Markdown from 'react-markdown';
4
3
  import { renderToStaticMarkup } from 'react-dom/server';
5
- import remarkGfm from 'remark-gfm';
6
- import rehypeSanitize from 'rehype-sanitize';
7
- import { Printer, Link, Download, Clock, HardDrive, Tag, Pencil, X, Save, Eye, SplitSquareHorizontal, CheckCircle, AlertCircle, Zap, Trash2, MessageSquareText, Send, Bot, User, RotateCcw, CheckCheck, ArrowLeft } from 'lucide-react';
4
+ import { Printer, Link, Download, Clock, HardDrive, Tag, Pencil, X, Save, Eye, SplitSquareHorizontal, CheckCircle, AlertCircle, Zap, Trash2, MessageSquareText, Send, Bot, User, RotateCcw, ArrowLeft, ArrowDown, Reply, Plus } from 'lucide-react';
8
5
  import styles from '../../Taskforce.module.css';
9
6
  import viewerStyles from './DocumentViewer.module.css';
10
- import taskFormStyles from '../task/TaskForm.module.css';
11
7
  import { Modal } from '../ui/Modal';
12
- import { getEffectiveAttachmentState } from './documentWorkspaceModel';
8
+ import { getEffectiveAttachmentState, withWorkspaceQuery } from './documentWorkspaceModel';
13
9
  import { DocumentGenerateModal } from './DocumentGenerateModal';
14
10
  import { fetchTaskforceApi, resolveTaskforceApiUrl } from '../../utils/taskforceApiClient';
15
11
  import { getDocumentDownloadName, getReadableDocumentName } from '../../utils/documentNames';
16
12
  import { getDocumentReferenceLabel } from '../../utils/documentReferences';
17
13
  import { ReferenceBadgeButton } from '../ui/ReferenceBadgeButton';
14
+ import { Markdown } from '../ui/Markdown';
18
15
  const DOC_TYPE_LABELS = {
19
16
  'implementation-plan': 'Implementation Plan',
20
17
  'review': 'Review',
@@ -35,6 +32,10 @@ const EDITOR_LAYOUT_CLASS = {
35
32
  preview: viewerStyles.editorLayoutPreview,
36
33
  };
37
34
  const PRINT_FRAME_CLEANUP_DELAY_MS = 1500;
35
+ const REVIEW_BOTTOM_THRESHOLD_PX = 80;
36
+ const DOCUMENT_REFRESH_ERROR = 'Document refresh failed; showing the previous saved version.';
37
+ const DOCUMENT_REVISION_CONFLICT_ERROR = 'A newer saved version is available. Cancel editing to reload it before saving.';
38
+ const UNSAVED_REVIEW_SESSION_KEY = '__new-review__';
38
39
  const PRINT_DOCUMENT_CSS = `
39
40
  @page {
40
41
  margin: 0.94in 1.02in 1in;
@@ -149,6 +150,14 @@ body {
149
150
  padding-left: 0.1em;
150
151
  }
151
152
 
153
+ .tf-print-document [data-task-list="true"] {
154
+ padding-left: 1.1em;
155
+ }
156
+
157
+ .tf-print-document [data-task-item="true"] {
158
+ list-style: none;
159
+ }
160
+
152
161
  .tf-print-document li > ul,
153
162
  .tf-print-document li > ol {
154
163
  margin-top: 0.34em;
@@ -319,33 +328,38 @@ function createPrintMarkdownComponents() {
319
328
  if (childArray.length !== 1)
320
329
  return null;
321
330
  const onlyChild = childArray[0];
322
- if (!React.isValidElement(onlyChild) || onlyChild.type !== 'strong')
331
+ if (!React.isValidElement(onlyChild))
323
332
  return null;
324
333
  const onlyChildProps = onlyChild.props;
334
+ const elementType = typeof onlyChild.type === 'string'
335
+ ? onlyChild.type
336
+ : onlyChildProps.node?.tagName;
337
+ if (elementType !== 'strong')
338
+ return null;
325
339
  const text = React.Children.toArray(onlyChildProps.children).join('').trim();
326
340
  if (!text)
327
341
  return null;
328
342
  return text;
329
343
  };
330
344
  return {
331
- input({ type, checked, ...props }) {
345
+ input({ type, checked, node: _node, ...props }) {
332
346
  if (type !== 'checkbox')
333
347
  return _jsx("input", { type: type, checked: checked, ...props });
334
348
  return (_jsx("input", { ...props, type: "checkbox", checked: Boolean(checked), disabled: true, readOnly: true }));
335
349
  },
336
350
  ul({ children, node, ...props }) {
337
351
  const taskList = nodeHasTaskItems(node);
338
- return (_jsx("ul", { ...props, style: taskList ? { paddingLeft: '1.2em' } : undefined, children: children }));
352
+ return (_jsx("ul", { ...props, "data-task-list": taskList ? 'true' : undefined, children: children }));
339
353
  },
340
354
  ol({ children, node, ...props }) {
341
355
  const taskList = nodeHasTaskItems(node);
342
- return (_jsx("ol", { ...props, style: taskList ? { paddingLeft: '1.2em' } : undefined, children: children }));
356
+ return (_jsx("ol", { ...props, "data-task-list": taskList ? 'true' : undefined, children: children }));
343
357
  },
344
358
  li({ children, node, ...props }) {
345
359
  const taskItem = typeof node?.checked === 'boolean' || nodeHasCheckboxInput(node);
346
- return (_jsx("li", { ...props, style: taskItem ? { listStyleType: 'none', listStyle: 'none', marginLeft: 0 } : undefined, children: children }));
360
+ return (_jsx("li", { ...props, "data-task-item": taskItem ? 'true' : undefined, children: children }));
347
361
  },
348
- p({ children, ...props }) {
362
+ p({ children, node: _node, ...props }) {
349
363
  const sectionLabel = isStandaloneStrongParagraph(children);
350
364
  if (sectionLabel) {
351
365
  return (_jsx("p", { ...props, className: "tf-print-section-label", children: sectionLabel }));
@@ -355,7 +369,7 @@ function createPrintMarkdownComponents() {
355
369
  };
356
370
  }
357
371
  export function buildPrintDocumentHtml(markdown) {
358
- const bodyHtml = renderToStaticMarkup(_jsx("div", { className: "tf-print-document", children: _jsx(Markdown, { remarkPlugins: [remarkGfm], rehypePlugins: [rehypeSanitize], components: createPrintMarkdownComponents(), children: markdown }) }));
372
+ const bodyHtml = renderToStaticMarkup(_jsx("div", { className: "tf-print-document", children: _jsx(Markdown, { variant: "document", documentOverrides: createPrintMarkdownComponents(), children: markdown }) }));
359
373
  return `<!doctype html>
360
374
  <html lang="en">
361
375
  <head>
@@ -400,9 +414,14 @@ function formatReviewAnchor(anchor) {
400
414
  if (!anchor)
401
415
  return null;
402
416
  if (anchor.kind === 'document')
403
- return 'Entire document';
404
- if (anchor.kind === 'quote')
405
- return anchor.quote ? `Quote: "${anchor.quote}"` : 'Quoted text';
417
+ return 'Whole document';
418
+ if (anchor.kind === 'quote') {
419
+ const quote = anchor.quote?.replace(/\s+/g, ' ').trim() || '';
420
+ if (!quote)
421
+ return 'Selected text';
422
+ const excerpt = quote.length > 72 ? `${quote.slice(0, 69).trimEnd()}…` : quote;
423
+ return `Selected: “${excerpt}”`;
424
+ }
406
425
  if (anchor.kind === 'line-range') {
407
426
  if (anchor.startLine === anchor.endLine)
408
427
  return `Line ${anchor.startLine}`;
@@ -422,6 +441,62 @@ function getReviewActorLabel(comment) {
422
441
  function normalizeAnchorText(text) {
423
442
  return text.replace(/\s+/g, ' ').trim();
424
443
  }
444
+ export function getReviewAnchorHealth(anchor, savedContent, savedRenderedText = savedContent) {
445
+ if (!anchor)
446
+ return 'unknown';
447
+ if (anchor.kind === 'document')
448
+ return 'valid';
449
+ if (savedContent === null)
450
+ return 'unknown';
451
+ if (anchor.kind === 'line-range') {
452
+ const lineCount = savedContent.split('\n').length;
453
+ return anchor.startLine >= 1
454
+ && anchor.endLine >= anchor.startLine
455
+ && anchor.endLine <= lineCount
456
+ ? 'valid'
457
+ : 'unresolved';
458
+ }
459
+ const quote = normalizeAnchorText(anchor.quote || '');
460
+ if (!quote)
461
+ return 'unknown';
462
+ if (savedRenderedText === null)
463
+ return 'unknown';
464
+ const normalizedContent = normalizeAnchorText(savedRenderedText);
465
+ const positions = [];
466
+ let searchFrom = 0;
467
+ while (searchFrom <= normalizedContent.length - quote.length) {
468
+ const index = normalizedContent.indexOf(quote, searchFrom);
469
+ if (index < 0)
470
+ break;
471
+ positions.push(index);
472
+ searchFrom = index + quote.length;
473
+ }
474
+ if (positions.length === 0)
475
+ return 'unresolved';
476
+ const hasOccurrenceIndex = typeof anchor.occurrenceIndex === 'number'
477
+ && Number.isInteger(anchor.occurrenceIndex)
478
+ && anchor.occurrenceIndex >= 0;
479
+ const prefix = normalizeAnchorText(anchor.prefix || '');
480
+ const suffix = normalizeAnchorText(anchor.suffix || '');
481
+ const contextMatches = (position) => {
482
+ const before = normalizedContent.slice(0, position).trimEnd();
483
+ const after = normalizedContent.slice(position + quote.length).trimStart();
484
+ return (!prefix || before.endsWith(prefix)) && (!suffix || after.startsWith(suffix));
485
+ };
486
+ if (hasOccurrenceIndex) {
487
+ const expectedPosition = positions[anchor.occurrenceIndex];
488
+ if (expectedPosition === undefined)
489
+ return 'moved';
490
+ return contextMatches(expectedPosition) ? 'valid' : 'moved';
491
+ }
492
+ if (!prefix && !suffix) {
493
+ return positions.length === 1 ? 'valid' : 'unknown';
494
+ }
495
+ const matchingPositions = positions.filter(contextMatches);
496
+ if (matchingPositions.length === 1)
497
+ return 'valid';
498
+ return matchingPositions.length === 0 ? 'moved' : 'unknown';
499
+ }
425
500
  function countOccurrences(haystack, needle) {
426
501
  if (!needle)
427
502
  return 0;
@@ -501,13 +576,17 @@ function toggleNthTaskCheckbox(markdown, targetIndex, nextChecked) {
501
576
  });
502
577
  return updated.join('\n');
503
578
  }
504
- export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', onSaved, onDeleted, onBackToTask, enableTaskGeneration = false }) {
579
+ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', workspaceId = null, onSaved, onDeleted, onBackToTask, taskReferences, enableTaskGeneration = false, initialScrollTop = 0, onScrollTopChange, }) {
505
580
  const fallbackReadableName = getReadableDocumentName(doc);
506
581
  const [currentDocumentName, setCurrentDocumentName] = useState(fallbackReadableName);
507
582
  const readableName = currentDocumentName;
508
- const downloadName = getDocumentDownloadName({ ...doc, displayName: currentDocumentName });
583
+ const downloadName = getDocumentDownloadName({ ...doc, title: currentDocumentName });
509
584
  const documentReferenceLabel = getDocumentReferenceLabel(doc);
510
585
  const [content, setContent] = useState(null);
586
+ const contentRef = useRef(null);
587
+ contentRef.current = content;
588
+ const [savedRenderedText, setSavedRenderedText] = useState(null);
589
+ const [currentDocumentVersion, setCurrentDocumentVersion] = useState(null);
511
590
  const [loadingContent, setLoadingContent] = useState(false);
512
591
  const [loadError, setLoadError] = useState(null);
513
592
  const [copied, setCopied] = useState(false);
@@ -516,19 +595,53 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
516
595
  const [loadingReviews, setLoadingReviews] = useState(false);
517
596
  const [reviewError, setReviewError] = useState(null);
518
597
  const [selectedReviewSessionId, setSelectedReviewSessionId] = useState(null);
519
- const [reviewDraft, setReviewDraft] = useState('');
598
+ const [reviewComposerDrafts, setReviewComposerDrafts] = useState({});
520
599
  const [reviewBusy, setReviewBusy] = useState(false);
521
- const [pendingReviewAnchor, setPendingReviewAnchor] = useState(null);
600
+ const [hasNewReviewComments, setHasNewReviewComments] = useState(false);
522
601
  const [editingReviewTitle, setEditingReviewTitle] = useState(false);
523
602
  const [reviewTitleDraft, setReviewTitleDraft] = useState('');
524
603
  const [editingCommentId, setEditingCommentId] = useState(null);
525
604
  const [editingCommentDraft, setEditingCommentDraft] = useState('');
605
+ const [replyingToCommentId, setReplyingToCommentId] = useState(null);
606
+ const [replyDraft, setReplyDraft] = useState('');
526
607
  const [showReviewSidebar, setShowReviewSidebar] = useState(true);
608
+ const [compactReviewViewport, setCompactReviewViewport] = useState(false);
609
+ const selectedReviewSessionIdRef = useRef(null);
610
+ const reviewDraftKey = selectedReviewSessionId || UNSAVED_REVIEW_SESSION_KEY;
611
+ const reviewDraft = reviewComposerDrafts[reviewDraftKey]?.body || '';
612
+ const pendingReviewAnchor = reviewComposerDrafts[reviewDraftKey]?.anchor || null;
613
+ const setReviewDraft = useCallback((body) => {
614
+ setReviewComposerDrafts((current) => {
615
+ const draftKey = selectedReviewSessionIdRef.current || UNSAVED_REVIEW_SESSION_KEY;
616
+ return {
617
+ ...current,
618
+ [draftKey]: {
619
+ body,
620
+ anchor: current[draftKey]?.anchor || null,
621
+ },
622
+ };
623
+ });
624
+ }, []);
625
+ const setPendingReviewAnchor = useCallback((anchor) => {
626
+ setReviewComposerDrafts((current) => {
627
+ const draftKey = selectedReviewSessionIdRef.current || UNSAVED_REVIEW_SESSION_KEY;
628
+ return {
629
+ ...current,
630
+ [draftKey]: {
631
+ body: current[draftKey]?.body || '',
632
+ anchor,
633
+ },
634
+ };
635
+ });
636
+ }, []);
527
637
  // Edit mode state
528
638
  const [editMode, setEditMode] = useState(false);
639
+ const editModeRef = useRef(false);
640
+ editModeRef.current = editMode;
529
641
  const [draft, setDraft] = useState('');
530
642
  const [layout, setLayout] = useState('split');
531
643
  const [saveStatus, setSaveStatus] = useState({ type: 'idle' });
644
+ const [revisionConflict, setRevisionConflict] = useState(false);
532
645
  const [showGenModal, setShowGenModal] = useState(false);
533
646
  const [monochromeMode, setMonochromeMode] = useState(false);
534
647
  const [deleting, setDeleting] = useState(false);
@@ -545,11 +658,41 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
545
658
  const textareaRef = useRef(null);
546
659
  const renameInputRef = useRef(null);
547
660
  const previewScrollRef = useRef(null);
661
+ const viewerScrollRef = useRef(null);
548
662
  const printFrameRef = useRef(null);
549
663
  const printCleanupTimeoutRef = useRef(null);
550
664
  const reviewThreadEndRef = useRef(null);
665
+ const reviewThreadRef = useRef(null);
666
+ const reviewRailRef = useRef(null);
667
+ const reviewCloseButtonRef = useRef(null);
668
+ const reviewToggleButtonRef = useRef(null);
669
+ const reviewRenameButtonRef = useRef(null);
670
+ const reviewReplyInputRef = useRef(null);
671
+ const reviewReplyTriggerRefs = useRef(new Map());
672
+ const reviewReplyReturnFocusIdRef = useRef(null);
673
+ const reviewSessionsRef = useRef([]);
674
+ const reviewPendingAutoScrollRef = useRef(false);
675
+ const contentRequestSequenceRef = useRef(0);
676
+ const adoptedDocumentRevisionRef = useRef(null);
677
+ const pendingDocumentRevisionRef = useRef(null);
678
+ const reviewRequestSequenceRef = useRef(0);
679
+ const reviewMutationVersionRef = useRef(0);
680
+ const reviewInitialLoadSequenceRef = useRef(null);
551
681
  const markdownContainerRef = useRef(null);
682
+ const pendingScrollTopRef = useRef(null);
683
+ const scrollReportTimeoutRef = useRef(null);
684
+ const restoredScrollDocIdRef = useRef('');
685
+ const onScrollTopChangeRef = useRef(onScrollTopChange);
552
686
  const activeReviewSession = reviewSessions.find((session) => session.id === selectedReviewSessionId) || reviewSessions[0] || null;
687
+ const activeReviewCommentIdSignature = activeReviewSession?.comments.map((comment) => comment.id).join('|') || '';
688
+ const activeReviewThreadCount = activeReviewSession?.threadCount
689
+ ?? activeReviewSession?.comments.filter((comment) => !comment.parentCommentId).length
690
+ ?? 0;
691
+ const activeReviewUnresolvedThreadCount = activeReviewSession?.unresolvedThreadCount
692
+ ?? activeReviewSession?.comments.filter((comment) => (!comment.parentCommentId && comment.threadStatus !== 'resolved')).length
693
+ ?? 0;
694
+ const reviewResolutionBlocked = activeReviewSession?.status === 'open'
695
+ && activeReviewUnresolvedThreadCount > 0;
553
696
  const filteredTasks = tasks.filter((task) => {
554
697
  const query = attachSearch.trim().toLowerCase();
555
698
  if (!query)
@@ -557,35 +700,172 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
557
700
  return task.title.toLowerCase().includes(query)
558
701
  || String(task.referenceLabel || '').trim().toLowerCase().includes(query);
559
702
  });
560
- const fetchContent = useCallback(async () => {
561
- setLoadingContent(true);
703
+ const closeReviewSidebar = useCallback(() => {
704
+ setPendingReviewAnchor(null);
705
+ setShowReviewSidebar(false);
706
+ }, [setPendingReviewAnchor]);
707
+ const restoreReviewReplyFocus = useCallback(() => {
708
+ const commentId = reviewReplyReturnFocusIdRef.current;
709
+ reviewReplyReturnFocusIdRef.current = null;
710
+ if (!commentId)
711
+ return;
712
+ window.setTimeout(() => {
713
+ reviewReplyTriggerRefs.current.get(commentId)?.focus();
714
+ }, 0);
715
+ }, []);
716
+ const closeReviewReplyComposer = useCallback(() => {
717
+ setReplyingToCommentId(null);
718
+ setReplyDraft('');
719
+ restoreReviewReplyFocus();
720
+ }, [restoreReviewReplyFocus]);
721
+ const isReviewNearBottom = useCallback(() => {
722
+ const node = reviewThreadRef.current;
723
+ if (!node)
724
+ return true;
725
+ return node.scrollHeight - node.scrollTop - node.clientHeight <= REVIEW_BOTTOM_THRESHOLD_PX;
726
+ }, []);
727
+ const handleReviewThreadScroll = useCallback(() => {
728
+ const nearBottom = isReviewNearBottom();
729
+ if (nearBottom)
730
+ setHasNewReviewComments(false);
731
+ }, [isReviewNearBottom]);
732
+ const scrollReviewToLatest = useCallback((behavior = 'smooth') => {
733
+ const endNode = reviewThreadEndRef.current;
734
+ if (typeof endNode?.scrollIntoView === 'function') {
735
+ endNode.scrollIntoView({ block: 'end', behavior });
736
+ }
737
+ setHasNewReviewComments(false);
738
+ }, []);
739
+ const selectReviewSession = useCallback((sessionId) => {
740
+ selectedReviewSessionIdRef.current = sessionId;
741
+ reviewPendingAutoScrollRef.current = sessionId !== null;
742
+ setHasNewReviewComments(false);
743
+ setReplyingToCommentId(null);
744
+ setReplyDraft('');
745
+ reviewReplyReturnFocusIdRef.current = null;
746
+ setSelectedReviewSessionId(sessionId);
747
+ }, []);
748
+ useEffect(() => {
749
+ selectedReviewSessionIdRef.current = selectedReviewSessionId;
750
+ }, [selectedReviewSessionId]);
751
+ useEffect(() => {
752
+ reviewSessionsRef.current = reviewSessions;
753
+ }, [reviewSessions]);
754
+ useEffect(() => {
755
+ if (typeof window.matchMedia !== 'function')
756
+ return;
757
+ const mediaQuery = window.matchMedia('(max-width: 1100px)');
758
+ const updateViewport = () => setCompactReviewViewport(mediaQuery.matches);
759
+ updateViewport();
760
+ mediaQuery.addEventListener?.('change', updateViewport);
761
+ return () => mediaQuery.removeEventListener?.('change', updateViewport);
762
+ }, []);
763
+ useEffect(() => {
764
+ if (!compactReviewViewport || !showReviewSidebar)
765
+ return;
766
+ const rail = reviewRailRef.current;
767
+ if (!rail)
768
+ return;
769
+ const focusableSelector = [
770
+ 'button:not([disabled])',
771
+ 'select:not([disabled])',
772
+ 'textarea:not([disabled])',
773
+ 'input:not([disabled])',
774
+ '[tabindex]:not([tabindex="-1"])',
775
+ ].join(',');
776
+ const focusCloseButton = window.requestAnimationFrame(() => reviewCloseButtonRef.current?.focus());
777
+ const handleKeyDown = (event) => {
778
+ if (event.key === 'Escape') {
779
+ event.preventDefault();
780
+ closeReviewSidebar();
781
+ return;
782
+ }
783
+ if (event.key !== 'Tab')
784
+ return;
785
+ const focusable = Array.from(rail.querySelectorAll(focusableSelector));
786
+ if (focusable.length === 0) {
787
+ event.preventDefault();
788
+ return;
789
+ }
790
+ const first = focusable[0];
791
+ const last = focusable[focusable.length - 1];
792
+ if (event.shiftKey && document.activeElement === first) {
793
+ event.preventDefault();
794
+ last.focus();
795
+ }
796
+ else if (!event.shiftKey && document.activeElement === last) {
797
+ event.preventDefault();
798
+ first.focus();
799
+ }
800
+ };
801
+ document.addEventListener('keydown', handleKeyDown);
802
+ return () => {
803
+ window.cancelAnimationFrame(focusCloseButton);
804
+ document.removeEventListener('keydown', handleKeyDown);
805
+ if (rail.contains(document.activeElement)) {
806
+ reviewToggleButtonRef.current?.focus();
807
+ }
808
+ };
809
+ }, [closeReviewSidebar, compactReviewViewport, showReviewSidebar]);
810
+ const fetchContent = useCallback(async (targetVersion, targetRevision) => {
811
+ const requestSequence = ++contentRequestSequenceRef.current;
812
+ const initialLoad = contentRef.current === null;
813
+ if (initialLoad)
814
+ setLoadingContent(true);
562
815
  setLoadError(null);
563
- setContent(null);
564
816
  try {
565
817
  // Avoid credentialed cross-origin redirects when cloud storage serves signed document URLs.
566
818
  const res = await fetchTaskforceApi(doc.apiUrl, { credentials: 'same-origin' }, apiBaseUrl);
567
819
  if (!res.ok)
568
820
  throw new Error(`Failed to load document (${res.status})`);
569
821
  const text = await res.text();
822
+ if (requestSequence !== contentRequestSequenceRef.current)
823
+ return;
824
+ if (editModeRef.current && contentRef.current !== null) {
825
+ pendingDocumentRevisionRef.current = { revision: targetRevision, version: targetVersion };
826
+ setRevisionConflict(true);
827
+ setSaveStatus({ type: 'error', message: DOCUMENT_REVISION_CONFLICT_ERROR });
828
+ return;
829
+ }
570
830
  setContent(text);
571
- setDraft(text);
831
+ if (!editModeRef.current)
832
+ setDraft(text);
833
+ setCurrentDocumentVersion(targetVersion);
834
+ adoptedDocumentRevisionRef.current = targetRevision;
835
+ pendingDocumentRevisionRef.current = null;
836
+ setRevisionConflict(false);
837
+ setSaveStatus((current) => current.type === 'error' && current.message === DOCUMENT_REFRESH_ERROR
838
+ ? { type: 'idle' }
839
+ : current);
572
840
  }
573
841
  catch (e) {
574
- setLoadError(e?.message || 'Failed to load document');
842
+ if (requestSequence !== contentRequestSequenceRef.current)
843
+ return;
844
+ if (initialLoad)
845
+ setLoadError(e?.message || 'Failed to load document');
846
+ else
847
+ setSaveStatus({ type: 'error', message: DOCUMENT_REFRESH_ERROR });
575
848
  }
576
849
  finally {
577
- setLoadingContent(false);
850
+ if (initialLoad && requestSequence === contentRequestSequenceRef.current)
851
+ setLoadingContent(false);
578
852
  }
579
853
  }, [apiBaseUrl, doc.apiUrl]);
580
854
  const fetchReviewSessions = useCallback(async (options) => {
855
+ const silent = options?.silent === true;
856
+ if (silent && reviewInitialLoadSequenceRef.current !== null)
857
+ return;
858
+ const requestSequence = ++reviewRequestSequenceRef.current;
859
+ const mutationVersion = reviewMutationVersionRef.current;
581
860
  if (!doc.assetId) {
861
+ reviewSessionsRef.current = [];
582
862
  setReviewSessions([]);
583
- setSelectedReviewSessionId(null);
863
+ selectReviewSession(null);
584
864
  setReviewError(null);
585
865
  return;
586
866
  }
587
- const silent = options?.silent === true;
588
867
  if (!silent) {
868
+ reviewInitialLoadSequenceRef.current = requestSequence;
589
869
  setLoadingReviews(true);
590
870
  setReviewError(null);
591
871
  }
@@ -594,27 +874,57 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
594
874
  const data = await res.json().catch(() => ({}));
595
875
  if (!res.ok)
596
876
  throw new Error(data.error || `Failed to load reviews (${res.status})`);
877
+ if (requestSequence !== reviewRequestSequenceRef.current
878
+ || mutationVersion !== reviewMutationVersionRef.current)
879
+ return;
597
880
  const sessions = Array.isArray(data.sessions) ? data.sessions : [];
881
+ const previousSessions = reviewSessionsRef.current;
882
+ const currentSessionId = selectedReviewSessionIdRef.current;
883
+ const nextSessionId = currentSessionId && sessions.some((session) => session.id === currentSessionId)
884
+ ? currentSessionId
885
+ : sessions[0]?.id ?? null;
886
+ if (silent && nextSessionId) {
887
+ const previousSession = previousSessions.find((session) => session.id === nextSessionId) || null;
888
+ const incomingSession = sessions.find((session) => session.id === nextSessionId) || null;
889
+ const previousCommentIds = new Set(previousSession?.comments.map((comment) => comment.id) || []);
890
+ const hasIncomingComments = incomingSession?.comments.some((comment) => !previousCommentIds.has(comment.id)) === true;
891
+ if (previousSession && hasIncomingComments) {
892
+ const nearBottom = isReviewNearBottom();
893
+ if (nearBottom) {
894
+ reviewPendingAutoScrollRef.current = true;
895
+ }
896
+ else {
897
+ setHasNewReviewComments(true);
898
+ }
899
+ }
900
+ }
901
+ reviewSessionsRef.current = sessions;
598
902
  setReviewSessions(sessions);
599
- setSelectedReviewSessionId((currentId) => {
600
- if (currentId && sessions.some((session) => session.id === currentId))
601
- return currentId;
602
- return sessions[0]?.id ?? null;
603
- });
903
+ if (nextSessionId !== currentSessionId)
904
+ selectReviewSession(nextSessionId);
604
905
  }
605
906
  catch (error) {
907
+ if (requestSequence !== reviewRequestSequenceRef.current
908
+ || mutationVersion !== reviewMutationVersionRef.current)
909
+ return;
606
910
  if (!silent) {
911
+ reviewSessionsRef.current = [];
607
912
  setReviewError(error?.message || 'Failed to load reviews');
608
913
  setReviewSessions([]);
609
- setSelectedReviewSessionId(null);
914
+ selectReviewSession(null);
610
915
  }
611
916
  }
612
917
  finally {
613
- if (!silent) {
918
+ if (!silent && reviewInitialLoadSequenceRef.current === requestSequence) {
919
+ reviewInitialLoadSequenceRef.current = null;
614
920
  setLoadingReviews(false);
615
921
  }
616
922
  }
617
- }, [apiBaseUrl, doc.assetId]);
923
+ }, [apiBaseUrl, doc.assetId, isReviewNearBottom, selectReviewSession]);
924
+ const markReviewMutation = useCallback(() => {
925
+ reviewMutationVersionRef.current += 1;
926
+ reviewRequestSequenceRef.current += 1;
927
+ }, []);
618
928
  const createReviewSession = useCallback(async () => {
619
929
  if (!doc.assetId || reviewBusy)
620
930
  return null;
@@ -636,8 +946,9 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
636
946
  const session = (data.session || null);
637
947
  if (!session)
638
948
  throw new Error('Review session payload missing.');
949
+ markReviewMutation();
639
950
  setReviewSessions((current) => [session, ...current.filter((entry) => entry.id !== session.id)]);
640
- setSelectedReviewSessionId(session.id);
951
+ selectReviewSession(session.id);
641
952
  return session;
642
953
  }
643
954
  catch (error) {
@@ -647,38 +958,143 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
647
958
  finally {
648
959
  setReviewBusy(false);
649
960
  }
650
- }, [apiBaseUrl, doc.assetId, reviewBusy, reviewSessions.length]);
961
+ }, [apiBaseUrl, doc.assetId, markReviewMutation, reviewBusy, reviewSessions.length, selectReviewSession]);
962
+ const documentIdentity = doc.assetId;
963
+ const documentRevision = `${doc.updatedAt || ''}:${doc.version || ''}`;
651
964
  useEffect(() => {
652
- fetchContent();
653
- void fetchReviewSessions();
965
+ contentRequestSequenceRef.current += 1;
966
+ reviewRequestSequenceRef.current += 1;
967
+ contentRef.current = null;
968
+ setContent(null);
654
969
  // Reset edit mode when doc changes
655
970
  setEditMode(false);
971
+ setRevisionConflict(false);
972
+ adoptedDocumentRevisionRef.current = null;
973
+ pendingDocumentRevisionRef.current = null;
656
974
  setSaveStatus({ type: 'idle' });
657
975
  setRenaming(false);
658
- const nextReadableName = getReadableDocumentName(doc);
659
- setCurrentDocumentName(nextReadableName);
660
- setRenameValue(nextReadableName);
661
976
  setCopied(false);
662
977
  setCopiedReference(false);
663
- setReviewDraft('');
664
- setPendingReviewAnchor(null);
978
+ setCurrentDocumentVersion(null);
979
+ setReviewComposerDrafts({});
980
+ setSavedRenderedText(null);
981
+ setHasNewReviewComments(false);
665
982
  setEditingReviewTitle(false);
666
983
  setReviewTitleDraft('');
667
984
  setEditingCommentId(null);
668
985
  setEditingCommentDraft('');
669
- }, [doc, fetchContent, fetchReviewSessions]);
986
+ setReplyingToCommentId(null);
987
+ setReplyDraft('');
988
+ reviewReplyReturnFocusIdRef.current = null;
989
+ }, [documentIdentity]);
670
990
  useEffect(() => {
671
- if (!activeReviewSession)
991
+ const targetVersion = typeof doc.version === 'number' && Number.isFinite(doc.version)
992
+ ? Math.max(1, Math.floor(doc.version))
993
+ : null;
994
+ if (editModeRef.current
995
+ && contentRef.current !== null
996
+ && adoptedDocumentRevisionRef.current !== documentRevision) {
997
+ contentRequestSequenceRef.current += 1;
998
+ pendingDocumentRevisionRef.current = { revision: documentRevision, version: targetVersion };
999
+ setRevisionConflict(true);
1000
+ setSaveStatus({ type: 'error', message: DOCUMENT_REVISION_CONFLICT_ERROR });
672
1001
  return;
673
- const endNode = reviewThreadEndRef.current;
674
- if (typeof endNode?.scrollIntoView === 'function') {
675
- endNode.scrollIntoView({ block: 'end' });
676
1002
  }
677
- }, [activeReviewSession?.comments.length, activeReviewSession?.id]);
1003
+ pendingDocumentRevisionRef.current = { revision: documentRevision, version: targetVersion };
1004
+ void fetchContent(targetVersion, documentRevision);
1005
+ }, [documentIdentity, documentRevision, fetchContent]);
1006
+ useEffect(() => {
1007
+ void fetchReviewSessions();
1008
+ // Review sessions are tied to the document, not each content revision.
1009
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1010
+ }, [documentIdentity]);
1011
+ useEffect(() => {
1012
+ if (editMode || !revisionConflict)
1013
+ return;
1014
+ const pendingRevision = pendingDocumentRevisionRef.current;
1015
+ if (!pendingRevision)
1016
+ return;
1017
+ setRevisionConflict(false);
1018
+ void fetchContent(pendingRevision.version, pendingRevision.revision);
1019
+ }, [editMode, fetchContent, revisionConflict]);
1020
+ useEffect(() => {
1021
+ setCurrentDocumentName(fallbackReadableName);
1022
+ setRenameValue(fallbackReadableName);
1023
+ }, [fallbackReadableName]);
1024
+ useEffect(() => {
1025
+ if (editMode || !markdownContainerRef.current)
1026
+ return;
1027
+ const hasQuoteAnchors = reviewSessions.some((session) => session.comments.some((comment) => comment.anchor?.kind === 'quote'));
1028
+ if (!hasQuoteAnchors)
1029
+ return;
1030
+ setSavedRenderedText(markdownContainerRef.current.textContent || '');
1031
+ }, [content, editMode, reviewSessions]);
1032
+ useEffect(() => {
1033
+ if (!activeReviewSession || !reviewPendingAutoScrollRef.current)
1034
+ return;
1035
+ reviewPendingAutoScrollRef.current = false;
1036
+ scrollReviewToLatest('auto');
1037
+ }, [activeReviewCommentIdSignature, activeReviewSession?.id, scrollReviewToLatest]);
678
1038
  useEffect(() => {
679
1039
  setReviewTitleDraft(activeReviewSession?.title?.trim() || '');
680
1040
  setEditingReviewTitle(false);
681
1041
  }, [activeReviewSession?.id, activeReviewSession?.title]);
1042
+ useEffect(() => {
1043
+ setReplyingToCommentId(null);
1044
+ setReplyDraft('');
1045
+ reviewReplyReturnFocusIdRef.current = null;
1046
+ }, [activeReviewSession?.id]);
1047
+ useEffect(() => {
1048
+ if (!replyingToCommentId)
1049
+ return;
1050
+ reviewReplyInputRef.current?.focus();
1051
+ }, [replyingToCommentId]);
1052
+ useEffect(() => {
1053
+ onScrollTopChangeRef.current = onScrollTopChange;
1054
+ }, [onScrollTopChange]);
1055
+ const flushScrollTopChange = useCallback(() => {
1056
+ if (scrollReportTimeoutRef.current !== null) {
1057
+ window.clearTimeout(scrollReportTimeoutRef.current);
1058
+ scrollReportTimeoutRef.current = null;
1059
+ }
1060
+ const scrollTop = pendingScrollTopRef.current;
1061
+ pendingScrollTopRef.current = null;
1062
+ if (scrollTop !== null) {
1063
+ onScrollTopChangeRef.current?.(scrollTop);
1064
+ }
1065
+ }, []);
1066
+ const reportScrollTopChange = useCallback((scrollTop) => {
1067
+ pendingScrollTopRef.current = Math.max(0, Math.round(scrollTop));
1068
+ if (scrollReportTimeoutRef.current !== null)
1069
+ return;
1070
+ scrollReportTimeoutRef.current = window.setTimeout(flushScrollTopChange, 200);
1071
+ }, [flushScrollTopChange]);
1072
+ useEffect(() => {
1073
+ return () => {
1074
+ const currentScrollTop = viewerScrollRef.current?.scrollTop;
1075
+ if (typeof currentScrollTop === 'number') {
1076
+ pendingScrollTopRef.current = Math.max(0, Math.round(currentScrollTop));
1077
+ }
1078
+ flushScrollTopChange();
1079
+ };
1080
+ }, [doc.assetId, flushScrollTopChange]);
1081
+ useEffect(() => {
1082
+ if (editMode || loadingContent || loadError || content === null)
1083
+ return;
1084
+ const scrollNode = viewerScrollRef.current;
1085
+ if (!scrollNode)
1086
+ return;
1087
+ if (restoredScrollDocIdRef.current === doc.assetId)
1088
+ return;
1089
+ restoredScrollDocIdRef.current = doc.assetId;
1090
+ const desiredScrollTop = Math.max(0, Math.round(initialScrollTop || 0));
1091
+ window.requestAnimationFrame(() => {
1092
+ window.requestAnimationFrame(() => {
1093
+ const maxScrollTop = Math.max(0, scrollNode.scrollHeight - scrollNode.clientHeight);
1094
+ scrollNode.scrollTop = Math.min(desiredScrollTop, maxScrollTop);
1095
+ });
1096
+ });
1097
+ }, [content, doc.assetId, editMode, initialScrollTop, loadError, loadingContent]);
682
1098
  useEffect(() => {
683
1099
  if (!renaming)
684
1100
  return;
@@ -688,7 +1104,7 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
688
1104
  }, 0);
689
1105
  }, [renaming]);
690
1106
  useEffect(() => {
691
- if (!doc.assetId || editMode)
1107
+ if (!doc.assetId)
692
1108
  return;
693
1109
  const refreshIfVisible = () => {
694
1110
  if (document.visibilityState !== 'visible')
@@ -703,7 +1119,7 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
703
1119
  window.removeEventListener('focus', refreshIfVisible);
704
1120
  document.removeEventListener('visibilitychange', refreshIfVisible);
705
1121
  };
706
- }, [doc.assetId, editMode, fetchReviewSessions]);
1122
+ }, [doc.assetId, fetchReviewSessions]);
707
1123
  // Ctrl+S / Cmd+S to save while editing
708
1124
  useEffect(() => {
709
1125
  if (!editMode)
@@ -757,6 +1173,13 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
757
1173
  const handleEnterEdit = () => {
758
1174
  if (!isEditable)
759
1175
  return;
1176
+ if (pendingDocumentRevisionRef.current) {
1177
+ setSaveStatus({ type: 'error', message: DOCUMENT_REFRESH_ERROR });
1178
+ return;
1179
+ }
1180
+ if (markdownContainerRef.current) {
1181
+ setSavedRenderedText(markdownContainerRef.current.textContent || '');
1182
+ }
760
1183
  setDraft(content ?? '');
761
1184
  setSaveStatus({ type: 'idle' });
762
1185
  setEditMode(true);
@@ -775,11 +1198,15 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
775
1198
  const handleSave = useCallback(async () => {
776
1199
  if (!isEditable)
777
1200
  return;
1201
+ if (revisionConflict) {
1202
+ setSaveStatus({ type: 'error', message: DOCUMENT_REVISION_CONFLICT_ERROR });
1203
+ return;
1204
+ }
778
1205
  if (saveStatus.type === 'saving')
779
1206
  return;
780
1207
  setSaveStatus({ type: 'saving' });
781
1208
  try {
782
- const res = await fetchTaskforceApi('/api/taskforce/documents/save', {
1209
+ const res = await fetchTaskforceApi(withWorkspaceQuery('/api/taskforce/documents/save', workspaceId), {
783
1210
  method: 'POST',
784
1211
  credentials: 'include',
785
1212
  headers: { 'Content-Type': 'application/json' },
@@ -789,7 +1216,11 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
789
1216
  if (!res.ok)
790
1217
  throw new Error(data.error || `Save failed (${res.status})`);
791
1218
  const updatedAt = data.updatedAt || new Date().toISOString();
1219
+ const savedVersion = typeof data.version === 'number' && Number.isFinite(data.version)
1220
+ ? Math.max(1, Math.floor(data.version))
1221
+ : null;
792
1222
  setContent(draft);
1223
+ setCurrentDocumentVersion(savedVersion);
793
1224
  setSaveStatus({ type: 'saved', savedAt: updatedAt });
794
1225
  onSaved?.(updatedAt);
795
1226
  // Return to view mode
@@ -798,7 +1229,7 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
798
1229
  catch (e) {
799
1230
  setSaveStatus({ type: 'error', message: e?.message || 'Save failed' });
800
1231
  }
801
- }, [apiBaseUrl, doc.fsPath, draft, saveStatus.type, onSaved, isEditable]);
1232
+ }, [apiBaseUrl, doc.fsPath, draft, saveStatus.type, onSaved, isEditable, revisionConflict, workspaceId]);
802
1233
  const handlePrint = useCallback(() => {
803
1234
  const printSource = editMode ? draft : (content ?? '');
804
1235
  if (!printSource.trim())
@@ -895,11 +1326,11 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
895
1326
  setRenaming(false);
896
1327
  return;
897
1328
  }
898
- const res = await fetchTaskforceApi(`/api/taskforce/documents/${encodeURIComponent(doc.assetId)}`, {
1329
+ const res = await fetchTaskforceApi(withWorkspaceQuery(`/api/taskforce/documents/${encodeURIComponent(doc.assetId)}`, workspaceId), {
899
1330
  method: 'PATCH',
900
1331
  credentials: 'include',
901
1332
  headers: { 'Content-Type': 'application/json' },
902
- body: JSON.stringify({ displayName: nextName })
1333
+ body: JSON.stringify({ title: nextName })
903
1334
  }, apiBaseUrl);
904
1335
  const data = await res.json().catch(() => ({}));
905
1336
  if (!res.ok) {
@@ -910,7 +1341,7 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
910
1341
  setRenameValue(nextName);
911
1342
  setRenaming(false);
912
1343
  onSaved?.(data.updatedAt || new Date().toISOString());
913
- }, [apiBaseUrl, doc.assetId, onSaved, readableName, renameValue]);
1344
+ }, [apiBaseUrl, doc.assetId, onSaved, readableName, renameValue, workspaceId]);
914
1345
  const handleRenameKeyDown = useCallback((event) => {
915
1346
  if (event.key === 'Enter') {
916
1347
  event.preventDefault();
@@ -935,7 +1366,7 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
935
1366
  return;
936
1367
  setDeleting(true);
937
1368
  try {
938
- const res = await fetchTaskforceApi(`/api/taskforce/documents/${encodeURIComponent(doc.assetId)}`, {
1369
+ const res = await fetchTaskforceApi(withWorkspaceQuery(`/api/taskforce/documents/${encodeURIComponent(doc.assetId)}`, workspaceId), {
939
1370
  method: 'DELETE',
940
1371
  credentials: 'include',
941
1372
  headers: { 'Content-Type': 'application/json' },
@@ -952,7 +1383,7 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
952
1383
  finally {
953
1384
  setDeleting(false);
954
1385
  }
955
- }, [apiBaseUrl, attachmentState, deleting, doc.assetId, doc.attachmentCount, onDeleted, readableName]);
1386
+ }, [apiBaseUrl, attachmentState, deleting, doc.assetId, doc.attachmentCount, onDeleted, readableName, workspaceId]);
956
1387
  const handleOpenAttachModal = useCallback(() => {
957
1388
  setAttachSearch('');
958
1389
  setAttachError(null);
@@ -965,7 +1396,7 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
965
1396
  setAttachError(null);
966
1397
  setAttachingTaskId(taskId);
967
1398
  try {
968
- const res = await fetchTaskforceApi(`/api/taskforce/documents/${encodeURIComponent(doc.assetId)}/attach`, {
1399
+ const res = await fetchTaskforceApi(withWorkspaceQuery(`/api/taskforce/documents/${encodeURIComponent(doc.assetId)}/attach`, workspaceId), {
969
1400
  method: 'POST',
970
1401
  credentials: 'include',
971
1402
  headers: { 'Content-Type': 'application/json' },
@@ -990,7 +1421,7 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
990
1421
  finally {
991
1422
  setAttachingTaskId(null);
992
1423
  }
993
- }, [apiBaseUrl, doc.assetId, onSaved]);
1424
+ }, [apiBaseUrl, doc.assetId, onSaved, workspaceId]);
994
1425
  const handleToggleReviewStatus = useCallback(async () => {
995
1426
  if (!activeReviewSession || reviewBusy)
996
1427
  return;
@@ -1010,6 +1441,7 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
1010
1441
  const updatedSession = (data.session || null);
1011
1442
  if (!updatedSession)
1012
1443
  throw new Error('Review session payload missing.');
1444
+ markReviewMutation();
1013
1445
  setReviewSessions((current) => current.map((session) => session.id === updatedSession.id ? updatedSession : session));
1014
1446
  }
1015
1447
  catch (error) {
@@ -1018,7 +1450,15 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
1018
1450
  finally {
1019
1451
  setReviewBusy(false);
1020
1452
  }
1021
- }, [activeReviewSession, apiBaseUrl, reviewBusy]);
1453
+ }, [activeReviewSession, apiBaseUrl, markReviewMutation, reviewBusy]);
1454
+ const restoreReviewRenameFocus = useCallback(() => {
1455
+ window.setTimeout(() => reviewRenameButtonRef.current?.focus(), 0);
1456
+ }, []);
1457
+ const cancelReviewTitleEdit = useCallback(() => {
1458
+ setReviewTitleDraft(activeReviewSession?.title || '');
1459
+ setEditingReviewTitle(false);
1460
+ restoreReviewRenameFocus();
1461
+ }, [activeReviewSession, restoreReviewRenameFocus]);
1022
1462
  const handleSaveReviewTitle = useCallback(async () => {
1023
1463
  if (!activeReviewSession || reviewBusy)
1024
1464
  return;
@@ -1038,8 +1478,10 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
1038
1478
  const updatedSession = (data.session || null);
1039
1479
  if (!updatedSession)
1040
1480
  throw new Error('Review session payload missing.');
1481
+ markReviewMutation();
1041
1482
  setReviewSessions((current) => current.map((session) => session.id === updatedSession.id ? updatedSession : session));
1042
1483
  setEditingReviewTitle(false);
1484
+ restoreReviewRenameFocus();
1043
1485
  }
1044
1486
  catch (error) {
1045
1487
  setReviewError(error?.message || 'Failed to update review');
@@ -1047,7 +1489,7 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
1047
1489
  finally {
1048
1490
  setReviewBusy(false);
1049
1491
  }
1050
- }, [activeReviewSession, apiBaseUrl, reviewBusy, reviewTitleDraft]);
1492
+ }, [activeReviewSession, apiBaseUrl, markReviewMutation, restoreReviewRenameFocus, reviewBusy, reviewTitleDraft]);
1051
1493
  const previewContent = editMode ? draft : (content ?? '');
1052
1494
  const handleCaptureReviewAnchor = useCallback(() => {
1053
1495
  if (editMode || !showReviewSidebar)
@@ -1069,7 +1511,7 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
1069
1511
  if (!anchor)
1070
1512
  return;
1071
1513
  setPendingReviewAnchor(anchor);
1072
- }, [editMode, showReviewSidebar]);
1514
+ }, [editMode, setPendingReviewAnchor, showReviewSidebar]);
1073
1515
  const handleToggleReviewSidebar = useCallback(() => {
1074
1516
  setShowReviewSidebar((current) => {
1075
1517
  const nextValue = !current;
@@ -1078,7 +1520,7 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
1078
1520
  }
1079
1521
  return nextValue;
1080
1522
  });
1081
- }, []);
1523
+ }, [setPendingReviewAnchor]);
1082
1524
  const handleAddReviewComment = useCallback(async () => {
1083
1525
  const body = reviewDraft.trim();
1084
1526
  if (!body || reviewBusy)
@@ -1107,13 +1549,20 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
1107
1549
  const updatedSession = (data.session || null);
1108
1550
  if (!updatedSession)
1109
1551
  throw new Error('Review session payload missing.');
1552
+ markReviewMutation();
1553
+ reviewPendingAutoScrollRef.current = true;
1554
+ setHasNewReviewComments(false);
1110
1555
  setReviewSessions((current) => {
1111
1556
  const rest = current.filter((entry) => entry.id !== updatedSession.id);
1112
1557
  return [updatedSession, ...rest];
1113
1558
  });
1114
- setSelectedReviewSessionId(updatedSession.id);
1115
- setReviewDraft('');
1116
- setPendingReviewAnchor(null);
1559
+ selectReviewSession(updatedSession.id);
1560
+ setReviewComposerDrafts((current) => {
1561
+ const next = { ...current };
1562
+ delete next[reviewDraftKey];
1563
+ delete next[updatedSession.id];
1564
+ return next;
1565
+ });
1117
1566
  }
1118
1567
  catch (error) {
1119
1568
  setReviewError(error?.message || 'Failed to add comment');
@@ -1121,7 +1570,17 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
1121
1570
  finally {
1122
1571
  setReviewBusy(false);
1123
1572
  }
1124
- }, [activeReviewSession, apiBaseUrl, createReviewSession, pendingReviewAnchor, reviewBusy, reviewDraft]);
1573
+ }, [
1574
+ activeReviewSession,
1575
+ apiBaseUrl,
1576
+ createReviewSession,
1577
+ pendingReviewAnchor,
1578
+ reviewBusy,
1579
+ reviewDraft,
1580
+ reviewDraftKey,
1581
+ markReviewMutation,
1582
+ selectReviewSession,
1583
+ ]);
1125
1584
  const handleStartEditingComment = useCallback((commentId, body) => {
1126
1585
  setEditingCommentId(commentId);
1127
1586
  setEditingCommentDraft(body);
@@ -1147,6 +1606,7 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
1147
1606
  const updatedSession = (data.session || null);
1148
1607
  if (!updatedSession)
1149
1608
  throw new Error('Review session payload missing.');
1609
+ markReviewMutation();
1150
1610
  setReviewSessions((current) => current.map((session) => session.id === updatedSession.id ? updatedSession : session));
1151
1611
  setEditingCommentId(null);
1152
1612
  setEditingCommentDraft('');
@@ -1157,16 +1617,24 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
1157
1617
  finally {
1158
1618
  setReviewBusy(false);
1159
1619
  }
1160
- }, [activeReviewSession, apiBaseUrl, editingCommentDraft, editingCommentId, reviewBusy]);
1620
+ }, [activeReviewSession, apiBaseUrl, editingCommentDraft, editingCommentId, markReviewMutation, reviewBusy]);
1161
1621
  const handleDeleteReviewComment = useCallback(async (commentId) => {
1162
1622
  if (!activeReviewSession || reviewBusy)
1163
1623
  return;
1164
- if (!window.confirm('Delete this review comment?'))
1624
+ const target = activeReviewSession.comments.find((comment) => comment.id === commentId) || null;
1625
+ const replyCount = target?.parentCommentId
1626
+ ? 0
1627
+ : activeReviewSession.comments.filter((comment) => comment.parentCommentId === commentId).length;
1628
+ const shouldCascade = replyCount > 0;
1629
+ const confirmation = shouldCascade
1630
+ ? `Delete this thread and its ${replyCount} ${replyCount === 1 ? 'reply' : 'replies'}? This cannot be undone.`
1631
+ : 'Delete this review comment?';
1632
+ if (!window.confirm(confirmation))
1165
1633
  return;
1166
1634
  setReviewBusy(true);
1167
1635
  setReviewError(null);
1168
1636
  try {
1169
- const res = await fetchTaskforceApi(`/api/taskforce/document-reviews/sessions/${encodeURIComponent(activeReviewSession.id)}/comments/${encodeURIComponent(commentId)}`, {
1637
+ const res = await fetchTaskforceApi(`/api/taskforce/document-reviews/sessions/${encodeURIComponent(activeReviewSession.id)}/comments/${encodeURIComponent(commentId)}${shouldCascade ? '?cascade=true' : ''}`, {
1170
1638
  method: 'DELETE',
1171
1639
  credentials: 'include',
1172
1640
  }, apiBaseUrl);
@@ -1176,6 +1644,7 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
1176
1644
  const updatedSession = (data.session || null);
1177
1645
  if (!updatedSession)
1178
1646
  throw new Error('Review session payload missing.');
1647
+ markReviewMutation();
1179
1648
  setReviewSessions((current) => current.map((session) => session.id === updatedSession.id ? updatedSession : session));
1180
1649
  if (editingCommentId === commentId) {
1181
1650
  setEditingCommentId(null);
@@ -1188,13 +1657,124 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
1188
1657
  finally {
1189
1658
  setReviewBusy(false);
1190
1659
  }
1191
- }, [activeReviewSession, apiBaseUrl, editingCommentId, reviewBusy]);
1660
+ }, [activeReviewSession, apiBaseUrl, editingCommentId, markReviewMutation, reviewBusy]);
1661
+ const handleAddReviewReply = useCallback(async (parentCommentId) => {
1662
+ if (!activeReviewSession || reviewBusy || replyingToCommentId !== parentCommentId)
1663
+ return;
1664
+ const body = replyDraft.trim();
1665
+ if (!body)
1666
+ return;
1667
+ setReviewBusy(true);
1668
+ setReviewError(null);
1669
+ try {
1670
+ const res = await fetchTaskforceApi(`/api/taskforce/document-reviews/sessions/${encodeURIComponent(activeReviewSession.id)}/comments/${encodeURIComponent(parentCommentId)}/replies`, {
1671
+ method: 'POST',
1672
+ credentials: 'include',
1673
+ headers: { 'Content-Type': 'application/json' },
1674
+ body: JSON.stringify({ body }),
1675
+ }, apiBaseUrl);
1676
+ const data = await res.json().catch(() => ({}));
1677
+ if (!res.ok)
1678
+ throw new Error(data.error || `Failed to add reply (${res.status})`);
1679
+ const updatedSession = (data.session || null);
1680
+ if (!updatedSession)
1681
+ throw new Error('Review session payload missing.');
1682
+ markReviewMutation();
1683
+ reviewPendingAutoScrollRef.current = true;
1684
+ setHasNewReviewComments(false);
1685
+ setReviewSessions((current) => current.map((session) => session.id === updatedSession.id ? updatedSession : session));
1686
+ closeReviewReplyComposer();
1687
+ }
1688
+ catch (error) {
1689
+ setReviewError(error?.message || 'Failed to add reply');
1690
+ }
1691
+ finally {
1692
+ setReviewBusy(false);
1693
+ }
1694
+ }, [activeReviewSession, apiBaseUrl, closeReviewReplyComposer, markReviewMutation, replyingToCommentId, replyDraft, reviewBusy]);
1695
+ const handleUpdateThreadStatus = useCallback(async (commentId, status) => {
1696
+ if (!activeReviewSession || reviewBusy)
1697
+ return;
1698
+ setReviewBusy(true);
1699
+ setReviewError(null);
1700
+ try {
1701
+ const res = await fetchTaskforceApi(`/api/taskforce/document-reviews/sessions/${encodeURIComponent(activeReviewSession.id)}/comments/${encodeURIComponent(commentId)}/thread-status`, {
1702
+ method: 'PATCH',
1703
+ credentials: 'include',
1704
+ headers: { 'Content-Type': 'application/json' },
1705
+ body: JSON.stringify({ status }),
1706
+ }, apiBaseUrl);
1707
+ const data = await res.json().catch(() => ({}));
1708
+ if (!res.ok)
1709
+ throw new Error(data.error || `Failed to update thread (${res.status})`);
1710
+ const updatedSession = (data.session || null);
1711
+ if (!updatedSession)
1712
+ throw new Error('Review session payload missing.');
1713
+ markReviewMutation();
1714
+ setReviewSessions((current) => current.map((session) => session.id === updatedSession.id ? updatedSession : session));
1715
+ setReplyingToCommentId(null);
1716
+ setReplyDraft('');
1717
+ }
1718
+ catch (error) {
1719
+ setReviewError(error?.message || 'Failed to update thread');
1720
+ }
1721
+ finally {
1722
+ setReviewBusy(false);
1723
+ }
1724
+ }, [activeReviewSession, apiBaseUrl, markReviewMutation, reviewBusy]);
1725
+ const renderReviewComment = (comment, isReply = false) => {
1726
+ const isAi = comment.authorActor?.kind === 'ai';
1727
+ const anchorLabel = formatReviewAnchor(comment.anchor);
1728
+ const anchorHealth = getReviewAnchorHealth(comment.anchor, content, savedRenderedText);
1729
+ const ActorIcon = isAi ? Bot : User;
1730
+ const isEditingComment = editingCommentId === comment.id;
1731
+ const canEditComment = comment.permissions?.canEdit === true;
1732
+ const canDeleteComment = comment.permissions?.canDelete === true;
1733
+ const canReply = comment.permissions?.canReply === true;
1734
+ const canResolve = comment.permissions?.canResolve === true;
1735
+ const canReopen = comment.permissions?.canReopen === true;
1736
+ const createdAtMs = Date.parse(comment.createdAt);
1737
+ const updatedAtMs = Date.parse(comment.updatedAt);
1738
+ const isEdited = Number.isFinite(createdAtMs)
1739
+ && Number.isFinite(updatedAtMs)
1740
+ && updatedAtMs > createdAtMs;
1741
+ return (_jsxs("article", { "data-review-comment-id": comment.id, "data-conversation-role": isAi ? 'assistant' : 'user', style: comment.authorActor?.color
1742
+ ? { '--review-accent': comment.authorActor.color }
1743
+ : undefined, className: `${viewerStyles.reviewComment} ${isReply ? viewerStyles.reviewReply : ''}`, children: [_jsxs("div", { className: viewerStyles.reviewCommentHeader, children: [_jsx("span", { className: viewerStyles.reviewCommentAvatar, style: comment.authorActor?.color ? { color: comment.authorActor.color } : undefined, "aria-hidden": "true", children: _jsx(ActorIcon, { size: 13, strokeWidth: 1.7 }) }), _jsx("span", { className: viewerStyles.reviewCommentAuthor, children: getReviewActorLabel(comment) }), _jsxs("time", { className: viewerStyles.reviewCommentTime, dateTime: comment.updatedAt, title: isEdited
1744
+ ? `Edited ${formatDate(comment.updatedAt)}; originally posted ${formatDate(comment.createdAt)}`
1745
+ : formatDate(comment.createdAt), children: [isEdited ? 'Edited · ' : '', formatReviewTimestamp(comment.updatedAt)] }), ((!isReply && comment.threadStatus === 'resolved')
1746
+ || canEditComment || canDeleteComment || isEditingComment) && (_jsxs("span", { className: viewerStyles.reviewCommentHeaderControls, children: [!isReply && comment.threadStatus === 'resolved' && (_jsx("span", { className: "tf-chip-success", children: "Resolved" })), (canEditComment || canDeleteComment || isEditingComment) && (_jsxs("span", { className: viewerStyles.reviewCommentActions, children: [!isEditingComment && canEditComment && (_jsx("button", { type: "button", className: `tf-control-icon ${viewerStyles.reviewCommentAction}`, onClick: () => handleStartEditingComment(comment.id, comment.body), disabled: reviewBusy, "aria-label": "Edit comment", title: "Edit comment", children: _jsx(Pencil, { size: 13 }) })), isEditingComment && (_jsx("button", { type: "button", className: "tf-button-ghost tf-button-compact", onClick: () => {
1747
+ setEditingCommentId(null);
1748
+ setEditingCommentDraft('');
1749
+ }, disabled: reviewBusy, children: "Cancel" })), canDeleteComment && (_jsx("button", { type: "button", className: `tf-control-icon ${viewerStyles.reviewCommentAction} ${viewerStyles.reviewCommentDeleteAction}`, onClick: () => { void handleDeleteReviewComment(comment.id); }, disabled: reviewBusy, "aria-label": "Delete comment", title: "Delete comment", children: _jsx(Trash2, { size: 13 }) }))] }))] }))] }), anchorLabel && (_jsxs("span", { className: viewerStyles.reviewAnchorRow, children: [_jsx("span", { className: viewerStyles.reviewAnchorLabel, title: comment.anchor?.kind === 'quote' ? comment.anchor.quote : undefined, children: anchorLabel }), anchorHealth !== 'valid' && (_jsx("span", { className: anchorHealth === 'moved'
1750
+ ? viewerStyles.reviewAnchorMoved
1751
+ : anchorHealth === 'unresolved'
1752
+ ? viewerStyles.reviewAnchorUnresolved
1753
+ : viewerStyles.reviewAnchorUnknown, title: anchorHealth === 'moved'
1754
+ ? 'The quoted text still exists, but its saved location or context changed.'
1755
+ : anchorHealth === 'unresolved'
1756
+ ? 'This anchor no longer resolves in the saved document.'
1757
+ : 'There is not enough saved context to verify this anchor.', children: anchorHealth === 'moved'
1758
+ ? 'Moved'
1759
+ : anchorHealth === 'unresolved'
1760
+ ? 'Unresolved'
1761
+ : 'Unknown' }))] })), _jsx("div", { className: viewerStyles.reviewCommentBody, children: isEditingComment ? (_jsxs("div", { className: viewerStyles.reviewCommentEditor, children: [_jsx("textarea", { className: `tf-field-shell ${viewerStyles.reviewCommentEditInput}`, value: editingCommentDraft, onChange: (event) => setEditingCommentDraft(event.target.value), disabled: reviewBusy, "aria-label": "Edit comment text" }), _jsx("button", { type: "button", className: "tf-button-primary tf-button-compact", onClick: () => { void handleSaveEditedComment(); }, disabled: reviewBusy || !editingCommentDraft.trim(), children: "Save comment" })] })) : (_jsx(Markdown, { variant: "conversation", taskReferences: taskReferences, children: comment.body })) }), !isReply && (_jsxs("div", { className: viewerStyles.reviewThreadActions, children: [canReply && (_jsxs("button", { ref: (element) => {
1762
+ if (element)
1763
+ reviewReplyTriggerRefs.current.set(comment.id, element);
1764
+ else
1765
+ reviewReplyTriggerRefs.current.delete(comment.id);
1766
+ }, type: "button", className: "tf-button-ghost tf-button-compact", onClick: () => {
1767
+ reviewReplyReturnFocusIdRef.current = comment.id;
1768
+ setReplyingToCommentId(comment.id);
1769
+ setReplyDraft('');
1770
+ }, disabled: reviewBusy, children: [_jsx(Reply, { size: 13 }), "Reply"] })), canResolve && (_jsxs("button", { type: "button", className: "tf-button-ghost tf-button-compact", onClick: () => { void handleUpdateThreadStatus(comment.id, 'resolved'); }, disabled: reviewBusy, children: [_jsx(CheckCircle, { size: 13 }), "Resolve"] })), canReopen && (_jsxs("button", { type: "button", className: "tf-button-ghost tf-button-compact", onClick: () => { void handleUpdateThreadStatus(comment.id, 'open'); }, disabled: reviewBusy, children: [_jsx(RotateCcw, { size: 13 }), "Reopen"] }))] }))] }, comment.id));
1771
+ };
1192
1772
  const persistContent = useCallback(async (nextContent) => {
1193
1773
  if (!isEditable)
1194
1774
  return false;
1195
1775
  setSaveStatus({ type: 'saving' });
1196
1776
  try {
1197
- const res = await fetchTaskforceApi('/api/taskforce/documents/save', {
1777
+ const res = await fetchTaskforceApi(withWorkspaceQuery('/api/taskforce/documents/save', workspaceId), {
1198
1778
  method: 'POST',
1199
1779
  credentials: 'include',
1200
1780
  headers: { 'Content-Type': 'application/json' },
@@ -1214,7 +1794,7 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
1214
1794
  setSaveStatus({ type: 'error', message: e?.message || 'Save failed' });
1215
1795
  return false;
1216
1796
  }
1217
- }, [apiBaseUrl, doc.fsPath, onSaved, isEditable]);
1797
+ }, [apiBaseUrl, doc.fsPath, onSaved, isEditable, workspaceId]);
1218
1798
  const handleToggleTaskCheckbox = useCallback((checkboxIndex, nextChecked) => {
1219
1799
  const currentSource = editMode ? draft : (content ?? '');
1220
1800
  const nextSource = toggleNthTaskCheckbox(currentSource, checkboxIndex, nextChecked);
@@ -1252,7 +1832,7 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
1252
1832
  });
1253
1833
  };
1254
1834
  const markdownComponents = {
1255
- input({ type, checked, ...props }) {
1835
+ input({ type, checked, node: _node, ...props }) {
1256
1836
  if (type !== 'checkbox')
1257
1837
  return _jsx("input", { type: type, checked: checked, ...props });
1258
1838
  checkboxRenderIndex += 1;
@@ -1261,15 +1841,15 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
1261
1841
  },
1262
1842
  ul({ children, node, ...props }) {
1263
1843
  const taskList = nodeHasTaskItems(node);
1264
- return (_jsx("ul", { ...props, style: taskList ? { paddingLeft: '1.25em' } : undefined, "data-task-list": taskList ? 'true' : undefined, children: children }));
1844
+ return (_jsx("ul", { ...props, "data-task-list": taskList ? 'true' : undefined, children: children }));
1265
1845
  },
1266
1846
  ol({ children, node, ...props }) {
1267
1847
  const taskList = nodeHasTaskItems(node);
1268
- return (_jsx("ol", { ...props, style: taskList ? { paddingLeft: '1.25em' } : undefined, "data-task-list": taskList ? 'true' : undefined, children: children }));
1848
+ return (_jsx("ol", { ...props, "data-task-list": taskList ? 'true' : undefined, children: children }));
1269
1849
  },
1270
1850
  li({ children, node, ...props }) {
1271
1851
  const taskItem = typeof node?.checked === 'boolean' || nodeHasCheckboxInput(node);
1272
- return (_jsx("li", { ...props, style: taskItem ? { listStyleType: 'none', listStyle: 'none', marginLeft: 0 } : undefined, "data-task-item": taskItem ? 'true' : undefined, children: children }));
1852
+ return (_jsx("li", { ...props, "data-task-item": taskItem ? 'true' : undefined, children: children }));
1273
1853
  }
1274
1854
  };
1275
1855
  return (_jsxs("div", { className: `${viewerStyles.viewer} ${editMode ? viewerStyles.viewerEditMode : ''} ${monochromeMode ? viewerStyles.viewerMonochrome : ''}`, children: [_jsxs("div", { className: viewerStyles.meta, children: [_jsxs("div", { className: viewerStyles.metaLeft, children: [_jsxs("span", { className: `${viewerStyles.typeBadge} ${DOC_TYPE_BADGE_CLASS[doc.docType] ?? ''}`, children: [_jsx(Tag, { size: 10 }), DOC_TYPE_LABELS[doc.docType]] }), renaming ? (_jsx("div", { className: viewerStyles.metaRenameRow, children: _jsx("input", { ref: renameInputRef, type: "text", className: styles.input, value: renameValue, onChange: (e) => setRenameValue(e.target.value), onBlur: () => { void handleRename(); }, onKeyDown: handleRenameKeyDown }) })) : (_jsx("span", { className: viewerStyles.metaDocumentName, title: readableName, onDoubleClick: () => {
@@ -1277,34 +1857,75 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
1277
1857
  return;
1278
1858
  setRenameValue(readableName);
1279
1859
  setRenaming(true);
1280
- }, children: readableName })), taskTitle && (_jsx("span", { className: viewerStyles.metaTaskName, title: `From task: ${taskTitle}`, children: taskTitle })), attachmentState === 'unattached' && (_jsx("span", { className: viewerStyles.statusBadge, children: "Unattached" })), doc.updatedAt && (_jsxs("span", { className: viewerStyles.metaDate, title: formatDate(doc.updatedAt), children: [_jsx(Clock, { size: 11 }), formatDate(doc.updatedAt)] })), _jsxs("span", { className: viewerStyles.metaSize, children: [_jsx(HardDrive, { size: 11 }), formatBytes(doc.sizeBytes)] }), documentReferenceLabel && (_jsx(ReferenceBadgeButton, { label: documentReferenceLabel, copied: copiedReference, onClick: () => { void handleCopyReference(); }, title: "Copy document reference" })), saveStatus.type === 'saved' && (_jsxs("span", { className: `${viewerStyles.saveStatus} ${viewerStyles.saveStatusSaved}`, children: [_jsx(CheckCircle, { size: 11 }), "Saved"] })), saveStatus.type === 'error' && (_jsxs("span", { className: `${viewerStyles.saveStatus} ${viewerStyles.saveStatusError}`, title: saveStatus.message, children: [_jsx(AlertCircle, { size: 11 }), saveStatus.message || 'Save failed'] })), isDirty && saveStatus.type !== 'saving' && (_jsx("span", { className: viewerStyles.unsaved, children: "Unsaved changes" }))] }), _jsx("div", { className: viewerStyles.actions, children: editMode ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: viewerStyles.layoutToggle, children: [_jsx("button", { className: `${viewerStyles.layoutBtn} ${layout === 'editor' ? viewerStyles.layoutBtnActive : ''}`, onClick: () => setLayout('editor'), title: "Editor only", children: _jsx(Pencil, { size: 12 }) }), _jsx("button", { className: `${viewerStyles.layoutBtn} ${layout === 'split' ? viewerStyles.layoutBtnActive : ''}`, onClick: () => setLayout('split'), title: "Split view", children: _jsx(SplitSquareHorizontal, { size: 12 }) }), _jsx("button", { className: `${viewerStyles.layoutBtn} ${layout === 'preview' ? viewerStyles.layoutBtnActive : ''}`, onClick: () => setLayout('preview'), title: "Preview only", children: _jsx(Eye, { size: 12 }) })] }), _jsxs("button", { className: viewerStyles.actionBtn, onClick: handleCancelEdit, title: "Discard changes", children: [_jsx(X, { size: 13 }), "Cancel"] }), _jsxs("button", { className: `${viewerStyles.actionBtn} ${viewerStyles.saveBtn}`, onClick: handleSave, disabled: saveStatus.type === 'saving' || !isDirty, title: "Save (Ctrl+S)", children: [_jsx(Save, { size: 13 }), saveStatus.type === 'saving' ? 'Saving…' : 'Save'] })] })) : (_jsxs(_Fragment, { children: [doc.taskId && onBackToTask && (_jsxs("button", { className: viewerStyles.actionBtn, onClick: () => onBackToTask(doc.taskId), title: "Back to task", "aria-label": "Back to task", children: [_jsx(ArrowLeft, { size: 13 }), "Back to task"] })), doc.assetId && (_jsxs("button", { className: viewerStyles.actionBtn, onClick: () => setRenaming((prev) => !prev), title: "Rename document", children: [_jsx(Pencil, { size: 13 }), renaming ? 'Close Rename' : 'Rename'] })), isEditable && (_jsxs("button", { className: `${viewerStyles.actionBtn} ${viewerStyles.editBtn}`, onClick: handleEnterEdit, title: "Edit document", children: [_jsx(Pencil, { size: 13 }), "Edit"] })), doc.assetId && (_jsxs("button", { className: viewerStyles.actionBtn, onClick: handleOpenAttachModal, title: "Attach document to a task", children: [_jsx(Link, { size: 13 }), "Attach"] })), _jsxs("button", { className: viewerStyles.actionBtn, onClick: handleToggleReviewSidebar, title: showReviewSidebar ? 'Hide review and comments' : 'Show review and comments', children: [_jsx(MessageSquareText, { size: 13 }), showReviewSidebar ? 'Hide Review' : 'Show Review'] }), _jsxs("button", { className: viewerStyles.actionBtn, onClick: handleCopyLink, title: "Copy link", children: [_jsx(Link, { size: 13 }), copied ? 'Copied!' : 'Copy link'] }), _jsxs("button", { className: viewerStyles.actionBtn, onClick: handleDownload, title: "Download .md", children: [_jsx(Download, { size: 13 }), "Download"] }), _jsxs("button", { className: viewerStyles.actionBtn, onClick: handlePrint, title: "Print", children: [_jsx(Printer, { size: 13 }), "Print"] }), _jsxs("button", { className: viewerStyles.actionBtn, onClick: () => setMonochromeMode((prev) => !prev), title: "Toggle black and white style", children: [_jsx(Eye, { size: 13 }), monochromeMode ? 'Color' : 'B/W'] }), enableTaskGeneration && doc.docType === 'implementation-plan' && !editMode && (_jsxs("button", { className: `${viewerStyles.actionBtn} ${viewerStyles.generateBtn}`, onClick: () => setShowGenModal(true), title: "Generate tasks from this plan", children: [_jsx(Zap, { size: 13 }), "Generate Tasks"] })), canDelete && (_jsxs("button", { className: `${viewerStyles.actionBtn} ${viewerStyles.dangerBtn}`, onClick: () => { void handleDelete(); }, disabled: deleting, title: attachmentState === 'attached'
1860
+ }, children: readableName })), taskTitle && (_jsx("span", { className: viewerStyles.metaTaskName, title: `From task: ${taskTitle}`, children: taskTitle })), attachmentState === 'unattached' && (_jsx("span", { className: viewerStyles.statusBadge, children: "Unattached" })), doc.updatedAt && (_jsxs("span", { className: viewerStyles.metaDate, title: formatDate(doc.updatedAt), children: [_jsx(Clock, { size: 11 }), formatDate(doc.updatedAt)] })), _jsxs("span", { className: viewerStyles.metaSize, children: [_jsx(HardDrive, { size: 11 }), formatBytes(doc.sizeBytes)] }), documentReferenceLabel && (_jsx(ReferenceBadgeButton, { label: documentReferenceLabel, copied: copiedReference, onClick: () => { void handleCopyReference(); }, title: readableName })), saveStatus.type === 'saved' && (_jsxs("span", { className: `${viewerStyles.saveStatus} ${viewerStyles.saveStatusSaved}`, children: [_jsx(CheckCircle, { size: 11 }), "Saved"] })), saveStatus.type === 'error' && (_jsxs("span", { className: `${viewerStyles.saveStatus} ${viewerStyles.saveStatusError}`, title: saveStatus.message, children: [_jsx(AlertCircle, { size: 11 }), saveStatus.message || 'Save failed'] })), isDirty && saveStatus.type !== 'saving' && (_jsx("span", { className: viewerStyles.unsaved, children: "Unsaved changes" }))] }), _jsx("div", { className: viewerStyles.actions, children: editMode ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: viewerStyles.layoutToggle, children: [_jsx("button", { className: `${viewerStyles.layoutBtn} ${layout === 'editor' ? viewerStyles.layoutBtnActive : ''}`, onClick: () => setLayout('editor'), title: "Editor only", children: _jsx(Pencil, { size: 12 }) }), _jsx("button", { className: `${viewerStyles.layoutBtn} ${layout === 'split' ? viewerStyles.layoutBtnActive : ''}`, onClick: () => setLayout('split'), title: "Split view", children: _jsx(SplitSquareHorizontal, { size: 12 }) }), _jsx("button", { className: `${viewerStyles.layoutBtn} ${layout === 'preview' ? viewerStyles.layoutBtnActive : ''}`, onClick: () => setLayout('preview'), title: "Preview only", children: _jsx(Eye, { size: 12 }) })] }), _jsxs("button", { ref: reviewToggleButtonRef, className: viewerStyles.actionBtn, onClick: handleToggleReviewSidebar, title: showReviewSidebar ? 'Hide review and comments' : 'Show review and comments', children: [_jsx(MessageSquareText, { size: 13 }), showReviewSidebar ? 'Hide Review' : 'Show Review'] }), _jsxs("button", { className: viewerStyles.actionBtn, onClick: handleCancelEdit, title: "Discard changes", children: [_jsx(X, { size: 13 }), "Cancel"] }), _jsxs("button", { className: `${viewerStyles.actionBtn} ${viewerStyles.saveBtn}`, onClick: handleSave, disabled: saveStatus.type === 'saving' || !isDirty || revisionConflict, title: "Save (Ctrl+S)", children: [_jsx(Save, { size: 13 }), saveStatus.type === 'saving' ? 'Saving…' : 'Save'] })] })) : (_jsxs(_Fragment, { children: [doc.taskId && onBackToTask && (_jsxs("button", { className: viewerStyles.actionBtn, onClick: () => onBackToTask(doc.taskId), title: "Back to task", "aria-label": "Back to task", children: [_jsx(ArrowLeft, { size: 13 }), "Back to task"] })), doc.assetId && (_jsxs("button", { className: viewerStyles.actionBtn, onClick: () => setRenaming((prev) => !prev), title: "Rename document", children: [_jsx(Pencil, { size: 13 }), renaming ? 'Close Rename' : 'Rename'] })), isEditable && (_jsxs("button", { className: `${viewerStyles.actionBtn} ${viewerStyles.editBtn}`, onClick: handleEnterEdit, title: "Edit document", children: [_jsx(Pencil, { size: 13 }), "Edit"] })), doc.assetId && (_jsxs("button", { className: viewerStyles.actionBtn, onClick: handleOpenAttachModal, title: "Attach document to a task", children: [_jsx(Link, { size: 13 }), "Attach"] })), _jsxs("button", { ref: reviewToggleButtonRef, className: viewerStyles.actionBtn, onClick: handleToggleReviewSidebar, title: showReviewSidebar ? 'Hide review and comments' : 'Show review and comments', children: [_jsx(MessageSquareText, { size: 13 }), showReviewSidebar ? 'Hide Review' : 'Show Review'] }), _jsxs("button", { className: viewerStyles.actionBtn, onClick: handleCopyLink, title: "Copy link", children: [_jsx(Link, { size: 13 }), copied ? 'Copied!' : 'Copy link'] }), _jsxs("button", { className: viewerStyles.actionBtn, onClick: handleDownload, title: "Download .md", children: [_jsx(Download, { size: 13 }), "Download"] }), _jsxs("button", { className: viewerStyles.actionBtn, onClick: handlePrint, title: "Print document. In the print dialog, disable headers and footers for the cleanest output.", children: [_jsx(Printer, { size: 13 }), "Print"] }), _jsxs("button", { className: viewerStyles.actionBtn, onClick: () => setMonochromeMode((prev) => !prev), title: "Toggle black and white style", children: [_jsx(Eye, { size: 13 }), monochromeMode ? 'Color' : 'B/W'] }), enableTaskGeneration && doc.docType === 'implementation-plan' && !editMode && (_jsxs("button", { className: `${viewerStyles.actionBtn} ${viewerStyles.generateBtn}`, onClick: () => setShowGenModal(true), title: "Generate tasks from this plan", children: [_jsx(Zap, { size: 13 }), "Generate Tasks"] })), canDelete && (_jsxs("button", { className: `${viewerStyles.actionBtn} ${viewerStyles.dangerBtn}`, onClick: () => { void handleDelete(); }, disabled: deleting, title: attachmentState === 'attached'
1281
1861
  ? 'Remove this document from linked tasks and delete it'
1282
1862
  : 'Permanently delete this unattached document', children: [_jsx(Trash2, { size: 13 }), deleting
1283
1863
  ? 'Deleting…'
1284
1864
  : attachmentState === 'attached'
1285
1865
  ? 'Delete & Unlink'
1286
- : 'Delete Permanently'] }))] })) })] }), loadingContent && (_jsx("div", { className: viewerStyles.viewerState, children: "Loading\u2026" })), !loadingContent && loadError && (_jsx("div", { className: viewerStyles.viewerStateError, children: loadError })), !loadingContent && !loadError && (editMode ? (_jsxs("div", { className: `${viewerStyles.editorArea} ${EDITOR_LAYOUT_CLASS[layout]}`, children: [(layout === 'editor' || layout === 'split') && (_jsxs("div", { className: viewerStyles.editorPane, children: [_jsx("div", { className: viewerStyles.editorPaneLabel, children: "Markdown" }), _jsx("textarea", { ref: textareaRef, className: `${viewerStyles.editorTextarea} tf-scrollbar`, value: draft, onScroll: () => syncPaneScroll('editor'), onChange: e => {
1287
- setDraft(e.target.value);
1288
- setSaveStatus(prev => prev.type === 'saving' ? prev : { type: 'idle' });
1289
- }, spellCheck: true, placeholder: "Write markdown here\u2026" })] })), (layout === 'preview' || layout === 'split') && (_jsxs("div", { className: viewerStyles.previewPane, children: [_jsx("div", { className: viewerStyles.editorPaneLabel, children: "Preview" }), _jsx("div", { ref: previewScrollRef, className: `${styles.docMarkdown} ${viewerStyles.markdownSurface}`, "data-testid": "doc-preview-scroll", onScroll: () => syncPaneScroll('preview'), children: _jsx(Markdown, { remarkPlugins: [remarkGfm], rehypePlugins: [rehypeSanitize], components: markdownComponents, children: previewContent }) })] }))] })) : (_jsxs("div", { className: `${viewerStyles.viewerBody} ${!showReviewSidebar ? viewerStyles.viewerBodyFullWidth : ''}`, children: [_jsx("div", { className: `${viewerStyles.viewerContent} ${viewerStyles.viewerMain} tf-scrollbar`, children: _jsx("div", { ref: markdownContainerRef, className: `${styles.docMarkdown} ${viewerStyles.markdownSurface}`, onMouseUp: showReviewSidebar ? handleCaptureReviewAnchor : undefined, children: _jsx(Markdown, { remarkPlugins: [remarkGfm], rehypePlugins: [rehypeSanitize], components: markdownComponents, children: previewContent }) }) }), showReviewSidebar && (_jsx("aside", { className: viewerStyles.reviewRail, children: _jsxs("section", { className: viewerStyles.reviewSection, "aria-label": "Review and comments", children: [_jsxs("div", { className: viewerStyles.reviewHeader, children: [_jsxs("div", { children: [_jsxs("div", { className: viewerStyles.reviewTitle, children: [_jsx(MessageSquareText, { size: 14 }), "Review & Comments"] }), _jsx("p", { className: viewerStyles.reviewSubtitle, children: "Comments stay attached to this document review session." })] }), _jsxs("div", { className: viewerStyles.reviewControls, children: [reviewSessions.length > 1 && (_jsx("select", { className: `${styles.select} ${viewerStyles.reviewSelect}`, value: activeReviewSession?.id || '', onChange: (event) => setSelectedReviewSessionId(event.target.value || null), "aria-label": "Select review session", children: reviewSessions.map((session) => (_jsx("option", { value: session.id, children: session.title?.trim() || 'Untitled review' }, session.id))) })), _jsxs("button", { type: "button", className: viewerStyles.actionBtn, onClick: () => { void createReviewSession(); }, disabled: reviewBusy || !doc.assetId, children: [_jsx(MessageSquareText, { size: 13 }), "Start Review"] }), activeReviewSession && (_jsxs("button", { type: "button", className: viewerStyles.actionBtn, onClick: () => { void handleToggleReviewStatus(); }, disabled: reviewBusy, children: [activeReviewSession.status === 'resolved' ? _jsx(RotateCcw, { size: 13 }) : _jsx(CheckCheck, { size: 13 }), activeReviewSession.status === 'resolved' ? 'Reopen' : 'Resolve'] }))] })] }), activeReviewSession && (_jsxs("div", { className: viewerStyles.reviewSessionMeta, children: [_jsx("span", { className: `${viewerStyles.statusBadge} ${activeReviewSession.status === 'resolved' ? viewerStyles.reviewStatusResolved : ''}`, children: activeReviewSession.status === 'resolved' ? 'Resolved' : 'Open' }), editingReviewTitle ? (_jsxs("div", { className: viewerStyles.reviewTitleEditRow, children: [_jsx("input", { type: "text", className: styles.input, value: reviewTitleDraft, onChange: (event) => setReviewTitleDraft(event.target.value), placeholder: "Untitled review" }), _jsx("button", { type: "button", className: styles.secondaryHeaderBtn, onClick: () => { void handleSaveReviewTitle(); }, disabled: reviewBusy, children: "Save Title" })] })) : (_jsx("span", { className: viewerStyles.reviewSessionLabel, children: activeReviewSession.title?.trim() || 'Untitled review' })), _jsxs("span", { className: viewerStyles.reviewSessionTimestamp, children: ["Updated ", formatReviewTimestamp(activeReviewSession.updatedAt)] }), !editingReviewTitle && (_jsxs("button", { type: "button", className: viewerStyles.actionBtn, onClick: () => setEditingReviewTitle(true), disabled: reviewBusy, children: [_jsx(Pencil, { size: 13 }), "Rename Review"] }))] })), reviewError && (_jsx("div", { className: viewerStyles.viewerStateError, children: reviewError })), _jsxs("div", { className: taskFormStyles.commentPanel, children: [_jsxs("div", { className: taskFormStyles.commentThread, children: [loadingReviews && (_jsx("div", { className: taskFormStyles.emptyComments, children: "Loading review comments\u2026" })), !loadingReviews && !activeReviewSession && (_jsx("div", { className: taskFormStyles.emptyComments, children: "Start a review to collect comments for this document." })), !loadingReviews && activeReviewSession && activeReviewSession.comments.length === 0 && (_jsx("div", { className: taskFormStyles.emptyComments, children: "No comments yet. Add the first review note for this document." })), !loadingReviews && activeReviewSession && activeReviewSession.comments.map((comment) => {
1290
- const isAi = comment.authorActor?.kind === 'ai';
1291
- const anchorLabel = formatReviewAnchor(comment.anchor);
1292
- const ActorIcon = isAi ? Bot : User;
1293
- const isEditingComment = editingCommentId === comment.id;
1294
- return (_jsxs("div", { className: `${taskFormStyles.comment} ${isAi ? taskFormStyles.commentAi : taskFormStyles.commentUser}`, children: [_jsxs("div", { className: taskFormStyles.commentHeader, children: [_jsxs("span", { className: taskFormStyles.commentAuthor, style: comment.authorActor?.color ? { color: comment.authorActor.color } : undefined, children: [_jsx(ActorIcon, { size: 12, strokeWidth: 1.5 }), getReviewActorLabel(comment)] }), _jsx("span", { className: taskFormStyles.commentTime, children: formatReviewTimestamp(comment.updatedAt) }), _jsxs("span", { className: viewerStyles.reviewCommentActions, children: [!isEditingComment && (_jsx("button", { type: "button", className: viewerStyles.reviewCommentAction, onClick: () => handleStartEditingComment(comment.id, comment.body), disabled: reviewBusy, children: "Edit" })), isEditingComment && (_jsx("button", { type: "button", className: viewerStyles.reviewCommentAction, onClick: () => {
1295
- setEditingCommentId(null);
1296
- setEditingCommentDraft('');
1297
- }, disabled: reviewBusy, children: "Cancel" })), _jsx("button", { type: "button", className: viewerStyles.reviewCommentAction, onClick: () => { void handleDeleteReviewComment(comment.id); }, disabled: reviewBusy, children: "Delete" })] })] }), anchorLabel && (_jsx("span", { className: viewerStyles.reviewAnchorLabel, children: anchorLabel })), _jsx("div", { className: taskFormStyles.commentText, children: isEditingComment ? (_jsxs("div", { className: viewerStyles.reviewCommentEditor, children: [_jsx("textarea", { className: taskFormStyles.commentInput, value: editingCommentDraft, onChange: (event) => setEditingCommentDraft(event.target.value), disabled: reviewBusy }), _jsx("button", { type: "button", className: styles.secondaryHeaderBtn, onClick: () => { void handleSaveEditedComment(); }, disabled: reviewBusy || !editingCommentDraft.trim(), children: "Save Comment" })] })) : (_jsx(Markdown, { remarkPlugins: [remarkGfm], rehypePlugins: [rehypeSanitize], children: comment.body })) })] }, comment.id));
1298
- }), _jsx("div", { ref: reviewThreadEndRef })] }), _jsxs("div", { className: taskFormStyles.commentInputArea, children: [_jsxs("div", { className: viewerStyles.reviewComposer, children: [pendingReviewAnchor && (_jsxs("div", { className: viewerStyles.reviewAnchorChip, children: [_jsx("span", { children: formatReviewAnchor(pendingReviewAnchor) || 'Selected text' }), 'quote' in pendingReviewAnchor && pendingReviewAnchor.quote && (_jsxs("span", { className: viewerStyles.reviewAnchorSnippet, children: ["\"", pendingReviewAnchor.quote, "\""] })), _jsx("button", { type: "button", className: viewerStyles.reviewAnchorClear, onClick: () => setPendingReviewAnchor(null), children: "Clear" })] })), _jsx("textarea", { className: taskFormStyles.commentInput, placeholder: activeReviewSession?.status === 'resolved'
1299
- ? 'Reopen this review to add more comments…'
1300
- : pendingReviewAnchor
1301
- ? 'Add a comment for the selected text…'
1302
- : 'Add a comment for this document review…', value: reviewDraft, onChange: (event) => setReviewDraft(event.target.value), disabled: reviewBusy || activeReviewSession?.status === 'resolved', onKeyDown: (event) => {
1866
+ : 'Delete Permanently'] }))] })) })] }), loadingContent && (_jsx("div", { className: viewerStyles.viewerState, children: "Loading\u2026" })), !loadingContent && loadError && (_jsx("div", { className: viewerStyles.viewerStateError, children: loadError })), !loadingContent && !loadError && (_jsxs("div", { className: `${viewerStyles.viewerBody} ${!showReviewSidebar ? viewerStyles.viewerBodyFullWidth : ''}`, children: [editMode ? (_jsxs("div", { className: `${viewerStyles.editorArea} ${viewerStyles.viewerMain} ${EDITOR_LAYOUT_CLASS[layout]}`, children: [(layout === 'editor' || layout === 'split') && (_jsxs("div", { className: viewerStyles.editorPane, children: [_jsx("div", { className: viewerStyles.editorPaneLabel, children: "Markdown" }), _jsx("textarea", { ref: textareaRef, className: `${viewerStyles.editorTextarea} tf-scrollbar`, value: draft, onScroll: () => syncPaneScroll('editor'), onChange: e => {
1867
+ setDraft(e.target.value);
1868
+ setSaveStatus(prev => prev.type === 'saving' ? prev : { type: 'idle' });
1869
+ }, spellCheck: true, placeholder: "Write markdown here\u2026" })] })), (layout === 'preview' || layout === 'split') && (_jsxs("div", { className: viewerStyles.previewPane, children: [_jsx("div", { className: viewerStyles.editorPaneLabel, children: "Preview" }), _jsx("div", { ref: previewScrollRef, className: `${styles.docMarkdown} ${viewerStyles.markdownSurface}`, "data-testid": "doc-preview-scroll", onScroll: () => syncPaneScroll('preview'), children: _jsx(Markdown, { variant: "document", taskReferences: taskReferences, documentOverrides: markdownComponents, children: previewContent }) })] }))] })) : (_jsx("div", { ref: viewerScrollRef, className: `${viewerStyles.viewerContent} ${viewerStyles.viewerMain} tf-scrollbar`, "data-testid": "doc-viewer-scroll", onScroll: (event) => reportScrollTopChange(event.currentTarget.scrollTop), children: _jsx("div", { ref: markdownContainerRef, className: `${styles.docMarkdown} ${viewerStyles.markdownSurface} ${viewerStyles.readerSurface}`, "data-testid": "doc-reader-surface", onMouseUp: showReviewSidebar ? handleCaptureReviewAnchor : undefined, onKeyUp: showReviewSidebar ? handleCaptureReviewAnchor : undefined, children: _jsx(Markdown, { variant: "document", taskReferences: taskReferences, documentOverrides: markdownComponents, children: previewContent }) }) })), showReviewSidebar && (_jsx("aside", { ref: reviewRailRef, className: viewerStyles.reviewRail, role: compactReviewViewport ? 'dialog' : undefined, "aria-modal": compactReviewViewport ? true : undefined, "aria-label": compactReviewViewport ? 'Review and comments' : undefined, children: _jsxs("section", { className: viewerStyles.reviewSection, "aria-label": "Review and comments", children: [_jsxs("div", { className: viewerStyles.reviewHeader, children: [_jsxs("div", { className: viewerStyles.reviewHeaderTop, children: [_jsx("span", { className: viewerStyles.reviewEyebrow, children: "Review" }), _jsxs("div", { className: viewerStyles.reviewHeaderActions, children: [activeReviewSession && (_jsx("span", { className: activeReviewSession.status === 'resolved' ? 'tf-chip-success' : 'tf-chip-warning', role: "status", "aria-live": "polite", children: activeReviewSession.status === 'resolved' ? 'Resolved' : 'Open' })), _jsx("button", { ref: reviewCloseButtonRef, type: "button", className: `tf-control-icon ${viewerStyles.reviewCloseButton}`, onClick: closeReviewSidebar, "aria-label": "Close review", title: "Close review", children: _jsx(X, { size: 15 }) })] })] }), activeReviewSession ? (_jsxs(_Fragment, { children: [editingReviewTitle ? (_jsxs("div", { className: viewerStyles.reviewTitleEditRow, children: [_jsx("input", { type: "text", className: `tf-field-shell ${viewerStyles.reviewTitleInput}`, value: reviewTitleDraft, onChange: (event) => setReviewTitleDraft(event.target.value), onKeyDown: (event) => {
1870
+ if (event.key !== 'Escape')
1871
+ return;
1872
+ event.preventDefault();
1873
+ event.stopPropagation();
1874
+ cancelReviewTitleEdit();
1875
+ }, placeholder: "Untitled review", "aria-label": "Review title", autoFocus: true }), _jsx("button", { type: "button", className: "tf-button-primary tf-button-compact", onClick: () => { void handleSaveReviewTitle(); }, disabled: reviewBusy, children: "Save" }), _jsx("button", { type: "button", className: "tf-button-ghost tf-button-compact", onClick: cancelReviewTitleEdit, disabled: reviewBusy, children: "Cancel" })] })) : (_jsx("h2", { className: viewerStyles.reviewSessionTitle, children: activeReviewSession.title?.trim() || 'Untitled review' })), _jsxs("div", { className: viewerStyles.reviewMetadataRow, children: [_jsxs("div", { className: viewerStyles.reviewMetadata, children: [_jsxs("div", { className: viewerStyles.reviewSessionDetails, children: [_jsxs("span", { children: [activeReviewThreadCount, ' ', activeReviewThreadCount === 1 ? 'thread' : 'threads', activeReviewSession.status === 'open' && activeReviewUnresolvedThreadCount > 0
1876
+ ? ` · ${activeReviewUnresolvedThreadCount} open`
1877
+ : ''] }), _jsx("span", { "aria-hidden": "true", children: "\u00B7" }), _jsxs("span", { children: ["Updated ", formatReviewTimestamp(activeReviewSession.updatedAt)] })] }), (activeReviewSession.documentVersion || currentDocumentVersion) && (_jsxs("div", { className: viewerStyles.reviewVersionDetails, children: [_jsxs("span", { children: ["Review ", activeReviewSession.documentVersion
1878
+ ? `v${activeReviewSession.documentVersion}`
1879
+ : 'version unknown'] }), _jsx("span", { "aria-hidden": "true", children: "\u00B7" }), _jsxs("span", { children: ["Document ", currentDocumentVersion
1880
+ ? `v${currentDocumentVersion}`
1881
+ : 'version unknown'] })] }))] }), _jsx("button", { ref: reviewRenameButtonRef, type: "button", className: "tf-control-icon tf-control-icon-compact", onClick: () => setEditingReviewTitle(true), disabled: reviewBusy, "aria-label": "Rename review", title: "Rename review", children: _jsx(Pencil, { size: 13 }) })] }), editMode && (_jsx("div", { className: viewerStyles.reviewDraftNotice, role: "status", children: isDirty
1882
+ ? 'Comments reference the saved document. Unsaved edits are not part of this review.'
1883
+ : 'Comments reference the saved document while you edit.' })), !editMode
1884
+ && activeReviewSession.documentVersion
1885
+ && currentDocumentVersion
1886
+ && activeReviewSession.documentVersion !== currentDocumentVersion && (_jsxs("div", { className: viewerStyles.reviewVersionNotice, role: "status", children: [_jsx(AlertCircle, { size: 13, "aria-hidden": "true" }), _jsxs("span", { children: ["Review covers document v", activeReviewSession.documentVersion, "; current document is v", currentDocumentVersion, "."] })] }))] })) : (_jsxs("div", { children: [_jsx("h2", { className: viewerStyles.reviewEmptyHeading, children: "No active review" }), _jsx("p", { className: viewerStyles.reviewSubtitle, children: "Start a review to collect feedback on this document." })] })), _jsxs("div", { className: viewerStyles.reviewControls, role: "group", "aria-label": "Review controls", children: [_jsxs("select", { className: `tf-field-shell ${viewerStyles.reviewSelect}`, value: activeReviewSession?.id || '', onChange: (event) => selectReviewSession(event.target.value || null), disabled: reviewBusy || reviewSessions.length === 0, "aria-label": "Select review session", children: [reviewSessions.length === 0 && _jsx("option", { value: "", children: "No review" }), reviewSessions.map((session) => (_jsx("option", { value: session.id, children: session.title?.trim() || 'Untitled review' }, session.id)))] }), _jsx("button", { type: "button", className: `tf-control-icon ${viewerStyles.reviewCreateButton}`, onClick: () => { void createReviewSession(); }, disabled: reviewBusy || !doc.assetId, "aria-label": "New review", title: "New Review", children: _jsx(Plus, { size: 15 }) }), activeReviewSession && (_jsxs("button", { type: "button", className: `tf-button-secondary tf-button-compact ${viewerStyles.reviewResolutionAction}`, onClick: () => {
1887
+ if (reviewResolutionBlocked)
1888
+ return;
1889
+ void handleToggleReviewStatus();
1890
+ }, disabled: reviewBusy, "aria-disabled": reviewResolutionBlocked || undefined, "aria-label": reviewResolutionBlocked
1891
+ ? `Resolve review unavailable: resolve ${activeReviewUnresolvedThreadCount} open thread${activeReviewUnresolvedThreadCount === 1 ? '' : 's'} first`
1892
+ : activeReviewSession.status === 'resolved'
1893
+ ? 'Reopen review'
1894
+ : 'Resolve review', title: reviewResolutionBlocked
1895
+ ? `Resolve ${activeReviewUnresolvedThreadCount} open thread${activeReviewUnresolvedThreadCount === 1 ? '' : 's'} first`
1896
+ : activeReviewSession.status === 'resolved'
1897
+ ? 'Reopen review'
1898
+ : 'Resolve review', children: [activeReviewSession.status === 'resolved'
1899
+ ? _jsx(RotateCcw, { size: 13 })
1900
+ : _jsx(CheckCircle, { size: 13 }), activeReviewSession.status === 'resolved'
1901
+ ? 'Reopen'
1902
+ : 'Resolve'] }))] })] }), reviewError && (_jsx("div", { className: viewerStyles.viewerStateError, children: reviewError })), _jsxs("div", { className: viewerStyles.reviewWorkspace, children: [_jsxs("div", { ref: reviewThreadRef, className: `${viewerStyles.reviewThread} tf-scrollbar`, "data-testid": "review-thread", onScroll: handleReviewThreadScroll, children: [loadingReviews && (_jsx("div", { className: viewerStyles.reviewEmptyState, children: "Loading review comments\u2026" })), !loadingReviews && !activeReviewSession && (_jsxs("div", { className: viewerStyles.reviewEmptyState, children: [_jsx(MessageSquareText, { size: 20 }), _jsx("span", { children: "Start a review to collect comments for this document." })] })), !loadingReviews && activeReviewSession && activeReviewSession.comments.length === 0 && (_jsxs("div", { className: viewerStyles.reviewEmptyState, children: [_jsx(MessageSquareText, { size: 20 }), _jsx("span", { children: "No comments yet. Add the first review note." })] })), !loadingReviews && activeReviewSession && activeReviewSession.comments
1903
+ .filter((comment) => !comment.parentCommentId)
1904
+ .map((rootComment) => {
1905
+ const replies = activeReviewSession.comments
1906
+ .filter((comment) => comment.parentCommentId === rootComment.id);
1907
+ return (_jsxs("section", { className: viewerStyles.reviewCommentThread, children: [renderReviewComment(rootComment), replies.length > 0 && (_jsx("div", { className: viewerStyles.reviewReplies, children: replies.map((reply) => renderReviewComment(reply, true)) })), replyingToCommentId === rootComment.id && (_jsxs("div", { className: viewerStyles.reviewReplyComposer, onKeyDown: (event) => {
1908
+ if (event.key !== 'Escape')
1909
+ return;
1910
+ event.preventDefault();
1911
+ event.stopPropagation();
1912
+ closeReviewReplyComposer();
1913
+ }, children: [_jsx("textarea", { ref: reviewReplyInputRef, className: `tf-field-shell ${viewerStyles.reviewReplyInput}`, value: replyDraft, onChange: (event) => setReplyDraft(event.target.value), placeholder: "Write a reply\u2026", disabled: reviewBusy, "aria-label": "Reply text", onKeyDown: (event) => {
1914
+ if (event.key === 'Enter' && !event.shiftKey) {
1915
+ event.preventDefault();
1916
+ void handleAddReviewReply(rootComment.id);
1917
+ }
1918
+ } }), _jsxs("div", { className: viewerStyles.reviewReplyComposerActions, children: [_jsx("button", { type: "button", className: "tf-button-ghost tf-button-compact", onClick: closeReviewReplyComposer, disabled: reviewBusy, children: "Cancel" }), _jsx("button", { type: "button", className: "tf-button-primary tf-button-compact", onClick: () => { void handleAddReviewReply(rootComment.id); }, disabled: reviewBusy || !replyDraft.trim(), children: "Reply" })] })] }))] }, rootComment.id));
1919
+ }), _jsx("div", { ref: reviewThreadEndRef })] }), hasNewReviewComments && activeReviewSession && (_jsx("div", { className: viewerStyles.reviewNewCommentsBar, "aria-live": "polite", children: _jsxs("button", { type: "button", className: "tf-button-secondary tf-button-compact", onClick: () => scrollReviewToLatest(), children: [_jsx(ArrowDown, { size: 13 }), "New comments"] }) })), activeReviewSession?.status === 'resolved' ? (_jsxs("div", { className: viewerStyles.reviewResolvedComposer, children: [_jsx("span", { className: viewerStyles.reviewResolvedIcon, "aria-hidden": "true", children: _jsx(CheckCircle, { size: 16 }) }), _jsxs("div", { className: viewerStyles.reviewResolvedCopy, children: [_jsx("strong", { children: "Review resolved" }), _jsx("span", { children: "Reopen it to add more comments." })] })] })) : (_jsxs("div", { className: viewerStyles.reviewComposerArea, children: [pendingReviewAnchor && (_jsxs("div", { className: viewerStyles.reviewAnchorChip, children: [_jsx("span", { children: pendingReviewAnchor.kind === 'quote'
1920
+ ? 'Selected text'
1921
+ : formatReviewAnchor(pendingReviewAnchor) || 'Selected text' }), 'quote' in pendingReviewAnchor && pendingReviewAnchor.quote && (_jsxs("span", { className: viewerStyles.reviewAnchorSnippet, children: ["\"", pendingReviewAnchor.quote, "\""] })), _jsx("button", { type: "button", className: viewerStyles.reviewAnchorClear, onClick: () => setPendingReviewAnchor(null), "aria-label": "Clear selected text", children: "Clear" })] })), _jsxs("div", { className: viewerStyles.reviewComposerRow, children: [_jsx("textarea", { className: `tf-field-shell ${viewerStyles.reviewComposerInput}`, placeholder: pendingReviewAnchor
1922
+ ? 'Add a comment for the selected text…'
1923
+ : 'Add a comment for this document review…', value: reviewDraft, onChange: (event) => setReviewDraft(event.target.value), disabled: reviewBusy, onKeyDown: (event) => {
1303
1924
  if (event.key === 'Enter' && !event.shiftKey) {
1304
1925
  event.preventDefault();
1305
1926
  void handleAddReviewComment();
1306
1927
  }
1307
- } })] }), _jsx("button", { type: "button", className: taskFormStyles.sendCommentBtn, onClick: () => { void handleAddReviewComment(); }, disabled: reviewBusy || !reviewDraft.trim() || activeReviewSession?.status === 'resolved', "aria-label": "Send review comment", title: "Send review comment", children: _jsx(Send, { size: 15 }) })] })] })] }) }))] }))), enableTaskGeneration && showGenModal && content !== null && (_jsx(DocumentGenerateModal, { content: content, docTitle: doc.title, apiBaseUrl: apiBaseUrl, onClose: () => setShowGenModal(false), onGenerated: (_count) => setShowGenModal(false) })), _jsx(Modal, { isOpen: attachModalOpen, onClose: () => {
1928
+ } }), _jsx("button", { type: "button", className: `tf-button-primary ${viewerStyles.reviewSendButton}`, onClick: () => { void handleAddReviewComment(); }, disabled: reviewBusy || !reviewDraft.trim(), "aria-label": "Send review comment", title: "Send review comment", children: _jsx(Send, { size: 15 }) })] }), _jsx("span", { className: viewerStyles.reviewComposerHint, children: "Enter to send \u00B7 Shift + Enter for a new line" })] }))] })] }) }))] })), enableTaskGeneration && showGenModal && content !== null && (_jsx(DocumentGenerateModal, { content: content, docTitle: doc.title, apiBaseUrl: apiBaseUrl, onClose: () => setShowGenModal(false), onGenerated: (_count) => setShowGenModal(false) })), _jsx(Modal, { isOpen: attachModalOpen, onClose: () => {
1308
1929
  if (attachingTaskId)
1309
1930
  return;
1310
1931
  setAttachModalOpen(false);
@@ -1312,5 +1933,5 @@ export function DocumentViewer({ doc, taskTitle, tasks = [], apiBaseUrl = '', on
1312
1933
  const isCurrentPrimaryAttachment = doc.taskId === task.id;
1313
1934
  const isBusy = attachingTaskId === task.id;
1314
1935
  return (_jsxs("button", { type: "button", className: viewerStyles.attachTaskRow, disabled: isBusy, onClick: () => { void handleAttachToTask(task.id); }, children: [_jsxs("span", { className: viewerStyles.attachTaskInfo, children: [_jsx("span", { className: viewerStyles.attachTaskTitle, children: task.title }), task.referenceLabel && (_jsx("span", { className: viewerStyles.attachTaskReference, children: task.referenceLabel }))] }), _jsx("span", { className: viewerStyles.attachTaskMeta, children: isBusy ? 'Attaching…' : isCurrentPrimaryAttachment ? 'Attached' : 'Attach' })] }, task.id));
1315
- })) })] }) }), !editMode && (_jsx("div", { className: viewerStyles.printHint, children: "For the cleanest output, disable browser Headers and footers in the print dialog." }))] }));
1936
+ })) })] }) })] }));
1316
1937
  }