@taskforcehq/taskforce 0.3.311 → 0.3.313

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 (454) hide show
  1. package/README.md +40 -2
  2. package/dist/TaskforceCore.js +1 -1
  3. package/dist/components/features/InitiativesModule.js +1 -1
  4. package/dist/components/features/TaskSettings.js +1 -1
  5. package/dist/components/views/StandaloneLayout.js +3 -6
  6. package/dist/components/views/standalone/modals/AccountHubModal.d.ts +1 -2
  7. package/dist/components/views/standalone/modals/AccountHubModal.js +2 -3
  8. package/dist/components/views/standalone/modals/HelpModal.js +15 -2
  9. package/dist/hooks/useFilterSort.js +1 -1
  10. package/dist/hooks/useTaskforce.js +2 -2
  11. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +5 -2
  12. package/dist/ui/assets/{AgentsModule-D8u9P5dZ.js → AgentsModule-BULqIo8e.js} +1 -1
  13. package/dist/ui/assets/{AnnotatedAttachmentWorkspace-CsUauFA2.js → AnnotatedAttachmentWorkspace-DHr4rHK9.js} +1 -1
  14. package/dist/ui/assets/{ContextAttachmentManager-DbQvDHFz.js → ContextAttachmentManager-DoMe2OpY.js} +1 -1
  15. package/dist/ui/assets/{DocumentWorkspace-BmTkN1A8.js → DocumentWorkspace-DumBWhvb.js} +1 -1
  16. package/dist/ui/assets/{EntityActivityTimeline-BXHTM-Nh.js → EntityActivityTimeline-sHk8Nzbq.js} +1 -1
  17. package/dist/ui/assets/{InitiativesModule-D33RyXx0.js → InitiativesModule-3X9UNzHh.js} +1 -1
  18. package/dist/ui/assets/{PlansPage-D0RXlT9_.js → PlansPage-C3A3EYaV.js} +1 -1
  19. package/dist/ui/assets/{TaskContextUpload-Vsg67lpR.js → TaskContextUpload-C8G7pWkX.js} +1 -1
  20. package/dist/ui/assets/{TaskSettings-DshLw7_d.js → TaskSettings-DM1o9Wla.js} +2 -2
  21. package/dist/ui/assets/{WorkflowsModule-CLM-1BnF.js → WorkflowsModule-CW0crzvD.js} +1 -1
  22. package/dist/ui/assets/documentReferences-BZB3nMRb.js +1 -0
  23. package/dist/ui/assets/index-BWFQ9mGn.js +5 -0
  24. package/dist/ui/assets/{index-DOR9PRqt.css → index-DcK_8tuE.css} +1 -1
  25. package/dist/ui/index.html +2 -2
  26. package/package.json +12 -4
  27. package/scripts/postinstall.js +4 -3
  28. package/dist/TaskforceCore.CategoryFallback.test.d.ts +0 -1
  29. package/dist/TaskforceCore.CategoryFallback.test.js +0 -101
  30. package/dist/TaskforceCore.filter-persistence.test.d.ts +0 -1
  31. package/dist/TaskforceCore.filter-persistence.test.js +0 -402
  32. package/dist/TaskforceCore.routing.test.d.ts +0 -1
  33. package/dist/TaskforceCore.routing.test.js +0 -311
  34. package/dist/TaskforceCore.test.d.ts +0 -1
  35. package/dist/TaskforceCore.test.js +0 -7910
  36. package/dist/TaskforceWidget.test.d.ts +0 -1
  37. package/dist/TaskforceWidget.test.js +0 -92
  38. package/dist/UnsavedChangesRelaxed.test.d.ts +0 -1
  39. package/dist/UnsavedChangesRelaxed.test.js +0 -16
  40. package/dist/__tests__/localizationCatalogs.test.d.ts +0 -1
  41. package/dist/__tests__/localizationCatalogs.test.js +0 -54
  42. package/dist/__tests__/workflowSimulation.test.d.ts +0 -1
  43. package/dist/__tests__/workflowSimulation.test.js +0 -113
  44. package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.test.d.ts +0 -1
  45. package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.test.js +0 -278
  46. package/dist/annotatedAttachments/payload.test.d.ts +0 -1
  47. package/dist/annotatedAttachments/payload.test.js +0 -67
  48. package/dist/compat/workspaceSyncCompat.test.d.ts +0 -1
  49. package/dist/compat/workspaceSyncCompat.test.js +0 -124
  50. package/dist/components/features/AgentsModule.test.d.ts +0 -1
  51. package/dist/components/features/AgentsModule.test.js +0 -601
  52. package/dist/components/features/AnnotatedAttachmentWorkspace.test.d.ts +0 -1
  53. package/dist/components/features/AnnotatedAttachmentWorkspace.test.js +0 -2883
  54. package/dist/components/features/DocumentWorkspace.test.d.ts +0 -1
  55. package/dist/components/features/DocumentWorkspace.test.js +0 -1439
  56. package/dist/components/features/TaskSettings.test.d.ts +0 -1
  57. package/dist/components/features/TaskSettings.test.js +0 -1674
  58. package/dist/components/features/settings/TaxonomyLibraryManager.test.d.ts +0 -1
  59. package/dist/components/features/settings/TaxonomyLibraryManager.test.js +0 -141
  60. package/dist/components/task/TaskActionHeader.test.d.ts +0 -1
  61. package/dist/components/task/TaskActionHeader.test.js +0 -91
  62. package/dist/components/task/TaskCard.test.d.ts +0 -1
  63. package/dist/components/task/TaskCard.test.js +0 -513
  64. package/dist/components/task/TaskContextUpload.test.d.ts +0 -1
  65. package/dist/components/task/TaskContextUpload.test.js +0 -506
  66. package/dist/components/task/TaskForm.test.d.ts +0 -1
  67. package/dist/components/task/TaskForm.test.js +0 -946
  68. package/dist/components/task/TaskKanban.empty-column-drop.test.d.ts +0 -1
  69. package/dist/components/task/TaskKanban.empty-column-drop.test.js +0 -66
  70. package/dist/components/task/TaskKanban.planning-drop.test.d.ts +0 -1
  71. package/dist/components/task/TaskKanban.planning-drop.test.js +0 -93
  72. package/dist/components/task/TaskKanban.test.d.ts +0 -1
  73. package/dist/components/task/TaskKanban.test.js +0 -99
  74. package/dist/components/task/TaskList.test.d.ts +0 -1
  75. package/dist/components/task/TaskList.test.js +0 -473
  76. package/dist/components/task/TaskStatusActions.test.d.ts +0 -1
  77. package/dist/components/task/TaskStatusActions.test.js +0 -54
  78. package/dist/components/task/taskKanbanDropRules.test.d.ts +0 -1
  79. package/dist/components/task/taskKanbanDropRules.test.js +0 -114
  80. package/dist/components/ui/LevelSelector.test.d.ts +0 -1
  81. package/dist/components/ui/LevelSelector.test.js +0 -55
  82. package/dist/components/ui/Markdown.test.d.ts +0 -1
  83. package/dist/components/ui/Markdown.test.js +0 -38
  84. package/dist/components/ui/MultiSelectFilter.test.d.ts +0 -1
  85. package/dist/components/ui/MultiSelectFilter.test.js +0 -74
  86. package/dist/components/ui/TaxonomyDropdown.test.d.ts +0 -1
  87. package/dist/components/ui/TaxonomyDropdown.test.js +0 -130
  88. package/dist/components/ui/TopNoticeLayer.test.d.ts +0 -1
  89. package/dist/components/ui/TopNoticeLayer.test.js +0 -25
  90. package/dist/components/views/AppShellHeader.test.d.ts +0 -1
  91. package/dist/components/views/AppShellHeader.test.js +0 -42
  92. package/dist/components/views/PlanComparisonPage.test.d.ts +0 -1
  93. package/dist/components/views/PlanComparisonPage.test.js +0 -758
  94. package/dist/components/views/PlansPage.test.d.ts +0 -1
  95. package/dist/components/views/PlansPage.test.js +0 -710
  96. package/dist/components/views/chrome/WorkspaceChromeSections.test.d.ts +0 -1
  97. package/dist/components/views/chrome/WorkspaceChromeSections.test.js +0 -54
  98. package/dist/components/views/chrome/workspaceChrome.test.d.ts +0 -1
  99. package/dist/components/views/chrome/workspaceChrome.test.js +0 -52
  100. package/dist/components/views/panels/DocumentFilterToolbar.test.d.ts +0 -1
  101. package/dist/components/views/panels/DocumentFilterToolbar.test.js +0 -19
  102. package/dist/components/views/panels/FilterToolbar.test.d.ts +0 -1
  103. package/dist/components/views/panels/FilterToolbar.test.js +0 -47
  104. package/dist/components/views/panels/PlanningDrawer.test.d.ts +0 -1
  105. package/dist/components/views/panels/PlanningDrawer.test.js +0 -529
  106. package/dist/components/views/planningScope.test.d.ts +0 -1
  107. package/dist/components/views/planningScope.test.js +0 -60
  108. package/dist/components/views/standalone/modals/AccountHubModal.test.d.ts +0 -1
  109. package/dist/components/views/standalone/modals/AccountHubModal.test.js +0 -72
  110. package/dist/components/views/standalone/modals/HelpModal.test.d.ts +0 -1
  111. package/dist/components/views/standalone/modals/HelpModal.test.js +0 -23
  112. package/dist/components/views/standalone/modals/SyncEnableWarningModal.test.d.ts +0 -1
  113. package/dist/components/views/standalone/modals/SyncEnableWarningModal.test.js +0 -24
  114. package/dist/components/views/teamManagementAccess.test.d.ts +0 -1
  115. package/dist/components/views/teamManagementAccess.test.js +0 -44
  116. package/dist/config/deployment.test.d.ts +0 -1
  117. package/dist/config/deployment.test.js +0 -90
  118. package/dist/config/envSchema.test.d.ts +0 -1
  119. package/dist/config/envSchema.test.js +0 -125
  120. package/dist/core/AiProfileService.test.d.ts +0 -1
  121. package/dist/core/AiProfileService.test.js +0 -184
  122. package/dist/core/AiProfiles.test.d.ts +0 -1
  123. package/dist/core/AiProfiles.test.js +0 -1873
  124. package/dist/core/AuthTokenService.test.d.ts +0 -1
  125. package/dist/core/AuthTokenService.test.js +0 -78
  126. package/dist/core/BulkUpdateFieldsPreview.test.d.ts +0 -1
  127. package/dist/core/BulkUpdateFieldsPreview.test.js +0 -62
  128. package/dist/core/CompletedAt.test.d.ts +0 -1
  129. package/dist/core/CompletedAt.test.js +0 -44
  130. package/dist/core/CreatedBy.test.d.ts +0 -1
  131. package/dist/core/CreatedBy.test.js +0 -188
  132. package/dist/core/DeletedTaskTrash.test.d.ts +0 -1
  133. package/dist/core/DeletedTaskTrash.test.js +0 -104
  134. package/dist/core/EntitlementsPolicy.test.d.ts +0 -1
  135. package/dist/core/EntitlementsPolicy.test.js +0 -280
  136. package/dist/core/GlobalSettingsService.test.d.ts +0 -1
  137. package/dist/core/GlobalSettingsService.test.js +0 -45
  138. package/dist/core/JsonBackupRuntime.test.d.ts +0 -1
  139. package/dist/core/JsonBackupRuntime.test.js +0 -155
  140. package/dist/core/PlanFeatureCatalog.test.d.ts +0 -1
  141. package/dist/core/PlanFeatureCatalog.test.js +0 -139
  142. package/dist/core/PlanVersionPolicy.test.d.ts +0 -1
  143. package/dist/core/PlanVersionPolicy.test.js +0 -236
  144. package/dist/core/PlanningEntities.test.d.ts +0 -1
  145. package/dist/core/PlanningEntities.test.js +0 -509
  146. package/dist/core/ScheduleFields.test.d.ts +0 -1
  147. package/dist/core/ScheduleFields.test.js +0 -193
  148. package/dist/core/SetupState.test.d.ts +0 -1
  149. package/dist/core/SetupState.test.js +0 -113
  150. package/dist/core/SignupMonetizationSettings.test.d.ts +0 -1
  151. package/dist/core/SignupMonetizationSettings.test.js +0 -515
  152. package/dist/core/Stats.test.d.ts +0 -1
  153. package/dist/core/Stats.test.js +0 -36
  154. package/dist/core/SystemAdmin.test.d.ts +0 -1
  155. package/dist/core/SystemAdmin.test.js +0 -1106
  156. package/dist/core/TaskActivitySync.test.d.ts +0 -1
  157. package/dist/core/TaskActivitySync.test.js +0 -90
  158. package/dist/core/TaskAttachmentsCanonical.test.d.ts +0 -1
  159. package/dist/core/TaskAttachmentsCanonical.test.js +0 -356
  160. package/dist/core/TaskAuditTimeline.test.d.ts +0 -1
  161. package/dist/core/TaskAuditTimeline.test.js +0 -319
  162. package/dist/core/TaskTaxonomyValidation.test.d.ts +0 -1
  163. package/dist/core/TaskTaxonomyValidation.test.js +0 -440
  164. package/dist/core/Taskforce.ids.test.d.ts +0 -1
  165. package/dist/core/Taskforce.ids.test.js +0 -611
  166. package/dist/core/Taskforce.listTasksSlim.test.d.ts +0 -1
  167. package/dist/core/Taskforce.listTasksSlim.test.js +0 -91
  168. package/dist/core/Taskforce.mcpAuth.test.d.ts +0 -1
  169. package/dist/core/Taskforce.mcpAuth.test.js +0 -450
  170. package/dist/core/Taskforce.realtimeMutation.test.d.ts +0 -1
  171. package/dist/core/Taskforce.realtimeMutation.test.js +0 -131
  172. package/dist/core/UserProfileAvatarDrafts.test.d.ts +0 -1
  173. package/dist/core/UserProfileAvatarDrafts.test.js +0 -138
  174. package/dist/core/WorkspaceDelete.test.d.ts +0 -1
  175. package/dist/core/WorkspaceDelete.test.js +0 -159
  176. package/dist/core/WorkspacePermissions.test.d.ts +0 -1
  177. package/dist/core/WorkspacePermissions.test.js +0 -270
  178. package/dist/core/WorkspacePlanMode.test.d.ts +0 -1
  179. package/dist/core/WorkspacePlanMode.test.js +0 -383
  180. package/dist/core/WorkspaceSyncSettings.test.d.ts +0 -1
  181. package/dist/core/WorkspaceSyncSettings.test.js +0 -65
  182. package/dist/core/__tests__/TaskAttachmentsCanonical.test.d.ts +0 -1
  183. package/dist/core/__tests__/TaskAttachmentsCanonical.test.js +0 -212
  184. package/dist/documentReviews/DocumentReviewSessionStore.test.d.ts +0 -1
  185. package/dist/documentReviews/DocumentReviewSessionStore.test.js +0 -127
  186. package/dist/hooks/authGuardPolicy.test.d.ts +0 -1
  187. package/dist/hooks/authGuardPolicy.test.js +0 -76
  188. package/dist/hooks/bootstrapTimeouts.test.d.ts +0 -1
  189. package/dist/hooks/bootstrapTimeouts.test.js +0 -12
  190. package/dist/hooks/sync/controlPlane.test.d.ts +0 -1
  191. package/dist/hooks/sync/controlPlane.test.js +0 -121
  192. package/dist/hooks/sync/lifecyclePolicy.test.d.ts +0 -1
  193. package/dist/hooks/sync/lifecyclePolicy.test.js +0 -124
  194. package/dist/hooks/sync/orchestratorShared.test.d.ts +0 -1
  195. package/dist/hooks/sync/orchestratorShared.test.js +0 -98
  196. package/dist/hooks/sync/pullLifecycle.test.d.ts +0 -1
  197. package/dist/hooks/sync/pullLifecycle.test.js +0 -80
  198. package/dist/hooks/sync/recovery.test.d.ts +0 -1
  199. package/dist/hooks/sync/recovery.test.js +0 -292
  200. package/dist/hooks/sync/transfers.test.d.ts +0 -1
  201. package/dist/hooks/sync/transfers.test.js +0 -928
  202. package/dist/hooks/sync/useRecentSyncEvents.test.d.ts +0 -1
  203. package/dist/hooks/sync/useRecentSyncEvents.test.js +0 -124
  204. package/dist/hooks/sync/useSyncStatusActions.test.d.ts +0 -1
  205. package/dist/hooks/sync/useSyncStatusActions.test.js +0 -133
  206. package/dist/hooks/sync/useSyncStatusControls.test.d.ts +0 -1
  207. package/dist/hooks/sync/useSyncStatusControls.test.js +0 -88
  208. package/dist/hooks/useFilterSort.test.d.ts +0 -1
  209. package/dist/hooks/useFilterSort.test.js +0 -419
  210. package/dist/hooks/useRealtimeSync.test.d.ts +0 -1
  211. package/dist/hooks/useRealtimeSync.test.js +0 -311
  212. package/dist/hooks/useSyncOrchestrator.aiProfiles.test.d.ts +0 -1
  213. package/dist/hooks/useSyncOrchestrator.aiProfiles.test.js +0 -54
  214. package/dist/hooks/useSyncOrchestrator.context-assets.test.d.ts +0 -1
  215. package/dist/hooks/useSyncOrchestrator.context-assets.test.js +0 -228
  216. package/dist/hooks/useSyncOrchestrator.retry-closure.test.d.ts +0 -1
  217. package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +0 -2027
  218. package/dist/hooks/useTaskData.test.d.ts +0 -1
  219. package/dist/hooks/useTaskData.test.js +0 -291
  220. package/dist/hooks/useTaskMutations.test.d.ts +0 -1
  221. package/dist/hooks/useTaskMutations.test.js +0 -256
  222. package/dist/hooks/useTaskforce.contract.test.d.ts +0 -1
  223. package/dist/hooks/useTaskforce.contract.test.js +0 -7
  224. package/dist/hooks/useTaskforce.priority-filters.test.d.ts +0 -1
  225. package/dist/hooks/useTaskforce.priority-filters.test.js +0 -28
  226. package/dist/hooks/useTaskforce.runtime-routing.test.d.ts +0 -1
  227. package/dist/hooks/useTaskforce.runtime-routing.test.js +0 -246
  228. package/dist/hooks/useTaskforce.sync-behavior.test.d.ts +0 -1
  229. package/dist/hooks/useTaskforce.sync-behavior.test.js +0 -3644
  230. package/dist/hooks/useWorkspaceSyncController.test.d.ts +0 -1
  231. package/dist/hooks/useWorkspaceSyncController.test.js +0 -192
  232. package/dist/hooks/workspace/useTaskforceApiRouting.test.d.ts +0 -1
  233. package/dist/hooks/workspace/useTaskforceApiRouting.test.js +0 -77
  234. package/dist/hooks/workspace/workspaceLocalState.test.d.ts +0 -1
  235. package/dist/hooks/workspace/workspaceLocalState.test.js +0 -59
  236. package/dist/localization/localizationCatalogs.test.d.ts +0 -1
  237. package/dist/localization/localizationCatalogs.test.js +0 -37
  238. package/dist/mcp/aiProfileBootstrap.test.d.ts +0 -1
  239. package/dist/mcp/aiProfileBootstrap.test.js +0 -68
  240. package/dist/mcp/canonicalAssetHelpers.test.d.ts +0 -1
  241. package/dist/mcp/canonicalAssetHelpers.test.js +0 -67
  242. package/dist/mcp/clientIntegrations.test.d.ts +0 -1
  243. package/dist/mcp/clientIntegrations.test.js +0 -219
  244. package/dist/mcp/optionResolution.test.d.ts +0 -1
  245. package/dist/mcp/optionResolution.test.js +0 -43
  246. package/dist/mcp/runtime.test.d.ts +0 -1
  247. package/dist/mcp/runtime.test.js +0 -5211
  248. package/dist/mcp/structuredCommentValidation.test.d.ts +0 -1
  249. package/dist/mcp/structuredCommentValidation.test.js +0 -31
  250. package/dist/mcp/structuredDocValidation.test.d.ts +0 -1
  251. package/dist/mcp/structuredDocValidation.test.js +0 -35
  252. package/dist/mcp/toolRegistry.test.d.ts +0 -1
  253. package/dist/mcp/toolRegistry.test.js +0 -34
  254. package/dist/migrations/billingSchemaParity.test.d.ts +0 -1
  255. package/dist/migrations/billingSchemaParity.test.js +0 -160
  256. package/dist/migrations/taskSchemaMigrations.test.d.ts +0 -1
  257. package/dist/migrations/taskSchemaMigrations.test.js +0 -225
  258. package/dist/qaOpen.test.d.ts +0 -1
  259. package/dist/qaOpen.test.js +0 -56
  260. package/dist/releaseVersion.test.d.ts +0 -1
  261. package/dist/releaseVersion.test.js +0 -32
  262. package/dist/runtime/appGates.test.d.ts +0 -1
  263. package/dist/runtime/appGates.test.js +0 -42
  264. package/dist/server/aiProfileAvatarAssets.test.d.ts +0 -1
  265. package/dist/server/aiProfileAvatarAssets.test.js +0 -213
  266. package/dist/server/annotatedAttachmentsRoutes.test.d.ts +0 -1
  267. package/dist/server/annotatedAttachmentsRoutes.test.js +0 -532
  268. package/dist/server/auth.test.d.ts +0 -1
  269. package/dist/server/auth.test.js +0 -131
  270. package/dist/server/buildInfo.test.d.ts +0 -1
  271. package/dist/server/buildInfo.test.js +0 -29
  272. package/dist/server/cors.test.d.ts +0 -1
  273. package/dist/server/cors.test.js +0 -77
  274. package/dist/server/documentReviewRoutes.test.d.ts +0 -1
  275. package/dist/server/documentReviewRoutes.test.js +0 -190
  276. package/dist/server/email.test.d.ts +0 -1
  277. package/dist/server/email.test.js +0 -113
  278. package/dist/server/index.cookieProxy.test.d.ts +0 -1
  279. package/dist/server/index.cookieProxy.test.js +0 -67
  280. package/dist/server/index.rateLimit.test.d.ts +0 -1
  281. package/dist/server/index.rateLimit.test.js +0 -22
  282. package/dist/server/index.test.d.ts +0 -1
  283. package/dist/server/index.test.js +0 -283
  284. package/dist/server/rateLimit.test.d.ts +0 -1
  285. package/dist/server/rateLimit.test.js +0 -107
  286. package/dist/server/realtimeSync.auth.test.d.ts +0 -1
  287. package/dist/server/realtimeSync.auth.test.js +0 -62
  288. package/dist/server/realtimeSync.replay.test.d.ts +0 -1
  289. package/dist/server/realtimeSync.replay.test.js +0 -192
  290. package/dist/server/realtimeSync.workspaceIsolation.test.d.ts +0 -1
  291. package/dist/server/realtimeSync.workspaceIsolation.test.js +0 -101
  292. package/dist/server/routes/billing.test.d.ts +0 -1
  293. package/dist/server/routes/billing.test.js +0 -3515
  294. package/dist/server/routes/shared.test.d.ts +0 -1
  295. package/dist/server/routes/shared.test.js +0 -32
  296. package/dist/server/routes/sync.integration.test.d.ts +0 -1
  297. package/dist/server/routes/sync.integration.test.js +0 -2932
  298. package/dist/server/routes/syncAuxRoutes.test.d.ts +0 -1
  299. package/dist/server/routes/syncAuxRoutes.test.js +0 -158
  300. package/dist/server/routes/syncRouteGuards.test.d.ts +0 -1
  301. package/dist/server/routes/syncRouteGuards.test.js +0 -94
  302. package/dist/server/routes.test.d.ts +0 -1
  303. package/dist/server/routes.test.js +0 -15612
  304. package/dist/server/runtimeMode.test.d.ts +0 -1
  305. package/dist/server/runtimeMode.test.js +0 -26
  306. package/dist/server/securityHeaders.test.d.ts +0 -1
  307. package/dist/server/securityHeaders.test.js +0 -70
  308. package/dist/services/templateEngine.test.d.ts +0 -1
  309. package/dist/services/templateEngine.test.js +0 -150
  310. package/dist/services/templates.test.d.ts +0 -1
  311. package/dist/services/templates.test.js +0 -45
  312. package/dist/services/workflowDocumentFixtures.test.d.ts +0 -1
  313. package/dist/services/workflowDocumentFixtures.test.js +0 -78
  314. package/dist/services/workflowExportMatrix.test.d.ts +0 -1
  315. package/dist/services/workflowExportMatrix.test.js +0 -113
  316. package/dist/services/workflowExportSnapshots.test.d.ts +0 -1
  317. package/dist/services/workflowExportSnapshots.test.js +0 -30
  318. package/dist/services/workflowGeneration.test.d.ts +0 -1
  319. package/dist/services/workflowGeneration.test.js +0 -12
  320. package/dist/services/workflowSimulation.test.d.ts +0 -1
  321. package/dist/services/workflowSimulation.test.js +0 -113
  322. package/dist/services/workflowV2Policy.test.d.ts +0 -1
  323. package/dist/services/workflowV2Policy.test.js +0 -80
  324. package/dist/shared/customTaxonomyLibrary.test.d.ts +0 -1
  325. package/dist/shared/customTaxonomyLibrary.test.js +0 -20
  326. package/dist/shared/passwordPolicy.test.d.ts +0 -1
  327. package/dist/shared/passwordPolicy.test.js +0 -34
  328. package/dist/shared/runtimeContract.test.d.ts +0 -1
  329. package/dist/shared/runtimeContract.test.js +0 -23
  330. package/dist/shared/taxonomyLibrary.test.d.ts +0 -1
  331. package/dist/shared/taxonomyLibrary.test.js +0 -26
  332. package/dist/shared/taxonomyState.test.d.ts +0 -1
  333. package/dist/shared/taxonomyState.test.js +0 -71
  334. package/dist/soak/preflight.cli.d.ts +0 -1
  335. package/dist/soak/preflight.cli.js +0 -28
  336. package/dist/soak/preflight.d.ts +0 -26
  337. package/dist/soak/preflight.js +0 -113
  338. package/dist/soak/preflight.test.d.ts +0 -1
  339. package/dist/soak/preflight.test.js +0 -39
  340. package/dist/storage/objectStorageClient.test.d.ts +0 -1
  341. package/dist/storage/objectStorageClient.test.js +0 -82
  342. package/dist/storage/objectStorageConfig.test.d.ts +0 -1
  343. package/dist/storage/objectStorageConfig.test.js +0 -50
  344. package/dist/storage/postgresAdapter.test.d.ts +0 -1
  345. package/dist/storage/postgresAdapter.test.js +0 -29
  346. package/dist/storage/workspaceAssetStore.test.d.ts +0 -1
  347. package/dist/storage/workspaceAssetStore.test.js +0 -588
  348. package/dist/sync/cloudSyncApi.test.d.ts +0 -1
  349. package/dist/sync/cloudSyncApi.test.js +0 -111
  350. package/dist/sync/collaborationSyncPayload.test.d.ts +0 -1
  351. package/dist/sync/collaborationSyncPayload.test.js +0 -125
  352. package/dist/sync/contentSyncPayload.test.d.ts +0 -1
  353. package/dist/sync/contentSyncPayload.test.js +0 -143
  354. package/dist/sync/encryptionService.test.d.ts +0 -1
  355. package/dist/sync/encryptionService.test.js +0 -52
  356. package/dist/sync/planningSyncPayload.test.d.ts +0 -1
  357. package/dist/sync/planningSyncPayload.test.js +0 -92
  358. package/dist/sync/realtimeFeature.test.d.ts +0 -1
  359. package/dist/sync/realtimeFeature.test.js +0 -30
  360. package/dist/sync/realtimeReconcile.test.d.ts +0 -1
  361. package/dist/sync/realtimeReconcile.test.js +0 -43
  362. package/dist/sync/syncApplyHandlers.test.d.ts +0 -1
  363. package/dist/sync/syncApplyHandlers.test.js +0 -626
  364. package/dist/sync/syncService.test.d.ts +0 -1
  365. package/dist/sync/syncService.test.js +0 -903
  366. package/dist/sync/taskSyncPayload.test.d.ts +0 -1
  367. package/dist/sync/taskSyncPayload.test.js +0 -54
  368. package/dist/sync/workspacePullFeed.test.d.ts +0 -1
  369. package/dist/sync/workspacePullFeed.test.js +0 -438
  370. package/dist/sync/workspaceSyncModel.test.d.ts +0 -1
  371. package/dist/sync/workspaceSyncModel.test.js +0 -1442
  372. package/dist/test/setup.d.ts +0 -1
  373. package/dist/test/setup.js +0 -15
  374. package/dist/ui/assets/documentReferences-BPWp6ce0.js +0 -1
  375. package/dist/ui/assets/index-zvbo2Jse.js +0 -5
  376. package/dist/utils/accountProfileSummaryCache.test.d.ts +0 -1
  377. package/dist/utils/accountProfileSummaryCache.test.js +0 -63
  378. package/dist/utils/annotatedAttachments.test.d.ts +0 -1
  379. package/dist/utils/annotatedAttachments.test.js +0 -108
  380. package/dist/utils/assignees.test.d.ts +0 -1
  381. package/dist/utils/assignees.test.js +0 -25
  382. package/dist/utils/avatarUpload.test.d.ts +0 -1
  383. package/dist/utils/avatarUpload.test.js +0 -40
  384. package/dist/utils/canonicalAssetKind.test.d.ts +0 -1
  385. package/dist/utils/canonicalAssetKind.test.js +0 -24
  386. package/dist/utils/coalescedRefresh.test.d.ts +0 -1
  387. package/dist/utils/coalescedRefresh.test.js +0 -30
  388. package/dist/utils/constants.icons.test.d.ts +0 -1
  389. package/dist/utils/constants.icons.test.js +0 -41
  390. package/dist/utils/planParser.test.d.ts +0 -1
  391. package/dist/utils/planParser.test.js +0 -183
  392. package/dist/utils/planningReferences.test.d.ts +0 -1
  393. package/dist/utils/planningReferences.test.js +0 -17
  394. package/dist/utils/supportContact.test.d.ts +0 -1
  395. package/dist/utils/supportContact.test.js +0 -19
  396. package/dist/utils/syncEventDetails.test.d.ts +0 -1
  397. package/dist/utils/syncEventDetails.test.js +0 -23
  398. package/dist/utils/syncEventPresentation.test.d.ts +0 -1
  399. package/dist/utils/syncEventPresentation.test.js +0 -64
  400. package/dist/utils/syncStatusPresentation.test.d.ts +0 -1
  401. package/dist/utils/syncStatusPresentation.test.js +0 -164
  402. package/dist/utils/taskActivity.test.d.ts +0 -1
  403. package/dist/utils/taskActivity.test.js +0 -218
  404. package/dist/utils/taskDraftDefaults.test.d.ts +0 -1
  405. package/dist/utils/taskDraftDefaults.test.js +0 -34
  406. package/dist/utils/taskDragZones.test.d.ts +0 -1
  407. package/dist/utils/taskDragZones.test.js +0 -14
  408. package/dist/utils/taskNormalization.test.d.ts +0 -1
  409. package/dist/utils/taskNormalization.test.js +0 -158
  410. package/dist/utils/taskSearch.test.d.ts +0 -1
  411. package/dist/utils/taskSearch.test.js +0 -69
  412. package/dist/utils/taskUtils.test.d.ts +0 -1
  413. package/dist/utils/taskUtils.test.js +0 -19
  414. package/dist/utils/taskforceApiClient.test.d.ts +0 -1
  415. package/dist/utils/taskforceApiClient.test.js +0 -44
  416. package/dist/utils/taxonomyFormDefaults.test.d.ts +0 -1
  417. package/dist/utils/taxonomyFormDefaults.test.js +0 -63
  418. package/dist/utils/uiNotice.test.d.ts +0 -1
  419. package/dist/utils/uiNotice.test.js +0 -18
  420. package/dist/utils/workspaceIdentity.test.d.ts +0 -1
  421. package/dist/utils/workspaceIdentity.test.js +0 -61
  422. package/dist/utils/workspaceLifecycle.test.d.ts +0 -1
  423. package/dist/utils/workspaceLifecycle.test.js +0 -64
  424. package/dist/utils/workspaceSyncPresentation.test.d.ts +0 -1
  425. package/dist/utils/workspaceSyncPresentation.test.js +0 -71
  426. package/scripts/bootstrap-playwright-auth.mjs +0 -155
  427. package/scripts/check-cloud-mcp.mjs +0 -83
  428. package/scripts/check-compat-boundaries.mjs +0 -41
  429. package/scripts/check-env.ts +0 -31
  430. package/scripts/check-localization-strings.mjs +0 -49
  431. package/scripts/check-runtime-boundaries.mjs +0 -44
  432. package/scripts/debug-global.mjs +0 -34
  433. package/scripts/debug-login.mjs +0 -32
  434. package/scripts/debug-server.mjs +0 -36
  435. package/scripts/deploy-prod.sh +0 -41
  436. package/scripts/deploy-staging.sh +0 -23
  437. package/scripts/export-sqlite-to-postgres.mjs +0 -123
  438. package/scripts/generate-env-example.ts +0 -8
  439. package/scripts/mcp-stdio-adapter.mjs +0 -160
  440. package/scripts/migrate-task-data-assets.mjs +0 -408
  441. package/scripts/playwright-auth.sh +0 -19
  442. package/scripts/qa-open-lib.mjs +0 -175
  443. package/scripts/qa-open-lib.mjs.d.ts +0 -49
  444. package/scripts/qa-open.mjs +0 -352
  445. package/scripts/release-version-lib.mjs +0 -88
  446. package/scripts/release-version.mjs +0 -72
  447. package/scripts/run-billing-performance-smoke.sh +0 -24
  448. package/scripts/run-dev-proxy.sh +0 -51
  449. package/scripts/run-e2e-realtime.sh +0 -30
  450. package/scripts/run-smoke.sh +0 -35
  451. package/scripts/run-soak.sh +0 -41
  452. package/scripts/test-global.js +0 -143
  453. package/scripts/update-homebrew-formula.sh +0 -108
  454. package/scripts/with-esbuild.sh +0 -11
@@ -1,758 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { fireEvent, render, screen, waitFor } from '@testing-library/react';
3
- import { within } from '@testing-library/react';
4
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
5
- import { PlanComparisonPage } from './PlanComparisonPage';
6
- describe('PlanComparisonPage', () => {
7
- beforeEach(() => {
8
- globalThis.__DEBUG_MODE__ = false;
9
- vi.stubGlobal('fetch', vi.fn(async () => ({
10
- ok: true,
11
- json: async () => ({
12
- pageTitle: 'Subscription Plans',
13
- pageDescription: 'Manage your subscription and explore available features. Your current plan is highlighted below.',
14
- pricingSource: {
15
- environment: 'production',
16
- runtimeMode: 'cloud'
17
- },
18
- plans: [
19
- {
20
- planId: 'free',
21
- displayName: 'Free',
22
- description: 'Start using Taskforce at no cost.',
23
- status: 'active',
24
- defaultVersion: {
25
- planVersionId: 'free-v1',
26
- versionNumber: 1,
27
- seatLimit: null,
28
- metadata: {}
29
- },
30
- features: [],
31
- pricing: {
32
- month: { pricingType: 'free', stripePriceId: null, unitAmount: null, currency: null, interval: 'month' },
33
- year: null
34
- }
35
- },
36
- {
37
- planId: 'team-5',
38
- displayName: 'Team 5',
39
- description: 'For small collaborative teams.',
40
- status: 'active',
41
- defaultVersion: {
42
- planVersionId: 'team-5-v2',
43
- versionNumber: 2,
44
- seatLimit: 5,
45
- metadata: {}
46
- },
47
- features: [],
48
- pricing: {
49
- month: { pricingType: 'stripe', stripePriceId: 'price_team_5_month', unitAmount: 2000, currency: 'usd', interval: 'month' },
50
- year: { pricingType: 'stripe', stripePriceId: 'price_team_5_year', unitAmount: 20000, currency: 'usd', interval: 'year' }
51
- }
52
- }
53
- ]
54
- })
55
- })));
56
- });
57
- afterEach(() => {
58
- delete globalThis.__DEBUG_MODE__;
59
- vi.unstubAllGlobals();
60
- });
61
- it('shows pricing source details only when debug mode is enabled', async () => {
62
- globalThis.__DEBUG_MODE__ = true;
63
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
64
- expect(await screen.findByText('Pricing source: production (cloud)')).toBeInTheDocument();
65
- });
66
- it('renders plan descriptions when provided by the pricing payload', async () => {
67
- const { container } = render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
68
- expect(await screen.findByText('Start using Taskforce at no cost.')).toBeInTheDocument();
69
- expect(screen.getByText('For small collaborative teams.')).toBeInTheDocument();
70
- expect(screen.getByRole('heading', { name: 'Founding beta' })).toBeInTheDocument();
71
- expect(screen.getByText(/Taskforce is in founding beta/)).toBeInTheDocument();
72
- expect(screen.getByText(/Early members get access while the product is still forming/)).toBeInTheDocument();
73
- expect(screen.getByText('Prices are listed in USD. Taxes may apply.')).toBeInTheDocument();
74
- expect(screen.getByText('Local install is free on every plan. Cloud limits apply only to hosted workspaces.')).toBeInTheDocument();
75
- expect(screen.getByRole('link', { name: 'support@taskforcehq.ai' })).toHaveAttribute('href', 'mailto:support@taskforcehq.ai');
76
- const foundingBeta = screen.getByRole('heading', { name: 'Founding beta' }).closest('section');
77
- const firstPlanCard = container.querySelector('[data-testid^="plan-card-"]');
78
- const planCards = container.querySelectorAll('[data-testid^="plan-card-"]');
79
- const lastPlanCard = planCards[planCards.length - 1];
80
- const pricingNotes = screen.getByText('Prices are listed in USD. Taxes may apply.').closest('div');
81
- const cloudCapacity = screen.getByRole('heading', { name: 'Need more cloud capacity?' }).closest('section');
82
- const teamWorkspacesCard = screen.getByRole('heading', { name: 'Team workspaces are coming soon.' }).closest('div');
83
- if (!foundingBeta || !firstPlanCard) {
84
- throw new Error('Expected founding beta copy and a plan card to render.');
85
- }
86
- if (!lastPlanCard || !pricingNotes) {
87
- throw new Error('Expected pricing notes to render below the plan cards.');
88
- }
89
- if (!cloudCapacity || !teamWorkspacesCard) {
90
- throw new Error('Expected cloud capacity copy to render above the team workspaces card.');
91
- }
92
- expect(Boolean(foundingBeta.compareDocumentPosition(firstPlanCard) & Node.DOCUMENT_POSITION_FOLLOWING)).toBe(true);
93
- expect(Boolean(lastPlanCard.compareDocumentPosition(pricingNotes) & Node.DOCUMENT_POSITION_FOLLOWING)).toBe(true);
94
- expect(Boolean(pricingNotes.compareDocumentPosition(cloudCapacity) & Node.DOCUMENT_POSITION_FOLLOWING)).toBe(true);
95
- expect(Boolean(cloudCapacity.compareDocumentPosition(teamWorkspacesCard) & Node.DOCUMENT_POSITION_FOLLOWING)).toBe(true);
96
- });
97
- it('renders pricing above the plan description', async () => {
98
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
99
- const teamCard = await screen.findByTestId('plan-card-team-5');
100
- const monthlyPrice = within(teamCard).getByText('$20');
101
- const description = within(teamCard).getByText('For small collaborative teams.');
102
- expect(Boolean(monthlyPrice.compareDocumentPosition(description) & Node.DOCUMENT_POSITION_FOLLOWING)).toBe(true);
103
- });
104
- it('shows founding offer pricing when campaign prices are present', async () => {
105
- vi.stubGlobal('fetch', vi.fn(async () => ({
106
- ok: true,
107
- json: async () => ({
108
- plans: [
109
- {
110
- planId: 'pro',
111
- displayName: 'Pro',
112
- description: 'For serious operators.',
113
- status: 'active',
114
- defaultVersion: {
115
- planVersionId: 'pro-v1',
116
- versionNumber: 1,
117
- seatLimit: null,
118
- metadata: {}
119
- },
120
- features: [],
121
- pricing: {
122
- month: { pricingType: 'stripe', stripePriceId: 'price_pro_month', unitAmount: 3000, currency: 'usd', interval: 'month' },
123
- year: null
124
- },
125
- campaignPricing: {
126
- month: { pricingType: 'stripe', stripePriceId: 'price_pro_campaign_month', unitAmount: 1200, currency: 'usd', interval: 'month' },
127
- year: null
128
- }
129
- }
130
- ]
131
- })
132
- })));
133
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
134
- const proCard = await screen.findByTestId('plan-card-pro');
135
- expect(within(proCard).getByText('$30')).toBeInTheDocument();
136
- expect(within(proCard).getByText('Founding Offer:')).toBeInTheDocument();
137
- expect(within(proCard).getByText('$12')).toBeInTheDocument();
138
- expect(within(proCard).getAllByText('/ month')).toHaveLength(2);
139
- });
140
- it('renders and selects campaign-only pricing intervals', async () => {
141
- const onSelectPlan = vi.fn();
142
- vi.stubGlobal('fetch', vi.fn(async () => ({
143
- ok: true,
144
- json: async () => ({
145
- plans: [
146
- {
147
- planId: 'pro',
148
- displayName: 'Pro',
149
- description: 'For serious operators.',
150
- status: 'active',
151
- defaultVersion: {
152
- planVersionId: 'pro-v1',
153
- versionNumber: 1,
154
- seatLimit: null,
155
- metadata: {}
156
- },
157
- features: [],
158
- pricing: {
159
- month: null,
160
- year: null
161
- },
162
- campaignPricing: {
163
- month: { pricingType: 'stripe', stripePriceId: 'price_pro_campaign_month', unitAmount: 1200, currency: 'usd', interval: 'month' },
164
- year: null
165
- }
166
- }
167
- ]
168
- })
169
- })));
170
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, onBack: () => { }, backLabel: "Back", onSelectPlan: onSelectPlan }));
171
- const proCard = await screen.findByTestId('plan-card-pro');
172
- expect(within(proCard).queryByText('$30')).not.toBeInTheDocument();
173
- expect(within(proCard).getByText('Founding Offer:')).toBeInTheDocument();
174
- expect(within(proCard).getByText('$12')).toBeInTheDocument();
175
- fireEvent.click(within(proCard).getByRole('button', { name: 'Get Started' }));
176
- expect(onSelectPlan).toHaveBeenCalledWith({
177
- planId: 'pro',
178
- planVersionId: 'pro-v1',
179
- interval: 'month',
180
- pricingType: 'stripe',
181
- pricingAudience: 'campaign',
182
- isCurrentPlan: false
183
- });
184
- });
185
- it('prefers pricing payload header copy when provided', async () => {
186
- vi.stubGlobal('fetch', vi.fn(async () => ({
187
- ok: true,
188
- json: async () => ({
189
- pageTitle: 'Choose Your Taskforce Plan',
190
- pageDescription: 'Compare plans and pick the right fit for your team.',
191
- pricingSource: {
192
- environment: 'production',
193
- runtimeMode: 'cloud'
194
- },
195
- plans: []
196
- })
197
- })));
198
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", subtitle: "Fallback subtitle", isAuthenticated: false, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
199
- expect(await screen.findByRole('heading', { name: 'Choose Your Taskforce Plan' })).toBeInTheDocument();
200
- expect(screen.getByText('Compare plans and pick the right fit for your team.')).toBeInTheDocument();
201
- });
202
- it('can keep the provided heading when pricing payload title exists', async () => {
203
- vi.stubGlobal('fetch', vi.fn(async () => ({
204
- ok: true,
205
- json: async () => ({
206
- pageTitle: 'Choose Your Taskforce Plan',
207
- pricingSource: {
208
- environment: 'production',
209
- runtimeMode: 'cloud'
210
- },
211
- plans: []
212
- })
213
- })));
214
- render(_jsx(PlanComparisonPage, { heading: "Pricing for human-agent work.", preferPricingPageTitle: false, isAuthenticated: false, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
215
- expect(await screen.findByRole('heading', { name: 'Pricing for human-agent work.' })).toBeInTheDocument();
216
- expect(screen.queryByRole('heading', { name: 'Choose Your Taskforce Plan' })).not.toBeInTheDocument();
217
- });
218
- it('renders pricing payload description as sanitized HTML', async () => {
219
- vi.stubGlobal('fetch', vi.fn(async () => ({
220
- ok: true,
221
- json: async () => ({
222
- pageTitle: 'Choose Your Taskforce Plan',
223
- pageDescription: '<p>Local install is <strong>free</strong>.</p><p><a href="https://example.com/pricing">Read more</a><a href="javascript:alert(1)">Nope</a></p><script>alert(1)</script>',
224
- plans: []
225
- })
226
- })));
227
- const { container } = render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", subtitle: "Fallback subtitle", isAuthenticated: false, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
228
- expect(await screen.findByText(/Local install is/)).toBeInTheDocument();
229
- expect(container.querySelector('strong')?.textContent).toBe('free');
230
- expect(container.querySelector('script')).toBeNull();
231
- expect(screen.queryByText('alert(1)')).not.toBeInTheDocument();
232
- expect(container.querySelector('a[href="https://example.com/pricing"]')?.textContent).toBe('Read more');
233
- expect(container.querySelector('a[href^="javascript:"]')).toBeNull();
234
- expect(screen.getByText('Nope')).toBeInTheDocument();
235
- });
236
- it('falls back to provided pricing source details when the pricing response omits them', async () => {
237
- globalThis.__DEBUG_MODE__ = true;
238
- vi.stubGlobal('fetch', vi.fn(async () => ({
239
- ok: true,
240
- json: async () => ({
241
- plans: [
242
- {
243
- planId: 'free',
244
- displayName: 'Free',
245
- status: 'active',
246
- defaultVersion: {
247
- planVersionId: 'free-v1',
248
- versionNumber: 1,
249
- seatLimit: null,
250
- metadata: {}
251
- },
252
- features: [],
253
- pricing: {
254
- month: { pricingType: 'free', stripePriceId: null, unitAmount: null, currency: null, interval: 'month' },
255
- year: null
256
- }
257
- }
258
- ]
259
- })
260
- })));
261
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, fallbackPricingSource: { environment: 'performance', runtimeMode: 'local' }, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
262
- expect(await screen.findByText('Pricing source: performance (local)')).toBeInTheDocument();
263
- });
264
- it('keeps pricing source details hidden when debug mode is disabled', async () => {
265
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
266
- await screen.findByRole('heading', { name: 'Subscription Plans' });
267
- expect(screen.queryByText('Pricing source: production (cloud)')).not.toBeInTheDocument();
268
- });
269
- it('renders public feature copy when provided by the pricing payload', async () => {
270
- vi.stubGlobal('fetch', vi.fn(async () => ({
271
- ok: true,
272
- json: async () => ({
273
- pricingSource: {
274
- environment: 'production',
275
- runtimeMode: 'cloud'
276
- },
277
- plans: [
278
- {
279
- planId: 'team-5',
280
- displayName: 'Team 5',
281
- status: 'active',
282
- defaultVersion: {
283
- planVersionId: 'team-5-v2',
284
- versionNumber: 2,
285
- seatLimit: 5,
286
- metadata: {}
287
- },
288
- features: [
289
- {
290
- featureKey: 'collaboration.ai_profiles',
291
- access: 'enabled',
292
- label: 'AI Profiles',
293
- publicLabel: 'AI teammates',
294
- publicDescription: 'Add reusable AI teammates to your workspace.',
295
- publicDescriptionVisible: true
296
- }
297
- ],
298
- pricing: {
299
- month: { pricingType: 'stripe', stripePriceId: 'price_team_5_month', unitAmount: 2000, currency: 'usd', interval: 'month' },
300
- year: null
301
- }
302
- }
303
- ]
304
- })
305
- })));
306
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
307
- expect(await screen.findByText('AI teammates')).toBeInTheDocument();
308
- expect(screen.getByText('Add reusable AI teammates to your workspace.')).toBeInTheDocument();
309
- expect(screen.queryByText('Collaboration Ai Profiles')).not.toBeInTheDocument();
310
- });
311
- it('hides feature descriptions when publicDescriptionVisible is false', async () => {
312
- vi.stubGlobal('fetch', vi.fn(async () => ({
313
- ok: true,
314
- json: async () => ({
315
- pricingSource: {
316
- environment: 'production',
317
- runtimeMode: 'cloud'
318
- },
319
- plans: [
320
- {
321
- planId: 'team-5',
322
- displayName: 'Team 5',
323
- status: 'active',
324
- defaultVersion: {
325
- planVersionId: 'team-5-v2',
326
- versionNumber: 2,
327
- seatLimit: 5,
328
- metadata: {}
329
- },
330
- features: [
331
- {
332
- featureKey: 'collaboration.ai_profiles',
333
- access: 'enabled',
334
- label: 'AI Profiles',
335
- publicLabel: 'AI teammates',
336
- publicDescription: 'Add reusable AI teammates to your workspace.',
337
- publicDescriptionVisible: false
338
- }
339
- ],
340
- pricing: {
341
- month: { pricingType: 'stripe', stripePriceId: 'price_team_5_month', unitAmount: 2000, currency: 'usd', interval: 'month' },
342
- year: null
343
- }
344
- }
345
- ]
346
- })
347
- })));
348
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
349
- expect(await screen.findByText('AI teammates')).toBeInTheDocument();
350
- expect(screen.queryByText('Add reusable AI teammates to your workspace.')).not.toBeInTheDocument();
351
- });
352
- it('renders inline numeric feature limits next to each feature label', async () => {
353
- vi.stubGlobal('fetch', vi.fn(async () => ({
354
- ok: true,
355
- json: async () => ({
356
- pricingSource: {
357
- environment: 'production',
358
- runtimeMode: 'cloud'
359
- },
360
- plans: [
361
- {
362
- planId: 'free',
363
- displayName: 'Free',
364
- status: 'active',
365
- defaultVersion: {
366
- planVersionId: 'free-v1',
367
- versionNumber: 1,
368
- seatLimit: 12,
369
- metadata: {}
370
- },
371
- features: [
372
- {
373
- featureKey: 'workspace.workspaces',
374
- access: 'enabled',
375
- label: 'Workspaces',
376
- config: { maxWorkspaces: 1 }
377
- },
378
- {
379
- featureKey: 'collaboration.ai_profiles',
380
- access: 'limited',
381
- label: 'AI Profiles',
382
- publicLabel: 'AI Agents',
383
- config: { maxAiProfiles: 4 }
384
- },
385
- {
386
- featureKey: 'context.uploads',
387
- access: 'enabled',
388
- label: 'Cloud Storage',
389
- config: { storageLimitMb: 24 }
390
- },
391
- {
392
- featureKey: 'collaboration.team_management',
393
- access: 'enabled',
394
- label: 'Team Management'
395
- }
396
- ],
397
- pricing: {
398
- month: { pricingType: 'free', stripePriceId: null, unitAmount: null, currency: null, interval: 'month' },
399
- year: null
400
- }
401
- }
402
- ]
403
- })
404
- })));
405
- const { container } = render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
406
- const freeCard = await screen.findByTestId('plan-card-free');
407
- const featureTextNodes = Array.from(freeCard.querySelectorAll('span')).map((node) => node.textContent);
408
- expect(featureTextNodes).toContain('1 Workspace');
409
- expect(featureTextNodes).toContain('4 AI Agents');
410
- expect(featureTextNodes).toContain('24MB Cloud Storage');
411
- expect(featureTextNodes).toContain('12 Team Management');
412
- expect(container.querySelector('[class*="featureLimitUnit"]')?.textContent).toBe('MB');
413
- });
414
- it('renders the storage unit suffix in a smaller accent span', async () => {
415
- vi.stubGlobal('fetch', vi.fn(async () => ({
416
- ok: true,
417
- json: async () => ({
418
- pricingSource: {
419
- environment: 'production',
420
- runtimeMode: 'cloud'
421
- },
422
- plans: [
423
- {
424
- planId: 'free',
425
- displayName: 'Free',
426
- status: 'active',
427
- defaultVersion: {
428
- planVersionId: 'free-v1',
429
- versionNumber: 1,
430
- seatLimit: null,
431
- metadata: {}
432
- },
433
- features: [
434
- {
435
- featureKey: 'context.uploads',
436
- access: 'enabled',
437
- label: 'Cloud Storage',
438
- config: { storageLimitMb: 64 }
439
- }
440
- ],
441
- pricing: {
442
- month: { pricingType: 'free', stripePriceId: null, unitAmount: null, currency: null, interval: 'month' },
443
- year: null
444
- }
445
- }
446
- ]
447
- })
448
- })));
449
- const { container } = render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
450
- await screen.findByText('Cloud Storage');
451
- const accent = container.querySelector('[class*="featureLimitAccent"]');
452
- const unit = container.querySelector('[class*="featureLimitUnit"]');
453
- expect(accent?.textContent).toBe('64MB');
454
- expect(unit?.textContent).toBe('MB');
455
- });
456
- it('renders storage limits above 1000 MB as rounded GB', async () => {
457
- vi.stubGlobal('fetch', vi.fn(async () => ({
458
- ok: true,
459
- json: async () => ({
460
- pricingSource: {
461
- environment: 'production',
462
- runtimeMode: 'cloud'
463
- },
464
- plans: [
465
- {
466
- planId: 'pro',
467
- displayName: 'Pro',
468
- status: 'active',
469
- defaultVersion: {
470
- planVersionId: 'pro-v1',
471
- versionNumber: 1,
472
- seatLimit: null,
473
- metadata: {}
474
- },
475
- features: [
476
- {
477
- featureKey: 'context.uploads',
478
- access: 'enabled',
479
- label: 'Cloud Storage',
480
- config: { storageLimitMb: 2500 }
481
- }
482
- ],
483
- pricing: {
484
- month: { pricingType: 'stripe', stripePriceId: 'price_pro_month', unitAmount: 1999, currency: 'usd', interval: 'month' },
485
- year: null
486
- }
487
- }
488
- ]
489
- })
490
- })));
491
- const { container } = render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
492
- await screen.findByText('Cloud Storage');
493
- const accent = container.querySelector('[class*="featureLimitAccent"]');
494
- const unit = container.querySelector('[class*="featureLimitUnit"]');
495
- expect(accent?.textContent).toBe('3GB');
496
- expect(unit?.textContent).toBe('GB');
497
- });
498
- it('hides missing yearly pricing rows and buttons instead of rendering unavailable state', async () => {
499
- vi.stubGlobal('fetch', vi.fn(async () => ({
500
- ok: true,
501
- json: async () => ({
502
- pricingSource: {
503
- environment: 'production',
504
- runtimeMode: 'cloud'
505
- },
506
- plans: [
507
- {
508
- planId: 'operator',
509
- displayName: 'Operator',
510
- status: 'active',
511
- defaultVersion: {
512
- planVersionId: 'operator-v1',
513
- versionNumber: 1,
514
- seatLimit: null,
515
- metadata: {}
516
- },
517
- features: [],
518
- pricing: {
519
- month: { pricingType: 'stripe', stripePriceId: 'price_operator_month', unitAmount: 999, currency: 'usd', interval: 'month' },
520
- year: null
521
- }
522
- }
523
- ]
524
- })
525
- })));
526
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: true, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
527
- const operatorCard = await screen.findByTestId('plan-card-operator');
528
- expect(within(operatorCard).getByText('$9.99')).toBeInTheDocument();
529
- expect(within(operatorCard).getByText('/ month')).toBeInTheDocument();
530
- expect(within(operatorCard).queryByText('/ year')).not.toBeInTheDocument();
531
- expect(within(operatorCard).queryByText('Unavailable')).not.toBeInTheDocument();
532
- expect(within(operatorCard).getByRole('button', { name: 'Get Started' })).toBeInTheDocument();
533
- expect(within(operatorCard).queryByRole('button', { name: 'Start Yearly' })).not.toBeInTheDocument();
534
- });
535
- it('does not mark a plan current when only the plan id matches but the version does not', async () => {
536
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: true, currentPlanId: "team-5", currentPlanVersionId: "team-5-v1", currentEntitlementState: "active", onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
537
- expect(await screen.findByRole('heading', { name: 'Subscription Plans' })).toBeInTheDocument();
538
- expect(screen.queryByText('Current Plan')).not.toBeInTheDocument();
539
- });
540
- it('marks a trialing entitlement as the current plan', async () => {
541
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: true, currentPlanId: "team-5", currentPlanVersionId: "team-5-v2", currentEntitlementState: "trialing", onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
542
- expect(await screen.findByRole('heading', { name: 'Subscription Plans' })).toBeInTheDocument();
543
- expect(screen.getByText('Current Plan')).toBeInTheDocument();
544
- });
545
- it('can show the current plan as a non-interactive indicator when billing is managed from page chrome', async () => {
546
- const onSelectPlan = vi.fn();
547
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: true, currentPlanId: "team-5", currentPlanVersionId: "team-5-v2", currentEntitlementState: "active", canManageCurrentPlan: true, currentPlanCardActionMode: "indicator", onBack: () => { }, backLabel: "Back", onSelectPlan: onSelectPlan }));
548
- expect(await screen.findByRole('heading', { name: 'Subscription Plans' })).toBeInTheDocument();
549
- const currentCard = screen.getByTestId('plan-card-team-5');
550
- expect(currentCard).not.toHaveAttribute('role', 'button');
551
- expect(screen.queryByTestId('plan-manage-team-5')).not.toBeInTheDocument();
552
- expect(screen.queryByRole('button', { name: 'Manage Plan' })).not.toBeInTheDocument();
553
- expect(screen.getByTestId('plan-current-team-5')).toBeDisabled();
554
- fireEvent.click(currentCard);
555
- expect(onSelectPlan).not.toHaveBeenCalled();
556
- });
557
- it('can render the page header bar even when shell chrome is present', async () => {
558
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: true, chrome: _jsx("div", { children: "Shell chrome" }), showHeaderBarWithChrome: true, topActions: _jsx("button", { type: "button", children: "Manage billing" }), onBack: () => { }, backLabel: "Back to App", onSelectPlan: () => { } }));
559
- expect(await screen.findByRole('heading', { name: 'Subscription Plans' })).toBeInTheDocument();
560
- expect(screen.getByRole('button', { name: 'Back to App' })).toBeInTheDocument();
561
- expect(screen.getByRole('button', { name: 'Manage billing' })).toBeInTheDocument();
562
- });
563
- it('does not mark a canceled entitlement as current through the plan-id fallback path', async () => {
564
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: true, currentPlanId: "team-5", currentPlanVersionId: null, currentEntitlementState: "canceled", onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
565
- expect(await screen.findByRole('heading', { name: 'Subscription Plans' })).toBeInTheDocument();
566
- expect(screen.queryByText('Current Plan')).not.toBeInTheDocument();
567
- });
568
- it('does not mark a linked pending-plan-selection entitlement as the current plan', async () => {
569
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: true, currentPlanId: "team-5", currentPlanVersionId: "team-5-v2", currentEntitlementState: "pending_plan_selection", canManageCurrentPlan: true, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
570
- expect(await screen.findByRole('heading', { name: 'Subscription Plans' })).toBeInTheDocument();
571
- expect(screen.queryByRole('button', { name: 'Manage Plan' })).not.toBeInTheDocument();
572
- expect(screen.queryByText('Current Plan')).not.toBeInTheDocument();
573
- expect(screen.getByRole('button', { name: 'Start Monthly' })).toBeInTheDocument();
574
- });
575
- it('can disable the page back button while onboarding remains blocked', async () => {
576
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: true, onBack: () => { }, backLabel: "Back to App", backDisabled: true, onSelectPlan: () => { } }));
577
- expect(await screen.findByRole('button', { name: 'Back to App' })).toBeDisabled();
578
- });
579
- it('shows pricing before auth resolves but keeps plan selection disabled until bootstrap finishes', async () => {
580
- const onSelectPlan = vi.fn();
581
- const view = render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, authSessionResolved: false, onBack: () => { }, backLabel: "Back", onSelectPlan: onSelectPlan }));
582
- expect(await screen.findByRole('heading', { name: 'Subscription Plans' })).toBeInTheDocument();
583
- const freeCard = screen.getByTestId('plan-card-free');
584
- expect(screen.getByRole('button', { name: 'Get Started' })).toBeDisabled();
585
- expect(screen.getByRole('button', { name: 'Start Monthly' })).toBeDisabled();
586
- expect(screen.getByRole('button', { name: 'Start Yearly' })).toBeDisabled();
587
- expect(freeCard).not.toHaveAttribute('role', 'button');
588
- view.rerender(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, authSessionResolved: true, onBack: () => { }, backLabel: "Back", onSelectPlan: onSelectPlan }));
589
- const enabledFreeCard = screen.getByTestId('plan-card-free');
590
- expect(screen.getByRole('button', { name: 'Get Started' })).toBeEnabled();
591
- expect(screen.getByRole('button', { name: 'Start Monthly' })).toBeEnabled();
592
- expect(screen.getByRole('button', { name: 'Start Yearly' })).toBeEnabled();
593
- expect(enabledFreeCard).toHaveAttribute('role', 'button');
594
- fireEvent.click(screen.getByRole('button', { name: 'Get Started' }));
595
- await waitFor(() => {
596
- expect(onSelectPlan).toHaveBeenCalledWith({
597
- planId: 'free',
598
- planVersionId: 'free-v1',
599
- interval: 'month',
600
- pricingType: 'free',
601
- pricingAudience: 'public',
602
- isCurrentPlan: false
603
- });
604
- });
605
- });
606
- it('selects the whole plan card using the default available interval', async () => {
607
- const onSelectPlan = vi.fn();
608
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, onBack: () => { }, backLabel: "Back", onSelectPlan: onSelectPlan }));
609
- await screen.findByRole('heading', { name: 'Subscription Plans' });
610
- const freeHeading = screen.getByRole('heading', { name: 'Free' });
611
- const freeCard = freeHeading.closest('[role="button"]');
612
- expect(freeCard).toBeTruthy();
613
- expect(within(freeCard).getByText('$0')).toBeInTheDocument();
614
- expect(within(freeCard).getByText('/ month')).toBeInTheDocument();
615
- fireEvent.click(freeCard);
616
- await waitFor(() => {
617
- expect(onSelectPlan).toHaveBeenCalledWith({
618
- planId: 'free',
619
- planVersionId: 'free-v1',
620
- interval: 'month',
621
- pricingType: 'free',
622
- pricingAudience: 'public',
623
- isCurrentPlan: false
624
- });
625
- });
626
- });
627
- it('does not trigger current-plan actions when the current plan is not Stripe-managed', async () => {
628
- const onSelectPlan = vi.fn();
629
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: true, currentPlanId: "free", currentPlanVersionId: "free-v1", currentEntitlementState: "active", canManageCurrentPlan: false, onBack: () => { }, backLabel: "Back", onSelectPlan: onSelectPlan }));
630
- await screen.findByRole('heading', { name: 'Subscription Plans' });
631
- const currentButton = screen.getByRole('button', { name: 'Current Plan' });
632
- expect(currentButton).toBeDisabled();
633
- expect(onSelectPlan).not.toHaveBeenCalled();
634
- });
635
- it('loads pricing from the provided cloud endpoint', async () => {
636
- const fetchMock = vi.fn().mockResolvedValue({
637
- ok: true,
638
- json: async () => ({
639
- pricingSource: {
640
- environment: 'performance',
641
- runtimeMode: 'cloud'
642
- },
643
- plans: [
644
- {
645
- planId: 'free',
646
- displayName: 'Free',
647
- status: 'active',
648
- defaultVersion: {
649
- planVersionId: 'free-v1',
650
- versionNumber: 1,
651
- seatLimit: null,
652
- metadata: {}
653
- },
654
- features: [],
655
- pricing: {
656
- month: { pricingType: 'free', stripePriceId: null, unitAmount: 0, currency: null, interval: 'month' },
657
- year: null
658
- }
659
- }
660
- ]
661
- })
662
- });
663
- vi.stubGlobal('fetch', fetchMock);
664
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, pricingEndpoint: "https://performance-app.example/api/taskforce/public/pricing", onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
665
- expect(await screen.findByRole('heading', { name: 'Free' })).toBeInTheDocument();
666
- expect(fetchMock).toHaveBeenCalledTimes(1);
667
- expect(fetchMock).toHaveBeenCalledWith('https://performance-app.example/api/taskforce/public/pricing', {
668
- method: 'GET',
669
- credentials: 'include'
670
- });
671
- expect(screen.queryByText('Connecting to plan pricing...')).not.toBeInTheDocument();
672
- });
673
- it('orders plans from free to highest priced tier', async () => {
674
- const fetchMock = vi.fn().mockResolvedValue({
675
- ok: true,
676
- json: async () => ({
677
- pricingSource: {
678
- environment: 'production',
679
- runtimeMode: 'cloud'
680
- },
681
- plans: [
682
- {
683
- planId: 'team-5',
684
- displayName: 'Team 5',
685
- status: 'active',
686
- defaultVersion: {
687
- planVersionId: 'team-5-v2',
688
- versionNumber: 3,
689
- seatLimit: 5,
690
- metadata: {}
691
- },
692
- features: [],
693
- pricing: {
694
- month: { pricingType: 'stripe', stripePriceId: 'price_team_5_month', unitAmount: 12000, currency: 'usd', interval: 'month' },
695
- year: { pricingType: 'stripe', stripePriceId: 'price_team_5_year', unitAmount: 120000, currency: 'usd', interval: 'year' }
696
- }
697
- },
698
- {
699
- planId: 'free',
700
- displayName: 'Free',
701
- status: 'active',
702
- defaultVersion: {
703
- planVersionId: 'free-v1',
704
- versionNumber: 1,
705
- seatLimit: null,
706
- metadata: {}
707
- },
708
- features: [],
709
- pricing: {
710
- month: { pricingType: 'free', stripePriceId: null, unitAmount: 0, currency: null, interval: 'month' },
711
- year: null
712
- }
713
- },
714
- {
715
- planId: 'basic',
716
- displayName: 'Basic',
717
- status: 'active',
718
- defaultVersion: {
719
- planVersionId: 'basic-v1',
720
- versionNumber: 2,
721
- seatLimit: 1,
722
- metadata: {}
723
- },
724
- features: [],
725
- pricing: {
726
- month: { pricingType: 'stripe', stripePriceId: 'price_basic_month', unitAmount: 3000, currency: 'usd', interval: 'month' },
727
- year: { pricingType: 'stripe', stripePriceId: 'price_basic_year', unitAmount: 30000, currency: 'usd', interval: 'year' }
728
- }
729
- }
730
- ]
731
- })
732
- });
733
- vi.stubGlobal('fetch', fetchMock);
734
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
735
- await screen.findByRole('heading', { name: 'Subscription Plans' });
736
- const planNames = screen.getAllByRole('heading', { level: 3 }).map((node) => node.textContent);
737
- expect(planNames).toEqual(['Free', 'Basic', 'Team 5']);
738
- });
739
- it('defaults to the same-origin pricing endpoint', async () => {
740
- const fetchMock = vi.fn().mockResolvedValue({
741
- ok: true,
742
- json: async () => ({
743
- pricingSource: {
744
- environment: 'production',
745
- runtimeMode: 'cloud'
746
- },
747
- plans: []
748
- })
749
- });
750
- vi.stubGlobal('fetch', fetchMock);
751
- render(_jsx(PlanComparisonPage, { heading: "Subscription Plans", isAuthenticated: false, onBack: () => { }, backLabel: "Back", onSelectPlan: () => { } }));
752
- await screen.findByText('Paid plans are getting their final polish.');
753
- expect(fetchMock).toHaveBeenCalledWith('/api/taskforce/public/pricing', {
754
- method: 'GET',
755
- credentials: 'include'
756
- });
757
- });
758
- });