@taskforcehq/taskforce 0.3.305 → 0.3.307

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (440) hide show
  1. package/README.md +0 -2
  2. package/dist/Taskforce.module.css +603 -107
  3. package/dist/TaskforceCore.js +216 -43
  4. package/dist/TaskforceCore.test.js +611 -28
  5. package/dist/assets/fonts/CourierPrime-Bold.woff2 +0 -0
  6. package/dist/assets/fonts/CourierPrime-BoldItalic.woff2 +0 -0
  7. package/dist/assets/fonts/CourierPrime-Italic.woff2 +0 -0
  8. package/dist/assets/fonts/CourierPrime-Regular.woff2 +0 -0
  9. package/dist/assets/fonts/Noir_medium.woff2 +0 -0
  10. package/dist/assets/fonts/Noir_regular.woff2 +0 -0
  11. package/dist/assets/fonts/RussoOne-Regular.woff2 +0 -0
  12. package/dist/assets/fonts/SpecialElite-Regular.woff2 +0 -0
  13. package/dist/compat/workspaceSyncCompat.js +46 -2
  14. package/dist/compat/workspaceSyncCompat.test.js +38 -1
  15. package/dist/components/activity/EntityActivityTimeline.d.ts +34 -0
  16. package/dist/components/activity/EntityActivityTimeline.js +81 -0
  17. package/dist/components/context/ContextAttachmentManager.d.ts +14 -0
  18. package/dist/components/context/ContextAttachmentManager.js +561 -0
  19. package/dist/components/features/AgentsModule.d.ts +14 -1
  20. package/dist/components/features/AgentsModule.js +366 -18
  21. package/dist/components/features/AgentsModule.test.js +507 -8
  22. package/dist/components/features/AnnotatedAttachmentWorkspace.d.ts +3 -1
  23. package/dist/components/features/AnnotatedAttachmentWorkspace.js +118 -4
  24. package/dist/components/features/AnnotatedAttachmentWorkspace.test.js +52 -0
  25. package/dist/components/features/DocumentIndex.d.ts +2 -2
  26. package/dist/components/features/DocumentIndex.js +3 -4
  27. package/dist/components/features/DocumentViewer.d.ts +7 -1
  28. package/dist/components/features/DocumentViewer.js +62 -4
  29. package/dist/components/features/DocumentWorkspace.d.ts +10 -2
  30. package/dist/components/features/DocumentWorkspace.js +15 -4
  31. package/dist/components/features/DocumentWorkspace.test.js +51 -1
  32. package/dist/components/features/TaskSettings.d.ts +2 -0
  33. package/dist/components/features/TaskSettings.js +83 -78
  34. package/dist/components/features/TaskSettings.test.js +171 -82
  35. package/dist/components/features/documentWorkspaceModel.d.ts +1 -1
  36. package/dist/components/task/TaskActionHeader.js +11 -5
  37. package/dist/components/task/TaskActionHeader.test.js +10 -0
  38. package/dist/components/task/TaskCard.js +24 -29
  39. package/dist/components/task/TaskCard.test.js +38 -3
  40. package/dist/components/task/TaskContextUpload.js +4 -526
  41. package/dist/components/task/TaskContextUpload.test.js +3 -3
  42. package/dist/components/task/TaskForm.js +61 -116
  43. package/dist/components/task/TaskForm.test.js +110 -8
  44. package/dist/components/task/TaskKanban.d.ts +2 -1
  45. package/dist/components/task/TaskKanban.js +94 -21
  46. package/dist/components/task/TaskKanban.test.js +36 -0
  47. package/dist/components/task/TaskList.js +5 -1
  48. package/dist/components/task/TaskList.test.js +4 -0
  49. package/dist/components/ui/EditableAvatarButton.d.ts +18 -0
  50. package/dist/components/ui/EditableAvatarButton.js +18 -0
  51. package/dist/components/ui/HierarchyActionBadge.d.ts +10 -0
  52. package/dist/components/ui/HierarchyActionBadge.js +5 -0
  53. package/dist/components/views/AppShellHeader.d.ts +3 -1
  54. package/dist/components/views/AppShellHeader.js +27 -11
  55. package/dist/components/views/AppShellHeader.test.js +18 -1
  56. package/dist/components/views/PlanComparisonPage.d.ts +9 -1
  57. package/dist/components/views/PlanComparisonPage.js +78 -14
  58. package/dist/components/views/PlanComparisonPage.test.js +257 -0
  59. package/dist/components/views/PlansPage.js +127 -36
  60. package/dist/components/views/PlansPage.test.js +294 -12
  61. package/dist/components/views/StandaloneLayout.js +529 -592
  62. package/dist/components/views/WidgetView.js +10 -8
  63. package/dist/components/views/panels/PlanningDrawer.d.ts +25 -5
  64. package/dist/components/views/panels/PlanningDrawer.js +270 -55
  65. package/dist/components/views/panels/PlanningDrawer.test.d.ts +1 -0
  66. package/dist/components/views/panels/PlanningDrawer.test.js +529 -0
  67. package/dist/components/views/planningScope.d.ts +20 -0
  68. package/dist/components/views/planningScope.js +25 -0
  69. package/dist/components/views/planningScope.test.d.ts +1 -0
  70. package/dist/components/views/planningScope.test.js +60 -0
  71. package/dist/components/views/standalone/modals/AccountHubModal.d.ts +26 -1
  72. package/dist/components/views/standalone/modals/AccountHubModal.js +76 -2
  73. package/dist/components/views/standalone/modals/AccountHubModal.test.js +20 -3
  74. package/dist/components/views/standalone/modals/AvatarImageManagerModal.d.ts +20 -0
  75. package/dist/components/views/standalone/modals/AvatarImageManagerModal.js +127 -0
  76. package/dist/components/views/standalone/modals/EditProfileModal.d.ts +2 -9
  77. package/dist/components/views/standalone/modals/EditProfileModal.js +3 -2
  78. package/dist/components/views/standalone/modals/SyncEnableWarningModal.d.ts +9 -0
  79. package/dist/components/views/standalone/modals/SyncEnableWarningModal.js +6 -0
  80. package/dist/components/views/standalone/modals/SyncEnableWarningModal.test.d.ts +1 -0
  81. package/dist/components/views/standalone/modals/SyncEnableWarningModal.test.js +24 -0
  82. package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +2 -1
  83. package/dist/components/views/standalone/modals/SyncStatusModal.js +2 -2
  84. package/dist/config/envSchema.js +1 -0
  85. package/dist/core/AiProfileService.d.ts +46 -2
  86. package/dist/core/AiProfileService.js +1073 -82
  87. package/dist/core/AiProfileService.test.js +19 -1
  88. package/dist/core/AiProfiles.test.js +1249 -44
  89. package/dist/core/AttachmentLinkService.d.ts +3 -0
  90. package/dist/core/AttachmentLinkService.js +110 -23
  91. package/dist/core/AuthIdentityService.d.ts +107 -0
  92. package/dist/core/AuthIdentityService.js +284 -0
  93. package/dist/core/AuthTokenService.d.ts +4 -0
  94. package/dist/core/AuthTokenService.js +34 -6
  95. package/dist/core/AuthTokenService.test.js +3 -3
  96. package/dist/core/EntitlementsPolicy.test.js +2 -2
  97. package/dist/core/GlobalSettingsService.js +127 -6
  98. package/dist/core/McpTokenService.d.ts +12 -0
  99. package/dist/core/McpTokenService.js +44 -1
  100. package/dist/core/PlanEntitlementService.d.ts +23 -2
  101. package/dist/core/PlanEntitlementService.js +343 -57
  102. package/dist/core/PlanFeatureCatalog.test.d.ts +1 -0
  103. package/dist/core/PlanFeatureCatalog.test.js +84 -0
  104. package/dist/core/PlanVersionPolicy.test.js +35 -2
  105. package/dist/core/PlanningEntities.test.js +418 -4
  106. package/dist/core/SignupMonetizationSettings.test.js +199 -27
  107. package/dist/core/SyncReconciliationService.js +2 -65
  108. package/dist/core/SystemAdmin.test.js +42 -42
  109. package/dist/core/TaskActivityService.d.ts +28 -1
  110. package/dist/core/TaskActivityService.js +227 -46
  111. package/dist/core/TaskActivitySync.test.d.ts +1 -0
  112. package/dist/core/TaskActivitySync.test.js +90 -0
  113. package/dist/core/TaskAttachmentsCanonical.test.js +51 -1
  114. package/dist/core/TaskAuditTimeline.test.js +96 -0
  115. package/dist/core/Taskforce.d.ts +415 -40
  116. package/dist/core/Taskforce.ids.test.js +58 -0
  117. package/dist/core/Taskforce.js +1543 -266
  118. package/dist/core/Taskforce.listTasksSlim.test.d.ts +1 -0
  119. package/dist/core/Taskforce.listTasksSlim.test.js +91 -0
  120. package/dist/core/Taskforce.mcpAuth.test.js +109 -0
  121. package/dist/core/UserProfileAvatarDrafts.test.js +30 -3
  122. package/dist/core/WorkspaceLifecycleService.js +0 -5
  123. package/dist/core/WorkspacePermissions.test.js +25 -1
  124. package/dist/core/WorkspacePlanMode.test.js +117 -16
  125. package/dist/core/shared.d.ts +1 -1
  126. package/dist/core/shared.js +5 -1
  127. package/dist/core/types.d.ts +75 -2
  128. package/dist/hooks/auth/useTaskforceAuthBootstrap.js +28 -2
  129. package/dist/hooks/bootstrapTimeouts.d.ts +4 -0
  130. package/dist/hooks/bootstrapTimeouts.js +8 -0
  131. package/dist/hooks/bootstrapTimeouts.test.d.ts +1 -0
  132. package/dist/hooks/bootstrapTimeouts.test.js +12 -0
  133. package/dist/hooks/sync/bootstrap.js +2 -0
  134. package/dist/hooks/sync/controlPlane.d.ts +37 -0
  135. package/dist/hooks/sync/controlPlane.js +78 -0
  136. package/dist/hooks/sync/controlPlane.test.d.ts +1 -0
  137. package/dist/hooks/sync/controlPlane.test.js +121 -0
  138. package/dist/hooks/sync/lifecyclePolicy.d.ts +45 -0
  139. package/dist/hooks/sync/lifecyclePolicy.js +93 -0
  140. package/dist/hooks/sync/lifecyclePolicy.test.d.ts +1 -0
  141. package/dist/hooks/sync/lifecyclePolicy.test.js +124 -0
  142. package/dist/hooks/sync/orchestratorShared.d.ts +13 -4
  143. package/dist/hooks/sync/orchestratorShared.js +129 -48
  144. package/dist/hooks/sync/orchestratorShared.test.js +50 -1
  145. package/dist/hooks/sync/pullLifecycle.d.ts +31 -0
  146. package/dist/hooks/sync/pullLifecycle.js +24 -0
  147. package/dist/hooks/sync/pullLifecycle.test.d.ts +1 -0
  148. package/dist/hooks/sync/pullLifecycle.test.js +80 -0
  149. package/dist/hooks/sync/recovery.d.ts +16 -2
  150. package/dist/hooks/sync/recovery.js +179 -53
  151. package/dist/hooks/sync/recovery.test.d.ts +1 -0
  152. package/dist/hooks/sync/recovery.test.js +292 -0
  153. package/dist/hooks/sync/transfers.d.ts +16 -3
  154. package/dist/hooks/sync/transfers.js +210 -66
  155. package/dist/hooks/sync/transfers.test.d.ts +1 -0
  156. package/dist/hooks/sync/transfers.test.js +928 -0
  157. package/dist/hooks/sync/useRecentSyncEvents.d.ts +21 -0
  158. package/dist/hooks/sync/useRecentSyncEvents.js +92 -0
  159. package/dist/hooks/sync/useRecentSyncEvents.test.d.ts +1 -0
  160. package/dist/hooks/sync/useRecentSyncEvents.test.js +124 -0
  161. package/dist/hooks/sync/useSyncStatusActions.d.ts +30 -0
  162. package/dist/hooks/sync/useSyncStatusActions.js +88 -0
  163. package/dist/hooks/sync/useSyncStatusActions.test.d.ts +1 -0
  164. package/dist/hooks/sync/useSyncStatusActions.test.js +133 -0
  165. package/dist/hooks/sync/useSyncStatusControls.d.ts +25 -0
  166. package/dist/hooks/sync/useSyncStatusControls.js +60 -0
  167. package/dist/hooks/sync/useSyncStatusControls.test.d.ts +1 -0
  168. package/dist/hooks/sync/useSyncStatusControls.test.js +88 -0
  169. package/dist/hooks/useFilterSort.js +13 -13
  170. package/dist/hooks/useFilterSort.test.js +87 -1
  171. package/dist/hooks/useSyncOrchestrator.aiProfiles.test.js +12 -0
  172. package/dist/hooks/useSyncOrchestrator.d.ts +9 -2
  173. package/dist/hooks/useSyncOrchestrator.js +409 -183
  174. package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +407 -0
  175. package/dist/hooks/useTaskData.js +8 -3
  176. package/dist/hooks/useTaskData.test.js +45 -0
  177. package/dist/hooks/useTaskforce.d.ts +145 -52
  178. package/dist/hooks/useTaskforce.js +592 -253
  179. package/dist/hooks/useTaskforce.runtime-routing.test.d.ts +1 -0
  180. package/dist/hooks/useTaskforce.runtime-routing.test.js +246 -0
  181. package/dist/hooks/useTaskforce.sync-behavior.test.js +2468 -201
  182. package/dist/hooks/useWorkspaceSyncController.d.ts +1 -0
  183. package/dist/hooks/useWorkspaceSyncController.js +13 -2
  184. package/dist/hooks/useWorkspaceSyncController.test.js +48 -0
  185. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.d.ts +16 -0
  186. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +328 -40
  187. package/dist/localization/locales/en-US.d.ts +0 -1
  188. package/dist/localization/locales/en-US.js +0 -1
  189. package/dist/localization/locales/es-419.js +0 -1
  190. package/dist/localization/locales/pt-BR.js +0 -1
  191. package/dist/mcp/canonicalAssetHelpers.d.ts +16 -4
  192. package/dist/mcp/canonicalAssetHelpers.js +18 -10
  193. package/dist/mcp/canonicalAssetHelpers.test.d.ts +1 -0
  194. package/dist/mcp/canonicalAssetHelpers.test.js +67 -0
  195. package/dist/mcp/clientIntegrations.d.ts +1 -0
  196. package/dist/mcp/clientIntegrations.js +25 -0
  197. package/dist/mcp/clientIntegrations.test.js +14 -3
  198. package/dist/mcp/clientProfileDefaults.js +3 -3
  199. package/dist/mcp/collaborationRegistrar.js +7 -7
  200. package/dist/mcp/documentAssetRegistrar.js +116 -10
  201. package/dist/mcp/runtime.d.ts +3 -0
  202. package/dist/mcp/runtime.js +1099 -185
  203. package/dist/mcp/runtime.test.js +1491 -140
  204. package/dist/mcp/taskAttachmentTypes.d.ts +1 -1
  205. package/dist/mcp/taskPlanningRegistrar.js +48 -0
  206. package/dist/mcp/toolRegistry.d.ts +56 -0
  207. package/dist/mcp/toolRegistry.js +8 -0
  208. package/dist/mcp/toolRegistry.test.js +4 -0
  209. package/dist/migrations/taskSchemaMigrations.d.ts +1 -1
  210. package/dist/migrations/taskSchemaMigrations.js +192 -61
  211. package/dist/migrations/taskSchemaMigrations.test.js +15 -0
  212. package/dist/resources/templates/workflow-sources/workflowDocs.mjs +6 -6
  213. package/dist/resources/templates/workflows/collaborate.yaml +1 -1
  214. package/dist/resources/templates/workflows/evaluate.yaml +2 -2
  215. package/dist/resources/templates/workflows/plan.yaml +1 -1
  216. package/dist/resources/templates/workflows/review.yaml +2 -2
  217. package/dist/server/aiProfileAvatarAssets.d.ts +49 -0
  218. package/dist/server/aiProfileAvatarAssets.js +319 -0
  219. package/dist/server/aiProfileAvatarAssets.test.d.ts +1 -0
  220. package/dist/server/aiProfileAvatarAssets.test.js +213 -0
  221. package/dist/server/annotatedAttachmentsRoutes.test.js +69 -10
  222. package/dist/server/auth/providers/apple.d.ts +33 -0
  223. package/dist/server/auth/providers/apple.js +82 -0
  224. package/dist/server/auth/providers/appleClientSecret.d.ts +37 -0
  225. package/dist/server/auth/providers/appleClientSecret.js +65 -0
  226. package/dist/server/auth/providers/github.d.ts +26 -0
  227. package/dist/server/auth/providers/github.js +86 -0
  228. package/dist/server/auth/providers/google.d.ts +21 -0
  229. package/dist/server/auth/providers/google.js +56 -0
  230. package/dist/server/auth/providers/types.d.ts +21 -0
  231. package/dist/server/auth/providers/types.js +1 -0
  232. package/dist/server/auth.d.ts +2 -0
  233. package/dist/server/auth.js +6 -3
  234. package/dist/server/documentReviewRoutes.test.js +36 -3
  235. package/dist/server/index.cookieProxy.test.js +1 -0
  236. package/dist/server/index.d.ts +12 -0
  237. package/dist/server/index.js +124 -9
  238. package/dist/server/index.rateLimit.test.js +3 -0
  239. package/dist/server/index.test.js +111 -3
  240. package/dist/server/routes/admin.d.ts +3 -0
  241. package/dist/server/routes/admin.js +459 -28
  242. package/dist/server/routes/annotatedAttachments.js +51 -0
  243. package/dist/server/routes/auth.d.ts +26 -2
  244. package/dist/server/routes/auth.js +1170 -71
  245. package/dist/server/routes/authSupport.d.ts +5 -1
  246. package/dist/server/routes/authSupport.js +13 -2
  247. package/dist/server/routes/billing.js +372 -35
  248. package/dist/server/routes/billing.test.js +595 -12
  249. package/dist/server/routes/documents.d.ts +1 -0
  250. package/dist/server/routes/documents.js +182 -70
  251. package/dist/server/routes/shared.d.ts +28 -2
  252. package/dist/server/routes/shared.js +69 -14
  253. package/dist/server/routes/sync.integration.test.js +658 -39
  254. package/dist/server/routes/sync.js +74 -608
  255. package/dist/server/routes/syncAuxRoutes.d.ts +15 -0
  256. package/dist/server/routes/syncAuxRoutes.js +91 -0
  257. package/dist/server/routes/syncAuxRoutes.test.d.ts +1 -0
  258. package/dist/server/routes/syncAuxRoutes.test.js +158 -0
  259. package/dist/server/routes/syncPullApplyRoutes.d.ts +36 -0
  260. package/dist/server/routes/syncPullApplyRoutes.js +204 -0
  261. package/dist/server/routes/syncPushRoutes.d.ts +24 -0
  262. package/dist/server/routes/syncPushRoutes.js +212 -0
  263. package/dist/server/routes/syncRouteGuards.d.ts +36 -0
  264. package/dist/server/routes/syncRouteGuards.js +67 -0
  265. package/dist/server/routes/syncRouteGuards.test.d.ts +1 -0
  266. package/dist/server/routes/syncRouteGuards.test.js +94 -0
  267. package/dist/server/routes/syncRouteTypes.d.ts +13 -0
  268. package/dist/server/routes/syncRouteTypes.js +1 -0
  269. package/dist/server/routes/syncSnapshotRoutes.d.ts +66 -0
  270. package/dist/server/routes/syncSnapshotRoutes.js +182 -0
  271. package/dist/server/routes/tasks.js +55 -10
  272. package/dist/server/routes/workspaces.js +36 -5
  273. package/dist/server/routes.js +147 -11
  274. package/dist/server/routes.test.js +2704 -183
  275. package/dist/services/workflowExportSnapshots.test.js +2 -0
  276. package/dist/shared/aiProfileSeatScope.d.ts +5 -0
  277. package/dist/shared/aiProfileSeatScope.js +21 -0
  278. package/dist/shared/aiProfileSurfaceType.d.ts +1 -1
  279. package/dist/shared/aiProfileSurfaceType.js +10 -8
  280. package/dist/shared/passwordPolicy.d.ts +13 -0
  281. package/dist/shared/passwordPolicy.js +84 -0
  282. package/dist/shared/passwordPolicy.test.d.ts +1 -0
  283. package/dist/shared/passwordPolicy.test.js +34 -0
  284. package/dist/storage/objectStorage.d.ts +1 -0
  285. package/dist/storage/objectStorage.js +2 -1
  286. package/dist/storage/objectStorageClient.d.ts +1 -0
  287. package/dist/storage/objectStorageClient.js +41 -8
  288. package/dist/storage/objectStorageClient.test.js +26 -1
  289. package/dist/storage/objectStorageConfig.js +3 -1
  290. package/dist/storage/objectStorageConfig.test.js +13 -1
  291. package/dist/storage/workspaceAssetStore.d.ts +15 -3
  292. package/dist/storage/workspaceAssetStore.js +132 -44
  293. package/dist/storage/workspaceAssetStore.test.js +93 -6
  294. package/dist/styles/fonts.css +70 -0
  295. package/dist/sync/collaborationSyncPayload.d.ts +6 -1
  296. package/dist/sync/collaborationSyncPayload.js +19 -11
  297. package/dist/sync/collaborationSyncPayload.test.js +14 -1
  298. package/dist/sync/collaborationSyncState.d.ts +3 -3
  299. package/dist/sync/collaborationSyncState.js +19 -12
  300. package/dist/sync/contentSyncPayload.d.ts +5 -1
  301. package/dist/sync/contentSyncPayload.js +9 -0
  302. package/dist/sync/contentSyncPayload.test.js +39 -0
  303. package/dist/sync/contentSyncState.d.ts +9 -9
  304. package/dist/sync/contentSyncState.js +248 -107
  305. package/dist/sync/planningSyncPayload.js +5 -0
  306. package/dist/sync/planningSyncPayload.test.js +24 -0
  307. package/dist/sync/syncApplyHandlers.d.ts +11 -4
  308. package/dist/sync/syncApplyHandlers.js +115 -42
  309. package/dist/sync/syncApplyHandlers.test.js +251 -4
  310. package/dist/sync/syncFieldSemantics.d.ts +12 -0
  311. package/dist/sync/syncFieldSemantics.js +55 -0
  312. package/dist/sync/syncResourceAdapters.d.ts +46 -0
  313. package/dist/sync/syncResourceAdapters.js +79 -0
  314. package/dist/sync/syncService.d.ts +6 -0
  315. package/dist/sync/syncService.js +65 -1
  316. package/dist/sync/syncService.test.js +96 -3
  317. package/dist/sync/taskSyncChangeKey.d.ts +2 -0
  318. package/dist/sync/taskSyncChangeKey.js +143 -0
  319. package/dist/sync/taskSyncPayload.js +3 -8
  320. package/dist/sync/workspacePullFeed.d.ts +4 -0
  321. package/dist/sync/workspacePullFeed.js +132 -72
  322. package/dist/sync/workspacePullFeed.test.js +92 -0
  323. package/dist/sync/workspaceRepair.js +5 -2
  324. package/dist/sync/workspaceSyncModel.d.ts +73 -6
  325. package/dist/sync/workspaceSyncModel.js +342 -73
  326. package/dist/sync/workspaceSyncModel.test.js +559 -14
  327. package/dist/sync/workspaceSyncState.d.ts +17 -0
  328. package/dist/sync/workspaceSyncState.js +2 -1
  329. package/dist/sync/workspaceSyncSurface.js +3 -8
  330. package/dist/types.d.ts +50 -2
  331. package/dist/ui/assets/AgentsModule-2y82_3DO.js +1 -0
  332. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BTLZZCiQ.js +3 -0
  333. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BVKew-mH.css +1 -0
  334. package/dist/ui/assets/ContextAttachmentManager-D2epuNnG.js +3 -0
  335. package/dist/ui/assets/CourierPrime-Bold-BuLj_dpw.woff2 +0 -0
  336. package/dist/ui/assets/CourierPrime-BoldItalic-BrK2pUkZ.woff2 +0 -0
  337. package/dist/ui/assets/CourierPrime-Italic-DFUZK5Ey.woff2 +0 -0
  338. package/dist/ui/assets/CourierPrime-Regular-BsKphzVf.woff2 +0 -0
  339. package/dist/ui/assets/DocumentWorkspace-D4rJKXzd.css +1 -0
  340. package/dist/ui/assets/DocumentWorkspace-sVa-3Do6.js +252 -0
  341. package/dist/ui/assets/EntityActivityTimeline-DyqvvhuF.css +1 -0
  342. package/dist/ui/assets/EntityActivityTimeline-Zods27y_.js +1 -0
  343. package/dist/ui/assets/{InitiativesModule-Dhm7M8e7.js → InitiativesModule-D4XseTwW.js} +1 -1
  344. package/dist/ui/assets/Noir_medium-bxQwKGzB.woff2 +0 -0
  345. package/dist/ui/assets/Noir_regular-ojf2kxlG.woff2 +0 -0
  346. package/dist/ui/assets/PlansPage-D5AcbO0L.js +1 -0
  347. package/dist/ui/assets/PlansPage-Dvqsz5zc.css +1 -0
  348. package/dist/ui/assets/RussoOne-Regular-Cu_qq_qC.woff2 +0 -0
  349. package/dist/ui/assets/SpecialElite-Regular-Di6gSvAS.woff2 +0 -0
  350. package/dist/ui/assets/TaskContextUpload-uC5qx4Bv.js +1 -0
  351. package/dist/ui/assets/TaskSettings-CqvPAsTv.js +9 -0
  352. package/dist/ui/assets/{WorkflowsModule-BcS4afRn.js → WorkflowsModule-oOA9bcdK.js} +4 -4
  353. package/dist/ui/assets/documentReferences-DPZuTgHh.js +1 -0
  354. package/dist/ui/assets/index-607WPo_X.js +4 -0
  355. package/dist/ui/assets/index-CYyodXsg.css +1 -0
  356. package/dist/ui/assets/{vendor-icons-BSUaRwF8.js → vendor-icons-B32hGuF2.js} +1 -1
  357. package/dist/ui/fonts/CourierPrime-Bold.ttf +0 -0
  358. package/dist/ui/fonts/CourierPrime-Bold.woff2 +0 -0
  359. package/dist/ui/fonts/CourierPrime-BoldItalic.ttf +0 -0
  360. package/dist/ui/fonts/CourierPrime-BoldItalic.woff2 +0 -0
  361. package/dist/ui/fonts/CourierPrime-Italic.ttf +0 -0
  362. package/dist/ui/fonts/CourierPrime-Italic.woff2 +0 -0
  363. package/dist/ui/fonts/CourierPrime-Regular.ttf +0 -0
  364. package/dist/ui/fonts/CourierPrime-Regular.woff2 +0 -0
  365. package/dist/ui/fonts/Noir_medium.otf +0 -0
  366. package/dist/ui/fonts/Noir_medium.woff2 +0 -0
  367. package/dist/ui/fonts/Noir_regular.otf +0 -0
  368. package/dist/ui/fonts/Noir_regular.woff2 +0 -0
  369. package/dist/ui/fonts/RussoOne-Regular.woff2 +0 -0
  370. package/dist/ui/fonts/SpecialElite-Regular.ttf +0 -0
  371. package/dist/ui/fonts/SpecialElite-Regular.woff2 +0 -0
  372. package/dist/ui/index.html +3 -3
  373. package/dist/ui/product/agent manager.png +0 -0
  374. package/dist/ui/product/agent_manager_02.png +0 -0
  375. package/dist/utils/accountProfileSummaryCache.d.ts +5 -0
  376. package/dist/utils/aiProfileEvents.d.ts +7 -0
  377. package/dist/utils/aiProfileEvents.js +6 -0
  378. package/dist/utils/assignees.d.ts +8 -0
  379. package/dist/utils/assignees.js +10 -1
  380. package/dist/utils/assignees.test.d.ts +1 -0
  381. package/dist/utils/assignees.test.js +25 -0
  382. package/dist/utils/avatarDisplay.d.ts +1 -0
  383. package/dist/utils/avatarDisplay.js +15 -0
  384. package/dist/utils/avatarUpload.d.ts +27 -0
  385. package/dist/utils/avatarUpload.js +132 -0
  386. package/dist/utils/avatarUpload.test.d.ts +1 -0
  387. package/dist/utils/avatarUpload.test.js +40 -0
  388. package/dist/utils/bootstrapTrace.d.ts +7 -0
  389. package/dist/utils/bootstrapTrace.js +29 -0
  390. package/dist/utils/commercialLifecyclePresentation.js +3 -0
  391. package/dist/utils/contextAssetEvents.d.ts +2 -0
  392. package/dist/utils/contextFiles.d.ts +3 -1
  393. package/dist/utils/contextFiles.js +2 -1
  394. package/dist/utils/syncEventDetails.d.ts +3 -0
  395. package/dist/utils/syncEventDetails.js +64 -0
  396. package/dist/utils/syncEventDetails.test.d.ts +1 -0
  397. package/dist/utils/syncEventDetails.test.js +23 -0
  398. package/dist/utils/syncEventPresentation.d.ts +15 -0
  399. package/dist/utils/syncEventPresentation.js +129 -0
  400. package/dist/utils/syncEventPresentation.test.d.ts +1 -0
  401. package/dist/utils/syncEventPresentation.test.js +64 -0
  402. package/dist/utils/syncStatusPresentation.d.ts +72 -0
  403. package/dist/utils/syncStatusPresentation.js +217 -0
  404. package/dist/utils/syncStatusPresentation.test.d.ts +1 -0
  405. package/dist/utils/syncStatusPresentation.test.js +164 -0
  406. package/dist/utils/taskActivity.d.ts +9 -1
  407. package/dist/utils/taskActivity.js +290 -22
  408. package/dist/utils/taskActivity.test.js +141 -8
  409. package/dist/utils/taskSearch.d.ts +22 -0
  410. package/dist/utils/taskSearch.js +87 -0
  411. package/dist/utils/taskSearch.test.d.ts +1 -0
  412. package/dist/utils/taskSearch.test.js +69 -0
  413. package/dist/utils/taskUtils.js +10 -3
  414. package/dist/utils/taskUtils.test.d.ts +1 -0
  415. package/dist/utils/taskUtils.test.js +19 -0
  416. package/dist/utils/workspaceSyncPresentation.d.ts +4 -0
  417. package/dist/utils/workspaceSyncPresentation.js +68 -2
  418. package/dist/utils/workspaceSyncPresentation.test.js +36 -1
  419. package/package.json +3 -2
  420. package/scripts/export-sqlite-to-postgres.mjs +7 -9
  421. package/scripts/run-e2e-realtime.sh +17 -3
  422. package/scripts/run-smoke.sh +17 -5
  423. package/scripts/run-soak.sh +17 -5
  424. package/src/resources/templates/workflow-sources/workflowDocs.mjs +6 -6
  425. package/src/resources/templates/workflows/collaborate.yaml +1 -1
  426. package/src/resources/templates/workflows/evaluate.yaml +2 -2
  427. package/src/resources/templates/workflows/plan.yaml +1 -1
  428. package/src/resources/templates/workflows/review.yaml +2 -2
  429. package/dist/ui/assets/AgentsModule-N2MnQBZk.js +0 -1
  430. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BG6P_GVW.js +0 -3
  431. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BaS2VwIr.css +0 -1
  432. package/dist/ui/assets/DocumentWorkspace-B3nV_Gc5.css +0 -1
  433. package/dist/ui/assets/DocumentWorkspace-DRbDMwh8.js +0 -252
  434. package/dist/ui/assets/PlansPage-C2dd2n1X.css +0 -1
  435. package/dist/ui/assets/PlansPage-Cq0zXj3I.js +0 -1
  436. package/dist/ui/assets/RussoOne-Regular-C3BxZIj7.ttf +0 -0
  437. package/dist/ui/assets/TaskSettings-ln0aF7xc.js +0 -9
  438. package/dist/ui/assets/index-C2-OXZV7.css +0 -1
  439. package/dist/ui/assets/index-DcSI5F86.js +0 -6
  440. package/scripts/migrate-planning-model.ts +0 -233
@@ -22,6 +22,12 @@ describe('planningSyncPayload', () => {
22
22
  createdAt: '2026-04-10T10:00:00.000Z',
23
23
  updatedAt: '2026-04-10T11:00:00.000Z',
24
24
  order: '2',
25
+ attachments: [{
26
+ path: 'workspaces/ws-1/assets/documents/asset-initiative.md',
27
+ assetId: 'asset-initiative',
28
+ referenceLabel: 'D-10',
29
+ caption: 'Launch plan',
30
+ }],
25
31
  isArchived: true,
26
32
  });
27
33
  expect(initiative).toEqual({
@@ -34,6 +40,12 @@ describe('planningSyncPayload', () => {
34
40
  createdAt: '2026-04-10T10:00:00.000Z',
35
41
  updatedAt: '2026-04-10T11:00:00.000Z',
36
42
  order: 2,
43
+ attachments: [{
44
+ path: 'workspaces/ws-1/assets/documents/asset-initiative.md',
45
+ assetId: 'asset-initiative',
46
+ referenceLabel: 'D-10',
47
+ caption: 'Launch plan',
48
+ }],
37
49
  isArchived: true,
38
50
  });
39
51
  });
@@ -49,6 +61,12 @@ describe('planningSyncPayload', () => {
49
61
  createdAt: '2026-04-10T10:00:00.000Z',
50
62
  updatedAt: '2026-04-10T11:00:00.000Z',
51
63
  order: '5',
64
+ attachments: [{
65
+ path: 'workspaces/ws-1/assets/documents/asset-workstream.md',
66
+ assetId: 'asset-workstream',
67
+ referenceLabel: 'D-11',
68
+ caption: 'Backend plan',
69
+ }],
52
70
  isArchived: false,
53
71
  });
54
72
  expect(workstream).toEqual({
@@ -62,6 +80,12 @@ describe('planningSyncPayload', () => {
62
80
  createdAt: '2026-04-10T10:00:00.000Z',
63
81
  updatedAt: '2026-04-10T11:00:00.000Z',
64
82
  order: 5,
83
+ attachments: [{
84
+ path: 'workspaces/ws-1/assets/documents/asset-workstream.md',
85
+ assetId: 'asset-workstream',
86
+ referenceLabel: 'D-11',
87
+ caption: 'Backend plan',
88
+ }],
65
89
  isArchived: false,
66
90
  });
67
91
  });
@@ -1,7 +1,8 @@
1
1
  import type { TaskforceCore, TaskforceSyncCapable } from '../core/Taskforce.js';
2
- import type { WorkspaceSyncAiProfileSnapshot, WorkspaceSyncAnnotatedAttachmentSessionSnapshot, WorkspaceSyncChange, WorkspaceSyncDocumentReviewCommentSnapshot, WorkspaceSyncDocumentReviewSessionSnapshot, WorkspaceSyncInitiativeSnapshot, WorkspaceSyncTaskEventSnapshot, WorkspaceSyncTaskSnapshot, WorkspaceSyncWorkspaceMemberSnapshot, WorkspaceSyncWorkstreamSnapshot } from './workspaceSyncModel.js';
2
+ import type { WorkspaceSyncAiProfileSnapshot, WorkspaceSyncAnnotatedAttachmentSessionSnapshot, WorkspaceSyncChange, WorkspaceSyncDocumentReviewCommentSnapshot, WorkspaceSyncDocumentReviewSessionSnapshot, WorkspaceSyncEntityEventSnapshot, WorkspaceSyncInitiativeSnapshot, WorkspaceSyncTaskSnapshot, WorkspaceSyncWorkspaceMemberSnapshot, WorkspaceSyncWorkstreamSnapshot } from './workspaceSyncModel.js';
3
3
  import type { BinaryAssetSyncPayload, DocumentSyncPayload } from './contentSyncPayload.js';
4
4
  import type { AiProfileSurfaceType } from '../shared/aiProfileSurfaceType.js';
5
+ import type { AiProfileSeatScope } from '../shared/aiProfileSeatScope.js';
5
6
  type SyncCore = TaskforceCore & TaskforceSyncCapable;
6
7
  type SyncRouteError = Error & {
7
8
  code?: string;
@@ -18,7 +19,12 @@ type NormalizeIncomingAiProfileSurfaceType = (value: unknown, context: {
18
19
  profileId?: string;
19
20
  workspaceId?: string;
20
21
  }) => AiProfileSurfaceType | null;
21
- type NormalizeTaskEventSyncPayload = (raw: unknown, workspaceId: string, sourceWatermark?: string) => WorkspaceSyncTaskEventSnapshot | null;
22
+ type NormalizeIncomingAiProfileSeatScope = (value: unknown, context: {
23
+ source: string;
24
+ profileId?: string;
25
+ workspaceId?: string;
26
+ }) => AiProfileSeatScope | null;
27
+ type NormalizeTaskEventSyncPayload = (raw: unknown, workspaceId: string, sourceWatermark?: string) => WorkspaceSyncEntityEventSnapshot | null;
22
28
  export interface WorkspaceSyncIncomingTaskMutation {
23
29
  archived: boolean;
24
30
  task: WorkspaceSyncTaskSnapshot;
@@ -54,7 +60,7 @@ export interface WorkspaceSyncIncomingApplyModel {
54
60
  incomingAnnotatedAttachmentSessionDeletes: Map<string, string>;
55
61
  };
56
62
  taskActivity: {
57
- incomingTaskEvents: Map<string, WorkspaceSyncTaskEventSnapshot>;
63
+ incomingTaskEvents: Map<string, WorkspaceSyncEntityEventSnapshot>;
58
64
  };
59
65
  }
60
66
  export interface PreparedWorkspaceTaskSyncSnapshot {
@@ -68,6 +74,7 @@ export declare function classifyWorkspaceSyncChanges(input: {
68
74
  normalizeWorkspaceSyncDocumentPath: (rawPath: unknown) => string | null;
69
75
  normalizeTaskAssetPath: (rawPath: unknown) => string | null;
70
76
  normalizeIncomingAiProfileSurfaceType: NormalizeIncomingAiProfileSurfaceType;
77
+ normalizeIncomingAiProfileSeatScope: NormalizeIncomingAiProfileSeatScope;
71
78
  normalizeTaskEventSyncPayload: NormalizeTaskEventSyncPayload;
72
79
  recordSyncDiagnostic: RecordSyncDiagnostic;
73
80
  }): WorkspaceSyncIncomingApplyModel;
@@ -162,7 +169,7 @@ export declare function applyCollaborationSyncChanges(input: {
162
169
  export declare function applyTaskActivitySyncChanges(input: {
163
170
  core: SyncCore;
164
171
  workspaceId: string;
165
- incomingTaskEvents: Map<string, WorkspaceSyncTaskEventSnapshot>;
172
+ incomingTaskEvents: Map<string, WorkspaceSyncEntityEventSnapshot>;
166
173
  recordSyncDiagnostic: RecordSyncDiagnostic;
167
174
  createSyncRouteError: CreateSyncRouteError;
168
175
  }): void;
@@ -83,7 +83,7 @@ function recordTaskReferenceNumberMismatch(input) {
83
83
  return true;
84
84
  }
85
85
  export function classifyWorkspaceSyncChanges(input) {
86
- const { workspaceId, incomingChanges, normalizeWorkspaceSyncDocumentPath, normalizeTaskAssetPath, normalizeIncomingAiProfileSurfaceType, normalizeTaskEventSyncPayload, recordSyncDiagnostic, } = input;
86
+ const { workspaceId, incomingChanges, normalizeWorkspaceSyncDocumentPath, normalizeTaskAssetPath, normalizeIncomingAiProfileSurfaceType, normalizeIncomingAiProfileSeatScope, normalizeTaskEventSyncPayload, recordSyncDiagnostic, } = input;
87
87
  const model = createIncomingApplyModel();
88
88
  for (const change of incomingChanges) {
89
89
  const raw = change;
@@ -111,7 +111,7 @@ export function classifyWorkspaceSyncChanges(input) {
111
111
  continue;
112
112
  }
113
113
  if (op === 'ai-profile-upsert') {
114
- const profile = normalizeAiProfileSyncPayload(raw.profile, workspaceId, normalizeIncomingAiProfileSurfaceType, 'apply.aiProfileUpsert');
114
+ const profile = normalizeAiProfileSyncPayload(raw.profile, workspaceId, normalizeIncomingAiProfileSurfaceType, normalizeIncomingAiProfileSeatScope, 'apply.aiProfileUpsert');
115
115
  const profileId = String(profile?.id || '').trim();
116
116
  if (profileId && profile) {
117
117
  const profileWorkspaceId = String(profile.workspaceId || '').trim();
@@ -194,7 +194,7 @@ export function classifyWorkspaceSyncChanges(input) {
194
194
  model.collaboration.incomingAnnotatedAttachmentSessionDeletes.set(deletedSession.id, deletedSession.deletedAt);
195
195
  continue;
196
196
  }
197
- if (op === 'task-event-upsert') {
197
+ if (op === 'task-event-upsert' || op === 'entity-event-upsert') {
198
198
  const event = normalizeTaskEventSyncPayload(raw.event, workspaceId, String(raw.updatedAt || raw.watermark || '').trim());
199
199
  if (event)
200
200
  model.taskActivity.incomingTaskEvents.set(event.id, event);
@@ -295,6 +295,7 @@ export function applyPlanningSyncChanges(input) {
295
295
  createdAt: initiative.createdAt,
296
296
  updatedAt: initiative.updatedAt,
297
297
  order: initiative.order,
298
+ attachments: initiative.attachments,
298
299
  isArchived: initiative.isArchived
299
300
  }, workspaceId);
300
301
  }
@@ -322,6 +323,7 @@ export function applyPlanningSyncChanges(input) {
322
323
  createdAt: workstream.createdAt,
323
324
  updatedAt: workstream.updatedAt,
324
325
  order: workstream.order,
326
+ attachments: workstream.attachments,
325
327
  isArchived: workstream.isArchived
326
328
  }, workspaceId);
327
329
  }
@@ -382,12 +384,22 @@ export function applyAiProfileAndMemberSyncChanges(input) {
382
384
  username: profile.username,
383
385
  icon: profile.icon,
384
386
  color: profile.color,
387
+ ...(Object.prototype.hasOwnProperty.call(profile, 'avatarUrl') ? { avatarUrl: profile.avatarUrl ?? null } : {}),
388
+ ...(Object.prototype.hasOwnProperty.call(profile, 'avatarSourceUrl') ? { avatarSourceUrl: profile.avatarSourceUrl ?? null } : {}),
389
+ ...(Object.prototype.hasOwnProperty.call(profile, 'avatarRevision') ? { avatarRevision: profile.avatarRevision ?? 0 } : {}),
390
+ avatarUpdatedAt: profile.avatarUpdatedAt ?? null,
385
391
  description: profile.description ?? null,
386
392
  role: profile.role ?? null,
387
393
  provider: profile.provider ?? null,
388
394
  model: profile.model ?? null,
389
395
  surfaceType: profile.surfaceType,
396
+ seatScope: profile.seatScope ?? null,
390
397
  providerMetadata: profile.providerMetadata,
398
+ archivedAt: profile.archivedAt ?? null,
399
+ archivedBy: profile.archivedBy ?? null,
400
+ archivedReason: profile.archivedReason ?? null,
401
+ mergedIntoProfileId: profile.mergedIntoProfileId ?? null,
402
+ rosterStateUpdatedAt: profile.rosterStateUpdatedAt ?? null,
391
403
  createdAt: profile.createdAt,
392
404
  updatedAt: profile.updatedAt,
393
405
  lastActiveAt: profile.lastActiveAt
@@ -430,27 +442,47 @@ export function applyAiProfileAndMemberSyncChanges(input) {
430
442
  }
431
443
  export async function applyContentSyncChanges(input) {
432
444
  const { core, workspaceId, incomingDocuments, incomingDocumentDeletes, incomingAssets, incomingAssetDeletes, basePath, hasObjectStorageClient, hasDocumentSyncMetadataDrift, hasBinaryAssetSyncMetadataDrift, getExistingDocument, writeWorkspaceSyncDocument, deleteWorkspaceSyncDocument, writeWorkspaceSyncBinaryAsset, deleteWorkspaceSyncBinaryAsset, getExistingBinaryAsset, recordSyncDiagnostic, options, } = input;
445
+ const contentApplyFailures = [];
446
+ const recordContentApplyFailure = (failure) => {
447
+ contentApplyFailures.push(failure);
448
+ };
449
+ const throwIfContentApplyFailed = () => {
450
+ if (contentApplyFailures.length === 0)
451
+ return;
452
+ const first = contentApplyFailures[0];
453
+ const error = new Error(`Failed to apply ${contentApplyFailures.length} synced content change${contentApplyFailures.length === 1 ? '' : 's'}; first failure: ${first.kind} ${first.path}: ${first.error}`);
454
+ error.statusCode = 500;
455
+ error.code = 'SYNC_CONTENT_APPLY_FAILED';
456
+ error.details = { failures: contentApplyFailures.slice(0, 10) };
457
+ throw error;
458
+ };
433
459
  if (incomingDocuments.length > 0) {
434
460
  for (const doc of incomingDocuments) {
435
461
  try {
436
462
  const existingDoc = core.getDocumentWatermark(workspaceId, doc.path);
437
- const existingDocFallback = getExistingDocument ? getExistingDocument(doc.path, workspaceId) : null;
438
- const localDocumentPath = path.resolve(basePath, doc.path);
439
- const localDocumentHash = !hasObjectStorageClient() && fs.existsSync(localDocumentPath)
440
- ? createHash('sha256').update(fs.readFileSync(localDocumentPath, 'utf8')).digest('hex')
441
- : '';
463
+ const existingDocFallback = (!existingDoc && getExistingDocument)
464
+ ? getExistingDocument(doc.path, workspaceId)
465
+ : null;
442
466
  const incomingHash = createHash('sha256').update(String(doc.content || '')).digest('hex');
443
467
  const existingUpdatedAt = String(existingDoc?.updatedAt || existingDocFallback?.updatedAt || '').trim();
444
- const existingHash = String(existingDoc?.contentHash || localDocumentHash || existingDocFallback?.contentHash || '').trim();
445
- const compare = resolveSyncConflictOrdering(doc.updatedAt, existingUpdatedAt, incomingHash, existingHash);
468
+ let existingHash = String(existingDoc?.contentHash || existingDocFallback?.contentHash || '').trim();
446
469
  const metadataDrift = hasDocumentSyncMetadataDrift(workspaceId, doc, options);
470
+ if (!hasObjectStorageClient() && (!existingHash || metadataDrift)) {
471
+ const localDocumentPath = path.resolve(basePath, doc.path);
472
+ if (fs.existsSync(localDocumentPath)) {
473
+ existingHash = createHash('sha256').update(fs.readFileSync(localDocumentPath, 'utf8')).digest('hex');
474
+ }
475
+ }
476
+ const compare = resolveSyncConflictOrdering(doc.updatedAt, existingUpdatedAt, incomingHash, existingHash);
447
477
  if (compare < 0)
448
478
  continue;
449
- if (compare === 0 && existingHash === incomingHash && !metadataDrift)
479
+ if (compare === 0 && existingHash === incomingHash && !metadataDrift && !hasObjectStorageClient())
450
480
  continue;
451
481
  await writeWorkspaceSyncDocument(basePath, doc, workspaceId, {
452
482
  ...options,
453
- allowReferenceNumberReassignment: options?.allowReferenceNumberReassignment === true || existingHash !== incomingHash
483
+ allowReferenceNumberReassignment: options?.allowReferenceNumberReassignment === true
484
+ || existingHash !== incomingHash
485
+ || metadataDrift
454
486
  });
455
487
  }
456
488
  catch (error) {
@@ -460,6 +492,11 @@ export async function applyContentSyncChanges(input) {
460
492
  assetId: typeof doc.assetId === 'string' ? doc.assetId : null,
461
493
  error: String(error?.message || error || '')
462
494
  });
495
+ recordContentApplyFailure({
496
+ kind: 'document',
497
+ path: doc.path,
498
+ error: String(error?.message || error || '')
499
+ });
463
500
  }
464
501
  }
465
502
  }
@@ -481,22 +518,23 @@ export async function applyContentSyncChanges(input) {
481
518
  const existing = getExistingBinaryAsset(asset.path, workspaceId);
482
519
  const incomingHash = createHash('sha256').update(Buffer.from(String(asset.contentBase64 || ''), 'base64')).digest('hex');
483
520
  const localFileMissing = !hasObjectStorageClient() && !fs.existsSync(localAssetPath);
484
- const localAssetHash = !hasObjectStorageClient() && !localFileMissing
485
- ? createHash('sha256').update(fs.readFileSync(localAssetPath)).digest('hex')
486
- : '';
487
521
  const existingUpdatedAt = String(existing?.updatedAt || '').trim();
488
- const existingHash = String(localAssetHash || existing?.contentSha256 || '').trim();
489
- const compare = resolveSyncConflictOrdering(asset.updatedAt, existingUpdatedAt, incomingHash, existingHash);
522
+ let existingHash = String(existing?.contentSha256 || '').trim();
490
523
  const metadataDrift = hasBinaryAssetSyncMetadataDrift(workspaceId, asset, options);
524
+ if (!hasObjectStorageClient() && !localFileMissing && (!existingHash || metadataDrift)) {
525
+ existingHash = createHash('sha256').update(fs.readFileSync(localAssetPath)).digest('hex');
526
+ }
527
+ const compare = resolveSyncConflictOrdering(asset.updatedAt, existingUpdatedAt, incomingHash, existingHash);
491
528
  if (compare < 0)
492
529
  continue;
493
- if (compare === 0 && existingHash === incomingHash && !localFileMissing && !metadataDrift)
530
+ if (compare === 0 && existingHash === incomingHash && !localFileMissing && !metadataDrift && !hasObjectStorageClient())
494
531
  continue;
495
532
  await writeWorkspaceSyncBinaryAsset(basePath, asset, workspaceId, {
496
533
  ...options,
497
534
  allowReferenceNumberReassignment: options?.allowReferenceNumberReassignment === true
498
535
  || existingHash !== incomingHash
499
536
  || localFileMissing
537
+ || metadataDrift
500
538
  });
501
539
  }
502
540
  catch (error) {
@@ -507,9 +545,15 @@ export async function applyContentSyncChanges(input) {
507
545
  kind: asset.kind,
508
546
  error: String(error?.message || error || '')
509
547
  });
548
+ recordContentApplyFailure({
549
+ kind: 'asset',
550
+ path: asset.path,
551
+ error: String(error?.message || error || '')
552
+ });
510
553
  }
511
554
  }
512
555
  }
556
+ throwIfContentApplyFailed();
513
557
  if (incomingAssetDeletes.size > 0) {
514
558
  for (const [assetPath, deletedAt] of incomingAssetDeletes.entries()) {
515
559
  const existing = getExistingBinaryAsset(assetPath, workspaceId);
@@ -745,22 +789,32 @@ export function applyTaskActivitySyncChanges(input) {
745
789
  return;
746
790
  for (const event of incomingTaskEvents.values()) {
747
791
  try {
748
- const taskId = String(event.taskId || '').trim();
749
- if (!taskId)
792
+ const entityType = event.entityType === 'initiative' || event.entityType === 'workstream' ? event.entityType : 'task';
793
+ const entityId = String(event.entityId || event.taskId || '').trim();
794
+ if (!entityId)
750
795
  continue;
751
- const existingTask = core.getTask(taskId, workspaceId);
752
- if (!existingTask) {
753
- recordSyncDiagnostic(workspaceId, 'apply', 'Skipped task event during sync apply because the task does not exist locally.', {
754
- source: 'apply.taskEventMissingTask',
796
+ const entityExists = entityType === 'task'
797
+ ? core.taskExistsForSync(entityId, workspaceId)
798
+ : entityType === 'initiative'
799
+ ? core.initiativeExistsForSync(entityId, workspaceId)
800
+ : core.workstreamExistsForSync(entityId, workspaceId);
801
+ if (!entityExists) {
802
+ recordSyncDiagnostic(workspaceId, 'apply', 'Skipped entity event during sync apply because the entity does not exist locally.', {
803
+ source: 'apply.entityEventMissingEntity',
755
804
  eventId: event.id,
756
- taskId,
805
+ entityType,
806
+ entityId,
757
807
  });
758
808
  continue;
759
809
  }
760
- const existing = core.listTaskEvents(taskId, workspaceId).find((entry) => entry.id === event.id) || null;
810
+ const existing = core.getEntityEventForSync({
811
+ workspaceId,
812
+ eventId: event.id,
813
+ });
761
814
  const incomingTieBreak = createHash('sha256')
762
815
  .update(JSON.stringify({
763
- taskId,
816
+ entityType,
817
+ entityId,
764
818
  action: event.action,
765
819
  actor: event.actor,
766
820
  actorType: event.actorType,
@@ -770,7 +824,8 @@ export function applyTaskActivitySyncChanges(input) {
770
824
  const existingTieBreak = existing
771
825
  ? createHash('sha256')
772
826
  .update(JSON.stringify({
773
- taskId: existing.taskId,
827
+ entityType: existing.entityType,
828
+ entityId: existing.entityId || ('taskId' in existing ? existing.taskId : ''),
774
829
  action: existing.action,
775
830
  actor: existing.actor,
776
831
  actorType: existing.actorType,
@@ -781,27 +836,45 @@ export function applyTaskActivitySyncChanges(input) {
781
836
  const compare = resolveSyncConflictOrdering(event.createdAt, String(existing?.createdAt || '').trim(), incomingTieBreak, existingTieBreak);
782
837
  if (compare < 0)
783
838
  continue;
784
- core.upsertTaskEventForSync({
785
- id: event.id,
786
- taskId,
787
- workspaceId,
788
- action: event.action,
789
- actor: event.actor,
790
- actorType: event.actorType,
791
- details: event.details,
792
- createdAt: event.createdAt,
793
- });
839
+ if (entityType === 'task') {
840
+ core.upsertEntityEventForSync({
841
+ id: event.id,
842
+ workspaceId,
843
+ entityType: 'task',
844
+ entityId,
845
+ taskId: String(event.taskId || entityId).trim(),
846
+ action: event.action,
847
+ actor: event.actor,
848
+ actorType: event.actorType,
849
+ details: event.details,
850
+ createdAt: event.createdAt,
851
+ });
852
+ }
853
+ else {
854
+ core.upsertEntityEventForSync({
855
+ id: event.id,
856
+ workspaceId,
857
+ entityType,
858
+ entityId,
859
+ action: event.action,
860
+ actor: event.actor,
861
+ actorType: event.actorType,
862
+ details: event.details,
863
+ createdAt: event.createdAt,
864
+ });
865
+ }
794
866
  }
795
867
  catch (error) {
796
868
  const details = {
797
- source: 'apply.taskEventUpsert',
869
+ source: 'apply.entityEventUpsert',
798
870
  eventId: event.id,
799
- taskId: event.taskId,
871
+ entityType: event.entityType,
872
+ entityId: event.entityId || event.taskId,
800
873
  error: String(error?.message || error || ''),
801
874
  errorCode: String(error?.code || '').trim() || null
802
875
  };
803
- recordSyncDiagnostic(workspaceId, 'apply', 'Failed to upsert task event during sync apply.', details);
804
- throw createSyncRouteError(`Failed to persist task event ${event.id} during sync apply: ${String(error?.message || error || 'Unknown error')}`, details, { code: 'TASK_EVENT_SYNC_APPLY_FAILED', statusCode: 500 });
876
+ recordSyncDiagnostic(workspaceId, 'apply', 'Failed to upsert entity event during sync apply.', details);
877
+ throw createSyncRouteError(`Failed to persist entity event ${event.id} during sync apply: ${String(error?.message || error || 'Unknown error')}`, details, { code: 'TASK_EVENT_SYNC_APPLY_FAILED', statusCode: 500 });
805
878
  }
806
879
  }
807
880
  }