@taskforcehq/taskforce 0.3.304 → 0.3.306
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.
- package/README.md +140 -247
- package/dist/Taskforce.module.css +295 -89
- package/dist/TaskforceCore.js +378 -111
- package/dist/TaskforceCore.test.js +1221 -107
- package/dist/assets/fonts/CourierPrime-Bold.woff2 +0 -0
- package/dist/assets/fonts/CourierPrime-BoldItalic.woff2 +0 -0
- package/dist/assets/fonts/CourierPrime-Italic.woff2 +0 -0
- package/dist/assets/fonts/CourierPrime-Regular.woff2 +0 -0
- package/dist/assets/fonts/Noir_medium.woff2 +0 -0
- package/dist/assets/fonts/Noir_regular.woff2 +0 -0
- package/dist/assets/fonts/RussoOne-Regular.woff2 +0 -0
- package/dist/assets/fonts/SpecialElite-Regular.woff2 +0 -0
- package/dist/compat/workspaceSyncCompat.js +52 -2
- package/dist/compat/workspaceSyncCompat.test.js +38 -1
- package/dist/components/context/ContextAttachmentManager.d.ts +14 -0
- package/dist/components/context/ContextAttachmentManager.js +549 -0
- package/dist/components/features/AgentsModule.d.ts +10 -1
- package/dist/components/features/AgentsModule.js +260 -15
- package/dist/components/features/AgentsModule.test.js +255 -5
- package/dist/components/features/DocumentIndex.d.ts +1 -1
- package/dist/components/features/DocumentIndex.js +1 -1
- package/dist/components/features/DocumentViewer.d.ts +6 -2
- package/dist/components/features/DocumentViewer.js +90 -10
- package/dist/components/features/DocumentWorkspace.d.ts +5 -22
- package/dist/components/features/DocumentWorkspace.js +12 -155
- package/dist/components/features/DocumentWorkspace.test.js +226 -6
- package/dist/components/features/TaskSettings.js +29 -3
- package/dist/components/features/TaskSettings.test.js +42 -1
- package/dist/components/features/documentWorkspaceModel.d.ts +24 -0
- package/dist/components/features/documentWorkspaceModel.js +57 -0
- package/dist/components/features/useDocumentWorkspaceController.d.ts +34 -0
- package/dist/components/features/useDocumentWorkspaceController.js +113 -0
- package/dist/components/task/TaskCard.js +19 -28
- package/dist/components/task/TaskCard.test.js +38 -3
- package/dist/components/task/TaskContextUpload.js +4 -526
- package/dist/components/task/TaskForm.d.ts +8 -8
- package/dist/components/task/TaskForm.js +362 -230
- package/dist/components/task/TaskForm.test.js +558 -381
- package/dist/components/task/TaskKanban.d.ts +2 -1
- package/dist/components/task/TaskKanban.js +96 -14
- package/dist/components/task/TaskKanban.test.js +36 -0
- package/dist/components/ui/EditableAvatarButton.d.ts +18 -0
- package/dist/components/ui/EditableAvatarButton.js +18 -0
- package/dist/components/views/PlanComparisonPage.d.ts +9 -1
- package/dist/components/views/PlanComparisonPage.js +70 -17
- package/dist/components/views/PlanComparisonPage.test.js +289 -41
- package/dist/components/views/PlansPage.js +239 -106
- package/dist/components/views/PlansPage.test.js +593 -42
- package/dist/components/views/StandaloneLayout.js +310 -554
- package/dist/components/views/panels/FilterToolbar.test.js +6 -4
- package/dist/components/views/panels/PlanningDrawer.d.ts +8 -1
- package/dist/components/views/panels/PlanningDrawer.js +18 -11
- package/dist/components/views/panels/PlanningDrawer.test.d.ts +1 -0
- package/dist/components/views/panels/PlanningDrawer.test.js +141 -0
- package/dist/components/views/planningScope.d.ts +20 -0
- package/dist/components/views/planningScope.js +25 -0
- package/dist/components/views/planningScope.test.d.ts +1 -0
- package/dist/components/views/planningScope.test.js +60 -0
- package/dist/components/views/standalone/modals/AccountHubModal.d.ts +27 -14
- package/dist/components/views/standalone/modals/AccountHubModal.js +87 -15
- package/dist/components/views/standalone/modals/AccountHubModal.test.js +42 -2
- package/dist/components/views/standalone/modals/AvatarImageManagerModal.d.ts +20 -0
- package/dist/components/views/standalone/modals/AvatarImageManagerModal.js +127 -0
- package/dist/components/views/standalone/modals/EditProfileModal.d.ts +2 -9
- package/dist/components/views/standalone/modals/EditProfileModal.js +3 -2
- package/dist/components/views/standalone/modals/SyncEnableWarningModal.d.ts +9 -0
- package/dist/components/views/standalone/modals/SyncEnableWarningModal.js +6 -0
- package/dist/components/views/standalone/modals/SyncEnableWarningModal.test.d.ts +1 -0
- package/dist/components/views/standalone/modals/SyncEnableWarningModal.test.js +24 -0
- package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +2 -1
- package/dist/components/views/standalone/modals/SyncStatusModal.js +2 -2
- package/dist/config/envSchema.js +1 -1
- package/dist/core/AiProfileService.d.ts +45 -3
- package/dist/core/AiProfileService.js +774 -63
- package/dist/core/AiProfileService.test.js +22 -2
- package/dist/core/AiProfiles.test.js +761 -2
- package/dist/core/AttachmentLinkService.js +57 -15
- package/dist/core/AuthIdentityService.d.ts +107 -0
- package/dist/core/AuthIdentityService.js +284 -0
- package/dist/core/AuthTokenService.d.ts +4 -0
- package/dist/core/AuthTokenService.js +34 -6
- package/dist/core/AuthTokenService.test.d.ts +1 -0
- package/dist/core/AuthTokenService.test.js +78 -0
- package/dist/core/EntitlementsPolicy.test.js +77 -15
- package/dist/core/GlobalSettingsService.js +115 -6
- package/dist/core/PlanEntitlementService.d.ts +30 -3
- package/dist/core/PlanEntitlementService.js +454 -93
- package/dist/core/PlanFeatureCatalog.test.d.ts +1 -0
- package/dist/core/PlanFeatureCatalog.test.js +84 -0
- package/dist/core/PlanVersionPolicy.test.js +54 -28
- package/dist/core/PlanningEntities.test.js +52 -0
- package/dist/core/SignupMonetizationSettings.test.js +241 -44
- package/dist/core/SyncReconciliationService.js +2 -65
- package/dist/core/SystemAdmin.test.js +244 -88
- package/dist/core/TaskAttachmentsCanonical.test.js +51 -1
- package/dist/core/TaskTaxonomyValidation.test.js +53 -0
- package/dist/core/Taskforce.d.ts +228 -14
- package/dist/core/Taskforce.js +814 -201
- package/dist/core/Taskforce.listTasksSlim.test.d.ts +1 -0
- package/dist/core/Taskforce.listTasksSlim.test.js +91 -0
- package/dist/core/UserProfileAvatarDrafts.test.js +30 -3
- package/dist/core/WorkspaceLifecycleService.js +0 -5
- package/dist/core/WorkspacePermissions.test.js +25 -1
- package/dist/core/WorkspacePlanMode.test.js +128 -27
- package/dist/core/shared.d.ts +3 -1
- package/dist/core/shared.js +16 -1
- package/dist/core/types.d.ts +68 -2
- package/dist/hooks/auth/useTaskforceAuthBootstrap.js +26 -1
- package/dist/hooks/sync/auth.js +3 -1
- package/dist/hooks/sync/bootstrap.js +2 -0
- package/dist/hooks/sync/controlPlane.d.ts +37 -0
- package/dist/hooks/sync/controlPlane.js +78 -0
- package/dist/hooks/sync/controlPlane.test.d.ts +1 -0
- package/dist/hooks/sync/controlPlane.test.js +121 -0
- package/dist/hooks/sync/lifecyclePolicy.d.ts +45 -0
- package/dist/hooks/sync/lifecyclePolicy.js +93 -0
- package/dist/hooks/sync/lifecyclePolicy.test.d.ts +1 -0
- package/dist/hooks/sync/lifecyclePolicy.test.js +124 -0
- package/dist/hooks/sync/orchestratorShared.d.ts +10 -1
- package/dist/hooks/sync/orchestratorShared.js +68 -47
- package/dist/hooks/sync/orchestratorShared.test.js +50 -1
- package/dist/hooks/sync/pullLifecycle.d.ts +31 -0
- package/dist/hooks/sync/pullLifecycle.js +24 -0
- package/dist/hooks/sync/pullLifecycle.test.d.ts +1 -0
- package/dist/hooks/sync/pullLifecycle.test.js +80 -0
- package/dist/hooks/sync/recovery.d.ts +16 -2
- package/dist/hooks/sync/recovery.js +171 -53
- package/dist/hooks/sync/recovery.test.d.ts +1 -0
- package/dist/hooks/sync/recovery.test.js +292 -0
- package/dist/hooks/sync/transfers.d.ts +16 -3
- package/dist/hooks/sync/transfers.js +186 -65
- package/dist/hooks/sync/transfers.test.d.ts +1 -0
- package/dist/hooks/sync/transfers.test.js +396 -0
- package/dist/hooks/sync/useRecentSyncEvents.d.ts +21 -0
- package/dist/hooks/sync/useRecentSyncEvents.js +92 -0
- package/dist/hooks/sync/useRecentSyncEvents.test.d.ts +1 -0
- package/dist/hooks/sync/useRecentSyncEvents.test.js +124 -0
- package/dist/hooks/sync/useSyncStatusActions.d.ts +30 -0
- package/dist/hooks/sync/useSyncStatusActions.js +88 -0
- package/dist/hooks/sync/useSyncStatusActions.test.d.ts +1 -0
- package/dist/hooks/sync/useSyncStatusActions.test.js +133 -0
- package/dist/hooks/sync/useSyncStatusControls.d.ts +25 -0
- package/dist/hooks/sync/useSyncStatusControls.js +60 -0
- package/dist/hooks/sync/useSyncStatusControls.test.d.ts +1 -0
- package/dist/hooks/sync/useSyncStatusControls.test.js +88 -0
- package/dist/hooks/useSyncOrchestrator.aiProfiles.test.js +12 -0
- package/dist/hooks/useSyncOrchestrator.d.ts +16 -6
- package/dist/hooks/useSyncOrchestrator.js +424 -175
- package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +487 -10
- package/dist/hooks/useTaskData.js +8 -3
- package/dist/hooks/useTaskData.test.js +45 -0
- package/dist/hooks/useTaskMutations.d.ts +2 -1
- package/dist/hooks/useTaskMutations.js +12 -1
- package/dist/hooks/useTaskMutations.test.js +30 -1
- package/dist/hooks/useTaskforce.d.ts +65 -4
- package/dist/hooks/useTaskforce.js +564 -243
- package/dist/hooks/useTaskforce.runtime-routing.test.d.ts +1 -0
- package/dist/hooks/useTaskforce.runtime-routing.test.js +152 -0
- package/dist/hooks/useTaskforce.sync-behavior.test.js +2454 -208
- package/dist/hooks/useWorkspaceSyncController.d.ts +4 -1
- package/dist/hooks/useWorkspaceSyncController.js +17 -2
- package/dist/hooks/useWorkspaceSyncController.test.js +1 -0
- package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.d.ts +16 -0
- package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +316 -35
- package/dist/localization/locales/en-US.d.ts +0 -1
- package/dist/localization/locales/en-US.js +0 -1
- package/dist/localization/locales/es-419.js +0 -1
- package/dist/localization/locales/pt-BR.js +0 -1
- package/dist/mcp/adminWorkspaceRegistrar.d.ts +2 -0
- package/dist/mcp/adminWorkspaceRegistrar.js +154 -0
- package/dist/mcp/collaborationRegistrar.d.ts +2 -0
- package/dist/mcp/collaborationRegistrar.js +71 -0
- package/dist/mcp/documentAssetRegistrar.d.ts +2 -0
- package/dist/mcp/documentAssetRegistrar.js +346 -0
- package/dist/mcp/runtime.d.ts +2 -0
- package/dist/mcp/runtime.js +2433 -3534
- package/dist/mcp/runtime.test.js +440 -2
- package/dist/mcp/taskPlanningRegistrar.d.ts +2 -0
- package/dist/mcp/taskPlanningRegistrar.js +418 -0
- package/dist/mcp/toolCatalog.d.ts +35 -0
- package/dist/mcp/toolCatalog.js +3 -0
- package/dist/migrations/taskSchemaMigrations.d.ts +1 -1
- package/dist/migrations/taskSchemaMigrations.js +171 -61
- package/dist/migrations/taskSchemaMigrations.test.js +15 -0
- package/dist/resources/templates/workflow-sources/workflowDocs.mjs +6 -6
- package/dist/resources/templates/workflows/collaborate.yaml +1 -1
- package/dist/resources/templates/workflows/evaluate.yaml +2 -2
- package/dist/resources/templates/workflows/plan.yaml +1 -1
- package/dist/resources/templates/workflows/review.yaml +2 -2
- package/dist/server/annotatedAttachmentsRoutes.test.js +3 -3
- package/dist/server/auth/providers/apple.d.ts +33 -0
- package/dist/server/auth/providers/apple.js +82 -0
- package/dist/server/auth/providers/appleClientSecret.d.ts +37 -0
- package/dist/server/auth/providers/appleClientSecret.js +65 -0
- package/dist/server/auth/providers/github.d.ts +26 -0
- package/dist/server/auth/providers/github.js +86 -0
- package/dist/server/auth/providers/google.d.ts +21 -0
- package/dist/server/auth/providers/google.js +56 -0
- package/dist/server/auth/providers/types.d.ts +21 -0
- package/dist/server/auth/providers/types.js +1 -0
- package/dist/server/auth.d.ts +2 -0
- package/dist/server/auth.js +6 -3
- package/dist/server/documentReviewRoutes.test.js +36 -3
- package/dist/server/index.cookieProxy.test.js +1 -0
- package/dist/server/index.d.ts +12 -0
- package/dist/server/index.js +120 -9
- package/dist/server/index.rateLimit.test.js +3 -0
- package/dist/server/index.test.js +106 -3
- package/dist/server/routes/admin.d.ts +4 -5
- package/dist/server/routes/admin.js +410 -80
- package/dist/server/routes/annotatedAttachments.d.ts +1 -1
- package/dist/server/routes/annotatedAttachments.js +1 -1
- package/dist/server/routes/auth.d.ts +16 -6
- package/dist/server/routes/auth.js +1015 -118
- package/dist/server/routes/authSupport.d.ts +30 -0
- package/dist/server/routes/authSupport.js +81 -0
- package/dist/server/routes/billing.d.ts +1 -1
- package/dist/server/routes/billing.js +276 -34
- package/dist/server/routes/billing.test.js +760 -52
- package/dist/server/routes/documentReviews.d.ts +1 -1
- package/dist/server/routes/documentReviews.js +1 -1
- package/dist/server/routes/documents.d.ts +5 -2
- package/dist/server/routes/documents.js +242 -74
- package/dist/server/routes/primitives.d.ts +11 -0
- package/dist/server/routes/primitives.js +73 -0
- package/dist/server/routes/resources.d.ts +1 -1
- package/dist/server/routes/resources.js +1 -1
- package/dist/server/routes/shared.d.ts +29 -3
- package/dist/server/routes/shared.js +69 -4
- package/dist/server/routes/sync.d.ts +1 -1
- package/dist/server/routes/sync.integration.test.js +437 -39
- package/dist/server/routes/sync.js +62 -606
- package/dist/server/routes/syncAuxRoutes.d.ts +15 -0
- package/dist/server/routes/syncAuxRoutes.js +91 -0
- package/dist/server/routes/syncAuxRoutes.test.d.ts +1 -0
- package/dist/server/routes/syncAuxRoutes.test.js +158 -0
- package/dist/server/routes/syncPullApplyRoutes.d.ts +36 -0
- package/dist/server/routes/syncPullApplyRoutes.js +204 -0
- package/dist/server/routes/syncPushRoutes.d.ts +24 -0
- package/dist/server/routes/syncPushRoutes.js +212 -0
- package/dist/server/routes/syncRouteGuards.d.ts +36 -0
- package/dist/server/routes/syncRouteGuards.js +67 -0
- package/dist/server/routes/syncRouteGuards.test.d.ts +1 -0
- package/dist/server/routes/syncRouteGuards.test.js +94 -0
- package/dist/server/routes/syncRouteTypes.d.ts +13 -0
- package/dist/server/routes/syncRouteTypes.js +1 -0
- package/dist/server/routes/syncSnapshotRoutes.d.ts +66 -0
- package/dist/server/routes/syncSnapshotRoutes.js +180 -0
- package/dist/server/routes/tasks.d.ts +1 -1
- package/dist/server/routes/tasks.js +44 -2
- package/dist/server/routes/workspaces.d.ts +1 -1
- package/dist/server/routes/workspaces.js +37 -6
- package/dist/server/routes.d.ts +2 -9
- package/dist/server/routes.js +136 -165
- package/dist/server/routes.test.js +2457 -162
- package/dist/services/workflowExportSnapshots.test.js +2 -0
- package/dist/shared/aiProfileSeatScope.d.ts +5 -0
- package/dist/shared/aiProfileSeatScope.js +21 -0
- package/dist/shared/passwordPolicy.d.ts +13 -0
- package/dist/shared/passwordPolicy.js +84 -0
- package/dist/shared/passwordPolicy.test.d.ts +1 -0
- package/dist/shared/passwordPolicy.test.js +34 -0
- package/dist/storage/workspaceAssetStore.d.ts +15 -3
- package/dist/storage/workspaceAssetStore.js +132 -44
- package/dist/storage/workspaceAssetStore.test.js +93 -6
- package/dist/styles/fonts.css +70 -0
- package/dist/sync/collaborationSyncPayload.d.ts +6 -1
- package/dist/sync/collaborationSyncPayload.js +17 -11
- package/dist/sync/collaborationSyncPayload.test.js +13 -1
- package/dist/sync/contentSyncState.d.ts +4 -8
- package/dist/sync/contentSyncState.js +33 -77
- package/dist/sync/syncApplyHandlers.d.ts +7 -0
- package/dist/sync/syncApplyHandlers.js +28 -13
- package/dist/sync/syncApplyHandlers.test.js +72 -3
- package/dist/sync/syncFieldSemantics.d.ts +12 -0
- package/dist/sync/syncFieldSemantics.js +55 -0
- package/dist/sync/syncResourceAdapters.d.ts +44 -0
- package/dist/sync/syncResourceAdapters.js +77 -0
- package/dist/sync/syncService.d.ts +6 -0
- package/dist/sync/syncService.js +60 -0
- package/dist/sync/syncService.test.js +71 -3
- package/dist/sync/taskSyncChangeKey.d.ts +2 -0
- package/dist/sync/taskSyncChangeKey.js +143 -0
- package/dist/sync/taskSyncPayload.js +3 -8
- package/dist/sync/workspacePullFeed.js +4 -3
- package/dist/sync/workspacePullFeed.test.js +43 -0
- package/dist/sync/workspaceRepair.js +5 -2
- package/dist/sync/workspaceSyncModel.d.ts +48 -0
- package/dist/sync/workspaceSyncModel.js +195 -31
- package/dist/sync/workspaceSyncModel.test.js +325 -12
- package/dist/sync/workspaceSyncState.d.ts +19 -0
- package/dist/sync/workspaceSyncState.js +3 -1
- package/dist/sync/workspaceSyncSurface.js +3 -8
- package/dist/types.d.ts +17 -0
- package/dist/ui/assets/AgentsModule-DrLawwNl.js +1 -0
- package/dist/ui/assets/{AnnotatedAttachmentWorkspace-BlS-cqnl.js → AnnotatedAttachmentWorkspace-Z9_whf7F.js} +1 -1
- package/dist/ui/assets/CourierPrime-Bold-BuLj_dpw.woff2 +0 -0
- package/dist/ui/assets/CourierPrime-BoldItalic-BrK2pUkZ.woff2 +0 -0
- package/dist/ui/assets/CourierPrime-Italic-DFUZK5Ey.woff2 +0 -0
- package/dist/ui/assets/CourierPrime-Regular-BsKphzVf.woff2 +0 -0
- package/dist/ui/assets/DocumentWorkspace-B03MaSkw.js +252 -0
- package/dist/ui/assets/DocumentWorkspace-Dhdso07p.css +1 -0
- package/dist/ui/assets/{InitiativesModule-BjR6iBf9.js → InitiativesModule-9E6ParrY.js} +1 -1
- package/dist/ui/assets/Noir_medium-bxQwKGzB.woff2 +0 -0
- package/dist/ui/assets/Noir_regular-ojf2kxlG.woff2 +0 -0
- package/dist/ui/assets/PlansPage-CvfnMiWq.css +1 -0
- package/dist/ui/assets/PlansPage-DRXscYxH.js +1 -0
- package/dist/ui/assets/RussoOne-Regular-Cu_qq_qC.woff2 +0 -0
- package/dist/ui/assets/SpecialElite-Regular-Di6gSvAS.woff2 +0 -0
- package/dist/ui/assets/TaskSettings-DZX4jk7e.js +9 -0
- package/dist/ui/assets/{WorkflowsModule-DnFqdUME.js → WorkflowsModule-BA7jcEpH.js} +1 -1
- package/dist/ui/assets/index-9eT8e0Lu.css +1 -0
- package/dist/ui/assets/index-C6k75jr8.js +6 -0
- package/dist/ui/assets/{vendor-icons-I7ZwG1z_.js → vendor-icons-DuEd_65c.js} +1 -1
- package/dist/ui/fonts/CourierPrime-Bold.ttf +0 -0
- package/dist/ui/fonts/CourierPrime-Bold.woff2 +0 -0
- package/dist/ui/fonts/CourierPrime-BoldItalic.ttf +0 -0
- package/dist/ui/fonts/CourierPrime-BoldItalic.woff2 +0 -0
- package/dist/ui/fonts/CourierPrime-Italic.ttf +0 -0
- package/dist/ui/fonts/CourierPrime-Italic.woff2 +0 -0
- package/dist/ui/fonts/CourierPrime-Regular.ttf +0 -0
- package/dist/ui/fonts/CourierPrime-Regular.woff2 +0 -0
- package/dist/ui/fonts/Noir_medium.otf +0 -0
- package/dist/ui/fonts/Noir_medium.woff2 +0 -0
- package/dist/ui/fonts/Noir_regular.otf +0 -0
- package/dist/ui/fonts/Noir_regular.woff2 +0 -0
- package/dist/ui/fonts/RussoOne-Regular.woff2 +0 -0
- package/dist/ui/fonts/SpecialElite-Regular.ttf +0 -0
- package/dist/ui/fonts/SpecialElite-Regular.woff2 +0 -0
- package/dist/ui/index.html +3 -3
- package/dist/utils/accountProfileSummaryCache.d.ts +5 -0
- package/dist/utils/assignees.d.ts +2 -0
- package/dist/utils/assignees.js +2 -0
- package/dist/utils/avatarUpload.d.ts +27 -0
- package/dist/utils/avatarUpload.js +132 -0
- package/dist/utils/avatarUpload.test.d.ts +1 -0
- package/dist/utils/avatarUpload.test.js +40 -0
- package/dist/utils/bootstrapTrace.d.ts +7 -0
- package/dist/utils/bootstrapTrace.js +29 -0
- package/dist/utils/commercialLifecyclePresentation.d.ts +19 -0
- package/dist/utils/commercialLifecyclePresentation.js +199 -0
- package/dist/utils/contextAssetEvents.d.ts +2 -0
- package/dist/utils/syncEventDetails.d.ts +3 -0
- package/dist/utils/syncEventDetails.js +64 -0
- package/dist/utils/syncEventDetails.test.d.ts +1 -0
- package/dist/utils/syncEventDetails.test.js +23 -0
- package/dist/utils/syncEventPresentation.d.ts +15 -0
- package/dist/utils/syncEventPresentation.js +129 -0
- package/dist/utils/syncEventPresentation.test.d.ts +1 -0
- package/dist/utils/syncEventPresentation.test.js +64 -0
- package/dist/utils/syncStatusPresentation.d.ts +72 -0
- package/dist/utils/syncStatusPresentation.js +217 -0
- package/dist/utils/syncStatusPresentation.test.d.ts +1 -0
- package/dist/utils/syncStatusPresentation.test.js +164 -0
- package/dist/utils/taskActivity.d.ts +2 -0
- package/dist/utils/taskActivity.js +228 -22
- package/dist/utils/taskActivity.test.js +119 -8
- package/dist/utils/workspaceSyncPresentation.d.ts +4 -0
- package/dist/utils/workspaceSyncPresentation.js +68 -2
- package/dist/utils/workspaceSyncPresentation.test.js +36 -1
- package/package.json +10 -2
- package/scripts/check-cloud-mcp.mjs +83 -0
- package/scripts/export-sqlite-to-postgres.mjs +7 -9
- package/scripts/playwright-auth.sh +5 -1
- package/scripts/run-billing-performance-smoke.sh +24 -0
- package/scripts/run-e2e-realtime.sh +17 -3
- package/scripts/run-smoke.sh +17 -5
- package/scripts/run-soak.sh +17 -5
- package/src/resources/templates/workflow-sources/workflowDocs.mjs +6 -6
- package/src/resources/templates/workflows/collaborate.yaml +1 -1
- package/src/resources/templates/workflows/evaluate.yaml +2 -2
- package/src/resources/templates/workflows/plan.yaml +1 -1
- package/src/resources/templates/workflows/review.yaml +2 -2
- package/dist/ui/assets/AgentsModule-BLWVbuKP.js +0 -1
- package/dist/ui/assets/DocumentWorkspace-BH_6DF6x.js +0 -250
- package/dist/ui/assets/DocumentWorkspace-C_8T8oz-.css +0 -1
- package/dist/ui/assets/PlansPage-C2dd2n1X.css +0 -1
- package/dist/ui/assets/PlansPage-CSDQ4sLa.js +0 -1
- package/dist/ui/assets/RussoOne-Regular-C3BxZIj7.ttf +0 -0
- package/dist/ui/assets/TaskSettings-CEDy34Jo.js +0 -9
- package/dist/ui/assets/index-DXUdtH1B.js +0 -6
- package/dist/ui/assets/index-Ii0B0rTO.css +0 -1
- package/scripts/migrate-planning-model.ts +0 -233
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
@font-face {
|
|
2
|
+
font-family: "Russo One";
|
|
3
|
+
src: url("../assets/fonts/RussoOne-Regular.woff2") format("woff2");
|
|
4
|
+
font-weight: 400;
|
|
5
|
+
font-style: normal;
|
|
6
|
+
font-display: swap;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
@font-face {
|
|
10
|
+
font-family: "Courier Prime";
|
|
11
|
+
src: url("../assets/fonts/CourierPrime-Regular.woff2") format("woff2");
|
|
12
|
+
font-weight: 400;
|
|
13
|
+
font-style: normal;
|
|
14
|
+
font-display: swap;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@font-face {
|
|
18
|
+
font-family: "Courier Prime";
|
|
19
|
+
src: url("../assets/fonts/CourierPrime-Italic.woff2") format("woff2");
|
|
20
|
+
font-weight: 400;
|
|
21
|
+
font-style: italic;
|
|
22
|
+
font-display: swap;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@font-face {
|
|
26
|
+
font-family: "Courier Prime";
|
|
27
|
+
src: url("../assets/fonts/CourierPrime-Bold.woff2") format("woff2");
|
|
28
|
+
font-weight: 700;
|
|
29
|
+
font-style: normal;
|
|
30
|
+
font-display: swap;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@font-face {
|
|
34
|
+
font-family: "Courier Prime";
|
|
35
|
+
src: url("../assets/fonts/CourierPrime-BoldItalic.woff2") format("woff2");
|
|
36
|
+
font-weight: 700;
|
|
37
|
+
font-style: italic;
|
|
38
|
+
font-display: swap;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@font-face {
|
|
42
|
+
font-family: "Special Elite";
|
|
43
|
+
src: url("../assets/fonts/SpecialElite-Regular.woff2") format("woff2");
|
|
44
|
+
font-weight: 400;
|
|
45
|
+
font-style: normal;
|
|
46
|
+
font-display: swap;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@font-face {
|
|
50
|
+
font-family: "Noir";
|
|
51
|
+
src: url("../assets/fonts/Noir_regular.woff2") format("woff2");
|
|
52
|
+
font-weight: 400;
|
|
53
|
+
font-style: normal;
|
|
54
|
+
font-display: swap;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@font-face {
|
|
58
|
+
font-family: "Noir";
|
|
59
|
+
src: url("../assets/fonts/Noir_medium.woff2") format("woff2");
|
|
60
|
+
font-weight: 500;
|
|
61
|
+
font-style: normal;
|
|
62
|
+
font-display: swap;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
:root {
|
|
66
|
+
--font-brand: "Russo One", sans-serif;
|
|
67
|
+
--font-typewriter: "Courier Prime", "Courier New", Courier, monospace;
|
|
68
|
+
--font-stamped: "Special Elite", "Courier Prime", "Courier New", Courier, monospace;
|
|
69
|
+
--font-noir: "Noir", var(--font-sans, ui-sans-serif, system-ui, sans-serif);
|
|
70
|
+
}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import type { WorkspaceSyncAiProfileSnapshot, WorkspaceSyncAnnotatedAttachmentSessionSnapshot, WorkspaceSyncDocumentReviewCommentSnapshot, WorkspaceSyncDocumentReviewSessionSnapshot } from './workspaceSyncModel.js';
|
|
2
2
|
import type { AiProfileSurfaceType } from '../shared/aiProfileSurfaceType.js';
|
|
3
|
+
import type { AiProfileSeatScope } from '../shared/aiProfileSeatScope.js';
|
|
3
4
|
export declare function normalizeAiProfileSyncPayload(raw: unknown, workspaceId: string, normalizeSurfaceType: (value: unknown, context: {
|
|
4
5
|
source: string;
|
|
5
6
|
profileId?: string;
|
|
6
7
|
workspaceId?: string;
|
|
7
|
-
}) => AiProfileSurfaceType | null,
|
|
8
|
+
}) => AiProfileSurfaceType | null, normalizeSeatScope: (value: unknown, context: {
|
|
9
|
+
source: string;
|
|
10
|
+
profileId?: string;
|
|
11
|
+
workspaceId?: string;
|
|
12
|
+
}) => AiProfileSeatScope | null, source: string): WorkspaceSyncAiProfileSnapshot | null;
|
|
8
13
|
export declare function normalizeDocumentReviewSessionSyncPayload(raw: unknown, sourceWatermark?: string): WorkspaceSyncDocumentReviewSessionSnapshot | null;
|
|
9
14
|
export declare function normalizeDocumentReviewCommentSyncPayload(raw: unknown, options?: {
|
|
10
15
|
sessionId?: string;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
+
import { hasOwnSyncField, normalizeSyncNullableString, normalizeSyncOptionalString, readSyncNullableIdField, readSyncNullableIsoStringField, readSyncNullableStringField, readSyncSameOriginAssetUrlField, } from './syncFieldSemantics.js';
|
|
1
2
|
function toOptionalTrimmedString(value) {
|
|
2
|
-
|
|
3
|
-
return undefined;
|
|
4
|
-
const normalized = value.trim();
|
|
5
|
-
return normalized.length > 0 ? normalized : undefined;
|
|
3
|
+
return normalizeSyncOptionalString(value);
|
|
6
4
|
}
|
|
7
5
|
function toNullableTrimmedString(value) {
|
|
8
|
-
return
|
|
6
|
+
return normalizeSyncNullableString(value);
|
|
9
7
|
}
|
|
10
8
|
function toOptionalPositiveInteger(value) {
|
|
11
9
|
if (value === undefined || value === null || value === '')
|
|
@@ -23,7 +21,7 @@ function toOptionalNonNegativeInteger(value) {
|
|
|
23
21
|
return 0;
|
|
24
22
|
return Math.max(0, Math.floor(normalized));
|
|
25
23
|
}
|
|
26
|
-
export function normalizeAiProfileSyncPayload(raw, workspaceId, normalizeSurfaceType, source) {
|
|
24
|
+
export function normalizeAiProfileSyncPayload(raw, workspaceId, normalizeSurfaceType, normalizeSeatScope, source) {
|
|
27
25
|
if (!raw || typeof raw !== 'object' || Array.isArray(raw))
|
|
28
26
|
return null;
|
|
29
27
|
const profile = raw;
|
|
@@ -39,17 +37,25 @@ export function normalizeAiProfileSyncPayload(raw, workspaceId, normalizeSurface
|
|
|
39
37
|
username: String(profile.username || '').trim(),
|
|
40
38
|
icon: String(profile.icon || 'Bot').trim() || 'Bot',
|
|
41
39
|
color: String(profile.color || '#8b5cf6').trim() || '#8b5cf6',
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
...(hasOwnSyncField(profile, 'avatarUrl') ? { avatarUrl: readSyncSameOriginAssetUrlField(profile, 'avatarUrl') ?? null } : {}),
|
|
41
|
+
...(hasOwnSyncField(profile, 'avatarSourceUrl') ? { avatarSourceUrl: readSyncSameOriginAssetUrlField(profile, 'avatarSourceUrl') ?? null } : {}),
|
|
42
|
+
description: readSyncNullableStringField(profile, 'description') ?? null,
|
|
43
|
+
role: readSyncNullableStringField(profile, 'role') ?? null,
|
|
44
|
+
provider: readSyncNullableStringField(profile, 'provider') ?? null,
|
|
45
|
+
model: readSyncNullableStringField(profile, 'model') ?? null,
|
|
46
46
|
surfaceType: normalizeSurfaceType(profile.surfaceType, { source, profileId, workspaceId: profileWorkspaceId }),
|
|
47
|
+
seatScope: normalizeSeatScope(profile.seatScope, { source, profileId, workspaceId: profileWorkspaceId }),
|
|
47
48
|
providerMetadata: profile.providerMetadata && typeof profile.providerMetadata === 'object' && !Array.isArray(profile.providerMetadata)
|
|
48
49
|
? profile.providerMetadata
|
|
49
50
|
: null,
|
|
51
|
+
archivedAt: readSyncNullableIsoStringField(profile, 'archivedAt') ?? null,
|
|
52
|
+
archivedBy: readSyncNullableIdField(profile, 'archivedBy') ?? null,
|
|
53
|
+
archivedReason: readSyncNullableStringField(profile, 'archivedReason') ?? null,
|
|
54
|
+
mergedIntoProfileId: readSyncNullableIdField(profile, 'mergedIntoProfileId') ?? null,
|
|
55
|
+
rosterStateUpdatedAt: readSyncNullableIsoStringField(profile, 'rosterStateUpdatedAt') ?? null,
|
|
50
56
|
createdAt: String(profile.createdAt || '').trim(),
|
|
51
57
|
updatedAt: String(profile.updatedAt || profile.createdAt || '').trim(),
|
|
52
|
-
lastActiveAt: toNullableTrimmedString(profile.lastActiveAt),
|
|
58
|
+
lastActiveAt: readSyncNullableIsoStringField(profile, 'lastActiveAt') ?? toNullableTrimmedString(profile.lastActiveAt),
|
|
53
59
|
};
|
|
54
60
|
}
|
|
55
61
|
export function normalizeDocumentReviewSessionSyncPayload(raw, sourceWatermark) {
|
|
@@ -6,6 +6,11 @@ describe('collaborationSyncPayload', () => {
|
|
|
6
6
|
return null;
|
|
7
7
|
return String(value).trim();
|
|
8
8
|
};
|
|
9
|
+
const normalizeSeatScope = (value) => {
|
|
10
|
+
if (value === undefined || value === null || value === '')
|
|
11
|
+
return null;
|
|
12
|
+
return String(value).trim();
|
|
13
|
+
};
|
|
9
14
|
it('normalizes ai profile sync payloads with workspace and surface type', () => {
|
|
10
15
|
const profile = normalizeAiProfileSyncPayload({
|
|
11
16
|
id: 'profile-1',
|
|
@@ -20,11 +25,12 @@ describe('collaborationSyncPayload', () => {
|
|
|
20
25
|
provider: ' OpenAI ',
|
|
21
26
|
model: ' gpt-5.4 ',
|
|
22
27
|
surfaceType: 'agent',
|
|
28
|
+
seatScope: 'cloud_metered',
|
|
23
29
|
providerMetadata: { foo: 'bar' },
|
|
24
30
|
createdAt: '2026-04-10T10:00:00.000Z',
|
|
25
31
|
updatedAt: '2026-04-10T11:00:00.000Z',
|
|
26
32
|
lastActiveAt: '2026-04-10T12:00:00.000Z',
|
|
27
|
-
}, 'workspace-a', normalizeSurfaceType, 'test.ai');
|
|
33
|
+
}, 'workspace-a', normalizeSurfaceType, normalizeSeatScope, 'test.ai');
|
|
28
34
|
expect(profile).toEqual({
|
|
29
35
|
id: 'profile-1',
|
|
30
36
|
workspaceId: 'workspace-a',
|
|
@@ -38,7 +44,13 @@ describe('collaborationSyncPayload', () => {
|
|
|
38
44
|
provider: 'OpenAI',
|
|
39
45
|
model: 'gpt-5.4',
|
|
40
46
|
surfaceType: 'agent',
|
|
47
|
+
seatScope: 'cloud_metered',
|
|
41
48
|
providerMetadata: { foo: 'bar' },
|
|
49
|
+
archivedAt: null,
|
|
50
|
+
archivedBy: null,
|
|
51
|
+
archivedReason: null,
|
|
52
|
+
mergedIntoProfileId: null,
|
|
53
|
+
rosterStateUpdatedAt: null,
|
|
42
54
|
createdAt: '2026-04-10T10:00:00.000Z',
|
|
43
55
|
updatedAt: '2026-04-10T11:00:00.000Z',
|
|
44
56
|
lastActiveAt: '2026-04-10T12:00:00.000Z',
|
|
@@ -28,12 +28,8 @@ export declare function resolveCanonicalAssetSyncLinkState(deps: ContentSyncStat
|
|
|
28
28
|
effectiveUpdatedAt: string;
|
|
29
29
|
};
|
|
30
30
|
export declare function getCanonicalSyncDocumentMetadata(deps: ContentSyncStateDeps, relativePath: string, workspaceId: string): Omit<DocumentSyncPayload, 'path' | 'updatedAt' | 'content'>;
|
|
31
|
-
export declare function hasDocumentSyncMetadataDrift(deps: ContentSyncStateDeps, workspaceId: string, doc: DocumentSyncPayload
|
|
32
|
-
|
|
33
|
-
}): boolean;
|
|
34
|
-
export declare function hasBinaryAssetSyncMetadataDrift(deps: ContentSyncStateDeps, workspaceId: string, asset: BinaryAssetSyncPayload, options?: {
|
|
35
|
-
allowReferenceNumberReassignment?: boolean;
|
|
36
|
-
}): boolean;
|
|
31
|
+
export declare function hasDocumentSyncMetadataDrift(deps: ContentSyncStateDeps, workspaceId: string, doc: DocumentSyncPayload): boolean;
|
|
32
|
+
export declare function hasBinaryAssetSyncMetadataDrift(deps: ContentSyncStateDeps, workspaceId: string, asset: BinaryAssetSyncPayload): boolean;
|
|
37
33
|
export declare function reconcileWorkspaceSyncLinks(deps: ContentSyncStateDeps, input: {
|
|
38
34
|
workspaceId: string;
|
|
39
35
|
assetId: string;
|
|
@@ -64,10 +60,10 @@ export declare function createContentSyncState(deps: ContentSyncStateDeps): {
|
|
|
64
60
|
effectiveUpdatedAt: string;
|
|
65
61
|
};
|
|
66
62
|
getCanonicalSyncDocumentMetadata: (relativePath: string, workspaceId: string) => Omit<DocumentSyncPayload, "path" | "updatedAt" | "content">;
|
|
67
|
-
hasDocumentSyncMetadataDrift: (workspaceId: string, doc: DocumentSyncPayload,
|
|
63
|
+
hasDocumentSyncMetadataDrift: (workspaceId: string, doc: DocumentSyncPayload, _options?: {
|
|
68
64
|
allowReferenceNumberReassignment?: boolean;
|
|
69
65
|
}) => boolean;
|
|
70
|
-
hasBinaryAssetSyncMetadataDrift: (workspaceId: string, asset: BinaryAssetSyncPayload,
|
|
66
|
+
hasBinaryAssetSyncMetadataDrift: (workspaceId: string, asset: BinaryAssetSyncPayload, _options?: {
|
|
71
67
|
allowReferenceNumberReassignment?: boolean;
|
|
72
68
|
}) => boolean;
|
|
73
69
|
reconcileWorkspaceSyncLinks: (input: {
|
|
@@ -38,7 +38,7 @@ export function getCanonicalSyncDocumentMetadata(deps, relativePath, workspaceId
|
|
|
38
38
|
linkRole: primaryLink?.role === 'reference' ? 'reference' : 'attachment'
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
|
-
export function hasDocumentSyncMetadataDrift(deps, workspaceId, doc
|
|
41
|
+
export function hasDocumentSyncMetadataDrift(deps, workspaceId, doc) {
|
|
42
42
|
if (!deps.workspaceAssetStore)
|
|
43
43
|
return false;
|
|
44
44
|
const existingAsset = deps.workspaceAssetStore.getByStorageKey(doc.path, workspaceId);
|
|
@@ -67,20 +67,10 @@ export function hasDocumentSyncMetadataDrift(deps, workspaceId, doc, options) {
|
|
|
67
67
|
? doc.taskId.trim()
|
|
68
68
|
: null;
|
|
69
69
|
const normalizedIncomingLinkRole = doc.linkRole === 'reference' ? 'reference' : 'attachment';
|
|
70
|
-
const allowReferenceNumberReassignment = options?.allowReferenceNumberReassignment === true;
|
|
71
70
|
const referenceNumberMismatch = Boolean(existingAsset.referenceNumber
|
|
72
71
|
&& normalizedIncomingReference
|
|
73
72
|
&& existingAsset.referenceNumber !== normalizedIncomingReference);
|
|
74
|
-
|
|
75
|
-
deps.recordSyncDiagnostic(workspaceId, 'apply', 'Detected document reference number mismatch during normal sync.', {
|
|
76
|
-
source: 'documents.referenceNumber.mismatch',
|
|
77
|
-
path: doc.path,
|
|
78
|
-
assetId: existingAsset.assetId,
|
|
79
|
-
existingReferenceNumber: existingAsset.referenceNumber,
|
|
80
|
-
incomingReferenceNumber: normalizedIncomingReference
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
return (allowReferenceNumberReassignment && existingAsset.referenceNumber !== normalizedIncomingReference)
|
|
73
|
+
return referenceNumberMismatch
|
|
84
74
|
|| existingAsset.version !== normalizedIncomingVersion
|
|
85
75
|
|| (existingAsset.documentId || null) !== normalizedIncomingDocumentId
|
|
86
76
|
|| (existingAsset.logicalName || null) !== normalizedIncomingLogicalName
|
|
@@ -89,7 +79,7 @@ export function hasDocumentSyncMetadataDrift(deps, workspaceId, doc, options) {
|
|
|
89
79
|
|| (primaryLink?.displayName || null) !== normalizedIncomingCaption
|
|
90
80
|
|| ((primaryLink?.role === 'reference' ? 'reference' : 'attachment')) !== normalizedIncomingLinkRole;
|
|
91
81
|
}
|
|
92
|
-
export function hasBinaryAssetSyncMetadataDrift(deps, workspaceId, asset
|
|
82
|
+
export function hasBinaryAssetSyncMetadataDrift(deps, workspaceId, asset) {
|
|
93
83
|
if (!deps.workspaceAssetStore)
|
|
94
84
|
return false;
|
|
95
85
|
const existingAsset = deps.workspaceAssetStore.getByStorageKey(asset.path, workspaceId);
|
|
@@ -116,20 +106,10 @@ export function hasBinaryAssetSyncMetadataDrift(deps, workspaceId, asset, option
|
|
|
116
106
|
: asset.kind === 'image'
|
|
117
107
|
? 'image'
|
|
118
108
|
: 'attachment';
|
|
119
|
-
const allowReferenceNumberReassignment = options?.allowReferenceNumberReassignment === true;
|
|
120
109
|
const referenceNumberMismatch = Boolean(existingAsset.referenceNumber
|
|
121
110
|
&& normalizedIncomingReference
|
|
122
111
|
&& existingAsset.referenceNumber !== normalizedIncomingReference);
|
|
123
|
-
|
|
124
|
-
deps.recordSyncDiagnostic(workspaceId, 'apply', 'Detected asset reference number mismatch during normal sync.', {
|
|
125
|
-
source: 'assets.referenceNumber.mismatch',
|
|
126
|
-
path: asset.path,
|
|
127
|
-
assetId: existingAsset.assetId,
|
|
128
|
-
existingReferenceNumber: existingAsset.referenceNumber,
|
|
129
|
-
incomingReferenceNumber: normalizedIncomingReference
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
return (allowReferenceNumberReassignment && existingAsset.referenceNumber !== normalizedIncomingReference)
|
|
112
|
+
return referenceNumberMismatch
|
|
133
113
|
|| (existingAsset.logicalName || null) !== normalizedIncomingLogicalName
|
|
134
114
|
|| (existingAsset.originalFilename || null) !== normalizedIncomingFilename
|
|
135
115
|
|| (primaryLink?.taskId || null) !== normalizedIncomingTaskId
|
|
@@ -175,7 +155,8 @@ export function reconcileWorkspaceSyncLinks(deps, input) {
|
|
|
175
155
|
deps.workspaceAssetStore.deleteLink({
|
|
176
156
|
workspaceId,
|
|
177
157
|
assetId,
|
|
178
|
-
|
|
158
|
+
targetType: link.targetType,
|
|
159
|
+
targetId: link.targetId,
|
|
179
160
|
role: link.role
|
|
180
161
|
});
|
|
181
162
|
}
|
|
@@ -205,26 +186,9 @@ export async function listWorkspaceSyncDocumentsSnapshot(deps, basePath, workspa
|
|
|
205
186
|
const root = path.resolve(basePath);
|
|
206
187
|
const objectStorageClient = deps.getObjectStorageClient();
|
|
207
188
|
const candidatePaths = new Set();
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
return;
|
|
212
|
-
const entries = fs.readdirSync(directory, { withFileTypes: true });
|
|
213
|
-
for (const entry of entries) {
|
|
214
|
-
const absolutePath = path.join(directory, entry.name);
|
|
215
|
-
if (entry.isDirectory()) {
|
|
216
|
-
collectMarkdownPaths(absolutePath);
|
|
217
|
-
continue;
|
|
218
|
-
}
|
|
219
|
-
if (!entry.isFile())
|
|
220
|
-
continue;
|
|
221
|
-
const relativeFromRoot = path.relative(root, absolutePath).replace(/\\/g, '/');
|
|
222
|
-
const normalized = deps.normalizeWorkspaceSyncDocumentPath(relativeFromRoot);
|
|
223
|
-
if (normalized)
|
|
224
|
-
candidatePaths.add(normalized);
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
collectMarkdownPaths(docsRoot);
|
|
189
|
+
// Shared document sync is canonical-document-only. Raw .taskforce/docs files
|
|
190
|
+
// are intentionally excluded because they are not workspace-scoped and must
|
|
191
|
+
// not re-enter cross-runtime shared document sync.
|
|
228
192
|
if (deps.workspaceAssetStore) {
|
|
229
193
|
const canonicalAssets = deps.workspaceAssetStore.listAllByWorkspace(workspaceId, {
|
|
230
194
|
includeDeleted: false,
|
|
@@ -345,28 +309,9 @@ export async function listWorkspaceSyncDocumentsSnapshot(deps, basePath, workspa
|
|
|
345
309
|
return docs;
|
|
346
310
|
}
|
|
347
311
|
export async function listWorkspaceSyncDocumentIndex(deps, basePath, workspaceId = 'default') {
|
|
348
|
-
const root = path.resolve(basePath);
|
|
349
312
|
const candidatePaths = new Set();
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
if (!fs.existsSync(directory))
|
|
353
|
-
return;
|
|
354
|
-
const entries = fs.readdirSync(directory, { withFileTypes: true });
|
|
355
|
-
for (const entry of entries) {
|
|
356
|
-
const absolutePath = path.join(directory, entry.name);
|
|
357
|
-
if (entry.isDirectory()) {
|
|
358
|
-
collectMarkdownPaths(absolutePath);
|
|
359
|
-
continue;
|
|
360
|
-
}
|
|
361
|
-
if (!entry.isFile())
|
|
362
|
-
continue;
|
|
363
|
-
const relativeFromRoot = path.relative(root, absolutePath).replace(/\\/g, '/');
|
|
364
|
-
const normalized = deps.normalizeWorkspaceSyncDocumentPath(relativeFromRoot);
|
|
365
|
-
if (normalized)
|
|
366
|
-
candidatePaths.add(normalized);
|
|
367
|
-
}
|
|
368
|
-
};
|
|
369
|
-
collectMarkdownPaths(docsRoot);
|
|
313
|
+
// Keep the document index aligned with the snapshot invariant above: only
|
|
314
|
+
// canonical workspace document assets may participate in shared document sync.
|
|
370
315
|
if (deps.workspaceAssetStore) {
|
|
371
316
|
const canonicalAssets = deps.workspaceAssetStore.listAllByWorkspace(workspaceId, {
|
|
372
317
|
includeDeleted: false,
|
|
@@ -533,15 +478,25 @@ export async function loadWorkspaceSyncDocumentPayload(deps, basePath, workspace
|
|
|
533
478
|
const absolutePath = path.resolve(path.join(root, normalizedPath));
|
|
534
479
|
if (absolutePath !== root && !absolutePath.startsWith(`${root}${path.sep}`))
|
|
535
480
|
return null;
|
|
481
|
+
const objectStorageClient = deps.getObjectStorageClient();
|
|
482
|
+
const canonicalAsset = deps.workspaceAssetStore?.getByStorageKey(normalizedPath, workspaceId);
|
|
536
483
|
let content = '';
|
|
537
484
|
let stat = null;
|
|
538
485
|
try {
|
|
539
|
-
if (
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
486
|
+
if (canonicalAsset?.kind === 'document' && canonicalAsset.storageProvider === 'r2' && objectStorageClient) {
|
|
487
|
+
const object = await objectStorageClient.getObject(normalizedPath);
|
|
488
|
+
if (!object?.body)
|
|
489
|
+
return null;
|
|
490
|
+
content = object.body.toString('utf8');
|
|
491
|
+
}
|
|
492
|
+
else {
|
|
493
|
+
if (!fs.existsSync(absolutePath))
|
|
494
|
+
return null;
|
|
495
|
+
stat = fs.statSync(absolutePath);
|
|
496
|
+
if (!stat.isFile())
|
|
497
|
+
return null;
|
|
498
|
+
content = fs.readFileSync(absolutePath, 'utf8');
|
|
499
|
+
}
|
|
545
500
|
}
|
|
546
501
|
catch (error) {
|
|
547
502
|
deps.recordSyncDiagnostic(workspaceId, 'pull', 'Failed to load targeted sync document payload.', {
|
|
@@ -558,7 +513,6 @@ export async function loadWorkspaceSyncDocumentPayload(deps, basePath, workspace
|
|
|
558
513
|
return next;
|
|
559
514
|
})();
|
|
560
515
|
const cached = workspaceCache.get(normalizedPath);
|
|
561
|
-
const canonicalAsset = deps.workspaceAssetStore?.getByStorageKey(normalizedPath, workspaceId);
|
|
562
516
|
let updatedAt = '';
|
|
563
517
|
if (canonicalAsset?.kind === 'document') {
|
|
564
518
|
updatedAt = resolveCanonicalAssetSyncLinkState(deps, canonicalAsset, workspaceId).effectiveUpdatedAt;
|
|
@@ -917,7 +871,8 @@ export function deleteWorkspaceSyncBinaryAsset(deps, basePath, assetPath, worksp
|
|
|
917
871
|
deps.workspaceAssetStore.deleteLink({
|
|
918
872
|
workspaceId,
|
|
919
873
|
assetId: existing.assetId,
|
|
920
|
-
|
|
874
|
+
targetType: link.targetType,
|
|
875
|
+
targetId: link.targetId,
|
|
921
876
|
role: link.role
|
|
922
877
|
});
|
|
923
878
|
}
|
|
@@ -967,7 +922,8 @@ export function deleteWorkspaceSyncDocument(deps, basePath, docPath, workspaceId
|
|
|
967
922
|
deps.workspaceAssetStore.deleteLink({
|
|
968
923
|
workspaceId,
|
|
969
924
|
assetId: existing.assetId,
|
|
970
|
-
|
|
925
|
+
targetType: link.targetType,
|
|
926
|
+
targetId: link.targetId,
|
|
971
927
|
role: link.role
|
|
972
928
|
});
|
|
973
929
|
}
|
|
@@ -987,8 +943,8 @@ export function createContentSyncState(deps) {
|
|
|
987
943
|
return {
|
|
988
944
|
resolveCanonicalAssetSyncLinkState: (asset, workspaceId) => resolveCanonicalAssetSyncLinkState(deps, asset, workspaceId),
|
|
989
945
|
getCanonicalSyncDocumentMetadata: (relativePath, workspaceId) => getCanonicalSyncDocumentMetadata(deps, relativePath, workspaceId),
|
|
990
|
-
hasDocumentSyncMetadataDrift: (workspaceId, doc,
|
|
991
|
-
hasBinaryAssetSyncMetadataDrift: (workspaceId, asset,
|
|
946
|
+
hasDocumentSyncMetadataDrift: (workspaceId, doc, _options) => hasDocumentSyncMetadataDrift(deps, workspaceId, doc),
|
|
947
|
+
hasBinaryAssetSyncMetadataDrift: (workspaceId, asset, _options) => hasBinaryAssetSyncMetadataDrift(deps, workspaceId, asset),
|
|
992
948
|
reconcileWorkspaceSyncLinks: (input) => reconcileWorkspaceSyncLinks(deps, input),
|
|
993
949
|
listWorkspaceSyncDocumentDeletesSnapshot: (workspaceId = 'default') => listWorkspaceSyncDocumentDeletesSnapshot(deps, workspaceId),
|
|
994
950
|
listWorkspaceSyncDocumentIndex: (basePath, workspaceId = 'default') => listWorkspaceSyncDocumentIndex(deps, basePath, workspaceId),
|
|
@@ -2,6 +2,7 @@ import type { TaskforceCore, TaskforceSyncCapable } from '../core/Taskforce.js';
|
|
|
2
2
|
import type { WorkspaceSyncAiProfileSnapshot, WorkspaceSyncAnnotatedAttachmentSessionSnapshot, WorkspaceSyncChange, WorkspaceSyncDocumentReviewCommentSnapshot, WorkspaceSyncDocumentReviewSessionSnapshot, WorkspaceSyncInitiativeSnapshot, WorkspaceSyncTaskEventSnapshot, WorkspaceSyncTaskSnapshot, WorkspaceSyncWorkspaceMemberSnapshot, WorkspaceSyncWorkstreamSnapshot } from './workspaceSyncModel.js';
|
|
3
3
|
import type { BinaryAssetSyncPayload, DocumentSyncPayload } from './contentSyncPayload.js';
|
|
4
4
|
import type { AiProfileSurfaceType } from '../shared/aiProfileSurfaceType.js';
|
|
5
|
+
import type { AiProfileSeatScope } from '../shared/aiProfileSeatScope.js';
|
|
5
6
|
type SyncCore = TaskforceCore & TaskforceSyncCapable;
|
|
6
7
|
type SyncRouteError = Error & {
|
|
7
8
|
code?: string;
|
|
@@ -18,6 +19,11 @@ type NormalizeIncomingAiProfileSurfaceType = (value: unknown, context: {
|
|
|
18
19
|
profileId?: string;
|
|
19
20
|
workspaceId?: string;
|
|
20
21
|
}) => AiProfileSurfaceType | null;
|
|
22
|
+
type NormalizeIncomingAiProfileSeatScope = (value: unknown, context: {
|
|
23
|
+
source: string;
|
|
24
|
+
profileId?: string;
|
|
25
|
+
workspaceId?: string;
|
|
26
|
+
}) => AiProfileSeatScope | null;
|
|
21
27
|
type NormalizeTaskEventSyncPayload = (raw: unknown, workspaceId: string, sourceWatermark?: string) => WorkspaceSyncTaskEventSnapshot | null;
|
|
22
28
|
export interface WorkspaceSyncIncomingTaskMutation {
|
|
23
29
|
archived: boolean;
|
|
@@ -68,6 +74,7 @@ export declare function classifyWorkspaceSyncChanges(input: {
|
|
|
68
74
|
normalizeWorkspaceSyncDocumentPath: (rawPath: unknown) => string | null;
|
|
69
75
|
normalizeTaskAssetPath: (rawPath: unknown) => string | null;
|
|
70
76
|
normalizeIncomingAiProfileSurfaceType: NormalizeIncomingAiProfileSurfaceType;
|
|
77
|
+
normalizeIncomingAiProfileSeatScope: NormalizeIncomingAiProfileSeatScope;
|
|
71
78
|
normalizeTaskEventSyncPayload: NormalizeTaskEventSyncPayload;
|
|
72
79
|
recordSyncDiagnostic: RecordSyncDiagnostic;
|
|
73
80
|
}): WorkspaceSyncIncomingApplyModel;
|
|
@@ -83,7 +83,7 @@ function recordTaskReferenceNumberMismatch(input) {
|
|
|
83
83
|
return true;
|
|
84
84
|
}
|
|
85
85
|
export function classifyWorkspaceSyncChanges(input) {
|
|
86
|
-
const { workspaceId, incomingChanges, normalizeWorkspaceSyncDocumentPath, normalizeTaskAssetPath, normalizeIncomingAiProfileSurfaceType, normalizeTaskEventSyncPayload, recordSyncDiagnostic, } = input;
|
|
86
|
+
const { workspaceId, incomingChanges, normalizeWorkspaceSyncDocumentPath, normalizeTaskAssetPath, normalizeIncomingAiProfileSurfaceType, normalizeIncomingAiProfileSeatScope, normalizeTaskEventSyncPayload, recordSyncDiagnostic, } = input;
|
|
87
87
|
const model = createIncomingApplyModel();
|
|
88
88
|
for (const change of incomingChanges) {
|
|
89
89
|
const raw = change;
|
|
@@ -111,7 +111,7 @@ export function classifyWorkspaceSyncChanges(input) {
|
|
|
111
111
|
continue;
|
|
112
112
|
}
|
|
113
113
|
if (op === 'ai-profile-upsert') {
|
|
114
|
-
const profile = normalizeAiProfileSyncPayload(raw.profile, workspaceId, normalizeIncomingAiProfileSurfaceType, 'apply.aiProfileUpsert');
|
|
114
|
+
const profile = normalizeAiProfileSyncPayload(raw.profile, workspaceId, normalizeIncomingAiProfileSurfaceType, normalizeIncomingAiProfileSeatScope, 'apply.aiProfileUpsert');
|
|
115
115
|
const profileId = String(profile?.id || '').trim();
|
|
116
116
|
if (profileId && profile) {
|
|
117
117
|
const profileWorkspaceId = String(profile.workspaceId || '').trim();
|
|
@@ -382,12 +382,20 @@ export function applyAiProfileAndMemberSyncChanges(input) {
|
|
|
382
382
|
username: profile.username,
|
|
383
383
|
icon: profile.icon,
|
|
384
384
|
color: profile.color,
|
|
385
|
+
...(Object.prototype.hasOwnProperty.call(profile, 'avatarUrl') ? { avatarUrl: profile.avatarUrl ?? null } : {}),
|
|
386
|
+
...(Object.prototype.hasOwnProperty.call(profile, 'avatarSourceUrl') ? { avatarSourceUrl: profile.avatarSourceUrl ?? null } : {}),
|
|
385
387
|
description: profile.description ?? null,
|
|
386
388
|
role: profile.role ?? null,
|
|
387
389
|
provider: profile.provider ?? null,
|
|
388
390
|
model: profile.model ?? null,
|
|
389
391
|
surfaceType: profile.surfaceType,
|
|
392
|
+
seatScope: profile.seatScope ?? null,
|
|
390
393
|
providerMetadata: profile.providerMetadata,
|
|
394
|
+
archivedAt: profile.archivedAt ?? null,
|
|
395
|
+
archivedBy: profile.archivedBy ?? null,
|
|
396
|
+
archivedReason: profile.archivedReason ?? null,
|
|
397
|
+
mergedIntoProfileId: profile.mergedIntoProfileId ?? null,
|
|
398
|
+
rosterStateUpdatedAt: profile.rosterStateUpdatedAt ?? null,
|
|
391
399
|
createdAt: profile.createdAt,
|
|
392
400
|
updatedAt: profile.updatedAt,
|
|
393
401
|
lastActiveAt: profile.lastActiveAt
|
|
@@ -434,14 +442,18 @@ export async function applyContentSyncChanges(input) {
|
|
|
434
442
|
for (const doc of incomingDocuments) {
|
|
435
443
|
try {
|
|
436
444
|
const existingDoc = core.getDocumentWatermark(workspaceId, doc.path);
|
|
437
|
-
const existingDocFallback =
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
? createHash('sha256').update(fs.readFileSync(localDocumentPath, 'utf8')).digest('hex')
|
|
441
|
-
: '';
|
|
445
|
+
const existingDocFallback = (!existingDoc && getExistingDocument)
|
|
446
|
+
? getExistingDocument(doc.path, workspaceId)
|
|
447
|
+
: null;
|
|
442
448
|
const incomingHash = createHash('sha256').update(String(doc.content || '')).digest('hex');
|
|
443
449
|
const existingUpdatedAt = String(existingDoc?.updatedAt || existingDocFallback?.updatedAt || '').trim();
|
|
444
|
-
|
|
450
|
+
let existingHash = String(existingDoc?.contentHash || existingDocFallback?.contentHash || '').trim();
|
|
451
|
+
if (!existingHash && !hasObjectStorageClient()) {
|
|
452
|
+
const localDocumentPath = path.resolve(basePath, doc.path);
|
|
453
|
+
if (fs.existsSync(localDocumentPath)) {
|
|
454
|
+
existingHash = createHash('sha256').update(fs.readFileSync(localDocumentPath, 'utf8')).digest('hex');
|
|
455
|
+
}
|
|
456
|
+
}
|
|
445
457
|
const compare = resolveSyncConflictOrdering(doc.updatedAt, existingUpdatedAt, incomingHash, existingHash);
|
|
446
458
|
const metadataDrift = hasDocumentSyncMetadataDrift(workspaceId, doc, options);
|
|
447
459
|
if (compare < 0)
|
|
@@ -450,7 +462,9 @@ export async function applyContentSyncChanges(input) {
|
|
|
450
462
|
continue;
|
|
451
463
|
await writeWorkspaceSyncDocument(basePath, doc, workspaceId, {
|
|
452
464
|
...options,
|
|
453
|
-
allowReferenceNumberReassignment: options?.allowReferenceNumberReassignment === true
|
|
465
|
+
allowReferenceNumberReassignment: options?.allowReferenceNumberReassignment === true
|
|
466
|
+
|| existingHash !== incomingHash
|
|
467
|
+
|| metadataDrift
|
|
454
468
|
});
|
|
455
469
|
}
|
|
456
470
|
catch (error) {
|
|
@@ -481,11 +495,11 @@ export async function applyContentSyncChanges(input) {
|
|
|
481
495
|
const existing = getExistingBinaryAsset(asset.path, workspaceId);
|
|
482
496
|
const incomingHash = createHash('sha256').update(Buffer.from(String(asset.contentBase64 || ''), 'base64')).digest('hex');
|
|
483
497
|
const localFileMissing = !hasObjectStorageClient() && !fs.existsSync(localAssetPath);
|
|
484
|
-
const localAssetHash = !hasObjectStorageClient() && !localFileMissing
|
|
485
|
-
? createHash('sha256').update(fs.readFileSync(localAssetPath)).digest('hex')
|
|
486
|
-
: '';
|
|
487
498
|
const existingUpdatedAt = String(existing?.updatedAt || '').trim();
|
|
488
|
-
|
|
499
|
+
let existingHash = String(existing?.contentSha256 || '').trim();
|
|
500
|
+
if (!existingHash && !hasObjectStorageClient() && !localFileMissing) {
|
|
501
|
+
existingHash = createHash('sha256').update(fs.readFileSync(localAssetPath)).digest('hex');
|
|
502
|
+
}
|
|
489
503
|
const compare = resolveSyncConflictOrdering(asset.updatedAt, existingUpdatedAt, incomingHash, existingHash);
|
|
490
504
|
const metadataDrift = hasBinaryAssetSyncMetadataDrift(workspaceId, asset, options);
|
|
491
505
|
if (compare < 0)
|
|
@@ -497,6 +511,7 @@ export async function applyContentSyncChanges(input) {
|
|
|
497
511
|
allowReferenceNumberReassignment: options?.allowReferenceNumberReassignment === true
|
|
498
512
|
|| existingHash !== incomingHash
|
|
499
513
|
|| localFileMissing
|
|
514
|
+
|| metadataDrift
|
|
500
515
|
});
|
|
501
516
|
}
|
|
502
517
|
catch (error) {
|