@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
@@ -1,13 +1,39 @@
1
1
  import { serializeTaskForSync } from './taskSyncPayload.js';
2
+ import { aiProfileSyncResourceAdapter, taskSyncResourceAdapter } from './syncResourceAdapters.js';
2
3
  export async function buildWorkspacePullFeed(input) {
3
4
  const buildStartedAtMs = Date.now();
4
5
  const { core, workspaceId, cursor, pageSize, encodeWorkspaceSyncCursor, contentSyncState, collaborationSyncState } = input;
5
6
  const syncCursor = cursor ? { watermark: cursor.u, id: cursor.id } : null;
6
7
  const dbFetchLimit = pageSize * 2 + 10;
8
+ const snapshotErrors = [];
9
+ const captureSnapshotError = (domain, error) => {
10
+ snapshotErrors.push({
11
+ domain,
12
+ error: String(error?.message || error || 'Unknown snapshot error')
13
+ });
14
+ };
15
+ const readSnapshot = (domain, fallback, reader) => {
16
+ try {
17
+ return reader();
18
+ }
19
+ catch (error) {
20
+ captureSnapshotError(domain, error);
21
+ return fallback;
22
+ }
23
+ };
24
+ const readSnapshotAsync = async (domain, fallback, reader) => {
25
+ try {
26
+ return await reader();
27
+ }
28
+ catch (error) {
29
+ captureSnapshotError(domain, error);
30
+ return fallback;
31
+ }
32
+ };
7
33
  const taskRows = core.listTasksForSync(workspaceId, syncCursor, dbFetchLimit);
8
34
  const upsertEntries = taskRows
9
35
  .map((entry) => {
10
- const watermark = String(entry.task?.updatedAt || entry.task?.createdAt || '').trim();
36
+ const watermark = taskSyncResourceAdapter.getWatermark(entry.task);
11
37
  const taskId = String(entry.task?.id || '').trim();
12
38
  return {
13
39
  kind: 'upsert',
@@ -27,7 +53,7 @@ export async function buildWorkspacePullFeed(input) {
27
53
  taskId: String(entry.taskId || '').trim()
28
54
  }))
29
55
  .filter((entry) => Number.isFinite(Date.parse(entry.watermark)) && entry.sortId.length > 0);
30
- const taxonomySnapshot = core.getTaxonomiesSyncSnapshot(workspaceId);
56
+ const taxonomySnapshot = readSnapshot('taxonomy', null, () => core.getTaxonomiesSyncSnapshot(workspaceId));
31
57
  const taxonomyEntries = (taxonomySnapshot
32
58
  && Array.isArray(taxonomySnapshot.taxonomies)
33
59
  && Number.isFinite(Date.parse(String(taxonomySnapshot.updatedAt || '').trim())))
@@ -39,7 +65,7 @@ export async function buildWorkspacePullFeed(input) {
39
65
  ...(taxonomySnapshot.taxonomyState ? { taxonomyState: taxonomySnapshot.taxonomyState } : {})
40
66
  }]
41
67
  : [];
42
- const initiativeEntries = core.listInitiatives(workspaceId)
68
+ const initiativeEntries = readSnapshot('initiatives', [], () => core.listInitiatives(workspaceId))
43
69
  .map((initiative) => ({
44
70
  kind: 'initiative',
45
71
  watermark: String(initiative.updatedAt || initiative.createdAt || '').trim(),
@@ -47,7 +73,7 @@ export async function buildWorkspacePullFeed(input) {
47
73
  initiative
48
74
  }))
49
75
  .filter((entry) => Number.isFinite(Date.parse(entry.watermark)) && entry.initiative.id.length > 0);
50
- const workstreamEntries = core.listWorkstreams(workspaceId)
76
+ const workstreamEntries = readSnapshot('workstreams', [], () => core.listWorkstreams(workspaceId))
51
77
  .map((workstream) => ({
52
78
  kind: 'workstream',
53
79
  watermark: String(workstream.updatedAt || workstream.createdAt || '').trim(),
@@ -55,16 +81,16 @@ export async function buildWorkspacePullFeed(input) {
55
81
  workstream
56
82
  }))
57
83
  .filter((entry) => Number.isFinite(Date.parse(entry.watermark)) && entry.workstream.id.length > 0);
58
- const aiProfileEntries = core.listAiProfiles(workspaceId)
84
+ const aiProfileEntries = readSnapshot('ai-profiles', [], () => core.listAiProfiles(workspaceId, { includeArchived: true }))
59
85
  .map((profile) => ({
60
86
  kind: 'ai-profile',
61
- watermark: String(profile.updatedAt || profile.createdAt || '').trim(),
87
+ watermark: aiProfileSyncResourceAdapter.getWatermark(profile),
62
88
  sortId: `ai-profile:${String(profile.id || '').trim()}`,
63
89
  profile
64
90
  }))
65
91
  .filter((entry) => Number.isFinite(Date.parse(entry.watermark)) && entry.sortId.length > 0);
66
92
  const indexStartedAtMs = Date.now();
67
- const documentIndex = await contentSyncState.listWorkspaceSyncDocumentIndex(core.getPaths().basePath, workspaceId);
93
+ const documentIndex = await readSnapshotAsync('documents.index', [], () => contentSyncState.listWorkspaceSyncDocumentIndex(core.getPaths().basePath, workspaceId));
68
94
  const documentEntries = documentIndex
69
95
  .map((doc) => ({
70
96
  kind: 'document',
@@ -76,13 +102,15 @@ export async function buildWorkspacePullFeed(input) {
76
102
  referenceNumber: doc.referenceNumber,
77
103
  version: doc.version,
78
104
  taskId: doc.taskId,
105
+ linkTargetType: doc.linkTargetType,
106
+ linkTargetId: doc.linkTargetId,
79
107
  logicalName: doc.logicalName,
80
108
  caption: doc.caption,
81
109
  originalFilename: doc.originalFilename,
82
110
  linkRole: (doc.linkRole === 'reference' ? 'reference' : 'attachment')
83
111
  }))
84
112
  .filter((entry) => Number.isFinite(Date.parse(entry.watermark)) && entry.path.length > 0);
85
- const documentDeleteEntries = contentSyncState.listWorkspaceSyncDocumentDeletesSnapshot(workspaceId)
113
+ const documentDeleteEntries = readSnapshot('documents.deletes', [], () => contentSyncState.listWorkspaceSyncDocumentDeletesSnapshot(workspaceId))
86
114
  .map((doc) => ({
87
115
  kind: 'document-delete',
88
116
  watermark: String(doc.deletedAt || '').trim(),
@@ -91,7 +119,7 @@ export async function buildWorkspacePullFeed(input) {
91
119
  assetId: typeof doc.assetId === 'string' && doc.assetId.trim().length > 0 ? doc.assetId.trim() : undefined
92
120
  }))
93
121
  .filter((entry) => Number.isFinite(Date.parse(entry.watermark)) && entry.path.length > 0);
94
- const documentReviewSessions = collaborationSyncState.listWorkspaceSyncDocumentReviewSessionsSnapshot(workspaceId);
122
+ const documentReviewSessions = readSnapshot('document-review-sessions', [], () => collaborationSyncState.listWorkspaceSyncDocumentReviewSessionsSnapshot(workspaceId));
95
123
  const documentReviewSessionEntries = documentReviewSessions
96
124
  .filter((session) => !session.deletedAt)
97
125
  .map((session) => ({
@@ -110,7 +138,7 @@ export async function buildWorkspacePullFeed(input) {
110
138
  sessionId: String(session.id || '').trim()
111
139
  }))
112
140
  .filter((entry) => Number.isFinite(Date.parse(entry.watermark)) && entry.sessionId.length > 0);
113
- const documentReviewComments = collaborationSyncState.listWorkspaceSyncDocumentReviewCommentsSnapshot(workspaceId);
141
+ const documentReviewComments = readSnapshot('document-review-comments', [], () => collaborationSyncState.listWorkspaceSyncDocumentReviewCommentsSnapshot(workspaceId));
114
142
  const documentReviewCommentEntries = documentReviewComments
115
143
  .filter((comment) => !comment.deletedAt)
116
144
  .map((comment) => ({
@@ -129,7 +157,7 @@ export async function buildWorkspacePullFeed(input) {
129
157
  commentId: String(comment.id || '').trim()
130
158
  }))
131
159
  .filter((entry) => Number.isFinite(Date.parse(entry.watermark)) && entry.commentId.length > 0);
132
- const annotatedAttachmentSessions = collaborationSyncState.listWorkspaceSyncAnnotatedAttachmentSessionsSnapshot(workspaceId);
160
+ const annotatedAttachmentSessions = readSnapshot('annotated-attachment-sessions', [], () => collaborationSyncState.listWorkspaceSyncAnnotatedAttachmentSessionsSnapshot(workspaceId));
133
161
  const annotatedAttachmentSessionEntries = annotatedAttachmentSessions
134
162
  .filter((session) => !session.deletedAt)
135
163
  .map((session) => ({
@@ -148,15 +176,38 @@ export async function buildWorkspacePullFeed(input) {
148
176
  sessionId: String(session.id || '').trim()
149
177
  }))
150
178
  .filter((entry) => Number.isFinite(Date.parse(entry.watermark)) && entry.sessionId.length > 0);
151
- const taskEventEntries = collaborationSyncState.listWorkspaceSyncTaskEventsSnapshot(workspaceId)
152
- .map((event) => ({
153
- kind: 'task-event',
154
- watermark: String(event.createdAt || '').trim(),
155
- sortId: `task-event:${String(event.id || '').trim()}`,
156
- event
157
- }))
158
- .filter((entry) => Number.isFinite(Date.parse(entry.watermark)) && entry.event.id.length > 0 && entry.event.taskId.length > 0);
159
- const assetIndex = await contentSyncState.listWorkspaceSyncBinaryAssetIndex(workspaceId);
179
+ const taskEventEntries = readSnapshot('task-events', [], () => collaborationSyncState.listWorkspaceSyncTaskEventsSnapshot(workspaceId))
180
+ .map((event) => {
181
+ const entityType = event.entityType === 'initiative' || event.entityType === 'workstream'
182
+ ? event.entityType
183
+ : 'task';
184
+ const entityId = String(event.entityId || event.taskId || '').trim();
185
+ if (entityType === 'task') {
186
+ return {
187
+ kind: 'task-event',
188
+ watermark: String(event.createdAt || '').trim(),
189
+ sortId: `task-event:${String(event.id || '').trim()}`,
190
+ event: {
191
+ ...event,
192
+ entityType: 'task',
193
+ entityId,
194
+ taskId: String(event.taskId || entityId).trim(),
195
+ },
196
+ };
197
+ }
198
+ return {
199
+ kind: 'entity-event',
200
+ watermark: String(event.createdAt || '').trim(),
201
+ sortId: `entity-event:${String(event.id || '').trim()}`,
202
+ event: {
203
+ ...event,
204
+ entityType,
205
+ entityId,
206
+ },
207
+ };
208
+ })
209
+ .filter((entry) => Number.isFinite(Date.parse(entry.watermark)) && entry.event.id.length > 0 && entry.event.entityId.length > 0 && (entry.kind !== 'task-event' || Boolean(entry.event.taskId)));
210
+ const assetIndex = await readSnapshotAsync('assets.index', [], () => contentSyncState.listWorkspaceSyncBinaryAssetIndex(workspaceId));
160
211
  const assetEntries = assetIndex
161
212
  .map((asset) => ({
162
213
  kind: 'asset',
@@ -168,13 +219,15 @@ export async function buildWorkspacePullFeed(input) {
168
219
  mimeType: asset.mimeType,
169
220
  referenceNumber: asset.referenceNumber,
170
221
  taskId: asset.taskId,
222
+ linkTargetType: asset.linkTargetType,
223
+ linkTargetId: asset.linkTargetId,
171
224
  logicalName: asset.logicalName,
172
225
  caption: asset.caption,
173
226
  originalFilename: asset.originalFilename,
174
227
  linkRole: asset.linkRole
175
228
  }))
176
229
  .filter((entry) => Number.isFinite(Date.parse(entry.watermark)) && entry.path.length > 0);
177
- const assetDeleteEntries = contentSyncState.listWorkspaceSyncBinaryAssetDeletesSnapshot(workspaceId)
230
+ const assetDeleteEntries = readSnapshot('assets.deletes', [], () => contentSyncState.listWorkspaceSyncBinaryAssetDeletesSnapshot(workspaceId))
178
231
  .map((asset) => ({
179
232
  kind: 'asset-delete',
180
233
  watermark: String(asset.deletedAt || '').trim(),
@@ -217,7 +270,7 @@ export async function buildWorkspacePullFeed(input) {
217
270
  return String(a.sortId || '').localeCompare(String(b.sortId || ''));
218
271
  });
219
272
  const page = afterCursor.slice(0, pageSize);
220
- const workspaceMembers = core.listWorkspaceUsers(workspaceId).map((member) => ({
273
+ const workspaceMembers = readSnapshot('workspace-members', [], () => core.listWorkspaceUsers(workspaceId)).map((member) => ({
221
274
  userId: member.userId,
222
275
  workspaceId,
223
276
  email: member.email,
@@ -286,55 +339,61 @@ export async function buildWorkspacePullFeed(input) {
286
339
  ? [{ op: 'annotated-attachment-session-delete', sessionId: entry.sessionId, deletedAt: entry.watermark, watermark: entry.watermark }]
287
340
  : entry.kind === 'task-event'
288
341
  ? [{ op: 'task-event-upsert', event: entry.event, watermark: entry.watermark }]
289
- : entry.kind === 'document'
290
- ? (() => {
291
- const payload = hydratedDocuments.get(entry.path);
292
- if (!payload)
293
- return [];
294
- return [{
295
- op: 'document-upsert',
296
- path: entry.path,
297
- updatedAt: entry.watermark,
298
- content: payload.content,
299
- assetId: payload.assetId,
300
- documentId: payload.documentId,
301
- referenceNumber: payload.referenceNumber,
302
- version: payload.version,
303
- taskId: payload.taskId,
304
- logicalName: payload.logicalName,
305
- caption: payload.caption,
306
- originalFilename: payload.originalFilename,
307
- linkRole: payload.linkRole === 'reference' ? 'reference' : 'attachment',
308
- watermark: entry.watermark
309
- }];
310
- })()
311
- : entry.kind === 'document-delete'
312
- ? [{ op: 'document-delete', path: entry.path, assetId: entry.assetId, deletedAt: entry.watermark, watermark: entry.watermark }]
313
- : entry.kind === 'asset'
314
- ? (() => {
315
- const payload = hydratedAssets.get(entry.path);
316
- if (!payload)
317
- return [];
318
- return [{
319
- op: 'asset-upsert',
320
- path: entry.path,
321
- updatedAt: entry.watermark,
322
- contentBase64: payload.contentBase64,
323
- assetId: payload.assetId,
324
- kind: payload.kind,
325
- mimeType: payload.mimeType,
326
- referenceNumber: payload.referenceNumber,
327
- taskId: payload.taskId,
328
- logicalName: payload.logicalName,
329
- caption: payload.caption,
330
- originalFilename: payload.originalFilename,
331
- linkRole: payload.linkRole,
332
- watermark: entry.watermark
333
- }];
334
- })()
335
- : entry.kind === 'asset-delete'
336
- ? [{ op: 'asset-delete', path: entry.path, assetId: entry.assetId, deletedAt: entry.watermark, watermark: entry.watermark }]
337
- : [{ op: 'upsert', task: entry.task, archived: Boolean(entry.archived), watermark: entry.watermark }]));
342
+ : entry.kind === 'entity-event'
343
+ ? [{ op: 'entity-event-upsert', event: entry.event, watermark: entry.watermark }]
344
+ : entry.kind === 'document'
345
+ ? (() => {
346
+ const payload = hydratedDocuments.get(entry.path);
347
+ if (!payload)
348
+ return [];
349
+ return [{
350
+ op: 'document-upsert',
351
+ path: entry.path,
352
+ updatedAt: entry.watermark,
353
+ content: payload.content,
354
+ assetId: payload.assetId,
355
+ documentId: payload.documentId,
356
+ referenceNumber: payload.referenceNumber,
357
+ version: payload.version,
358
+ taskId: payload.taskId,
359
+ linkTargetType: payload.linkTargetType,
360
+ linkTargetId: payload.linkTargetId,
361
+ logicalName: payload.logicalName,
362
+ caption: payload.caption,
363
+ originalFilename: payload.originalFilename,
364
+ linkRole: payload.linkRole === 'reference' ? 'reference' : 'attachment',
365
+ watermark: entry.watermark
366
+ }];
367
+ })()
368
+ : entry.kind === 'document-delete'
369
+ ? [{ op: 'document-delete', path: entry.path, assetId: entry.assetId, deletedAt: entry.watermark, watermark: entry.watermark }]
370
+ : entry.kind === 'asset'
371
+ ? (() => {
372
+ const payload = hydratedAssets.get(entry.path);
373
+ if (!payload)
374
+ return [];
375
+ return [{
376
+ op: 'asset-upsert',
377
+ path: entry.path,
378
+ updatedAt: entry.watermark,
379
+ contentBase64: payload.contentBase64,
380
+ assetId: payload.assetId,
381
+ kind: payload.kind,
382
+ mimeType: payload.mimeType,
383
+ referenceNumber: payload.referenceNumber,
384
+ taskId: payload.taskId,
385
+ linkTargetType: payload.linkTargetType,
386
+ linkTargetId: payload.linkTargetId,
387
+ logicalName: payload.logicalName,
388
+ caption: payload.caption,
389
+ originalFilename: payload.originalFilename,
390
+ linkRole: payload.linkRole,
391
+ watermark: entry.watermark
392
+ }];
393
+ })()
394
+ : entry.kind === 'asset-delete'
395
+ ? [{ op: 'asset-delete', path: entry.path, assetId: entry.assetId, deletedAt: entry.watermark, watermark: entry.watermark }]
396
+ : [{ op: 'upsert', task: entry.task, archived: Boolean(entry.archived), watermark: entry.watermark }]));
338
397
  const encodeMs = Date.now() - encodeStartedAtMs;
339
398
  return {
340
399
  workspaceMembers,
@@ -350,7 +409,8 @@ export async function buildWorkspacePullFeed(input) {
350
409
  indexMs,
351
410
  hydrationMs,
352
411
  encodeMs,
353
- buildMs: Date.now() - buildStartedAtMs
412
+ buildMs: Date.now() - buildStartedAtMs,
413
+ snapshotErrors
354
414
  }
355
415
  };
356
416
  }
@@ -126,6 +126,7 @@ describe('workspacePullFeed', () => {
126
126
  userId: 'user-1',
127
127
  email: 'person@example.com',
128
128
  displayName: 'Person',
129
+ avatarUrl: '/api/taskforce/context/users%2Fuser-1%2Fprofile%2Favatar%2Fheadshot.webp',
129
130
  role: 'owner',
130
131
  permissionMode: 'read-write',
131
132
  betaAccess: true,
@@ -167,6 +168,97 @@ describe('workspacePullFeed', () => {
167
168
  displayName: 'Person',
168
169
  })
169
170
  ]);
171
+ expect(result.workspaceMembers[0]).not.toHaveProperty('avatarUrl');
172
+ });
173
+ it('includes ai-profile upserts with avatar fields in the pull feed', async () => {
174
+ const core = createCoreMock();
175
+ core.listAiProfiles = () => [
176
+ {
177
+ id: 'ai-profile-1',
178
+ workspaceId: 'workspace-1',
179
+ profileToken: 'tfp_test',
180
+ name: 'Codex',
181
+ username: 'codex',
182
+ icon: 'Bot',
183
+ color: '#0ea5e9',
184
+ avatarUrl: '/api/taskforce/context/workspaces%2Fworkspace-1%2Fassets%2Fimages%2Fai-profiles%2Fai-profile-1%2Favatar%2Favatar.webp',
185
+ avatarSourceUrl: '/api/taskforce/context/workspaces%2Fworkspace-1%2Fassets%2Fimages%2Fai-profiles%2Fai-profile-1%2Favatar%2Fsource.webp',
186
+ createdAt: '2026-04-10T10:00:00.000Z',
187
+ updatedAt: '2026-04-10T10:05:00.000Z',
188
+ lastActiveAt: '2026-04-10T10:05:00.000Z'
189
+ }
190
+ ];
191
+ const result = await buildWorkspacePullFeed({
192
+ core,
193
+ workspaceId: 'workspace-1',
194
+ cursor: null,
195
+ pageSize: 10,
196
+ encodeWorkspaceSyncCursor: encodeCursor,
197
+ contentSyncState: createContentSyncStateMock(),
198
+ collaborationSyncState: createCollaborationSyncStateMock(),
199
+ });
200
+ expect(result.changes).toEqual([
201
+ expect.objectContaining({
202
+ op: 'ai-profile-upsert',
203
+ watermark: '2026-04-10T10:05:00.000Z',
204
+ profile: expect.objectContaining({
205
+ id: 'ai-profile-1',
206
+ avatarUrl: expect.stringContaining('/api/taskforce/context/'),
207
+ avatarSourceUrl: expect.stringContaining('/api/taskforce/context/')
208
+ })
209
+ })
210
+ ]);
211
+ expect(result.nextCursor).toBe('2026-04-10T10:05:00.000Z|ai-profile:ai-profile-1');
212
+ expect(result.hasMore).toBe(false);
213
+ });
214
+ it('degrades optional snapshot failures into diagnostics instead of throwing the pull feed', async () => {
215
+ const core = createCoreMock();
216
+ const content = createContentSyncStateMock();
217
+ const collaboration = createCollaborationSyncStateMock();
218
+ core.listTasksForSync = () => [
219
+ {
220
+ archived: false,
221
+ task: {
222
+ id: 'task-1',
223
+ title: 'Still syncs tasks',
224
+ status: 'task',
225
+ category: 'general',
226
+ type: 'task',
227
+ createdAt: '2026-04-10T10:00:00.000Z',
228
+ }
229
+ }
230
+ ];
231
+ core.listWorkspaceUsers = () => {
232
+ throw new Error('workspace members exploded');
233
+ };
234
+ content.listWorkspaceSyncBinaryAssetIndex = async () => {
235
+ throw new Error('asset index exploded');
236
+ };
237
+ collaboration.listWorkspaceSyncDocumentReviewSessionsSnapshot = () => {
238
+ throw new Error('review sessions exploded');
239
+ };
240
+ const result = await buildWorkspacePullFeed({
241
+ core,
242
+ workspaceId: 'workspace-1',
243
+ cursor: null,
244
+ pageSize: 10,
245
+ encodeWorkspaceSyncCursor: encodeCursor,
246
+ contentSyncState: content,
247
+ collaborationSyncState: collaboration,
248
+ });
249
+ expect(result.changes).toEqual([
250
+ expect.objectContaining({
251
+ op: 'upsert',
252
+ task: expect.objectContaining({ id: 'task-1' })
253
+ })
254
+ ]);
255
+ expect(result.workspaceMembers).toEqual([]);
256
+ expect(result.diagnostics.assetIndexCount).toBe(0);
257
+ expect(result.diagnostics.snapshotErrors).toEqual(expect.arrayContaining([
258
+ expect.objectContaining({ domain: 'assets.index', error: 'asset index exploded' }),
259
+ expect.objectContaining({ domain: 'document-review-sessions', error: 'review sessions exploded' }),
260
+ expect.objectContaining({ domain: 'workspace-members', error: 'workspace members exploded' }),
261
+ ]));
170
262
  });
171
263
  it('hydrates document and asset payloads only for entries included in the current page', async () => {
172
264
  const core = createCoreMock();
@@ -338,8 +338,9 @@ export function scanWorkspaceRepair(input) {
338
338
  for (const asset of assets) {
339
339
  const links = input.workspaceAssetStore.listLinksForAsset(asset.assetId, snapshot.workspaceId, { includeDeleted: false });
340
340
  for (const link of links) {
341
- if (activeTaskIds.has(link.taskId))
341
+ if (link.targetType === 'task' && link.taskId && activeTaskIds.has(link.taskId))
342
342
  continue;
343
+ const linkedTargetId = link.targetId;
343
344
  issues.push({
344
345
  code: 'stale_asset_link',
345
346
  entityKind: 'link',
@@ -349,7 +350,9 @@ export function scanWorkspaceRepair(input) {
349
350
  role: link.role,
350
351
  repairable: true,
351
352
  recommendedAction: 'delete-link',
352
- detail: 'Canonical asset link points to a task that no longer exists in this workspace.'
353
+ detail: link.targetType === 'task'
354
+ ? 'Canonical asset link points to a task that no longer exists in this workspace.'
355
+ : `Canonical asset link points to a missing ${link.targetType} target (${linkedTargetId}).`
353
356
  });
354
357
  }
355
358
  }