@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,9 +1,16 @@
1
- import { describe, expect, it, vi } from 'vitest';
2
- import { applyCollaborationSyncChanges, applyContentSyncChanges, applyPreparedTaskSyncSnapshot, applyTaskSyncDeletes, classifyWorkspaceSyncChanges, prepareTaskSyncSnapshotApply, } from './syncApplyHandlers.js';
1
+ import fs from 'node:fs';
2
+ import { createHash } from 'node:crypto';
3
+ import { describe, expect, it, vi, afterEach } from 'vitest';
4
+ import { applyCollaborationSyncChanges, applyContentSyncChanges, applyPlanningSyncChanges, applyPreparedTaskSyncSnapshot, applyTaskActivitySyncChanges, applyTaskSyncDeletes, classifyWorkspaceSyncChanges, prepareTaskSyncSnapshotApply, } from './syncApplyHandlers.js';
3
5
  function createCoreFixture(overrides = {}) {
4
6
  return {
5
7
  resolveTaskIdentifier: vi.fn().mockReturnValue(null),
6
8
  getTask: vi.fn().mockReturnValue(null),
9
+ taskExistsForSync: vi.fn().mockReturnValue(true),
10
+ initiativeExistsForSync: vi.fn().mockReturnValue(true),
11
+ workstreamExistsForSync: vi.fn().mockReturnValue(true),
12
+ getTaskEventForSync: vi.fn().mockReturnValue(null),
13
+ getEntityEventForSync: vi.fn().mockReturnValue(null),
7
14
  deleteTaskForSync: vi.fn(),
8
15
  applyWorkspaceSyncSnapshot: vi.fn().mockReturnValue({
9
16
  total: 1,
@@ -29,6 +36,9 @@ function createCoreFixture(overrides = {}) {
29
36
  };
30
37
  }
31
38
  describe('syncApplyHandlers', () => {
39
+ afterEach(() => {
40
+ vi.restoreAllMocks();
41
+ });
32
42
  it('classifies task and workstream changes, then prepares and applies the task snapshot pipeline', () => {
33
43
  const diagnostics = [];
34
44
  const workspaceId = 'workspace-1';
@@ -87,6 +97,7 @@ describe('syncApplyHandlers', () => {
87
97
  normalizeWorkspaceSyncDocumentPath: (rawPath) => typeof rawPath === 'string' ? rawPath : null,
88
98
  normalizeTaskAssetPath: (rawPath) => typeof rawPath === 'string' ? rawPath : null,
89
99
  normalizeIncomingAiProfileSurfaceType: () => null,
100
+ normalizeIncomingAiProfileSeatScope: () => null,
90
101
  normalizeTaskEventSyncPayload: () => null,
91
102
  recordSyncDiagnostic: (targetWorkspaceId, eventType, message, details) => {
92
103
  diagnostics.push({ workspaceId: targetWorkspaceId, eventType, message, details });
@@ -179,6 +190,84 @@ describe('syncApplyHandlers', () => {
179
190
  }, workspaceId);
180
191
  expect(result).toEqual(expect.objectContaining({ total: 1 }));
181
192
  });
193
+ it('preserves planning attachments when applying initiative and workstream sync changes', () => {
194
+ const core = createCoreFixture({
195
+ upsertInitiativeForSync: vi.fn(),
196
+ upsertWorkstreamForSync: vi.fn(),
197
+ updateTaxonomies: vi.fn(),
198
+ });
199
+ applyPlanningSyncChanges({
200
+ core,
201
+ workspaceId: 'workspace-1',
202
+ incomingInitiatives: new Map([
203
+ ['initiative-1', {
204
+ id: 'initiative-1',
205
+ referenceNumber: 12,
206
+ referenceLabel: 'I-12',
207
+ title: 'Initiative',
208
+ description: 'Initiative description',
209
+ ownerId: null,
210
+ createdAt: '2026-04-10T09:00:00.000Z',
211
+ updatedAt: '2026-04-10T10:00:00.000Z',
212
+ order: 1,
213
+ attachments: [{
214
+ path: '/api/taskforce/documents/asset-init-doc/content',
215
+ fsPath: 'workspaces/workspace-1/assets/documents/initiative.md',
216
+ assetId: 'asset-init-doc',
217
+ caption: 'Initiative context',
218
+ timestamp: '2026-04-10T10:00:00.000Z'
219
+ }],
220
+ isArchived: false,
221
+ }],
222
+ ]),
223
+ incomingWorkstreams: new Map([
224
+ ['workstream-1', {
225
+ id: 'workstream-1',
226
+ referenceNumber: 689,
227
+ referenceLabel: 'WS-689',
228
+ initiativeId: 'initiative-1',
229
+ title: 'Security Audit Remediation',
230
+ description: 'Workstream description',
231
+ ownerId: null,
232
+ createdAt: '2026-04-10T09:00:00.000Z',
233
+ updatedAt: '2026-04-10T10:00:00.000Z',
234
+ order: 2,
235
+ attachments: [{
236
+ path: '/api/taskforce/documents/asset-workstream-doc/content',
237
+ fsPath: 'workspaces/workspace-1/assets/documents/security-findings-register.md',
238
+ assetId: 'asset-workstream-doc',
239
+ caption: 'Living security findings register for WS-689',
240
+ timestamp: '2026-04-10T10:00:00.000Z'
241
+ }],
242
+ isArchived: false,
243
+ }],
244
+ ]),
245
+ incomingTaxonomies: null,
246
+ incomingTaxonomyState: null,
247
+ incomingTaxonomiesUpdatedAt: '',
248
+ workspaceTaxonomySyncMeta: new Map(),
249
+ recordSyncDiagnostic: vi.fn(),
250
+ });
251
+ expect(core.upsertInitiativeForSync).toHaveBeenCalledWith(expect.objectContaining({
252
+ id: 'initiative-1',
253
+ attachments: [
254
+ expect.objectContaining({
255
+ assetId: 'asset-init-doc',
256
+ caption: 'Initiative context'
257
+ })
258
+ ]
259
+ }), 'workspace-1');
260
+ expect(core.upsertWorkstreamForSync).toHaveBeenCalledWith(expect.objectContaining({
261
+ id: 'workstream-1',
262
+ referenceLabel: 'WS-689',
263
+ attachments: [
264
+ expect.objectContaining({
265
+ assetId: 'asset-workstream-doc',
266
+ caption: 'Living security findings register for WS-689'
267
+ })
268
+ ]
269
+ }), 'workspace-1');
270
+ });
182
271
  it('applies document and asset changes through the content handler helpers', async () => {
183
272
  const core = createCoreFixture();
184
273
  const writeWorkspaceSyncDocument = vi.fn().mockResolvedValue(undefined);
@@ -231,7 +320,7 @@ describe('syncApplyHandlers', () => {
231
320
  expect(core.notifyDocumentMetadataMutation).toHaveBeenNthCalledWith(1, 'workspace-1', ['docs/spec.md', 'assets/proof.png'], 'upsert');
232
321
  expect(core.notifyDocumentMetadataMutation).toHaveBeenNthCalledWith(2, 'workspace-1', ['docs/stale.md', 'assets/stale.png'], 'delete');
233
322
  });
234
- it('only allows reference reassignment for content writes when the content changed or repair is explicit', async () => {
323
+ it('allows reference reassignment when metadata drift requires normal sync convergence', async () => {
235
324
  const core = createCoreFixture({
236
325
  getDocumentWatermark: vi.fn().mockReturnValue(null),
237
326
  });
@@ -280,9 +369,112 @@ describe('syncApplyHandlers', () => {
280
369
  }),
281
370
  recordSyncDiagnostic: vi.fn(),
282
371
  });
283
- expect(writeWorkspaceSyncDocument).toHaveBeenCalledWith('/tmp/taskforce-sync-content', expect.objectContaining({ path: 'docs/spec.md' }), 'workspace-1', { allowReferenceNumberReassignment: false });
372
+ expect(writeWorkspaceSyncDocument).toHaveBeenCalledWith('/tmp/taskforce-sync-content', expect.objectContaining({ path: 'docs/spec.md' }), 'workspace-1', { allowReferenceNumberReassignment: true });
284
373
  expect(writeWorkspaceSyncBinaryAsset).toHaveBeenCalledWith('/tmp/taskforce-sync-content', expect.objectContaining({ path: 'assets/proof.png' }), 'workspace-1', { allowReferenceNumberReassignment: true });
285
374
  });
375
+ it('reuses persisted content hashes instead of re-reading unchanged local files while reasserting object storage payloads', async () => {
376
+ const existingDocContent = '# Spec';
377
+ const existingAssetBytes = Buffer.from('png-bytes');
378
+ const core = createCoreFixture({
379
+ getDocumentWatermark: vi.fn().mockReturnValue({
380
+ updatedAt: '2026-04-10T10:00:00.000Z',
381
+ contentHash: createHash('sha256').update(existingDocContent).digest('hex'),
382
+ }),
383
+ });
384
+ const writeWorkspaceSyncDocument = vi.fn().mockResolvedValue(undefined);
385
+ const writeWorkspaceSyncBinaryAsset = vi.fn().mockResolvedValue(undefined);
386
+ const readSpy = vi.spyOn(fs, 'readFileSync').mockImplementation(((targetPath) => {
387
+ const value = String(targetPath);
388
+ if (value.endsWith('spec.md'))
389
+ return existingDocContent;
390
+ return existingAssetBytes;
391
+ }));
392
+ await applyContentSyncChanges({
393
+ core,
394
+ workspaceId: 'workspace-1',
395
+ incomingDocuments: [
396
+ {
397
+ path: 'docs/spec.md',
398
+ updatedAt: '2026-04-10T10:00:00.000Z',
399
+ content: existingDocContent,
400
+ assetId: 'asset-doc-1',
401
+ },
402
+ ],
403
+ incomingDocumentDeletes: new Map(),
404
+ incomingAssets: [
405
+ {
406
+ path: 'assets/proof.png',
407
+ updatedAt: '2026-04-10T10:05:00.000Z',
408
+ contentBase64: existingAssetBytes.toString('base64'),
409
+ assetId: 'asset-image-1',
410
+ kind: 'image',
411
+ mimeType: 'image/png',
412
+ },
413
+ ],
414
+ incomingAssetDeletes: new Map(),
415
+ basePath: '/tmp/taskforce-sync-content',
416
+ hasObjectStorageClient: () => true,
417
+ hasDocumentSyncMetadataDrift: () => false,
418
+ hasBinaryAssetSyncMetadataDrift: () => false,
419
+ getExistingDocument: () => {
420
+ throw new Error('document fallback should not be used when persisted metadata exists');
421
+ },
422
+ writeWorkspaceSyncDocument,
423
+ deleteWorkspaceSyncDocument: vi.fn(),
424
+ writeWorkspaceSyncBinaryAsset,
425
+ deleteWorkspaceSyncBinaryAsset: vi.fn(),
426
+ getExistingBinaryAsset: () => ({
427
+ updatedAt: '2026-04-10T10:05:00.000Z',
428
+ contentSha256: createHash('sha256').update(existingAssetBytes).digest('hex'),
429
+ }),
430
+ recordSyncDiagnostic: vi.fn(),
431
+ });
432
+ expect(readSpy).not.toHaveBeenCalled();
433
+ expect(writeWorkspaceSyncDocument).toHaveBeenCalledWith('/tmp/taskforce-sync-content', expect.objectContaining({ path: 'docs/spec.md', assetId: 'asset-doc-1' }), 'workspace-1', { allowReferenceNumberReassignment: false });
434
+ expect(writeWorkspaceSyncBinaryAsset).toHaveBeenCalledWith('/tmp/taskforce-sync-content', expect.objectContaining({ path: 'assets/proof.png', assetId: 'asset-image-1' }), 'workspace-1', { allowReferenceNumberReassignment: false });
435
+ });
436
+ it('rejects synced content applies when a binary asset write fails', async () => {
437
+ const core = createCoreFixture();
438
+ const recordSyncDiagnostic = vi.fn();
439
+ await expect(applyContentSyncChanges({
440
+ core,
441
+ workspaceId: 'workspace-1',
442
+ incomingDocuments: [],
443
+ incomingDocumentDeletes: new Map(),
444
+ incomingAssets: [
445
+ {
446
+ path: 'assets/proof.png',
447
+ updatedAt: '2026-04-10T10:05:00.000Z',
448
+ contentBase64: Buffer.from('png-bytes').toString('base64'),
449
+ assetId: 'asset-image-1',
450
+ kind: 'image',
451
+ mimeType: 'image/png',
452
+ },
453
+ ],
454
+ incomingAssetDeletes: new Map(),
455
+ basePath: '/tmp/taskforce-sync-content',
456
+ hasObjectStorageClient: () => true,
457
+ hasDocumentSyncMetadataDrift: () => false,
458
+ hasBinaryAssetSyncMetadataDrift: () => false,
459
+ getExistingDocument: () => null,
460
+ writeWorkspaceSyncDocument: vi.fn(),
461
+ deleteWorkspaceSyncDocument: vi.fn(),
462
+ writeWorkspaceSyncBinaryAsset: vi.fn().mockRejectedValue(new Error('R2 write failed')),
463
+ deleteWorkspaceSyncBinaryAsset: vi.fn(),
464
+ getExistingBinaryAsset: () => null,
465
+ recordSyncDiagnostic,
466
+ })).rejects.toMatchObject({
467
+ code: 'SYNC_CONTENT_APPLY_FAILED',
468
+ statusCode: 500,
469
+ });
470
+ expect(recordSyncDiagnostic).toHaveBeenCalledWith('workspace-1', 'apply', 'Failed to apply synced asset change.', expect.objectContaining({
471
+ source: 'assets.apply.write',
472
+ path: 'assets/proof.png',
473
+ assetId: 'asset-image-1',
474
+ kind: 'image',
475
+ error: 'R2 write failed'
476
+ }));
477
+ });
286
478
  it('applies collaboration upserts and deletes through the collaboration handlers', () => {
287
479
  const core = createCoreFixture();
288
480
  applyCollaborationSyncChanges({
@@ -376,4 +568,59 @@ describe('syncApplyHandlers', () => {
376
568
  deletedAt: '2026-04-10T11:10:00.000Z',
377
569
  });
378
570
  });
571
+ it('applies entity events through lean sync lookups instead of hydrated entity activity reads', () => {
572
+ const core = createCoreFixture({
573
+ taskExistsForSync: vi.fn().mockReturnValue(true),
574
+ getEntityEventForSync: vi.fn().mockReturnValue(null),
575
+ listTaskEvents: vi.fn(() => {
576
+ throw new Error('hydrated task activity lookup should not run during sync apply');
577
+ }),
578
+ getTask: vi.fn(() => {
579
+ throw new Error('hydrated task lookup should not run during sync apply');
580
+ }),
581
+ getInitiative: vi.fn(() => {
582
+ throw new Error('hydrated initiative lookup should not run during sync apply');
583
+ }),
584
+ getWorkstream: vi.fn(() => {
585
+ throw new Error('hydrated workstream lookup should not run during sync apply');
586
+ }),
587
+ listEntityEventsForSync: vi.fn(() => {
588
+ throw new Error('hydrated entity event listing should not run during sync apply');
589
+ }),
590
+ upsertEntityEventForSync: vi.fn(),
591
+ });
592
+ applyTaskActivitySyncChanges({
593
+ core,
594
+ workspaceId: 'workspace-1',
595
+ incomingTaskEvents: new Map([
596
+ ['task-event-1', {
597
+ id: 'task-event-1',
598
+ taskId: 'task-1',
599
+ entityType: 'task',
600
+ entityId: 'task-1',
601
+ workspaceId: 'workspace-1',
602
+ action: 'task-updated',
603
+ actor: 'user-1',
604
+ actorType: 'human',
605
+ details: { changes: { status: { from: 'task', to: 'review' } } },
606
+ createdAt: '2026-04-10T10:00:00.000Z',
607
+ }],
608
+ ]),
609
+ recordSyncDiagnostic: vi.fn(),
610
+ createSyncRouteError: (message, details) => Object.assign(new Error(message), { details }),
611
+ });
612
+ expect(core.taskExistsForSync).toHaveBeenCalledWith('task-1', 'workspace-1');
613
+ expect(core.getEntityEventForSync).toHaveBeenCalledWith({
614
+ workspaceId: 'workspace-1',
615
+ eventId: 'task-event-1',
616
+ });
617
+ expect(core.upsertEntityEventForSync).toHaveBeenCalledWith(expect.objectContaining({
618
+ id: 'task-event-1',
619
+ taskId: 'task-1',
620
+ entityType: 'task',
621
+ entityId: 'task-1',
622
+ workspaceId: 'workspace-1',
623
+ action: 'task-updated',
624
+ }));
625
+ });
379
626
  });
@@ -0,0 +1,12 @@
1
+ export declare function hasOwnSyncField(source: unknown, field: string): boolean;
2
+ export declare function normalizeSyncOptionalString(value: unknown): string | undefined;
3
+ export declare function normalizeSyncNullableString(value: unknown): string | null;
4
+ export declare function normalizeSyncOptionalId(value: unknown): string | undefined;
5
+ export declare function normalizeSyncNullableId(value: unknown): string | null;
6
+ export declare function normalizeSyncNullableIsoString(value: unknown): string | null;
7
+ export declare function normalizeSyncSameOriginAssetUrl(value: unknown): string | null;
8
+ export declare function readSyncOptionalStringField(source: Record<string, unknown>, field: string): string | undefined;
9
+ export declare function readSyncNullableStringField(source: Record<string, unknown>, field: string): string | null | undefined;
10
+ export declare function readSyncNullableIdField(source: Record<string, unknown>, field: string): string | null | undefined;
11
+ export declare function readSyncNullableIsoStringField(source: Record<string, unknown>, field: string): string | null | undefined;
12
+ export declare function readSyncSameOriginAssetUrlField(source: Record<string, unknown>, field: string): string | null | undefined;
@@ -0,0 +1,55 @@
1
+ export function hasOwnSyncField(source, field) {
2
+ return Boolean(source) && typeof source === 'object' && Object.prototype.hasOwnProperty.call(source, field);
3
+ }
4
+ export function normalizeSyncOptionalString(value) {
5
+ if (value === undefined || value === null)
6
+ return undefined;
7
+ const normalized = String(value).trim();
8
+ return normalized.length > 0 ? normalized : undefined;
9
+ }
10
+ export function normalizeSyncNullableString(value) {
11
+ if (value === undefined || value === null)
12
+ return null;
13
+ const normalized = String(value).trim();
14
+ return normalized.length > 0 ? normalized : null;
15
+ }
16
+ export function normalizeSyncOptionalId(value) {
17
+ return normalizeSyncOptionalString(value);
18
+ }
19
+ export function normalizeSyncNullableId(value) {
20
+ return normalizeSyncNullableString(value);
21
+ }
22
+ export function normalizeSyncNullableIsoString(value) {
23
+ return normalizeSyncNullableString(value);
24
+ }
25
+ export function normalizeSyncSameOriginAssetUrl(value) {
26
+ const normalized = normalizeSyncNullableString(value);
27
+ if (!normalized)
28
+ return null;
29
+ return normalized.startsWith('/api/taskforce/context/') ? normalized : null;
30
+ }
31
+ export function readSyncOptionalStringField(source, field) {
32
+ if (!hasOwnSyncField(source, field))
33
+ return undefined;
34
+ return normalizeSyncOptionalString(source[field]);
35
+ }
36
+ export function readSyncNullableStringField(source, field) {
37
+ if (!hasOwnSyncField(source, field))
38
+ return undefined;
39
+ return normalizeSyncNullableString(source[field]);
40
+ }
41
+ export function readSyncNullableIdField(source, field) {
42
+ if (!hasOwnSyncField(source, field))
43
+ return undefined;
44
+ return normalizeSyncNullableId(source[field]);
45
+ }
46
+ export function readSyncNullableIsoStringField(source, field) {
47
+ if (!hasOwnSyncField(source, field))
48
+ return undefined;
49
+ return normalizeSyncNullableIsoString(source[field]);
50
+ }
51
+ export function readSyncSameOriginAssetUrlField(source, field) {
52
+ if (!hasOwnSyncField(source, field))
53
+ return undefined;
54
+ return normalizeSyncSameOriginAssetUrl(source[field]);
55
+ }
@@ -0,0 +1,46 @@
1
+ import type { TaskItem } from '../types.js';
2
+ export interface SyncAiProfileLike {
3
+ id?: string | null;
4
+ workspaceId?: string | null;
5
+ profileToken?: string | null;
6
+ name?: string | null;
7
+ username?: string | null;
8
+ icon?: string | null;
9
+ color?: string | null;
10
+ avatarUrl?: string | null;
11
+ avatarSourceUrl?: string | null;
12
+ avatarRevision?: number | null;
13
+ avatarUpdatedAt?: string | null;
14
+ description?: string | null;
15
+ role?: string | null;
16
+ provider?: string | null;
17
+ model?: string | null;
18
+ surfaceType?: string | null;
19
+ seatScope?: string | null;
20
+ providerMetadata?: Record<string, unknown> | null;
21
+ archivedAt?: string | null;
22
+ archivedBy?: string | null;
23
+ archivedReason?: string | null;
24
+ mergedIntoProfileId?: string | null;
25
+ rosterStateUpdatedAt?: string | null;
26
+ createdAt?: string | null;
27
+ updatedAt?: string | null;
28
+ lastActiveAt?: string | null;
29
+ }
30
+ export interface SyncResourceAdapter<T> {
31
+ kind: string;
32
+ getId: (resource: T) => string;
33
+ getWatermark: (resource: T) => string;
34
+ getChangeKey: (resource: T) => string;
35
+ }
36
+ export interface SyncResourceBaselineState {
37
+ watermarks?: Map<string, string> | null;
38
+ changeKeys?: Map<string, string> | null;
39
+ }
40
+ export declare function getAiProfileSyncWatermark(profile: Partial<SyncAiProfileLike> | null | undefined): string;
41
+ export declare function getAiProfileSyncChangeKey(profile: Partial<SyncAiProfileLike> | null | undefined): string;
42
+ export declare const taskSyncResourceAdapter: SyncResourceAdapter<Partial<TaskItem> & {
43
+ isArchived?: boolean | null;
44
+ }>;
45
+ export declare const aiProfileSyncResourceAdapter: SyncResourceAdapter<Partial<SyncAiProfileLike>>;
46
+ export declare function shouldSyncResource<T>(adapter: SyncResourceAdapter<T>, resource: T, baseline?: SyncResourceBaselineState | null): boolean;
@@ -0,0 +1,79 @@
1
+ import { buildTaskSyncChangeKey } from './taskSyncChangeKey.js';
2
+ import { normalizeSyncNullableIsoString, normalizeSyncNullableString, normalizeSyncOptionalId, normalizeSyncSameOriginAssetUrl, } from './syncFieldSemantics.js';
3
+ function normalizeSyncTimestampMax(...values) {
4
+ return values.reduce((latest, value) => {
5
+ const normalized = normalizeSyncNullableIsoString(value) || '';
6
+ if (!latest)
7
+ return normalized;
8
+ if (!normalized)
9
+ return latest;
10
+ return normalized > latest ? normalized : latest;
11
+ }, '');
12
+ }
13
+ export function getAiProfileSyncWatermark(profile) {
14
+ const source = profile || {};
15
+ return normalizeSyncTimestampMax(source.createdAt, source.updatedAt, source.lastActiveAt, source.archivedAt, source.rosterStateUpdatedAt);
16
+ }
17
+ export function getAiProfileSyncChangeKey(profile) {
18
+ const source = profile || {};
19
+ return JSON.stringify({
20
+ id: String(source.id || '').trim(),
21
+ workspaceId: String(source.workspaceId || '').trim(),
22
+ profileToken: String(source.profileToken || '').trim(),
23
+ name: String(source.name || '').trim(),
24
+ username: String(source.username || '').trim(),
25
+ icon: String(source.icon || 'Bot').trim() || 'Bot',
26
+ color: String(source.color || '#8b5cf6').trim() || '#8b5cf6',
27
+ avatarUrl: normalizeSyncSameOriginAssetUrl(source.avatarUrl) || '',
28
+ avatarSourceUrl: normalizeSyncSameOriginAssetUrl(source.avatarSourceUrl) || '',
29
+ avatarRevision: Number.isFinite(Number(source.avatarRevision)) ? Math.max(0, Math.floor(Number(source.avatarRevision))) : 0,
30
+ avatarUpdatedAt: normalizeSyncNullableIsoString(source.avatarUpdatedAt) || '',
31
+ description: normalizeSyncNullableString(source.description) || '',
32
+ role: normalizeSyncNullableString(source.role) || '',
33
+ provider: normalizeSyncNullableString(source.provider) || '',
34
+ model: normalizeSyncNullableString(source.model) || '',
35
+ surfaceType: normalizeSyncNullableString(source.surfaceType) || '',
36
+ seatScope: normalizeSyncNullableString(source.seatScope) || '',
37
+ providerMetadata: source.providerMetadata && typeof source.providerMetadata === 'object' && !Array.isArray(source.providerMetadata)
38
+ ? source.providerMetadata
39
+ : null,
40
+ archivedAt: normalizeSyncNullableIsoString(source.archivedAt) || '',
41
+ archivedBy: normalizeSyncOptionalId(source.archivedBy) || '',
42
+ archivedReason: normalizeSyncNullableString(source.archivedReason) || '',
43
+ mergedIntoProfileId: normalizeSyncOptionalId(source.mergedIntoProfileId) || '',
44
+ rosterStateUpdatedAt: normalizeSyncNullableIsoString(source.rosterStateUpdatedAt) || '',
45
+ createdAt: normalizeSyncNullableIsoString(source.createdAt) || '',
46
+ updatedAt: normalizeSyncNullableIsoString(source.updatedAt) || '',
47
+ lastActiveAt: normalizeSyncNullableIsoString(source.lastActiveAt) || '',
48
+ });
49
+ }
50
+ export const taskSyncResourceAdapter = {
51
+ kind: 'task',
52
+ getId: (task) => String(task?.id || '').trim(),
53
+ getWatermark: (task) => String(task?.updatedAt || task?.createdAt || '').trim(),
54
+ getChangeKey: (task) => buildTaskSyncChangeKey(task, Boolean(task?.isArchived))
55
+ };
56
+ export const aiProfileSyncResourceAdapter = {
57
+ kind: 'ai-profile',
58
+ getId: (profile) => String(profile?.id || '').trim(),
59
+ getWatermark: (profile) => getAiProfileSyncWatermark(profile),
60
+ getChangeKey: (profile) => getAiProfileSyncChangeKey(profile)
61
+ };
62
+ export function shouldSyncResource(adapter, resource, baseline) {
63
+ const id = adapter.getId(resource);
64
+ if (!id)
65
+ return false;
66
+ const currentChangeKey = adapter.getChangeKey(resource);
67
+ const previousWatermarks = baseline?.watermarks;
68
+ if (!previousWatermarks || previousWatermarks.size === 0)
69
+ return true;
70
+ if (!previousWatermarks.has(id))
71
+ return true;
72
+ const previousChangeKeys = baseline?.changeKeys;
73
+ const previousChangeKey = previousChangeKeys?.get(id);
74
+ if (typeof previousChangeKey === 'string') {
75
+ return previousChangeKey !== currentChangeKey;
76
+ }
77
+ const previousWatermark = previousWatermarks.get(id) || '';
78
+ return previousWatermark !== currentChangeKey;
79
+ }
@@ -56,6 +56,8 @@ export interface WorkspacePushSyncResult {
56
56
  changeCount: number;
57
57
  deleteCount: number;
58
58
  currentTaskIds: Set<string>;
59
+ currentTaskWatermarks?: Map<string, string>;
60
+ currentTaskChangeKeys?: Map<string, string>;
59
61
  deleteTaskIds: Set<string>;
60
62
  currentInitiativeIds: Set<string>;
61
63
  currentInitiativeWatermarks: Map<string, string>;
@@ -63,6 +65,7 @@ export interface WorkspacePushSyncResult {
63
65
  currentWorkstreamWatermarks: Map<string, string>;
64
66
  currentAiProfileIds: Set<string>;
65
67
  currentAiProfileWatermarks: Map<string, string>;
68
+ currentAiProfileChangeKeys?: Map<string, string>;
66
69
  currentDocumentPaths: Set<string>;
67
70
  deleteDocumentPaths: Set<string>;
68
71
  currentDocumentWatermarks: Map<string, string>;
@@ -81,6 +84,7 @@ export interface WorkspacePushSyncResult {
81
84
  currentTaskEventWatermarks: Map<string, string>;
82
85
  /** Watermarks for every task upsert that was successfully pushed. */
83
86
  pushedWatermarks: Map<string, string>;
87
+ pushedTaskChangeKeys?: Map<string, string>;
84
88
  /** Server-emitted realtime mutation event ids for this push apply. */
85
89
  emittedEventIds: string[];
86
90
  /** Authoritative task snapshots returned immediately by the push route for incoming task upserts. */
@@ -106,6 +110,7 @@ export interface WorkspacePullSyncResult {
106
110
  success: boolean;
107
111
  kind?: WorkspacePullFailureKind;
108
112
  status?: number;
113
+ errorCode?: string;
109
114
  retryAfterMs?: number;
110
115
  transient?: boolean;
111
116
  failures?: string[];
@@ -121,6 +126,7 @@ export interface WorkspacePullSyncResult {
121
126
  pulledActiveUpserts: boolean;
122
127
  pulledArchivedUpserts: boolean;
123
128
  pulledTaskEventUpserts?: boolean;
129
+ pulledPlanningUpserts?: boolean;
124
130
  documentDecryptFailures?: string[];
125
131
  emittedEventIds?: string[];
126
132
  serverDiagnostics?: Record<string, unknown> | null;