@taskforcehq/taskforce 0.3.329 → 0.3.332
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -2
- package/dist/Taskforce.module.css +290 -45
- package/dist/components/features/AiProfilesModule.js +3 -5
- package/dist/components/features/TaskSettings.js +70 -14
- package/dist/components/features/TaskforceAgentsModule.d.ts +1 -2
- package/dist/components/features/TaskforceAgentsModule.js +586 -116
- package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.d.ts +2 -2
- package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.js +2 -2
- package/dist/components/features/agentConnections/AgentConnectionControl.d.ts +15 -0
- package/dist/components/features/agentConnections/AgentConnectionControl.js +125 -0
- package/dist/components/features/agentConnections/ModelConnectionsPanel.d.ts +18 -0
- package/dist/components/features/agentConnections/ModelConnectionsPanel.js +393 -0
- package/dist/components/features/agentConnections/modelConnectionsApi.d.ts +65 -0
- package/dist/components/features/agentConnections/modelConnectionsApi.js +129 -0
- package/dist/components/features/planning/PlanningModule.js +15 -3
- package/dist/components/features/planning/planningMetadata.d.ts +10 -0
- package/dist/components/features/planning/planningMetadata.js +8 -0
- package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +15 -24
- package/dist/components/features/taskforceAgentEditorModel.d.ts +2 -1
- package/dist/components/features/taskforceAgentEditorModel.js +3 -1
- package/dist/components/features/workflowManager/workflowManagerApi.d.ts +1 -1
- package/dist/components/features/workflowManager/workflowManagerApi.js +3 -0
- package/dist/components/task/TaskWorkflowAssignmentField.js +68 -10
- package/dist/components/views/StandaloneLayout.js +62 -27
- package/dist/components/views/panels/PlanningDrawer.d.ts +2 -1
- package/dist/components/views/panels/PlanningDrawer.js +12 -8
- package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +4 -3
- package/dist/components/views/standalone/modals/SyncStatusModal.js +33 -38
- package/dist/config/envSchema.js +55 -1
- package/dist/core/McpTokenService.d.ts +25 -1
- package/dist/core/McpTokenService.js +106 -15
- package/dist/core/TaskChecklistCommandService.d.ts +27 -0
- package/dist/core/TaskChecklistCommandService.js +83 -5
- package/dist/core/TaskLifecycleCommandService.d.ts +3 -1
- package/dist/core/TaskLifecycleCommandService.js +6 -2
- package/dist/core/Taskforce.d.ts +43 -3
- package/dist/core/Taskforce.js +158 -7
- package/dist/core/types.d.ts +9 -0
- package/dist/documentReviews/DocumentReviewCommentStore.d.ts +2 -0
- package/dist/documentReviews/DocumentReviewCommentStore.js +28 -9
- package/dist/documentReviews/commandService.d.ts +2 -1
- package/dist/documentReviews/commandService.js +6 -3
- package/dist/hooks/sync/orchestratorShared.d.ts +1 -0
- package/dist/hooks/sync/orchestratorShared.js +2 -0
- package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.d.ts +3 -0
- package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.js +85 -9
- package/dist/hooks/sync/useSyncStatusControls.d.ts +4 -1
- package/dist/hooks/sync/useSyncStatusControls.js +47 -11
- package/dist/hooks/useSyncOrchestrator.d.ts +3 -0
- package/dist/hooks/useSyncOrchestrator.js +111 -2
- package/dist/hooks/useTaskData.d.ts +31 -1
- package/dist/hooks/useTaskData.js +29 -7
- package/dist/hooks/useTaskMutations.d.ts +3 -1
- package/dist/hooks/useTaskMutations.js +46 -12
- package/dist/hooks/useTaskforce.d.ts +2 -0
- package/dist/hooks/useTaskforce.js +11 -2
- package/dist/mcp/clientRegistry.d.ts +2 -2
- package/dist/mcp/clientRegistry.js +1 -1
- package/dist/mcp/documentAssetRegistrar.js +9 -6
- package/dist/mcp/durableTaskMutationRouter.d.ts +4 -1
- package/dist/mcp/durableTaskMutationRouter.js +10 -0
- package/dist/mcp/durableTaskRelationshipMutationRouter.js +4 -0
- package/dist/mcp/httpProtocolRouting.d.ts +11 -0
- package/dist/mcp/httpProtocolRouting.js +22 -0
- package/dist/mcp/localCliHealth.d.ts +2 -2
- package/dist/mcp/localCliHealth.js +2 -2
- package/dist/mcp/localServiceProxy.d.ts +1 -0
- package/dist/mcp/localServiceProxy.js +530 -68
- package/dist/mcp/planningAttachmentCommandAdapter.d.ts +3 -1
- package/dist/mcp/planningAttachmentCommandAdapter.js +20 -2
- package/dist/mcp/runtime.d.ts +54 -79
- package/dist/mcp/runtime.js +408 -102
- package/dist/mcp/taskPlanningRegistrar.js +25 -6
- package/dist/mcp/toolProfiles.d.ts +2 -0
- package/dist/mcp/toolProfiles.js +11 -0
- package/dist/mcp/toolRegistry.d.ts +1 -0
- package/dist/mcp/toolRegistry.js +9 -8
- package/dist/mcp/workflowExecutionRegistrar.js +4 -4
- package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
- package/dist/migrations/taskSchemaMigrations.js +415 -0
- package/dist/runtime/appGates.d.ts +2 -1
- package/dist/runtime/appGates.js +7 -0
- package/dist/server/buildInfo.d.ts +1 -0
- package/dist/server/buildInfo.js +5 -1
- package/dist/server/cloudMcpCapacityTelemetry.d.ts +68 -0
- package/dist/server/cloudMcpCapacityTelemetry.js +221 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +108 -11
- package/dist/server/localDatabaseIdentity.js +4 -1
- package/dist/server/localServiceLease.js +2 -1
- package/dist/server/localServiceSessions.d.ts +14 -17
- package/dist/server/localServiceSessions.js +308 -94
- package/dist/server/localWorkspaceSyncServerRuntime.js +25 -19
- package/dist/server/routes/admin.d.ts +4 -0
- package/dist/server/routes/admin.js +126 -5
- package/dist/server/routes/agents.d.ts +7 -0
- package/dist/server/routes/agents.js +277 -24
- package/dist/server/routes/billing.js +5 -1
- package/dist/server/routes/durableTaskHttpRouters.d.ts +2 -0
- package/dist/server/routes/executorPhaseAApprovals.d.ts +19 -0
- package/dist/server/routes/executorPhaseAApprovals.js +140 -0
- package/dist/server/routes/executorPhaseAIssuerRedemptions.d.ts +11 -0
- package/dist/server/routes/executorPhaseAIssuerRedemptions.js +24 -0
- package/dist/server/routes/githubReviewEvidence.d.ts +19 -0
- package/dist/server/routes/githubReviewEvidence.js +116 -0
- package/dist/server/routes/localService.d.ts +15 -4
- package/dist/server/routes/localService.js +136 -40
- package/dist/server/routes/modelConnections.d.ts +24 -0
- package/dist/server/routes/modelConnections.js +205 -0
- package/dist/server/routes/shared.d.ts +22 -0
- package/dist/server/routes/shared.js +298 -182
- package/dist/server/routes/sync.js +1 -0
- package/dist/server/routes/syncAuxRoutes.js +5 -1
- package/dist/server/routes/syncPushRoutes.d.ts +1 -0
- package/dist/server/routes/syncPushRoutes.js +1 -0
- package/dist/server/routes/syncV3FeedRoutes.js +10 -1
- package/dist/server/routes/syncV3OperationRoutes.js +35 -9
- package/dist/server/routes/tasks.js +21 -2
- package/dist/server/routes/workflows.js +9 -1
- package/dist/server/routes.js +59 -0
- package/dist/service/localServiceCli.d.ts +2 -2
- package/dist/service/localServiceCli.js +4 -3
- package/dist/services/codexAppServerModelGateway.d.ts +54 -5
- package/dist/services/codexAppServerModelGateway.js +246 -21
- package/dist/services/codexDeviceCodeLoginManager.d.ts +39 -0
- package/dist/services/codexDeviceCodeLoginManager.js +265 -0
- package/dist/services/codexModelProviderConnectionLifecycle.d.ts +8 -0
- package/dist/services/codexModelProviderConnectionLifecycle.js +73 -0
- package/dist/services/executorPhaseAApprovalRuntime.d.ts +14 -0
- package/dist/services/executorPhaseAApprovalRuntime.js +24 -0
- package/dist/services/executorPhaseAApprovalService.d.ts +40 -0
- package/dist/services/executorPhaseAApprovalService.js +609 -0
- package/dist/services/executorPhaseADriftEvaluator.d.ts +78 -0
- package/dist/services/executorPhaseADriftEvaluator.js +93 -0
- package/dist/services/executorPhaseAIssuerCore.d.ts +139 -0
- package/dist/services/executorPhaseAIssuerCore.js +402 -0
- package/dist/services/executorPhaseAIssuerRedemptionService.d.ts +34 -0
- package/dist/services/executorPhaseAIssuerRedemptionService.js +158 -0
- package/dist/services/githubReviewEvidenceRuntime.d.ts +14 -0
- package/dist/services/githubReviewEvidenceRuntime.js +30 -0
- package/dist/services/githubReviewEvidenceService.d.ts +93 -0
- package/dist/services/githubReviewEvidenceService.js +336 -0
- package/dist/services/modelGateway.d.ts +7 -0
- package/dist/services/modelProviderConnectionService.d.ts +71 -0
- package/dist/services/modelProviderConnectionService.js +279 -0
- package/dist/services/modelProviderCredentialHome.d.ts +32 -0
- package/dist/services/modelProviderCredentialHome.js +271 -0
- package/dist/services/ownerScopedModelConnectionGateway.d.ts +12 -0
- package/dist/services/ownerScopedModelConnectionGateway.js +30 -0
- package/dist/services/taskforceAgentConnectionBindingService.d.ts +66 -0
- package/dist/services/taskforceAgentConnectionBindingService.js +185 -0
- package/dist/services/taskforceAgentMcpBridge.d.ts +2 -2
- package/dist/services/taskforceAgentMcpBridge.js +42 -29
- package/dist/shared/adminEdgeProxy.d.ts +5 -0
- package/dist/shared/adminEdgeProxy.js +94 -0
- package/dist/shared/adminProxySessionCookies.d.ts +16 -0
- package/dist/shared/adminProxySessionCookies.js +86 -0
- package/dist/shared/aiProfileColors.d.ts +31 -1
- package/dist/shared/aiProfileColors.js +14 -6
- package/dist/shared/executorPhaseAApprovalGoldenVector.json +269 -0
- package/dist/shared/executorPhaseAApprovalReceipt.d.ts +112 -0
- package/dist/shared/executorPhaseAApprovalReceipt.js +58 -0
- package/dist/shared/executorPhaseAApprovalTrustPolicy.json +10 -0
- package/dist/shared/executorPhaseADriftContracts.d.ts +37 -0
- package/dist/shared/executorPhaseADriftContracts.js +63 -0
- package/dist/shared/executorPhaseAIssuerContracts.d.ts +75 -0
- package/dist/shared/executorPhaseAIssuerContracts.js +90 -0
- package/dist/shared/executorPhaseARunAuthorization.d.ts +120 -0
- package/dist/shared/executorPhaseARunAuthorization.js +232 -0
- package/dist/shared/executorPhaseASchemaValidation.d.ts +7 -0
- package/dist/shared/executorPhaseASchemaValidation.js +53 -0
- package/dist/shared/executorPhaseASchemas/approval-receipt.schema.json +106 -0
- package/dist/shared/executorPhaseASchemas/drift-attestation.schema.json +54 -0
- package/dist/shared/executorPhaseASchemas/drift-request.schema.json +47 -0
- package/dist/shared/executorPhaseASchemas/foundation-manifest.schema.json +29 -0
- package/dist/shared/executorPhaseASchemas/issuer-audit-record.schema.json +24 -0
- package/dist/shared/executorPhaseASchemas/issuer-proof.schema.json +43 -0
- package/dist/shared/executorPhaseASchemas/issuer-redemption-request.schema.json +18 -0
- package/dist/shared/executorPhaseASchemas/issuer-redemption-response.schema.json +39 -0
- package/dist/shared/executorPhaseASchemas/logical-envelope.schema.json +149 -0
- package/dist/shared/executorPhaseASchemas/preflight-report.schema.json +216 -0
- package/dist/shared/executorPhaseASchemas/run-capability.schema.json +111 -0
- package/dist/shared/executorPhaseASchemas/sender-proof.schema.json +37 -0
- package/dist/shared/executorPhaseASchemas/workload-grant.schema.json +68 -0
- package/dist/shared/executorPhaseASchemas/workload-jwt-claims.schema.json +67 -0
- package/dist/shared/executorPhaseATiming.d.ts +1 -0
- package/dist/shared/executorPhaseATiming.js +1 -0
- package/dist/shared/planningIdentity.js +1 -1
- package/dist/shared/productLogoKeys.d.ts +2 -0
- package/dist/shared/productLogoKeys.js +18 -0
- package/dist/shared/taskforceAgentDefinition.d.ts +0 -1
- package/dist/shared/taskforceAgentDefinition.js +6 -9
- package/dist/shared/taskforceAgentModels.js +7 -3
- package/dist/shared/userFeatureGrants.d.ts +4 -0
- package/dist/shared/userFeatureGrants.js +7 -0
- package/dist/storage/executorPhaseAApprovalReceiptStore.d.ts +37 -0
- package/dist/storage/executorPhaseAApprovalReceiptStore.js +81 -0
- package/dist/storage/executorPhaseARunAuthorizationStore.d.ts +103 -0
- package/dist/storage/executorPhaseARunAuthorizationStore.js +492 -0
- package/dist/storage/githubReviewEvidenceInstallationStore.d.ts +26 -0
- package/dist/storage/githubReviewEvidenceInstallationStore.js +89 -0
- package/dist/storage/modelProviderConnectionStore.d.ts +99 -0
- package/dist/storage/modelProviderConnectionStore.js +446 -0
- package/dist/storage/postgresAdapter.d.ts +4 -0
- package/dist/storage/postgresAdapter.js +14 -1
- package/dist/storage/postgresRequestDiagnostics.d.ts +9 -1
- package/dist/storage/postgresRequestDiagnostics.js +15 -2
- package/dist/storage/postgresWorker.js +20 -2
- package/dist/storage/postgresWorkerProtocol.d.ts +7 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -0
- package/dist/storage/workflowStore.d.ts +2 -0
- package/dist/storage/workflowStore.js +39 -2
- package/dist/sync/cloudSyncApi.js +4 -2
- package/dist/sync/collaborationSyncState.js +5 -0
- package/dist/sync/coordinator/localSyncExecutionPermitStore.js +60 -29
- package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.d.ts +10 -0
- package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.js +29 -0
- package/dist/sync/coordinator/localWorkspaceSyncRunner.d.ts +3 -1
- package/dist/sync/coordinator/localWorkspaceSyncRunner.js +18 -0
- package/dist/sync/coordinator/localWorkspaceSyncRunnerState.d.ts +15 -1
- package/dist/sync/coordinator/localWorkspaceSyncRunnerState.js +99 -2
- package/dist/sync/coordinator/workspaceSyncCredentialBroker.d.ts +1 -0
- package/dist/sync/coordinator/workspaceSyncCredentialBroker.js +33 -4
- package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.d.ts +2 -1
- package/dist/sync/engine/workspaceSyncContentVersionStore.d.ts +38 -0
- package/dist/sync/engine/workspaceSyncContentVersionStore.js +50 -1
- package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +6 -6
- package/dist/sync/engine/workspaceSyncEnginePushCompletion.d.ts +14 -0
- package/dist/sync/engine/workspaceSyncEnginePushCompletion.js +84 -0
- package/dist/sync/engine/workspaceSyncEngineRecovery.js +1 -0
- package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +1 -0
- package/dist/sync/engine/workspaceSyncEngineRuntime.js +1 -0
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +112 -38
- package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +6 -0
- package/dist/sync/engine/workspaceSyncEngineTransfers.js +3 -1
- package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.d.ts +1 -0
- package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +31 -0
- package/dist/sync/syncApplyHandlers.d.ts +3 -0
- package/dist/sync/syncApplyHandlers.js +81 -15
- package/dist/sync/syncService.d.ts +15 -0
- package/dist/sync/syncService.js +83 -18
- package/dist/sync/taskforceAgentSyncAuthorization.d.ts +16 -0
- package/dist/sync/taskforceAgentSyncAuthorization.js +20 -0
- package/dist/sync/v3/combinedFeedCapability.js +4 -0
- package/dist/sync/v3/durableInitiativeMutationRouter.js +18 -10
- package/dist/sync/v3/durableOperationReplay.d.ts +14 -0
- package/dist/sync/v3/durableOperationReplay.js +18 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +3 -0
- package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +2 -1
- package/dist/sync/v3/durableTaskChecklistMutationRouter.js +58 -15
- package/dist/sync/v3/durableTaskCommentMutationRouter.js +3 -0
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +1 -1
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +10 -0
- package/dist/sync/v3/durableTaxonomyMutationRouter.js +5 -0
- package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.d.ts +18 -7
- package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +89 -23
- package/dist/sync/v3/durableWorkstreamMutationRouter.js +18 -10
- package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.js +16 -5
- package/dist/sync/v3/localOutboxDispatchRuntime.js +2 -2
- package/dist/sync/v3/localOutboxRecoveryPreparationService.js +8 -2
- package/dist/sync/v3/localTaskChecklistOutboxHandler.js +16 -2
- package/dist/sync/v3/localTaskChecklistOutboxService.d.ts +4 -0
- package/dist/sync/v3/localTaskChecklistOutboxService.js +14 -1
- package/dist/sync/v3/localTaskCreateOutboxService.d.ts +3 -1
- package/dist/sync/v3/localTaskCreateOutboxService.js +6 -1
- package/dist/sync/v3/localTaskDeleteOutboxService.js +1 -0
- package/dist/sync/v3/localTaskLifecycleOutboxService.d.ts +2 -1
- package/dist/sync/v3/localTaskLifecycleOutboxService.js +5 -1
- package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -1
- package/dist/sync/v3/localTaskMetadataOutboxService.js +6 -2
- package/dist/sync/v3/localTaskStatusOutboxService.d.ts +10 -1
- package/dist/sync/v3/localTaskStatusOutboxService.js +238 -16
- package/dist/sync/v3/syncDurabilityStore.d.ts +36 -1
- package/dist/sync/v3/syncDurabilityStore.js +202 -8
- package/dist/sync/v3/taskChecklistMutationService.d.ts +11 -0
- package/dist/sync/v3/taskChecklistMutationService.js +44 -1
- package/dist/sync/v3/taskStatusMutationService.d.ts +29 -1
- package/dist/sync/v3/taskStatusMutationService.js +119 -3
- package/dist/sync/v3/workflowAssignmentSync.d.ts +5 -0
- package/dist/sync/v3/workflowAssignmentSync.js +27 -0
- package/dist/sync/v3/workflowRuntimeMutationService.d.ts +5 -0
- package/dist/sync/v3/workflowRuntimeMutationService.js +124 -71
- package/dist/sync/v3/workspaceSyncJournalReader.js +1 -1
- package/dist/sync/v3/workspaceSyncOperationRetentionService.d.ts +16 -0
- package/dist/sync/v3/workspaceSyncOperationRetentionService.js +83 -0
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +9 -2
- package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +25 -3
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +44 -32
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +9 -5
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +54 -38
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +10 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +70 -31
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +2 -1
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +16 -0
- package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +6 -0
- package/dist/sync/v3/workspaceSyncV3Feed.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3Feed.js +6 -1
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +2 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +49 -18
- package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +3 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +5 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +36 -2
- package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.d.ts +17 -0
- package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.js +64 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.js +50 -5
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.js +33 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.js +8 -0
- package/dist/sync/workspaceRepair.d.ts +5 -2
- package/dist/sync/workspaceRepair.js +161 -6
- package/dist/sync/workspaceSyncModel.d.ts +21 -0
- package/dist/sync/workspaceSyncModel.js +35 -7
- package/dist/sync/workspaceSyncState.d.ts +1 -0
- package/dist/sync/workspaceSyncV2SnapshotBuilder.d.ts +6 -0
- package/dist/sync/workspaceSyncV2SnapshotBuilder.js +5 -0
- package/dist/ui/assets/AiIdentityRosterCard-CDMPtnbC.js +1 -0
- package/dist/ui/assets/AiProfilesModule-Cww85C4E.js +1 -0
- package/dist/ui/assets/{AnnotatedAttachmentWorkspace-B68Wg-RV.js → AnnotatedAttachmentWorkspace-Dt9TKYSH.js} +1 -1
- package/dist/ui/assets/{AssetTraySortControl-C8Rztyal.js → AssetTraySortControl-CKgapnxu.js} +1 -1
- package/dist/ui/assets/{ContextAttachmentManager-Cj3c7X9y.js → ContextAttachmentManager-T-cEVcOZ.js} +2 -2
- package/dist/ui/assets/{DocumentWorkspace-B5uvzems.js → DocumentWorkspace-HD4MUjAZ.js} +1 -1
- package/dist/ui/assets/{EntityActivityTimeline-BVFvCB5R.js → EntityActivityTimeline-_V0zfMuh.js} +1 -1
- package/dist/ui/assets/PlanningModule-mTkBygsB.js +1 -0
- package/dist/ui/assets/{PlansPage-AY4cGWco.js → PlansPage-Btiq06VO.js} +1 -1
- package/dist/ui/assets/{TaskContextUpload-DZxTVesW.js → TaskContextUpload-C00NVUpn.js} +1 -1
- package/dist/ui/assets/TaskSettings-Cp-L-4xh.js +12 -0
- package/dist/ui/assets/TaskforceAgentsModule-Coq9-PUp.js +24 -0
- package/dist/ui/assets/TaskforceAgentsModule-b-8R25cJ.css +1 -0
- package/dist/ui/assets/{WorkflowManagerModule-DEr5di_r.js → WorkflowManagerModule-CuqRzMmM.js} +1 -1
- package/dist/ui/assets/index-BZ-hdZSk.css +1 -0
- package/dist/ui/assets/index-DSQINwt9.js +7 -0
- package/dist/ui/assets/{vendor-icons-D9Lpw-j4.js → vendor-icons-Bsq-mcEn.js} +1 -1
- package/dist/ui/branding/logos/letterhead_dark.png +0 -0
- package/dist/ui/branding/logos/letterhead_light.png +0 -0
- package/dist/ui/branding/logos/signature_dark.png +0 -0
- package/dist/ui/branding/logos/signature_light.png +0 -0
- package/dist/ui/index.html +3 -3
- package/dist/utils/aiProfileDefaultLogo.js +16 -48
- package/dist/utils/httpSetCookie.d.ts +1 -0
- package/dist/utils/httpSetCookie.js +4 -1
- package/dist/utils/localRuntimeUrl.d.ts +1 -0
- package/dist/utils/localRuntimeUrl.js +14 -0
- package/dist/utils/productLogoRegistry.d.ts +2 -0
- package/dist/utils/productLogoRegistry.js +36 -0
- package/dist/utils/syncStatusPresentation.d.ts +4 -0
- package/dist/utils/syncStatusPresentation.js +17 -0
- package/dist/utils/taskEvents.d.ts +2 -0
- package/dist/utils/workspaceSyncPresentation.d.ts +1 -1
- package/dist/utils/workspaceSyncPresentation.js +23 -17
- package/package.json +24 -4
- package/dist/ui/assets/AiIdentityRosterCard-BZM4aQnM.js +0 -1
- package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +0 -1
- package/dist/ui/assets/PlanningModule-B5DWQOGz.js +0 -1
- package/dist/ui/assets/TaskSettings-BeWAuyZj.js +0 -12
- package/dist/ui/assets/TaskforceAgentsModule-BifCYtjR.js +0 -21
- package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +0 -1
- package/dist/ui/assets/index-I5zhdtgt.js +0 -7
- package/dist/ui/assets/index-VRFsx3wz.css +0 -1
|
@@ -26,13 +26,21 @@ function requireMutationResult(task, taskId) {
|
|
|
26
26
|
throw new TaskChecklistCommandError(`Task ${taskId} not found`, 'TASK_NOT_FOUND', 404, { taskId });
|
|
27
27
|
}
|
|
28
28
|
export function createTaskChecklistCommandService(deps) {
|
|
29
|
-
const replaceItems = (taskId, items, operationKey) => {
|
|
30
|
-
|
|
29
|
+
const replaceItems = (taskId, items, operationKey, options) => {
|
|
30
|
+
const mutated = deps.replace({
|
|
31
31
|
taskId,
|
|
32
32
|
items,
|
|
33
|
-
operationId: deps.createId('operation', operationKey),
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
operationId: options?.operationId || deps.createId('operation', operationKey),
|
|
34
|
+
...(options?.expectedDetailRevision
|
|
35
|
+
? { expectedDetailRevision: options.expectedDetailRevision }
|
|
36
|
+
: {}),
|
|
37
|
+
...(options?.requireDurableIdempotency
|
|
38
|
+
? { requireDurableIdempotency: true }
|
|
39
|
+
: {}),
|
|
40
|
+
...(options?.itemUpdateIntent ? { itemUpdateIntent: options.itemUpdateIntent } : {}),
|
|
41
|
+
});
|
|
42
|
+
requireMutationResult(mutated, taskId);
|
|
43
|
+
return mutated?.checklistItems || deps.listItems(taskId);
|
|
36
44
|
};
|
|
37
45
|
return {
|
|
38
46
|
replace(input) {
|
|
@@ -107,5 +115,75 @@ export function createTaskChecklistCommandService(deps) {
|
|
|
107
115
|
items,
|
|
108
116
|
};
|
|
109
117
|
},
|
|
118
|
+
update(input) {
|
|
119
|
+
const task = deps.resolveTask(input.taskId);
|
|
120
|
+
const itemId = String(input.itemId ?? '').trim();
|
|
121
|
+
if (!itemId) {
|
|
122
|
+
throw new TaskChecklistCommandError('update_task_checklist_item requires itemId.');
|
|
123
|
+
}
|
|
124
|
+
const currentItems = deps.listItems(task.id);
|
|
125
|
+
const existingItem = currentItems.find((item) => item.id === itemId);
|
|
126
|
+
if (!existingItem) {
|
|
127
|
+
throw new TaskChecklistCommandError(`Checklist item ${itemId} was not found on task ${task.id}.`, 'TASK_CHECKLIST_ITEM_NOT_FOUND', 404, { taskId: task.id, itemId });
|
|
128
|
+
}
|
|
129
|
+
const hasTitle = input.title !== undefined || input.text !== undefined;
|
|
130
|
+
const hasCompleted = input.isCompleted !== undefined || input.done !== undefined;
|
|
131
|
+
const hasOrder = input.order !== undefined;
|
|
132
|
+
if (!hasTitle && !hasCompleted && !hasOrder) {
|
|
133
|
+
throw new TaskChecklistCommandError('update_task_checklist_item requires at least one of text, done, or order.');
|
|
134
|
+
}
|
|
135
|
+
const title = hasTitle
|
|
136
|
+
? normalizeTitle(input.title ?? input.text, 'update_task_checklist_item text')
|
|
137
|
+
: existingItem.title;
|
|
138
|
+
const completedInput = input.isCompleted ?? input.done;
|
|
139
|
+
if (hasCompleted && typeof completedInput !== 'boolean') {
|
|
140
|
+
throw new TaskChecklistCommandError('update_task_checklist_item done must be a boolean.');
|
|
141
|
+
}
|
|
142
|
+
const isCompleted = hasCompleted ? completedInput : existingItem.isCompleted;
|
|
143
|
+
const parsedOrder = hasOrder ? Number(input.order) : existingItem.order;
|
|
144
|
+
if (hasOrder && (!Number.isInteger(parsedOrder) || parsedOrder < 0)) {
|
|
145
|
+
throw new TaskChecklistCommandError('update_task_checklist_item order must be a non-negative integer.');
|
|
146
|
+
}
|
|
147
|
+
const expectedDetailRevision = input.expectedDetailRevision === undefined
|
|
148
|
+
? undefined
|
|
149
|
+
: String(input.expectedDetailRevision).trim();
|
|
150
|
+
if (input.expectedDetailRevision !== undefined && !expectedDetailRevision) {
|
|
151
|
+
throw new TaskChecklistCommandError('update_task_checklist_item expectedDetailRevision must contain non-whitespace text.');
|
|
152
|
+
}
|
|
153
|
+
const unchanged = existingItem.title === title
|
|
154
|
+
&& existingItem.isCompleted === isCompleted
|
|
155
|
+
&& existingItem.order === parsedOrder;
|
|
156
|
+
const nextItem = unchanged
|
|
157
|
+
? existingItem
|
|
158
|
+
: {
|
|
159
|
+
...existingItem,
|
|
160
|
+
title,
|
|
161
|
+
isCompleted,
|
|
162
|
+
order: parsedOrder,
|
|
163
|
+
updatedAt: deps.now(),
|
|
164
|
+
};
|
|
165
|
+
const nextItems = currentItems.map((item) => item.id === itemId ? nextItem : item);
|
|
166
|
+
const items = replaceItems(task.id, nextItems, `task-checklist-update:${task.id}:${itemId}`, {
|
|
167
|
+
operationId: input.operationId,
|
|
168
|
+
expectedDetailRevision,
|
|
169
|
+
requireDurableIdempotency: input.requireDurableIdempotency,
|
|
170
|
+
...(input.requireDurableIdempotency ? {
|
|
171
|
+
itemUpdateIntent: {
|
|
172
|
+
kind: 'item-update',
|
|
173
|
+
itemId,
|
|
174
|
+
patch: {
|
|
175
|
+
...(hasTitle ? { text: title } : {}),
|
|
176
|
+
...(hasCompleted ? { done: isCompleted } : {}),
|
|
177
|
+
...(hasOrder ? { order: parsedOrder } : {}),
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
} : {}),
|
|
181
|
+
});
|
|
182
|
+
const item = items.find((candidate) => candidate.id === itemId);
|
|
183
|
+
if (!item) {
|
|
184
|
+
throw new TaskChecklistCommandError(`Checklist item ${itemId} was not found after updating task ${task.id}.`, 'TASK_CHECKLIST_ITEM_NOT_FOUND', 404, { taskId: task.id, itemId });
|
|
185
|
+
}
|
|
186
|
+
return { taskId: task.id, item, items };
|
|
187
|
+
},
|
|
110
188
|
};
|
|
111
189
|
}
|
|
@@ -30,6 +30,7 @@ export interface TaskLifecycleCommandServiceDependencies {
|
|
|
30
30
|
updates: Record<string, unknown>;
|
|
31
31
|
forceDurable?: boolean;
|
|
32
32
|
assigneeIntent?: TaskLifecycleAssigneeIntent;
|
|
33
|
+
handoffComment?: string;
|
|
33
34
|
}): TaskLifecycleTask;
|
|
34
35
|
mutateLifecycle(input: {
|
|
35
36
|
taskId: string;
|
|
@@ -40,7 +41,7 @@ export interface TaskLifecycleCommandServiceDependencies {
|
|
|
40
41
|
reason: string | undefined;
|
|
41
42
|
};
|
|
42
43
|
}): TaskLifecycleTask | null;
|
|
43
|
-
resolveReviewer(task: TaskLifecycleTask): TaskLifecycleReviewerResolution;
|
|
44
|
+
resolveReviewer(task: TaskLifecycleTask, reviewer?: unknown): TaskLifecycleReviewerResolution;
|
|
44
45
|
}
|
|
45
46
|
export declare class TaskLifecycleCommandError extends Error {
|
|
46
47
|
readonly code: string;
|
|
@@ -81,6 +82,7 @@ export declare function createTaskLifecycleCommandService(deps: TaskLifecycleCom
|
|
|
81
82
|
finish(task: TaskLifecycleTask, input: {
|
|
82
83
|
outcome: unknown;
|
|
83
84
|
comment?: unknown;
|
|
85
|
+
reviewer?: unknown;
|
|
84
86
|
}): FinishTaskCommandResult;
|
|
85
87
|
reopen(task: TaskLifecycleTask, input: {
|
|
86
88
|
activeAiProfileId: string | null | undefined;
|
|
@@ -88,8 +88,12 @@ export function createTaskLifecycleCommandService(deps) {
|
|
|
88
88
|
nextTool: 'reopen_task',
|
|
89
89
|
});
|
|
90
90
|
}
|
|
91
|
+
const normalizedComment = typeof input.comment === 'string' ? input.comment.trim() : '';
|
|
92
|
+
if (normalizedOutcome === 'review' && !normalizedComment) {
|
|
93
|
+
throw new TaskLifecycleCommandError('finish_task requires a nonblank handoff comment when outcome is review.', 'TASK_FINISH_REVIEW_COMMENT_REQUIRED', 400, { taskId: task.id, outcome: normalizedOutcome });
|
|
94
|
+
}
|
|
91
95
|
const reviewerResolution = normalizedOutcome === 'review'
|
|
92
|
-
? deps.resolveReviewer(task)
|
|
96
|
+
? deps.resolveReviewer(task, input.reviewer)
|
|
93
97
|
: undefined;
|
|
94
98
|
const updated = deps.setStatus({
|
|
95
99
|
task,
|
|
@@ -99,8 +103,8 @@ export function createTaskLifecycleCommandService(deps) {
|
|
|
99
103
|
...(reviewerResolution
|
|
100
104
|
? { assigneeIntent: { kind: 'set', value: reviewerResolution.assignee } }
|
|
101
105
|
: {}),
|
|
106
|
+
...(normalizedOutcome === 'review' ? { handoffComment: normalizedComment } : {}),
|
|
102
107
|
});
|
|
103
|
-
const normalizedComment = typeof input.comment === 'string' ? input.comment.trim() : '';
|
|
104
108
|
return {
|
|
105
109
|
task: updated,
|
|
106
110
|
completion: {
|
package/dist/core/Taskforce.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { DurableTaskStatusMutationPayload } from './TaskDurableStatusMutati
|
|
|
5
5
|
import { WorkspaceAssetStore } from '../storage/workspaceAssetStore.js';
|
|
6
6
|
import { resolveAdminAuditRetentionPolicy, type AdminAuditRetentionDiagnostics, type AdminAuditRetentionRun } from './AdminAuditRetentionService.js';
|
|
7
7
|
import type { WorkspaceSyncV3TaskAttachmentLink } from '../sync/v3/workspaceSyncV3NestedTaskCodecs.js';
|
|
8
|
+
import { type InternalUserFeatureKey } from '../shared/userFeatureGrants.js';
|
|
8
9
|
import type { TaskRestoreDestination } from '../shared/taskRestoreDestination.js';
|
|
9
10
|
import { type SyncEventInput } from './SyncReconciliationService.js';
|
|
10
11
|
import { type FirstClassTaxonomyDisplayLabels, type NormalizedWorkspaceTaxonomyState, type WorkspaceTaxonomyState } from '../shared/taxonomyState.js';
|
|
@@ -458,6 +459,7 @@ export type SystemRole = 'system_admin' | 'user';
|
|
|
458
459
|
type PermissionMode = 'read-only' | 'read-write';
|
|
459
460
|
type AuthTokenPurpose = 'email_verification' | 'password_reset' | 'invite_accept';
|
|
460
461
|
export type McpAccessTokenScope = 'tasks:read' | 'tasks:write' | 'workspace:read';
|
|
462
|
+
export type McpCloudToolProfile = 'default' | 'extended';
|
|
461
463
|
type McpAccessTokenStatus = 'active' | 'revoked' | 'expired';
|
|
462
464
|
export type McpOAuthProvider = 'chatgpt' | 'claude' | 'grok' | 'gemini' | 'mistral' | 'perplexity';
|
|
463
465
|
type McpOAuthClientStatus = 'active' | 'revoked';
|
|
@@ -586,6 +588,7 @@ interface SystemUserRecord {
|
|
|
586
588
|
systemRole: SystemRole;
|
|
587
589
|
betaAccess: boolean;
|
|
588
590
|
disabled: boolean;
|
|
591
|
+
internalFeatureGrants: InternalUserFeatureKey[];
|
|
589
592
|
planId?: string | null;
|
|
590
593
|
planName?: string | null;
|
|
591
594
|
planVersionId?: string | null;
|
|
@@ -608,6 +611,7 @@ export interface PurgedSystemUserSummary {
|
|
|
608
611
|
deletedMcpOauthConnectorGrantCount: number;
|
|
609
612
|
deletedUiStateCount: number;
|
|
610
613
|
deletedUserPreferenceCount: number;
|
|
614
|
+
deletedUserFeatureGrantCount: number;
|
|
611
615
|
deletedEntitlementCount: number;
|
|
612
616
|
deletedUserBillingCount: number;
|
|
613
617
|
deletedUserCount: number;
|
|
@@ -772,6 +776,7 @@ export interface McpAccessTokenRecord {
|
|
|
772
776
|
userEmail?: string | null;
|
|
773
777
|
name: string;
|
|
774
778
|
scopes: McpAccessTokenScope[];
|
|
779
|
+
toolProfile: McpCloudToolProfile;
|
|
775
780
|
tokenPrefix: string;
|
|
776
781
|
status: McpAccessTokenStatus;
|
|
777
782
|
lastUsedAt?: string | null;
|
|
@@ -799,6 +804,7 @@ export interface McpAccessTokenAuthResult {
|
|
|
799
804
|
workspaceId: string;
|
|
800
805
|
userId: string;
|
|
801
806
|
scopes: McpAccessTokenScope[];
|
|
807
|
+
toolProfile?: McpCloudToolProfile;
|
|
802
808
|
status: McpAccessTokenStatus;
|
|
803
809
|
}
|
|
804
810
|
export interface McpAccessTokenInspectionResult {
|
|
@@ -808,12 +814,14 @@ export interface McpAccessTokenInspectionResult {
|
|
|
808
814
|
userId: string;
|
|
809
815
|
name: string;
|
|
810
816
|
scopes: McpAccessTokenScope[];
|
|
817
|
+
toolProfile: McpCloudToolProfile;
|
|
811
818
|
status: McpAccessTokenStatus;
|
|
812
819
|
}
|
|
813
820
|
export interface McpOAuthClientRecord {
|
|
814
821
|
id: string;
|
|
815
822
|
provider: McpOAuthProvider;
|
|
816
823
|
clientName: string;
|
|
824
|
+
applicationType: 'native' | 'web';
|
|
817
825
|
productClientId?: string | null;
|
|
818
826
|
redirectUris: string[];
|
|
819
827
|
status: McpOAuthClientStatus;
|
|
@@ -829,6 +837,7 @@ export interface McpOAuthConnectorGrantRecord {
|
|
|
829
837
|
workspaceId: string;
|
|
830
838
|
userId: string;
|
|
831
839
|
scopes: McpAccessTokenScope[];
|
|
840
|
+
toolProfile: McpCloudToolProfile;
|
|
832
841
|
tokenPrefix: string;
|
|
833
842
|
status: McpOAuthGrantStatus;
|
|
834
843
|
lastUsedAt?: string | null;
|
|
@@ -851,6 +860,7 @@ export interface McpOAuthAccessTokenAuthResult {
|
|
|
851
860
|
provider: McpOAuthProvider;
|
|
852
861
|
productClientId?: string | null;
|
|
853
862
|
scopes: McpAccessTokenScope[];
|
|
863
|
+
toolProfile?: McpCloudToolProfile;
|
|
854
864
|
status: McpOAuthGrantStatus;
|
|
855
865
|
aiProfileId?: string | null;
|
|
856
866
|
aiProfileToken?: string | null;
|
|
@@ -964,7 +974,9 @@ export interface TaskforceSyncCapable {
|
|
|
964
974
|
upsertInitiativeForSync(initiative: InitiativeItem, workspaceId?: string | null): InitiativeItem;
|
|
965
975
|
upsertWorkstreamForSync(workstream: WorkstreamItem, workspaceId?: string | null): WorkstreamItem;
|
|
966
976
|
upsertDocumentReviewSessionForSync(session: DocumentReviewSessionRecord): DocumentReviewSessionRecord;
|
|
967
|
-
upsertDocumentReviewCommentForSync(comment: DocumentReviewCommentSyncRecord
|
|
977
|
+
upsertDocumentReviewCommentForSync(comment: DocumentReviewCommentSyncRecord, options?: {
|
|
978
|
+
allowAuthoritativeThreadReconciliation?: boolean;
|
|
979
|
+
}): DocumentReviewCommentSyncRecord;
|
|
968
980
|
upsertAnnotatedAttachmentSessionForSync(session: AnnotatedAttachmentSessionRecord): AnnotatedAttachmentSessionRecord;
|
|
969
981
|
upsertTaskEventForSync(event: TaskEvent): TaskEvent;
|
|
970
982
|
upsertEntityEventForSync(event: EntityEvent, options?: {
|
|
@@ -1633,6 +1645,9 @@ export declare class TaskforceCore implements TaskforceSyncCapable {
|
|
|
1633
1645
|
setSystemRole(userId: string, role: SystemRole): boolean;
|
|
1634
1646
|
setUserDisabledGlobal(userId: string, disabled: boolean): boolean;
|
|
1635
1647
|
setUserBetaAccessGlobal(userId: string, enabled: boolean): boolean;
|
|
1648
|
+
hasUserFeatureGrant(userId: string, featureKey: unknown): boolean;
|
|
1649
|
+
listUserFeatureGrants(userId: string): InternalUserFeatureKey[];
|
|
1650
|
+
setUserFeatureGrant(userId: string, featureKey: unknown, enabled: boolean, updatedBy?: string | null): boolean;
|
|
1636
1651
|
markUserEmailVerified(userId: string): {
|
|
1637
1652
|
emailVerifiedAt: string;
|
|
1638
1653
|
} | null;
|
|
@@ -1774,7 +1789,9 @@ export declare class TaskforceCore implements TaskforceSyncCapable {
|
|
|
1774
1789
|
includeDeleted?: boolean;
|
|
1775
1790
|
}): AnnotatedAttachmentSessionRecord[];
|
|
1776
1791
|
upsertDocumentReviewSessionForSync(session: DocumentReviewSessionRecord): DocumentReviewSessionRecord;
|
|
1777
|
-
upsertDocumentReviewCommentForSync(comment: Omit<DocumentReviewCommentSyncRecord, 'parentCommentId' | 'threadStatus' | 'threadStatusUpdatedAt' | 'resolvedAt' | 'resolvedByActorId'> & Partial<Pick<DocumentReviewCommentSyncRecord, 'parentCommentId' | 'threadStatus' | 'threadStatusUpdatedAt' | 'resolvedAt' | 'resolvedByActorId'
|
|
1792
|
+
upsertDocumentReviewCommentForSync(comment: Omit<DocumentReviewCommentSyncRecord, 'parentCommentId' | 'threadStatus' | 'threadStatusUpdatedAt' | 'resolvedAt' | 'resolvedByActorId'> & Partial<Pick<DocumentReviewCommentSyncRecord, 'parentCommentId' | 'threadStatus' | 'threadStatusUpdatedAt' | 'resolvedAt' | 'resolvedByActorId'>>, options?: {
|
|
1793
|
+
allowAuthoritativeThreadReconciliation?: boolean;
|
|
1794
|
+
}): DocumentReviewCommentSyncRecord;
|
|
1778
1795
|
upsertAnnotatedAttachmentSessionForSync(session: AnnotatedAttachmentSessionRecord): AnnotatedAttachmentSessionRecord;
|
|
1779
1796
|
upsertTaskEventForSync(event: TaskEvent): TaskEvent;
|
|
1780
1797
|
upsertEntityEventForSync(event: EntityEvent, options?: {
|
|
@@ -2208,6 +2225,15 @@ export declare class TaskforceCore implements TaskforceSyncCapable {
|
|
|
2208
2225
|
tokenId: string;
|
|
2209
2226
|
createdByIp?: string | null;
|
|
2210
2227
|
}): McpAccessTokenIssueResult;
|
|
2228
|
+
updateMcpAccessTokenToolProfile(input: {
|
|
2229
|
+
actorUserId: string;
|
|
2230
|
+
workspaceId: string;
|
|
2231
|
+
tokenId: string;
|
|
2232
|
+
toolProfile: unknown;
|
|
2233
|
+
}): {
|
|
2234
|
+
record: McpAccessTokenRecord;
|
|
2235
|
+
previousToolProfile: McpCloudToolProfile;
|
|
2236
|
+
};
|
|
2211
2237
|
authenticateMcpAccessToken(token: string, workspaceId?: string): McpAccessTokenAuthResult | null;
|
|
2212
2238
|
inspectMcpAccessToken(token: string): McpAccessTokenInspectionResult | null;
|
|
2213
2239
|
recordMcpAccessTokenUsage(input: {
|
|
@@ -2220,6 +2246,7 @@ export declare class TaskforceCore implements TaskforceSyncCapable {
|
|
|
2220
2246
|
provider: McpOAuthProvider | string;
|
|
2221
2247
|
clientName: string;
|
|
2222
2248
|
redirectUris: unknown;
|
|
2249
|
+
applicationType?: unknown;
|
|
2223
2250
|
productClientId?: string | null;
|
|
2224
2251
|
}): McpOAuthClientRecord;
|
|
2225
2252
|
getMcpOAuthClient(clientId: string, provider?: McpOAuthProvider | string | null): McpOAuthClientRecord | null;
|
|
@@ -2253,6 +2280,15 @@ export declare class TaskforceCore implements TaskforceSyncCapable {
|
|
|
2253
2280
|
workspaceId: string;
|
|
2254
2281
|
grantId: string;
|
|
2255
2282
|
}): McpOAuthConnectorGrantRecord;
|
|
2283
|
+
updateMcpOAuthConnectorGrantToolProfile(input: {
|
|
2284
|
+
actorUserId: string;
|
|
2285
|
+
workspaceId: string;
|
|
2286
|
+
grantId: string;
|
|
2287
|
+
toolProfile: unknown;
|
|
2288
|
+
}): {
|
|
2289
|
+
record: McpOAuthConnectorGrantRecord;
|
|
2290
|
+
previousToolProfile: McpCloudToolProfile;
|
|
2291
|
+
};
|
|
2256
2292
|
authenticateMcpOAuthAccessToken(token: string, workspaceId?: string): McpOAuthAccessTokenAuthResult | null;
|
|
2257
2293
|
bindMcpOAuthConnectorGrantAiProfile(input: {
|
|
2258
2294
|
grantId: string;
|
|
@@ -2426,7 +2462,9 @@ export declare class TaskforceCore implements TaskforceSyncCapable {
|
|
|
2426
2462
|
notifyDurableWorkflowRuntimeCommitted(workspaceId: string, _executionId: string): void;
|
|
2427
2463
|
installDurableInitiativeAuthoritativeForSync(initiative: InitiativeItem, workspaceId: string): InitiativeItem;
|
|
2428
2464
|
installDurableWorkstreamAuthoritativeForSync(workstream: WorkstreamItem, workspaceId: string): WorkstreamItem;
|
|
2429
|
-
installDurableTaskCreateAuthoritativeForSync(task: TaskItem, workspaceId: string
|
|
2465
|
+
installDurableTaskCreateAuthoritativeForSync(task: TaskItem, workspaceId: string, options?: {
|
|
2466
|
+
preserveDeletedSuccessor?: boolean;
|
|
2467
|
+
}): TaskItem;
|
|
2430
2468
|
installWorkspaceSyncV3TaskRootAuthoritativeForSync(task: TaskItem, workspaceId: string): TaskItem;
|
|
2431
2469
|
bulkCreateTasks(tasks: Array<Partial<TaskItem>>, options?: {
|
|
2432
2470
|
atomic?: boolean;
|
|
@@ -2467,8 +2505,10 @@ export declare class TaskforceCore implements TaskforceSyncCapable {
|
|
|
2467
2505
|
notifyDurableTaskMetadataCommitted(workspaceId: string, taskId: string): void;
|
|
2468
2506
|
addComment(id: string, text: string, author: string, workspaceId?: string, options?: {
|
|
2469
2507
|
persistBackup?: boolean;
|
|
2508
|
+
emitRealtime?: boolean;
|
|
2470
2509
|
actorRef?: string;
|
|
2471
2510
|
skipTaskEvents?: boolean;
|
|
2511
|
+
commentId?: string;
|
|
2472
2512
|
}): TaskItem | null;
|
|
2473
2513
|
private addPlanningEntityComment;
|
|
2474
2514
|
addInitiativeComment(id: string, text: string, author: string, workspaceId?: string, options?: {
|
package/dist/core/Taskforce.js
CHANGED
|
@@ -27,6 +27,7 @@ import { listTaskAttachmentLinksForDurableSync as listTaskAttachmentLinksForDura
|
|
|
27
27
|
import { EntityEventIdentityCollisionError, addEntityEventService, addTaskEventService, buildEntityActivityService, buildTaskActivityService, getEntityEventForSyncService, getTaskEventForSyncService, listEntityEventsInternalService, listWorkspaceEntityEventsForSyncService, listTaskEventsInternalService, listWorkspaceTaskEventsForSyncService, replaceEntityEventsService, replaceTaskCommentsService, replaceTaskEventsService, upsertEntityEventForSyncService, deleteEntityEventForSyncService, upsertTaskEventForSyncService, } from './TaskActivityService.js';
|
|
28
28
|
import { addDeletedTaskRecordService, getDeletedTaskService, listDeletedTasksService, listDeletedTasksReadOnlyService, mapDeletedTaskRowService, normalizeTaskSnapshotForRestoreService, normalizeDeletedTaskRestoreLifecycleService, purgeExpiredDeletedTasksService, } from './DeletedTaskLifecycleService.js';
|
|
29
29
|
import { DELETED_TASK_RETENTION_DAYS } from '../shared/deletedTaskRetention.js';
|
|
30
|
+
import { INTERNAL_SUBSCRIPTION_MODEL_FEATURE_KEY, isSupportedInternalUserFeatureKey, } from '../shared/userFeatureGrants.js';
|
|
30
31
|
import { applyWorkspaceSyncSnapshotService, claimPushIdempotencyService, completePushIdempotencyClaimService, deleteDocumentWatermarkService, deleteDocumentWatermarkStrictService, getDocumentWatermarkService, listTasksForSyncService, listWorkspaceSyncDeletesSinceService, readPushIdempotencyService, releasePushIdempotencyClaimService, renewPushIdempotencyClaimService, recordSyncEventDurablyService, recordSyncEventService, upsertDocumentWatermarkService, upsertDocumentWatermarkStrictService, writePushIdempotencyService, } from './SyncReconciliationService.js';
|
|
31
32
|
import { getGlobalSettingsService, hasPersistedGlobalSettingsService, readGlobalConfigService, updateGlobalSettingsService, writeGlobalConfigService, } from './GlobalSettingsService.js';
|
|
32
33
|
import { getWorkspaceTaxonomyStateService, upsertWorkspaceTaxonomyStateService, } from './TaxonomySettingsService.js';
|
|
@@ -62,7 +63,7 @@ import { getCanonicalDocumentName } from '../utils/documentNames.js';
|
|
|
62
63
|
import { isPathInsideRoot, resolveStorageKeyPathInsideRoot } from '../utils/pathSafety.js';
|
|
63
64
|
import { DEFAULT_TASKFORCE_THEME } from '../utils/theme.js';
|
|
64
65
|
import { normalizeTaskSearchQuery } from '../utils/taskSearch.js';
|
|
65
|
-
import { ensureAssigneeTaskSchema, ensureAnnotatedAttachmentSessionsSchema, ensureAuthIdentitySchema, backfillPlanningAttachmentAssetIdentities, ensureBillingSchema, ensureDocumentReviewSessionsSchema, ensureDocumentReferenceSchema, ensureEntitlementsSchema, ensurePlanningReferenceSchema, ensureScheduleTaskSchema, ensureWorkstreamTaskOrderSchema, ensureTaskAssetsSchema, ensureTaskApproachRemoved, ensureAgentRolesSchema, ensureTaskforceAgentsSchema, ensureTaskforceAgentSkillsSchema, ensureTaskReferenceSchema, ensureTenantSchema, ensureWorkflowSchema, ensureWorkspaceAssetsSchema, ensureWorkspaceSchema, ensureLocalSyncCoordinatorSchema, ensureWorkspaceSyncDurabilitySchema } from '../migrations/taskSchemaMigrations.js';
|
|
66
|
+
import { ensureAssigneeTaskSchema, ensureAnnotatedAttachmentSessionsSchema, ensureAuthIdentitySchema, backfillPlanningAttachmentAssetIdentities, ensureBillingSchema, ensureDocumentReviewSessionsSchema, ensureDocumentReferenceSchema, ensureEntitlementsSchema, ensurePlanningReferenceSchema, ensureScheduleTaskSchema, ensureWorkstreamTaskOrderSchema, ensureTaskAssetsSchema, ensureTaskApproachRemoved, ensureAgentRolesSchema, ensureGitHubReviewEvidenceInstallationBindingsSchema, ensureExecutorPhaseAApprovalReceiptsSchema, ensureExecutorPhaseARunAuthorizationsSchema, ensureModelProviderConnectionsSchema, ensureTaskforceAgentConnectionBindingsSchema, ensureTaskforceAgentsSchema, ensureTaskforceAgentSkillsSchema, ensureTaskReferenceSchema, ensureTenantSchema, ensureWorkflowSchema, ensureWorkspaceAssetsSchema, ensureWorkspaceSchema, ensureLocalSyncCoordinatorSchema, ensureWorkspaceSyncDurabilitySchema } from '../migrations/taskSchemaMigrations.js';
|
|
66
67
|
import { repairTaskUpdatedAtOnlySyncDrift } from '../migrations/taskUpdatedAtSyncDriftMigration.js';
|
|
67
68
|
export class TaskforceRuleError extends Error {
|
|
68
69
|
statusCode;
|
|
@@ -1457,7 +1458,14 @@ export class TaskforceCore {
|
|
|
1457
1458
|
ensureDocumentReferenceSchema(this.db);
|
|
1458
1459
|
ensureDocumentReviewSessionsSchema(this.db);
|
|
1459
1460
|
ensureAnnotatedAttachmentSessionsSchema(this.db);
|
|
1461
|
+
ensureModelProviderConnectionsSchema(this.db);
|
|
1460
1462
|
ensureTaskforceAgentsSchema(this.db);
|
|
1463
|
+
ensureTaskforceAgentConnectionBindingsSchema(this.db);
|
|
1464
|
+
ensureGitHubReviewEvidenceInstallationBindingsSchema(this.db);
|
|
1465
|
+
if (this.runtimeMode === 'cloud') {
|
|
1466
|
+
ensureExecutorPhaseAApprovalReceiptsSchema(this.db);
|
|
1467
|
+
ensureExecutorPhaseARunAuthorizationsSchema(this.db);
|
|
1468
|
+
}
|
|
1461
1469
|
ensureAgentRolesSchema(this.db);
|
|
1462
1470
|
ensureTaskforceAgentSkillsSchema(this.db);
|
|
1463
1471
|
ensureWorkflowSchema(this.db);
|
|
@@ -1969,6 +1977,18 @@ export class TaskforceCore {
|
|
|
1969
1977
|
PRIMARY KEY (tenant_id, user_id, prefs_key)
|
|
1970
1978
|
);
|
|
1971
1979
|
|
|
1980
|
+
CREATE TABLE IF NOT EXISTS user_feature_grants (
|
|
1981
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
1982
|
+
user_id TEXT NOT NULL,
|
|
1983
|
+
feature_key TEXT NOT NULL,
|
|
1984
|
+
enabled INTEGER NOT NULL DEFAULT 0,
|
|
1985
|
+
created_at TEXT NOT NULL,
|
|
1986
|
+
updated_at TEXT NOT NULL,
|
|
1987
|
+
updated_by TEXT,
|
|
1988
|
+
PRIMARY KEY (tenant_id, user_id, feature_key),
|
|
1989
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
1990
|
+
);
|
|
1991
|
+
|
|
1972
1992
|
CREATE TABLE IF NOT EXISTS admin_audit_logs (
|
|
1973
1993
|
id TEXT PRIMARY KEY,
|
|
1974
1994
|
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
@@ -2013,6 +2033,7 @@ export class TaskforceCore {
|
|
|
2013
2033
|
provider TEXT NOT NULL,
|
|
2014
2034
|
client_name TEXT NOT NULL,
|
|
2015
2035
|
redirect_uris_json TEXT NOT NULL,
|
|
2036
|
+
application_type TEXT NOT NULL DEFAULT 'web',
|
|
2016
2037
|
product_client_id TEXT,
|
|
2017
2038
|
status TEXT NOT NULL DEFAULT 'active',
|
|
2018
2039
|
created_at TEXT NOT NULL,
|
|
@@ -2047,6 +2068,7 @@ export class TaskforceCore {
|
|
|
2047
2068
|
user_id TEXT NOT NULL,
|
|
2048
2069
|
workspace_id TEXT NOT NULL DEFAULT 'default',
|
|
2049
2070
|
scopes_json TEXT NOT NULL,
|
|
2071
|
+
tool_profile TEXT NOT NULL DEFAULT 'default',
|
|
2050
2072
|
token_prefix TEXT NOT NULL,
|
|
2051
2073
|
token_hash TEXT NOT NULL,
|
|
2052
2074
|
status TEXT NOT NULL DEFAULT 'active',
|
|
@@ -2188,6 +2210,7 @@ export class TaskforceCore {
|
|
|
2188
2210
|
CREATE INDEX IF NOT EXISTS idx_ui_state_workspace_key ON ui_state(workspace_id, state_key);
|
|
2189
2211
|
CREATE INDEX IF NOT EXISTS idx_workspace_settings_workspace_key ON workspace_settings(workspace_id, settings_key);
|
|
2190
2212
|
CREATE INDEX IF NOT EXISTS idx_user_preferences_user_key ON user_preferences(user_id, prefs_key);
|
|
2213
|
+
CREATE INDEX IF NOT EXISTS idx_user_feature_grants_feature_enabled ON user_feature_grants(tenant_id, feature_key, enabled);
|
|
2191
2214
|
CREATE INDEX IF NOT EXISTS idx_admin_audit_logs_tenant_created ON admin_audit_logs(tenant_id, created_at);
|
|
2192
2215
|
CREATE INDEX IF NOT EXISTS idx_admin_audit_logs_workspace_created ON admin_audit_logs(workspace_id, created_at);
|
|
2193
2216
|
CREATE INDEX IF NOT EXISTS idx_task_events_task_created ON task_events(tenant_id, workspace_id, task_id, created_at);
|
|
@@ -2363,6 +2386,9 @@ export class TaskforceCore {
|
|
|
2363
2386
|
if (!mcpOauthClientColumns.some((c) => c.name === 'product_client_id')) {
|
|
2364
2387
|
this.db.exec(`ALTER TABLE mcp_oauth_clients ADD COLUMN product_client_id TEXT`);
|
|
2365
2388
|
}
|
|
2389
|
+
if (!mcpOauthClientColumns.some((c) => c.name === 'application_type')) {
|
|
2390
|
+
this.db.exec(`ALTER TABLE mcp_oauth_clients ADD COLUMN application_type TEXT NOT NULL DEFAULT 'web'`);
|
|
2391
|
+
}
|
|
2366
2392
|
const mcpOauthGrantColumns = this.db.prepare(`PRAGMA table_info(mcp_oauth_connector_grants)`).all();
|
|
2367
2393
|
if (!mcpOauthGrantColumns.some((c) => c.name === 'product_client_id')) {
|
|
2368
2394
|
this.db.exec(`ALTER TABLE mcp_oauth_connector_grants ADD COLUMN product_client_id TEXT`);
|
|
@@ -2376,14 +2402,19 @@ export class TaskforceCore {
|
|
|
2376
2402
|
if (!mcpOauthGrantColumns.some((c) => c.name === 'ai_profile_name')) {
|
|
2377
2403
|
this.db.exec(`ALTER TABLE mcp_oauth_connector_grants ADD COLUMN ai_profile_name TEXT`);
|
|
2378
2404
|
}
|
|
2405
|
+
if (!mcpOauthGrantColumns.some((c) => c.name === 'tool_profile')) {
|
|
2406
|
+
this.db.exec(`ALTER TABLE mcp_oauth_connector_grants ADD COLUMN tool_profile TEXT NOT NULL DEFAULT 'default'`);
|
|
2407
|
+
}
|
|
2379
2408
|
}
|
|
2380
2409
|
else {
|
|
2381
2410
|
try {
|
|
2382
2411
|
this.db.exec(`ALTER TABLE mcp_oauth_clients ADD COLUMN IF NOT EXISTS product_client_id TEXT`);
|
|
2412
|
+
this.db.exec(`ALTER TABLE mcp_oauth_clients ADD COLUMN IF NOT EXISTS application_type TEXT NOT NULL DEFAULT 'web'`);
|
|
2383
2413
|
this.db.exec(`ALTER TABLE mcp_oauth_connector_grants ADD COLUMN IF NOT EXISTS product_client_id TEXT`);
|
|
2384
2414
|
this.db.exec(`ALTER TABLE mcp_oauth_connector_grants ADD COLUMN IF NOT EXISTS ai_profile_id TEXT`);
|
|
2385
2415
|
this.db.exec(`ALTER TABLE mcp_oauth_connector_grants ADD COLUMN IF NOT EXISTS ai_profile_token TEXT`);
|
|
2386
2416
|
this.db.exec(`ALTER TABLE mcp_oauth_connector_grants ADD COLUMN IF NOT EXISTS ai_profile_name TEXT`);
|
|
2417
|
+
this.db.exec(`ALTER TABLE mcp_oauth_connector_grants ADD COLUMN IF NOT EXISTS tool_profile TEXT NOT NULL DEFAULT 'default'`);
|
|
2387
2418
|
}
|
|
2388
2419
|
catch {
|
|
2389
2420
|
// Best-effort schema repair for existing deployments.
|
|
@@ -6956,7 +6987,7 @@ export class TaskforceCore {
|
|
|
6956
6987
|
OR LOWER(COALESCE(u.system_role, 'user')) LIKE ?
|
|
6957
6988
|
)`
|
|
6958
6989
|
: '';
|
|
6959
|
-
const params = [this.tenantId];
|
|
6990
|
+
const params = [INTERNAL_SUBSCRIPTION_MODEL_FEATURE_KEY, this.tenantId];
|
|
6960
6991
|
if (query) {
|
|
6961
6992
|
params.push(queryPattern, queryPattern, queryPattern, queryPattern, queryPattern, queryPattern, queryPattern);
|
|
6962
6993
|
}
|
|
@@ -6969,6 +7000,14 @@ export class TaskforceCore {
|
|
|
6969
7000
|
COALESCE(u.system_role, 'user') AS system_role,
|
|
6970
7001
|
COALESCE(u.beta_access, 1) AS beta_access,
|
|
6971
7002
|
COALESCE(u.is_disabled, 0) AS is_disabled,
|
|
7003
|
+
CASE WHEN EXISTS (
|
|
7004
|
+
SELECT 1
|
|
7005
|
+
FROM user_feature_grants g
|
|
7006
|
+
WHERE g.tenant_id = u.tenant_id
|
|
7007
|
+
AND g.user_id = u.id
|
|
7008
|
+
AND g.feature_key = ?
|
|
7009
|
+
AND g.enabled = 1
|
|
7010
|
+
) THEN 1 ELSE 0 END AS subscription_model_access,
|
|
6972
7011
|
u.created_at,
|
|
6973
7012
|
u.updated_at,
|
|
6974
7013
|
u.email_verified_at,
|
|
@@ -7000,6 +7039,9 @@ export class TaskforceCore {
|
|
|
7000
7039
|
systemRole: this.normalizeSystemRole(row.system_role, 'user'),
|
|
7001
7040
|
betaAccess: row.beta_access === undefined || row.beta_access === null ? true : Boolean(row.beta_access),
|
|
7002
7041
|
disabled: Boolean(row.is_disabled),
|
|
7042
|
+
internalFeatureGrants: Boolean(row.subscription_model_access)
|
|
7043
|
+
? [INTERNAL_SUBSCRIPTION_MODEL_FEATURE_KEY]
|
|
7044
|
+
: [],
|
|
7003
7045
|
planId: row.plan_id ? String(row.plan_id) : null,
|
|
7004
7046
|
planName: row.plan_name ? String(row.plan_name) : null,
|
|
7005
7047
|
planVersionId: row.plan_version_id ? String(row.plan_version_id) : null,
|
|
@@ -7073,6 +7115,53 @@ export class TaskforceCore {
|
|
|
7073
7115
|
`).run(enabled ? 1 : 0, new Date().toISOString(), this.tenantId, normalizedUserId);
|
|
7074
7116
|
return Number(result?.changes || 0) > 0;
|
|
7075
7117
|
}
|
|
7118
|
+
hasUserFeatureGrant(userId, featureKey) {
|
|
7119
|
+
const normalizedUserId = String(userId || '').trim();
|
|
7120
|
+
if (!normalizedUserId || !isSupportedInternalUserFeatureKey(featureKey))
|
|
7121
|
+
return false;
|
|
7122
|
+
const row = this.db.prepare(`
|
|
7123
|
+
SELECT enabled
|
|
7124
|
+
FROM user_feature_grants
|
|
7125
|
+
WHERE tenant_id = ? AND user_id = ? AND feature_key = ?
|
|
7126
|
+
LIMIT 1
|
|
7127
|
+
`).get(this.tenantId, normalizedUserId, featureKey);
|
|
7128
|
+
return Boolean(row?.enabled);
|
|
7129
|
+
}
|
|
7130
|
+
listUserFeatureGrants(userId) {
|
|
7131
|
+
const normalizedUserId = String(userId || '').trim();
|
|
7132
|
+
if (!normalizedUserId)
|
|
7133
|
+
return [];
|
|
7134
|
+
const rows = this.db.prepare(`
|
|
7135
|
+
SELECT feature_key
|
|
7136
|
+
FROM user_feature_grants
|
|
7137
|
+
WHERE tenant_id = ? AND user_id = ? AND enabled = 1
|
|
7138
|
+
ORDER BY feature_key
|
|
7139
|
+
`).all(this.tenantId, normalizedUserId);
|
|
7140
|
+
return rows
|
|
7141
|
+
.map((row) => row.feature_key)
|
|
7142
|
+
.filter(isSupportedInternalUserFeatureKey);
|
|
7143
|
+
}
|
|
7144
|
+
setUserFeatureGrant(userId, featureKey, enabled, updatedBy) {
|
|
7145
|
+
const normalizedUserId = String(userId || '').trim();
|
|
7146
|
+
if (!normalizedUserId || !isSupportedInternalUserFeatureKey(featureKey))
|
|
7147
|
+
return false;
|
|
7148
|
+
const user = this.db.prepare(`
|
|
7149
|
+
SELECT id FROM users WHERE tenant_id = ? AND id = ? LIMIT 1
|
|
7150
|
+
`).get(this.tenantId, normalizedUserId);
|
|
7151
|
+
if (!user?.id)
|
|
7152
|
+
return false;
|
|
7153
|
+
const now = new Date().toISOString();
|
|
7154
|
+
this.db.prepare(`
|
|
7155
|
+
INSERT INTO user_feature_grants (
|
|
7156
|
+
tenant_id, user_id, feature_key, enabled, created_at, updated_at, updated_by
|
|
7157
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
7158
|
+
ON CONFLICT (tenant_id, user_id, feature_key) DO UPDATE SET
|
|
7159
|
+
enabled = excluded.enabled,
|
|
7160
|
+
updated_at = excluded.updated_at,
|
|
7161
|
+
updated_by = excluded.updated_by
|
|
7162
|
+
`).run(this.tenantId, normalizedUserId, featureKey, enabled ? 1 : 0, now, now, String(updatedBy || '').trim() || null);
|
|
7163
|
+
return true;
|
|
7164
|
+
}
|
|
7076
7165
|
markUserEmailVerified(userId) {
|
|
7077
7166
|
const normalizedUserId = String(userId || '').trim();
|
|
7078
7167
|
if (!normalizedUserId)
|
|
@@ -7179,6 +7268,14 @@ export class TaskforceCore {
|
|
|
7179
7268
|
if (hasCommercialBillingState) {
|
|
7180
7269
|
throw new TaskforceRuleError('Cannot purge a user with active commercial billing state', 409, 'SYSTEM_USER_PURGE_BLOCKED_BILLING_STATE');
|
|
7181
7270
|
}
|
|
7271
|
+
const modelConnectionCount = Number(this.db.prepare(`
|
|
7272
|
+
SELECT COUNT(*) AS count
|
|
7273
|
+
FROM model_provider_connections
|
|
7274
|
+
WHERE tenant_id = ? AND owner_user_id = ?
|
|
7275
|
+
`).get(this.tenantId, targetUserId)?.count || 0);
|
|
7276
|
+
if (modelConnectionCount > 0) {
|
|
7277
|
+
throw new TaskforceRuleError('Disconnect and clean up the user model connections before purging this account', 409, 'SYSTEM_USER_PURGE_BLOCKED_MODEL_CONNECTIONS');
|
|
7278
|
+
}
|
|
7182
7279
|
const now = new Date().toISOString();
|
|
7183
7280
|
const runCount = (sql, ...params) => Number(this.db.prepare(sql).run(...params)?.changes || 0);
|
|
7184
7281
|
const workspaceIds = this.db.prepare(`
|
|
@@ -7278,6 +7375,11 @@ export class TaskforceCore {
|
|
|
7278
7375
|
WHERE tenant_id = ?
|
|
7279
7376
|
AND user_id = ?
|
|
7280
7377
|
`, this.tenantId, targetUserId);
|
|
7378
|
+
const deletedUserFeatureGrantCount = runCount(`
|
|
7379
|
+
DELETE FROM user_feature_grants
|
|
7380
|
+
WHERE tenant_id = ?
|
|
7381
|
+
AND user_id = ?
|
|
7382
|
+
`, this.tenantId, targetUserId);
|
|
7281
7383
|
const deletedUserBillingCount = runCount(`
|
|
7282
7384
|
DELETE FROM user_billing
|
|
7283
7385
|
WHERE tenant_id = ?
|
|
@@ -7305,6 +7407,7 @@ export class TaskforceCore {
|
|
|
7305
7407
|
deletedMcpOauthConnectorGrantCount,
|
|
7306
7408
|
deletedUiStateCount,
|
|
7307
7409
|
deletedUserPreferenceCount,
|
|
7410
|
+
deletedUserFeatureGrantCount,
|
|
7308
7411
|
deletedEntitlementCount,
|
|
7309
7412
|
deletedUserBillingCount,
|
|
7310
7413
|
deletedUserCount
|
|
@@ -7651,7 +7754,7 @@ export class TaskforceCore {
|
|
|
7651
7754
|
deletedAt: session.deletedAt,
|
|
7652
7755
|
});
|
|
7653
7756
|
}
|
|
7654
|
-
upsertDocumentReviewCommentForSync(comment) {
|
|
7757
|
+
upsertDocumentReviewCommentForSync(comment, options) {
|
|
7655
7758
|
const deps = this.getDocumentReviewServiceDeps();
|
|
7656
7759
|
return deps.commentStore.upsertForSync({
|
|
7657
7760
|
id: comment.id,
|
|
@@ -7671,7 +7774,7 @@ export class TaskforceCore {
|
|
|
7671
7774
|
createdAt: comment.createdAt,
|
|
7672
7775
|
updatedAt: comment.updatedAt,
|
|
7673
7776
|
deletedAt: comment.deletedAt,
|
|
7674
|
-
});
|
|
7777
|
+
}, options);
|
|
7675
7778
|
}
|
|
7676
7779
|
upsertAnnotatedAttachmentSessionForSync(session) {
|
|
7677
7780
|
const deps = this.getAnnotatedAttachmentServiceDeps();
|
|
@@ -8743,6 +8846,9 @@ export class TaskforceCore {
|
|
|
8743
8846
|
regenerateMcpAccessToken(input) {
|
|
8744
8847
|
return this.mcpTokenService.regenerateMcpAccessToken(input);
|
|
8745
8848
|
}
|
|
8849
|
+
updateMcpAccessTokenToolProfile(input) {
|
|
8850
|
+
return this.mcpTokenService.updateMcpAccessTokenToolProfile(input);
|
|
8851
|
+
}
|
|
8746
8852
|
authenticateMcpAccessToken(token, workspaceId) {
|
|
8747
8853
|
return this.mcpTokenService.authenticateMcpAccessToken(token, workspaceId);
|
|
8748
8854
|
}
|
|
@@ -8770,6 +8876,9 @@ export class TaskforceCore {
|
|
|
8770
8876
|
revokeMcpOAuthConnectorGrant(input) {
|
|
8771
8877
|
return this.mcpTokenService.revokeMcpOAuthConnectorGrant(input);
|
|
8772
8878
|
}
|
|
8879
|
+
updateMcpOAuthConnectorGrantToolProfile(input) {
|
|
8880
|
+
return this.mcpTokenService.updateMcpOAuthConnectorGrantToolProfile(input);
|
|
8881
|
+
}
|
|
8773
8882
|
authenticateMcpOAuthAccessToken(token, workspaceId) {
|
|
8774
8883
|
return this.mcpTokenService.authenticateMcpOAuthAccessToken(token, workspaceId);
|
|
8775
8884
|
}
|
|
@@ -9871,7 +9980,7 @@ export class TaskforceCore {
|
|
|
9871
9980
|
return this.getWorkstream(workstreamId, normalizedWorkspaceId) || updated;
|
|
9872
9981
|
})();
|
|
9873
9982
|
}
|
|
9874
|
-
installDurableTaskCreateAuthoritativeForSync(task, workspaceId) {
|
|
9983
|
+
installDurableTaskCreateAuthoritativeForSync(task, workspaceId, options) {
|
|
9875
9984
|
const normalizedWorkspaceId = this.normalizeWorkspaceId(workspaceId);
|
|
9876
9985
|
const taskId = String(task?.id || '').trim();
|
|
9877
9986
|
const createdAt = String(task?.createdAt || '').trim();
|
|
@@ -9889,6 +9998,31 @@ export class TaskforceCore {
|
|
|
9889
9998
|
return this.db.transaction(() => {
|
|
9890
9999
|
const existing = this.getTask(taskId, normalizedWorkspaceId);
|
|
9891
10000
|
if (!existing) {
|
|
10001
|
+
const deleted = options?.preserveDeletedSuccessor
|
|
10002
|
+
? this.getDeletedTask(taskId, normalizedWorkspaceId)
|
|
10003
|
+
: null;
|
|
10004
|
+
if (deleted) {
|
|
10005
|
+
this.relocateTaskReferenceConflict(normalizedWorkspaceId, referenceNumber, taskId, updatedAt);
|
|
10006
|
+
if (this.reserveTaskReferenceNumber(normalizedWorkspaceId, referenceNumber, taskId) !== referenceNumber) {
|
|
10007
|
+
throw new TaskforceRuleError('Authoritative task reference is already in use.', 409, 'WORKSPACE_SYNC_AUTHORITATIVE_RESPONSE_INVALID');
|
|
10008
|
+
}
|
|
10009
|
+
const authoritativeSnapshot = {
|
|
10010
|
+
...deleted.taskSnapshot,
|
|
10011
|
+
referenceNumber,
|
|
10012
|
+
localReferenceNumber: null,
|
|
10013
|
+
referenceLabel: deriveTaskReferenceLabel({ referenceNumber, localReferenceNumber: null }),
|
|
10014
|
+
createdAt,
|
|
10015
|
+
createdBy: task.createdBy,
|
|
10016
|
+
};
|
|
10017
|
+
const updated = this.db.prepare(`
|
|
10018
|
+
UPDATE deleted_tasks SET task_snapshot_json = ?
|
|
10019
|
+
WHERE tenant_id = ? AND workspace_id = ? AND task_id = ?
|
|
10020
|
+
`).run(JSON.stringify(authoritativeSnapshot), this.tenantId, normalizedWorkspaceId, taskId);
|
|
10021
|
+
if (Number(updated.changes || 0) !== 1) {
|
|
10022
|
+
throw new TaskforceRuleError('Captured deleted task history is missing.', 409, 'WORKSPACE_SYNC_AUTHORITATIVE_RESPONSE_INVALID');
|
|
10023
|
+
}
|
|
10024
|
+
return this.getDeletedTask(taskId, normalizedWorkspaceId).taskSnapshot;
|
|
10025
|
+
}
|
|
9892
10026
|
throw new TaskforceRuleError('Task not found.', 404, 'TASK_NOT_FOUND');
|
|
9893
10027
|
}
|
|
9894
10028
|
const mutableCreateFields = [
|
|
@@ -10653,8 +10787,25 @@ export class TaskforceCore {
|
|
|
10653
10787
|
return null;
|
|
10654
10788
|
const submittedAuthor = String(author || '').trim() || 'user';
|
|
10655
10789
|
const normalizedAuthor = this.normalizeCommentAuthor(author, normalizedWorkspaceId);
|
|
10790
|
+
const explicitCommentId = String(options?.commentId || '').trim();
|
|
10791
|
+
if (explicitCommentId) {
|
|
10792
|
+
const persisted = this.db.prepare(`
|
|
10793
|
+
SELECT task_id, text, author, submitted_author
|
|
10794
|
+
FROM comments
|
|
10795
|
+
WHERE tenant_id = ? AND workspace_id = ? AND id = ?
|
|
10796
|
+
`).get(this.tenantId, normalizedWorkspaceId, explicitCommentId);
|
|
10797
|
+
if (persisted) {
|
|
10798
|
+
if (persisted.task_id !== id
|
|
10799
|
+
|| persisted.text !== text
|
|
10800
|
+
|| persisted.author !== normalizedAuthor
|
|
10801
|
+
|| String(persisted.submitted_author || persisted.author) !== submittedAuthor) {
|
|
10802
|
+
throw new TaskforceRuleError('Task comment identity is assigned to different content.', 409, 'TASK_COMMENT_IDENTITY_CONFLICT');
|
|
10803
|
+
}
|
|
10804
|
+
return this.getTask(id, normalizedWorkspaceId);
|
|
10805
|
+
}
|
|
10806
|
+
}
|
|
10656
10807
|
const comment = {
|
|
10657
|
-
id: this.generateEntityId('comment'),
|
|
10808
|
+
id: explicitCommentId || this.generateEntityId('comment'),
|
|
10658
10809
|
author: normalizedAuthor,
|
|
10659
10810
|
submittedAuthor,
|
|
10660
10811
|
text,
|
|
@@ -10697,7 +10848,7 @@ export class TaskforceCore {
|
|
|
10697
10848
|
if (options?.persistBackup !== false)
|
|
10698
10849
|
this.persistBackup();
|
|
10699
10850
|
const updated = this.getTask(id, normalizedWorkspaceId);
|
|
10700
|
-
if (updated) {
|
|
10851
|
+
if (updated && options?.emitRealtime !== false) {
|
|
10701
10852
|
this.emitRealtimeMutation({
|
|
10702
10853
|
workspaceId: normalizedWorkspaceId,
|
|
10703
10854
|
entityType: 'task',
|