@taskforcehq/taskforce 0.3.305 → 0.3.306
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Taskforce.module.css +295 -89
- package/dist/TaskforceCore.js +215 -43
- package/dist/TaskforceCore.test.js +433 -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/context/ContextAttachmentManager.d.ts +14 -0
- package/dist/components/context/ContextAttachmentManager.js +549 -0
- package/dist/components/features/AgentsModule.d.ts +10 -1
- package/dist/components/features/AgentsModule.js +260 -15
- package/dist/components/features/AgentsModule.test.js +255 -5
- package/dist/components/features/DocumentViewer.d.ts +5 -1
- package/dist/components/features/DocumentViewer.js +60 -3
- package/dist/components/features/DocumentWorkspace.js +1 -1
- package/dist/components/features/DocumentWorkspace.test.js +33 -0
- package/dist/components/features/documentWorkspaceModel.d.ts +1 -1
- package/dist/components/task/TaskCard.js +19 -28
- package/dist/components/task/TaskCard.test.js +38 -3
- package/dist/components/task/TaskContextUpload.js +4 -526
- package/dist/components/task/TaskForm.js +85 -90
- 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 -13
- package/dist/components/task/TaskKanban.test.js +36 -0
- package/dist/components/ui/EditableAvatarButton.d.ts +18 -0
- package/dist/components/ui/EditableAvatarButton.js +18 -0
- package/dist/components/views/PlanComparisonPage.d.ts +9 -1
- package/dist/components/views/PlanComparisonPage.js +70 -14
- package/dist/components/views/PlanComparisonPage.test.js +238 -0
- package/dist/components/views/PlansPage.js +127 -36
- package/dist/components/views/PlansPage.test.js +294 -12
- package/dist/components/views/StandaloneLayout.js +283 -533
- package/dist/components/views/panels/PlanningDrawer.d.ts +8 -1
- package/dist/components/views/panels/PlanningDrawer.js +18 -11
- package/dist/components/views/panels/PlanningDrawer.test.d.ts +1 -0
- package/dist/components/views/panels/PlanningDrawer.test.js +141 -0
- package/dist/components/views/planningScope.d.ts +20 -0
- package/dist/components/views/planningScope.js +25 -0
- package/dist/components/views/planningScope.test.d.ts +1 -0
- package/dist/components/views/planningScope.test.js +60 -0
- package/dist/components/views/standalone/modals/AccountHubModal.d.ts +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/core/AiProfileService.d.ts +39 -2
- package/dist/core/AiProfileService.js +639 -73
- package/dist/core/AiProfileService.test.js +19 -1
- package/dist/core/AiProfiles.test.js +566 -7
- package/dist/core/AttachmentLinkService.js +57 -15
- package/dist/core/AuthIdentityService.d.ts +107 -0
- package/dist/core/AuthIdentityService.js +284 -0
- package/dist/core/AuthTokenService.d.ts +4 -0
- package/dist/core/AuthTokenService.js +34 -6
- package/dist/core/AuthTokenService.test.js +3 -3
- package/dist/core/EntitlementsPolicy.test.js +2 -2
- package/dist/core/GlobalSettingsService.js +115 -6
- 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 +52 -0
- 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/TaskAttachmentsCanonical.test.js +51 -1
- package/dist/core/Taskforce.d.ts +225 -14
- package/dist/core/Taskforce.js +765 -192
- package/dist/core/Taskforce.listTasksSlim.test.d.ts +1 -0
- package/dist/core/Taskforce.listTasksSlim.test.js +91 -0
- package/dist/core/UserProfileAvatarDrafts.test.js +30 -3
- package/dist/core/WorkspaceLifecycleService.js +0 -5
- package/dist/core/WorkspacePermissions.test.js +25 -1
- package/dist/core/WorkspacePlanMode.test.js +117 -16
- package/dist/core/shared.d.ts +1 -1
- package/dist/core/shared.js +5 -1
- package/dist/core/types.d.ts +68 -2
- package/dist/hooks/auth/useTaskforceAuthBootstrap.js +26 -1
- package/dist/hooks/sync/bootstrap.js +2 -0
- package/dist/hooks/sync/controlPlane.d.ts +37 -0
- package/dist/hooks/sync/controlPlane.js +78 -0
- package/dist/hooks/sync/controlPlane.test.d.ts +1 -0
- package/dist/hooks/sync/controlPlane.test.js +121 -0
- package/dist/hooks/sync/lifecyclePolicy.d.ts +45 -0
- package/dist/hooks/sync/lifecyclePolicy.js +93 -0
- package/dist/hooks/sync/lifecyclePolicy.test.d.ts +1 -0
- package/dist/hooks/sync/lifecyclePolicy.test.js +124 -0
- package/dist/hooks/sync/orchestratorShared.d.ts +10 -1
- package/dist/hooks/sync/orchestratorShared.js +68 -47
- package/dist/hooks/sync/orchestratorShared.test.js +50 -1
- package/dist/hooks/sync/pullLifecycle.d.ts +31 -0
- package/dist/hooks/sync/pullLifecycle.js +24 -0
- package/dist/hooks/sync/pullLifecycle.test.d.ts +1 -0
- package/dist/hooks/sync/pullLifecycle.test.js +80 -0
- package/dist/hooks/sync/recovery.d.ts +16 -2
- package/dist/hooks/sync/recovery.js +171 -53
- package/dist/hooks/sync/recovery.test.d.ts +1 -0
- package/dist/hooks/sync/recovery.test.js +292 -0
- package/dist/hooks/sync/transfers.d.ts +15 -3
- package/dist/hooks/sync/transfers.js +179 -62
- package/dist/hooks/sync/transfers.test.d.ts +1 -0
- package/dist/hooks/sync/transfers.test.js +396 -0
- package/dist/hooks/sync/useRecentSyncEvents.d.ts +21 -0
- package/dist/hooks/sync/useRecentSyncEvents.js +92 -0
- package/dist/hooks/sync/useRecentSyncEvents.test.d.ts +1 -0
- package/dist/hooks/sync/useRecentSyncEvents.test.js +124 -0
- package/dist/hooks/sync/useSyncStatusActions.d.ts +30 -0
- package/dist/hooks/sync/useSyncStatusActions.js +88 -0
- package/dist/hooks/sync/useSyncStatusActions.test.d.ts +1 -0
- package/dist/hooks/sync/useSyncStatusActions.test.js +133 -0
- package/dist/hooks/sync/useSyncStatusControls.d.ts +25 -0
- package/dist/hooks/sync/useSyncStatusControls.js +60 -0
- package/dist/hooks/sync/useSyncStatusControls.test.d.ts +1 -0
- package/dist/hooks/sync/useSyncStatusControls.test.js +88 -0
- package/dist/hooks/useSyncOrchestrator.aiProfiles.test.js +12 -0
- package/dist/hooks/useSyncOrchestrator.d.ts +9 -2
- package/dist/hooks/useSyncOrchestrator.js +359 -178
- 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 +60 -2
- package/dist/hooks/useTaskforce.js +549 -240
- package/dist/hooks/useTaskforce.runtime-routing.test.d.ts +1 -0
- package/dist/hooks/useTaskforce.runtime-routing.test.js +152 -0
- package/dist/hooks/useTaskforce.sync-behavior.test.js +2380 -212
- package/dist/hooks/useWorkspaceSyncController.d.ts +1 -0
- package/dist/hooks/useWorkspaceSyncController.js +6 -1
- package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.d.ts +16 -0
- package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +316 -35
- package/dist/localization/locales/en-US.d.ts +0 -1
- package/dist/localization/locales/en-US.js +0 -1
- package/dist/localization/locales/es-419.js +0 -1
- package/dist/localization/locales/pt-BR.js +0 -1
- package/dist/mcp/documentAssetRegistrar.js +3 -3
- package/dist/mcp/runtime.d.ts +2 -0
- package/dist/mcp/runtime.js +131 -64
- package/dist/mcp/runtime.test.js +291 -12
- package/dist/migrations/taskSchemaMigrations.d.ts +1 -1
- package/dist/migrations/taskSchemaMigrations.js +171 -61
- package/dist/migrations/taskSchemaMigrations.test.js +15 -0
- package/dist/resources/templates/workflow-sources/workflowDocs.mjs +6 -6
- package/dist/resources/templates/workflows/collaborate.yaml +1 -1
- package/dist/resources/templates/workflows/evaluate.yaml +2 -2
- package/dist/resources/templates/workflows/plan.yaml +1 -1
- package/dist/resources/templates/workflows/review.yaml +2 -2
- package/dist/server/annotatedAttachmentsRoutes.test.js +3 -3
- package/dist/server/auth/providers/apple.d.ts +33 -0
- package/dist/server/auth/providers/apple.js +82 -0
- package/dist/server/auth/providers/appleClientSecret.d.ts +37 -0
- package/dist/server/auth/providers/appleClientSecret.js +65 -0
- package/dist/server/auth/providers/github.d.ts +26 -0
- package/dist/server/auth/providers/github.js +86 -0
- package/dist/server/auth/providers/google.d.ts +21 -0
- package/dist/server/auth/providers/google.js +56 -0
- package/dist/server/auth/providers/types.d.ts +21 -0
- package/dist/server/auth/providers/types.js +1 -0
- package/dist/server/auth.d.ts +2 -0
- package/dist/server/auth.js +6 -3
- package/dist/server/documentReviewRoutes.test.js +36 -3
- package/dist/server/index.cookieProxy.test.js +1 -0
- package/dist/server/index.d.ts +12 -0
- package/dist/server/index.js +120 -9
- package/dist/server/index.rateLimit.test.js +3 -0
- package/dist/server/index.test.js +106 -3
- package/dist/server/routes/admin.d.ts +3 -0
- package/dist/server/routes/admin.js +272 -19
- package/dist/server/routes/auth.d.ts +15 -2
- package/dist/server/routes/auth.js +994 -57
- package/dist/server/routes/authSupport.d.ts +1 -1
- package/dist/server/routes/authSupport.js +1 -1
- package/dist/server/routes/billing.js +361 -35
- package/dist/server/routes/billing.test.js +592 -12
- package/dist/server/routes/documents.d.ts +1 -0
- package/dist/server/routes/documents.js +172 -70
- package/dist/server/routes/shared.d.ts +28 -2
- package/dist/server/routes/shared.js +69 -4
- package/dist/server/routes/sync.integration.test.js +437 -39
- package/dist/server/routes/sync.js +61 -605
- package/dist/server/routes/syncAuxRoutes.d.ts +15 -0
- package/dist/server/routes/syncAuxRoutes.js +91 -0
- package/dist/server/routes/syncAuxRoutes.test.d.ts +1 -0
- package/dist/server/routes/syncAuxRoutes.test.js +158 -0
- package/dist/server/routes/syncPullApplyRoutes.d.ts +36 -0
- package/dist/server/routes/syncPullApplyRoutes.js +204 -0
- package/dist/server/routes/syncPushRoutes.d.ts +24 -0
- package/dist/server/routes/syncPushRoutes.js +212 -0
- package/dist/server/routes/syncRouteGuards.d.ts +36 -0
- package/dist/server/routes/syncRouteGuards.js +67 -0
- package/dist/server/routes/syncRouteGuards.test.d.ts +1 -0
- package/dist/server/routes/syncRouteGuards.test.js +94 -0
- package/dist/server/routes/syncRouteTypes.d.ts +13 -0
- package/dist/server/routes/syncRouteTypes.js +1 -0
- package/dist/server/routes/syncSnapshotRoutes.d.ts +66 -0
- package/dist/server/routes/syncSnapshotRoutes.js +180 -0
- package/dist/server/routes/tasks.js +43 -1
- package/dist/server/routes/workspaces.js +36 -5
- package/dist/server/routes.js +60 -3
- package/dist/server/routes.test.js +1824 -171
- package/dist/services/workflowExportSnapshots.test.js +2 -0
- package/dist/shared/aiProfileSeatScope.d.ts +5 -0
- package/dist/shared/aiProfileSeatScope.js +21 -0
- package/dist/shared/passwordPolicy.d.ts +13 -0
- package/dist/shared/passwordPolicy.js +84 -0
- package/dist/shared/passwordPolicy.test.d.ts +1 -0
- package/dist/shared/passwordPolicy.test.js +34 -0
- package/dist/storage/workspaceAssetStore.d.ts +15 -3
- package/dist/storage/workspaceAssetStore.js +132 -44
- package/dist/storage/workspaceAssetStore.test.js +93 -6
- package/dist/styles/fonts.css +70 -0
- package/dist/sync/collaborationSyncPayload.d.ts +6 -1
- package/dist/sync/collaborationSyncPayload.js +17 -11
- package/dist/sync/collaborationSyncPayload.test.js +13 -1
- package/dist/sync/contentSyncState.d.ts +4 -8
- package/dist/sync/contentSyncState.js +17 -70
- package/dist/sync/syncApplyHandlers.d.ts +7 -0
- package/dist/sync/syncApplyHandlers.js +28 -13
- package/dist/sync/syncApplyHandlers.test.js +70 -3
- package/dist/sync/syncFieldSemantics.d.ts +12 -0
- package/dist/sync/syncFieldSemantics.js +55 -0
- package/dist/sync/syncResourceAdapters.d.ts +44 -0
- package/dist/sync/syncResourceAdapters.js +77 -0
- package/dist/sync/syncService.d.ts +5 -0
- package/dist/sync/syncService.js +52 -0
- package/dist/sync/syncService.test.js +57 -3
- package/dist/sync/taskSyncChangeKey.d.ts +2 -0
- package/dist/sync/taskSyncChangeKey.js +143 -0
- package/dist/sync/taskSyncPayload.js +3 -8
- package/dist/sync/workspacePullFeed.js +4 -3
- package/dist/sync/workspacePullFeed.test.js +43 -0
- package/dist/sync/workspaceRepair.js +5 -2
- package/dist/sync/workspaceSyncModel.d.ts +45 -0
- package/dist/sync/workspaceSyncModel.js +183 -28
- package/dist/sync/workspaceSyncModel.test.js +291 -12
- 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 +17 -0
- package/dist/ui/assets/AgentsModule-DrLawwNl.js +1 -0
- package/dist/ui/assets/{AnnotatedAttachmentWorkspace-BG6P_GVW.js → AnnotatedAttachmentWorkspace-Z9_whf7F.js} +1 -1
- package/dist/ui/assets/CourierPrime-Bold-BuLj_dpw.woff2 +0 -0
- package/dist/ui/assets/CourierPrime-BoldItalic-BrK2pUkZ.woff2 +0 -0
- package/dist/ui/assets/CourierPrime-Italic-DFUZK5Ey.woff2 +0 -0
- package/dist/ui/assets/CourierPrime-Regular-BsKphzVf.woff2 +0 -0
- package/dist/ui/assets/DocumentWorkspace-B03MaSkw.js +252 -0
- package/dist/ui/assets/DocumentWorkspace-Dhdso07p.css +1 -0
- package/dist/ui/assets/{InitiativesModule-Dhm7M8e7.js → InitiativesModule-9E6ParrY.js} +1 -1
- package/dist/ui/assets/Noir_medium-bxQwKGzB.woff2 +0 -0
- package/dist/ui/assets/Noir_regular-ojf2kxlG.woff2 +0 -0
- package/dist/ui/assets/PlansPage-CvfnMiWq.css +1 -0
- package/dist/ui/assets/PlansPage-DRXscYxH.js +1 -0
- package/dist/ui/assets/RussoOne-Regular-Cu_qq_qC.woff2 +0 -0
- package/dist/ui/assets/SpecialElite-Regular-Di6gSvAS.woff2 +0 -0
- package/dist/ui/assets/{TaskSettings-ln0aF7xc.js → TaskSettings-DZX4jk7e.js} +1 -1
- package/dist/ui/assets/{WorkflowsModule-BcS4afRn.js → WorkflowsModule-BA7jcEpH.js} +1 -1
- package/dist/ui/assets/index-9eT8e0Lu.css +1 -0
- package/dist/ui/assets/index-C6k75jr8.js +6 -0
- package/dist/ui/assets/{vendor-icons-BSUaRwF8.js → vendor-icons-DuEd_65c.js} +1 -1
- package/dist/ui/fonts/CourierPrime-Bold.ttf +0 -0
- package/dist/ui/fonts/CourierPrime-Bold.woff2 +0 -0
- package/dist/ui/fonts/CourierPrime-BoldItalic.ttf +0 -0
- package/dist/ui/fonts/CourierPrime-BoldItalic.woff2 +0 -0
- package/dist/ui/fonts/CourierPrime-Italic.ttf +0 -0
- package/dist/ui/fonts/CourierPrime-Italic.woff2 +0 -0
- package/dist/ui/fonts/CourierPrime-Regular.ttf +0 -0
- package/dist/ui/fonts/CourierPrime-Regular.woff2 +0 -0
- package/dist/ui/fonts/Noir_medium.otf +0 -0
- package/dist/ui/fonts/Noir_medium.woff2 +0 -0
- package/dist/ui/fonts/Noir_regular.otf +0 -0
- package/dist/ui/fonts/Noir_regular.woff2 +0 -0
- package/dist/ui/fonts/RussoOne-Regular.woff2 +0 -0
- package/dist/ui/fonts/SpecialElite-Regular.ttf +0 -0
- package/dist/ui/fonts/SpecialElite-Regular.woff2 +0 -0
- package/dist/ui/index.html +3 -3
- package/dist/utils/accountProfileSummaryCache.d.ts +5 -0
- package/dist/utils/assignees.d.ts +2 -0
- package/dist/utils/assignees.js +2 -0
- package/dist/utils/avatarUpload.d.ts +27 -0
- package/dist/utils/avatarUpload.js +132 -0
- package/dist/utils/avatarUpload.test.d.ts +1 -0
- package/dist/utils/avatarUpload.test.js +40 -0
- package/dist/utils/bootstrapTrace.d.ts +7 -0
- package/dist/utils/bootstrapTrace.js +29 -0
- package/dist/utils/commercialLifecyclePresentation.js +3 -0
- package/dist/utils/contextAssetEvents.d.ts +2 -0
- package/dist/utils/syncEventDetails.d.ts +3 -0
- package/dist/utils/syncEventDetails.js +64 -0
- package/dist/utils/syncEventDetails.test.d.ts +1 -0
- package/dist/utils/syncEventDetails.test.js +23 -0
- package/dist/utils/syncEventPresentation.d.ts +15 -0
- package/dist/utils/syncEventPresentation.js +129 -0
- package/dist/utils/syncEventPresentation.test.d.ts +1 -0
- package/dist/utils/syncEventPresentation.test.js +64 -0
- package/dist/utils/syncStatusPresentation.d.ts +72 -0
- package/dist/utils/syncStatusPresentation.js +217 -0
- package/dist/utils/syncStatusPresentation.test.d.ts +1 -0
- package/dist/utils/syncStatusPresentation.test.js +164 -0
- package/dist/utils/taskActivity.d.ts +2 -0
- package/dist/utils/taskActivity.js +228 -22
- package/dist/utils/taskActivity.test.js +119 -8
- package/dist/utils/workspaceSyncPresentation.d.ts +4 -0
- package/dist/utils/workspaceSyncPresentation.js +68 -2
- package/dist/utils/workspaceSyncPresentation.test.js +36 -1
- package/package.json +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/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/index-C2-OXZV7.css +0 -1
- package/dist/ui/assets/index-DcSI5F86.js +0 -6
- package/scripts/migrate-planning-model.ts +0 -233
package/dist/mcp/runtime.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ 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;
|
|
@@ -23,6 +24,7 @@ export interface TaskforceMcpServerOptions {
|
|
|
23
24
|
aiProfileProvider?: AiProfileBootstrapConfig['aiProfileProvider'];
|
|
24
25
|
aiProfileModel?: AiProfileBootstrapConfig['aiProfileModel'];
|
|
25
26
|
aiProfileSurfaceType?: AiProfileBootstrapConfig['aiProfileSurfaceType'];
|
|
27
|
+
aiProfileSeatScope?: AiProfileSeatScope | null;
|
|
26
28
|
actorType?: 'local' | 'user' | 'token' | 'oauth';
|
|
27
29
|
requestId?: string | null;
|
|
28
30
|
ip?: string | null;
|
package/dist/mcp/runtime.js
CHANGED
|
@@ -23,6 +23,7 @@ import { getImageReferenceLabel, parseImageReference } from '../utils/imageRefer
|
|
|
23
23
|
import { inferCanonicalAssetKind, isValidCanonicalDocumentAsset } from '../utils/canonicalAssetKind.js';
|
|
24
24
|
import { getTaskReferenceLabel, shouldUseProvisionalTaskReferences } from '../utils/taskReferences.js';
|
|
25
25
|
import { parseAiProfileSurfaceType } from '../shared/aiProfileSurfaceType.js';
|
|
26
|
+
import { parseAiProfileSeatScope } from '../shared/aiProfileSeatScope.js';
|
|
26
27
|
import { formatWorkstreamReference, resolveInitiativeReference, parseWorkstreamReference, } from '../utils/planningReferences.js';
|
|
27
28
|
import { MCP_TOOL_PERMISSIONS, MCP_WRITE_TOOL_NAMES } from './toolRegistry.js';
|
|
28
29
|
import { registerAdminWorkspaceTools } from './adminWorkspaceRegistrar.js';
|
|
@@ -102,6 +103,13 @@ function resolveRecoverableToolError(error) {
|
|
|
102
103
|
message,
|
|
103
104
|
code,
|
|
104
105
|
...(details !== undefined ? { details } : {}),
|
|
106
|
+
...(code === 'AI_PROFILE_RETIRED'
|
|
107
|
+
? {
|
|
108
|
+
nextTool: 'resolve_profile',
|
|
109
|
+
suggestedArgs: {},
|
|
110
|
+
retryHint: 'Call resolve_profile to intentionally reactivate the retired AI identity, then retry the original mutating tool call.'
|
|
111
|
+
}
|
|
112
|
+
: {}),
|
|
105
113
|
...(code === 'TAXONOMY_NEEDS_CONFIRMATION' ? { needs_confirmation: true } : {})
|
|
106
114
|
};
|
|
107
115
|
}
|
|
@@ -227,6 +235,7 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
227
235
|
const allowedScopes = Array.isArray(options.auth?.scopes)
|
|
228
236
|
? Array.from(new Set(options.auth.scopes))
|
|
229
237
|
: null;
|
|
238
|
+
const configuredAiProfileSeatScope = runtimeMode === 'cloud' ? 'cloud_metered' : 'local_unmetered';
|
|
230
239
|
if (logStartup) {
|
|
231
240
|
console.error(`[Taskforce MCP] Starting for project: ${PROJECT_NAME} at ${PROJECT_ROOT}`);
|
|
232
241
|
}
|
|
@@ -333,7 +342,7 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
333
342
|
},
|
|
334
343
|
tools: {},
|
|
335
344
|
},
|
|
336
|
-
instructions: `You are an AI collaborator connected to Taskforce, a shared task management system for AI-developer pairs.\n\nIMPORTANT: Before mutating Taskforce data, ensure Taskforce knows which AI profile you are acting as. The preferred path is ambient session binding: if your MCP connection is configured with x-taskforce-ai-name and optionally x-taskforce-ai-profile-token headers, Taskforce can auto-bind that AI identity for get_current_profile and later writes. If no AI identity is currently bound, call resolve_profile with your name. Reuse the returned profileToken across sessions, especially for stateless clients.\n\nStateless client pattern: call resolve_profile, save the returned profileToken, and include profileToken on later mutating tool calls only when your MCP client does not preserve session identity between calls.\n\nTo inspect your current attribution state before writes, call get_current_profile. It reports whether identity is bound, how it was resolved, and the suggested args to use with list_tasks.\n\nWhen setting resolve_profile.surfaceType, classify yourself by the kind of identity you are registering: use agent for a persistent named AI collaborator in Taskforce, coding_tool for the coding surface or terminal tool itself, chat_app for a conversational app identity, ide for an IDE-native copilot identity, and other only when none of those fit. If you are unsure and you are registering a named collaborator such as a teammate-style AI persona, choose agent.\n\nTo get tasks assigned to yourself, call get_current_profile, then use the returned suggestedArgs with list_tasks. When you begin active work on a tracked task, prefer start_task. It sets the task to in-progress and claims it for your AI profile when the task is currently unassigned. When work on a tracked task is complete, prefer finish_task for the final handoff: use outcome='review' when the next step is human validation or approval, and use outcome='done' only when no explicit human action is requested. Do not leave a task in-progress after reporting completed implementation unless the user explicitly wants more work to continue in the same task.\n\nTaxonomy rule: always call get_config before setting category, type, priority, approach, status, or complexity. Do not rely on remembered enum values.\n\nUse identifier prefixes to choose the correct retrieval path: T-123 goes to task tools such as get_task, IN-123 goes to initiative tools such as get_initiative, WS-123 goes to workstream tools such as get_workstream, I-123 goes to image tools such as get_image, and D-123 goes to document tools such as get_document. Do not send I-123 or D-123 identifiers to get_task.\n\nFor annotated images, use search_images first when you know only a keyword, filename, or rough title. Once you have the exact identifier, call get_image, then use get_annotated_attachment_sessions to list saved sessions, then use read_annotated_attachment_payload for the structured annotation payload.\n\nFor documents, use search_documents first when you know only a keyword, filename, or rough title. Once you have the exact identifier, call get_document, then read_document_content to inspect the document body. For a lower-friction review flow, prefer review_document; otherwise use get_document_review_sessions or create_document_review_session, then add_document_review_comment to record review feedback.`,
|
|
345
|
+
instructions: `You are an AI collaborator connected to Taskforce, a shared task management system for AI-developer pairs.\n\nIMPORTANT: Before mutating Taskforce data, ensure Taskforce knows which AI profile you are acting as. The preferred path is ambient session binding: if your MCP connection is configured with x-taskforce-ai-name and optionally x-taskforce-ai-profile-token headers, Taskforce can auto-bind that AI identity for get_current_profile and later writes. If no AI identity is currently bound, call resolve_profile with your name. Reuse the returned profileToken across sessions, especially for stateless clients.\n\nStateless client pattern: call resolve_profile, save the returned profileToken, and include profileToken on later mutating tool calls only when your MCP client does not preserve session identity between calls.\n\nTo inspect your current attribution state before writes, call get_current_profile. It reports whether identity is bound, how it was resolved, and the suggested args to use with list_tasks.\n\nWhen setting resolve_profile.surfaceType, classify yourself by the kind of identity you are registering: use agent for a persistent named AI collaborator in Taskforce, coding_tool for the coding surface or terminal tool itself, chat_app for a conversational app identity, ide for an IDE-native copilot identity, and other only when none of those fit. If you are unsure and you are registering a named collaborator such as a teammate-style AI persona, choose agent.\n\nTo get tasks assigned to yourself, call get_current_profile, then use the returned suggestedArgs with list_tasks. When you begin active work on a tracked task, prefer start_task. It sets the task to in-progress and claims it for your AI profile when the task is currently unassigned. When work on a tracked task is complete, prefer finish_task for the final handoff: use outcome='review' when the next step is human validation or approval, and use outcome='done' only when no explicit human action is requested. Do not leave a task in-progress after reporting completed implementation unless the user explicitly wants more work to continue in the same task.\n\nTaxonomy rule: always call get_config before setting category, type, priority, approach, status, or complexity. Do not rely on remembered enum values.\n\nUse identifier prefixes to choose the correct retrieval path: T-123 goes to task tools such as get_task, IN-123 goes to initiative tools such as get_initiative, WS-123 goes to workstream tools such as get_workstream, I-123 goes to image tools such as get_image, and D-123 goes to document tools such as get_document. Do not send I-123 or D-123 identifiers to get_task.\n\nFor annotated images, use search_images first when you know only a keyword, filename, or rough title. Once you have the exact identifier, call get_image, then use get_annotated_attachment_sessions to list saved sessions, then use read_annotated_attachment_payload for the structured annotation payload. If an image reference is being used for UI, placement, or visual correction feedback, treat the saved annotation payload as the source of truth and do not infer intent from the screenshot alone.\n\nFor documents, use search_documents first when you know only a keyword, filename, or rough title. Once you have the exact identifier, call get_document, then read_document_content to inspect the document body. For a lower-friction review flow, prefer review_document; otherwise use get_document_review_sessions or create_document_review_session, then add_document_review_comment to record review feedback.`,
|
|
337
346
|
});
|
|
338
347
|
const TOOL_PERMISSIONS = MCP_TOOL_PERMISSIONS;
|
|
339
348
|
const RESOURCE_PERMISSIONS = {
|
|
@@ -562,6 +571,7 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
562
571
|
provider: typeof actor.meta?.provider === 'string' ? actor.meta.provider : null,
|
|
563
572
|
model: typeof actor.meta?.model === 'string' ? actor.meta.model : null,
|
|
564
573
|
surfaceType: typeof actor.meta?.surfaceType === 'string' ? actor.meta.surfaceType : null,
|
|
574
|
+
seatScope: parseAiProfileSeatScope(actor.meta?.seatScope),
|
|
565
575
|
} : {}),
|
|
566
576
|
...(activeAiProfileId && actor.id === activeAiProfileId ? { isCurrentProfile: true } : {})
|
|
567
577
|
}))
|
|
@@ -581,6 +591,7 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
581
591
|
provider: profile.provider ?? null,
|
|
582
592
|
model: profile.model ?? null,
|
|
583
593
|
surfaceType: profile.surfaceType ?? null,
|
|
594
|
+
seatScope: profile.seatScope ?? null,
|
|
584
595
|
lastActiveAt: profile.lastActiveAt ?? null,
|
|
585
596
|
};
|
|
586
597
|
}
|
|
@@ -692,7 +703,7 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
692
703
|
}
|
|
693
704
|
function buildConfiguredAiProfileResolveInput(includeToken = true) {
|
|
694
705
|
const configuredSurfaceType = parseAiProfileSurfaceType(configuredAiProfileSurfaceType);
|
|
695
|
-
|
|
706
|
+
const baseInput = buildResolveAiProfileInputFromBootstrap(ACTIVE_WORKSPACE_ID, {
|
|
696
707
|
aiProfileToken: configuredAiProfileToken,
|
|
697
708
|
aiProfileName: configuredAiProfileName,
|
|
698
709
|
aiProfileIcon: configuredAiProfileIcon,
|
|
@@ -703,6 +714,51 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
703
714
|
aiProfileModel: configuredAiProfileModel,
|
|
704
715
|
aiProfileSurfaceType: configuredSurfaceType,
|
|
705
716
|
}, includeToken);
|
|
717
|
+
if (!baseInput)
|
|
718
|
+
return null;
|
|
719
|
+
return baseInput;
|
|
720
|
+
}
|
|
721
|
+
function normalizeConfiguredAiProfileUsername(value, fallbackName) {
|
|
722
|
+
const source = String(value || fallbackName || '').trim().toLowerCase();
|
|
723
|
+
const normalized = source
|
|
724
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
725
|
+
.replace(/-+/g, '-')
|
|
726
|
+
.replace(/^-+|-+$/g, '')
|
|
727
|
+
.slice(0, 48);
|
|
728
|
+
return normalized || 'ai';
|
|
729
|
+
}
|
|
730
|
+
function findArchivedConfiguredAiProfileCandidate() {
|
|
731
|
+
if (configuredAiProfileToken) {
|
|
732
|
+
const profile = core.getAiProfileByToken({
|
|
733
|
+
workspaceId: ACTIVE_WORKSPACE_ID,
|
|
734
|
+
profileToken: configuredAiProfileToken,
|
|
735
|
+
includeArchived: true,
|
|
736
|
+
seatScope: configuredAiProfileSeatScope,
|
|
737
|
+
});
|
|
738
|
+
if (profile?.archivedAt)
|
|
739
|
+
return profile;
|
|
740
|
+
}
|
|
741
|
+
const configuredName = String(configuredAiProfileName || '').trim();
|
|
742
|
+
if (!configuredName)
|
|
743
|
+
return null;
|
|
744
|
+
const normalizedUsername = normalizeConfiguredAiProfileUsername(undefined, configuredName).toLowerCase();
|
|
745
|
+
return core.listAiProfiles(ACTIVE_WORKSPACE_ID, { includeArchived: true }).find((profile) => {
|
|
746
|
+
if (!profile.archivedAt)
|
|
747
|
+
return false;
|
|
748
|
+
if ((profile.seatScope ?? null) !== configuredAiProfileSeatScope)
|
|
749
|
+
return false;
|
|
750
|
+
const profileName = String(profile.name || '').trim().toLowerCase();
|
|
751
|
+
const profileUsername = String(profile.username || '').trim().toLowerCase();
|
|
752
|
+
return profileName === configuredName.toLowerCase() || profileUsername === normalizedUsername;
|
|
753
|
+
}) || null;
|
|
754
|
+
}
|
|
755
|
+
function throwArchivedConfiguredAiProfileError(profile) {
|
|
756
|
+
throw new TaskforceRuleError(`AI profile "${profile.name}" has been retired from this workspace. Call resolve_profile to reactivate it before retrying.`, 409, 'AI_PROFILE_RETIRED', {
|
|
757
|
+
workspaceId: ACTIVE_WORKSPACE_ID,
|
|
758
|
+
profileId: profile.id,
|
|
759
|
+
profileToken: profile.profileToken || null,
|
|
760
|
+
archivedReason: profile.archivedReason || null,
|
|
761
|
+
});
|
|
706
762
|
}
|
|
707
763
|
function ensureResolvedProfileFromConnection(defaults) {
|
|
708
764
|
if (activeAiProfileId)
|
|
@@ -710,10 +766,16 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
710
766
|
const allowCreateFromName = defaults?.allowCreateFromName === true;
|
|
711
767
|
const configuredResolveInput = buildConfiguredAiProfileResolveInput(true);
|
|
712
768
|
const configuredResolveFallbackInput = buildConfiguredAiProfileResolveInput(false);
|
|
769
|
+
const archivedConfiguredProfile = findArchivedConfiguredAiProfileCandidate();
|
|
770
|
+
if (archivedConfiguredProfile) {
|
|
771
|
+
throwArchivedConfiguredAiProfileError(archivedConfiguredProfile);
|
|
772
|
+
}
|
|
713
773
|
if (configuredAiProfileToken) {
|
|
714
774
|
if (configuredResolveInput) {
|
|
715
775
|
try {
|
|
716
|
-
const resolved = core.resolveAiProfile(configuredResolveInput
|
|
776
|
+
const resolved = core.resolveAiProfile(configuredResolveInput, {
|
|
777
|
+
trustedSeatScope: configuredAiProfileSeatScope,
|
|
778
|
+
});
|
|
717
779
|
activeAiProfileId = resolved.profile.id;
|
|
718
780
|
activeAiBindingSource = 'connection_bootstrap';
|
|
719
781
|
return;
|
|
@@ -725,6 +787,7 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
725
787
|
const profile = core.getAiProfileByToken({
|
|
726
788
|
workspaceId: ACTIVE_WORKSPACE_ID,
|
|
727
789
|
profileToken: configuredAiProfileToken,
|
|
790
|
+
seatScope: configuredAiProfileSeatScope,
|
|
728
791
|
});
|
|
729
792
|
if (profile) {
|
|
730
793
|
activeAiProfileId = profile.id;
|
|
@@ -736,7 +799,9 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
736
799
|
}
|
|
737
800
|
}
|
|
738
801
|
if (allowCreateFromName && configuredResolveFallbackInput) {
|
|
739
|
-
const resolved = core.resolveAiProfile(configuredResolveFallbackInput
|
|
802
|
+
const resolved = core.resolveAiProfile(configuredResolveFallbackInput, {
|
|
803
|
+
trustedSeatScope: configuredAiProfileSeatScope,
|
|
804
|
+
});
|
|
740
805
|
activeAiProfileId = resolved.profile.id;
|
|
741
806
|
activeAiBindingSource = 'connection_bootstrap';
|
|
742
807
|
}
|
|
@@ -756,6 +821,7 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
756
821
|
const profile = core.getAiProfileByToken({
|
|
757
822
|
workspaceId: ACTIVE_WORKSPACE_ID,
|
|
758
823
|
profileToken,
|
|
824
|
+
seatScope: configuredAiProfileSeatScope,
|
|
759
825
|
});
|
|
760
826
|
if (profile) {
|
|
761
827
|
activeAiProfileId = profile.id;
|
|
@@ -764,7 +830,9 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
764
830
|
}
|
|
765
831
|
const configuredResolveInput = buildConfiguredAiProfileResolveInput(false);
|
|
766
832
|
if (configuredResolveInput) {
|
|
767
|
-
const resolved = core.resolveAiProfile(configuredResolveInput
|
|
833
|
+
const resolved = core.resolveAiProfile(configuredResolveInput, {
|
|
834
|
+
trustedSeatScope: configuredAiProfileSeatScope,
|
|
835
|
+
});
|
|
768
836
|
activeAiProfileId = resolved.profile.id;
|
|
769
837
|
activeAiBindingSource = 'connection_bootstrap';
|
|
770
838
|
return;
|
|
@@ -1224,6 +1292,21 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
1224
1292
|
const d = String(date.getDate()).padStart(2, '0');
|
|
1225
1293
|
return `${y}-${m}-${d}`;
|
|
1226
1294
|
}
|
|
1295
|
+
function dateOnlyToIsoWeekKey(dateOnly) {
|
|
1296
|
+
const parsed = parseDateOnlyLocal(dateOnly);
|
|
1297
|
+
if (!parsed)
|
|
1298
|
+
return null;
|
|
1299
|
+
const weekDate = new Date(Date.UTC(parsed.getFullYear(), parsed.getMonth(), parsed.getDate()));
|
|
1300
|
+
const day = weekDate.getUTCDay() || 7;
|
|
1301
|
+
weekDate.setUTCDate(weekDate.getUTCDate() + 4 - day);
|
|
1302
|
+
const year = weekDate.getUTCFullYear();
|
|
1303
|
+
const yearStart = new Date(Date.UTC(year, 0, 1));
|
|
1304
|
+
const week = Math.ceil((((weekDate.getTime() - yearStart.getTime()) / 86400000) + 1) / 7);
|
|
1305
|
+
return `${year}-W${String(week).padStart(2, '0')}`;
|
|
1306
|
+
}
|
|
1307
|
+
function currentIsoWeekKeyLocal() {
|
|
1308
|
+
return dateOnlyToIsoWeekKey(formatDateOnlyLocal(new Date())) || '';
|
|
1309
|
+
}
|
|
1227
1310
|
function addDaysDateOnly(dateOnly, days) {
|
|
1228
1311
|
const parsed = parseDateOnlyLocal(dateOnly);
|
|
1229
1312
|
if (!parsed)
|
|
@@ -1817,53 +1900,20 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
1817
1900
|
case "list_tasks": {
|
|
1818
1901
|
const startedAtMs = Date.now();
|
|
1819
1902
|
const { format = "markdown", category, status, openOnly = false, assignee, priority, type, sort = "created", order = "desc", limit } = args;
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
if (assignee)
|
|
1831
|
-
tasks = tasks.filter(t => (t.assignee || 'unassigned') === assignee);
|
|
1832
|
-
if (priority !== undefined)
|
|
1833
|
-
tasks = tasks.filter(t => t.priority === Number(priority));
|
|
1834
|
-
if (type)
|
|
1835
|
-
tasks = tasks.filter(t => t.type === type);
|
|
1836
|
-
// Sorting
|
|
1837
|
-
tasks.sort((a, b) => {
|
|
1838
|
-
let aVal, bVal;
|
|
1839
|
-
if (sort === "priority") {
|
|
1840
|
-
aVal = a.priority;
|
|
1841
|
-
bVal = b.priority;
|
|
1842
|
-
}
|
|
1843
|
-
else if (sort === "updated") {
|
|
1844
|
-
aVal = a.updatedAt || a.createdAt;
|
|
1845
|
-
bVal = b.updatedAt || b.createdAt;
|
|
1846
|
-
}
|
|
1847
|
-
else {
|
|
1848
|
-
aVal = a.createdAt;
|
|
1849
|
-
bVal = b.createdAt;
|
|
1850
|
-
}
|
|
1851
|
-
const cmp = aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
|
|
1852
|
-
return order === "asc" ? cmp : -cmp;
|
|
1903
|
+
const slimTasks = core.listTasksSlim(ACTIVE_WORKSPACE_ID, {
|
|
1904
|
+
category,
|
|
1905
|
+
status,
|
|
1906
|
+
openOnly: Boolean(openOnly),
|
|
1907
|
+
assignee,
|
|
1908
|
+
priority: priority !== undefined ? Number(priority) : undefined,
|
|
1909
|
+
type,
|
|
1910
|
+
sort,
|
|
1911
|
+
order,
|
|
1912
|
+
limit: typeof limit === 'number' ? limit : (limit ? Number(limit) : undefined),
|
|
1853
1913
|
});
|
|
1854
|
-
// Limiting
|
|
1855
|
-
if (limit && limit > 0) {
|
|
1856
|
-
tasks = tasks.slice(0, limit);
|
|
1857
|
-
}
|
|
1858
|
-
// Strip verbose detail fields — descriptions, comments, events, and derived
|
|
1859
|
-
// activity are omitted from list responses to keep context window usage
|
|
1860
|
-
// manageable. Use get_task to retrieve full details for a specific task.
|
|
1861
|
-
const slimTasks = tasks.map(({ description, comments, taskEvents, activity, createdByActor, assigneeActor, attachments, checklistItems, ...rest }) => rest);
|
|
1862
1914
|
logMcpReadObservation('list_tasks', startedAtMs, {
|
|
1863
1915
|
format,
|
|
1864
|
-
totalTasks: data.tasks.length,
|
|
1865
1916
|
returnedTasks: slimTasks.length,
|
|
1866
|
-
filtered: slimTasks.length !== data.tasks.length,
|
|
1867
1917
|
openOnly,
|
|
1868
1918
|
hasAssigneeFilter: Boolean(assignee),
|
|
1869
1919
|
hasStatusFilter: Boolean(status),
|
|
@@ -1895,6 +1945,8 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
1895
1945
|
model,
|
|
1896
1946
|
surfaceType: typeof surfaceType === 'string' || surfaceType === null ? surfaceType : undefined,
|
|
1897
1947
|
profileToken: typeof profileToken === 'string' ? profileToken : null
|
|
1948
|
+
}, {
|
|
1949
|
+
trustedSeatScope: configuredAiProfileSeatScope,
|
|
1898
1950
|
});
|
|
1899
1951
|
activeAiProfileId = resolved.profile.id;
|
|
1900
1952
|
activeAiBindingSource = 'session';
|
|
@@ -1921,6 +1973,7 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
1921
1973
|
provider: resolved.profile.provider ?? null,
|
|
1922
1974
|
model: resolved.profile.model ?? null,
|
|
1923
1975
|
surfaceType: resolved.profile.surfaceType ?? null,
|
|
1976
|
+
seatScope: resolved.profile.seatScope ?? null,
|
|
1924
1977
|
lastActiveAt: resolved.profile.lastActiveAt
|
|
1925
1978
|
},
|
|
1926
1979
|
...(resolved.duplicateWarning && { duplicateWarning: resolved.duplicateWarning })
|
|
@@ -1951,6 +2004,7 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
1951
2004
|
profile = core.getAiProfileByToken({
|
|
1952
2005
|
workspaceId: ACTIVE_WORKSPACE_ID,
|
|
1953
2006
|
profileToken: profileToken.trim(),
|
|
2007
|
+
seatScope: configuredAiProfileSeatScope,
|
|
1954
2008
|
});
|
|
1955
2009
|
if (!profile) {
|
|
1956
2010
|
throw new Error('Invalid AI profile token. Call resolve_profile again and retry.');
|
|
@@ -2430,19 +2484,21 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
2430
2484
|
}
|
|
2431
2485
|
const linkedTasks = (workspaceAssetStore?.listLinksForAsset(image.assetId, ACTIVE_WORKSPACE_ID) || [])
|
|
2432
2486
|
.filter((entry) => !entry.deletedAt)
|
|
2487
|
+
.filter((entry) => entry.targetType === 'task' && !!entry.taskId)
|
|
2433
2488
|
.reduce((entries, link) => {
|
|
2434
|
-
|
|
2489
|
+
const taskId = link.taskId;
|
|
2490
|
+
if (entries.some((entry) => entry.taskId === taskId))
|
|
2435
2491
|
return entries;
|
|
2436
|
-
const task = core.resolveTaskIdentifier(
|
|
2492
|
+
const task = core.resolveTaskIdentifier(taskId, ACTIVE_WORKSPACE_ID);
|
|
2437
2493
|
const taskReferenceLabel = task?.referenceLabel || (task ? getTaskReferenceLabel(task) : null);
|
|
2438
|
-
const sessions = (linkedTaskSessions.get(
|
|
2494
|
+
const sessions = (linkedTaskSessions.get(taskId) || []).map((session) => ({
|
|
2439
2495
|
id: session.id,
|
|
2440
2496
|
title: session.title,
|
|
2441
2497
|
updatedAt: session.updatedAt,
|
|
2442
2498
|
annotationCount: Array.isArray(session.annotations) ? session.annotations.length : 0,
|
|
2443
2499
|
}));
|
|
2444
2500
|
entries.push({
|
|
2445
|
-
taskId
|
|
2501
|
+
taskId,
|
|
2446
2502
|
referenceLabel: taskReferenceLabel,
|
|
2447
2503
|
role: link.role,
|
|
2448
2504
|
caption: link.displayName || null,
|
|
@@ -2492,11 +2548,13 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
2492
2548
|
const asset = resolveDocumentAssetByIdentifierOrThrow(documentId);
|
|
2493
2549
|
const linkedTasks = (workspaceAssetStore?.listLinksForAsset(asset.assetId, ACTIVE_WORKSPACE_ID) || [])
|
|
2494
2550
|
.filter((entry) => !entry.deletedAt)
|
|
2551
|
+
.filter((entry) => entry.targetType === 'task' && !!entry.taskId)
|
|
2495
2552
|
.map((link) => {
|
|
2496
|
-
const
|
|
2553
|
+
const taskId = link.taskId;
|
|
2554
|
+
const task = core.resolveTaskIdentifier(taskId, ACTIVE_WORKSPACE_ID);
|
|
2497
2555
|
const taskReferenceLabel = task?.referenceLabel || (task ? getTaskReferenceLabel(task) : null);
|
|
2498
2556
|
return {
|
|
2499
|
-
taskId
|
|
2557
|
+
taskId,
|
|
2500
2558
|
referenceLabel: taskReferenceLabel,
|
|
2501
2559
|
role: link.role,
|
|
2502
2560
|
caption: link.displayName || null,
|
|
@@ -3188,16 +3246,19 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
3188
3246
|
}
|
|
3189
3247
|
case "get_schedule_board": {
|
|
3190
3248
|
const { week, showWeekends = false } = args;
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
const board = core.getScheduleBoard(
|
|
3249
|
+
const weekKey = typeof week === 'string' && week.trim()
|
|
3250
|
+
? week.trim()
|
|
3251
|
+
: currentIsoWeekKeyLocal();
|
|
3252
|
+
const board = core.getScheduleBoard(weekKey, Boolean(showWeekends), ACTIVE_WORKSPACE_ID);
|
|
3195
3253
|
return {
|
|
3196
3254
|
content: [{ type: "text", text: JSON.stringify(board, null, 2) }],
|
|
3197
3255
|
};
|
|
3198
3256
|
}
|
|
3199
3257
|
case "schedule_task": {
|
|
3200
|
-
const { id:
|
|
3258
|
+
const { id: legacyInputId, taskId, scheduledDate: legacyScheduledDate, date, orderInDay: legacyOrderInDay, order } = args;
|
|
3259
|
+
const inputId = taskId ?? legacyInputId;
|
|
3260
|
+
const scheduledDate = date ?? legacyScheduledDate;
|
|
3261
|
+
const orderInDay = order ?? legacyOrderInDay;
|
|
3201
3262
|
const { id } = resolveTaskByIdentifierOrThrow(inputId);
|
|
3202
3263
|
if (!scheduledDate || typeof scheduledDate !== 'string')
|
|
3203
3264
|
throw new Error('scheduledDate is required');
|
|
@@ -3230,7 +3291,8 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
3230
3291
|
};
|
|
3231
3292
|
}
|
|
3232
3293
|
case "unschedule_task": {
|
|
3233
|
-
const { id:
|
|
3294
|
+
const { id: legacyInputId, taskId } = args;
|
|
3295
|
+
const inputId = taskId ?? legacyInputId;
|
|
3234
3296
|
const { id } = resolveTaskByIdentifierOrThrow(inputId);
|
|
3235
3297
|
const result = core.updateTaskSchedule(id, { scheduledDate: null, orderInDay: null }, ACTIVE_WORKSPACE_ID);
|
|
3236
3298
|
if (!result) {
|
|
@@ -3261,13 +3323,18 @@ export function createTaskforceMcpServer(options = {}) {
|
|
|
3261
3323
|
};
|
|
3262
3324
|
}
|
|
3263
3325
|
case "reorder_scheduled_tasks": {
|
|
3264
|
-
const { moves } = args;
|
|
3265
|
-
|
|
3326
|
+
const { moves, date, taskIds } = args;
|
|
3327
|
+
const inputMoves = Array.isArray(moves)
|
|
3328
|
+
? moves
|
|
3329
|
+
: Array.isArray(taskIds) && typeof date === 'string'
|
|
3330
|
+
? taskIds.map((taskId, index) => ({ id: taskId, scheduledDate: date, orderInDay: index }))
|
|
3331
|
+
: null;
|
|
3332
|
+
if (!Array.isArray(inputMoves)) {
|
|
3266
3333
|
throw new Error('moves must be an array');
|
|
3267
3334
|
}
|
|
3268
|
-
const resolvedMoves =
|
|
3335
|
+
const resolvedMoves = inputMoves.map((move) => ({
|
|
3269
3336
|
...move,
|
|
3270
|
-
id: resolveTaskByIdentifierOrThrow(move?.id).id
|
|
3337
|
+
id: resolveTaskByIdentifierOrThrow(move?.taskId ?? move?.id).id
|
|
3271
3338
|
}));
|
|
3272
3339
|
const result = core.reorderScheduledTasks(resolvedMoves, ACTIVE_WORKSPACE_ID);
|
|
3273
3340
|
recordMcpWriteAudit('reorder_scheduled_tasks', {
|