@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.
- package/README.md +0 -2
- package/dist/Taskforce.module.css +603 -107
- package/dist/TaskforceCore.js +216 -43
- package/dist/TaskforceCore.test.js +611 -28
- 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 +46 -2
- package/dist/compat/workspaceSyncCompat.test.js +38 -1
- package/dist/components/activity/EntityActivityTimeline.d.ts +34 -0
- package/dist/components/activity/EntityActivityTimeline.js +81 -0
- package/dist/components/context/ContextAttachmentManager.d.ts +14 -0
- package/dist/components/context/ContextAttachmentManager.js +561 -0
- package/dist/components/features/AgentsModule.d.ts +14 -1
- package/dist/components/features/AgentsModule.js +366 -18
- package/dist/components/features/AgentsModule.test.js +507 -8
- package/dist/components/features/AnnotatedAttachmentWorkspace.d.ts +3 -1
- package/dist/components/features/AnnotatedAttachmentWorkspace.js +118 -4
- package/dist/components/features/AnnotatedAttachmentWorkspace.test.js +52 -0
- package/dist/components/features/DocumentIndex.d.ts +2 -2
- package/dist/components/features/DocumentIndex.js +3 -4
- package/dist/components/features/DocumentViewer.d.ts +7 -1
- package/dist/components/features/DocumentViewer.js +62 -4
- package/dist/components/features/DocumentWorkspace.d.ts +10 -2
- package/dist/components/features/DocumentWorkspace.js +15 -4
- package/dist/components/features/DocumentWorkspace.test.js +51 -1
- package/dist/components/features/TaskSettings.d.ts +2 -0
- package/dist/components/features/TaskSettings.js +83 -78
- package/dist/components/features/TaskSettings.test.js +171 -82
- package/dist/components/features/documentWorkspaceModel.d.ts +1 -1
- package/dist/components/task/TaskActionHeader.js +11 -5
- package/dist/components/task/TaskActionHeader.test.js +10 -0
- package/dist/components/task/TaskCard.js +24 -29
- package/dist/components/task/TaskCard.test.js +38 -3
- package/dist/components/task/TaskContextUpload.js +4 -526
- package/dist/components/task/TaskContextUpload.test.js +3 -3
- package/dist/components/task/TaskForm.js +61 -116
- package/dist/components/task/TaskForm.test.js +110 -8
- package/dist/components/task/TaskKanban.d.ts +2 -1
- package/dist/components/task/TaskKanban.js +94 -21
- package/dist/components/task/TaskKanban.test.js +36 -0
- package/dist/components/task/TaskList.js +5 -1
- package/dist/components/task/TaskList.test.js +4 -0
- package/dist/components/ui/EditableAvatarButton.d.ts +18 -0
- package/dist/components/ui/EditableAvatarButton.js +18 -0
- package/dist/components/ui/HierarchyActionBadge.d.ts +10 -0
- package/dist/components/ui/HierarchyActionBadge.js +5 -0
- package/dist/components/views/AppShellHeader.d.ts +3 -1
- package/dist/components/views/AppShellHeader.js +27 -11
- package/dist/components/views/AppShellHeader.test.js +18 -1
- package/dist/components/views/PlanComparisonPage.d.ts +9 -1
- package/dist/components/views/PlanComparisonPage.js +78 -14
- package/dist/components/views/PlanComparisonPage.test.js +257 -0
- package/dist/components/views/PlansPage.js +127 -36
- package/dist/components/views/PlansPage.test.js +294 -12
- package/dist/components/views/StandaloneLayout.js +529 -592
- package/dist/components/views/WidgetView.js +10 -8
- package/dist/components/views/panels/PlanningDrawer.d.ts +25 -5
- package/dist/components/views/panels/PlanningDrawer.js +270 -55
- package/dist/components/views/panels/PlanningDrawer.test.d.ts +1 -0
- package/dist/components/views/panels/PlanningDrawer.test.js +529 -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 +26 -1
- package/dist/components/views/standalone/modals/AccountHubModal.js +76 -2
- package/dist/components/views/standalone/modals/AccountHubModal.test.js +20 -3
- 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 -0
- package/dist/core/AiProfileService.d.ts +46 -2
- package/dist/core/AiProfileService.js +1073 -82
- package/dist/core/AiProfileService.test.js +19 -1
- package/dist/core/AiProfiles.test.js +1249 -44
- package/dist/core/AttachmentLinkService.d.ts +3 -0
- package/dist/core/AttachmentLinkService.js +110 -23
- 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.js +3 -3
- package/dist/core/EntitlementsPolicy.test.js +2 -2
- package/dist/core/GlobalSettingsService.js +127 -6
- package/dist/core/McpTokenService.d.ts +12 -0
- package/dist/core/McpTokenService.js +44 -1
- package/dist/core/PlanEntitlementService.d.ts +23 -2
- package/dist/core/PlanEntitlementService.js +343 -57
- package/dist/core/PlanFeatureCatalog.test.d.ts +1 -0
- package/dist/core/PlanFeatureCatalog.test.js +84 -0
- package/dist/core/PlanVersionPolicy.test.js +35 -2
- package/dist/core/PlanningEntities.test.js +418 -4
- package/dist/core/SignupMonetizationSettings.test.js +199 -27
- package/dist/core/SyncReconciliationService.js +2 -65
- package/dist/core/SystemAdmin.test.js +42 -42
- package/dist/core/TaskActivityService.d.ts +28 -1
- package/dist/core/TaskActivityService.js +227 -46
- package/dist/core/TaskActivitySync.test.d.ts +1 -0
- package/dist/core/TaskActivitySync.test.js +90 -0
- package/dist/core/TaskAttachmentsCanonical.test.js +51 -1
- package/dist/core/TaskAuditTimeline.test.js +96 -0
- package/dist/core/Taskforce.d.ts +415 -40
- package/dist/core/Taskforce.ids.test.js +58 -0
- package/dist/core/Taskforce.js +1543 -266
- package/dist/core/Taskforce.listTasksSlim.test.d.ts +1 -0
- package/dist/core/Taskforce.listTasksSlim.test.js +91 -0
- package/dist/core/Taskforce.mcpAuth.test.js +109 -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 +117 -16
- package/dist/core/shared.d.ts +1 -1
- package/dist/core/shared.js +5 -1
- package/dist/core/types.d.ts +75 -2
- package/dist/hooks/auth/useTaskforceAuthBootstrap.js +28 -2
- package/dist/hooks/bootstrapTimeouts.d.ts +4 -0
- package/dist/hooks/bootstrapTimeouts.js +8 -0
- package/dist/hooks/bootstrapTimeouts.test.d.ts +1 -0
- package/dist/hooks/bootstrapTimeouts.test.js +12 -0
- 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 +13 -4
- package/dist/hooks/sync/orchestratorShared.js +129 -48
- 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 +179 -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 +210 -66
- package/dist/hooks/sync/transfers.test.d.ts +1 -0
- package/dist/hooks/sync/transfers.test.js +928 -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/useFilterSort.js +13 -13
- package/dist/hooks/useFilterSort.test.js +87 -1
- package/dist/hooks/useSyncOrchestrator.aiProfiles.test.js +12 -0
- package/dist/hooks/useSyncOrchestrator.d.ts +9 -2
- package/dist/hooks/useSyncOrchestrator.js +409 -183
- package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +407 -0
- package/dist/hooks/useTaskData.js +8 -3
- package/dist/hooks/useTaskData.test.js +45 -0
- package/dist/hooks/useTaskforce.d.ts +145 -52
- package/dist/hooks/useTaskforce.js +592 -253
- package/dist/hooks/useTaskforce.runtime-routing.test.d.ts +1 -0
- package/dist/hooks/useTaskforce.runtime-routing.test.js +246 -0
- package/dist/hooks/useTaskforce.sync-behavior.test.js +2468 -201
- package/dist/hooks/useWorkspaceSyncController.d.ts +1 -0
- package/dist/hooks/useWorkspaceSyncController.js +13 -2
- package/dist/hooks/useWorkspaceSyncController.test.js +48 -0
- package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.d.ts +16 -0
- package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +328 -40
- 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/canonicalAssetHelpers.d.ts +16 -4
- package/dist/mcp/canonicalAssetHelpers.js +18 -10
- package/dist/mcp/canonicalAssetHelpers.test.d.ts +1 -0
- package/dist/mcp/canonicalAssetHelpers.test.js +67 -0
- package/dist/mcp/clientIntegrations.d.ts +1 -0
- package/dist/mcp/clientIntegrations.js +25 -0
- package/dist/mcp/clientIntegrations.test.js +14 -3
- package/dist/mcp/clientProfileDefaults.js +3 -3
- package/dist/mcp/collaborationRegistrar.js +7 -7
- package/dist/mcp/documentAssetRegistrar.js +116 -10
- package/dist/mcp/runtime.d.ts +3 -0
- package/dist/mcp/runtime.js +1099 -185
- package/dist/mcp/runtime.test.js +1491 -140
- package/dist/mcp/taskAttachmentTypes.d.ts +1 -1
- package/dist/mcp/taskPlanningRegistrar.js +48 -0
- package/dist/mcp/toolRegistry.d.ts +56 -0
- package/dist/mcp/toolRegistry.js +8 -0
- package/dist/mcp/toolRegistry.test.js +4 -0
- package/dist/migrations/taskSchemaMigrations.d.ts +1 -1
- package/dist/migrations/taskSchemaMigrations.js +192 -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/aiProfileAvatarAssets.d.ts +49 -0
- package/dist/server/aiProfileAvatarAssets.js +319 -0
- package/dist/server/aiProfileAvatarAssets.test.d.ts +1 -0
- package/dist/server/aiProfileAvatarAssets.test.js +213 -0
- package/dist/server/annotatedAttachmentsRoutes.test.js +69 -10
- 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 +124 -9
- package/dist/server/index.rateLimit.test.js +3 -0
- package/dist/server/index.test.js +111 -3
- package/dist/server/routes/admin.d.ts +3 -0
- package/dist/server/routes/admin.js +459 -28
- package/dist/server/routes/annotatedAttachments.js +51 -0
- package/dist/server/routes/auth.d.ts +26 -2
- package/dist/server/routes/auth.js +1170 -71
- package/dist/server/routes/authSupport.d.ts +5 -1
- package/dist/server/routes/authSupport.js +13 -2
- package/dist/server/routes/billing.js +372 -35
- package/dist/server/routes/billing.test.js +595 -12
- package/dist/server/routes/documents.d.ts +1 -0
- package/dist/server/routes/documents.js +182 -70
- package/dist/server/routes/shared.d.ts +28 -2
- package/dist/server/routes/shared.js +69 -14
- package/dist/server/routes/sync.integration.test.js +658 -39
- package/dist/server/routes/sync.js +74 -608
- 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 +182 -0
- package/dist/server/routes/tasks.js +55 -10
- package/dist/server/routes/workspaces.js +36 -5
- package/dist/server/routes.js +147 -11
- package/dist/server/routes.test.js +2704 -183
- 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/aiProfileSurfaceType.d.ts +1 -1
- package/dist/shared/aiProfileSurfaceType.js +10 -8
- 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/objectStorage.d.ts +1 -0
- package/dist/storage/objectStorage.js +2 -1
- package/dist/storage/objectStorageClient.d.ts +1 -0
- package/dist/storage/objectStorageClient.js +41 -8
- package/dist/storage/objectStorageClient.test.js +26 -1
- package/dist/storage/objectStorageConfig.js +3 -1
- package/dist/storage/objectStorageConfig.test.js +13 -1
- 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 +19 -11
- package/dist/sync/collaborationSyncPayload.test.js +14 -1
- package/dist/sync/collaborationSyncState.d.ts +3 -3
- package/dist/sync/collaborationSyncState.js +19 -12
- package/dist/sync/contentSyncPayload.d.ts +5 -1
- package/dist/sync/contentSyncPayload.js +9 -0
- package/dist/sync/contentSyncPayload.test.js +39 -0
- package/dist/sync/contentSyncState.d.ts +9 -9
- package/dist/sync/contentSyncState.js +248 -107
- package/dist/sync/planningSyncPayload.js +5 -0
- package/dist/sync/planningSyncPayload.test.js +24 -0
- package/dist/sync/syncApplyHandlers.d.ts +11 -4
- package/dist/sync/syncApplyHandlers.js +115 -42
- package/dist/sync/syncApplyHandlers.test.js +251 -4
- package/dist/sync/syncFieldSemantics.d.ts +12 -0
- package/dist/sync/syncFieldSemantics.js +55 -0
- package/dist/sync/syncResourceAdapters.d.ts +46 -0
- package/dist/sync/syncResourceAdapters.js +79 -0
- package/dist/sync/syncService.d.ts +6 -0
- package/dist/sync/syncService.js +65 -1
- package/dist/sync/syncService.test.js +96 -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.d.ts +4 -0
- package/dist/sync/workspacePullFeed.js +132 -72
- package/dist/sync/workspacePullFeed.test.js +92 -0
- package/dist/sync/workspaceRepair.js +5 -2
- package/dist/sync/workspaceSyncModel.d.ts +73 -6
- package/dist/sync/workspaceSyncModel.js +342 -73
- package/dist/sync/workspaceSyncModel.test.js +559 -14
- package/dist/sync/workspaceSyncState.d.ts +17 -0
- package/dist/sync/workspaceSyncState.js +2 -1
- package/dist/sync/workspaceSyncSurface.js +3 -8
- package/dist/types.d.ts +50 -2
- package/dist/ui/assets/AgentsModule-2y82_3DO.js +1 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-BTLZZCiQ.js +3 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-BVKew-mH.css +1 -0
- package/dist/ui/assets/ContextAttachmentManager-D2epuNnG.js +3 -0
- 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-D4rJKXzd.css +1 -0
- package/dist/ui/assets/DocumentWorkspace-sVa-3Do6.js +252 -0
- package/dist/ui/assets/EntityActivityTimeline-DyqvvhuF.css +1 -0
- package/dist/ui/assets/EntityActivityTimeline-Zods27y_.js +1 -0
- package/dist/ui/assets/{InitiativesModule-Dhm7M8e7.js → InitiativesModule-D4XseTwW.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-D5AcbO0L.js +1 -0
- package/dist/ui/assets/PlansPage-Dvqsz5zc.css +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/TaskContextUpload-uC5qx4Bv.js +1 -0
- package/dist/ui/assets/TaskSettings-CqvPAsTv.js +9 -0
- package/dist/ui/assets/{WorkflowsModule-BcS4afRn.js → WorkflowsModule-oOA9bcdK.js} +4 -4
- package/dist/ui/assets/documentReferences-DPZuTgHh.js +1 -0
- package/dist/ui/assets/index-607WPo_X.js +4 -0
- package/dist/ui/assets/index-CYyodXsg.css +1 -0
- package/dist/ui/assets/{vendor-icons-BSUaRwF8.js → vendor-icons-B32hGuF2.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/ui/product/agent manager.png +0 -0
- package/dist/ui/product/agent_manager_02.png +0 -0
- package/dist/utils/accountProfileSummaryCache.d.ts +5 -0
- package/dist/utils/aiProfileEvents.d.ts +7 -0
- package/dist/utils/aiProfileEvents.js +6 -0
- package/dist/utils/assignees.d.ts +8 -0
- package/dist/utils/assignees.js +10 -1
- package/dist/utils/assignees.test.d.ts +1 -0
- package/dist/utils/assignees.test.js +25 -0
- package/dist/utils/avatarDisplay.d.ts +1 -0
- package/dist/utils/avatarDisplay.js +15 -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.js +3 -0
- package/dist/utils/contextAssetEvents.d.ts +2 -0
- package/dist/utils/contextFiles.d.ts +3 -1
- package/dist/utils/contextFiles.js +2 -1
- 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 +9 -1
- package/dist/utils/taskActivity.js +290 -22
- package/dist/utils/taskActivity.test.js +141 -8
- package/dist/utils/taskSearch.d.ts +22 -0
- package/dist/utils/taskSearch.js +87 -0
- package/dist/utils/taskSearch.test.d.ts +1 -0
- package/dist/utils/taskSearch.test.js +69 -0
- package/dist/utils/taskUtils.js +10 -3
- package/dist/utils/taskUtils.test.d.ts +1 -0
- package/dist/utils/taskUtils.test.js +19 -0
- 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 +3 -2
- package/scripts/export-sqlite-to-postgres.mjs +7 -9
- 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-N2MnQBZk.js +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-BG6P_GVW.js +0 -3
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-BaS2VwIr.css +0 -1
- package/dist/ui/assets/DocumentWorkspace-B3nV_Gc5.css +0 -1
- package/dist/ui/assets/DocumentWorkspace-DRbDMwh8.js +0 -252
- package/dist/ui/assets/PlansPage-C2dd2n1X.css +0 -1
- package/dist/ui/assets/PlansPage-Cq0zXj3I.js +0 -1
- package/dist/ui/assets/RussoOne-Regular-C3BxZIj7.ttf +0 -0
- package/dist/ui/assets/TaskSettings-ln0aF7xc.js +0 -9
- package/dist/ui/assets/index-C2-OXZV7.css +0 -1
- package/dist/ui/assets/index-DcSI5F86.js +0 -6
- package/scripts/migrate-planning-model.ts +0 -233
|
@@ -47,11 +47,15 @@ function mapAssetRow(row) {
|
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
function mapLinkRow(row) {
|
|
50
|
+
const targetType = String(row.target_type || 'task').trim();
|
|
51
|
+
const targetId = String(row.task_id || '').trim();
|
|
50
52
|
return {
|
|
51
53
|
tenantId: String(row.tenant_id || 'default'),
|
|
52
54
|
workspaceId: String(row.workspace_id || 'default'),
|
|
53
55
|
assetId: String(row.asset_id || ''),
|
|
54
|
-
|
|
56
|
+
targetType,
|
|
57
|
+
targetId,
|
|
58
|
+
taskId: targetType === 'task' ? targetId : null,
|
|
55
59
|
role: String(row.role || 'attachment'),
|
|
56
60
|
displayName: row.display_name == null ? null : String(row.display_name),
|
|
57
61
|
sortOrder: row.sort_order == null ? null : Number(row.sort_order),
|
|
@@ -73,10 +77,36 @@ function usesReadableAssetReference(kind) {
|
|
|
73
77
|
export class WorkspaceAssetStore {
|
|
74
78
|
db;
|
|
75
79
|
tenantId;
|
|
80
|
+
supportsTargetTypeCache = null;
|
|
76
81
|
constructor(db, tenantId) {
|
|
77
82
|
this.db = db;
|
|
78
83
|
this.tenantId = tenantId;
|
|
79
84
|
}
|
|
85
|
+
supportsTargetType() {
|
|
86
|
+
if (this.supportsTargetTypeCache !== null)
|
|
87
|
+
return this.supportsTargetTypeCache;
|
|
88
|
+
try {
|
|
89
|
+
if (this.db.provider === 'postgres') {
|
|
90
|
+
const row = this.db.prepare(`
|
|
91
|
+
SELECT 1
|
|
92
|
+
FROM information_schema.columns
|
|
93
|
+
WHERE table_schema = current_schema()
|
|
94
|
+
AND table_name = 'workspace_asset_links'
|
|
95
|
+
AND column_name = 'target_type'
|
|
96
|
+
LIMIT 1
|
|
97
|
+
`).get();
|
|
98
|
+
this.supportsTargetTypeCache = Boolean(row);
|
|
99
|
+
return this.supportsTargetTypeCache;
|
|
100
|
+
}
|
|
101
|
+
const columns = this.db.prepare(`PRAGMA table_info(workspace_asset_links)`).all();
|
|
102
|
+
this.supportsTargetTypeCache = columns.some((column) => String(column.name || '').trim() === 'target_type');
|
|
103
|
+
return this.supportsTargetTypeCache;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
this.supportsTargetTypeCache = false;
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
80
110
|
normalizePersistedAsset(entry) {
|
|
81
111
|
const normalizedKind = normalizeCanonicalAssetKind({
|
|
82
112
|
kind: entry.kind,
|
|
@@ -411,47 +441,93 @@ export class WorkspaceAssetStore {
|
|
|
411
441
|
upsertLink(input) {
|
|
412
442
|
const workspaceId = normalizeWorkspaceId(input.workspaceId);
|
|
413
443
|
const assetId = normalizeId(input.assetId);
|
|
414
|
-
const
|
|
444
|
+
const targetType = normalizeId(input.targetType, input.taskId ? 'task' : 'task');
|
|
445
|
+
const targetId = normalizeId(input.targetId, input.taskId || '');
|
|
415
446
|
const role = normalizeId(input.role, 'attachment');
|
|
416
447
|
const createdAt = normalizeId(input.createdAt, new Date().toISOString());
|
|
417
448
|
const updatedAt = normalizeId(input.updatedAt, createdAt);
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
449
|
+
if (!targetId) {
|
|
450
|
+
throw new Error('Workspace asset links require a targetId.');
|
|
451
|
+
}
|
|
452
|
+
if (this.supportsTargetType()) {
|
|
453
|
+
this.db.prepare(`
|
|
454
|
+
INSERT INTO workspace_asset_links (
|
|
455
|
+
tenant_id,
|
|
456
|
+
workspace_id,
|
|
457
|
+
asset_id,
|
|
458
|
+
target_type,
|
|
459
|
+
task_id,
|
|
460
|
+
role,
|
|
461
|
+
display_name,
|
|
462
|
+
sort_order,
|
|
463
|
+
created_at,
|
|
464
|
+
updated_at,
|
|
465
|
+
deleted_at
|
|
466
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
467
|
+
ON CONFLICT(tenant_id, workspace_id, asset_id, task_id, role) DO UPDATE SET
|
|
468
|
+
target_type = excluded.target_type,
|
|
469
|
+
display_name = excluded.display_name,
|
|
470
|
+
sort_order = excluded.sort_order,
|
|
471
|
+
updated_at = excluded.updated_at,
|
|
472
|
+
deleted_at = excluded.deleted_at
|
|
473
|
+
`).run(this.tenantId, workspaceId, assetId, targetType, targetId, role, normalizeNullable(input.displayName), input.sortOrder == null ? null : Math.floor(Number(input.sortOrder)), createdAt, updatedAt, normalizeNullable(input.deletedAt));
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
this.db.prepare(`
|
|
477
|
+
INSERT INTO workspace_asset_links (
|
|
478
|
+
tenant_id,
|
|
479
|
+
workspace_id,
|
|
480
|
+
asset_id,
|
|
481
|
+
task_id,
|
|
482
|
+
role,
|
|
483
|
+
display_name,
|
|
484
|
+
sort_order,
|
|
485
|
+
created_at,
|
|
486
|
+
updated_at,
|
|
487
|
+
deleted_at
|
|
488
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
489
|
+
ON CONFLICT(tenant_id, workspace_id, asset_id, task_id, role) DO UPDATE SET
|
|
490
|
+
display_name = excluded.display_name,
|
|
491
|
+
sort_order = excluded.sort_order,
|
|
492
|
+
updated_at = excluded.updated_at,
|
|
493
|
+
deleted_at = excluded.deleted_at
|
|
494
|
+
`).run(this.tenantId, workspaceId, assetId, targetId, role, normalizeNullable(input.displayName), input.sortOrder == null ? null : Math.floor(Number(input.sortOrder)), createdAt, updatedAt, normalizeNullable(input.deletedAt));
|
|
495
|
+
}
|
|
437
496
|
return this.listLinksForAsset(assetId, workspaceId, { includeDeleted: true })
|
|
438
|
-
.find((entry) => entry.
|
|
497
|
+
.find((entry) => entry.targetType === targetType && entry.targetId === targetId && entry.role === role);
|
|
439
498
|
}
|
|
440
499
|
listLinksForTask(taskIdRaw, workspaceIdRaw, options) {
|
|
500
|
+
return this.listLinksForTarget('task', taskIdRaw, workspaceIdRaw, options);
|
|
501
|
+
}
|
|
502
|
+
listLinksForTarget(targetTypeRaw, targetIdRaw, workspaceIdRaw, options) {
|
|
441
503
|
const workspaceId = normalizeWorkspaceId(workspaceIdRaw);
|
|
442
|
-
const
|
|
443
|
-
|
|
504
|
+
const targetType = normalizeId(targetTypeRaw, 'task');
|
|
505
|
+
const targetId = normalizeId(targetIdRaw);
|
|
506
|
+
if (!targetId)
|
|
444
507
|
return [];
|
|
445
508
|
const includeDeleted = options?.includeDeleted === true;
|
|
446
|
-
const rows = this.
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
509
|
+
const rows = this.supportsTargetType()
|
|
510
|
+
? this.db.prepare(`
|
|
511
|
+
SELECT *
|
|
512
|
+
FROM workspace_asset_links
|
|
513
|
+
WHERE tenant_id = ?
|
|
514
|
+
AND workspace_id = ?
|
|
515
|
+
AND target_type = ?
|
|
516
|
+
AND task_id = ?
|
|
517
|
+
${includeDeleted ? '' : 'AND deleted_at IS NULL'}
|
|
518
|
+
ORDER BY COALESCE(sort_order, 2147483647) ASC, created_at ASC, asset_id ASC
|
|
519
|
+
`).all(this.tenantId, workspaceId, targetType, targetId)
|
|
520
|
+
: (targetType === 'task'
|
|
521
|
+
? this.db.prepare(`
|
|
522
|
+
SELECT *
|
|
523
|
+
FROM workspace_asset_links
|
|
524
|
+
WHERE tenant_id = ?
|
|
525
|
+
AND workspace_id = ?
|
|
526
|
+
AND task_id = ?
|
|
527
|
+
${includeDeleted ? '' : 'AND deleted_at IS NULL'}
|
|
528
|
+
ORDER BY COALESCE(sort_order, 2147483647) ASC, created_at ASC, asset_id ASC
|
|
529
|
+
`).all(this.tenantId, workspaceId, targetId)
|
|
530
|
+
: []);
|
|
455
531
|
return rows.map(mapLinkRow);
|
|
456
532
|
}
|
|
457
533
|
listLinksForAsset(assetIdRaw, workspaceIdRaw, options) {
|
|
@@ -474,23 +550,35 @@ export class WorkspaceAssetStore {
|
|
|
474
550
|
deleteLink(input) {
|
|
475
551
|
const workspaceId = normalizeWorkspaceId(input.workspaceId);
|
|
476
552
|
const assetId = normalizeId(input.assetId);
|
|
477
|
-
const
|
|
553
|
+
const targetType = normalizeId(input.targetType, input.taskId ? 'task' : 'task');
|
|
554
|
+
const targetId = normalizeId(input.targetId, input.taskId || '');
|
|
478
555
|
const role = normalizeId(input.role);
|
|
479
|
-
if (!assetId || !
|
|
556
|
+
if (!assetId || !targetId || !role)
|
|
480
557
|
return false;
|
|
481
558
|
if (input.hardDelete) {
|
|
482
|
-
const result = this.
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
559
|
+
const result = this.supportsTargetType()
|
|
560
|
+
? this.db.prepare(`
|
|
561
|
+
DELETE FROM workspace_asset_links
|
|
562
|
+
WHERE tenant_id = ? AND workspace_id = ? AND asset_id = ? AND target_type = ? AND task_id = ? AND role = ?
|
|
563
|
+
`).run(this.tenantId, workspaceId, assetId, targetType, targetId, role)
|
|
564
|
+
: this.db.prepare(`
|
|
565
|
+
DELETE FROM workspace_asset_links
|
|
566
|
+
WHERE tenant_id = ? AND workspace_id = ? AND asset_id = ? AND task_id = ? AND role = ?
|
|
567
|
+
`).run(this.tenantId, workspaceId, assetId, targetId, role);
|
|
486
568
|
return Number(result?.changes || 0) > 0;
|
|
487
569
|
}
|
|
488
570
|
const nowIso = new Date().toISOString();
|
|
489
|
-
const result = this.
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
571
|
+
const result = this.supportsTargetType()
|
|
572
|
+
? this.db.prepare(`
|
|
573
|
+
UPDATE workspace_asset_links
|
|
574
|
+
SET deleted_at = ?, updated_at = ?
|
|
575
|
+
WHERE tenant_id = ? AND workspace_id = ? AND asset_id = ? AND target_type = ? AND task_id = ? AND role = ?
|
|
576
|
+
`).run(nowIso, nowIso, this.tenantId, workspaceId, assetId, targetType, targetId, role)
|
|
577
|
+
: this.db.prepare(`
|
|
578
|
+
UPDATE workspace_asset_links
|
|
579
|
+
SET deleted_at = ?, updated_at = ?
|
|
580
|
+
WHERE tenant_id = ? AND workspace_id = ? AND asset_id = ? AND task_id = ? AND role = ?
|
|
581
|
+
`).run(nowIso, nowIso, this.tenantId, workspaceId, assetId, targetId, role);
|
|
494
582
|
return Number(result?.changes || 0) > 0;
|
|
495
583
|
}
|
|
496
584
|
}
|
|
@@ -23,6 +23,40 @@ function makeStore() {
|
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
|
+
function makeLegacyLinkStore() {
|
|
27
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'taskforce-workspace-assets-legacy-'));
|
|
28
|
+
const dbPath = path.join(root, 'taskforce.db');
|
|
29
|
+
const db = createDatabaseAdapter({ sqliteDbPath: dbPath });
|
|
30
|
+
ensureTaskAssetsSchema(db);
|
|
31
|
+
ensureWorkspaceAssetsSchema(db);
|
|
32
|
+
ensureDocumentReferenceSchema(db);
|
|
33
|
+
db.exec(`DROP TABLE IF EXISTS workspace_asset_links`);
|
|
34
|
+
db.exec(`
|
|
35
|
+
CREATE TABLE IF NOT EXISTS workspace_asset_links (
|
|
36
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
37
|
+
workspace_id TEXT NOT NULL,
|
|
38
|
+
asset_id TEXT NOT NULL,
|
|
39
|
+
task_id TEXT NOT NULL,
|
|
40
|
+
role TEXT NOT NULL,
|
|
41
|
+
display_name TEXT,
|
|
42
|
+
sort_order INTEGER,
|
|
43
|
+
created_at TEXT NOT NULL,
|
|
44
|
+
updated_at TEXT NOT NULL,
|
|
45
|
+
deleted_at TEXT,
|
|
46
|
+
PRIMARY KEY (tenant_id, workspace_id, asset_id, task_id, role)
|
|
47
|
+
);
|
|
48
|
+
`);
|
|
49
|
+
const store = new WorkspaceAssetStore(db, 'default');
|
|
50
|
+
return {
|
|
51
|
+
root,
|
|
52
|
+
db,
|
|
53
|
+
store,
|
|
54
|
+
cleanup() {
|
|
55
|
+
db.close();
|
|
56
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
26
60
|
describe('WorkspaceAssetStore', () => {
|
|
27
61
|
const cleanups = [];
|
|
28
62
|
afterEach(() => {
|
|
@@ -64,6 +98,50 @@ describe('WorkspaceAssetStore', () => {
|
|
|
64
98
|
referenceNumber: 1
|
|
65
99
|
});
|
|
66
100
|
});
|
|
101
|
+
it('supports legacy workspace asset links without target_type', () => {
|
|
102
|
+
const ctx = makeLegacyLinkStore();
|
|
103
|
+
cleanups.push(() => ctx.cleanup());
|
|
104
|
+
const now = new Date().toISOString();
|
|
105
|
+
ctx.store.upsertAsset({
|
|
106
|
+
assetId: 'asset-legacy-1',
|
|
107
|
+
workspaceId: 'workspace-1',
|
|
108
|
+
kind: 'file',
|
|
109
|
+
originalFilename: 'legacy.pdf',
|
|
110
|
+
mimeType: 'application/pdf',
|
|
111
|
+
storageProvider: 'local',
|
|
112
|
+
storageKey: 'workspaces/workspace-1/assets/files/asset-legacy-1-legacy.pdf',
|
|
113
|
+
contentSha256: 'sha-legacy',
|
|
114
|
+
sizeBytes: 42,
|
|
115
|
+
createdAt: now,
|
|
116
|
+
updatedAt: now
|
|
117
|
+
});
|
|
118
|
+
const created = ctx.store.upsertLink({
|
|
119
|
+
workspaceId: 'workspace-1',
|
|
120
|
+
assetId: 'asset-legacy-1',
|
|
121
|
+
taskId: 'task-1',
|
|
122
|
+
role: 'attachment',
|
|
123
|
+
displayName: 'Legacy attachment',
|
|
124
|
+
createdAt: now,
|
|
125
|
+
updatedAt: now
|
|
126
|
+
});
|
|
127
|
+
expect(created.targetType).toBe('task');
|
|
128
|
+
expect(created.targetId).toBe('task-1');
|
|
129
|
+
expect(ctx.store.listLinksForTask('task-1', 'workspace-1')).toEqual([
|
|
130
|
+
expect.objectContaining({
|
|
131
|
+
assetId: 'asset-legacy-1',
|
|
132
|
+
targetType: 'task',
|
|
133
|
+
targetId: 'task-1',
|
|
134
|
+
role: 'attachment'
|
|
135
|
+
})
|
|
136
|
+
]);
|
|
137
|
+
expect(ctx.store.deleteLink({
|
|
138
|
+
workspaceId: 'workspace-1',
|
|
139
|
+
assetId: 'asset-legacy-1',
|
|
140
|
+
taskId: 'task-1',
|
|
141
|
+
role: 'attachment'
|
|
142
|
+
})).toBe(true);
|
|
143
|
+
expect(ctx.store.listLinksForTask('task-1', 'workspace-1')).toEqual([]);
|
|
144
|
+
});
|
|
67
145
|
it('assigns sequential document reference numbers per workspace', () => {
|
|
68
146
|
const ctx = makeStore();
|
|
69
147
|
cleanups.push(() => ctx.cleanup());
|
|
@@ -382,7 +460,7 @@ describe('WorkspaceAssetStore', () => {
|
|
|
382
460
|
const all = ctx.store.listByWorkspace('workspace-1', { includeDeleted: true });
|
|
383
461
|
expect(all.map((entry) => entry.assetId).sort()).toEqual(['asset-a', 'asset-b']);
|
|
384
462
|
});
|
|
385
|
-
it('creates, lists, and soft-deletes
|
|
463
|
+
it('creates, lists, and soft-deletes generic target links while preserving task compatibility helpers', () => {
|
|
386
464
|
const ctx = makeStore();
|
|
387
465
|
cleanups.push(() => ctx.cleanup());
|
|
388
466
|
ctx.store.upsertAsset({
|
|
@@ -399,27 +477,36 @@ describe('WorkspaceAssetStore', () => {
|
|
|
399
477
|
ctx.store.upsertLink({
|
|
400
478
|
workspaceId: 'workspace-1',
|
|
401
479
|
assetId: 'asset-link-1',
|
|
402
|
-
|
|
480
|
+
targetType: 'task',
|
|
481
|
+
targetId: 'task-1',
|
|
403
482
|
role: 'attachment',
|
|
404
483
|
sortOrder: 2
|
|
405
484
|
});
|
|
406
485
|
ctx.store.upsertLink({
|
|
407
486
|
workspaceId: 'workspace-1',
|
|
408
487
|
assetId: 'asset-link-1',
|
|
409
|
-
|
|
488
|
+
targetType: 'initiative',
|
|
489
|
+
targetId: 'initiative-2',
|
|
410
490
|
role: 'reference',
|
|
411
491
|
sortOrder: 1
|
|
412
492
|
});
|
|
413
493
|
const taskLinks = ctx.store.listLinksForTask('task-1', 'workspace-1');
|
|
414
494
|
expect(taskLinks).toHaveLength(1);
|
|
415
|
-
expect(taskLinks[0]).toMatchObject({ assetId: 'asset-link-1', role: 'attachment' });
|
|
495
|
+
expect(taskLinks[0]).toMatchObject({ assetId: 'asset-link-1', role: 'attachment', targetType: 'task', targetId: 'task-1', taskId: 'task-1' });
|
|
496
|
+
const initiativeLinks = ctx.store.listLinksForTarget('initiative', 'initiative-2', 'workspace-1');
|
|
497
|
+
expect(initiativeLinks).toHaveLength(1);
|
|
498
|
+
expect(initiativeLinks[0]).toMatchObject({ assetId: 'asset-link-1', role: 'reference', targetType: 'initiative', targetId: 'initiative-2', taskId: null });
|
|
416
499
|
const assetLinks = ctx.store.listLinksForAsset('asset-link-1', 'workspace-1');
|
|
417
500
|
expect(assetLinks).toHaveLength(2);
|
|
418
|
-
expect(assetLinks.map((entry) => entry.
|
|
501
|
+
expect(assetLinks.map((entry) => [entry.targetType, entry.targetId])).toEqual([
|
|
502
|
+
['initiative', 'initiative-2'],
|
|
503
|
+
['task', 'task-1'],
|
|
504
|
+
]);
|
|
419
505
|
expect(ctx.store.deleteLink({
|
|
420
506
|
workspaceId: 'workspace-1',
|
|
421
507
|
assetId: 'asset-link-1',
|
|
422
|
-
|
|
508
|
+
targetType: 'task',
|
|
509
|
+
targetId: 'task-1',
|
|
423
510
|
role: 'attachment'
|
|
424
511
|
})).toBe(true);
|
|
425
512
|
expect(ctx.store.listLinksForTask('task-1', 'workspace-1')).toHaveLength(0);
|
|
@@ -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,27 @@ 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
|
+
...(hasOwnSyncField(profile, 'avatarRevision') ? { avatarRevision: toOptionalNonNegativeInteger(profile.avatarRevision) } : {}),
|
|
43
|
+
avatarUpdatedAt: readSyncNullableIsoStringField(profile, 'avatarUpdatedAt') ?? null,
|
|
44
|
+
description: readSyncNullableStringField(profile, 'description') ?? null,
|
|
45
|
+
role: readSyncNullableStringField(profile, 'role') ?? null,
|
|
46
|
+
provider: readSyncNullableStringField(profile, 'provider') ?? null,
|
|
47
|
+
model: readSyncNullableStringField(profile, 'model') ?? null,
|
|
46
48
|
surfaceType: normalizeSurfaceType(profile.surfaceType, { source, profileId, workspaceId: profileWorkspaceId }),
|
|
49
|
+
seatScope: normalizeSeatScope(profile.seatScope, { source, profileId, workspaceId: profileWorkspaceId }),
|
|
47
50
|
providerMetadata: profile.providerMetadata && typeof profile.providerMetadata === 'object' && !Array.isArray(profile.providerMetadata)
|
|
48
51
|
? profile.providerMetadata
|
|
49
52
|
: null,
|
|
53
|
+
archivedAt: readSyncNullableIsoStringField(profile, 'archivedAt') ?? null,
|
|
54
|
+
archivedBy: readSyncNullableIdField(profile, 'archivedBy') ?? null,
|
|
55
|
+
archivedReason: readSyncNullableStringField(profile, 'archivedReason') ?? null,
|
|
56
|
+
mergedIntoProfileId: readSyncNullableIdField(profile, 'mergedIntoProfileId') ?? null,
|
|
57
|
+
rosterStateUpdatedAt: readSyncNullableIsoStringField(profile, 'rosterStateUpdatedAt') ?? null,
|
|
50
58
|
createdAt: String(profile.createdAt || '').trim(),
|
|
51
59
|
updatedAt: String(profile.updatedAt || profile.createdAt || '').trim(),
|
|
52
|
-
lastActiveAt: toNullableTrimmedString(profile.lastActiveAt),
|
|
60
|
+
lastActiveAt: readSyncNullableIsoStringField(profile, 'lastActiveAt') ?? toNullableTrimmedString(profile.lastActiveAt),
|
|
53
61
|
};
|
|
54
62
|
}
|
|
55
63
|
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',
|
|
@@ -33,12 +39,19 @@ describe('collaborationSyncPayload', () => {
|
|
|
33
39
|
username: 'agent',
|
|
34
40
|
icon: 'Bot',
|
|
35
41
|
color: '#111111',
|
|
42
|
+
avatarUpdatedAt: null,
|
|
36
43
|
description: 'Product coding agent',
|
|
37
44
|
role: 'Implementer',
|
|
38
45
|
provider: 'OpenAI',
|
|
39
46
|
model: 'gpt-5.4',
|
|
40
47
|
surfaceType: 'agent',
|
|
48
|
+
seatScope: 'cloud_metered',
|
|
41
49
|
providerMetadata: { foo: 'bar' },
|
|
50
|
+
archivedAt: null,
|
|
51
|
+
archivedBy: null,
|
|
52
|
+
archivedReason: null,
|
|
53
|
+
mergedIntoProfileId: null,
|
|
54
|
+
rosterStateUpdatedAt: null,
|
|
42
55
|
createdAt: '2026-04-10T10:00:00.000Z',
|
|
43
56
|
updatedAt: '2026-04-10T11:00:00.000Z',
|
|
44
57
|
lastActiveAt: '2026-04-10T12:00:00.000Z',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TaskforceCore, TaskforceSyncCapable } from '../core/Taskforce.js';
|
|
2
|
-
import type { WorkspaceSyncAnnotatedAttachmentSessionSnapshot, WorkspaceSyncDocumentReviewCommentSnapshot, WorkspaceSyncDocumentReviewSessionSnapshot,
|
|
2
|
+
import type { WorkspaceSyncAnnotatedAttachmentSessionSnapshot, WorkspaceSyncDocumentReviewCommentSnapshot, WorkspaceSyncDocumentReviewSessionSnapshot, WorkspaceSyncEntityEventSnapshot } from './workspaceSyncModel.js';
|
|
3
3
|
type SyncCore = TaskforceCore & TaskforceSyncCapable;
|
|
4
4
|
interface CollaborationSyncStateDeps {
|
|
5
5
|
core: SyncCore;
|
|
@@ -7,11 +7,11 @@ interface CollaborationSyncStateDeps {
|
|
|
7
7
|
export declare function listWorkspaceSyncDocumentReviewSessionsSnapshot(deps: CollaborationSyncStateDeps, workspaceId?: string): WorkspaceSyncDocumentReviewSessionSnapshot[];
|
|
8
8
|
export declare function listWorkspaceSyncDocumentReviewCommentsSnapshot(deps: CollaborationSyncStateDeps, workspaceId?: string): WorkspaceSyncDocumentReviewCommentSnapshot[];
|
|
9
9
|
export declare function listWorkspaceSyncAnnotatedAttachmentSessionsSnapshot(deps: CollaborationSyncStateDeps, workspaceId?: string): WorkspaceSyncAnnotatedAttachmentSessionSnapshot[];
|
|
10
|
-
export declare function listWorkspaceSyncTaskEventsSnapshot(deps: CollaborationSyncStateDeps, workspaceId?: string):
|
|
10
|
+
export declare function listWorkspaceSyncTaskEventsSnapshot(deps: CollaborationSyncStateDeps, workspaceId?: string): WorkspaceSyncEntityEventSnapshot[];
|
|
11
11
|
export declare function createCollaborationSyncState(deps: CollaborationSyncStateDeps): {
|
|
12
12
|
listWorkspaceSyncDocumentReviewSessionsSnapshot: (workspaceId?: string) => WorkspaceSyncDocumentReviewSessionSnapshot[];
|
|
13
13
|
listWorkspaceSyncDocumentReviewCommentsSnapshot: (workspaceId?: string) => WorkspaceSyncDocumentReviewCommentSnapshot[];
|
|
14
14
|
listWorkspaceSyncAnnotatedAttachmentSessionsSnapshot: (workspaceId?: string) => WorkspaceSyncAnnotatedAttachmentSessionSnapshot[];
|
|
15
|
-
listWorkspaceSyncTaskEventsSnapshot: (workspaceId?: string) =>
|
|
15
|
+
listWorkspaceSyncTaskEventsSnapshot: (workspaceId?: string) => WorkspaceSyncEntityEventSnapshot[];
|
|
16
16
|
};
|
|
17
17
|
export {};
|
|
@@ -52,19 +52,26 @@ export function listWorkspaceSyncAnnotatedAttachmentSessionsSnapshot(deps, works
|
|
|
52
52
|
&& session.baseImageAssetId.length > 0));
|
|
53
53
|
}
|
|
54
54
|
export function listWorkspaceSyncTaskEventsSnapshot(deps, workspaceId = 'default') {
|
|
55
|
-
return deps.core.
|
|
56
|
-
.map((event) =>
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
55
|
+
return deps.core.listEntityEventsForSync({ workspaceId })
|
|
56
|
+
.map((event) => {
|
|
57
|
+
const entityType = event.entityType === 'initiative' || event.entityType === 'workstream'
|
|
58
|
+
? event.entityType
|
|
59
|
+
: 'task';
|
|
60
|
+
return {
|
|
61
|
+
id: event.id,
|
|
62
|
+
workspaceId: event.workspaceId,
|
|
63
|
+
entityType,
|
|
64
|
+
entityId: String(event.entityId || ('taskId' in event ? event.taskId : '') || '').trim(),
|
|
65
|
+
taskId: entityType === 'task' && 'taskId' in event ? event.taskId : undefined,
|
|
66
|
+
action: event.action,
|
|
67
|
+
actor: event.actor,
|
|
68
|
+
actorType: event.actorType,
|
|
69
|
+
details: event.details,
|
|
70
|
+
createdAt: event.createdAt,
|
|
71
|
+
};
|
|
72
|
+
})
|
|
66
73
|
.filter((event) => (event.id.length > 0
|
|
67
|
-
&& event.
|
|
74
|
+
&& event.entityId.length > 0
|
|
68
75
|
&& event.workspaceId.length > 0
|
|
69
76
|
&& event.action.length > 0
|
|
70
77
|
&& event.createdAt.length > 0));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { WorkspaceAssetLinkRole } from '../storage/workspaceAssetStore.js';
|
|
1
|
+
import type { WorkspaceAssetLinkRole, WorkspaceAssetLinkTargetType } from '../storage/workspaceAssetStore.js';
|
|
2
2
|
export interface DocumentSyncPayload {
|
|
3
3
|
path: string;
|
|
4
4
|
updatedAt: string;
|
|
@@ -8,6 +8,8 @@ export interface DocumentSyncPayload {
|
|
|
8
8
|
referenceNumber?: number | null;
|
|
9
9
|
version?: number | null;
|
|
10
10
|
taskId?: string | null;
|
|
11
|
+
linkTargetType?: WorkspaceAssetLinkTargetType | null;
|
|
12
|
+
linkTargetId?: string | null;
|
|
11
13
|
logicalName?: string | null;
|
|
12
14
|
caption?: string | null;
|
|
13
15
|
originalFilename?: string | null;
|
|
@@ -27,6 +29,8 @@ export interface BinaryAssetSyncPayload {
|
|
|
27
29
|
mimeType: string;
|
|
28
30
|
referenceNumber?: number | null;
|
|
29
31
|
taskId?: string | null;
|
|
32
|
+
linkTargetType?: WorkspaceAssetLinkTargetType | null;
|
|
33
|
+
linkTargetId?: string | null;
|
|
30
34
|
logicalName?: string | null;
|
|
31
35
|
caption?: string | null;
|
|
32
36
|
originalFilename?: string | null;
|