@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
@@ -275,6 +275,10 @@ export interface GlobalTaskforceSettings {
275
275
  site?: {
276
276
  showRunTaskforceLocally?: boolean;
277
277
  pricingPageEnabled?: boolean;
278
+ animatedBackgroundEnabled?: boolean;
279
+ siteTheme?: 'dark' | 'light';
280
+ pricingPageTitle?: string;
281
+ pricingPageDescription?: string;
278
282
  };
279
283
  setup?: {
280
284
  mode?: 'core' | 'operations';
@@ -287,6 +291,25 @@ export interface GlobalTaskforceSettings {
287
291
  signedUploadTtlSeconds?: number;
288
292
  signedDownloadTtlSeconds?: number;
289
293
  };
294
+ oauthProviders?: {
295
+ google?: {
296
+ enabled?: boolean;
297
+ clientId?: string;
298
+ clientSecret?: string;
299
+ };
300
+ github?: {
301
+ enabled?: boolean;
302
+ clientId?: string;
303
+ clientSecret?: string;
304
+ };
305
+ apple?: {
306
+ enabled?: boolean;
307
+ servicesId?: string;
308
+ teamId?: string;
309
+ keyId?: string;
310
+ privateKeyPem?: string;
311
+ };
312
+ };
290
313
  }
291
314
  export interface SettingsSplitPayload {
292
315
  system: GlobalTaskforceSettings;
@@ -303,11 +326,11 @@ export interface UserGlobalSyncSettings {
303
326
  export type OnboardingPolicyMode = 'require_plan_selection' | 'auto_grant_free' | 'auto_start_trial';
304
327
  export interface OnboardingPolicy {
305
328
  mode: OnboardingPolicyMode;
306
- planVersionId: string | null;
329
+ planId: string | null;
307
330
  }
308
331
  export interface OnboardingPolicyValidationResult {
309
332
  valid: boolean;
310
- code?: 'ONBOARDING_PLAN_VERSION_REQUIRED' | 'ONBOARDING_PLAN_VERSION_NOT_FOUND' | 'ONBOARDING_PLAN_NOT_ENABLED' | 'ONBOARDING_PLAN_MUST_BE_FREE' | 'ONBOARDING_PLAN_TRIAL_REQUIRED';
333
+ code?: 'ONBOARDING_PLAN_REQUIRED' | 'ONBOARDING_PLAN_NOT_FOUND' | 'ONBOARDING_PLAN_NOT_ENABLED' | 'ONBOARDING_PLAN_MUST_BE_FREE' | 'ONBOARDING_PLAN_TRIAL_REQUIRED';
311
334
  message?: string;
312
335
  details?: Record<string, unknown>;
313
336
  }
@@ -316,6 +339,36 @@ export type SystemRole = 'system_admin' | 'user';
316
339
  export type PermissionMode = 'read-only' | 'read-write';
317
340
  export type AuthTokenPurpose = 'email_verification' | 'password_reset' | 'invite_accept';
318
341
  export type McpAccessTokenScope = 'tasks:read' | 'tasks:write' | 'workspace:read';
342
+ export type UserAuthProvider = 'password' | 'google' | 'github' | 'apple';
343
+ export interface UserAuthIdentity {
344
+ id: string;
345
+ tenantId: string;
346
+ userId: string;
347
+ provider: UserAuthProvider;
348
+ providerSubject: string | null;
349
+ providerEmail: string | null;
350
+ providerEmailVerified: boolean | null;
351
+ displayNameSnapshot: string | null;
352
+ avatarUrlSnapshot: string | null;
353
+ createdAt: string;
354
+ updatedAt: string;
355
+ lastLoginAt: string | null;
356
+ linkedAt: string | null;
357
+ disabledAt: string | null;
358
+ }
359
+ export type InviteeState = 'pending_setup' | 'existing_account';
360
+ export interface InviteAcceptanceDetails {
361
+ state: 'valid' | 'expired' | 'used' | 'missing' | 'revoked';
362
+ email?: string;
363
+ userId?: string;
364
+ workspaceId?: string;
365
+ inviteeState?: InviteeState;
366
+ availableMethods?: UserAuthProvider[];
367
+ /** @deprecated use inviteeState */
368
+ inviteeKind?: 'existing_user' | 'new_user';
369
+ /** @deprecated use availableMethods */
370
+ passwordRequired?: boolean;
371
+ }
319
372
  export type McpAccessTokenStatus = 'active' | 'revoked' | 'expired';
320
373
  export type McpOAuthProvider = 'chatgpt' | 'claude';
321
374
  export type McpOAuthClientStatus = 'active' | 'revoked';
@@ -326,6 +379,8 @@ export interface UserAccessRecord {
326
379
  role: AccessRole;
327
380
  permissionMode: PermissionMode;
328
381
  disabled: boolean;
382
+ accountDisabled?: boolean;
383
+ workspaceDisabled?: boolean;
329
384
  betaAccess: boolean;
330
385
  }
331
386
  export interface UserIdentityRecord {
@@ -340,6 +395,7 @@ export interface WorkspaceUserRecord {
340
395
  userId: string;
341
396
  email: string;
342
397
  displayName?: string | null;
398
+ avatarUrl?: string | null;
343
399
  role: AccessRole;
344
400
  permissionMode: PermissionMode;
345
401
  betaAccess: boolean;
@@ -453,6 +509,9 @@ export interface PlanFeatureCatalogItem {
453
509
  featureKey: string;
454
510
  label: string;
455
511
  description: string;
512
+ publicLabel?: string | null;
513
+ publicDescription?: string | null;
514
+ publicDisplayOrder?: number | null;
456
515
  allowedAccessModes: PlanFeatureAccess[];
457
516
  configTemplate: Record<string, unknown>;
458
517
  dependsOn?: string[];
@@ -470,10 +529,20 @@ export interface PlanVersionSnapshot {
470
529
  export interface PlanCatalogSnapshot {
471
530
  planId: string;
472
531
  displayName: string;
532
+ description: string | null;
473
533
  status: 'active' | 'archived';
474
534
  createdAt: string;
475
535
  updatedAt: string;
476
536
  }
537
+ export interface OnboardingPlanOption {
538
+ planId: string;
539
+ planDisplayName: string;
540
+ defaultPlanVersionId: string;
541
+ defaultVersionNumber: number;
542
+ planStatus: 'active' | 'archived';
543
+ supportsAutoGrantFree: boolean;
544
+ supportsAutoStartTrial: boolean;
545
+ }
477
546
  export interface AccountEntitlementSnapshot {
478
547
  accountId: string;
479
548
  planVersionId: string;
@@ -520,6 +589,7 @@ export interface PasswordAuthResult {
520
589
  userId: string;
521
590
  workspaceId: string;
522
591
  role: AccessRole;
592
+ identityId?: string;
523
593
  };
524
594
  code?: 'INVALID_CREDENTIALS' | 'EMAIL_NOT_VERIFIED';
525
595
  }
@@ -612,4 +682,7 @@ export interface McpOAuthAccessTokenAuthResult {
612
682
  provider: McpOAuthProvider;
613
683
  scopes: McpAccessTokenScope[];
614
684
  status: McpOAuthGrantStatus;
685
+ aiProfileId?: string | null;
686
+ aiProfileToken?: string | null;
687
+ aiProfileName?: string | null;
615
688
  }
@@ -1,6 +1,11 @@
1
1
  import { useCallback, useEffect } from 'react';
2
2
  import { createDefaultAssigneeOptions } from '../../utils/assignees';
3
+ import { logBootstrapDebug } from '../workspace/workspaceLocalState';
3
4
  import { persistLocalMutationActorUserId, readLocalMutationActorUserId } from '../../utils/taskforceApiClient';
5
+ import { AUTH_SESSION_REQUEST_TIMEOUT_MS } from '../bootstrapTimeouts';
6
+ function getBootstrapTimestamp() {
7
+ return typeof performance !== 'undefined' ? performance.now() : Date.now();
8
+ }
4
9
  export function useTaskforceAuthBootstrap({ runtimeConfigReady, shouldProbeCloudAuth, authSessionResolved, resolveCloudAuthUrl, authOnlyCloudMode, authRequiredError, runtimeMode, workspaceSelectionScope, markBootstrapPhase, markBootstrapStalled, setRuntimeMode, setAuthRequiredForApi, setIsAuthenticated, setAuthUserId, setAuthWorkspaceId, setAuthUserEmail, setAuthUserDisplayName, setAuthUserAvatarUrl, setUserGlobalSyncStatus, setUserGlobalSyncError, setHasBetaAccess, setAvailableWorkspaces, setHydratedWorkspaceRole, setAssigneeOptions, setAuthBlocked, setAuthSessionResolved, setError, applyResolvedWorkspaceId, readPersistedWorkspaceId, authSessionRequestRef, authSessionEpochRef, authSessionLastCheckedAtRef, authSessionLastResultRef, isLoopbackHost, setAuthStateReadyRefs }) {
5
10
  const checkAuthSession = useCallback(async (options) => {
6
11
  const force = options?.force === true;
@@ -41,11 +46,20 @@ export function useTaskforceAuthBootstrap({ runtimeConfigReady, shouldProbeCloud
41
46
  const requestEpoch = ++authSessionEpochRef.current;
42
47
  let request = null;
43
48
  request = (async () => {
49
+ const startedAt = getBootstrapTimestamp();
44
50
  const abortController = new AbortController();
45
51
  const timeoutId = typeof window !== 'undefined'
46
- ? window.setTimeout(() => abortController.abort(), 8000)
52
+ ? window.setTimeout(() => abortController.abort(), AUTH_SESSION_REQUEST_TIMEOUT_MS)
47
53
  : null;
48
54
  const isStaleRequest = () => authSessionEpochRef.current !== requestEpoch;
55
+ const logResult = (event, details) => {
56
+ logBootstrapDebug(event, {
57
+ durationMs: Math.max(0, Math.round(getBootstrapTimestamp() - startedAt)),
58
+ force,
59
+ sessionUrl,
60
+ ...details
61
+ });
62
+ };
49
63
  try {
50
64
  const res = await fetch(sessionUrl, {
51
65
  method: 'GET',
@@ -59,6 +73,7 @@ export function useTaskforceAuthBootstrap({ runtimeConfigReady, shouldProbeCloud
59
73
  if (res.status === 429) {
60
74
  setAuthSessionResolved(true);
61
75
  setAuthStateReadyRefs(authSessionLastResultRef.current, true, false);
76
+ logResult('auth_session_rate_limited', { status: res.status });
62
77
  return authSessionLastResultRef.current;
63
78
  }
64
79
  if (!res.ok) {
@@ -70,6 +85,7 @@ export function useTaskforceAuthBootstrap({ runtimeConfigReady, shouldProbeCloud
70
85
  setAuthSessionResolved(true);
71
86
  setAuthStateReadyRefs(false, true, false);
72
87
  authSessionLastResultRef.current = false;
88
+ logResult('auth_session_request_failed', { status: res.status });
73
89
  return false;
74
90
  }
75
91
  const data = await res.json();
@@ -117,9 +133,16 @@ export function useTaskforceAuthBootstrap({ runtimeConfigReady, shouldProbeCloud
117
133
  authSessionLastResultRef.current = authenticated;
118
134
  if (authenticated)
119
135
  markBootstrapPhase('ready');
136
+ logResult('auth_session_resolved', {
137
+ status: res.status,
138
+ authenticated,
139
+ workspaceId: authenticated ? workspaceId : '',
140
+ userId: authenticated ? userId : 'anonymous',
141
+ authRequiredForApi: nextAuthRequiredForApi
142
+ });
120
143
  return authenticated;
121
144
  }
122
- catch {
145
+ catch (error) {
123
146
  if (isStaleRequest()) {
124
147
  return authSessionLastResultRef.current;
125
148
  }
@@ -129,6 +152,9 @@ export function useTaskforceAuthBootstrap({ runtimeConfigReady, shouldProbeCloud
129
152
  setAuthStateReadyRefs(false, true, false);
130
153
  authSessionLastResultRef.current = false;
131
154
  markBootstrapStalled('Unable to verify your session.');
155
+ logResult('auth_session_exception', {
156
+ error: error instanceof Error ? error.message : String(error)
157
+ });
132
158
  return authSessionLastResultRef.current;
133
159
  }
134
160
  finally {
@@ -0,0 +1,4 @@
1
+ export declare const BOOTSTRAP_REQUEST_TIMEOUT_MS = 12000;
2
+ export declare const CLOUD_BOOTSTRAP_REQUEST_TIMEOUT_MS = 30000;
3
+ export declare const AUTH_SESSION_REQUEST_TIMEOUT_MS = 20000;
4
+ export declare function resolveBootstrapRequestTimeoutMs(runtimeMode: 'local' | 'cloud'): number;
@@ -0,0 +1,8 @@
1
+ export const BOOTSTRAP_REQUEST_TIMEOUT_MS = 12_000;
2
+ export const CLOUD_BOOTSTRAP_REQUEST_TIMEOUT_MS = 30_000;
3
+ export const AUTH_SESSION_REQUEST_TIMEOUT_MS = 20_000;
4
+ export function resolveBootstrapRequestTimeoutMs(runtimeMode) {
5
+ return runtimeMode === 'cloud'
6
+ ? CLOUD_BOOTSTRAP_REQUEST_TIMEOUT_MS
7
+ : BOOTSTRAP_REQUEST_TIMEOUT_MS;
8
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { AUTH_SESSION_REQUEST_TIMEOUT_MS, BOOTSTRAP_REQUEST_TIMEOUT_MS, CLOUD_BOOTSTRAP_REQUEST_TIMEOUT_MS, resolveBootstrapRequestTimeoutMs } from './bootstrapTimeouts';
3
+ describe('bootstrap timeout budgets', () => {
4
+ it('keeps local bootstrap checks short', () => {
5
+ expect(resolveBootstrapRequestTimeoutMs('local')).toBe(BOOTSTRAP_REQUEST_TIMEOUT_MS);
6
+ });
7
+ it('gives cloud bootstrap checks enough room for edge delays', () => {
8
+ expect(resolveBootstrapRequestTimeoutMs('cloud')).toBe(CLOUD_BOOTSTRAP_REQUEST_TIMEOUT_MS);
9
+ expect(CLOUD_BOOTSTRAP_REQUEST_TIMEOUT_MS).toBeGreaterThan(BOOTSTRAP_REQUEST_TIMEOUT_MS);
10
+ expect(AUTH_SESSION_REQUEST_TIMEOUT_MS).toBeGreaterThan(BOOTSTRAP_REQUEST_TIMEOUT_MS);
11
+ });
12
+ });
@@ -45,6 +45,8 @@ export function resolveRepairPhase(args) {
45
45
  return 'provision-local';
46
46
  if (workspaceSyncPhase === 'attach-cloud')
47
47
  return 'attach-cloud';
48
+ if (workspaceSyncPhase === 'active' || lastBootstrapPhase === 'active')
49
+ return 'active';
48
50
  if (lastBootstrapPhase === 'provision-local' || lastBootstrapPhase === 'attach-cloud') {
49
51
  return lastBootstrapPhase;
50
52
  }
@@ -0,0 +1,37 @@
1
+ import type { WorkspaceSyncPhase } from '../../sync/workspaceSyncState';
2
+ export type WorkspaceSyncBlockedReason = 'cloud-auth-unconfigured' | 'runtime-not-local' | 'sync-disabled' | 'invalid-workspace' | 'repair-active' | 'attach-cloud' | 'provision-local' | 'auth-required' | 'push-in-flight' | 'pull-in-flight' | 'retry-pending' | 'lease-held';
3
+ export type WorkspaceSyncOperation = 'pull' | 'push' | 'repair';
4
+ export type WorkspaceSyncControlPlaneDecision = {
5
+ allowed: true;
6
+ } | {
7
+ allowed: false;
8
+ reason: WorkspaceSyncBlockedReason;
9
+ retainPendingSignature: boolean;
10
+ };
11
+ interface WorkspaceSyncControlPlaneBaseArgs {
12
+ cloudAuthConfigured: boolean;
13
+ runtimeMode: 'local' | 'cloud';
14
+ workspaceCloudSyncEnabled: boolean;
15
+ currentWorkspaceId: string;
16
+ isAuthenticated: boolean;
17
+ }
18
+ interface PushSyncReadinessArgs extends WorkspaceSyncControlPlaneBaseArgs {
19
+ workspaceSyncPhase: WorkspaceSyncPhase;
20
+ repairModeActive: boolean;
21
+ repairModeBypass: boolean;
22
+ pushInFlight: boolean;
23
+ pullInFlight: boolean;
24
+ }
25
+ interface PullSyncReadinessArgs extends WorkspaceSyncControlPlaneBaseArgs {
26
+ workspaceSyncPhase: WorkspaceSyncPhase;
27
+ repairModeActive: boolean;
28
+ repairModeBypass: boolean;
29
+ retryPending: boolean;
30
+ pushInFlight: boolean;
31
+ pullInFlight: boolean;
32
+ }
33
+ export declare function resolvePushSyncReadiness(args: PushSyncReadinessArgs): WorkspaceSyncControlPlaneDecision;
34
+ export declare function resolvePullSyncReadiness(args: PullSyncReadinessArgs): WorkspaceSyncControlPlaneDecision;
35
+ export declare function resolveRetrySyncReadiness(args: WorkspaceSyncControlPlaneBaseArgs): WorkspaceSyncControlPlaneDecision;
36
+ export declare function createWorkspaceSyncLeaseHeldDecision(operation: WorkspaceSyncOperation): WorkspaceSyncControlPlaneDecision;
37
+ export {};
@@ -0,0 +1,78 @@
1
+ import { isValidWorkspaceKey } from './orchestratorShared';
2
+ const ALLOW_SYNC_OPERATION = { allowed: true };
3
+ function blockSyncOperation(reason, options) {
4
+ return {
5
+ allowed: false,
6
+ reason,
7
+ retainPendingSignature: options?.retainPendingSignature === true
8
+ };
9
+ }
10
+ function resolveBaseSyncReadiness(args, options) {
11
+ if (!args.cloudAuthConfigured)
12
+ return blockSyncOperation('cloud-auth-unconfigured');
13
+ if (args.runtimeMode !== 'local')
14
+ return blockSyncOperation('runtime-not-local');
15
+ if (!args.workspaceCloudSyncEnabled)
16
+ return blockSyncOperation('sync-disabled');
17
+ if ((options?.requireValidWorkspace ?? true) && !isValidWorkspaceKey(args.currentWorkspaceId)) {
18
+ return blockSyncOperation('invalid-workspace');
19
+ }
20
+ return null;
21
+ }
22
+ export function resolvePushSyncReadiness(args) {
23
+ const baseReadiness = resolveBaseSyncReadiness(args);
24
+ if (baseReadiness)
25
+ return baseReadiness;
26
+ if (args.repairModeActive && !args.repairModeBypass) {
27
+ return blockSyncOperation('repair-active', { retainPendingSignature: true });
28
+ }
29
+ if (args.workspaceSyncPhase === 'attach-cloud') {
30
+ return blockSyncOperation('attach-cloud', { retainPendingSignature: true });
31
+ }
32
+ if (!args.isAuthenticated) {
33
+ return blockSyncOperation('auth-required');
34
+ }
35
+ if (args.pushInFlight) {
36
+ return blockSyncOperation('push-in-flight', { retainPendingSignature: true });
37
+ }
38
+ if (args.pullInFlight) {
39
+ return blockSyncOperation('pull-in-flight', { retainPendingSignature: true });
40
+ }
41
+ return ALLOW_SYNC_OPERATION;
42
+ }
43
+ export function resolvePullSyncReadiness(args) {
44
+ const baseReadiness = resolveBaseSyncReadiness(args);
45
+ if (baseReadiness)
46
+ return baseReadiness;
47
+ if (args.repairModeActive && !args.repairModeBypass) {
48
+ return blockSyncOperation('repair-active');
49
+ }
50
+ if (args.workspaceSyncPhase === 'provision-local') {
51
+ return blockSyncOperation('provision-local');
52
+ }
53
+ if (args.retryPending) {
54
+ return blockSyncOperation('retry-pending');
55
+ }
56
+ if (!args.isAuthenticated) {
57
+ return blockSyncOperation('auth-required');
58
+ }
59
+ if (args.pullInFlight) {
60
+ return blockSyncOperation('pull-in-flight');
61
+ }
62
+ if (args.pushInFlight) {
63
+ return blockSyncOperation('push-in-flight');
64
+ }
65
+ return ALLOW_SYNC_OPERATION;
66
+ }
67
+ export function resolveRetrySyncReadiness(args) {
68
+ const baseReadiness = resolveBaseSyncReadiness(args, { requireValidWorkspace: false });
69
+ if (baseReadiness)
70
+ return baseReadiness;
71
+ if (!args.isAuthenticated) {
72
+ return blockSyncOperation('auth-required');
73
+ }
74
+ return ALLOW_SYNC_OPERATION;
75
+ }
76
+ export function createWorkspaceSyncLeaseHeldDecision(operation) {
77
+ return blockSyncOperation('lease-held', { retainPendingSignature: operation === 'push' });
78
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,121 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { createWorkspaceSyncLeaseHeldDecision, resolvePullSyncReadiness, resolvePushSyncReadiness, resolveRetrySyncReadiness, } from './controlPlane';
3
+ const makeBaseArgs = () => ({
4
+ cloudAuthConfigured: true,
5
+ runtimeMode: 'local',
6
+ workspaceCloudSyncEnabled: true,
7
+ currentWorkspaceId: 'workspace-123',
8
+ isAuthenticated: true
9
+ });
10
+ describe('sync control plane', () => {
11
+ it('blocks push during repair and retains the pending signature', () => {
12
+ expect(resolvePushSyncReadiness({
13
+ ...makeBaseArgs(),
14
+ workspaceSyncPhase: 'active',
15
+ repairModeActive: true,
16
+ repairModeBypass: false,
17
+ pushInFlight: false,
18
+ pullInFlight: false
19
+ })).toEqual({
20
+ allowed: false,
21
+ reason: 'repair-active',
22
+ retainPendingSignature: true
23
+ });
24
+ });
25
+ it('allows repair push to bypass the repair-active gate', () => {
26
+ expect(resolvePushSyncReadiness({
27
+ ...makeBaseArgs(),
28
+ workspaceSyncPhase: 'active',
29
+ repairModeActive: true,
30
+ repairModeBypass: true,
31
+ pushInFlight: false,
32
+ pullInFlight: false
33
+ })).toEqual({ allowed: true });
34
+ });
35
+ it('blocks push during attach-cloud and retains the pending signature', () => {
36
+ expect(resolvePushSyncReadiness({
37
+ ...makeBaseArgs(),
38
+ workspaceSyncPhase: 'attach-cloud',
39
+ repairModeActive: false,
40
+ repairModeBypass: false,
41
+ pushInFlight: false,
42
+ pullInFlight: false
43
+ })).toEqual({
44
+ allowed: false,
45
+ reason: 'attach-cloud',
46
+ retainPendingSignature: true
47
+ });
48
+ });
49
+ it('blocks pull during provision-local', () => {
50
+ expect(resolvePullSyncReadiness({
51
+ ...makeBaseArgs(),
52
+ workspaceSyncPhase: 'provision-local',
53
+ repairModeActive: false,
54
+ repairModeBypass: false,
55
+ retryPending: false,
56
+ pushInFlight: false,
57
+ pullInFlight: false
58
+ })).toEqual({
59
+ allowed: false,
60
+ reason: 'provision-local',
61
+ retainPendingSignature: false
62
+ });
63
+ });
64
+ it('blocks pull when a retry is already pending', () => {
65
+ expect(resolvePullSyncReadiness({
66
+ ...makeBaseArgs(),
67
+ workspaceSyncPhase: 'active',
68
+ repairModeActive: false,
69
+ repairModeBypass: false,
70
+ retryPending: true,
71
+ pushInFlight: false,
72
+ pullInFlight: false
73
+ })).toEqual({
74
+ allowed: false,
75
+ reason: 'retry-pending',
76
+ retainPendingSignature: false
77
+ });
78
+ });
79
+ it('surfaces auth-required for retry readiness before the session is refreshed', () => {
80
+ expect(resolveRetrySyncReadiness({
81
+ ...makeBaseArgs(),
82
+ isAuthenticated: false
83
+ })).toEqual({
84
+ allowed: false,
85
+ reason: 'auth-required',
86
+ retainPendingSignature: false
87
+ });
88
+ });
89
+ it('rejects invalid workspace ids for transfer operations', () => {
90
+ expect(resolvePushSyncReadiness({
91
+ ...makeBaseArgs(),
92
+ currentWorkspaceId: 'default',
93
+ workspaceSyncPhase: 'active',
94
+ repairModeActive: false,
95
+ repairModeBypass: false,
96
+ pushInFlight: false,
97
+ pullInFlight: false
98
+ })).toEqual({
99
+ allowed: false,
100
+ reason: 'invalid-workspace',
101
+ retainPendingSignature: false
102
+ });
103
+ });
104
+ it('marks lease contention as retaining the pending signature only for push', () => {
105
+ expect(createWorkspaceSyncLeaseHeldDecision('push')).toEqual({
106
+ allowed: false,
107
+ reason: 'lease-held',
108
+ retainPendingSignature: true
109
+ });
110
+ expect(createWorkspaceSyncLeaseHeldDecision('pull')).toEqual({
111
+ allowed: false,
112
+ reason: 'lease-held',
113
+ retainPendingSignature: false
114
+ });
115
+ expect(createWorkspaceSyncLeaseHeldDecision('repair')).toEqual({
116
+ allowed: false,
117
+ reason: 'lease-held',
118
+ retainPendingSignature: false
119
+ });
120
+ });
121
+ });
@@ -0,0 +1,45 @@
1
+ import type { WorkspaceSyncPhase } from '../../sync/workspaceSyncState';
2
+ export type WorkspaceSyncPresentationStatus = 'off' | 'syncing' | 'attention' | 'healthy';
3
+ interface WorkspaceSyncPresentationArgs {
4
+ enabled: boolean;
5
+ phase: WorkspaceSyncPhase;
6
+ busy: boolean;
7
+ retryAt: string | null;
8
+ lastErrorMessage: string | null;
9
+ }
10
+ interface WorkspaceSyncLifecycleBaseArgs {
11
+ cloudAuthConfigured: boolean;
12
+ runtimeMode: 'local' | 'cloud';
13
+ workspaceCloudSyncEnabled: boolean;
14
+ authSessionResolved: boolean;
15
+ }
16
+ interface WorkspaceSyncAutomaticPullArgs extends WorkspaceSyncLifecycleBaseArgs {
17
+ workspaceSyncPhase: WorkspaceSyncPhase;
18
+ lastPullAt: string | null;
19
+ retryPending: boolean;
20
+ }
21
+ interface WorkspaceSyncFullReconcileArgs extends WorkspaceSyncLifecycleBaseArgs {
22
+ workspaceSyncPhase: WorkspaceSyncPhase;
23
+ isAuthenticated: boolean;
24
+ }
25
+ interface WorkspaceSyncStartupRepairArgs extends WorkspaceSyncFullReconcileArgs {
26
+ alreadyRan: boolean;
27
+ }
28
+ interface WorkspaceSyncReactivePushArgs extends WorkspaceSyncLifecycleBaseArgs {
29
+ workspaceSyncPhase: WorkspaceSyncPhase;
30
+ workspaceSyncReferenceSnapshotsReady: boolean;
31
+ }
32
+ export declare function resolveWorkspaceSyncPresentation({ enabled, phase, busy, retryAt, lastErrorMessage }: WorkspaceSyncPresentationArgs): {
33
+ status: WorkspaceSyncPresentationStatus;
34
+ summary: string;
35
+ recommendedAction: string;
36
+ };
37
+ export declare function shouldScheduleWorkspaceReactivePush(args: WorkspaceSyncReactivePushArgs): boolean;
38
+ export declare function shouldStartWorkspacePushWatchdog(args: WorkspaceSyncReactivePushArgs): boolean;
39
+ export declare function resolveWorkspaceAutomaticPullPolicy(args: WorkspaceSyncAutomaticPullArgs): {
40
+ shouldStart: boolean;
41
+ shouldKickOffImmediately: boolean;
42
+ };
43
+ export declare function shouldStartWorkspacePeriodicFullReconcile(args: WorkspaceSyncFullReconcileArgs): boolean;
44
+ export declare function shouldRunWorkspaceStartupRepair(args: WorkspaceSyncStartupRepairArgs): boolean;
45
+ export {};
@@ -0,0 +1,93 @@
1
+ function canRunLocalWorkspaceSyncLifecycle(args) {
2
+ return args.cloudAuthConfigured
3
+ && args.runtimeMode === 'local'
4
+ && args.workspaceCloudSyncEnabled
5
+ && args.authSessionResolved;
6
+ }
7
+ export function resolveWorkspaceSyncPresentation({ enabled, phase, busy, retryAt, lastErrorMessage }) {
8
+ if (!enabled) {
9
+ return {
10
+ status: 'off',
11
+ summary: 'Sync is turned off for this workspace.',
12
+ recommendedAction: 'Turn on sync when you are ready to back up this workspace.'
13
+ };
14
+ }
15
+ if (phase === 'provision-local') {
16
+ return {
17
+ status: 'syncing',
18
+ summary: busy
19
+ ? 'Uploading this workspace to cloud for the first time.'
20
+ : 'Preparing the first upload to cloud.',
21
+ recommendedAction: 'Keep this window open while the first upload finishes. If it seems stalled, press Sync.'
22
+ };
23
+ }
24
+ if (phase === 'attach-cloud') {
25
+ return {
26
+ status: 'syncing',
27
+ summary: busy
28
+ ? 'Pulling the cloud workspace into this device.'
29
+ : 'Waiting for the first cloud pull into this device.',
30
+ recommendedAction: 'Keep this window open for the first cloud pull. If it does not move, press Repair.'
31
+ };
32
+ }
33
+ if (retryAt) {
34
+ return {
35
+ status: 'attention',
36
+ summary: 'Sync hit a temporary problem and will retry automatically.',
37
+ recommendedAction: 'Wait for the automatic retry, or press Sync to retry now.'
38
+ };
39
+ }
40
+ if (lastErrorMessage || phase === 'error') {
41
+ return {
42
+ status: 'attention',
43
+ summary: 'Sync needs attention before it can continue.',
44
+ recommendedAction: 'Press Sync to retry. If the same error keeps returning, press Repair.'
45
+ };
46
+ }
47
+ if (busy) {
48
+ return {
49
+ status: 'syncing',
50
+ summary: 'Sync is currently running.',
51
+ recommendedAction: 'No action needed.'
52
+ };
53
+ }
54
+ return {
55
+ status: 'healthy',
56
+ summary: 'Sync is healthy.',
57
+ recommendedAction: 'No action needed.'
58
+ };
59
+ }
60
+ export function shouldScheduleWorkspaceReactivePush(args) {
61
+ return canRunLocalWorkspaceSyncLifecycle(args)
62
+ && args.workspaceSyncPhase !== 'attach-cloud'
63
+ && args.workspaceSyncReferenceSnapshotsReady;
64
+ }
65
+ export function shouldStartWorkspacePushWatchdog(args) {
66
+ return canRunLocalWorkspaceSyncLifecycle(args)
67
+ && args.workspaceSyncPhase === 'active'
68
+ && args.workspaceSyncReferenceSnapshotsReady;
69
+ }
70
+ export function resolveWorkspaceAutomaticPullPolicy(args) {
71
+ if (!canRunLocalWorkspaceSyncLifecycle(args)) {
72
+ return { shouldStart: false, shouldKickOffImmediately: false };
73
+ }
74
+ if (args.workspaceSyncPhase === 'provision-local' || args.workspaceSyncPhase === 'error' || args.retryPending) {
75
+ return { shouldStart: false, shouldKickOffImmediately: false };
76
+ }
77
+ return {
78
+ shouldStart: true,
79
+ shouldKickOffImmediately: args.workspaceSyncPhase === 'attach-cloud' || !args.lastPullAt
80
+ };
81
+ }
82
+ export function shouldStartWorkspacePeriodicFullReconcile(args) {
83
+ return canRunLocalWorkspaceSyncLifecycle(args)
84
+ && args.isAuthenticated
85
+ && args.workspaceSyncPhase === 'active';
86
+ }
87
+ export function shouldRunWorkspaceStartupRepair(args) {
88
+ return canRunLocalWorkspaceSyncLifecycle(args)
89
+ && args.isAuthenticated
90
+ && args.workspaceSyncPhase !== 'provision-local'
91
+ && args.workspaceSyncPhase !== 'attach-cloud'
92
+ && !args.alreadyRan;
93
+ }
@@ -0,0 +1 @@
1
+ export {};