@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
|
@@ -12,7 +12,6 @@ export const ptBR = {
|
|
|
12
12
|
updatedLabel: 'Atualizado:',
|
|
13
13
|
completedLabel: 'Concluido:',
|
|
14
14
|
emptyValue: '—',
|
|
15
|
-
parentCannotSchedule: 'Tarefas pai nao podem ser agendadas. Agende as tarefas folha.',
|
|
16
15
|
dueBeforeScheduled: 'A data de vencimento e anterior a data agendada.',
|
|
17
16
|
overdue: 'Esta tarefa esta atrasada.'
|
|
18
17
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { WorkspaceAssetEntry, WorkspaceAssetKind, WorkspaceAssetLinkRole, WorkspaceAssetScanStatus, WorkspaceAssetStore } from '../storage/workspaceAssetStore.js';
|
|
1
|
+
import type { WorkspaceAssetEntry, WorkspaceAssetKind, WorkspaceAssetLinkRole, WorkspaceAssetLinkTargetType, WorkspaceAssetScanStatus, WorkspaceAssetStore } from '../storage/workspaceAssetStore.js';
|
|
2
2
|
import type { McpTaskAttachmentDescriptor, TaskAttachmentRecord } from './taskAttachmentTypes.js';
|
|
3
3
|
export interface CanonicalAssetHelpersDeps {
|
|
4
4
|
activeWorkspaceId: string;
|
|
@@ -9,6 +9,7 @@ export interface CanonicalAssetHelpersDeps {
|
|
|
9
9
|
getObject(storageKey: string): Promise<{
|
|
10
10
|
body: Buffer;
|
|
11
11
|
} | null>;
|
|
12
|
+
putObject?(storageKey: string, body: Buffer, contentType: string): Promise<void>;
|
|
12
13
|
} | null;
|
|
13
14
|
sanitizeFilenameForPath: (filenameRaw: unknown, fallback?: string) => string;
|
|
14
15
|
sanitizeDisplayName: (valueRaw: unknown, fallback: string) => string;
|
|
@@ -31,7 +32,7 @@ export declare function createCanonicalAssetHelpers(deps: CanonicalAssetHelpersD
|
|
|
31
32
|
getAttachmentAssetRecord: (attachment: TaskAttachmentRecord) => WorkspaceAssetEntry | null;
|
|
32
33
|
buildAttachmentDownloadUrl: (attachment: McpTaskAttachmentDescriptor) => string;
|
|
33
34
|
buildDocumentDownloadUrl: (asset: WorkspaceAssetEntry) => string;
|
|
34
|
-
readCanonicalAttachmentBuffer: (taskId: string, attachment: McpTaskAttachmentDescriptor) => Promise<Buffer>;
|
|
35
|
+
readCanonicalAttachmentBuffer: (taskId: string, attachment: McpTaskAttachmentDescriptor, targetLabel?: string) => Promise<Buffer>;
|
|
35
36
|
readCanonicalDocumentBuffer: (asset: WorkspaceAssetEntry) => Promise<Buffer>;
|
|
36
37
|
toTaskAttachmentRecord: (attachment: string | TaskAttachmentRecord) => TaskAttachmentRecord;
|
|
37
38
|
resolveAttachmentLogicalFilename: (attachmentInput: string | TaskAttachmentRecord, assetOverride?: ReturnType<(attachment: TaskAttachmentRecord) => WorkspaceAssetEntry | null> | null) => string;
|
|
@@ -47,7 +48,7 @@ export declare function createCanonicalAssetHelpers(deps: CanonicalAssetHelpersD
|
|
|
47
48
|
absolutePath: string;
|
|
48
49
|
logicalFilename: string;
|
|
49
50
|
};
|
|
50
|
-
|
|
51
|
+
ensureCanonicalAttachment: (relativePathRaw: string, targetTypeRaw: WorkspaceAssetLinkTargetType, targetIdRaw: string, captionRaw: string | undefined, timestampRaw: string | undefined, role: WorkspaceAssetLinkRole, options?: {
|
|
51
52
|
originalFilename?: string;
|
|
52
53
|
logicalName?: string;
|
|
53
54
|
assetId?: string;
|
|
@@ -57,7 +58,18 @@ export declare function createCanonicalAssetHelpers(deps: CanonicalAssetHelpersD
|
|
|
57
58
|
scanStatus?: WorkspaceAssetScanStatus;
|
|
58
59
|
scanEngine?: string | null;
|
|
59
60
|
scanDetails?: string | null;
|
|
60
|
-
}) => WorkspaceAssetEntry | null
|
|
61
|
+
}) => Promise<WorkspaceAssetEntry | null>;
|
|
62
|
+
ensureCanonicalTaskAttachment: (relativePathRaw: string, taskIdRaw: string, captionRaw: string | undefined, timestampRaw: string | undefined, role: WorkspaceAssetLinkRole, options?: Parameters<(relativePathRaw: string, targetTypeRaw: WorkspaceAssetLinkTargetType, targetIdRaw: string, captionRaw: string | undefined, timestampRaw: string | undefined, role: WorkspaceAssetLinkRole, options?: {
|
|
63
|
+
originalFilename?: string;
|
|
64
|
+
logicalName?: string;
|
|
65
|
+
assetId?: string;
|
|
66
|
+
documentId?: string | null;
|
|
67
|
+
createdAt?: string;
|
|
68
|
+
createdByUserId?: string | null;
|
|
69
|
+
scanStatus?: WorkspaceAssetScanStatus;
|
|
70
|
+
scanEngine?: string | null;
|
|
71
|
+
scanDetails?: string | null;
|
|
72
|
+
}) => Promise<WorkspaceAssetEntry | null>>[6]) => Promise<WorkspaceAssetEntry | null>;
|
|
61
73
|
buildCanonicalWorkspaceAssetRelativePath: (params: {
|
|
62
74
|
workspaceIdRaw: unknown;
|
|
63
75
|
kind: WorkspaceAssetKind;
|
|
@@ -65,13 +65,13 @@ export function createCanonicalAssetHelpers(deps) {
|
|
|
65
65
|
];
|
|
66
66
|
return parts.join(', ');
|
|
67
67
|
};
|
|
68
|
-
const readCanonicalAttachmentBuffer = async (taskId, attachment) => {
|
|
68
|
+
const readCanonicalAttachmentBuffer = async (taskId, attachment, targetLabel = 'task') => {
|
|
69
69
|
const assetId = String(attachment.assetId || '').trim();
|
|
70
70
|
const asset = assetId && deps.workspaceAssetStore
|
|
71
71
|
? deps.workspaceAssetStore.get(assetId, deps.activeWorkspaceId)
|
|
72
72
|
: null;
|
|
73
73
|
if (!asset || asset.deletedAt) {
|
|
74
|
-
throw new Error(`Attachment ${attachment.attachmentId} not found on
|
|
74
|
+
throw new Error(`Attachment ${attachment.attachmentId} not found on ${targetLabel} ${taskId}`);
|
|
75
75
|
}
|
|
76
76
|
if (asset.scanStatus === 'infected') {
|
|
77
77
|
throw new Error('Attachment is quarantined');
|
|
@@ -93,16 +93,16 @@ export function createCanonicalAssetHelpers(deps) {
|
|
|
93
93
|
throw new Error(`Attachment read failed from R2 (${attachmentContext}): ${message || 'Unknown object storage error'}`);
|
|
94
94
|
}
|
|
95
95
|
if (!object) {
|
|
96
|
-
throw new Error(`Attachment ${attachment.attachmentId} not found on
|
|
96
|
+
throw new Error(`Attachment ${attachment.attachmentId} not found on ${targetLabel} ${taskId}`);
|
|
97
97
|
}
|
|
98
98
|
return object.body;
|
|
99
99
|
}
|
|
100
100
|
const resolvedPath = path.resolve(deps.basePath, asset.storageKey);
|
|
101
101
|
if (!resolvedPath.startsWith(path.resolve(deps.basePath))) {
|
|
102
|
-
throw new Error(`Attachment ${attachment.attachmentId} not found on
|
|
102
|
+
throw new Error(`Attachment ${attachment.attachmentId} not found on ${targetLabel} ${taskId}`);
|
|
103
103
|
}
|
|
104
104
|
if (!fs.existsSync(resolvedPath) || !fs.statSync(resolvedPath).isFile()) {
|
|
105
|
-
throw new Error(`Attachment ${attachment.attachmentId} not found on
|
|
105
|
+
throw new Error(`Attachment ${attachment.attachmentId} not found on ${targetLabel} ${taskId}`);
|
|
106
106
|
}
|
|
107
107
|
return fs.readFileSync(resolvedPath);
|
|
108
108
|
};
|
|
@@ -189,12 +189,13 @@ export function createCanonicalAssetHelpers(deps) {
|
|
|
189
189
|
}
|
|
190
190
|
return null;
|
|
191
191
|
};
|
|
192
|
-
const
|
|
192
|
+
const ensureCanonicalAttachment = async (relativePathRaw, targetTypeRaw, targetIdRaw, captionRaw, timestampRaw, role, options) => {
|
|
193
193
|
if (!deps.workspaceAssetStore)
|
|
194
194
|
return null;
|
|
195
195
|
const relativePath = String(relativePathRaw || '').trim();
|
|
196
|
-
const
|
|
197
|
-
|
|
196
|
+
const targetType = String(targetTypeRaw || 'task').trim();
|
|
197
|
+
const targetId = String(targetIdRaw || '').trim();
|
|
198
|
+
if (!relativePath || !targetId)
|
|
198
199
|
return null;
|
|
199
200
|
const absolutePath = path.resolve(deps.projectRoot, relativePath);
|
|
200
201
|
if (!fs.existsSync(absolutePath) || !fs.statSync(absolutePath).isFile())
|
|
@@ -206,6 +207,10 @@ export function createCanonicalAssetHelpers(deps) {
|
|
|
206
207
|
const kind = deps.inferAssetKind(relativePath, mimeType);
|
|
207
208
|
const timestamp = String(timestampRaw || new Date().toISOString()).trim() || new Date().toISOString();
|
|
208
209
|
const existing = deps.workspaceAssetStore.getByStorageKey(storageKey, deps.activeWorkspaceId);
|
|
210
|
+
const shouldPersistToObjectStorage = typeof deps.objectStorageClient?.putObject === 'function';
|
|
211
|
+
if (shouldPersistToObjectStorage) {
|
|
212
|
+
await deps.objectStorageClient.putObject(storageKey, buffer, mimeType || 'application/octet-stream');
|
|
213
|
+
}
|
|
209
214
|
const originalFilename = deps.sanitizeFilenameForPath(options?.originalFilename || existing?.originalFilename || path.basename(relativePath));
|
|
210
215
|
const logicalName = deps.sanitizeDisplayName(options?.logicalName || existing?.logicalName || originalFilename, originalFilename);
|
|
211
216
|
const asset = deps.workspaceAssetStore.upsertAsset({
|
|
@@ -215,7 +220,7 @@ export function createCanonicalAssetHelpers(deps) {
|
|
|
215
220
|
logicalName,
|
|
216
221
|
originalFilename,
|
|
217
222
|
mimeType,
|
|
218
|
-
storageProvider: 'local',
|
|
223
|
+
storageProvider: shouldPersistToObjectStorage ? 'r2' : 'local',
|
|
219
224
|
storageKey,
|
|
220
225
|
contentSha256: createHash('sha256').update(buffer).digest('hex'),
|
|
221
226
|
sizeBytes: stats.size,
|
|
@@ -234,7 +239,8 @@ export function createCanonicalAssetHelpers(deps) {
|
|
|
234
239
|
deps.workspaceAssetStore.upsertLink({
|
|
235
240
|
workspaceId: deps.activeWorkspaceId,
|
|
236
241
|
assetId: asset.assetId,
|
|
237
|
-
|
|
242
|
+
targetType,
|
|
243
|
+
targetId,
|
|
238
244
|
role,
|
|
239
245
|
displayName: kind === 'document' ? null : (captionRaw || null),
|
|
240
246
|
updatedAt: timestamp,
|
|
@@ -242,6 +248,7 @@ export function createCanonicalAssetHelpers(deps) {
|
|
|
242
248
|
});
|
|
243
249
|
return asset;
|
|
244
250
|
};
|
|
251
|
+
const ensureCanonicalTaskAttachment = (relativePathRaw, taskIdRaw, captionRaw, timestampRaw, role, options) => ensureCanonicalAttachment(relativePathRaw, 'task', taskIdRaw, captionRaw, timestampRaw, role, options);
|
|
245
252
|
return {
|
|
246
253
|
normalizeAttachmentStorageKey,
|
|
247
254
|
buildSyntheticAttachmentId,
|
|
@@ -253,6 +260,7 @@ export function createCanonicalAssetHelpers(deps) {
|
|
|
253
260
|
toTaskAttachmentRecord,
|
|
254
261
|
resolveAttachmentLogicalFilename,
|
|
255
262
|
resolveCanonicalOverwriteTarget,
|
|
263
|
+
ensureCanonicalAttachment,
|
|
256
264
|
ensureCanonicalTaskAttachment,
|
|
257
265
|
buildCanonicalWorkspaceAssetRelativePath: deps.buildCanonicalWorkspaceAssetRelativePath,
|
|
258
266
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { TaskforceCore } from '../core/Taskforce';
|
|
6
|
+
import { createCanonicalAssetHelpers } from './canonicalAssetHelpers';
|
|
7
|
+
function makeCore() {
|
|
8
|
+
const projectRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'taskforce-mcp-canonical-assets-'));
|
|
9
|
+
const core = new TaskforceCore({
|
|
10
|
+
projectRoot,
|
|
11
|
+
storagePath: path.join(projectRoot, '.taskforce')
|
|
12
|
+
});
|
|
13
|
+
return {
|
|
14
|
+
projectRoot,
|
|
15
|
+
core,
|
|
16
|
+
cleanup: () => fs.rmSync(projectRoot, { recursive: true, force: true })
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
describe('MCP canonical asset helpers', () => {
|
|
20
|
+
it('uploads canonical attachments to object storage before recording durable cloud metadata', async () => {
|
|
21
|
+
const { projectRoot, core, cleanup } = makeCore();
|
|
22
|
+
try {
|
|
23
|
+
core.createWorkspace({ workspaceId: 'workspace-1', name: 'Workspace 1' });
|
|
24
|
+
const task = core.createTask({ title: 'Object-backed attachment' }, { workspaceId: 'workspace-1' });
|
|
25
|
+
const relativePath = '.taskforce/workspaces/workspace-1/assets/documents/asset-test-note.md';
|
|
26
|
+
const absolutePath = path.join(projectRoot, relativePath);
|
|
27
|
+
fs.mkdirSync(path.dirname(absolutePath), { recursive: true });
|
|
28
|
+
fs.writeFileSync(absolutePath, '# Stored in object storage\n', 'utf8');
|
|
29
|
+
const putObject = vi.fn(async () => { });
|
|
30
|
+
const helpers = createCanonicalAssetHelpers({
|
|
31
|
+
activeWorkspaceId: 'workspace-1',
|
|
32
|
+
projectRoot,
|
|
33
|
+
basePath: core.getPaths().basePath,
|
|
34
|
+
workspaceAssetStore: core.getWorkspaceAssetStore(),
|
|
35
|
+
objectStorageClient: {
|
|
36
|
+
getObject: vi.fn(async () => null),
|
|
37
|
+
putObject,
|
|
38
|
+
},
|
|
39
|
+
sanitizeFilenameForPath: (value, fallback = 'file.txt') => String(value || fallback).trim() || fallback,
|
|
40
|
+
sanitizeDisplayName: (value, fallback) => String(value || fallback).trim() || fallback,
|
|
41
|
+
toPosixPath: (value) => value.replace(/\\/g, '/'),
|
|
42
|
+
inferMimeTypeFromPath: (value) => value.endsWith('.md') ? 'text/markdown' : 'application/octet-stream',
|
|
43
|
+
inferAssetKind: (value, mimeType) => (value.endsWith('.md') || mimeType === 'text/markdown' ? 'document' : 'file'),
|
|
44
|
+
buildCanonicalWorkspaceAssetRelativePath: () => ({
|
|
45
|
+
assetId: 'asset-test-note',
|
|
46
|
+
relativePath: 'workspaces/workspace-1/assets/documents/asset-test-note.md'
|
|
47
|
+
})
|
|
48
|
+
});
|
|
49
|
+
const asset = await helpers.ensureCanonicalTaskAttachment(relativePath, task.id, 'note.md', '2026-04-27T01:00:00.000Z', 'attachment', { originalFilename: 'note.md', logicalName: 'note.md' });
|
|
50
|
+
expect(putObject).toHaveBeenCalledWith('workspaces/workspace-1/assets/documents/asset-test-note.md', Buffer.from('# Stored in object storage\n', 'utf8'), 'text/markdown');
|
|
51
|
+
expect(asset?.storageProvider).toBe('r2');
|
|
52
|
+
expect(core.getWorkspaceAssetStore().get(asset.assetId, 'workspace-1')?.storageProvider).toBe('r2');
|
|
53
|
+
expect(core.getWorkspaceAssetStore().listLinksForTask(task.id, 'workspace-1')).toEqual(expect.arrayContaining([
|
|
54
|
+
expect.objectContaining({
|
|
55
|
+
assetId: asset?.assetId,
|
|
56
|
+
targetType: 'task',
|
|
57
|
+
role: 'attachment',
|
|
58
|
+
deletedAt: null,
|
|
59
|
+
})
|
|
60
|
+
]));
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
core.close();
|
|
64
|
+
cleanup();
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -31,6 +31,7 @@ export interface CloudMcpClientIntegration {
|
|
|
31
31
|
serverConfig?: unknown;
|
|
32
32
|
renderedText?: string;
|
|
33
33
|
}
|
|
34
|
+
export declare function buildLocalAiProfileEnv(clientId: McpClientId): Record<string, string>;
|
|
34
35
|
export declare const MCP_CLIENT_OPTIONS: McpClientOption[];
|
|
35
36
|
export declare function sanitizeMcpId(value: string, fallback: string): string;
|
|
36
37
|
export declare function buildCloudMcpServerId(workspaceName?: string | null, projectName?: string | null): string;
|
|
@@ -1,4 +1,29 @@
|
|
|
1
1
|
import { buildAiProfileBootstrapHeaders } from './aiProfileBootstrap.js';
|
|
2
|
+
const LOCAL_AI_PROFILE_DEFAULTS = {
|
|
3
|
+
general: { name: 'Taskforce MCP Agent', icon: 'Bot', role: 'AI collaborator', provider: 'MCP client', model: 'Local MCP', surfaceType: 'agent' },
|
|
4
|
+
cursor: { name: 'Cursor', icon: 'Bot', role: 'IDE coding assistant', provider: 'Cursor', model: 'Cursor', surfaceType: 'ide' },
|
|
5
|
+
cline: { name: 'Cline', icon: 'Bot', role: 'IDE coding assistant', provider: 'Cline', model: 'Cline', surfaceType: 'ide' },
|
|
6
|
+
vscode: { name: 'VS Code Copilot', icon: 'Bot', role: 'IDE coding assistant', provider: 'Microsoft', model: 'Copilot', surfaceType: 'ide' },
|
|
7
|
+
windsurf: { name: 'Windsurf', icon: 'Bot', role: 'IDE coding assistant', provider: 'Windsurf', model: 'Windsurf', surfaceType: 'ide' },
|
|
8
|
+
antigravity: { name: 'Antigravity', icon: 'Bot', role: 'Coding agent', provider: 'Google', model: 'Antigravity', surfaceType: 'coding_tool' },
|
|
9
|
+
openclaw: { name: 'OpenClaw', icon: 'Bot', role: 'AI agent', provider: 'OpenClaw', model: 'OpenClaw', surfaceType: 'agent' },
|
|
10
|
+
codex: { name: 'Codex', icon: 'Bot', role: 'Coding agent', provider: 'OpenAI', model: 'Codex', surfaceType: 'cli' },
|
|
11
|
+
'claude-code': { name: 'Claude Code', icon: 'Bot', role: 'Coding agent', provider: 'Anthropic', model: 'Claude Code', surfaceType: 'cli' },
|
|
12
|
+
'gemini-cli': { name: 'Gemini CLI', icon: 'Bot', role: 'Coding agent', provider: 'Google', model: 'Gemini CLI', surfaceType: 'cli' },
|
|
13
|
+
'claude-desktop': { name: 'Claude Desktop', icon: 'Bot', role: 'Desktop AI collaborator', provider: 'Anthropic', model: 'Claude Desktop', surfaceType: 'chat_app' },
|
|
14
|
+
'chatgpt-desktop': { name: 'ChatGPT Desktop', icon: 'Bot', role: 'Desktop AI collaborator', provider: 'OpenAI', model: 'ChatGPT Desktop', surfaceType: 'chat_app' },
|
|
15
|
+
};
|
|
16
|
+
export function buildLocalAiProfileEnv(clientId) {
|
|
17
|
+
const defaults = LOCAL_AI_PROFILE_DEFAULTS[clientId] || LOCAL_AI_PROFILE_DEFAULTS.general;
|
|
18
|
+
return {
|
|
19
|
+
TASKFORCE_AI_NAME: defaults.name,
|
|
20
|
+
TASKFORCE_AI_ICON: defaults.icon,
|
|
21
|
+
TASKFORCE_AI_ROLE: defaults.role,
|
|
22
|
+
TASKFORCE_AI_PROVIDER: defaults.provider,
|
|
23
|
+
TASKFORCE_AI_MODEL: defaults.model,
|
|
24
|
+
TASKFORCE_AI_SURFACE_TYPE: defaults.surfaceType,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
2
27
|
export const MCP_CLIENT_OPTIONS = [
|
|
3
28
|
{ id: 'general', label: 'General' },
|
|
4
29
|
{ id: 'antigravity', label: 'Antigravity' },
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { MCP_CLIENT_OPTIONS, buildCloudMcpClientIntegration, buildLocalMcpClientIntegration, buildCloudMcpServerId, } from './clientIntegrations';
|
|
2
|
+
import { MCP_CLIENT_OPTIONS, buildCloudMcpClientIntegration, buildLocalMcpClientIntegration, buildCloudMcpServerId, buildLocalAiProfileEnv, } from './clientIntegrations';
|
|
3
3
|
describe('clientIntegrations', () => {
|
|
4
4
|
it('builds a readable cloud MCP server id from workspace name', () => {
|
|
5
5
|
expect(buildCloudMcpServerId('Workspace Alpha', null)).toBe('taskforce-workspace-alpha');
|
|
@@ -78,7 +78,7 @@ describe('clientIntegrations', () => {
|
|
|
78
78
|
aiProfileRole: 'Coding Agent',
|
|
79
79
|
aiProfileProvider: 'OpenAI',
|
|
80
80
|
aiProfileModel: 'Codex',
|
|
81
|
-
aiProfileSurfaceType: '
|
|
81
|
+
aiProfileSurfaceType: 'cli',
|
|
82
82
|
});
|
|
83
83
|
const vscode = buildCloudMcpClientIntegration({
|
|
84
84
|
clientId: 'vscode',
|
|
@@ -98,7 +98,7 @@ describe('clientIntegrations', () => {
|
|
|
98
98
|
expect(codex.renderedText).toContain('X-Taskforce-AI-Role = "Coding Agent"');
|
|
99
99
|
expect(codex.renderedText).toContain('X-Taskforce-AI-Provider = "OpenAI"');
|
|
100
100
|
expect(codex.renderedText).toContain('X-Taskforce-AI-Model = "Codex"');
|
|
101
|
-
expect(codex.renderedText).toContain('X-Taskforce-AI-Surface-Type = "
|
|
101
|
+
expect(codex.renderedText).toContain('X-Taskforce-AI-Surface-Type = "cli"');
|
|
102
102
|
expect(codex.instructionText).toContain('Use the generated config exactly as shown.');
|
|
103
103
|
expect(codex.instructionText).toContain('generated AI bootstrap headers');
|
|
104
104
|
expect(vscode.serverConfig).toEqual({
|
|
@@ -180,6 +180,17 @@ describe('clientIntegrations', () => {
|
|
|
180
180
|
expect(integration.renderedText).toContain('TASKFORCE_TENANT_ID = "tenant-alpha"');
|
|
181
181
|
expect(integration.renderedText).not.toContain('Authorization');
|
|
182
182
|
});
|
|
183
|
+
it('builds non-secret local AI profile env metadata for stdio clients', () => {
|
|
184
|
+
expect(buildLocalAiProfileEnv('codex')).toEqual({
|
|
185
|
+
TASKFORCE_AI_NAME: 'Codex',
|
|
186
|
+
TASKFORCE_AI_ICON: 'Bot',
|
|
187
|
+
TASKFORCE_AI_ROLE: 'Coding agent',
|
|
188
|
+
TASKFORCE_AI_PROVIDER: 'OpenAI',
|
|
189
|
+
TASKFORCE_AI_MODEL: 'Codex',
|
|
190
|
+
TASKFORCE_AI_SURFACE_TYPE: 'cli',
|
|
191
|
+
});
|
|
192
|
+
expect(buildLocalAiProfileEnv('codex')).not.toHaveProperty('TASKFORCE_AI_PROFILE_TOKEN');
|
|
193
|
+
});
|
|
183
194
|
it('builds local VS Code config with stdio transport', () => {
|
|
184
195
|
const integration = buildLocalMcpClientIntegration({
|
|
185
196
|
clientId: 'vscode',
|
|
@@ -7,15 +7,15 @@ const CLIENT_LABELS = {
|
|
|
7
7
|
export function getDefaultAiProfileMetadataForClient(clientId) {
|
|
8
8
|
switch (clientId) {
|
|
9
9
|
case 'codex':
|
|
10
|
-
return { icon: 'Code2', color: '#10a37f', description: 'OpenAI Codex coding agent connected through MCP.', role: 'Coding Agent', provider: 'OpenAI', model: 'Codex', surfaceType: '
|
|
10
|
+
return { icon: 'Code2', color: '#10a37f', description: 'OpenAI Codex CLI coding agent connected through MCP.', role: 'CLI Coding Agent', provider: 'OpenAI', model: 'Codex', surfaceType: 'cli' };
|
|
11
11
|
case 'chatgpt-desktop':
|
|
12
12
|
return { icon: 'MessageSquare', color: '#10a37f', description: 'ChatGPT desktop app connected through the Taskforce MCP connector.', role: 'AI Assistant', provider: 'OpenAI', model: 'ChatGPT', surfaceType: 'chat_app' };
|
|
13
13
|
case 'claude-code':
|
|
14
|
-
return { icon: 'Sparkles', color: '#d97706', description: 'Claude Code coding agent connected through MCP.', role: 'Coding Agent', provider: 'Anthropic', model: 'Claude Code', surfaceType: '
|
|
14
|
+
return { icon: 'Sparkles', color: '#d97706', description: 'Claude Code CLI coding agent connected through MCP.', role: 'CLI Coding Agent', provider: 'Anthropic', model: 'Claude Code', surfaceType: 'cli' };
|
|
15
15
|
case 'claude-desktop':
|
|
16
16
|
return { icon: 'MessageSquareMore', color: '#d97706', description: 'Claude Desktop connected through the Taskforce MCP connector.', role: 'AI Assistant', provider: 'Anthropic', model: 'Claude', surfaceType: 'chat_app' };
|
|
17
17
|
case 'gemini-cli':
|
|
18
|
-
return { icon: 'Gem', color: '#2563eb', description: 'Gemini CLI coding agent connected through MCP.', role: 'Coding Agent', provider: 'Google', model: 'Gemini', surfaceType: '
|
|
18
|
+
return { icon: 'Gem', color: '#2563eb', description: 'Gemini CLI coding agent connected through MCP.', role: 'CLI Coding Agent', provider: 'Google', model: 'Gemini', surfaceType: 'cli' };
|
|
19
19
|
case 'vscode':
|
|
20
20
|
return { icon: 'Code2', color: '#2563eb', description: 'VS Code MCP-connected coding agent.', role: 'Coding Agent', provider: null, model: null, surfaceType: 'ide' };
|
|
21
21
|
case 'cline':
|
|
@@ -27,15 +27,15 @@ export function registerCollaborationTools(registerTool, executeTool) {
|
|
|
27
27
|
inputSchema: { properties: {} },
|
|
28
28
|
}));
|
|
29
29
|
register('get_current_profile', (context) => ({
|
|
30
|
-
description: context.describeTool('Inspect the effective AI profile for this session. Use this when an agent needs to know its current profile id before filtering for tasks assigned to itself. If no profile is currently bound, this tool explains how to bootstrap with resolve_profile. You may also pass profileToken to inspect a stateless AI profile without mutating session state. The response includes
|
|
30
|
+
description: context.describeTool('Inspect the effective AI profile for this session. Use this when an agent needs to know its current profile id before filtering for tasks assigned to itself. If no profile is currently bound, this tool explains how to bootstrap with resolve_profile. You may also pass your own profileToken to inspect a stateless AI profile without mutating session state. The response includes your profileToken only for private agent/client storage; do not write it to repos, task comments, task attachments, logs, generated docs, or shared output.'),
|
|
31
31
|
inputSchema: {
|
|
32
32
|
properties: {
|
|
33
|
-
profileToken: stringProperty('Optional AI profile token to inspect when no profile is currently bound in session state.'),
|
|
33
|
+
profileToken: stringProperty('Optional AI profile token to inspect when no profile is currently bound in session state. Pass only a token previously issued to this AI identity.'),
|
|
34
34
|
},
|
|
35
35
|
},
|
|
36
36
|
}));
|
|
37
37
|
register('resolve_profile', (context) => ({
|
|
38
|
-
description: context.describeTool('Resolve or create the current AI collaborator profile for this workspace. On first bootstrap, omit profileToken and Taskforce will create a named AI profile, issue a stable profileToken, and return the profile id to use in assignee, createdBy, and comment author fields on later calls. When a valid profileToken is provided, Taskforce resolves the existing profile and updates any supplied presentation fields such as name, icon, color, description, role, provider, model, and surfaceType. Update semantics: omitted optional fields leave existing stored values unchanged. For description, role, provider, and model, empty strings are ignored rather than clearing. For surfaceType, null or an empty string clears the stored value; valid enum values replace it.'),
|
|
38
|
+
description: context.describeTool('Resolve or create the current AI collaborator profile for this workspace. On first bootstrap, omit profileToken and Taskforce will create a named AI profile, issue a stable profileToken, and return the profile id to use in assignee, createdBy, and comment author fields on later calls. Store the returned profileToken only in private agent/client state and include it on future mutating calls when your MCP client does not preserve session identity. Never write profileToken values to repos, task comments, task attachments, logs, generated docs, or shared output. When a valid profileToken is provided, Taskforce resolves the existing profile and updates any supplied presentation fields such as name, icon, color, description, role, provider, model, and surfaceType. Update semantics: omitted optional fields leave existing stored values unchanged. For description, role, provider, and model, empty strings are ignored rather than clearing. For surfaceType, null or an empty string clears the stored value; valid enum values replace it.'),
|
|
39
39
|
inputSchema: {
|
|
40
40
|
properties: {
|
|
41
41
|
name: stringProperty('Display name for the AI collaborator.'),
|
|
@@ -50,9 +50,9 @@ export function registerCollaborationTools(registerTool, executeTool) {
|
|
|
50
50
|
{ type: 'string', enum: [...AI_PROFILE_SURFACE_TYPES] },
|
|
51
51
|
{ type: 'null' },
|
|
52
52
|
],
|
|
53
|
-
description: 'Optional self-declared AI surface type. Use agent for a persistent named AI collaborator in Taskforce,
|
|
53
|
+
description: 'Optional self-declared AI surface type. Use agent for a persistent named AI collaborator in Taskforce, cli for terminal-native coding agents, coding_tool for coding surfaces that are not specifically CLI or IDE-native, chat_app for a conversational app identity, and ide for an IDE-native copilot identity. If you are unsure or none of those fit, choose agent. Omit to leave unchanged; pass null or an empty string to clear.',
|
|
54
54
|
},
|
|
55
|
-
profileToken: stringProperty('Previously issued Taskforce profile token.
|
|
55
|
+
profileToken: stringProperty('Previously issued Taskforce profile token for this AI identity. Keep it in private agent/client state; when provided, Taskforce resolves the existing profile instead of creating a new one, and applies any supplied presentation field updates to that profile.'),
|
|
56
56
|
},
|
|
57
57
|
required: ['name'],
|
|
58
58
|
},
|
|
@@ -63,9 +63,9 @@ export function registerCollaborationTools(registerTool, executeTool) {
|
|
|
63
63
|
properties: {
|
|
64
64
|
id: stringProperty('Task ID or task reference such as T-123.'),
|
|
65
65
|
text: stringProperty('Comment text.'),
|
|
66
|
-
author: stringProperty('
|
|
66
|
+
author: stringProperty('Optional comment author identity. Defaults to your resolved AI profile. Prefer stable actor IDs for overrides (`ai-profile-*`, workspace user IDs, `user`, `system`). Display names are not authoritative and may be canonicalized back to the bound actor; use `user` only for human-authored comments.'),
|
|
67
67
|
},
|
|
68
|
-
required: ['id', 'text'
|
|
68
|
+
required: ['id', 'text'],
|
|
69
69
|
},
|
|
70
70
|
}));
|
|
71
71
|
}
|
|
@@ -35,8 +35,8 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
35
35
|
inputSchema: {
|
|
36
36
|
properties: {
|
|
37
37
|
taskId: stringProperty('Task ID or task reference such as T-123.'),
|
|
38
|
+
id: stringProperty('Alias for taskId. Task ID or task reference such as T-123.'),
|
|
38
39
|
},
|
|
39
|
-
required: ['taskId'],
|
|
40
40
|
},
|
|
41
41
|
}));
|
|
42
42
|
register('read_task_attachment', (context) => ({
|
|
@@ -50,6 +50,96 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
50
50
|
required: ['taskId', 'attachmentId'],
|
|
51
51
|
},
|
|
52
52
|
}));
|
|
53
|
+
register('get_workstream_attachments', (context) => ({
|
|
54
|
+
description: context.describeTool('List attachment descriptors for one workstream. This returns metadata only; use read_workstream_attachment for file contents.'),
|
|
55
|
+
inputSchema: {
|
|
56
|
+
properties: {
|
|
57
|
+
id: stringProperty('Workstream ID or workstream reference such as WS-123.'),
|
|
58
|
+
},
|
|
59
|
+
required: ['id'],
|
|
60
|
+
},
|
|
61
|
+
}));
|
|
62
|
+
register('read_workstream_attachment', (context) => ({
|
|
63
|
+
description: context.describeTool('Read one workstream attachment by attachmentId. Prefer this tool over opening attachment path URLs directly.'),
|
|
64
|
+
inputSchema: {
|
|
65
|
+
properties: {
|
|
66
|
+
workstreamId: stringProperty('Workstream ID or workstream reference such as WS-123.'),
|
|
67
|
+
attachmentId: stringProperty('Attachment descriptor id from get_workstream_attachments.'),
|
|
68
|
+
format: stringProperty('Read format. Use metadata for descriptors or download for a download URL.', ['text', 'metadata', 'download']),
|
|
69
|
+
maxChars: numberProperty('Optional max inline character count for readable text attachments.'),
|
|
70
|
+
},
|
|
71
|
+
required: ['workstreamId', 'attachmentId'],
|
|
72
|
+
},
|
|
73
|
+
}));
|
|
74
|
+
register('save_workstream_attachment', (context) => ({
|
|
75
|
+
description: context.describeTool('Save a file and attach it to a workstream. Use this for generated content or existing files from disk. Set overwrite=true to replace an existing canonical attachment with the same filename.'),
|
|
76
|
+
inputSchema: {
|
|
77
|
+
properties: {
|
|
78
|
+
id: stringProperty('Workstream ID or workstream reference such as WS-123.'),
|
|
79
|
+
filename: stringProperty('Destination filename for the attachment.'),
|
|
80
|
+
content: stringProperty('Inline file content; use this for AI-authored markdown/text attachments.'),
|
|
81
|
+
sourcePath: stringProperty('Path to an existing source file. Must be within project root, a Taskforce-managed attachment source, or an approved agent workspace root.'),
|
|
82
|
+
caption: stringProperty('Optional attachment caption.'),
|
|
83
|
+
overwrite: booleanProperty('When true, overwrite an existing canonical workstream attachment with the same filename instead of creating a new one.'),
|
|
84
|
+
},
|
|
85
|
+
required: ['id', 'filename'],
|
|
86
|
+
},
|
|
87
|
+
}));
|
|
88
|
+
register('delete_workstream_attachment', (context) => ({
|
|
89
|
+
description: context.describeTool('Delete one workstream attachment. Use get_workstream_attachments first to inspect attachment ids before removing one.'),
|
|
90
|
+
inputSchema: {
|
|
91
|
+
properties: {
|
|
92
|
+
workstreamId: stringProperty('Workstream ID or workstream reference such as WS-123.'),
|
|
93
|
+
attachmentId: stringProperty('Attachment descriptor id from get_workstream_attachments.'),
|
|
94
|
+
},
|
|
95
|
+
required: ['workstreamId', 'attachmentId'],
|
|
96
|
+
},
|
|
97
|
+
}));
|
|
98
|
+
register('get_initiative_attachments', (context) => ({
|
|
99
|
+
description: context.describeTool('List attachment descriptors for one initiative. This returns metadata only; use read_initiative_attachment for file contents.'),
|
|
100
|
+
inputSchema: {
|
|
101
|
+
properties: {
|
|
102
|
+
id: stringProperty('Initiative ID or initiative reference such as IN-123.'),
|
|
103
|
+
},
|
|
104
|
+
required: ['id'],
|
|
105
|
+
},
|
|
106
|
+
}));
|
|
107
|
+
register('read_initiative_attachment', (context) => ({
|
|
108
|
+
description: context.describeTool('Read one initiative attachment by attachmentId. Prefer this tool over opening attachment path URLs directly.'),
|
|
109
|
+
inputSchema: {
|
|
110
|
+
properties: {
|
|
111
|
+
initiativeId: stringProperty('Initiative ID or initiative reference such as IN-123.'),
|
|
112
|
+
attachmentId: stringProperty('Attachment descriptor id from get_initiative_attachments.'),
|
|
113
|
+
format: stringProperty('Read format. Use metadata for descriptors or download for a download URL.', ['text', 'metadata', 'download']),
|
|
114
|
+
maxChars: numberProperty('Optional max inline character count for readable text attachments.'),
|
|
115
|
+
},
|
|
116
|
+
required: ['initiativeId', 'attachmentId'],
|
|
117
|
+
},
|
|
118
|
+
}));
|
|
119
|
+
register('save_initiative_attachment', (context) => ({
|
|
120
|
+
description: context.describeTool('Save a file and attach it to an initiative. Use this for generated content or existing files from disk. Set overwrite=true to replace an existing canonical attachment with the same filename.'),
|
|
121
|
+
inputSchema: {
|
|
122
|
+
properties: {
|
|
123
|
+
id: stringProperty('Initiative ID or initiative reference such as IN-123.'),
|
|
124
|
+
filename: stringProperty('Destination filename for the attachment.'),
|
|
125
|
+
content: stringProperty('Inline file content; use this for AI-authored markdown/text attachments.'),
|
|
126
|
+
sourcePath: stringProperty('Path to an existing source file. Must be within project root, a Taskforce-managed attachment source, or an approved agent workspace root.'),
|
|
127
|
+
caption: stringProperty('Optional attachment caption.'),
|
|
128
|
+
overwrite: booleanProperty('When true, overwrite an existing canonical initiative attachment with the same filename instead of creating a new one.'),
|
|
129
|
+
},
|
|
130
|
+
required: ['id', 'filename'],
|
|
131
|
+
},
|
|
132
|
+
}));
|
|
133
|
+
register('delete_initiative_attachment', (context) => ({
|
|
134
|
+
description: context.describeTool('Delete one initiative attachment. Use get_initiative_attachments first to inspect attachment ids before removing one.'),
|
|
135
|
+
inputSchema: {
|
|
136
|
+
properties: {
|
|
137
|
+
initiativeId: stringProperty('Initiative ID or initiative reference such as IN-123.'),
|
|
138
|
+
attachmentId: stringProperty('Attachment descriptor id from get_initiative_attachments.'),
|
|
139
|
+
},
|
|
140
|
+
required: ['initiativeId', 'attachmentId'],
|
|
141
|
+
},
|
|
142
|
+
}));
|
|
53
143
|
register('search_images', (context) => ({
|
|
54
144
|
description: context.describeTool('Search image assets by keyword, title, filename, caption, or I-123 reference. Use this before get_image when you only know a rough identifier.'),
|
|
55
145
|
inputSchema: {
|
|
@@ -61,12 +151,12 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
61
151
|
},
|
|
62
152
|
}));
|
|
63
153
|
register('get_image', (context) => ({
|
|
64
|
-
description: context.describeTool('Get a single image by asset id or image reference such as I-123. Use this first when the user references an image, then use get_annotated_attachment_sessions and read_annotated_attachment_payload for annotation details.'),
|
|
154
|
+
description: context.describeTool('Get a single image by asset id or image reference such as I-123. Use this first when the user references an image, then use get_annotated_attachment_sessions and read_annotated_attachment_payload for annotation details. When the image is being used for UI, placement, or visual correction feedback, read the saved annotation payload before making changes.'),
|
|
65
155
|
inputSchema: {
|
|
66
156
|
properties: {
|
|
67
157
|
id: stringProperty('Image asset id or image reference such as I-123.'),
|
|
158
|
+
imageId: stringProperty('Alias for id. Image asset id or image reference such as I-123.'),
|
|
68
159
|
},
|
|
69
|
-
required: ['id'],
|
|
70
160
|
},
|
|
71
161
|
}));
|
|
72
162
|
register('search_documents', (context) => ({
|
|
@@ -84,8 +174,8 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
84
174
|
inputSchema: {
|
|
85
175
|
properties: {
|
|
86
176
|
id: stringProperty('Document asset id or document reference such as D-123.'),
|
|
177
|
+
documentId: stringProperty('Alias for id. Document asset id or document reference such as D-123.'),
|
|
87
178
|
},
|
|
88
|
-
required: ['id'],
|
|
89
179
|
},
|
|
90
180
|
}));
|
|
91
181
|
register('read_document_content', (context) => ({
|
|
@@ -99,7 +189,7 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
99
189
|
},
|
|
100
190
|
}));
|
|
101
191
|
register('get_annotated_attachment_sessions', (context) => ({
|
|
102
|
-
description: context.describeTool('List saved annotation sessions for one image. Use this after get_image when you need the saved annotation sessions before opening one payload.'),
|
|
192
|
+
description: context.describeTool('List saved annotation sessions for one image. Use this after get_image when you need the saved annotation sessions before opening one payload. If the user is pointing at a visual target in I-123, do not stop at the screenshot alone; inspect the saved session payload next.'),
|
|
103
193
|
inputSchema: {
|
|
104
194
|
properties: {
|
|
105
195
|
imageId: stringProperty('Image asset id or image reference such as I-123.'),
|
|
@@ -108,7 +198,7 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
108
198
|
},
|
|
109
199
|
}));
|
|
110
200
|
register('read_annotated_attachment_payload', (context) => ({
|
|
111
|
-
description: context.describeTool('Read the structured payload for one annotated attachment session, including markers, geometry, and derived crop hints.'),
|
|
201
|
+
description: context.describeTool('Read the structured payload for one annotated attachment session, including markers, geometry, and derived crop hints. Use this as the authoritative instruction source when I-123 is being used for UI placement or visual change requests.'),
|
|
112
202
|
inputSchema: {
|
|
113
203
|
properties: {
|
|
114
204
|
sessionId: stringProperty('Annotated attachment session id.'),
|
|
@@ -161,13 +251,14 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
161
251
|
properties: {
|
|
162
252
|
sessionId: stringProperty('Annotated attachment session id.'),
|
|
163
253
|
type: stringProperty('Marker type.'),
|
|
254
|
+
kind: stringProperty('Alias for type. Marker kind: pin, box, arrow, or text-note.'),
|
|
164
255
|
x: numberProperty('Normalized x coordinate in the 0..1 range.'),
|
|
165
256
|
y: numberProperty('Normalized y coordinate in the 0..1 range.'),
|
|
166
257
|
width: numberProperty('Optional normalized width in the 0..1 range.'),
|
|
167
258
|
height: numberProperty('Optional normalized height in the 0..1 range.'),
|
|
168
259
|
text: stringProperty('Optional marker text or note.'),
|
|
260
|
+
instruction: stringProperty('Alias for text. Marker instruction or note.'),
|
|
169
261
|
},
|
|
170
|
-
required: ['sessionId', 'type', 'x', 'y'],
|
|
171
262
|
},
|
|
172
263
|
}));
|
|
173
264
|
register('bulk_add_annotated_attachment_markers', (context) => ({
|
|
@@ -179,13 +270,14 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
179
270
|
type: 'object',
|
|
180
271
|
properties: {
|
|
181
272
|
type: { type: 'string' },
|
|
273
|
+
kind: { type: 'string' },
|
|
182
274
|
x: { type: 'number' },
|
|
183
275
|
y: { type: 'number' },
|
|
184
276
|
width: { type: 'number' },
|
|
185
277
|
height: { type: 'number' },
|
|
186
278
|
text: { type: 'string' },
|
|
279
|
+
instruction: { type: 'string' },
|
|
187
280
|
},
|
|
188
|
-
required: ['type', 'x', 'y'],
|
|
189
281
|
}),
|
|
190
282
|
},
|
|
191
283
|
required: ['sessionId', 'markers'],
|
|
@@ -273,9 +365,19 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
273
365
|
inputSchema: {
|
|
274
366
|
properties: {
|
|
275
367
|
documentId: stringProperty('Document asset id or document reference such as D-123.'),
|
|
368
|
+
id: stringProperty('Alias for documentId. Document asset id or document reference such as D-123.'),
|
|
369
|
+
sessionId: stringProperty('Optional existing review session id.'),
|
|
370
|
+
title: stringProperty('Optional review session title when a new session is created.'),
|
|
276
371
|
prompt: stringProperty('Review instructions or focus areas.'),
|
|
372
|
+
comments: arrayProperty('Explicit review comments to add. When omitted, prompt is saved as a single review comment.', {
|
|
373
|
+
type: 'object',
|
|
374
|
+
properties: {
|
|
375
|
+
body: { type: 'string' },
|
|
376
|
+
anchor: { type: 'object' },
|
|
377
|
+
},
|
|
378
|
+
required: ['body'],
|
|
379
|
+
}),
|
|
277
380
|
},
|
|
278
|
-
required: ['documentId', 'prompt'],
|
|
279
381
|
},
|
|
280
382
|
}));
|
|
281
383
|
register('add_document_review_comment', (context) => ({
|
|
@@ -320,13 +422,17 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
320
422
|
},
|
|
321
423
|
}));
|
|
322
424
|
register('save_task_attachment', (context) => ({
|
|
323
|
-
description: context.describeTool('Save a file and attach it to a task. Use this for generated content
|
|
425
|
+
description: context.describeTool('Save a file and attach it to a task. Use this for generated content, existing files from disk, or staged remote uploads for binary files in cloud MCP. Set overwrite=true to replace an existing canonical attachment with the same filename. For AI-authored markdown/text, use inline content for AI-authored markdown/text rather than writing an external temp file first.'),
|
|
324
426
|
inputSchema: {
|
|
325
427
|
properties: {
|
|
326
428
|
id: stringProperty('Task ID or task reference such as T-123.'),
|
|
327
429
|
filename: stringProperty('Destination filename for the attachment.'),
|
|
328
430
|
content: stringProperty('Inline file content; use this for AI-authored markdown/text attachments.'),
|
|
329
431
|
sourcePath: stringProperty('Path to an existing source file. Must be within project root, a Taskforce-managed attachment source, or an approved agent workspace root.'),
|
|
432
|
+
uploadedPath: stringProperty('Finalize a previously staged remote upload by passing the uploaded Taskforce storage path returned by save_task_attachment init mode.'),
|
|
433
|
+
uploadDraftId: stringProperty('Finalize a previously staged remote upload by passing the uploadDraftId returned by save_task_attachment init mode.'),
|
|
434
|
+
mimeType: stringProperty('Mime type for staged remote uploads such as image/png or image/jpeg. Provide this with sizeBytes to start a staged upload.'),
|
|
435
|
+
sizeBytes: numberProperty('File size in bytes for staged remote uploads. Provide this with mimeType to start a staged upload.'),
|
|
330
436
|
caption: stringProperty('Optional attachment caption.'),
|
|
331
437
|
overwrite: booleanProperty('When true, overwrite an existing canonical task attachment with the same filename instead of creating a new one.'),
|
|
332
438
|
},
|
package/dist/mcp/runtime.d.ts
CHANGED
|
@@ -2,10 +2,12 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
|
2
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
3
|
import { McpAccessTokenScope, TaskforceCore } from '../core/Taskforce.js';
|
|
4
4
|
import { type AiProfileBootstrapConfig } from './aiProfileBootstrap.js';
|
|
5
|
+
import { type AiProfileSeatScope } from '../shared/aiProfileSeatScope.js';
|
|
5
6
|
export interface TaskforceMcpServerOptions {
|
|
6
7
|
projectRoot?: string;
|
|
7
8
|
tenantId?: string;
|
|
8
9
|
workspaceId?: string;
|
|
10
|
+
core?: TaskforceCore;
|
|
9
11
|
serverName?: string;
|
|
10
12
|
version?: string;
|
|
11
13
|
logStartup?: boolean;
|
|
@@ -23,6 +25,7 @@ export interface TaskforceMcpServerOptions {
|
|
|
23
25
|
aiProfileProvider?: AiProfileBootstrapConfig['aiProfileProvider'];
|
|
24
26
|
aiProfileModel?: AiProfileBootstrapConfig['aiProfileModel'];
|
|
25
27
|
aiProfileSurfaceType?: AiProfileBootstrapConfig['aiProfileSurfaceType'];
|
|
28
|
+
aiProfileSeatScope?: AiProfileSeatScope | null;
|
|
26
29
|
actorType?: 'local' | 'user' | 'token' | 'oauth';
|
|
27
30
|
requestId?: string | null;
|
|
28
31
|
ip?: string | null;
|