@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
@@ -31,7 +31,7 @@ function openCore(projectRoot) {
31
31
  core.updatePlanVersionFeatures({
32
32
  planVersionId: 'free-v1',
33
33
  features: [
34
- { featureKey: 'workspace.switching', access: 'enabled' }
34
+ { featureKey: 'workspace.workspaces', access: 'enabled' }
35
35
  ]
36
36
  });
37
37
  insertFreePriceMapping(core, 'free-v1');
@@ -44,7 +44,7 @@ describe('TaskforceCore onboarding policy', () => {
44
44
  try {
45
45
  expect(core.getOnboardingPolicy()).toEqual({
46
46
  mode: 'require_plan_selection',
47
- planVersionId: null
47
+ planId: null
48
48
  });
49
49
  }
50
50
  finally {
@@ -68,13 +68,13 @@ describe('TaskforceCore onboarding policy', () => {
68
68
  core.updatePlanVersionFeatures({
69
69
  planVersionId: 'free-v1',
70
70
  features: [
71
- { featureKey: 'workspace.switching', access: 'enabled' }
71
+ { featureKey: 'workspace.workspaces', access: 'enabled' }
72
72
  ]
73
73
  });
74
74
  try {
75
75
  expect(core.getOnboardingPolicy()).toEqual({
76
76
  mode: 'require_plan_selection',
77
- planVersionId: null
77
+ planId: null
78
78
  });
79
79
  }
80
80
  finally {
@@ -82,16 +82,16 @@ describe('TaskforceCore onboarding policy', () => {
82
82
  fs.rmSync(projectRoot, { recursive: true, force: true });
83
83
  }
84
84
  });
85
- it('fails validation for auto_grant_free without a plan version id', () => {
85
+ it('fails validation for auto_grant_free without a plan id', () => {
86
86
  const projectRoot = makeProjectRoot();
87
87
  const core = openCore(projectRoot);
88
88
  try {
89
89
  expect(core.validateOnboardingPolicy({
90
90
  mode: 'auto_grant_free',
91
- planVersionId: null
91
+ planId: null
92
92
  })).toEqual(expect.objectContaining({
93
93
  valid: false,
94
- code: 'ONBOARDING_PLAN_VERSION_REQUIRED'
94
+ code: 'ONBOARDING_PLAN_REQUIRED'
95
95
  }));
96
96
  }
97
97
  finally {
@@ -99,16 +99,16 @@ describe('TaskforceCore onboarding policy', () => {
99
99
  fs.rmSync(projectRoot, { recursive: true, force: true });
100
100
  }
101
101
  });
102
- it('fails validation when the configured version does not exist', () => {
102
+ it('fails validation when the configured plan does not exist', () => {
103
103
  const projectRoot = makeProjectRoot();
104
104
  const core = openCore(projectRoot);
105
105
  try {
106
106
  expect(core.validateOnboardingPolicy({
107
107
  mode: 'auto_grant_free',
108
- planVersionId: 'missing-v9'
108
+ planId: 'missing'
109
109
  })).toEqual(expect.objectContaining({
110
110
  valid: false,
111
- code: 'ONBOARDING_PLAN_VERSION_NOT_FOUND'
111
+ code: 'ONBOARDING_PLAN_NOT_FOUND'
112
112
  }));
113
113
  }
114
114
  finally {
@@ -116,14 +116,14 @@ describe('TaskforceCore onboarding policy', () => {
116
116
  fs.rmSync(projectRoot, { recursive: true, force: true });
117
117
  }
118
118
  });
119
- it('fails validation when the configured version belongs to a disabled plan', () => {
119
+ it('fails validation when the configured plan is disabled', () => {
120
120
  const projectRoot = makeProjectRoot();
121
121
  const core = openCore(projectRoot);
122
122
  try {
123
123
  core.upsertPlanCatalog({ planId: 'free', displayName: 'Free', status: 'archived' });
124
124
  expect(core.validateOnboardingPolicy({
125
125
  mode: 'auto_grant_free',
126
- planVersionId: 'free-v1'
126
+ planId: 'free'
127
127
  })).toEqual(expect.objectContaining({
128
128
  valid: false,
129
129
  code: 'ONBOARDING_PLAN_NOT_ENABLED'
@@ -134,14 +134,14 @@ describe('TaskforceCore onboarding policy', () => {
134
134
  fs.rmSync(projectRoot, { recursive: true, force: true });
135
135
  }
136
136
  });
137
- it('fails validation when auto_grant_free points at a version without free pricing', () => {
137
+ it('fails validation when auto_grant_free points at a plan whose default version lacks free pricing', () => {
138
138
  const projectRoot = makeProjectRoot();
139
139
  const core = openCore(projectRoot);
140
140
  try {
141
141
  core.upsertPlanCatalog({ planId: 'team-5', displayName: 'Team 5', status: 'active' });
142
142
  expect(core.validateOnboardingPolicy({
143
143
  mode: 'auto_grant_free',
144
- planVersionId: 'team-5-v1'
144
+ planId: 'team-5'
145
145
  })).toEqual(expect.objectContaining({
146
146
  valid: false,
147
147
  code: 'ONBOARDING_PLAN_MUST_BE_FREE'
@@ -152,13 +152,13 @@ describe('TaskforceCore onboarding policy', () => {
152
152
  fs.rmSync(projectRoot, { recursive: true, force: true });
153
153
  }
154
154
  });
155
- it('passes validation for require_plan_selection without a plan version id', () => {
155
+ it('passes validation for require_plan_selection without a plan id', () => {
156
156
  const projectRoot = makeProjectRoot();
157
157
  const core = openCore(projectRoot);
158
158
  try {
159
159
  expect(core.validateOnboardingPolicy({
160
160
  mode: 'require_plan_selection',
161
- planVersionId: null
161
+ planId: null
162
162
  })).toEqual({ valid: true });
163
163
  }
164
164
  finally {
@@ -172,7 +172,7 @@ describe('TaskforceCore onboarding policy', () => {
172
172
  try {
173
173
  const created = core.registerPasswordUser({
174
174
  email: 'implicit-onboarding@example.com',
175
- password: 'password123'
175
+ password: 'ValidPassphrase123!'
176
176
  });
177
177
  expect(created.planSelectionRequired).toBe(true);
178
178
  expect(created.checkoutPending).toBe(false);
@@ -201,15 +201,15 @@ describe('TaskforceCore onboarding policy', () => {
201
201
  billing: {
202
202
  onboardingPolicy: {
203
203
  mode: 'require_plan_selection',
204
- planVersionId: null
204
+ planId: null
205
205
  }
206
206
  }
207
207
  });
208
208
  const db = core.getDatabaseAdapter();
209
209
  db.prepare(`
210
- INSERT INTO users (id, tenant_id, email, display_name, auth_provider, external_auth_id, is_disabled, created_at, updated_at)
211
- VALUES (?, ?, ?, ?, ?, ?, 0, ?, ?)
212
- `).run('pending-u1', tenantId, 'pending@example.com', 'Pending', 'token', 'pending-u1', now, now);
210
+ INSERT INTO users (id, tenant_id, email, display_name, is_disabled, created_at, updated_at)
211
+ VALUES (?, ?, ?, ?, 0, ?, ?)
212
+ `).run('pending-u1', tenantId, 'pending@example.com', 'Pending', now, now);
213
213
  db.prepare(`
214
214
  INSERT INTO user_billing (user_id, tenant_id, entitlement_state, created_at, updated_at)
215
215
  VALUES (?, ?, ?, ?, ?)
@@ -248,9 +248,9 @@ describe('TaskforceCore onboarding policy', () => {
248
248
  core.upsertPlanCatalog({ planId: 'basic', displayName: 'Basic', status: 'active' });
249
249
  const db = core.getDatabaseAdapter();
250
250
  db.prepare(`
251
- INSERT INTO users (id, tenant_id, email, display_name, auth_provider, external_auth_id, is_disabled, created_at, updated_at)
252
- VALUES (?, ?, ?, ?, ?, ?, 0, ?, ?)
253
- `).run('checkout-u1', tenantId, 'checkout@example.com', 'Checkout', 'token', 'checkout-u1', now, now);
251
+ INSERT INTO users (id, tenant_id, email, display_name, is_disabled, created_at, updated_at)
252
+ VALUES (?, ?, ?, ?, 0, ?, ?)
253
+ `).run('checkout-u1', tenantId, 'checkout@example.com', 'Checkout', now, now);
254
254
  core.transitionCanonicalCommercialState({
255
255
  accountId: 'checkout-u1',
256
256
  planVersionId: 'basic-v1',
@@ -286,9 +286,9 @@ describe('TaskforceCore onboarding policy', () => {
286
286
  core.upsertPlanCatalog({ planId: 'basic', displayName: 'Basic', status: 'active' });
287
287
  const db = core.getDatabaseAdapter();
288
288
  db.prepare(`
289
- INSERT INTO users (id, tenant_id, email, display_name, auth_provider, external_auth_id, is_disabled, created_at, updated_at)
290
- VALUES (?, ?, ?, ?, ?, ?, 0, ?, ?)
291
- `).run('expired-checkout-u1', tenantId, 'expired@example.com', 'Expired Checkout', 'token', 'expired-checkout-u1', now, now);
289
+ INSERT INTO users (id, tenant_id, email, display_name, is_disabled, created_at, updated_at)
290
+ VALUES (?, ?, ?, ?, 0, ?, ?)
291
+ `).run('expired-checkout-u1', tenantId, 'expired@example.com', 'Expired Checkout', now, now);
292
292
  core.transitionCanonicalCommercialState({
293
293
  accountId: 'expired-checkout-u1',
294
294
  planVersionId: 'basic-v1',
@@ -340,4 +340,176 @@ describe('TaskforceCore onboarding policy', () => {
340
340
  fs.rmSync(projectRoot, { recursive: true, force: true });
341
341
  }
342
342
  });
343
+ it('treats an expired trialing entitlement as requiring plan reselection', () => {
344
+ const projectRoot = makeProjectRoot();
345
+ const tenantId = path.basename(projectRoot);
346
+ const core = openCore(projectRoot);
347
+ try {
348
+ const now = new Date().toISOString();
349
+ const expiredAt = new Date(Date.now() - (60 * 1000)).toISOString();
350
+ core.upsertPlanCatalog({ planId: 'basic', displayName: 'Basic', status: 'active' });
351
+ const db = core.getDatabaseAdapter();
352
+ db.prepare(`
353
+ INSERT INTO users (id, tenant_id, email, display_name, is_disabled, created_at, updated_at)
354
+ VALUES (?, ?, ?, ?, 0, ?, ?)
355
+ `).run('expired-trial-u1', tenantId, 'expired-trial@example.com', 'Expired Trial', now, now);
356
+ core.transitionCanonicalCommercialState({
357
+ accountId: 'expired-trial-u1',
358
+ planVersionId: 'basic-v1',
359
+ state: 'trialing',
360
+ source: 'system',
361
+ updatedBy: 'trial-start',
362
+ billingMirrorPlanId: 'basic',
363
+ effectiveAt: now,
364
+ effectiveUntil: expiredAt,
365
+ createdAt: now,
366
+ updatedAt: now
367
+ });
368
+ expect(core.getAccountAccessStatus('expired-trial-u1')).toEqual(expect.objectContaining({
369
+ gate: 'plan_selection_required',
370
+ canAccessApp: false,
371
+ canAccessPlans: true,
372
+ planSelectionRequired: true,
373
+ message: 'Choose a plan to continue.'
374
+ }));
375
+ expect(core.getAccountEntitlement('expired-trial-u1')).toEqual(expect.objectContaining({
376
+ state: 'pending_plan_selection',
377
+ effectiveUntil: null
378
+ }));
379
+ const entitlementRow = db.prepare(`
380
+ SELECT entitlement_state, effective_until, updated_by
381
+ FROM account_entitlements
382
+ WHERE tenant_id = ? AND account_id = ?
383
+ LIMIT 1
384
+ `).get(tenantId, 'expired-trial-u1');
385
+ expect(entitlementRow).toEqual(expect.objectContaining({
386
+ entitlement_state: 'pending_plan_selection',
387
+ effective_until: null,
388
+ updated_by: 'trial-expired'
389
+ }));
390
+ const billingRow = db.prepare(`
391
+ SELECT entitlement_state, tier, effective_until
392
+ FROM user_billing
393
+ WHERE tenant_id = ? AND user_id = ?
394
+ LIMIT 1
395
+ `).get(tenantId, 'expired-trial-u1');
396
+ expect(billingRow).toEqual(expect.objectContaining({
397
+ entitlement_state: 'pending_plan_selection',
398
+ tier: '',
399
+ effective_until: null
400
+ }));
401
+ }
402
+ finally {
403
+ core.close();
404
+ fs.rmSync(projectRoot, { recursive: true, force: true });
405
+ }
406
+ });
407
+ it('auto-heals a pending-plan-selection entitlement from an active Stripe billing mirror', () => {
408
+ const projectRoot = makeProjectRoot();
409
+ const tenantId = path.basename(projectRoot);
410
+ const core = openCore(projectRoot);
411
+ try {
412
+ const now = new Date().toISOString();
413
+ const nextRenewal = new Date(Date.now() + (24 * 60 * 60 * 1000)).toISOString();
414
+ core.upsertPlanCatalog({ planId: 'team-5', displayName: 'Team 5', status: 'active' });
415
+ const db = core.getDatabaseAdapter();
416
+ db.prepare(`
417
+ INSERT INTO users (id, tenant_id, email, display_name, is_disabled, created_at, updated_at)
418
+ VALUES (?, ?, ?, ?, 0, ?, ?)
419
+ `).run('mirror-heal-u1', tenantId, 'mirror-heal@example.com', 'Mirror Heal', now, now);
420
+ core.transitionCanonicalCommercialState({
421
+ accountId: 'mirror-heal-u1',
422
+ planVersionId: 'free-v1',
423
+ state: 'pending_plan_selection',
424
+ source: 'backfill',
425
+ updatedBy: 'backfill',
426
+ billingMirrorPlanId: null,
427
+ effectiveAt: now,
428
+ createdAt: now,
429
+ updatedAt: now
430
+ });
431
+ db.prepare(`
432
+ UPDATE user_billing
433
+ SET stripe_customer_id = ?, stripe_subscription_id = ?, entitlement_state = ?, tier = ?, effective_until = ?, updated_at = ?
434
+ WHERE tenant_id = ? AND user_id = ?
435
+ `).run('cus_heal', 'sub_heal', 'active', 'team-5', nextRenewal, now, tenantId, 'mirror-heal-u1');
436
+ expect(core.getAccountAccessStatus('mirror-heal-u1')).toEqual(expect.objectContaining({
437
+ gate: 'ok',
438
+ canAccessApp: true,
439
+ planSelectionRequired: false
440
+ }));
441
+ expect(core.getAccountEntitlement('mirror-heal-u1')).toEqual(expect.objectContaining({
442
+ state: 'active',
443
+ planId: 'team-5',
444
+ planVersionId: 'team-5-v1',
445
+ effectiveUntil: nextRenewal
446
+ }));
447
+ const entitlementRow = db.prepare(`
448
+ SELECT entitlement_state, plan_version_id, effective_until, updated_by
449
+ FROM account_entitlements
450
+ WHERE tenant_id = ? AND account_id = ?
451
+ LIMIT 1
452
+ `).get(tenantId, 'mirror-heal-u1');
453
+ expect(entitlementRow).toEqual(expect.objectContaining({
454
+ entitlement_state: 'active',
455
+ plan_version_id: 'team-5-v1',
456
+ effective_until: nextRenewal,
457
+ updated_by: 'billing-mirror-auto-heal'
458
+ }));
459
+ }
460
+ finally {
461
+ core.close();
462
+ fs.rmSync(projectRoot, { recursive: true, force: true });
463
+ }
464
+ });
465
+ it('auto-heals a pending-plan-selection entitlement from Stripe status and price mapping when mirror state is stale', () => {
466
+ const projectRoot = makeProjectRoot();
467
+ const tenantId = path.basename(projectRoot);
468
+ const core = openCore(projectRoot);
469
+ try {
470
+ const now = new Date().toISOString();
471
+ const nextRenewal = new Date(Date.now() + (24 * 60 * 60 * 1000)).toISOString();
472
+ core.upsertPlanCatalog({ planId: 'team-5', displayName: 'Team 5', status: 'active' });
473
+ const db = core.getDatabaseAdapter();
474
+ db.prepare(`
475
+ INSERT INTO users (id, tenant_id, email, display_name, is_disabled, created_at, updated_at)
476
+ VALUES (?, ?, ?, ?, 0, ?, ?)
477
+ `).run('mirror-price-heal-u1', tenantId, 'mirror-price-heal@example.com', 'Mirror Price Heal', now, now);
478
+ core.transitionCanonicalCommercialState({
479
+ accountId: 'mirror-price-heal-u1',
480
+ planVersionId: 'free-v1',
481
+ state: 'pending_plan_selection',
482
+ source: 'backfill',
483
+ updatedBy: 'checkout-expired',
484
+ billingMirrorPlanId: null,
485
+ effectiveAt: now,
486
+ createdAt: now,
487
+ updatedAt: now
488
+ });
489
+ db.prepare(`
490
+ UPDATE user_billing
491
+ SET stripe_customer_id = ?, stripe_subscription_id = ?, stripe_price_id = ?, stripe_status = ?, entitlement_state = ?, tier = ?, effective_until = ?, updated_at = ?
492
+ WHERE tenant_id = ? AND user_id = ?
493
+ `).run('cus_heal_2', 'sub_heal_2', 'price_team_5_month', 'active', 'pending_plan_selection', 'team-5', nextRenewal, now, tenantId, 'mirror-price-heal-u1');
494
+ db.prepare(`
495
+ INSERT INTO billing_price_mappings (tenant_id, plan_version_id, billing_interval, stripe_price_id, active, created_at, updated_at)
496
+ VALUES (?, ?, ?, ?, 1, ?, ?)
497
+ `).run(tenantId, 'team-5-v1', 'month', 'price_team_5_month', now, now);
498
+ expect(core.getAccountAccessStatus('mirror-price-heal-u1')).toEqual(expect.objectContaining({
499
+ gate: 'ok',
500
+ canAccessApp: true,
501
+ planSelectionRequired: false
502
+ }));
503
+ expect(core.getAccountEntitlement('mirror-price-heal-u1')).toEqual(expect.objectContaining({
504
+ state: 'active',
505
+ planId: 'team-5',
506
+ planVersionId: 'team-5-v1',
507
+ effectiveUntil: nextRenewal
508
+ }));
509
+ }
510
+ finally {
511
+ core.close();
512
+ fs.rmSync(projectRoot, { recursive: true, force: true });
513
+ }
514
+ });
343
515
  });
@@ -1,4 +1,5 @@
1
1
  import { DEFAULT_TYPE_VALUE } from '../shared/taxonomyDefaults.js';
2
+ import { buildTaskSyncChangeKey } from '../sync/taskSyncChangeKey.js';
2
3
  export function listTasksForSyncService(deps, workspaceId, cursor, limit) {
3
4
  const normalizedWorkspaceId = deps.normalizeWorkspaceId(workspaceId);
4
5
  const safeLimit = Math.max(1, Math.min(10000, Math.floor(limit)));
@@ -67,72 +68,8 @@ export function listWorkspaceSyncDeletesSinceService(deps, workspaceId, cursor,
67
68
  }))
68
69
  .filter((row) => row.taskId.length > 0 && Number.isFinite(Date.parse(row.deletedAt)));
69
70
  }
70
- function normalizeConflictTaxonomies(value) {
71
- if (!value || typeof value !== 'object')
72
- return {};
73
- const source = value;
74
- return Object.keys(source).sort().reduce((acc, key) => {
75
- const raw = source[key];
76
- if (Array.isArray(raw)) {
77
- acc[key] = raw.map((entry) => String(entry ?? '')).sort();
78
- }
79
- else if (raw === null || raw === undefined) {
80
- acc[key] = '';
81
- }
82
- else {
83
- acc[key] = String(raw);
84
- }
85
- return acc;
86
- }, {});
87
- }
88
- function normalizeConflictChecklistItems(value) {
89
- if (!Array.isArray(value))
90
- return [];
91
- return value
92
- .map((item) => {
93
- const entry = item && typeof item === 'object' ? item : {};
94
- return {
95
- id: String(entry.id || '').trim(),
96
- title: String(entry.title || '').trim(),
97
- isCompleted: Boolean(entry.isCompleted),
98
- order: entry.order === undefined || entry.order === null ? '' : String(entry.order),
99
- };
100
- })
101
- .sort((left, right) => {
102
- const leftOrder = Number.parseInt(left.order, 10);
103
- const rightOrder = Number.parseInt(right.order, 10);
104
- if (Number.isFinite(leftOrder) && Number.isFinite(rightOrder) && leftOrder !== rightOrder) {
105
- return leftOrder - rightOrder;
106
- }
107
- if (left.title !== right.title)
108
- return left.title.localeCompare(right.title);
109
- return left.id.localeCompare(right.id);
110
- });
111
- }
112
71
  function buildSyncConflictKey(task, archivedValue) {
113
- const source = task || {};
114
- return JSON.stringify({
115
- id: String(source.id || ''),
116
- title: String(source.title || ''),
117
- description: source.description === null || source.description === undefined ? '' : String(source.description),
118
- category: String(source.category || ''),
119
- type: String(source.type || ''),
120
- priority: source.priority === undefined || source.priority === null ? '' : String(source.priority),
121
- complexity: source.complexity === undefined || source.complexity === null ? '' : String(source.complexity),
122
- status: String(source.status || ''),
123
- approach: source.approach === undefined || source.approach === null ? '' : String(source.approach),
124
- canceledReason: source.canceledReason === undefined || source.canceledReason === null ? '' : String(source.canceledReason),
125
- scheduledDate: source.scheduledDate === undefined || source.scheduledDate === null ? '' : String(source.scheduledDate),
126
- dueDate: source.dueDate === undefined || source.dueDate === null ? '' : String(source.dueDate),
127
- scheduledWeekKey: source.scheduledWeekKey === undefined || source.scheduledWeekKey === null ? '' : String(source.scheduledWeekKey),
128
- orderInDay: source.orderInDay === undefined || source.orderInDay === null ? '' : String(source.orderInDay),
129
- workstreamId: source.workstreamId === undefined || source.workstreamId === null ? '' : String(source.workstreamId),
130
- referenceNumber: source.referenceNumber === undefined || source.referenceNumber === null ? '' : String(source.referenceNumber),
131
- assignee: source.assignee === undefined || source.assignee === null ? '' : String(source.assignee),
132
- taxonomies: normalizeConflictTaxonomies(source.taxonomies),
133
- checklistItems: normalizeConflictChecklistItems(source.checklistItems),
134
- isArchived: archivedValue ? '1' : '0'
135
- });
72
+ return buildTaskSyncChangeKey(task, archivedValue);
136
73
  }
137
74
  export function applyWorkspaceSyncSnapshotService(deps, input, workspaceId) {
138
75
  const normalizedWorkspaceId = deps.normalizeWorkspaceId(workspaceId);