@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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { fireEvent, render, screen } from '@testing-library/react';
|
|
2
|
+
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
|
3
3
|
import userEvent from '@testing-library/user-event';
|
|
4
4
|
import { describe, it, expect, vi } from 'vitest';
|
|
5
5
|
import { TaskSettings } from './TaskSettings';
|
|
@@ -109,8 +109,22 @@ describe('TaskSettings Component', () => {
|
|
|
109
109
|
};
|
|
110
110
|
return render(_jsx(TaskSettings, { ...props }));
|
|
111
111
|
};
|
|
112
|
+
const renderMcpComponent = (overrides = {}) => {
|
|
113
|
+
const { settingsModel: settingsModelOverrides = {}, ...rest } = overrides;
|
|
114
|
+
return renderComponent({
|
|
115
|
+
...rest,
|
|
116
|
+
renderMode: 'mcp-only',
|
|
117
|
+
settingsModel: {
|
|
118
|
+
...settingsModelOverrides,
|
|
119
|
+
initialSection: 'mcp'
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
};
|
|
112
123
|
const openMcpSettings = async (user) => {
|
|
113
|
-
|
|
124
|
+
const mcpButton = screen.queryByRole('button', { name: /^MCP$/i });
|
|
125
|
+
if (mcpButton) {
|
|
126
|
+
await user.click(mcpButton);
|
|
127
|
+
}
|
|
114
128
|
};
|
|
115
129
|
const openCloudMcpSettings = async (user) => {
|
|
116
130
|
await openMcpSettings(user);
|
|
@@ -139,7 +153,7 @@ describe('TaskSettings Component', () => {
|
|
|
139
153
|
expect(screen.queryByRole('button', { name: /workflows/i })).not.toBeInTheDocument();
|
|
140
154
|
expect(screen.queryByRole('button', { name: /agents/i })).not.toBeInTheDocument();
|
|
141
155
|
expect(screen.getByRole('button', { name: /taxonomy/i })).toBeInTheDocument();
|
|
142
|
-
expect(screen.
|
|
156
|
+
expect(screen.queryByRole('button', { name: /^mcp$/i })).not.toBeInTheDocument();
|
|
143
157
|
expect(screen.getByRole('button', { name: /integrations/i })).toBeInTheDocument();
|
|
144
158
|
});
|
|
145
159
|
it('4.1b General tab removes old profile/account chrome', () => {
|
|
@@ -852,7 +866,7 @@ describe('TaskSettings Component', () => {
|
|
|
852
866
|
json: async () => ({ items: [] })
|
|
853
867
|
}));
|
|
854
868
|
const user = userEvent.setup();
|
|
855
|
-
|
|
869
|
+
renderMcpComponent({
|
|
856
870
|
settingsModel: {
|
|
857
871
|
runtimeMode: 'cloud',
|
|
858
872
|
isAuthenticated: true,
|
|
@@ -860,8 +874,14 @@ describe('TaskSettings Component', () => {
|
|
|
860
874
|
fetchCloudAuthApi
|
|
861
875
|
}
|
|
862
876
|
});
|
|
863
|
-
await user
|
|
877
|
+
await openMcpSettings(user);
|
|
864
878
|
expect(await screen.findByText('Cloud MCP Configuration')).toBeInTheDocument();
|
|
879
|
+
expect(screen.getByText(/Cloud MCP connects agents to Taskforce through the hosted MCP endpoint/i)).toBeInTheDocument();
|
|
880
|
+
expect(screen.getByText(/Once the MCP is configured, prompt your agent:/i)).toBeInTheDocument();
|
|
881
|
+
expect(screen.getByRole('button', { name: 'Resolve your profile with Taskforce.' })).toBeInTheDocument();
|
|
882
|
+
const cloudInstructionLabel = screen.getByText('General MCP Configuration Instructions');
|
|
883
|
+
const cloudProfilePrompt = screen.getByText(/Once the MCP is configured, prompt your agent:/i);
|
|
884
|
+
expect(cloudInstructionLabel.compareDocumentPosition(cloudProfilePrompt) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
|
|
865
885
|
expect(screen.getByRole('button', { name: 'Generate Token' })).toBeInTheDocument();
|
|
866
886
|
expect(screen.queryByRole('button', { name: 'Local MCP' })).not.toBeInTheDocument();
|
|
867
887
|
expect(screen.queryByText('MCP Path Mapping (Host Root)')).not.toBeInTheDocument();
|
|
@@ -870,13 +890,28 @@ describe('TaskSettings Component', () => {
|
|
|
870
890
|
credentials: 'include'
|
|
871
891
|
}));
|
|
872
892
|
}, 10000);
|
|
893
|
+
it('4.20a MCP setup tells users how to register the agent profile', async () => {
|
|
894
|
+
renderMcpComponent({
|
|
895
|
+
settingsModel: {
|
|
896
|
+
runtimeMode: 'local',
|
|
897
|
+
isAuthenticated: false
|
|
898
|
+
}
|
|
899
|
+
});
|
|
900
|
+
expect(screen.getByText(/Local MCP connects through your local Taskforce install/i)).toBeInTheDocument();
|
|
901
|
+
expect(screen.getByText(/Once the MCP is configured, prompt your agent:/i)).toBeInTheDocument();
|
|
902
|
+
expect(screen.getByRole('button', { name: 'Resolve your profile with Taskforce.' })).toBeInTheDocument();
|
|
903
|
+
const localInstructionLabel = screen.getByText('General MCP Configuration Instructions');
|
|
904
|
+
const localProfilePrompt = screen.getByText(/Once the MCP is configured, prompt your agent:/i);
|
|
905
|
+
expect(localInstructionLabel.compareDocumentPosition(localProfilePrompt) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
|
|
906
|
+
expect(screen.queryByText('Ask Your Agent to Register')).not.toBeInTheDocument();
|
|
907
|
+
});
|
|
873
908
|
it('4.21 Local authenticated runtime defaults MCP tab to local with local-first toggle', async () => {
|
|
874
909
|
const fetchCloudAuthApi = vi.fn(async () => ({
|
|
875
910
|
ok: true,
|
|
876
911
|
json: async () => ({ items: [] })
|
|
877
912
|
}));
|
|
878
913
|
const user = userEvent.setup();
|
|
879
|
-
|
|
914
|
+
renderMcpComponent({
|
|
880
915
|
settingsModel: {
|
|
881
916
|
runtimeMode: 'local',
|
|
882
917
|
isAuthenticated: true,
|
|
@@ -885,7 +920,7 @@ describe('TaskSettings Component', () => {
|
|
|
885
920
|
fetchCloudAuthApi
|
|
886
921
|
}
|
|
887
922
|
});
|
|
888
|
-
await user
|
|
923
|
+
await openMcpSettings(user);
|
|
889
924
|
const localButton = await screen.findByRole('button', { name: 'Local MCP' });
|
|
890
925
|
const cloudButton = screen.getByRole('button', { name: 'Cloud MCP' });
|
|
891
926
|
expect(localButton.compareDocumentPosition(cloudButton) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
|
|
@@ -926,7 +961,7 @@ describe('TaskSettings Component', () => {
|
|
|
926
961
|
};
|
|
927
962
|
});
|
|
928
963
|
const user = userEvent.setup();
|
|
929
|
-
|
|
964
|
+
renderMcpComponent({
|
|
930
965
|
settingsModel: {
|
|
931
966
|
runtimeMode: 'local',
|
|
932
967
|
isAuthenticated: true,
|
|
@@ -947,11 +982,11 @@ describe('TaskSettings Component', () => {
|
|
|
947
982
|
expiresAt: null
|
|
948
983
|
})
|
|
949
984
|
}));
|
|
950
|
-
expect(
|
|
985
|
+
expect(await screen.findByDisplayValue('tfmcp_example_secret')).toBeInTheDocument();
|
|
951
986
|
}, 10000);
|
|
952
987
|
it('4.23c MCP token name defaults to the workspace name', async () => {
|
|
953
988
|
const user = userEvent.setup();
|
|
954
|
-
|
|
989
|
+
renderMcpComponent({
|
|
955
990
|
settingsModel: {
|
|
956
991
|
runtimeMode: 'local',
|
|
957
992
|
isAuthenticated: true,
|
|
@@ -982,7 +1017,7 @@ describe('TaskSettings Component', () => {
|
|
|
982
1017
|
};
|
|
983
1018
|
});
|
|
984
1019
|
const user = userEvent.setup();
|
|
985
|
-
|
|
1020
|
+
renderMcpComponent({
|
|
986
1021
|
settingsModel: {
|
|
987
1022
|
runtimeMode: 'local',
|
|
988
1023
|
isAuthenticated: true,
|
|
@@ -991,9 +1026,9 @@ describe('TaskSettings Component', () => {
|
|
|
991
1026
|
}
|
|
992
1027
|
});
|
|
993
1028
|
await openCloudMcpSettings(user);
|
|
994
|
-
|
|
995
|
-
await user.type(await screen.findByPlaceholderText('
|
|
996
|
-
await user.click(screen.
|
|
1029
|
+
expect(screen.queryByText('Test Connection')).not.toBeInTheDocument();
|
|
1030
|
+
await user.type(await screen.findByPlaceholderText('Generate a token to populate the full secret'), 'tfmcp_example_secret');
|
|
1031
|
+
await user.click(screen.getByRole('button', { name: 'Test Token' }));
|
|
997
1032
|
expect(fetchCloudAuthApi).toHaveBeenCalledWith('/api/taskforce/settings/mcp/test-connection', expect.objectContaining({
|
|
998
1033
|
method: 'POST',
|
|
999
1034
|
credentials: 'include'
|
|
@@ -1023,7 +1058,7 @@ describe('TaskSettings Component', () => {
|
|
|
1023
1058
|
};
|
|
1024
1059
|
});
|
|
1025
1060
|
const user = userEvent.setup();
|
|
1026
|
-
|
|
1061
|
+
renderMcpComponent({
|
|
1027
1062
|
settingsModel: {
|
|
1028
1063
|
runtimeMode: 'local',
|
|
1029
1064
|
isAuthenticated: true,
|
|
@@ -1033,9 +1068,8 @@ describe('TaskSettings Component', () => {
|
|
|
1033
1068
|
}
|
|
1034
1069
|
});
|
|
1035
1070
|
await openCloudMcpSettings(user);
|
|
1036
|
-
await user.
|
|
1037
|
-
await user.
|
|
1038
|
-
await user.click(screen.getAllByRole('button', { name: 'Test Connection' })[1]);
|
|
1071
|
+
await user.type(await screen.findByPlaceholderText('Generate a token to populate the full secret'), 'tfmcp_example_secret');
|
|
1072
|
+
await user.click(screen.getByRole('button', { name: 'Test Token' }));
|
|
1039
1073
|
expect(await screen.findByText('The dedicated MCP host is responding with a gateway error.')).toBeInTheDocument();
|
|
1040
1074
|
expect(screen.getByText(/Endpoint: https:\/\/performance-mcp\.taskforcehq\.ai\/mcp/i)).toBeInTheDocument();
|
|
1041
1075
|
expect(screen.getByText(/Error code: MCP_ENDPOINT_GATEWAY_ERROR/i)).toBeInTheDocument();
|
|
@@ -1047,7 +1081,7 @@ describe('TaskSettings Component', () => {
|
|
|
1047
1081
|
json: async () => ({ items: [] })
|
|
1048
1082
|
}));
|
|
1049
1083
|
const user = userEvent.setup();
|
|
1050
|
-
|
|
1084
|
+
renderMcpComponent({
|
|
1051
1085
|
settingsModel: {
|
|
1052
1086
|
runtimeMode: 'local',
|
|
1053
1087
|
isAuthenticated: true,
|
|
@@ -1069,7 +1103,7 @@ describe('TaskSettings Component', () => {
|
|
|
1069
1103
|
json: async () => ({ items: [] })
|
|
1070
1104
|
}));
|
|
1071
1105
|
const user = userEvent.setup();
|
|
1072
|
-
|
|
1106
|
+
renderMcpComponent({
|
|
1073
1107
|
settingsModel: {
|
|
1074
1108
|
runtimeMode: 'local',
|
|
1075
1109
|
isAuthenticated: true,
|
|
@@ -1089,7 +1123,7 @@ describe('TaskSettings Component', () => {
|
|
|
1089
1123
|
json: async () => ({ items: [] })
|
|
1090
1124
|
}));
|
|
1091
1125
|
const user = userEvent.setup();
|
|
1092
|
-
|
|
1126
|
+
renderMcpComponent({
|
|
1093
1127
|
settingsModel: {
|
|
1094
1128
|
runtimeMode: 'local',
|
|
1095
1129
|
isAuthenticated: true,
|
|
@@ -1109,7 +1143,7 @@ describe('TaskSettings Component', () => {
|
|
|
1109
1143
|
json: async () => ({ items: [] })
|
|
1110
1144
|
}));
|
|
1111
1145
|
const user = userEvent.setup();
|
|
1112
|
-
|
|
1146
|
+
renderMcpComponent({
|
|
1113
1147
|
settingsModel: {
|
|
1114
1148
|
runtimeMode: 'local',
|
|
1115
1149
|
isAuthenticated: true,
|
|
@@ -1131,7 +1165,7 @@ describe('TaskSettings Component', () => {
|
|
|
1131
1165
|
json: async () => ({ items: [] })
|
|
1132
1166
|
}));
|
|
1133
1167
|
const user = userEvent.setup();
|
|
1134
|
-
|
|
1168
|
+
renderMcpComponent({
|
|
1135
1169
|
settingsModel: {
|
|
1136
1170
|
runtimeMode: 'local',
|
|
1137
1171
|
isAuthenticated: true,
|
|
@@ -1153,7 +1187,7 @@ describe('TaskSettings Component', () => {
|
|
|
1153
1187
|
json: async () => ({ items: [] })
|
|
1154
1188
|
}));
|
|
1155
1189
|
const user = userEvent.setup();
|
|
1156
|
-
|
|
1190
|
+
renderMcpComponent({
|
|
1157
1191
|
settingsModel: {
|
|
1158
1192
|
runtimeMode: 'local',
|
|
1159
1193
|
isAuthenticated: true,
|
|
@@ -1175,7 +1209,7 @@ describe('TaskSettings Component', () => {
|
|
|
1175
1209
|
json: async () => ({ items: [] })
|
|
1176
1210
|
}));
|
|
1177
1211
|
const user = userEvent.setup();
|
|
1178
|
-
|
|
1212
|
+
renderMcpComponent({
|
|
1179
1213
|
settingsModel: {
|
|
1180
1214
|
runtimeMode: 'local',
|
|
1181
1215
|
isAuthenticated: true,
|
|
@@ -1197,7 +1231,7 @@ describe('TaskSettings Component', () => {
|
|
|
1197
1231
|
json: async () => ({ items: [] })
|
|
1198
1232
|
}));
|
|
1199
1233
|
const user = userEvent.setup();
|
|
1200
|
-
|
|
1234
|
+
renderMcpComponent({
|
|
1201
1235
|
settingsModel: {
|
|
1202
1236
|
runtimeMode: 'local',
|
|
1203
1237
|
isAuthenticated: true,
|
|
@@ -1219,7 +1253,7 @@ describe('TaskSettings Component', () => {
|
|
|
1219
1253
|
json: async () => ({ items: [] })
|
|
1220
1254
|
}));
|
|
1221
1255
|
const user = userEvent.setup();
|
|
1222
|
-
|
|
1256
|
+
renderMcpComponent({
|
|
1223
1257
|
settingsModel: {
|
|
1224
1258
|
runtimeMode: 'local',
|
|
1225
1259
|
isAuthenticated: true,
|
|
@@ -1242,7 +1276,7 @@ describe('TaskSettings Component', () => {
|
|
|
1242
1276
|
json: async () => ({ items: [] })
|
|
1243
1277
|
}));
|
|
1244
1278
|
const user = userEvent.setup();
|
|
1245
|
-
|
|
1279
|
+
renderMcpComponent({
|
|
1246
1280
|
settingsModel: {
|
|
1247
1281
|
runtimeMode: 'local',
|
|
1248
1282
|
isAuthenticated: true,
|
|
@@ -1269,7 +1303,7 @@ describe('TaskSettings Component', () => {
|
|
|
1269
1303
|
json: async () => ({ items: [] })
|
|
1270
1304
|
}));
|
|
1271
1305
|
const user = userEvent.setup();
|
|
1272
|
-
|
|
1306
|
+
renderMcpComponent({
|
|
1273
1307
|
settingsModel: {
|
|
1274
1308
|
runtimeMode: 'local',
|
|
1275
1309
|
isAuthenticated: true,
|
|
@@ -1346,7 +1380,7 @@ describe('TaskSettings Component', () => {
|
|
|
1346
1380
|
json: async () => ({ items: [] })
|
|
1347
1381
|
}));
|
|
1348
1382
|
const user = userEvent.setup();
|
|
1349
|
-
|
|
1383
|
+
renderMcpComponent({
|
|
1350
1384
|
settingsModel: {
|
|
1351
1385
|
runtimeMode: 'local',
|
|
1352
1386
|
isAuthenticated: true,
|
|
@@ -1361,7 +1395,7 @@ describe('TaskSettings Component', () => {
|
|
|
1361
1395
|
}, 10000);
|
|
1362
1396
|
it('4.23g Cloud MCP configuration offers snippet and full-config copy actions', async () => {
|
|
1363
1397
|
const user = userEvent.setup();
|
|
1364
|
-
|
|
1398
|
+
renderMcpComponent({
|
|
1365
1399
|
settingsModel: {
|
|
1366
1400
|
runtimeMode: 'local',
|
|
1367
1401
|
isAuthenticated: true,
|
|
@@ -1374,7 +1408,7 @@ describe('TaskSettings Component', () => {
|
|
|
1374
1408
|
}, 10000);
|
|
1375
1409
|
it('4.23g1 Cloud MCP copy warns before a token is generated', async () => {
|
|
1376
1410
|
const user = userEvent.setup();
|
|
1377
|
-
|
|
1411
|
+
renderMcpComponent({
|
|
1378
1412
|
settingsModel: {
|
|
1379
1413
|
runtimeMode: 'local',
|
|
1380
1414
|
isAuthenticated: true,
|
|
@@ -1388,7 +1422,7 @@ describe('TaskSettings Component', () => {
|
|
|
1388
1422
|
}, 10000);
|
|
1389
1423
|
it('4.23g2 Cloud MCP settings do not surface automation identity controls', async () => {
|
|
1390
1424
|
const user = userEvent.setup();
|
|
1391
|
-
|
|
1425
|
+
renderMcpComponent({
|
|
1392
1426
|
settingsModel: {
|
|
1393
1427
|
runtimeMode: 'local',
|
|
1394
1428
|
isAuthenticated: true,
|
|
@@ -1402,7 +1436,7 @@ describe('TaskSettings Component', () => {
|
|
|
1402
1436
|
}, 10000);
|
|
1403
1437
|
it('4.23g3 Cloud MCP config does not include AI identity headers by default', async () => {
|
|
1404
1438
|
const user = userEvent.setup();
|
|
1405
|
-
|
|
1439
|
+
renderMcpComponent({
|
|
1406
1440
|
settingsModel: {
|
|
1407
1441
|
runtimeMode: 'local',
|
|
1408
1442
|
isAuthenticated: true,
|
|
@@ -1415,34 +1449,52 @@ describe('TaskSettings Component', () => {
|
|
|
1415
1449
|
expect(screen.queryByText(/X-Taskforce-AI-Name/i)).not.toBeInTheDocument();
|
|
1416
1450
|
expect(screen.queryByText(/X-Taskforce-AI-Profile-Token/i)).not.toBeInTheDocument();
|
|
1417
1451
|
}, 10000);
|
|
1418
|
-
it('4.23h Active tokens sort first and
|
|
1452
|
+
it('4.23h Active tokens sort first and inactive tokens only show delete actions', async () => {
|
|
1419
1453
|
const user = userEvent.setup();
|
|
1420
|
-
const
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1454
|
+
const confirmSpy = vi.spyOn(window, 'confirm').mockImplementation(() => true);
|
|
1455
|
+
const fetchCloudAuthApi = vi.fn(async (path, init) => {
|
|
1456
|
+
if (path === '/api/taskforce/settings/mcp/tokens/token-expired' && init?.method === 'DELETE') {
|
|
1457
|
+
return {
|
|
1458
|
+
ok: true,
|
|
1459
|
+
json: async () => ({ success: true, deleted: true })
|
|
1460
|
+
};
|
|
1461
|
+
}
|
|
1462
|
+
return {
|
|
1463
|
+
ok: true,
|
|
1464
|
+
json: async () => ({
|
|
1465
|
+
items: [
|
|
1466
|
+
{
|
|
1467
|
+
id: 'token-expired',
|
|
1468
|
+
name: 'Expired Token',
|
|
1469
|
+
scopes: ['tasks:read'],
|
|
1470
|
+
tokenPrefix: 'tfmcp_expired',
|
|
1471
|
+
status: 'expired',
|
|
1472
|
+
createdAt: '2026-03-03T00:00:00.000Z',
|
|
1473
|
+
lastUsedAt: null,
|
|
1474
|
+
},
|
|
1475
|
+
{
|
|
1476
|
+
id: 'token-revoked',
|
|
1477
|
+
name: 'Old Token',
|
|
1478
|
+
scopes: ['tasks:read'],
|
|
1479
|
+
tokenPrefix: 'tfmcp_old',
|
|
1480
|
+
status: 'revoked',
|
|
1481
|
+
createdAt: '2026-03-01T00:00:00.000Z',
|
|
1482
|
+
lastUsedAt: null,
|
|
1483
|
+
},
|
|
1484
|
+
{
|
|
1485
|
+
id: 'token-active',
|
|
1486
|
+
name: 'Current Token',
|
|
1487
|
+
scopes: ['tasks:read', 'tasks:write'],
|
|
1488
|
+
tokenPrefix: 'tfmcp_new',
|
|
1489
|
+
status: 'active',
|
|
1490
|
+
createdAt: '2026-03-02T00:00:00.000Z',
|
|
1491
|
+
lastUsedAt: null,
|
|
1492
|
+
}
|
|
1493
|
+
]
|
|
1494
|
+
})
|
|
1495
|
+
};
|
|
1496
|
+
});
|
|
1497
|
+
renderMcpComponent({
|
|
1446
1498
|
settingsModel: {
|
|
1447
1499
|
runtimeMode: 'local',
|
|
1448
1500
|
isAuthenticated: true,
|
|
@@ -1452,16 +1504,27 @@ describe('TaskSettings Component', () => {
|
|
|
1452
1504
|
});
|
|
1453
1505
|
await openCloudMcpSettings(user);
|
|
1454
1506
|
expect(await screen.findByText('Current Token')).toBeInTheDocument();
|
|
1507
|
+
expect(screen.getByText('Expired Token')).toBeInTheDocument();
|
|
1455
1508
|
expect(screen.getByText('Old Token')).toBeInTheDocument();
|
|
1456
|
-
const tokenLabels = screen.getAllByText(/^(Current Token|Old Token)$/);
|
|
1509
|
+
const tokenLabels = screen.getAllByText(/^(Current Token|Expired Token|Old Token)$/);
|
|
1457
1510
|
expect(tokenLabels[0]).toHaveTextContent('Current Token');
|
|
1458
|
-
expect(tokenLabels[1]).toHaveTextContent('
|
|
1511
|
+
expect(tokenLabels[1]).toHaveTextContent('Expired Token');
|
|
1512
|
+
expect(tokenLabels[2]).toHaveTextContent('Old Token');
|
|
1459
1513
|
expect(screen.getAllByRole('button', { name: 'Regenerate' })).toHaveLength(1);
|
|
1460
1514
|
expect(screen.getAllByRole('button', { name: 'Revoke' })).toHaveLength(1);
|
|
1515
|
+
expect(screen.getAllByRole('button', { name: 'Delete' })).toHaveLength(2);
|
|
1516
|
+
await user.click(screen.getAllByRole('button', { name: 'Delete' })[0]);
|
|
1517
|
+
expect(confirmSpy).toHaveBeenCalledWith('Delete this token record? This does not affect active tokens.');
|
|
1518
|
+
expect(fetchCloudAuthApi).toHaveBeenCalledWith('/api/taskforce/settings/mcp/tokens/token-expired', expect.objectContaining({
|
|
1519
|
+
method: 'DELETE',
|
|
1520
|
+
credentials: 'include'
|
|
1521
|
+
}));
|
|
1522
|
+
await waitFor(() => expect(screen.queryByText('Expired Token')).not.toBeInTheDocument());
|
|
1523
|
+
confirmSpy.mockRestore();
|
|
1461
1524
|
}, 10000);
|
|
1462
1525
|
it('4.23f Cloud MCP snippet keeps the server id short enough for client tool-name limits', async () => {
|
|
1463
1526
|
const user = userEvent.setup();
|
|
1464
|
-
|
|
1527
|
+
renderMcpComponent({
|
|
1465
1528
|
settingsModel: {
|
|
1466
1529
|
runtimeMode: 'local',
|
|
1467
1530
|
isAuthenticated: true,
|
|
@@ -1480,33 +1543,59 @@ describe('TaskSettings Component', () => {
|
|
|
1480
1543
|
expect(serverId.length).toBeLessThanOrEqual(33);
|
|
1481
1544
|
expect(`mcp_${serverId}_set_schedule_preferences`.length).toBeLessThanOrEqual(64);
|
|
1482
1545
|
}, 10000);
|
|
1483
|
-
it('4.24 Local signed-out runtime
|
|
1546
|
+
it('4.24 Local signed-out runtime keeps Cloud MCP visible with an auth prompt', async () => {
|
|
1484
1547
|
const user = userEvent.setup();
|
|
1485
|
-
|
|
1548
|
+
const fetchCloudAuthApi = vi.fn(async () => ({
|
|
1549
|
+
ok: true,
|
|
1550
|
+
json: async () => ({ items: [] })
|
|
1551
|
+
}));
|
|
1552
|
+
renderMcpComponent({
|
|
1486
1553
|
settingsModel: {
|
|
1487
1554
|
runtimeMode: 'local',
|
|
1488
|
-
isAuthenticated: false
|
|
1555
|
+
isAuthenticated: false,
|
|
1556
|
+
fetchCloudAuthApi
|
|
1489
1557
|
}
|
|
1490
1558
|
});
|
|
1491
|
-
await user
|
|
1492
|
-
expect(screen.
|
|
1559
|
+
await openMcpSettings(user);
|
|
1560
|
+
expect(screen.getByRole('button', { name: 'Local MCP' })).toBeInTheDocument();
|
|
1561
|
+
expect(screen.getByRole('button', { name: 'Cloud MCP' })).toBeInTheDocument();
|
|
1493
1562
|
expect(screen.getByRole('combobox', { name: 'MCP client' })).toHaveValue('general');
|
|
1494
1563
|
expect(screen.getByText('General MCP Configuration Instructions')).toBeInTheDocument();
|
|
1495
1564
|
expect(screen.queryByText('MCP Path Mapping (Host Root)')).not.toBeInTheDocument();
|
|
1496
1565
|
await user.click(screen.getByRole('button', { name: 'Advanced' }));
|
|
1497
1566
|
expect(screen.getByText('MCP Path Mapping (Host Root)')).toBeInTheDocument();
|
|
1567
|
+
await user.click(screen.getByRole('button', { name: 'Cloud MCP' }));
|
|
1568
|
+
expect(screen.getByText('Sign in to use Cloud MCP')).toBeInTheDocument();
|
|
1569
|
+
expect(screen.getByText(/Register or sign in to generate cloud MCP tokens/i)).toBeInTheDocument();
|
|
1498
1570
|
expect(screen.queryByText('Cloud MCP Configuration')).not.toBeInTheDocument();
|
|
1499
|
-
expect(
|
|
1571
|
+
expect(fetchCloudAuthApi).not.toHaveBeenCalled();
|
|
1500
1572
|
});
|
|
1501
|
-
it('4.24a Local MCP
|
|
1573
|
+
it('4.24a Local signed-out Cloud MCP prompt can open login and registration', async () => {
|
|
1502
1574
|
const user = userEvent.setup();
|
|
1503
|
-
|
|
1575
|
+
const onOpenCloudAuth = vi.fn();
|
|
1576
|
+
renderMcpComponent({
|
|
1577
|
+
settingsModel: {
|
|
1578
|
+
runtimeMode: 'local',
|
|
1579
|
+
isAuthenticated: false,
|
|
1580
|
+
onOpenCloudAuth
|
|
1581
|
+
}
|
|
1582
|
+
});
|
|
1583
|
+
await openMcpSettings(user);
|
|
1584
|
+
await user.click(screen.getByRole('button', { name: 'Cloud MCP' }));
|
|
1585
|
+
await user.click(screen.getByRole('button', { name: 'Sign In' }));
|
|
1586
|
+
expect(onOpenCloudAuth).toHaveBeenCalledWith('login');
|
|
1587
|
+
await user.click(screen.getByRole('button', { name: 'Register' }));
|
|
1588
|
+
expect(onOpenCloudAuth).toHaveBeenCalledWith('register');
|
|
1589
|
+
});
|
|
1590
|
+
it('4.24b Local MCP selector offers General first and keeps the rest alphabetical', async () => {
|
|
1591
|
+
const user = userEvent.setup();
|
|
1592
|
+
renderMcpComponent({
|
|
1504
1593
|
settingsModel: {
|
|
1505
1594
|
runtimeMode: 'local',
|
|
1506
1595
|
isAuthenticated: false
|
|
1507
1596
|
}
|
|
1508
1597
|
});
|
|
1509
|
-
await user
|
|
1598
|
+
await openMcpSettings(user);
|
|
1510
1599
|
const options = screen.getAllByRole('option').map((option) => option.textContent);
|
|
1511
1600
|
expect(options).toEqual([
|
|
1512
1601
|
'General',
|
|
@@ -1521,9 +1610,9 @@ describe('TaskSettings Component', () => {
|
|
|
1521
1610
|
'Windsurf'
|
|
1522
1611
|
]);
|
|
1523
1612
|
});
|
|
1524
|
-
it('4.
|
|
1613
|
+
it('4.24c Local Codex shows config.toml MCP output without token headers', async () => {
|
|
1525
1614
|
const user = userEvent.setup();
|
|
1526
|
-
|
|
1615
|
+
renderMcpComponent({
|
|
1527
1616
|
settingsModel: {
|
|
1528
1617
|
runtimeMode: 'local',
|
|
1529
1618
|
isAuthenticated: false,
|
|
@@ -1534,7 +1623,7 @@ describe('TaskSettings Component', () => {
|
|
|
1534
1623
|
mcpScriptPath: '/usr/local/bin/taskforce'
|
|
1535
1624
|
}
|
|
1536
1625
|
});
|
|
1537
|
-
await user
|
|
1626
|
+
await openMcpSettings(user);
|
|
1538
1627
|
await user.selectOptions(screen.getByRole('combobox', { name: 'MCP client' }), 'codex');
|
|
1539
1628
|
expect(await screen.findByText(/Codex Configuration Instructions/i)).toBeInTheDocument();
|
|
1540
1629
|
expect((await screen.findAllByText(/\.codex\/config\.toml/i)).length).toBeGreaterThan(0);
|
|
@@ -1542,9 +1631,9 @@ describe('TaskSettings Component', () => {
|
|
|
1542
1631
|
expect(screen.getByText(/command = "taskforce"/i)).toBeInTheDocument();
|
|
1543
1632
|
expect(screen.queryByText(/Authorization/i)).not.toBeInTheDocument();
|
|
1544
1633
|
});
|
|
1545
|
-
it('4.
|
|
1634
|
+
it('4.24d Local VS Code uses stdio config under servers', async () => {
|
|
1546
1635
|
const user = userEvent.setup();
|
|
1547
|
-
|
|
1636
|
+
renderMcpComponent({
|
|
1548
1637
|
settingsModel: {
|
|
1549
1638
|
runtimeMode: 'local',
|
|
1550
1639
|
isAuthenticated: false,
|
|
@@ -1555,16 +1644,16 @@ describe('TaskSettings Component', () => {
|
|
|
1555
1644
|
mcpScriptPath: '/usr/local/bin/taskforce'
|
|
1556
1645
|
}
|
|
1557
1646
|
});
|
|
1558
|
-
await user
|
|
1647
|
+
await openMcpSettings(user);
|
|
1559
1648
|
await user.selectOptions(screen.getByRole('combobox', { name: 'MCP client' }), 'vscode');
|
|
1560
1649
|
expect(await screen.findByText(/VS Code Configuration Instructions/i)).toBeInTheDocument();
|
|
1561
1650
|
expect(screen.getByText(/"servers"/)).toBeInTheDocument();
|
|
1562
1651
|
expect(screen.getByText(/"type"/)).toBeInTheDocument();
|
|
1563
1652
|
expect(screen.getByText(/"stdio"/)).toBeInTheDocument();
|
|
1564
1653
|
});
|
|
1565
|
-
it('4.
|
|
1654
|
+
it('4.24e Local Claude Code shows a stdio add command', async () => {
|
|
1566
1655
|
const user = userEvent.setup();
|
|
1567
|
-
|
|
1656
|
+
renderMcpComponent({
|
|
1568
1657
|
settingsModel: {
|
|
1569
1658
|
runtimeMode: 'local',
|
|
1570
1659
|
isAuthenticated: false,
|
|
@@ -1575,7 +1664,7 @@ describe('TaskSettings Component', () => {
|
|
|
1575
1664
|
mcpScriptPath: '/usr/local/bin/taskforce'
|
|
1576
1665
|
}
|
|
1577
1666
|
});
|
|
1578
|
-
await user
|
|
1667
|
+
await openMcpSettings(user);
|
|
1579
1668
|
await user.selectOptions(screen.getByRole('combobox', { name: 'MCP client' }), 'claude-code');
|
|
1580
1669
|
expect(await screen.findByText(/Claude Code Configuration Instructions/i)).toBeInTheDocument();
|
|
1581
1670
|
expect(screen.getByText(/claude mcp add taskforce-/i)).toBeInTheDocument();
|
|
@@ -15,7 +15,7 @@ export interface DocMeta {
|
|
|
15
15
|
updatedAt: string | null;
|
|
16
16
|
editable?: boolean;
|
|
17
17
|
attachmentCount?: number;
|
|
18
|
-
attachmentState?: 'attached' | 'unattached'
|
|
18
|
+
attachmentState?: 'attached' | 'unattached';
|
|
19
19
|
}
|
|
20
20
|
export declare function normalizeDocPath(value: string): string;
|
|
21
21
|
export declare function docPathMatches(candidate: string, requested: string): boolean;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { Check,
|
|
3
|
+
import { Check, Link2, Loader2, Plus, RotateCcw, Trash2, Unlink, X } from 'lucide-react';
|
|
4
4
|
import styles from '../../Taskforce.module.css';
|
|
5
5
|
import { t } from '../../localization';
|
|
6
6
|
import { TaskStatusActions } from './TaskStatusActions';
|
|
7
7
|
import { getTaskReferenceDisplayState } from '../../utils/taskReferences';
|
|
8
8
|
import { TaskReferenceBadge } from './TaskReferenceBadge';
|
|
9
|
+
import { HierarchyActionBadge } from '../ui/HierarchyActionBadge';
|
|
9
10
|
import { formatInitiativeReference, getWorkstreamReferenceLabel } from '../../utils/planningReferences';
|
|
10
11
|
export function TaskActionHeader({ editingTaskId, loading, autoSaveState = 'idle', title, handleSubmit, resetForm, handleCopyId, copiedId, tasks, currentTask: currentTaskProp, currentTaskWorkstream, currentTaskInitiative, workstreamInput = '', onWorkstreamInputChange, onSetWorkstreamForCurrentTask, handleToggleInProgress, handleToggleReview, handleToggleComplete, handleToggleCancel, handleSetStatus, handleArchiveTask, handleUnarchiveTask, handleRestoreDeletedTask, handlePermanentlyDeleteDeletedTask }) {
|
|
11
12
|
const [showWorkstreamEditor, setShowWorkstreamEditor] = React.useState(false);
|
|
@@ -32,10 +33,15 @@ export function TaskActionHeader({ editingTaskId, loading, autoSaveState = 'idle
|
|
|
32
33
|
return;
|
|
33
34
|
onSetWorkstreamForCurrentTask?.();
|
|
34
35
|
}, [onSetWorkstreamForCurrentTask, workstreamInput]);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
const handleWorkstreamRemove = React.useCallback(() => {
|
|
37
|
+
setShowWorkstreamEditor(false);
|
|
38
|
+
onWorkstreamInputChange?.('');
|
|
39
|
+
onSetWorkstreamForCurrentTask?.(null);
|
|
40
|
+
}, [onSetWorkstreamForCurrentTask, onWorkstreamInputChange]);
|
|
41
|
+
return (_jsx("div", { className: styles.stickyActionHeader, children: editingTaskId ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: styles.taskHierarchyHeader, children: [_jsxs("div", { className: styles.taskHierarchyBadgeRow, children: [currentTaskWorkstream ? (_jsx(_Fragment, { children: _jsx(HierarchyActionBadge, { onClick: handleWorkstreamRemove, disabled: loading || isArchivedReadOnly || isDeletedReadOnly, title: "Remove from workstream", ariaLabel: "Remove from workstream", children: _jsx(Unlink, { size: 13 }) }) })) : null, currentTaskInitiative ? (_jsxs("span", { className: styles.taskHierarchySegment, children: [_jsx("span", { className: styles.taskHierarchyDivider, children: "/" }), _jsx(TaskReferenceBadge, { copied: copiedId === currentInitiativeReferenceLabel, onClick: (e) => handleCopyId(e, currentInitiativeReferenceLabel), disabled: loading, title: "Copy initiative reference", label: currentInitiativeReferenceLabel })] })) : null, currentTaskWorkstream ? (_jsxs("span", { className: styles.taskHierarchySegment, children: [_jsx("span", { className: styles.taskHierarchyDivider, children: "/" }), _jsx(TaskReferenceBadge, { copied: copiedId === currentWorkstreamReferenceLabel, onClick: (e) => handleCopyId(e, currentWorkstreamReferenceLabel), disabled: loading, title: "Copy workstream reference", label: currentWorkstreamReferenceLabel })] })) : (_jsx(_Fragment, { children: _jsx(HierarchyActionBadge, { onClick: () => {
|
|
42
|
+
onWorkstreamInputChange?.('');
|
|
43
|
+
setShowWorkstreamEditor((value) => !value);
|
|
44
|
+
}, disabled: loading || isArchivedReadOnly || isDeletedReadOnly, title: "Attach to workstream", ariaLabel: "Attach to workstream", children: _jsx(Link2, { size: 13 }) }) })), currentTaskReferenceLabel ? (_jsxs("span", { className: styles.taskHierarchySegment, children: [_jsx("span", { className: styles.taskHierarchyDivider, children: "/" }), _jsx(TaskReferenceBadge, { copied: canCopyCurrentTaskReference && copiedId === currentTaskReference.label, onClick: (e) => handleCopyId(e, currentTaskReference.label), disabled: loading || !canCopyCurrentTaskReference, title: canCopyCurrentTaskReference ? t('actionHeader.copyTaskIdTitle') : 'Task reference pending sync', label: currentTaskReferenceLabel })] })) : null, currentTaskReferenceIsProvisional ? (_jsx("span", { className: styles.taskHierarchyMeta, title: "Temporary local reference until cloud sync assigns the final task number.", children: "Pending sync" })) : null] }), showWorkstreamEditor && !currentTaskWorkstream ? (_jsxs("div", { className: styles.taskHierarchyEditor, children: [_jsx("input", { type: "text", className: `${styles.input} ${styles.taskHierarchyInput}`, value: workstreamInput, onChange: (event) => onWorkstreamInputChange?.(event.target.value), placeholder: "WS-123", "aria-label": "Attach workstream reference", onKeyDown: (event) => {
|
|
39
45
|
if (event.key === 'Enter') {
|
|
40
46
|
event.preventDefault();
|
|
41
47
|
handleWorkstreamConfirm();
|
|
@@ -60,6 +60,16 @@ describe('TaskActionHeader', () => {
|
|
|
60
60
|
expect(screen.getByText('IN-5')).toBeInTheDocument();
|
|
61
61
|
expect(screen.getByText('WS-12')).toBeInTheDocument();
|
|
62
62
|
expect(screen.getByText('T-1')).toBeInTheDocument();
|
|
63
|
+
expect(screen.getByRole('button', { name: /remove from workstream/i })).toBeInTheDocument();
|
|
64
|
+
});
|
|
65
|
+
it('removes the current workstream from the hierarchy header', async () => {
|
|
66
|
+
const user = userEvent.setup();
|
|
67
|
+
const onSetWorkstreamForCurrentTask = vi.fn();
|
|
68
|
+
const onWorkstreamInputChange = vi.fn();
|
|
69
|
+
render(_jsx(TaskActionHeader, { ...baseProps, editingTaskId: "task-1", title: "Polish task modal", currentTask: baseTask, currentTaskWorkstream: workstream, onSetWorkstreamForCurrentTask: onSetWorkstreamForCurrentTask, onWorkstreamInputChange: onWorkstreamInputChange }));
|
|
70
|
+
await user.click(screen.getByRole('button', { name: /remove from workstream/i }));
|
|
71
|
+
expect(onWorkstreamInputChange).toHaveBeenCalledWith('');
|
|
72
|
+
expect(onSetWorkstreamForCurrentTask).toHaveBeenCalledWith(null);
|
|
63
73
|
});
|
|
64
74
|
it('opens and cancels the inline workstream attach editor for unlinked tasks', async () => {
|
|
65
75
|
const user = userEvent.setup();
|