@taskforcehq/taskforce 0.3.304 → 0.3.306

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 (383) hide show
  1. package/README.md +140 -247
  2. package/dist/Taskforce.module.css +295 -89
  3. package/dist/TaskforceCore.js +378 -111
  4. package/dist/TaskforceCore.test.js +1221 -107
  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 +52 -2
  14. package/dist/compat/workspaceSyncCompat.test.js +38 -1
  15. package/dist/components/context/ContextAttachmentManager.d.ts +14 -0
  16. package/dist/components/context/ContextAttachmentManager.js +549 -0
  17. package/dist/components/features/AgentsModule.d.ts +10 -1
  18. package/dist/components/features/AgentsModule.js +260 -15
  19. package/dist/components/features/AgentsModule.test.js +255 -5
  20. package/dist/components/features/DocumentIndex.d.ts +1 -1
  21. package/dist/components/features/DocumentIndex.js +1 -1
  22. package/dist/components/features/DocumentViewer.d.ts +6 -2
  23. package/dist/components/features/DocumentViewer.js +90 -10
  24. package/dist/components/features/DocumentWorkspace.d.ts +5 -22
  25. package/dist/components/features/DocumentWorkspace.js +12 -155
  26. package/dist/components/features/DocumentWorkspace.test.js +226 -6
  27. package/dist/components/features/TaskSettings.js +29 -3
  28. package/dist/components/features/TaskSettings.test.js +42 -1
  29. package/dist/components/features/documentWorkspaceModel.d.ts +24 -0
  30. package/dist/components/features/documentWorkspaceModel.js +57 -0
  31. package/dist/components/features/useDocumentWorkspaceController.d.ts +34 -0
  32. package/dist/components/features/useDocumentWorkspaceController.js +113 -0
  33. package/dist/components/task/TaskCard.js +19 -28
  34. package/dist/components/task/TaskCard.test.js +38 -3
  35. package/dist/components/task/TaskContextUpload.js +4 -526
  36. package/dist/components/task/TaskForm.d.ts +8 -8
  37. package/dist/components/task/TaskForm.js +362 -230
  38. package/dist/components/task/TaskForm.test.js +558 -381
  39. package/dist/components/task/TaskKanban.d.ts +2 -1
  40. package/dist/components/task/TaskKanban.js +96 -14
  41. package/dist/components/task/TaskKanban.test.js +36 -0
  42. package/dist/components/ui/EditableAvatarButton.d.ts +18 -0
  43. package/dist/components/ui/EditableAvatarButton.js +18 -0
  44. package/dist/components/views/PlanComparisonPage.d.ts +9 -1
  45. package/dist/components/views/PlanComparisonPage.js +70 -17
  46. package/dist/components/views/PlanComparisonPage.test.js +289 -41
  47. package/dist/components/views/PlansPage.js +239 -106
  48. package/dist/components/views/PlansPage.test.js +593 -42
  49. package/dist/components/views/StandaloneLayout.js +310 -554
  50. package/dist/components/views/panels/FilterToolbar.test.js +6 -4
  51. package/dist/components/views/panels/PlanningDrawer.d.ts +8 -1
  52. package/dist/components/views/panels/PlanningDrawer.js +18 -11
  53. package/dist/components/views/panels/PlanningDrawer.test.d.ts +1 -0
  54. package/dist/components/views/panels/PlanningDrawer.test.js +141 -0
  55. package/dist/components/views/planningScope.d.ts +20 -0
  56. package/dist/components/views/planningScope.js +25 -0
  57. package/dist/components/views/planningScope.test.d.ts +1 -0
  58. package/dist/components/views/planningScope.test.js +60 -0
  59. package/dist/components/views/standalone/modals/AccountHubModal.d.ts +27 -14
  60. package/dist/components/views/standalone/modals/AccountHubModal.js +87 -15
  61. package/dist/components/views/standalone/modals/AccountHubModal.test.js +42 -2
  62. package/dist/components/views/standalone/modals/AvatarImageManagerModal.d.ts +20 -0
  63. package/dist/components/views/standalone/modals/AvatarImageManagerModal.js +127 -0
  64. package/dist/components/views/standalone/modals/EditProfileModal.d.ts +2 -9
  65. package/dist/components/views/standalone/modals/EditProfileModal.js +3 -2
  66. package/dist/components/views/standalone/modals/SyncEnableWarningModal.d.ts +9 -0
  67. package/dist/components/views/standalone/modals/SyncEnableWarningModal.js +6 -0
  68. package/dist/components/views/standalone/modals/SyncEnableWarningModal.test.d.ts +1 -0
  69. package/dist/components/views/standalone/modals/SyncEnableWarningModal.test.js +24 -0
  70. package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +2 -1
  71. package/dist/components/views/standalone/modals/SyncStatusModal.js +2 -2
  72. package/dist/config/envSchema.js +1 -1
  73. package/dist/core/AiProfileService.d.ts +45 -3
  74. package/dist/core/AiProfileService.js +774 -63
  75. package/dist/core/AiProfileService.test.js +22 -2
  76. package/dist/core/AiProfiles.test.js +761 -2
  77. package/dist/core/AttachmentLinkService.js +57 -15
  78. package/dist/core/AuthIdentityService.d.ts +107 -0
  79. package/dist/core/AuthIdentityService.js +284 -0
  80. package/dist/core/AuthTokenService.d.ts +4 -0
  81. package/dist/core/AuthTokenService.js +34 -6
  82. package/dist/core/AuthTokenService.test.d.ts +1 -0
  83. package/dist/core/AuthTokenService.test.js +78 -0
  84. package/dist/core/EntitlementsPolicy.test.js +77 -15
  85. package/dist/core/GlobalSettingsService.js +115 -6
  86. package/dist/core/PlanEntitlementService.d.ts +30 -3
  87. package/dist/core/PlanEntitlementService.js +454 -93
  88. package/dist/core/PlanFeatureCatalog.test.d.ts +1 -0
  89. package/dist/core/PlanFeatureCatalog.test.js +84 -0
  90. package/dist/core/PlanVersionPolicy.test.js +54 -28
  91. package/dist/core/PlanningEntities.test.js +52 -0
  92. package/dist/core/SignupMonetizationSettings.test.js +241 -44
  93. package/dist/core/SyncReconciliationService.js +2 -65
  94. package/dist/core/SystemAdmin.test.js +244 -88
  95. package/dist/core/TaskAttachmentsCanonical.test.js +51 -1
  96. package/dist/core/TaskTaxonomyValidation.test.js +53 -0
  97. package/dist/core/Taskforce.d.ts +228 -14
  98. package/dist/core/Taskforce.js +814 -201
  99. package/dist/core/Taskforce.listTasksSlim.test.d.ts +1 -0
  100. package/dist/core/Taskforce.listTasksSlim.test.js +91 -0
  101. package/dist/core/UserProfileAvatarDrafts.test.js +30 -3
  102. package/dist/core/WorkspaceLifecycleService.js +0 -5
  103. package/dist/core/WorkspacePermissions.test.js +25 -1
  104. package/dist/core/WorkspacePlanMode.test.js +128 -27
  105. package/dist/core/shared.d.ts +3 -1
  106. package/dist/core/shared.js +16 -1
  107. package/dist/core/types.d.ts +68 -2
  108. package/dist/hooks/auth/useTaskforceAuthBootstrap.js +26 -1
  109. package/dist/hooks/sync/auth.js +3 -1
  110. package/dist/hooks/sync/bootstrap.js +2 -0
  111. package/dist/hooks/sync/controlPlane.d.ts +37 -0
  112. package/dist/hooks/sync/controlPlane.js +78 -0
  113. package/dist/hooks/sync/controlPlane.test.d.ts +1 -0
  114. package/dist/hooks/sync/controlPlane.test.js +121 -0
  115. package/dist/hooks/sync/lifecyclePolicy.d.ts +45 -0
  116. package/dist/hooks/sync/lifecyclePolicy.js +93 -0
  117. package/dist/hooks/sync/lifecyclePolicy.test.d.ts +1 -0
  118. package/dist/hooks/sync/lifecyclePolicy.test.js +124 -0
  119. package/dist/hooks/sync/orchestratorShared.d.ts +10 -1
  120. package/dist/hooks/sync/orchestratorShared.js +68 -47
  121. package/dist/hooks/sync/orchestratorShared.test.js +50 -1
  122. package/dist/hooks/sync/pullLifecycle.d.ts +31 -0
  123. package/dist/hooks/sync/pullLifecycle.js +24 -0
  124. package/dist/hooks/sync/pullLifecycle.test.d.ts +1 -0
  125. package/dist/hooks/sync/pullLifecycle.test.js +80 -0
  126. package/dist/hooks/sync/recovery.d.ts +16 -2
  127. package/dist/hooks/sync/recovery.js +171 -53
  128. package/dist/hooks/sync/recovery.test.d.ts +1 -0
  129. package/dist/hooks/sync/recovery.test.js +292 -0
  130. package/dist/hooks/sync/transfers.d.ts +16 -3
  131. package/dist/hooks/sync/transfers.js +186 -65
  132. package/dist/hooks/sync/transfers.test.d.ts +1 -0
  133. package/dist/hooks/sync/transfers.test.js +396 -0
  134. package/dist/hooks/sync/useRecentSyncEvents.d.ts +21 -0
  135. package/dist/hooks/sync/useRecentSyncEvents.js +92 -0
  136. package/dist/hooks/sync/useRecentSyncEvents.test.d.ts +1 -0
  137. package/dist/hooks/sync/useRecentSyncEvents.test.js +124 -0
  138. package/dist/hooks/sync/useSyncStatusActions.d.ts +30 -0
  139. package/dist/hooks/sync/useSyncStatusActions.js +88 -0
  140. package/dist/hooks/sync/useSyncStatusActions.test.d.ts +1 -0
  141. package/dist/hooks/sync/useSyncStatusActions.test.js +133 -0
  142. package/dist/hooks/sync/useSyncStatusControls.d.ts +25 -0
  143. package/dist/hooks/sync/useSyncStatusControls.js +60 -0
  144. package/dist/hooks/sync/useSyncStatusControls.test.d.ts +1 -0
  145. package/dist/hooks/sync/useSyncStatusControls.test.js +88 -0
  146. package/dist/hooks/useSyncOrchestrator.aiProfiles.test.js +12 -0
  147. package/dist/hooks/useSyncOrchestrator.d.ts +16 -6
  148. package/dist/hooks/useSyncOrchestrator.js +424 -175
  149. package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +487 -10
  150. package/dist/hooks/useTaskData.js +8 -3
  151. package/dist/hooks/useTaskData.test.js +45 -0
  152. package/dist/hooks/useTaskMutations.d.ts +2 -1
  153. package/dist/hooks/useTaskMutations.js +12 -1
  154. package/dist/hooks/useTaskMutations.test.js +30 -1
  155. package/dist/hooks/useTaskforce.d.ts +65 -4
  156. package/dist/hooks/useTaskforce.js +564 -243
  157. package/dist/hooks/useTaskforce.runtime-routing.test.d.ts +1 -0
  158. package/dist/hooks/useTaskforce.runtime-routing.test.js +152 -0
  159. package/dist/hooks/useTaskforce.sync-behavior.test.js +2454 -208
  160. package/dist/hooks/useWorkspaceSyncController.d.ts +4 -1
  161. package/dist/hooks/useWorkspaceSyncController.js +17 -2
  162. package/dist/hooks/useWorkspaceSyncController.test.js +1 -0
  163. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.d.ts +16 -0
  164. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +316 -35
  165. package/dist/localization/locales/en-US.d.ts +0 -1
  166. package/dist/localization/locales/en-US.js +0 -1
  167. package/dist/localization/locales/es-419.js +0 -1
  168. package/dist/localization/locales/pt-BR.js +0 -1
  169. package/dist/mcp/adminWorkspaceRegistrar.d.ts +2 -0
  170. package/dist/mcp/adminWorkspaceRegistrar.js +154 -0
  171. package/dist/mcp/collaborationRegistrar.d.ts +2 -0
  172. package/dist/mcp/collaborationRegistrar.js +71 -0
  173. package/dist/mcp/documentAssetRegistrar.d.ts +2 -0
  174. package/dist/mcp/documentAssetRegistrar.js +346 -0
  175. package/dist/mcp/runtime.d.ts +2 -0
  176. package/dist/mcp/runtime.js +2433 -3534
  177. package/dist/mcp/runtime.test.js +440 -2
  178. package/dist/mcp/taskPlanningRegistrar.d.ts +2 -0
  179. package/dist/mcp/taskPlanningRegistrar.js +418 -0
  180. package/dist/mcp/toolCatalog.d.ts +35 -0
  181. package/dist/mcp/toolCatalog.js +3 -0
  182. package/dist/migrations/taskSchemaMigrations.d.ts +1 -1
  183. package/dist/migrations/taskSchemaMigrations.js +171 -61
  184. package/dist/migrations/taskSchemaMigrations.test.js +15 -0
  185. package/dist/resources/templates/workflow-sources/workflowDocs.mjs +6 -6
  186. package/dist/resources/templates/workflows/collaborate.yaml +1 -1
  187. package/dist/resources/templates/workflows/evaluate.yaml +2 -2
  188. package/dist/resources/templates/workflows/plan.yaml +1 -1
  189. package/dist/resources/templates/workflows/review.yaml +2 -2
  190. package/dist/server/annotatedAttachmentsRoutes.test.js +3 -3
  191. package/dist/server/auth/providers/apple.d.ts +33 -0
  192. package/dist/server/auth/providers/apple.js +82 -0
  193. package/dist/server/auth/providers/appleClientSecret.d.ts +37 -0
  194. package/dist/server/auth/providers/appleClientSecret.js +65 -0
  195. package/dist/server/auth/providers/github.d.ts +26 -0
  196. package/dist/server/auth/providers/github.js +86 -0
  197. package/dist/server/auth/providers/google.d.ts +21 -0
  198. package/dist/server/auth/providers/google.js +56 -0
  199. package/dist/server/auth/providers/types.d.ts +21 -0
  200. package/dist/server/auth/providers/types.js +1 -0
  201. package/dist/server/auth.d.ts +2 -0
  202. package/dist/server/auth.js +6 -3
  203. package/dist/server/documentReviewRoutes.test.js +36 -3
  204. package/dist/server/index.cookieProxy.test.js +1 -0
  205. package/dist/server/index.d.ts +12 -0
  206. package/dist/server/index.js +120 -9
  207. package/dist/server/index.rateLimit.test.js +3 -0
  208. package/dist/server/index.test.js +106 -3
  209. package/dist/server/routes/admin.d.ts +4 -5
  210. package/dist/server/routes/admin.js +410 -80
  211. package/dist/server/routes/annotatedAttachments.d.ts +1 -1
  212. package/dist/server/routes/annotatedAttachments.js +1 -1
  213. package/dist/server/routes/auth.d.ts +16 -6
  214. package/dist/server/routes/auth.js +1015 -118
  215. package/dist/server/routes/authSupport.d.ts +30 -0
  216. package/dist/server/routes/authSupport.js +81 -0
  217. package/dist/server/routes/billing.d.ts +1 -1
  218. package/dist/server/routes/billing.js +276 -34
  219. package/dist/server/routes/billing.test.js +760 -52
  220. package/dist/server/routes/documentReviews.d.ts +1 -1
  221. package/dist/server/routes/documentReviews.js +1 -1
  222. package/dist/server/routes/documents.d.ts +5 -2
  223. package/dist/server/routes/documents.js +242 -74
  224. package/dist/server/routes/primitives.d.ts +11 -0
  225. package/dist/server/routes/primitives.js +73 -0
  226. package/dist/server/routes/resources.d.ts +1 -1
  227. package/dist/server/routes/resources.js +1 -1
  228. package/dist/server/routes/shared.d.ts +29 -3
  229. package/dist/server/routes/shared.js +69 -4
  230. package/dist/server/routes/sync.d.ts +1 -1
  231. package/dist/server/routes/sync.integration.test.js +437 -39
  232. package/dist/server/routes/sync.js +62 -606
  233. package/dist/server/routes/syncAuxRoutes.d.ts +15 -0
  234. package/dist/server/routes/syncAuxRoutes.js +91 -0
  235. package/dist/server/routes/syncAuxRoutes.test.d.ts +1 -0
  236. package/dist/server/routes/syncAuxRoutes.test.js +158 -0
  237. package/dist/server/routes/syncPullApplyRoutes.d.ts +36 -0
  238. package/dist/server/routes/syncPullApplyRoutes.js +204 -0
  239. package/dist/server/routes/syncPushRoutes.d.ts +24 -0
  240. package/dist/server/routes/syncPushRoutes.js +212 -0
  241. package/dist/server/routes/syncRouteGuards.d.ts +36 -0
  242. package/dist/server/routes/syncRouteGuards.js +67 -0
  243. package/dist/server/routes/syncRouteGuards.test.d.ts +1 -0
  244. package/dist/server/routes/syncRouteGuards.test.js +94 -0
  245. package/dist/server/routes/syncRouteTypes.d.ts +13 -0
  246. package/dist/server/routes/syncRouteTypes.js +1 -0
  247. package/dist/server/routes/syncSnapshotRoutes.d.ts +66 -0
  248. package/dist/server/routes/syncSnapshotRoutes.js +180 -0
  249. package/dist/server/routes/tasks.d.ts +1 -1
  250. package/dist/server/routes/tasks.js +44 -2
  251. package/dist/server/routes/workspaces.d.ts +1 -1
  252. package/dist/server/routes/workspaces.js +37 -6
  253. package/dist/server/routes.d.ts +2 -9
  254. package/dist/server/routes.js +136 -165
  255. package/dist/server/routes.test.js +2457 -162
  256. package/dist/services/workflowExportSnapshots.test.js +2 -0
  257. package/dist/shared/aiProfileSeatScope.d.ts +5 -0
  258. package/dist/shared/aiProfileSeatScope.js +21 -0
  259. package/dist/shared/passwordPolicy.d.ts +13 -0
  260. package/dist/shared/passwordPolicy.js +84 -0
  261. package/dist/shared/passwordPolicy.test.d.ts +1 -0
  262. package/dist/shared/passwordPolicy.test.js +34 -0
  263. package/dist/storage/workspaceAssetStore.d.ts +15 -3
  264. package/dist/storage/workspaceAssetStore.js +132 -44
  265. package/dist/storage/workspaceAssetStore.test.js +93 -6
  266. package/dist/styles/fonts.css +70 -0
  267. package/dist/sync/collaborationSyncPayload.d.ts +6 -1
  268. package/dist/sync/collaborationSyncPayload.js +17 -11
  269. package/dist/sync/collaborationSyncPayload.test.js +13 -1
  270. package/dist/sync/contentSyncState.d.ts +4 -8
  271. package/dist/sync/contentSyncState.js +33 -77
  272. package/dist/sync/syncApplyHandlers.d.ts +7 -0
  273. package/dist/sync/syncApplyHandlers.js +28 -13
  274. package/dist/sync/syncApplyHandlers.test.js +72 -3
  275. package/dist/sync/syncFieldSemantics.d.ts +12 -0
  276. package/dist/sync/syncFieldSemantics.js +55 -0
  277. package/dist/sync/syncResourceAdapters.d.ts +44 -0
  278. package/dist/sync/syncResourceAdapters.js +77 -0
  279. package/dist/sync/syncService.d.ts +6 -0
  280. package/dist/sync/syncService.js +60 -0
  281. package/dist/sync/syncService.test.js +71 -3
  282. package/dist/sync/taskSyncChangeKey.d.ts +2 -0
  283. package/dist/sync/taskSyncChangeKey.js +143 -0
  284. package/dist/sync/taskSyncPayload.js +3 -8
  285. package/dist/sync/workspacePullFeed.js +4 -3
  286. package/dist/sync/workspacePullFeed.test.js +43 -0
  287. package/dist/sync/workspaceRepair.js +5 -2
  288. package/dist/sync/workspaceSyncModel.d.ts +48 -0
  289. package/dist/sync/workspaceSyncModel.js +195 -31
  290. package/dist/sync/workspaceSyncModel.test.js +325 -12
  291. package/dist/sync/workspaceSyncState.d.ts +19 -0
  292. package/dist/sync/workspaceSyncState.js +3 -1
  293. package/dist/sync/workspaceSyncSurface.js +3 -8
  294. package/dist/types.d.ts +17 -0
  295. package/dist/ui/assets/AgentsModule-DrLawwNl.js +1 -0
  296. package/dist/ui/assets/{AnnotatedAttachmentWorkspace-BlS-cqnl.js → AnnotatedAttachmentWorkspace-Z9_whf7F.js} +1 -1
  297. package/dist/ui/assets/CourierPrime-Bold-BuLj_dpw.woff2 +0 -0
  298. package/dist/ui/assets/CourierPrime-BoldItalic-BrK2pUkZ.woff2 +0 -0
  299. package/dist/ui/assets/CourierPrime-Italic-DFUZK5Ey.woff2 +0 -0
  300. package/dist/ui/assets/CourierPrime-Regular-BsKphzVf.woff2 +0 -0
  301. package/dist/ui/assets/DocumentWorkspace-B03MaSkw.js +252 -0
  302. package/dist/ui/assets/DocumentWorkspace-Dhdso07p.css +1 -0
  303. package/dist/ui/assets/{InitiativesModule-BjR6iBf9.js → InitiativesModule-9E6ParrY.js} +1 -1
  304. package/dist/ui/assets/Noir_medium-bxQwKGzB.woff2 +0 -0
  305. package/dist/ui/assets/Noir_regular-ojf2kxlG.woff2 +0 -0
  306. package/dist/ui/assets/PlansPage-CvfnMiWq.css +1 -0
  307. package/dist/ui/assets/PlansPage-DRXscYxH.js +1 -0
  308. package/dist/ui/assets/RussoOne-Regular-Cu_qq_qC.woff2 +0 -0
  309. package/dist/ui/assets/SpecialElite-Regular-Di6gSvAS.woff2 +0 -0
  310. package/dist/ui/assets/TaskSettings-DZX4jk7e.js +9 -0
  311. package/dist/ui/assets/{WorkflowsModule-DnFqdUME.js → WorkflowsModule-BA7jcEpH.js} +1 -1
  312. package/dist/ui/assets/index-9eT8e0Lu.css +1 -0
  313. package/dist/ui/assets/index-C6k75jr8.js +6 -0
  314. package/dist/ui/assets/{vendor-icons-I7ZwG1z_.js → vendor-icons-DuEd_65c.js} +1 -1
  315. package/dist/ui/fonts/CourierPrime-Bold.ttf +0 -0
  316. package/dist/ui/fonts/CourierPrime-Bold.woff2 +0 -0
  317. package/dist/ui/fonts/CourierPrime-BoldItalic.ttf +0 -0
  318. package/dist/ui/fonts/CourierPrime-BoldItalic.woff2 +0 -0
  319. package/dist/ui/fonts/CourierPrime-Italic.ttf +0 -0
  320. package/dist/ui/fonts/CourierPrime-Italic.woff2 +0 -0
  321. package/dist/ui/fonts/CourierPrime-Regular.ttf +0 -0
  322. package/dist/ui/fonts/CourierPrime-Regular.woff2 +0 -0
  323. package/dist/ui/fonts/Noir_medium.otf +0 -0
  324. package/dist/ui/fonts/Noir_medium.woff2 +0 -0
  325. package/dist/ui/fonts/Noir_regular.otf +0 -0
  326. package/dist/ui/fonts/Noir_regular.woff2 +0 -0
  327. package/dist/ui/fonts/RussoOne-Regular.woff2 +0 -0
  328. package/dist/ui/fonts/SpecialElite-Regular.ttf +0 -0
  329. package/dist/ui/fonts/SpecialElite-Regular.woff2 +0 -0
  330. package/dist/ui/index.html +3 -3
  331. package/dist/utils/accountProfileSummaryCache.d.ts +5 -0
  332. package/dist/utils/assignees.d.ts +2 -0
  333. package/dist/utils/assignees.js +2 -0
  334. package/dist/utils/avatarUpload.d.ts +27 -0
  335. package/dist/utils/avatarUpload.js +132 -0
  336. package/dist/utils/avatarUpload.test.d.ts +1 -0
  337. package/dist/utils/avatarUpload.test.js +40 -0
  338. package/dist/utils/bootstrapTrace.d.ts +7 -0
  339. package/dist/utils/bootstrapTrace.js +29 -0
  340. package/dist/utils/commercialLifecyclePresentation.d.ts +19 -0
  341. package/dist/utils/commercialLifecyclePresentation.js +199 -0
  342. package/dist/utils/contextAssetEvents.d.ts +2 -0
  343. package/dist/utils/syncEventDetails.d.ts +3 -0
  344. package/dist/utils/syncEventDetails.js +64 -0
  345. package/dist/utils/syncEventDetails.test.d.ts +1 -0
  346. package/dist/utils/syncEventDetails.test.js +23 -0
  347. package/dist/utils/syncEventPresentation.d.ts +15 -0
  348. package/dist/utils/syncEventPresentation.js +129 -0
  349. package/dist/utils/syncEventPresentation.test.d.ts +1 -0
  350. package/dist/utils/syncEventPresentation.test.js +64 -0
  351. package/dist/utils/syncStatusPresentation.d.ts +72 -0
  352. package/dist/utils/syncStatusPresentation.js +217 -0
  353. package/dist/utils/syncStatusPresentation.test.d.ts +1 -0
  354. package/dist/utils/syncStatusPresentation.test.js +164 -0
  355. package/dist/utils/taskActivity.d.ts +2 -0
  356. package/dist/utils/taskActivity.js +228 -22
  357. package/dist/utils/taskActivity.test.js +119 -8
  358. package/dist/utils/workspaceSyncPresentation.d.ts +4 -0
  359. package/dist/utils/workspaceSyncPresentation.js +68 -2
  360. package/dist/utils/workspaceSyncPresentation.test.js +36 -1
  361. package/package.json +10 -2
  362. package/scripts/check-cloud-mcp.mjs +83 -0
  363. package/scripts/export-sqlite-to-postgres.mjs +7 -9
  364. package/scripts/playwright-auth.sh +5 -1
  365. package/scripts/run-billing-performance-smoke.sh +24 -0
  366. package/scripts/run-e2e-realtime.sh +17 -3
  367. package/scripts/run-smoke.sh +17 -5
  368. package/scripts/run-soak.sh +17 -5
  369. package/src/resources/templates/workflow-sources/workflowDocs.mjs +6 -6
  370. package/src/resources/templates/workflows/collaborate.yaml +1 -1
  371. package/src/resources/templates/workflows/evaluate.yaml +2 -2
  372. package/src/resources/templates/workflows/plan.yaml +1 -1
  373. package/src/resources/templates/workflows/review.yaml +2 -2
  374. package/dist/ui/assets/AgentsModule-BLWVbuKP.js +0 -1
  375. package/dist/ui/assets/DocumentWorkspace-BH_6DF6x.js +0 -250
  376. package/dist/ui/assets/DocumentWorkspace-C_8T8oz-.css +0 -1
  377. package/dist/ui/assets/PlansPage-C2dd2n1X.css +0 -1
  378. package/dist/ui/assets/PlansPage-CSDQ4sLa.js +0 -1
  379. package/dist/ui/assets/RussoOne-Regular-C3BxZIj7.ttf +0 -0
  380. package/dist/ui/assets/TaskSettings-CEDy34Jo.js +0 -9
  381. package/dist/ui/assets/index-DXUdtH1B.js +0 -6
  382. package/dist/ui/assets/index-Ii0B0rTO.css +0 -1
  383. package/scripts/migrate-planning-model.ts +0 -233
@@ -1,8 +1,17 @@
1
1
  import { parseAiProfileSurfaceType } from '../shared/aiProfileSurfaceType.js';
2
+ import { parseAiProfileSeatScope } from '../shared/aiProfileSeatScope.js';
2
3
  import { serializeTaskForSync } from './taskSyncPayload.js';
4
+ import { aiProfileSyncResourceAdapter, taskSyncResourceAdapter, shouldSyncResource, } from './syncResourceAdapters.js';
5
+ import { normalizeSyncSameOriginAssetUrl } from './syncFieldSemantics.js';
3
6
  export function toWorkspaceSyncTaskSnapshot(task) {
4
7
  return serializeTaskForSync(task);
5
8
  }
9
+ function normalizeWorkspaceSyncPathSet(value, fallback) {
10
+ const source = value ?? fallback;
11
+ return new Set(Array.from(source)
12
+ .map((entry) => String(entry || '').trim())
13
+ .filter((entry) => entry.length > 0));
14
+ }
6
15
  function sortTaskEventsForSync(taskEvents) {
7
16
  return [...taskEvents].sort((left, right) => {
8
17
  const leftCreatedAt = String(left?.createdAt || '').trim();
@@ -25,61 +34,79 @@ export function buildWorkspaceSyncPayloadModel(input) {
25
34
  const pendingDeleteIds = new Set(Array.from(input.pendingDeletedTaskIds)
26
35
  .map((taskId) => String(taskId || '').trim())
27
36
  .filter((taskId) => taskId.length > 0));
37
+ const pendingDeleteWatermarks = new Map(Array.from(input.pendingDeletedTaskWatermarks || new Map())
38
+ .map(([taskId, deletedAt]) => [String(taskId || '').trim(), String(deletedAt || '').trim()])
39
+ .filter(([taskId, deletedAt]) => taskId.length > 0 && Number.isFinite(Date.parse(deletedAt))));
28
40
  const lastWatermarks = input.lastPushedWatermarks;
29
- const isDirty = (task) => {
41
+ const lastTaskChangeKeys = input.lastPushedTaskChangeKeys;
42
+ const isDirty = (task, archived) => {
30
43
  if ((task?.referenceNumber === undefined || task?.referenceNumber === null) && Number.isFinite(Number(task?.localReferenceNumber))) {
31
44
  return true;
32
45
  }
33
- if (!lastWatermarks || lastWatermarks.size === 0)
34
- return true;
35
- const taskId = String(task?.id || '').trim();
36
- if (!taskId)
37
- return false;
38
- const currentWatermark = String(task?.updatedAt || task?.createdAt || '').trim();
39
- return lastWatermarks.get(taskId) !== currentWatermark;
46
+ return shouldSyncResource(taskSyncResourceAdapter, { ...task, isArchived: archived }, {
47
+ watermarks: lastWatermarks,
48
+ changeKeys: lastTaskChangeKeys,
49
+ });
40
50
  };
41
51
  const activeTasksOrdered = sortTasksForSync(input.tasks || []);
42
52
  const archivedTasksOrdered = sortTasksForSync(input.archivedTasks || []);
53
+ const currentTaskWatermarks = new Map();
54
+ const currentTaskChangeKeys = new Map();
43
55
  const pushedWatermarks = new Map();
56
+ const pushedTaskChangeKeys = new Map();
44
57
  const activeChanges = activeTasksOrdered
45
- .filter((task) => !pendingDeleteIds.has(String(task?.id || '').trim()) && isDirty(task))
58
+ .filter((task) => !pendingDeleteIds.has(String(task?.id || '').trim()) && isDirty(task, false))
46
59
  .map((task) => {
47
60
  const taskId = String(task?.id || '').trim();
48
- const wm = String(task?.updatedAt || task?.createdAt || '').trim();
49
- if (taskId)
61
+ const wm = taskSyncResourceAdapter.getWatermark(task);
62
+ const changeKey = taskSyncResourceAdapter.getChangeKey({ ...task, isArchived: false });
63
+ if (taskId) {
50
64
  pushedWatermarks.set(taskId, wm);
65
+ pushedTaskChangeKeys.set(taskId, changeKey);
66
+ }
51
67
  return { op: 'upsert', archived: false, task: toWorkspaceSyncTaskSnapshot(task) };
52
68
  });
53
69
  const archivedChanges = archivedTasksOrdered
54
- .filter((task) => !pendingDeleteIds.has(String(task?.id || '').trim()) && isDirty(task))
70
+ .filter((task) => !pendingDeleteIds.has(String(task?.id || '').trim()) && isDirty(task, true))
55
71
  .map((task) => {
56
72
  const taskId = String(task?.id || '').trim();
57
- const wm = String(task?.updatedAt || task?.createdAt || '').trim();
58
- if (taskId)
73
+ const wm = taskSyncResourceAdapter.getWatermark(task);
74
+ const changeKey = taskSyncResourceAdapter.getChangeKey({ ...task, isArchived: true });
75
+ if (taskId) {
59
76
  pushedWatermarks.set(taskId, wm);
77
+ pushedTaskChangeKeys.set(taskId, changeKey);
78
+ }
60
79
  return { op: 'upsert', archived: true, task: toWorkspaceSyncTaskSnapshot(task) };
61
80
  });
62
81
  const currentTaskIds = new Set();
63
82
  for (const task of input.tasks || []) {
64
83
  const taskId = String(task?.id || '').trim();
65
- if (taskId)
66
- currentTaskIds.add(taskId);
84
+ if (!taskId)
85
+ continue;
86
+ currentTaskIds.add(taskId);
87
+ currentTaskWatermarks.set(taskId, taskSyncResourceAdapter.getWatermark(task));
88
+ currentTaskChangeKeys.set(taskId, taskSyncResourceAdapter.getChangeKey({ ...task, isArchived: false }));
67
89
  }
68
90
  for (const task of input.archivedTasks || []) {
69
91
  const taskId = String(task?.id || '').trim();
70
- if (taskId)
71
- currentTaskIds.add(taskId);
92
+ if (!taskId)
93
+ continue;
94
+ currentTaskIds.add(taskId);
95
+ currentTaskWatermarks.set(taskId, taskSyncResourceAdapter.getWatermark(task));
96
+ currentTaskChangeKeys.set(taskId, taskSyncResourceAdapter.getChangeKey({ ...task, isArchived: true }));
72
97
  }
73
98
  const deleteChanges = Array.from(input.lastPushedTaskIds)
74
99
  .filter((taskId) => !currentTaskIds.has(taskId))
75
100
  .map((taskId) => ({
76
101
  op: 'delete',
77
- taskId
102
+ taskId,
103
+ deletedAt: pendingDeleteWatermarks.get(taskId) || payloadBuiltAt
78
104
  }));
79
105
  const queuedDeleteChanges = Array.from(pendingDeleteIds)
80
106
  .map((taskId) => ({
81
107
  op: 'delete',
82
- taskId
108
+ taskId,
109
+ deletedAt: pendingDeleteWatermarks.get(taskId) || payloadBuiltAt
83
110
  }));
84
111
  const deleteTaskIds = new Set([
85
112
  ...deleteChanges.map((change) => String(change.taskId)),
@@ -170,9 +197,13 @@ export function buildWorkspaceSyncPayloadModel(input) {
170
197
  .map((profile) => String(profile?.id || '').trim())
171
198
  .filter((profileId) => profileId.length > 0));
172
199
  const currentAiProfileWatermarks = new Map((Array.isArray(input.aiProfiles) ? input.aiProfiles : [])
173
- .map((profile) => [String(profile?.id || '').trim(), String(profile?.updatedAt || profile?.createdAt || '').trim()])
200
+ .map((profile) => [String(profile?.id || '').trim(), aiProfileSyncResourceAdapter.getWatermark(profile)])
201
+ .filter(([profileId]) => profileId.length > 0));
202
+ const currentAiProfileChangeKeys = new Map((Array.isArray(input.aiProfiles) ? input.aiProfiles : [])
203
+ .map((profile) => [String(profile?.id || '').trim(), aiProfileSyncResourceAdapter.getChangeKey(profile)])
174
204
  .filter(([profileId]) => profileId.length > 0));
175
205
  const previousAiProfileWatermarks = input.lastPushedAiProfileWatermarks;
206
+ const previousAiProfileChangeKeys = input.lastPushedAiProfileChangeKeys;
176
207
  const shouldSendAllAiProfiles = !previousAiProfileWatermarks || previousAiProfileWatermarks.size === 0;
177
208
  const aiProfileUpsertChanges = (Array.isArray(input.aiProfiles) ? input.aiProfiles : [])
178
209
  .map((profile) => ({
@@ -185,14 +216,30 @@ export function buildWorkspaceSyncPayloadModel(input) {
185
216
  username: String(profile.username || '').trim(),
186
217
  icon: String(profile.icon || 'Bot').trim() || 'Bot',
187
218
  color: String(profile.color || '#8b5cf6').trim() || '#8b5cf6',
219
+ avatarUrl: normalizeSyncSameOriginAssetUrl(profile.avatarUrl),
220
+ avatarSourceUrl: normalizeSyncSameOriginAssetUrl(profile.avatarSourceUrl),
188
221
  description: typeof profile.description === 'string' ? profile.description.trim() || null : null,
189
222
  role: typeof profile.role === 'string' ? profile.role.trim() || null : null,
190
223
  provider: typeof profile.provider === 'string' ? profile.provider.trim() || null : null,
191
224
  model: typeof profile.model === 'string' ? profile.model.trim() || null : null,
192
225
  surfaceType: parseAiProfileSurfaceType(profile.surfaceType),
226
+ seatScope: parseAiProfileSeatScope(profile.seatScope),
193
227
  providerMetadata: profile.providerMetadata && typeof profile.providerMetadata === 'object' && !Array.isArray(profile.providerMetadata)
194
228
  ? profile.providerMetadata
195
229
  : null,
230
+ archivedAt: typeof profile.archivedAt === 'string' && profile.archivedAt.trim().length > 0
231
+ ? profile.archivedAt.trim()
232
+ : null,
233
+ archivedBy: typeof profile.archivedBy === 'string' && profile.archivedBy.trim().length > 0
234
+ ? profile.archivedBy.trim()
235
+ : null,
236
+ archivedReason: typeof profile.archivedReason === 'string' ? profile.archivedReason.trim() || null : null,
237
+ mergedIntoProfileId: typeof profile.mergedIntoProfileId === 'string' && profile.mergedIntoProfileId.trim().length > 0
238
+ ? profile.mergedIntoProfileId.trim()
239
+ : null,
240
+ rosterStateUpdatedAt: typeof profile.rosterStateUpdatedAt === 'string' && profile.rosterStateUpdatedAt.trim().length > 0
241
+ ? profile.rosterStateUpdatedAt.trim()
242
+ : null,
196
243
  createdAt: String(profile.createdAt || '').trim(),
197
244
  updatedAt: String(profile.updatedAt || profile.createdAt || '').trim(),
198
245
  lastActiveAt: typeof profile.lastActiveAt === 'string' && profile.lastActiveAt.trim().length > 0
@@ -204,11 +251,13 @@ export function buildWorkspaceSyncPayloadModel(input) {
204
251
  .filter((change) => {
205
252
  if (shouldSendAllAiProfiles)
206
253
  return true;
207
- return previousAiProfileWatermarks.get(change.profile.id) !== change.profile.updatedAt;
254
+ return shouldSyncResource(aiProfileSyncResourceAdapter, change.profile, {
255
+ watermarks: previousAiProfileWatermarks,
256
+ changeKeys: previousAiProfileChangeKeys,
257
+ });
208
258
  });
209
- const currentDocumentPaths = new Set((Array.isArray(input.documents) ? input.documents : [])
210
- .map((doc) => String(doc?.path || '').trim())
211
- .filter((docPath) => docPath.length > 0));
259
+ const currentDocumentPaths = normalizeWorkspaceSyncPathSet(input.currentDocumentPaths, (Array.isArray(input.documents) ? input.documents : [])
260
+ .map((doc) => String(doc?.path || '').trim()));
212
261
  const deleteDocumentPaths = new Set(Array.from(input.lastPushedDocumentPaths || new Set())
213
262
  .map((docPath) => String(docPath || '').trim())
214
263
  .filter((docPath) => docPath.length > 0 && !currentDocumentPaths.has(docPath)));
@@ -239,9 +288,8 @@ export function buildWorkspaceSyncPayloadModel(input) {
239
288
  return true;
240
289
  return previousDocumentWatermarks.get(doc.path) !== doc.updatedAt;
241
290
  });
242
- const currentAssetPaths = new Set((Array.isArray(input.assets) ? input.assets : [])
243
- .map((asset) => String(asset?.path || '').trim())
244
- .filter((assetPath) => assetPath.length > 0));
291
+ const currentAssetPaths = normalizeWorkspaceSyncPathSet(input.currentAssetPaths, (Array.isArray(input.assets) ? input.assets : [])
292
+ .map((asset) => String(asset?.path || '').trim()));
245
293
  const deleteAssetPaths = new Set(Array.from(input.lastPushedAssetPaths || new Set())
246
294
  .map((assetPath) => String(assetPath || '').trim())
247
295
  .filter((assetPath) => assetPath.length > 0 && !currentAssetPaths.has(assetPath)));
@@ -489,11 +537,52 @@ export function buildWorkspaceSyncPayloadModel(input) {
489
537
  ...taskEventUpsertChanges,
490
538
  ...activeChanges,
491
539
  ...archivedChanges,
492
- ...Array.from(deleteTaskIds).map((taskId) => ({ op: 'delete', taskId }))
540
+ ...Array.from(deleteTaskIds).map((taskId) => ({
541
+ op: 'delete',
542
+ taskId,
543
+ deletedAt: pendingDeleteWatermarks.get(taskId) || payloadBuiltAt
544
+ }))
493
545
  ];
546
+ const baselineResetReason = input.baselineResetReason ?? null;
547
+ const resolveDomainDeltaDiagnostics = (args) => {
548
+ const changeCount = args.upsertCount + (args.deleteCount || 0);
549
+ if (args.currentCount === 0 && changeCount === 0) {
550
+ return {
551
+ mode: 'none',
552
+ reason: null,
553
+ currentCount: 0,
554
+ baselineCount: args.baselineCount,
555
+ changeCount
556
+ };
557
+ }
558
+ if (args.alwaysFull) {
559
+ return {
560
+ mode: changeCount > 0 ? 'send-all' : 'none',
561
+ reason: changeCount > 0 ? 'full-state-domain' : null,
562
+ currentCount: args.currentCount,
563
+ baselineCount: args.baselineCount,
564
+ changeCount
565
+ };
566
+ }
567
+ const shouldSendAll = args.baselineCount === 0 && args.currentCount > 0 && args.upsertCount >= args.currentCount;
568
+ return {
569
+ mode: shouldSendAll ? 'send-all' : 'delta',
570
+ reason: shouldSendAll ? (baselineResetReason || 'missing-baseline') : null,
571
+ currentCount: args.currentCount,
572
+ baselineCount: args.baselineCount,
573
+ changeCount
574
+ };
575
+ };
576
+ const byOp = changes.reduce((acc, change) => {
577
+ const op = String(change.op || '').trim();
578
+ acc[op] = (acc[op] || 0) + 1;
579
+ return acc;
580
+ }, {});
494
581
  return {
495
582
  changes,
496
583
  currentTaskIds: new Set(Array.from(currentTaskIds).filter((taskId) => !pendingDeleteIds.has(taskId))),
584
+ currentTaskWatermarks: new Map(Array.from(currentTaskWatermarks.entries()).filter(([taskId]) => !pendingDeleteIds.has(taskId))),
585
+ currentTaskChangeKeys: new Map(Array.from(currentTaskChangeKeys.entries()).filter(([taskId]) => !pendingDeleteIds.has(taskId))),
497
586
  deleteTaskIds,
498
587
  currentInitiativeIds,
499
588
  currentInitiativeWatermarks,
@@ -501,6 +590,7 @@ export function buildWorkspaceSyncPayloadModel(input) {
501
590
  currentWorkstreamWatermarks,
502
591
  currentAiProfileIds,
503
592
  currentAiProfileWatermarks,
593
+ currentAiProfileChangeKeys,
504
594
  currentDocumentPaths,
505
595
  deleteDocumentPaths,
506
596
  currentDocumentWatermarks,
@@ -517,7 +607,77 @@ export function buildWorkspaceSyncPayloadModel(input) {
517
607
  deleteAnnotatedAttachmentSessionIds,
518
608
  currentAnnotatedAttachmentSessionWatermarks,
519
609
  currentTaskEventWatermarks,
520
- pushedWatermarks
610
+ pushedWatermarks,
611
+ pushedTaskChangeKeys,
612
+ deltaDiagnostics: {
613
+ totalChanges: changes.length,
614
+ byOp,
615
+ baselineResetReason,
616
+ domains: {
617
+ tasks: resolveDomainDeltaDiagnostics({
618
+ currentCount: currentTaskIds.size,
619
+ baselineCount: lastWatermarks?.size || 0,
620
+ upsertCount: activeChanges.length + archivedChanges.length,
621
+ deleteCount: deleteTaskIds.size
622
+ }),
623
+ initiatives: resolveDomainDeltaDiagnostics({
624
+ currentCount: currentInitiativeIds.size,
625
+ baselineCount: previousInitiativeWatermarks?.size || 0,
626
+ upsertCount: initiativeUpsertChanges.length
627
+ }),
628
+ workstreams: resolveDomainDeltaDiagnostics({
629
+ currentCount: currentWorkstreamIds.size,
630
+ baselineCount: previousWorkstreamWatermarks?.size || 0,
631
+ upsertCount: workstreamUpsertChanges.length
632
+ }),
633
+ aiProfiles: resolveDomainDeltaDiagnostics({
634
+ currentCount: currentAiProfileIds.size,
635
+ baselineCount: previousAiProfileWatermarks?.size || 0,
636
+ upsertCount: aiProfileUpsertChanges.length
637
+ }),
638
+ documents: resolveDomainDeltaDiagnostics({
639
+ currentCount: currentDocumentPaths.size,
640
+ baselineCount: previousDocumentWatermarks?.size || 0,
641
+ upsertCount: documentUpsertChanges.length,
642
+ deleteCount: deleteDocumentPaths.size
643
+ }),
644
+ assets: resolveDomainDeltaDiagnostics({
645
+ currentCount: currentAssetPaths.size,
646
+ baselineCount: previousAssetWatermarks?.size || 0,
647
+ upsertCount: assetUpsertChanges.length,
648
+ deleteCount: deleteAssetPaths.size
649
+ }),
650
+ documentReviewSessions: resolveDomainDeltaDiagnostics({
651
+ currentCount: currentDocumentReviewSessionIds.size,
652
+ baselineCount: previousDocumentReviewSessionWatermarks?.size || 0,
653
+ upsertCount: documentReviewSessionUpsertChanges.length,
654
+ deleteCount: deleteDocumentReviewSessionIds.size
655
+ }),
656
+ documentReviewComments: resolveDomainDeltaDiagnostics({
657
+ currentCount: currentDocumentReviewCommentIds.size,
658
+ baselineCount: previousDocumentReviewCommentWatermarks?.size || 0,
659
+ upsertCount: documentReviewCommentUpsertChanges.length,
660
+ deleteCount: deleteDocumentReviewCommentIds.size
661
+ }),
662
+ annotatedAttachmentSessions: resolveDomainDeltaDiagnostics({
663
+ currentCount: currentAnnotatedAttachmentSessionIds.size,
664
+ baselineCount: previousAnnotatedAttachmentSessionWatermarks?.size || 0,
665
+ upsertCount: annotatedAttachmentSessionUpsertChanges.length,
666
+ deleteCount: deleteAnnotatedAttachmentSessionIds.size
667
+ }),
668
+ taskEvents: resolveDomainDeltaDiagnostics({
669
+ currentCount: currentTaskEventWatermarks.size,
670
+ baselineCount: previousTaskEventWatermarks?.size || 0,
671
+ upsertCount: taskEventUpsertChanges.length
672
+ }),
673
+ taxonomy: resolveDomainDeltaDiagnostics({
674
+ currentCount: (input.taxonomyState && typeof input.taxonomyState === 'object') || Array.isArray(input.taxonomies) ? 1 : 0,
675
+ baselineCount: 0,
676
+ upsertCount: byOp['taxonomy-upsert'] || 0,
677
+ alwaysFull: true
678
+ })
679
+ }
680
+ }
521
681
  };
522
682
  }
523
683
  export function buildWorkspaceSyncSignatureModel(input) {
@@ -561,7 +721,11 @@ export function buildWorkspaceSyncSignatureModel(input) {
561
721
  id: String(profile.id || '').trim(),
562
722
  updatedAt: String(profile.updatedAt || profile.createdAt || '').trim(),
563
723
  name: String(profile.name || '').trim(),
564
- username: String(profile.username || '').trim()
724
+ username: String(profile.username || '').trim(),
725
+ archivedAt: String(profile.archivedAt || '').trim(),
726
+ archivedReason: String(profile.archivedReason || '').trim(),
727
+ mergedIntoProfileId: String(profile.mergedIntoProfileId || '').trim(),
728
+ rosterStateUpdatedAt: String(profile.rosterStateUpdatedAt || '').trim()
565
729
  }))
566
730
  .filter((profile) => profile.id.length > 0)
567
731
  .sort((a, b) => a.id.localeCompare(b.id))