@taskforcehq/taskforce 0.3.327 → 0.3.329
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 +257 -87
- package/dist/TaskforceCore.js +237 -230
- package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.js +1 -1
- package/dist/cli.js +34 -0
- package/dist/cliCloudTargetGuard.d.ts +5 -0
- package/dist/cliCloudTargetGuard.js +11 -0
- package/dist/components/activity/EntityActivityTimeline.js +15 -5
- package/dist/components/context/AttachmentPreviewHost.js +1 -1
- package/dist/components/context/ContextAttachmentManager.d.ts +3 -0
- package/dist/components/context/ContextAttachmentManager.js +116 -20
- package/dist/components/features/AnnotatedAttachmentWorkspace.js +24 -8
- package/dist/components/features/TaskSettings.d.ts +12 -1
- package/dist/components/features/TaskSettings.js +147 -40
- package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.d.ts +1 -1
- package/dist/components/features/planning/PlanningEntitySummary.d.ts +3 -1
- package/dist/components/features/planning/PlanningEntitySummary.js +3 -2
- package/dist/components/features/planning/PlanningLinkPicker.d.ts +3 -1
- package/dist/components/features/planning/PlanningLinkPicker.js +5 -3
- package/dist/components/features/planning/PlanningModule.js +28 -14
- package/dist/components/features/planning/PlanningTaskOrderList.d.ts +1 -1
- package/dist/components/features/planning/PlanningTaskOrderList.js +17 -6
- package/dist/components/features/planning/PlanningVisualIdentity.d.ts +14 -0
- package/dist/components/features/planning/PlanningVisualIdentity.js +106 -0
- package/dist/components/features/planning/planningTaskArrangement.d.ts +1 -0
- package/dist/components/features/planning/planningTaskArrangement.js +5 -5
- package/dist/components/features/planning/planningWorkspaceModel.d.ts +11 -0
- package/dist/components/features/taskforceAgentEditorModel.js +3 -1
- package/dist/components/task/TaskActionHeader.d.ts +2 -1
- package/dist/components/task/TaskActionHeader.js +2 -2
- package/dist/components/task/TaskCard.d.ts +5 -0
- package/dist/components/task/TaskCard.js +101 -13
- package/dist/components/task/TaskContextUpload.d.ts +3 -0
- package/dist/components/task/TaskContextUpload.js +2 -2
- package/dist/components/task/TaskForm.d.ts +4 -0
- package/dist/components/task/TaskForm.js +32 -7
- package/dist/components/task/TaskImageReviews.js +28 -19
- package/dist/components/task/TaskKanban.d.ts +6 -1
- package/dist/components/task/TaskKanban.js +152 -6
- package/dist/components/task/TaskList.d.ts +5 -0
- package/dist/components/task/TaskList.js +3 -3
- package/dist/components/task/TaskStatusActions.js +11 -2
- package/dist/components/task/TaskWorkstreamPicker.js +2 -1
- package/dist/components/ui/DocumentTypeIcon.d.ts +7 -0
- package/dist/components/ui/DocumentTypeIcon.js +8 -0
- package/dist/components/ui/PasswordInput.d.ts +6 -0
- package/dist/components/ui/PasswordInput.js +11 -0
- package/dist/components/ui/TaxonomyDropdown.d.ts +9 -1
- package/dist/components/ui/TaxonomyDropdown.js +30 -3
- package/dist/components/ui/TopNoticeLayer.js +1 -1
- package/dist/components/views/AppShellHeader.js +32 -11
- package/dist/components/views/PlanComparisonPage.js +12 -0
- package/dist/components/views/StandaloneLayout.js +68 -39
- package/dist/components/views/WidgetView.js +10 -7
- package/dist/components/views/panels/PlanningDrawer.d.ts +7 -1
- package/dist/components/views/panels/PlanningDrawer.js +51 -54
- package/dist/components/views/standalone/modals/AccountSettingsModal.js +26 -17
- package/dist/config/envSchema.js +13 -0
- package/dist/config/localServiceCloudTarget.d.ts +10 -0
- package/dist/config/localServiceCloudTarget.js +76 -0
- package/dist/config/localServiceRuntimeContract.d.ts +13 -0
- package/dist/config/localServiceRuntimeContract.js +135 -0
- package/dist/core/AiProfileService.d.ts +1 -0
- package/dist/core/AiProfileService.js +48 -9
- package/dist/core/AttachmentLinkService.js +7 -4
- package/dist/core/DeletedTaskLifecycleService.d.ts +5 -0
- package/dist/core/DeletedTaskLifecycleService.js +55 -3
- package/dist/core/McpTokenService.d.ts +4 -0
- package/dist/core/McpTokenService.js +52 -0
- package/dist/core/TaskAttachmentLinksDurableMutationService.d.ts +8 -2
- package/dist/core/TaskAttachmentLinksDurableMutationService.js +51 -18
- package/dist/core/Taskforce.d.ts +124 -2
- package/dist/core/Taskforce.js +1175 -87
- package/dist/core/types.d.ts +8 -1
- package/dist/documentReviews/DocumentReviewCommentStore.d.ts +11 -0
- package/dist/documentReviews/DocumentReviewCommentStore.js +35 -2
- package/dist/documentReviews/service.d.ts +4 -0
- package/dist/documentReviews/service.js +141 -46
- package/dist/hooks/sync/useDurableLocalOutboxDrain.d.ts +1 -1
- package/dist/hooks/sync/useDurableTaskCreateMutation.js +1 -1
- package/dist/hooks/sync/useDurableTaskMetadataMutation.d.ts +1 -0
- package/dist/hooks/sync/useDurableTaskMetadataMutation.js +1 -0
- package/dist/hooks/sync/useDurableTaskStatusMutation.d.ts +1 -0
- package/dist/hooks/tasks/taskHttpMutation.js +1 -0
- package/dist/hooks/tasks/useCloudTaskSearch.d.ts +12 -0
- package/dist/hooks/tasks/useCloudTaskSearch.js +71 -0
- package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.d.ts +16 -0
- package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.js +197 -0
- package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +16 -3
- package/dist/hooks/tasks/useTaskEditorNavigation.js +72 -13
- package/dist/hooks/tasks/useTaskFormActions.d.ts +9 -0
- package/dist/hooks/tasks/useTaskFormActions.js +96 -17
- package/dist/hooks/ui/useSettingsModel.d.ts +24 -2
- package/dist/hooks/ui/useSettingsModel.js +13 -2
- package/dist/hooks/ui/useSettingsPersistence.d.ts +12 -1
- package/dist/hooks/ui/useSettingsPersistence.js +74 -47
- package/dist/hooks/useFilterSort.d.ts +7 -3
- package/dist/hooks/useFilterSort.js +15 -5
- package/dist/hooks/useTaskData.d.ts +10 -1
- package/dist/hooks/useTaskData.js +216 -7
- package/dist/hooks/useTaskMutations.d.ts +10 -2
- package/dist/hooks/useTaskMutations.js +223 -43
- package/dist/hooks/useTaskforce.d.ts +94 -57
- package/dist/hooks/useTaskforce.js +428 -16
- package/dist/hooks/useUiNotice.d.ts +4 -0
- package/dist/hooks/useUiNotice.js +4 -0
- package/dist/mcp/adminWorkspaceRegistrar.js +3 -3
- package/dist/mcp/canonicalAssetHelpers.d.ts +13 -0
- package/dist/mcp/canonicalAssetHelpers.js +39 -5
- package/dist/mcp/collaborationRegistrar.js +15 -13
- package/dist/mcp/documentAssetRegistrar.js +60 -44
- package/dist/mcp/documentHelpers.d.ts +1 -0
- package/dist/mcp/documentHelpers.js +7 -3
- package/dist/mcp/localServiceProxy.js +4 -1
- package/dist/mcp/runtime.d.ts +16 -0
- package/dist/mcp/runtime.js +735 -210
- package/dist/mcp/taskAttachmentCommandAdapter.d.ts +2 -0
- package/dist/mcp/taskAttachmentCommandAdapter.js +14 -8
- package/dist/mcp/taskPlanningRegistrar.js +78 -67
- package/dist/mcp/toolCallCompatibility.js +38 -1
- package/dist/mcp/toolCatalog.d.ts +1 -0
- package/dist/mcp/toolRegistry.js +2 -2
- package/dist/migrations/taskSchemaMigrations.js +47 -0
- package/dist/runtime/appGateDefinitions.d.ts +30 -6
- package/dist/runtime/appGateDefinitions.js +6 -6
- package/dist/runtime/appGates.d.ts +12 -13
- package/dist/runtime/appGates.js +29 -13
- package/dist/runtime/nodeAppGates.d.ts +8 -0
- package/dist/runtime/nodeAppGates.js +27 -0
- package/dist/server/appAccess.d.ts +12 -0
- package/dist/server/appAccess.js +21 -0
- package/dist/server/authorizedWorkspaceAccess.d.ts +12 -0
- package/dist/server/authorizedWorkspaceAccess.js +40 -0
- package/dist/server/cloudCollectionRead.d.ts +25 -0
- package/dist/server/cloudCollectionRead.js +120 -0
- package/dist/server/cloudCollectionReadPool.d.ts +52 -0
- package/dist/server/cloudCollectionReadPool.js +140 -0
- package/dist/server/cloudCollectionReadWorker.d.ts +1 -0
- package/dist/server/cloudCollectionReadWorker.js +36 -0
- package/dist/server/index.d.ts +6 -11
- package/dist/server/index.js +67 -42
- package/dist/server/localServiceLease.d.ts +6 -0
- package/dist/server/localServiceLease.js +17 -1
- package/dist/server/localWorkspaceSyncServerRuntime.js +10 -3
- package/dist/server/rateLimit.d.ts +1 -0
- package/dist/server/rateLimit.js +4 -0
- package/dist/server/realtimeSyncWs.js +36 -12
- package/dist/server/routes/admin.js +1 -0
- package/dist/server/routes/agentRoles.js +3 -2
- package/dist/server/routes/agentSkills.js +3 -2
- package/dist/server/routes/agents.js +118 -16
- package/dist/server/routes/annotatedAttachments.js +3 -2
- package/dist/server/routes/auth.js +3 -1
- package/dist/server/routes/documents.d.ts +5 -2
- package/dist/server/routes/documents.js +160 -13
- package/dist/server/routes/durableTaskHttpRouters.d.ts +11 -2
- package/dist/server/routes/durableTaskHttpRouters.js +2 -2
- package/dist/server/routes/localService.js +4 -0
- package/dist/server/routes/primitives.d.ts +4 -0
- package/dist/server/routes/shared.d.ts +24 -0
- package/dist/server/routes/shared.js +114 -18
- package/dist/server/routes/sync.js +22 -0
- package/dist/server/routes/syncAuxRoutes.js +5 -2
- package/dist/server/routes/syncPullApplyRoutes.js +23 -4
- package/dist/server/routes/syncV3FeedRoutes.js +22 -18
- package/dist/server/routes/syncV3LocalCaptureRoutes.js +48 -4
- package/dist/server/routes/syncV3LocalFeedApplyRoutes.d.ts +1 -0
- package/dist/server/routes/syncV3LocalFeedApplyRoutes.js +26 -0
- package/dist/server/routes/syncV3OperationRoutes.js +27 -2
- package/dist/server/routes/tasks.js +299 -97
- package/dist/server/routes/workspaces.js +43 -1
- package/dist/server/routes.js +35 -7
- package/dist/server/workspaceDeletionAdmission.d.ts +23 -0
- package/dist/server/workspaceDeletionAdmission.js +50 -0
- package/dist/service/localServiceCli.js +52 -25
- package/dist/service/localServiceClientLifecycle.js +93 -6
- package/dist/services/codexAppServerModelGateway.d.ts +112 -0
- package/dist/services/codexAppServerModelGateway.js +438 -0
- package/dist/services/taskforceAgentMcpBridge.d.ts +7 -1
- package/dist/services/taskforceAgentMcpBridge.js +23 -3
- package/dist/shared/planningIdentity.d.ts +20 -0
- package/dist/shared/planningIdentity.js +79 -0
- package/dist/shared/taskforceAgentDefinition.js +7 -1
- package/dist/shared/taskforceAgentModels.d.ts +1 -0
- package/dist/shared/taskforceAgentModels.js +30 -1
- package/dist/storage/postgresAdapter.d.ts +20 -3
- package/dist/storage/postgresAdapter.js +110 -14
- package/dist/storage/postgresRequestDiagnostics.d.ts +8 -0
- package/dist/storage/postgresRequestDiagnostics.js +24 -0
- package/dist/storage/postgresWorker.js +13 -4
- package/dist/storage/postgresWorkerProtocol.d.ts +29 -0
- package/dist/storage/postgresWorkerProtocol.js +30 -0
- package/dist/storage/workspaceAssetStore.d.ts +32 -0
- package/dist/storage/workspaceAssetStore.js +70 -0
- package/dist/sync/cloudSyncApi.d.ts +4 -1
- package/dist/sync/cloudSyncApi.js +7 -2
- package/dist/sync/contentSyncState.d.ts +1 -1
- package/dist/sync/coordinator/localSyncExecutionPermitStore.d.ts +17 -0
- package/dist/sync/coordinator/localSyncExecutionPermitStore.js +77 -23
- package/dist/sync/coordinator/localWorkspaceSyncRunner.js +6 -2
- package/dist/sync/coordinator/workspaceSyncTransportGateway.js +4 -2
- package/dist/sync/engine/workspaceSyncEngineBrowserGatewayRemoteServices.js +20 -2
- package/dist/sync/engine/workspaceSyncEngineLocalServices.d.ts +4 -0
- package/dist/sync/engine/workspaceSyncEngineLocalServices.js +11 -0
- package/dist/sync/engine/workspaceSyncEngineRemoteServices.d.ts +16 -0
- package/dist/sync/engine/workspaceSyncEngineRemoteServices.js +2 -1
- package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.d.ts +1 -1
- package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.js +46 -4
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.d.ts +3 -1
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +51 -11
- package/dist/sync/engine/workspaceSyncEngineTransfers.d.ts +1 -1
- package/dist/sync/engine/workspaceSyncEngineTransfers.js +8 -3
- package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +2 -0
- package/dist/sync/syncApplyHandlers.d.ts +3 -1
- package/dist/sync/syncApplyHandlers.js +29 -0
- package/dist/sync/syncService.d.ts +2 -0
- package/dist/sync/syncService.js +13 -1
- package/dist/sync/taskSyncPayload.d.ts +1 -0
- package/dist/sync/taskSyncPayload.js +6 -0
- package/dist/sync/v3/combinedFeedCapability.js +4 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.d.ts +3 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +31 -3
- package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +2 -0
- package/dist/sync/v3/durableTaskChecklistMutationRouter.js +4 -0
- package/dist/sync/v3/durableTaskHttpBulkMutationRouter.d.ts +1 -0
- package/dist/sync/v3/durableTaskHttpBulkMutationRouter.js +47 -12
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +5 -3
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +27 -2
- package/dist/sync/v3/localInitiativeOutboxService.js +4 -2
- package/dist/sync/v3/localOutboxDispatcher.js +5 -1
- package/dist/sync/v3/localTaskAttachmentLinksOutboxHandler.js +12 -2
- package/dist/sync/v3/localTaskAttachmentLinksOutboxService.d.ts +3 -0
- package/dist/sync/v3/localTaskAttachmentLinksOutboxService.js +62 -10
- package/dist/sync/v3/localTaskCreateOutboxService.js +15 -6
- package/dist/sync/v3/localTaskMetadataClient.d.ts +1 -0
- package/dist/sync/v3/localTaskMetadataClient.js +1 -0
- package/dist/sync/v3/localTaskMetadataOutboxHandler.js +5 -1
- package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -0
- package/dist/sync/v3/localTaskMetadataOutboxService.js +7 -0
- package/dist/sync/v3/localTaskRestoreOutboxService.js +14 -6
- package/dist/sync/v3/localTaskStatusClient.d.ts +1 -0
- package/dist/sync/v3/localTaskStatusClient.js +6 -1
- package/dist/sync/v3/localTaskStatusOutboxService.d.ts +2 -0
- package/dist/sync/v3/localTaskStatusOutboxService.js +54 -13
- package/dist/sync/v3/localWorkstreamOutboxService.js +4 -2
- package/dist/sync/v3/syncDurabilityStore.d.ts +15 -0
- package/dist/sync/v3/syncDurabilityStore.js +201 -43
- package/dist/sync/v3/taskAttachmentLinksMutationService.d.ts +7 -4
- package/dist/sync/v3/taskAttachmentLinksMutationService.js +37 -12
- package/dist/sync/v3/taskChecklistMutationService.d.ts +4 -2
- package/dist/sync/v3/taskChecklistMutationService.js +4 -0
- package/dist/sync/v3/taskCreateMutationService.d.ts +2 -2
- package/dist/sync/v3/taskCreateMutationService.js +7 -4
- package/dist/sync/v3/taskMetadataCoexistence.js +4 -0
- package/dist/sync/v3/taskMetadataMutationService.d.ts +3 -0
- package/dist/sync/v3/taskMetadataMutationService.js +4 -0
- package/dist/sync/v3/taskRestoreMutationService.d.ts +2 -2
- package/dist/sync/v3/taskRestoreMutationService.js +7 -4
- package/dist/sync/v3/taskStatusMutationService.d.ts +2 -0
- package/dist/sync/v3/taskStatusMutationService.js +4 -0
- package/dist/sync/v3/workflowAssignmentSync.d.ts +1 -0
- package/dist/sync/v3/workflowAssignmentSync.js +3 -0
- package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.d.ts +1 -1
- package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.js +14 -12
- package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.d.ts +11 -0
- package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.js +27 -10
- package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.d.ts +2 -1
- package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.js +52 -10
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +10 -1
- package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.js +15 -4
- package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +66 -13
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +11 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +57 -22
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +10 -4
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +124 -51
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +10 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +120 -28
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +3 -1
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +18 -0
- package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +6 -0
- package/dist/sync/v3/workspaceSyncV3FeedProfile.d.ts +1 -1
- package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.js +23 -10
- package/dist/sync/v3/workspaceSyncV3NestedTaskApply.d.ts +3 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskApply.js +64 -13
- package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.d.ts +9 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.js +26 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +15 -5
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +50 -14
- package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.d.ts +2 -1
- package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.js +11 -3
- package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +3 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +2 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +19 -7
- package/dist/sync/v3/workspaceSyncV3RepairSqlBatching.d.ts +2 -0
- package/dist/sync/v3/workspaceSyncV3RepairSqlBatching.js +10 -0
- package/dist/sync/v3/workspaceSyncV3TaskCommentAudit.js +9 -2
- package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.js +37 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.d.ts +6 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.js +9 -0
- package/dist/sync/v3/workspaceSyncV3TaskRootProjection.d.ts +1 -1
- package/dist/sync/v3/workspaceSyncV3TaskRootProjection.js +1 -1
- package/dist/sync/workspacePullFeed.d.ts +6 -1
- package/dist/sync/workspacePullFeed.js +174 -162
- package/dist/sync/workspaceRepair.d.ts +3 -0
- package/dist/sync/workspaceRepair.js +67 -6
- package/dist/sync/workspaceSyncModel.d.ts +11 -0
- package/dist/sync/workspaceSyncModel.js +27 -2
- package/dist/types.d.ts +55 -1
- package/dist/types.js +6 -0
- package/dist/ui/assets/{AiIdentityRosterCard-DB1BLO_j.js → AiIdentityRosterCard-BZM4aQnM.js} +1 -1
- package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +1 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-B68Wg-RV.js +3 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-TzYu7pkG.css +1 -0
- package/dist/ui/assets/AssetTraySortControl-C8Rztyal.js +1 -0
- package/dist/ui/assets/ContextAttachmentManager-Cj3c7X9y.js +3 -0
- package/dist/ui/assets/{DocumentWorkspace-BC7sy5TG.js → DocumentWorkspace-B5uvzems.js} +4 -4
- package/dist/ui/assets/EntityActivityTimeline-BVFvCB5R.js +1 -0
- package/dist/ui/assets/PlanningModule-B5DWQOGz.js +1 -0
- package/dist/ui/assets/PlanningModule-CoIR9hbV.css +1 -0
- package/dist/ui/assets/PlansPage-AY4cGWco.js +1 -0
- package/dist/ui/assets/TaskContextUpload-DZxTVesW.js +1 -0
- package/dist/ui/assets/TaskContextUpload-qmBeUw3u.css +1 -0
- package/dist/ui/assets/TaskSettings-BeWAuyZj.js +12 -0
- package/dist/ui/assets/{TaskforceAgentsModule-CkAxW19K.js → TaskforceAgentsModule-BifCYtjR.js} +6 -6
- package/dist/ui/assets/WorkflowManagerModule-DEr5di_r.js +1 -0
- package/dist/ui/assets/index-I5zhdtgt.js +7 -0
- package/dist/ui/assets/index-VRFsx3wz.css +1 -0
- package/dist/ui/assets/{vendor-icons-B8ZNsH1g.js → vendor-icons-D9Lpw-j4.js} +1 -1
- package/dist/ui/index.html +3 -3
- package/dist/utils/constants.d.ts +2 -2
- package/dist/utils/constants.js +1 -1
- package/dist/utils/contextAttachmentUpload.d.ts +2 -0
- package/dist/utils/contextAttachmentUpload.js +7 -0
- package/dist/utils/contextFiles.d.ts +1 -1
- package/dist/utils/contextFiles.js +4 -4
- package/dist/utils/taskActivity.d.ts +3 -2
- package/dist/utils/taskActivity.js +19 -2
- package/dist/utils/taskEditorReconciliation.d.ts +40 -0
- package/dist/utils/taskEditorReconciliation.js +217 -0
- package/dist/utils/taskNormalization.d.ts +1 -0
- package/dist/utils/taskNormalization.js +39 -0
- package/dist/utils/taskSearch.js +2 -2
- package/dist/utils/uiNotice.d.ts +4 -0
- package/package.json +21 -4
- package/dist/ui/assets/AiProfilesModule-DPxQeF9N.js +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-CBRZ8rca.css +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-DHNYaNg6.js +0 -3
- package/dist/ui/assets/AssetTraySortControl-DphbyHVc.js +0 -1
- package/dist/ui/assets/ContextAttachmentManager-CMxSzHqc.js +0 -3
- package/dist/ui/assets/EntityActivityTimeline-pJ2ZjZ-k.js +0 -1
- package/dist/ui/assets/PlanningModule-CeTqXMMz.css +0 -1
- package/dist/ui/assets/PlanningModule-t5GbvVR9.js +0 -1
- package/dist/ui/assets/PlansPage-BVH_NfgT.js +0 -1
- package/dist/ui/assets/TaskContextUpload-Ds4LnDzV.css +0 -1
- package/dist/ui/assets/TaskContextUpload-bl4fOOUz.js +0 -1
- package/dist/ui/assets/TaskSettings-xVsxSa0g.js +0 -12
- package/dist/ui/assets/WorkflowManagerModule-BKqIGVnF.js +0 -1
- package/dist/ui/assets/index-BzJlVnNS.css +0 -1
- package/dist/ui/assets/index-Cx7vZJHL.js +0 -7
|
@@ -35,6 +35,10 @@ export function useUiNotice() {
|
|
|
35
35
|
ttlMs,
|
|
36
36
|
actionLabel: action?.label,
|
|
37
37
|
onAction: action?.onAction,
|
|
38
|
+
actionPrimary: action?.primary,
|
|
39
|
+
secondaryActionLabel: action?.secondaryLabel,
|
|
40
|
+
onSecondaryAction: action?.onSecondaryAction,
|
|
41
|
+
dismissible: action?.dismissible,
|
|
38
42
|
ownerKey: action?.ownerKey
|
|
39
43
|
});
|
|
40
44
|
// Actionable notices stay available until the action or explicit
|
|
@@ -78,11 +78,11 @@ export function registerAdminWorkspaceTools(registerTool, executeTool) {
|
|
|
78
78
|
description: { type: 'string' },
|
|
79
79
|
category: { type: 'string' },
|
|
80
80
|
type: { type: 'string' },
|
|
81
|
-
priority: { type: '
|
|
81
|
+
priority: { type: 'integer', description: context.priorityDesc, enum: context.priorityEnum },
|
|
82
82
|
assignee: { type: 'string', description: `${context.assigneeHint} Call list_assignees to inspect the current eligible IDs.` },
|
|
83
83
|
owner: { type: 'string', description: `${context.assigneeHint} Alias for assignee.` },
|
|
84
84
|
status: { type: 'string', enum: ['task', 'on-hold', 'in-progress', 'review', 'done', 'cancelled'] },
|
|
85
|
-
complexity: { type: '
|
|
85
|
+
complexity: { type: 'integer', minimum: 1, maximum: 5, description: context.complexityDesc },
|
|
86
86
|
},
|
|
87
87
|
required: ['id'],
|
|
88
88
|
}),
|
|
@@ -101,7 +101,7 @@ export function registerAdminWorkspaceTools(registerTool, executeTool) {
|
|
|
101
101
|
priorities: arrayProperty('Ordered priority definitions to save.', {
|
|
102
102
|
type: 'object',
|
|
103
103
|
properties: {
|
|
104
|
-
value: { type: '
|
|
104
|
+
value: { type: 'integer', minimum: 1 },
|
|
105
105
|
label: { type: 'string' },
|
|
106
106
|
},
|
|
107
107
|
}),
|
|
@@ -35,12 +35,23 @@ export interface CanonicalAssetHelpersDeps {
|
|
|
35
35
|
assetId: string;
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
+
export declare class CanonicalDocumentHeadStaleError extends Error {
|
|
39
|
+
readonly details: Record<string, unknown>;
|
|
40
|
+
readonly code = "MCP_DOCUMENT_HEAD_STALE";
|
|
41
|
+
readonly statusCode = 409;
|
|
42
|
+
constructor(details: Record<string, unknown>);
|
|
43
|
+
}
|
|
38
44
|
export declare function createCanonicalAssetHelpers(deps: CanonicalAssetHelpersDeps): {
|
|
39
45
|
normalizeAttachmentStorageKey: (pathValue: unknown, fsPathValue: unknown) => string | null;
|
|
40
46
|
buildSyntheticAttachmentId: (taskId: string, attachment: TaskAttachmentRecord) => string;
|
|
41
47
|
getAttachmentAssetRecord: (attachment: TaskAttachmentRecord) => WorkspaceAssetEntry | null;
|
|
42
48
|
buildAttachmentDownloadUrl: (attachment: McpTaskAttachmentDescriptor) => string;
|
|
43
49
|
buildDocumentDownloadUrl: (asset: WorkspaceAssetEntry | WorkspaceDocumentEntry) => string;
|
|
50
|
+
assertCanonicalDocumentHeadCurrent: (asset: WorkspaceAssetEntry | WorkspaceDocumentEntry) => import("../sync/engine/workspaceSyncPublishedContentResolver.js").WorkspaceSyncPublishedLegacyContent | import("../sync/engine/workspaceSyncPublishedContentResolver.js").WorkspaceSyncPublishedVersionedContent | {
|
|
51
|
+
source: "legacy";
|
|
52
|
+
physicalKey: string;
|
|
53
|
+
storageProvider: import("../storage/objectStorage.js").ObjectStorageProvider;
|
|
54
|
+
};
|
|
44
55
|
readCanonicalAttachmentBuffer: (taskId: string, attachment: McpTaskAttachmentDescriptor, targetLabel?: string) => Promise<Buffer>;
|
|
45
56
|
readCanonicalDocumentBuffer: (asset: WorkspaceAssetEntry | WorkspaceDocumentEntry) => Promise<Buffer>;
|
|
46
57
|
toTaskAttachmentRecord: (attachment: string | TaskAttachmentRecord) => TaskAttachmentRecord;
|
|
@@ -68,6 +79,7 @@ export declare function createCanonicalAssetHelpers(deps: CanonicalAssetHelpersD
|
|
|
68
79
|
scanEngine?: string | null;
|
|
69
80
|
scanDetails?: string | null;
|
|
70
81
|
createLink?: boolean;
|
|
82
|
+
displayName?: string;
|
|
71
83
|
}) => Promise<WorkspaceAssetEntry | null>;
|
|
72
84
|
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?: {
|
|
73
85
|
originalFilename?: string;
|
|
@@ -80,6 +92,7 @@ export declare function createCanonicalAssetHelpers(deps: CanonicalAssetHelpersD
|
|
|
80
92
|
scanEngine?: string | null;
|
|
81
93
|
scanDetails?: string | null;
|
|
82
94
|
createLink?: boolean;
|
|
95
|
+
displayName?: string;
|
|
83
96
|
}) => Promise<WorkspaceAssetEntry | null>>[6]) => Promise<WorkspaceAssetEntry | null>;
|
|
84
97
|
buildCanonicalWorkspaceAssetRelativePath: (params: {
|
|
85
98
|
workspaceIdRaw: unknown;
|
|
@@ -3,6 +3,16 @@ import * as path from 'path';
|
|
|
3
3
|
import { createHash, randomUUID } from 'node:crypto';
|
|
4
4
|
import { verifyWorkspaceSyncPublishedContentBody, } from '../sync/engine/workspaceSyncPublishedContentResolver.js';
|
|
5
5
|
import { normalizeRelativeStorageKey, resolveExistingStorageKeyFilePathInsideRoot, resolveStorageKeyWritePathInsideRoot } from '../utils/pathSafety.js';
|
|
6
|
+
export class CanonicalDocumentHeadStaleError extends Error {
|
|
7
|
+
details;
|
|
8
|
+
code = 'MCP_DOCUMENT_HEAD_STALE';
|
|
9
|
+
statusCode = 409;
|
|
10
|
+
constructor(details) {
|
|
11
|
+
super('The published document head does not match the current canonical document metadata.');
|
|
12
|
+
this.details = details;
|
|
13
|
+
this.name = 'CanonicalDocumentHeadStaleError';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
6
16
|
export function createCanonicalAssetHelpers(deps) {
|
|
7
17
|
const normalizeAttachmentStorageKey = (pathValue, fsPathValue) => {
|
|
8
18
|
const fsPathRaw = String(fsPathValue || '').trim().replace(/\\/g, '/');
|
|
@@ -50,6 +60,30 @@ export function createCanonicalAssetHelpers(deps) {
|
|
|
50
60
|
legacyProvider: asset.storageProvider,
|
|
51
61
|
});
|
|
52
62
|
};
|
|
63
|
+
const assertCanonicalDocumentHeadCurrent = (asset) => {
|
|
64
|
+
const resolved = resolveCanonicalContentRead(asset, 'document');
|
|
65
|
+
if (resolved.source === 'deleted') {
|
|
66
|
+
throw new Error(`Document ${asset.assetId} not found in workspace ${deps.activeWorkspaceId}.`);
|
|
67
|
+
}
|
|
68
|
+
if (resolved.source === 'versioned' && (resolved.storageProvider !== asset.storageProvider
|
|
69
|
+
|| resolved.contentSha256 !== asset.contentSha256
|
|
70
|
+
|| resolved.sizeBytes !== asset.sizeBytes)) {
|
|
71
|
+
throw new CanonicalDocumentHeadStaleError({
|
|
72
|
+
assetId: asset.assetId,
|
|
73
|
+
currentVersion: asset.version,
|
|
74
|
+
currentStorageProvider: asset.storageProvider,
|
|
75
|
+
currentContentSha256: asset.contentSha256,
|
|
76
|
+
currentSizeBytes: asset.sizeBytes,
|
|
77
|
+
headVersionId: resolved.versionId,
|
|
78
|
+
headStorageProvider: resolved.storageProvider,
|
|
79
|
+
headContentSha256: resolved.contentSha256,
|
|
80
|
+
headSizeBytes: resolved.sizeBytes,
|
|
81
|
+
nextTool: 'update_document',
|
|
82
|
+
guidance: 'Retry update_document with the complete current body and expectedVersion to republish the canonical immutable head. Do not use the returned download until the repair succeeds.',
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return resolved;
|
|
86
|
+
};
|
|
53
87
|
const buildSyntheticAttachmentId = (taskId, attachment) => {
|
|
54
88
|
const stableSource = [
|
|
55
89
|
taskId,
|
|
@@ -157,10 +191,7 @@ export function createCanonicalAssetHelpers(deps) {
|
|
|
157
191
|
if (asset.scanStatus === 'pending') {
|
|
158
192
|
throw new Error('Document scan pending');
|
|
159
193
|
}
|
|
160
|
-
const resolved =
|
|
161
|
-
if (resolved.source === 'deleted') {
|
|
162
|
-
throw new Error(`Document ${asset.assetId} not found in workspace ${deps.activeWorkspaceId}.`);
|
|
163
|
-
}
|
|
194
|
+
const resolved = assertCanonicalDocumentHeadCurrent(asset);
|
|
164
195
|
if (resolved.storageProvider === 'r2') {
|
|
165
196
|
if (!normalizeRelativeStorageKey(resolved.physicalKey)) {
|
|
166
197
|
throw new Error(`Document ${asset.assetId} not found in workspace ${deps.activeWorkspaceId}.`);
|
|
@@ -324,7 +355,9 @@ export function createCanonicalAssetHelpers(deps) {
|
|
|
324
355
|
targetType,
|
|
325
356
|
targetId,
|
|
326
357
|
role,
|
|
327
|
-
displayName:
|
|
358
|
+
displayName: options?.displayName !== undefined
|
|
359
|
+
? options.displayName
|
|
360
|
+
: kind === 'document' ? null : (captionRaw || null),
|
|
328
361
|
updatedAt: timestamp,
|
|
329
362
|
deletedAt: null
|
|
330
363
|
});
|
|
@@ -338,6 +371,7 @@ export function createCanonicalAssetHelpers(deps) {
|
|
|
338
371
|
getAttachmentAssetRecord,
|
|
339
372
|
buildAttachmentDownloadUrl,
|
|
340
373
|
buildDocumentDownloadUrl,
|
|
374
|
+
assertCanonicalDocumentHeadCurrent,
|
|
341
375
|
readCanonicalAttachmentBuffer,
|
|
342
376
|
readCanonicalDocumentBuffer,
|
|
343
377
|
toTaskAttachmentRecord,
|
|
@@ -23,7 +23,7 @@ export function registerCollaborationTools(registerTool, executeTool) {
|
|
|
23
23
|
});
|
|
24
24
|
};
|
|
25
25
|
register('list_assignees', (context) => ({
|
|
26
|
-
description: context.describeTool('List eligible assignees for the active workspace.
|
|
26
|
+
description: context.describeTool('List eligible assignees for the active workspace. Includes members and AI profiles. Use query for a bounded ID, label, or username match.'),
|
|
27
27
|
inputSchema: {
|
|
28
28
|
properties: {
|
|
29
29
|
query: stringProperty('Optional case-insensitive substring matched against assignee ID, label, and username. When non-empty, returns at most 25 matches unless limit is set.'),
|
|
@@ -32,7 +32,7 @@ export function registerCollaborationTools(registerTool, executeTool) {
|
|
|
32
32
|
},
|
|
33
33
|
}));
|
|
34
34
|
register('get_current_profile', (context) => ({
|
|
35
|
-
description: context.describeTool('Inspect current AI identity for this call
|
|
35
|
+
description: context.describeTool('Inspect current AI identity for this call and write readiness. Stateless/scheduled agents may pass profileToken. Use before writes or to decide whether resolve_profile is needed.'),
|
|
36
36
|
inputSchema: {
|
|
37
37
|
properties: {
|
|
38
38
|
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.'),
|
|
@@ -40,24 +40,25 @@ export function registerCollaborationTools(registerTool, executeTool) {
|
|
|
40
40
|
},
|
|
41
41
|
}));
|
|
42
42
|
register('resolve_profile', (context) => ({
|
|
43
|
-
description: context.describeTool('Resolve or create this AI collaborator profile
|
|
43
|
+
description: context.describeTool('Resolve or create this AI collaborator profile using a stable product name. Stateless agents use name + surfaceType and may reuse profileToken. If OAuth recovery returns candidates, retry with profileId. Store profileToken privately only; pass it on writes. Never write profileToken to repos, tasks, logs, or docs.'),
|
|
44
44
|
inputSchema: {
|
|
45
45
|
properties: {
|
|
46
|
-
name: stringProperty('Stable
|
|
47
|
-
icon: stringProperty('Optional icon
|
|
48
|
-
color: stringProperty('Optional
|
|
49
|
-
description: stringProperty('Optional
|
|
50
|
-
role: stringProperty('Optional role label
|
|
51
|
-
provider: stringProperty('Optional provider
|
|
52
|
-
model: stringProperty('Optional model
|
|
46
|
+
name: stringProperty('Stable collaborator or product name; exclude model names and versions.'),
|
|
47
|
+
icon: stringProperty('Optional profile icon or emoji; omit to leave unchanged.'),
|
|
48
|
+
color: stringProperty('Optional Taskforce palette token or hex color; omit to use the assigned default or retain the current value.'),
|
|
49
|
+
description: stringProperty('Optional profile description; omit to leave unchanged.'),
|
|
50
|
+
role: stringProperty('Optional role label; omit to leave unchanged.'),
|
|
51
|
+
provider: stringProperty('Optional provider metadata; omit to leave unchanged.'),
|
|
52
|
+
model: stringProperty('Optional model metadata; omit to leave unchanged.'),
|
|
53
53
|
surfaceType: {
|
|
54
54
|
anyOf: [
|
|
55
55
|
{ type: 'string', enum: [...AI_PROFILE_SURFACE_TYPES] },
|
|
56
56
|
{ type: 'null' },
|
|
57
57
|
],
|
|
58
|
-
description: 'Optional
|
|
58
|
+
description: 'Optional surface: agent (persistent collaborator), cli (terminal coding agent), coding_tool (other coding surface), chat_app (chat app), or ide (IDE copilot). Use agent when unsure. Omit to retain; null or empty clears.',
|
|
59
59
|
},
|
|
60
|
-
|
|
60
|
+
profileId: stringProperty('Compatible profile ID from a prior selection-required response.'),
|
|
61
|
+
profileToken: stringProperty('Private token previously issued for this AI identity; reuses and optionally updates that profile.'),
|
|
61
62
|
},
|
|
62
63
|
required: ['name'],
|
|
63
64
|
},
|
|
@@ -73,11 +74,12 @@ export function registerCollaborationTools(registerTool, executeTool) {
|
|
|
73
74
|
},
|
|
74
75
|
}));
|
|
75
76
|
register('add_comment', (context) => ({
|
|
76
|
-
description: context.describeTool('Add a comment to a task.
|
|
77
|
+
description: context.describeTool('Add a comment to a task. Pass idempotencyKey when retrying after an ambiguous timeout; reuse it only with the exact same target and text.'),
|
|
77
78
|
inputSchema: {
|
|
78
79
|
properties: {
|
|
79
80
|
id: stringProperty('Task ID or task reference such as T-123.'),
|
|
80
81
|
text: stringProperty('Comment text.'),
|
|
82
|
+
idempotencyKey: { type: 'string', minLength: 1, maxLength: 128, description: 'Optional opaque retry key scoped to the active workspace, actor, and tool.' },
|
|
81
83
|
},
|
|
82
84
|
required: ['id', 'text'],
|
|
83
85
|
},
|
|
@@ -2,8 +2,16 @@ import { bindDomainTool } from './toolCatalog.js';
|
|
|
2
2
|
function stringProperty(description, enumValues) {
|
|
3
3
|
return enumValues ? { type: 'string', description, enum: enumValues } : { type: 'string', description };
|
|
4
4
|
}
|
|
5
|
-
function
|
|
6
|
-
return { type: 'number', description };
|
|
5
|
+
function boundedNumberProperty(description, minimum, maximum) {
|
|
6
|
+
return { type: 'number', description, minimum, maximum };
|
|
7
|
+
}
|
|
8
|
+
function integerProperty(description, minimum, maximum) {
|
|
9
|
+
return {
|
|
10
|
+
type: 'integer',
|
|
11
|
+
description,
|
|
12
|
+
...(minimum === undefined ? {} : { minimum }),
|
|
13
|
+
...(maximum === undefined ? {} : { maximum }),
|
|
14
|
+
};
|
|
7
15
|
}
|
|
8
16
|
function booleanProperty(description) {
|
|
9
17
|
return { type: 'boolean', description };
|
|
@@ -17,12 +25,12 @@ function annotatedAttachmentMarkerProperty() {
|
|
|
17
25
|
properties: {
|
|
18
26
|
type: { type: 'string' },
|
|
19
27
|
kind: { type: 'string' },
|
|
20
|
-
x: { type: 'number' },
|
|
21
|
-
y: { type: 'number' },
|
|
22
|
-
width: { type: 'number' },
|
|
23
|
-
height: { type: 'number' },
|
|
24
|
-
x2: { type: 'number' },
|
|
25
|
-
y2: { type: 'number' },
|
|
28
|
+
x: { type: 'number', minimum: 0, maximum: 1 },
|
|
29
|
+
y: { type: 'number', minimum: 0, maximum: 1 },
|
|
30
|
+
width: { type: 'number', minimum: 0, maximum: 1 },
|
|
31
|
+
height: { type: 'number', minimum: 0, maximum: 1 },
|
|
32
|
+
x2: { type: 'number', minimum: 0, maximum: 1 },
|
|
33
|
+
y2: { type: 'number', minimum: 0, maximum: 1 },
|
|
26
34
|
text: { type: 'string' },
|
|
27
35
|
instruction: { type: 'string' },
|
|
28
36
|
instructionType: { type: 'string' },
|
|
@@ -85,6 +93,7 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
85
93
|
properties: descriptor.inputSchema.properties,
|
|
86
94
|
...(descriptor.inputSchema.required ? { required: descriptor.inputSchema.required } : {}),
|
|
87
95
|
},
|
|
96
|
+
...(descriptor.annotations ? { annotations: descriptor.annotations } : {}),
|
|
88
97
|
};
|
|
89
98
|
},
|
|
90
99
|
handler: bindDomainTool(executeTool, name),
|
|
@@ -95,11 +104,11 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
95
104
|
inputSchema: {
|
|
96
105
|
properties: {
|
|
97
106
|
taskId: stringProperty('Task ID or task reference such as T-123.'),
|
|
98
|
-
id: stringProperty('Alias for taskId. Task ID or task reference such as T-123.'),
|
|
99
107
|
attachmentId: stringProperty('Optional attachment descriptor id to include content for one attachment.'),
|
|
100
108
|
format: stringProperty('Optional read format when attachmentId is provided. Use metadata for descriptors or download for a download URL.', ['text', 'metadata', 'download']),
|
|
101
|
-
maxChars:
|
|
109
|
+
maxChars: integerProperty('Optional max inline character count for readable text attachments. Longer content is truncated with size metadata and a download hint.', 1),
|
|
102
110
|
},
|
|
111
|
+
required: ['taskId'],
|
|
103
112
|
},
|
|
104
113
|
}));
|
|
105
114
|
register('get_workstream_attachments', (context) => ({
|
|
@@ -109,13 +118,14 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
109
118
|
id: stringProperty('Workstream ID or workstream reference such as WS-123.'),
|
|
110
119
|
attachmentId: stringProperty('Optional attachment descriptor id to include content for one attachment.'),
|
|
111
120
|
format: stringProperty('Optional read format when attachmentId is provided. Use metadata for descriptors or download for a download URL.', ['text', 'metadata', 'download']),
|
|
112
|
-
maxChars:
|
|
121
|
+
maxChars: integerProperty('Optional max inline character count for readable text attachments. Longer content is truncated with size metadata and a download hint.', 1),
|
|
113
122
|
},
|
|
114
123
|
required: ['id'],
|
|
115
124
|
},
|
|
116
125
|
}));
|
|
117
126
|
register('link_document', (context) => ({
|
|
118
127
|
description: context.describeTool('Link an existing canonical document to a task, initiative, or workstream without copying it. The operation is idempotent. Use search_documents first when you do not know the exact D-123 reference or asset id.'),
|
|
128
|
+
annotations: { idempotentHint: true },
|
|
119
129
|
inputSchema: {
|
|
120
130
|
properties: {
|
|
121
131
|
documentId: stringProperty('Canonical document reference such as D-123, document id, or asset id.'),
|
|
@@ -139,6 +149,7 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
139
149
|
}));
|
|
140
150
|
register('rehome_document', (context) => ({
|
|
141
151
|
description: context.describeTool('Atomically move an existing canonical document reference between a task, initiative, or workstream without copying or deleting the document. Use this instead of separate link_document and unlink_document calls when correcting planning scope.'),
|
|
152
|
+
annotations: { idempotentHint: true },
|
|
142
153
|
inputSchema: {
|
|
143
154
|
properties: {
|
|
144
155
|
documentId: stringProperty('Canonical document reference such as D-123, document id, or asset id.'),
|
|
@@ -159,18 +170,18 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
159
170
|
}));
|
|
160
171
|
register('save_workstream_attachment', (context) => ({
|
|
161
172
|
description: context.describeTool(context.runtimeMode === 'cloud'
|
|
162
|
-
? 'Save
|
|
163
|
-
: 'Save
|
|
173
|
+
? 'Save inline content as a workstream-owned attachment. Use overwrite=true to replace the same filename.'
|
|
174
|
+
: 'Save inline content or an approved local file as a workstream-owned attachment. Use overwrite=true to replace the same filename.'),
|
|
164
175
|
inputSchema: {
|
|
165
176
|
properties: {
|
|
166
177
|
id: stringProperty('Workstream ID or workstream reference such as WS-123.'),
|
|
167
178
|
filename: stringProperty('Destination filename for the attachment.'),
|
|
168
|
-
content: stringProperty('Inline
|
|
179
|
+
content: stringProperty('Inline text content.'),
|
|
169
180
|
...(context.runtimeMode === 'local' ? {
|
|
170
181
|
sourcePath: stringProperty("Existing local file. Allowed roots: project, registered Git worktrees, Taskforce-managed sources, approved agent workspaces, or the bound profile's ~/.taskforce/qa/<username>/artifacts."),
|
|
171
182
|
} : {}),
|
|
172
183
|
caption: stringProperty('Optional attachment caption.'),
|
|
173
|
-
overwrite: booleanProperty('
|
|
184
|
+
overwrite: booleanProperty('Replace the existing attachment with the same filename.'),
|
|
174
185
|
},
|
|
175
186
|
required: ['id', 'filename'],
|
|
176
187
|
},
|
|
@@ -192,25 +203,25 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
192
203
|
id: stringProperty('Initiative ID or initiative reference such as IN-123.'),
|
|
193
204
|
attachmentId: stringProperty('Optional attachment descriptor id to include content for one attachment.'),
|
|
194
205
|
format: stringProperty('Optional read format when attachmentId is provided. Use metadata for descriptors or download for a download URL.', ['text', 'metadata', 'download']),
|
|
195
|
-
maxChars:
|
|
206
|
+
maxChars: integerProperty('Optional max inline character count for readable text attachments. Longer content is truncated with size metadata and a download hint.', 1),
|
|
196
207
|
},
|
|
197
208
|
required: ['id'],
|
|
198
209
|
},
|
|
199
210
|
}));
|
|
200
211
|
register('save_initiative_attachment', (context) => ({
|
|
201
212
|
description: context.describeTool(context.runtimeMode === 'cloud'
|
|
202
|
-
? 'Save
|
|
203
|
-
: 'Save
|
|
213
|
+
? 'Save inline content as an initiative-owned attachment. Use overwrite=true to replace the same filename.'
|
|
214
|
+
: 'Save inline content or an approved local file as an initiative-owned attachment. Use overwrite=true to replace the same filename.'),
|
|
204
215
|
inputSchema: {
|
|
205
216
|
properties: {
|
|
206
217
|
id: stringProperty('Initiative ID or initiative reference such as IN-123.'),
|
|
207
218
|
filename: stringProperty('Destination filename for the attachment.'),
|
|
208
|
-
content: stringProperty('Inline
|
|
219
|
+
content: stringProperty('Inline text content.'),
|
|
209
220
|
...(context.runtimeMode === 'local' ? {
|
|
210
221
|
sourcePath: stringProperty("Existing local file. Allowed roots: project, registered Git worktrees, Taskforce-managed sources, approved agent workspaces, or the bound profile's ~/.taskforce/qa/<username>/artifacts."),
|
|
211
222
|
} : {}),
|
|
212
223
|
caption: stringProperty('Optional attachment caption.'),
|
|
213
|
-
overwrite: booleanProperty('
|
|
224
|
+
overwrite: booleanProperty('Replace the existing attachment with the same filename.'),
|
|
214
225
|
},
|
|
215
226
|
required: ['id', 'filename'],
|
|
216
227
|
},
|
|
@@ -226,11 +237,12 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
226
237
|
},
|
|
227
238
|
}));
|
|
228
239
|
register('search_images', (context) => ({
|
|
229
|
-
description: context.describeTool('Search image assets by keyword, title, filename, caption, or I-123 reference. Use
|
|
240
|
+
description: context.describeTool('Search image assets by keyword, title, filename, caption, or I-123 reference. Use offset/limit to continue broad searches, then call get_image for the selected result.'),
|
|
230
241
|
inputSchema: {
|
|
231
242
|
properties: {
|
|
232
243
|
query: stringProperty('Search term for image lookup, including I-123 references.'),
|
|
233
|
-
limit:
|
|
244
|
+
limit: integerProperty('Page size (default 10; max 50).', 1, 50),
|
|
245
|
+
offset: integerProperty('Non-negative result offset (default 0).', 0),
|
|
234
246
|
},
|
|
235
247
|
required: ['query'],
|
|
236
248
|
},
|
|
@@ -239,17 +251,18 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
239
251
|
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_image_annotations for saved annotation sessions and payloads. When the image is being used for UI, placement, or visual correction feedback, read the saved annotation payload before making changes.'),
|
|
240
252
|
inputSchema: {
|
|
241
253
|
properties: {
|
|
242
|
-
|
|
243
|
-
imageId: stringProperty('Alias for id. Image asset id or image reference such as I-123.'),
|
|
254
|
+
imageId: stringProperty('Image asset id or image reference such as I-123.'),
|
|
244
255
|
},
|
|
256
|
+
required: ['imageId'],
|
|
245
257
|
},
|
|
246
258
|
}));
|
|
247
259
|
register('search_documents', (context) => ({
|
|
248
|
-
description: context.describeTool('Search document assets by keyword, title, filename, caption, or D-123 reference. Use
|
|
260
|
+
description: context.describeTool('Search document assets by keyword, title, filename, caption, or D-123 reference. Use offset/limit to continue broad searches, then call get_document for the selected result.'),
|
|
249
261
|
inputSchema: {
|
|
250
262
|
properties: {
|
|
251
263
|
query: stringProperty('Search term for document lookup, including D-123 references.'),
|
|
252
|
-
limit:
|
|
264
|
+
limit: integerProperty('Page size (default 10; max 50).', 1, 50),
|
|
265
|
+
offset: integerProperty('Non-negative result offset (default 0).', 0),
|
|
253
266
|
},
|
|
254
267
|
required: ['query'],
|
|
255
268
|
},
|
|
@@ -261,8 +274,9 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
261
274
|
documentId: stringProperty('Document asset id or document reference such as D-123.'),
|
|
262
275
|
includeContent: booleanProperty('When true, include bounded inline text content or a download reference for binary documents.'),
|
|
263
276
|
format: stringProperty('Optional read mode when including content.', ['metadata', 'text', 'content', 'full', 'download']),
|
|
264
|
-
maxChars:
|
|
277
|
+
maxChars: integerProperty('Optional max inline character count for readable documents. Longer content is truncated with size metadata and a download hint.', 1),
|
|
265
278
|
},
|
|
279
|
+
required: ['documentId'],
|
|
266
280
|
},
|
|
267
281
|
}));
|
|
268
282
|
register('update_document', (context) => ({
|
|
@@ -285,7 +299,6 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
285
299
|
inputSchema: {
|
|
286
300
|
properties: {
|
|
287
301
|
imageId: stringProperty('Image asset id or image reference such as I-123.'),
|
|
288
|
-
imageAssetId: stringProperty('Alias for imageId. Image asset id or image reference such as I-123.'),
|
|
289
302
|
taskId: stringProperty('Optional task ID or task reference such as T-123 to narrow sessions linked to one task.'),
|
|
290
303
|
sessionId: stringProperty('Optional annotated attachment session id to include the structured payload for one session.'),
|
|
291
304
|
},
|
|
@@ -344,16 +357,16 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
344
357
|
sessionId: stringProperty('Annotated attachment session id.'),
|
|
345
358
|
type: stringProperty('Marker type.'),
|
|
346
359
|
kind: stringProperty('Alias for type. Marker kind: pin, box, arrow, or text-note.'),
|
|
347
|
-
x:
|
|
348
|
-
y:
|
|
349
|
-
width:
|
|
350
|
-
height:
|
|
360
|
+
x: boundedNumberProperty('Normalized x coordinate in the 0..1 range.', 0, 1),
|
|
361
|
+
y: boundedNumberProperty('Normalized y coordinate in the 0..1 range.', 0, 1),
|
|
362
|
+
width: boundedNumberProperty('Optional normalized width in the 0..1 range.', 0, 1),
|
|
363
|
+
height: boundedNumberProperty('Optional normalized height in the 0..1 range.', 0, 1),
|
|
351
364
|
text: stringProperty('Optional marker text or note.'),
|
|
352
365
|
instruction: stringProperty('Alias for text. Marker instruction or note.'),
|
|
353
366
|
instructionType: stringProperty('Optional marker instruction category.'),
|
|
354
367
|
color: stringProperty('Optional marker color.'),
|
|
355
|
-
x2:
|
|
356
|
-
y2:
|
|
368
|
+
x2: boundedNumberProperty('Arrow endpoint normalized x coordinate.', 0, 1),
|
|
369
|
+
y2: boundedNumberProperty('Arrow endpoint normalized y coordinate.', 0, 1),
|
|
357
370
|
},
|
|
358
371
|
required: ['sessionId'],
|
|
359
372
|
},
|
|
@@ -374,12 +387,12 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
374
387
|
properties: {
|
|
375
388
|
sessionId: stringProperty('Annotated attachment session id.'),
|
|
376
389
|
markerId: stringProperty('Marker id within the session.'),
|
|
377
|
-
x:
|
|
378
|
-
y:
|
|
379
|
-
width:
|
|
380
|
-
height:
|
|
381
|
-
x2:
|
|
382
|
-
y2:
|
|
390
|
+
x: boundedNumberProperty('Updated normalized x coordinate.', 0, 1),
|
|
391
|
+
y: boundedNumberProperty('Updated normalized y coordinate.', 0, 1),
|
|
392
|
+
width: boundedNumberProperty('Updated normalized width.', 0, 1),
|
|
393
|
+
height: boundedNumberProperty('Updated normalized height.', 0, 1),
|
|
394
|
+
x2: boundedNumberProperty('Updated arrow endpoint normalized x coordinate.', 0, 1),
|
|
395
|
+
y2: boundedNumberProperty('Updated arrow endpoint normalized y coordinate.', 0, 1),
|
|
383
396
|
instruction: stringProperty('Updated marker instruction.'),
|
|
384
397
|
instructionType: stringProperty('Updated marker instruction category.'),
|
|
385
398
|
color: stringProperty('Updated marker color.'),
|
|
@@ -393,7 +406,7 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
393
406
|
properties: {
|
|
394
407
|
sessionId: stringProperty('Annotated attachment session id.'),
|
|
395
408
|
markerId: stringProperty('Marker id within the session.'),
|
|
396
|
-
toIndex:
|
|
409
|
+
toIndex: integerProperty('Target zero-based review order.', 0),
|
|
397
410
|
},
|
|
398
411
|
required: ['sessionId', 'markerId', 'toIndex'],
|
|
399
412
|
},
|
|
@@ -466,13 +479,14 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
466
479
|
},
|
|
467
480
|
}));
|
|
468
481
|
register('add_document_review_comment', (context) => ({
|
|
469
|
-
description: context.describeTool('Add one follow-up comment to an existing review session. Prefer review_document for
|
|
482
|
+
description: context.describeTool('Add one follow-up comment to an existing review session. Prefer review_document for a complete review. Pass idempotencyKey only for exact retries after an ambiguous timeout.'),
|
|
470
483
|
inputSchema: {
|
|
471
484
|
properties: {
|
|
472
485
|
sessionId: stringProperty('Document review session id.'),
|
|
473
486
|
body: stringProperty('Comment text.'),
|
|
474
487
|
anchor: documentReviewAnchorProperty(),
|
|
475
488
|
parentCommentId: stringProperty('Optional root comment id. When supplied, adds a reply to that one-level thread; replies cannot target other replies.'),
|
|
489
|
+
idempotencyKey: { type: 'string', minLength: 1, maxLength: 128, description: 'Optional opaque retry key scoped to the active workspace, actor, and tool.' },
|
|
476
490
|
},
|
|
477
491
|
required: ['sessionId', 'body'],
|
|
478
492
|
},
|
|
@@ -536,10 +550,11 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
536
550
|
uploadedPath: stringProperty('Finalize a previously staged remote upload by passing the uploaded Taskforce storage path returned by save_task_attachment init mode.'),
|
|
537
551
|
uploadDraftId: stringProperty('Finalize a previously staged remote upload by passing the uploadDraftId returned by save_task_attachment init mode.'),
|
|
538
552
|
mimeType: stringProperty('Mime type for staged remote uploads such as image/png or image/jpeg. Provide this with sizeBytes to start a staged upload.'),
|
|
539
|
-
sizeBytes:
|
|
553
|
+
sizeBytes: integerProperty('File size in bytes for staged remote uploads. Provide this with mimeType to start a staged upload.', 0),
|
|
540
554
|
}),
|
|
541
|
-
expectedSizeBytes:
|
|
555
|
+
expectedSizeBytes: integerProperty('Optional exact byte count for integrity verification. The save is rejected before attachment when the persisted bytes would differ.', 0),
|
|
542
556
|
expectedSha256: stringProperty('Optional lowercase or uppercase SHA-256 hex digest for integrity verification. The save is rejected before attachment when the persisted bytes would differ.'),
|
|
557
|
+
displayName: stringProperty('Optional attachment display name. Defaults to filename and is independent from caption.'),
|
|
543
558
|
caption: stringProperty('Optional attachment caption.'),
|
|
544
559
|
overwrite: booleanProperty('When true, overwrite an existing canonical task attachment with the same filename instead of creating a new one.'),
|
|
545
560
|
},
|
|
@@ -548,6 +563,7 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
|
|
|
548
563
|
}));
|
|
549
564
|
register('set_task_plan', (context) => ({
|
|
550
565
|
description: context.describeTool('Create or replace the canonical Markdown implementation plan for a task. Identical retries are no-ops. Optionally replace the task description with a concise summary after the plan is verified; a description failure preserves the valid plan and returns partial-success recovery guidance.'),
|
|
566
|
+
annotations: { idempotentHint: true },
|
|
551
567
|
inputSchema: {
|
|
552
568
|
properties: {
|
|
553
569
|
taskId: stringProperty('Task ID or task reference such as T-123.'),
|
|
@@ -51,8 +51,10 @@ export function createDocumentHelpers(deps) {
|
|
|
51
51
|
}
|
|
52
52
|
const requestedLimit = Number(options?.limit);
|
|
53
53
|
const limit = Number.isFinite(requestedLimit)
|
|
54
|
-
? Math.max(1, Math.min(
|
|
54
|
+
? Math.max(1, Math.min(51, Math.trunc(requestedLimit)))
|
|
55
55
|
: 10;
|
|
56
|
+
const requestedOffset = Number(options?.offset);
|
|
57
|
+
const offset = Number.isFinite(requestedOffset) ? Math.max(0, Math.trunc(requestedOffset)) : 0;
|
|
56
58
|
const normalize = (value) => typeof value === 'string' ? value.trim().toLowerCase() : '';
|
|
57
59
|
const tokenize = (value) => normalize(value).split(/[^a-z0-9]+/i).filter(Boolean);
|
|
58
60
|
const allDocuments = deps.workspaceAssetStore.listDocumentsByWorkspace(deps.activeWorkspaceId);
|
|
@@ -103,8 +105,10 @@ export function createDocumentHelpers(deps) {
|
|
|
103
105
|
return [{ asset, matchedOn: Array.from(matchedOn), score }];
|
|
104
106
|
});
|
|
105
107
|
return scoredMatches
|
|
106
|
-
.sort((a, b) => b.score - a.score
|
|
107
|
-
.
|
|
108
|
+
.sort((a, b) => b.score - a.score
|
|
109
|
+
|| String(b.asset.updatedAt || '').localeCompare(String(a.asset.updatedAt || ''))
|
|
110
|
+
|| a.asset.assetId.localeCompare(b.asset.assetId))
|
|
111
|
+
.slice(offset, offset + limit);
|
|
108
112
|
};
|
|
109
113
|
const resolveDocumentAssetByIdentifierOrThrow = (documentIdentifier, options) => {
|
|
110
114
|
const normalizedValue = typeof documentIdentifier === 'string' ? documentIdentifier.trim() : '';
|
|
@@ -3,6 +3,7 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
|
3
3
|
import { JSONRPCMessageSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
4
4
|
import { normalizeMcpConnectionId, parseMcpClientId } from './clientRegistry.js';
|
|
5
5
|
import { normalizeMcpToolProfile } from './toolProfiles.js';
|
|
6
|
+
import { localServiceCloudTargetsEqual, parseLocalServiceCloudTarget, } from '../config/localServiceCloudTarget.js';
|
|
6
7
|
import { discoverOrStartLocalService, LOCAL_SERVICE_API_BASE_PATH, LOCAL_SERVICE_PROTOCOL_VERSION, } from '../service/localServiceClientLifecycle.js';
|
|
7
8
|
const REQUEST_TIMEOUT_MS = 120_000;
|
|
8
9
|
const MAX_IN_FLIGHT = 32;
|
|
@@ -24,6 +25,7 @@ async function readJson(response, label) {
|
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
27
|
function validateReadiness(readiness, descriptor) {
|
|
28
|
+
const readinessCloudTarget = parseLocalServiceCloudTarget(readiness.cloudTarget);
|
|
27
29
|
if (!readiness.ready)
|
|
28
30
|
throw new Error('Taskforce shared local service is not accepting new work.');
|
|
29
31
|
if (readiness.protocolVersion !== LOCAL_SERVICE_PROTOCOL_VERSION
|
|
@@ -31,7 +33,8 @@ function validateReadiness(readiness, descriptor) {
|
|
|
31
33
|
|| readiness.generation !== descriptor.generation
|
|
32
34
|
|| readiness.pid !== descriptor.pid
|
|
33
35
|
|| readiness.endpoint !== descriptor.endpoint
|
|
34
|
-
|| readiness.dataIdentity !== descriptor.ownershipKey
|
|
36
|
+
|| readiness.dataIdentity !== descriptor.ownershipKey
|
|
37
|
+
|| !localServiceCloudTargetsEqual(readinessCloudTarget, descriptor.cloudTarget)) {
|
|
35
38
|
throw new Error('Taskforce shared local service readiness does not match its descriptor.');
|
|
36
39
|
}
|
|
37
40
|
}
|
package/dist/mcp/runtime.d.ts
CHANGED
|
@@ -16,6 +16,18 @@ import { createDurableTaskCommentMutationRouter } from '../sync/v3/durableTaskCo
|
|
|
16
16
|
import { createDurableTaskChecklistMutationRouter } from '../sync/v3/durableTaskChecklistMutationRouter.js';
|
|
17
17
|
import { createDurableTaskAttachmentLinksMutationRouter } from '../sync/v3/durableTaskAttachmentLinksMutationRouter.js';
|
|
18
18
|
import type { LocalDataOwnerPermit } from '../server/localDataOwnerPermit.js';
|
|
19
|
+
export type McpToolCallTiming = {
|
|
20
|
+
requestId: string | null;
|
|
21
|
+
toolName: string;
|
|
22
|
+
isWrite: boolean;
|
|
23
|
+
outcome: 'success' | 'failure';
|
|
24
|
+
totalMs: number;
|
|
25
|
+
preparationMs: number;
|
|
26
|
+
validationMs: number;
|
|
27
|
+
handlerMs: number;
|
|
28
|
+
responseBytes: number;
|
|
29
|
+
subphases: Record<string, number>;
|
|
30
|
+
};
|
|
19
31
|
export interface TaskforceMcpServerOptions {
|
|
20
32
|
projectRoot?: string;
|
|
21
33
|
tenantId?: string;
|
|
@@ -34,6 +46,7 @@ export interface TaskforceMcpServerOptions {
|
|
|
34
46
|
mutationKind: string;
|
|
35
47
|
payloadFingerprint: string;
|
|
36
48
|
}) => void;
|
|
49
|
+
onToolCallTiming?: (timing: McpToolCallTiming) => void;
|
|
37
50
|
operationIdentityScope?: {
|
|
38
51
|
generation: string;
|
|
39
52
|
sessionId: string;
|
|
@@ -45,10 +58,12 @@ export interface TaskforceMcpServerOptions {
|
|
|
45
58
|
durableTaxonomyMutationRouter?: ReturnType<typeof createDurableTaxonomyMutationRouter>;
|
|
46
59
|
durableInitiativeMutationRouterFactory?: (actorRef: string, options?: {
|
|
47
60
|
operationId?: string;
|
|
61
|
+
commentId?: string;
|
|
48
62
|
deferPostCommitNotification?: (notify: () => void) => void;
|
|
49
63
|
}) => ReturnType<typeof createDurableInitiativeMutationRouter>;
|
|
50
64
|
durableWorkstreamMutationRouterFactory?: (actorRef: string, options?: {
|
|
51
65
|
operationId?: string;
|
|
66
|
+
commentId?: string;
|
|
52
67
|
deferPostCommitNotification?: (notify: () => void) => void;
|
|
53
68
|
}) => ReturnType<typeof createDurableWorkstreamMutationRouter>;
|
|
54
69
|
durableTaskRelationshipMutationRouter?: ReturnType<typeof createDurableTaskRelationshipMutationRouter>;
|
|
@@ -62,6 +77,7 @@ export interface TaskforceMcpServerOptions {
|
|
|
62
77
|
userId?: string | null;
|
|
63
78
|
tokenId?: string | null;
|
|
64
79
|
aiProfileId?: string | null;
|
|
80
|
+
aiProfileIdentityAsserted?: boolean;
|
|
65
81
|
aiProfileToken?: AiProfileBootstrapConfig['aiProfileToken'];
|
|
66
82
|
aiProfileName?: AiProfileBootstrapConfig['aiProfileName'];
|
|
67
83
|
aiProfileIcon?: AiProfileBootstrapConfig['aiProfileIcon'];
|