@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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { fingerprintWorkspaceSyncPayload, } from '../v3/syncDurabilityStore.js';
|
|
2
2
|
import { canonicalWorkspaceSyncJson } from '../v3/canonicalWorkspaceSyncJson.js';
|
|
3
3
|
import { WORKSPACE_SYNC_V2_EXCLUDABLE_PROJECTIONS, } from '../v3/workspaceSyncV2ProjectionExclusions.js';
|
|
4
|
+
import { createWorkspaceSyncEngineV2SettlementIdentityProjection } from '../engine/workspaceSyncEnginePushCompletion.js';
|
|
4
5
|
import { WORKSPACE_PUSH_PREPARED_PLAN_VERSION, } from '../workspacePushPreparedPlan.js';
|
|
5
6
|
import { LOCAL_SYNC_COORDINATOR_ID } from './localSyncCoordinatorTypes.js';
|
|
6
7
|
export const LOCAL_WORKSPACE_SYNC_RUNNER_STATE_VERSION = 1;
|
|
@@ -123,6 +124,7 @@ const ENCODED_PAYLOAD_OPTIONAL_KEYS = [
|
|
|
123
124
|
'currentTaskChangeKeys',
|
|
124
125
|
'currentTaskRelationshipChangeKeys',
|
|
125
126
|
'currentTaxonomyChangeKey',
|
|
127
|
+
'currentPlanningIdentityWatermarks',
|
|
126
128
|
'currentAiProfileChangeKeys',
|
|
127
129
|
'currentTaskforceAgentIds',
|
|
128
130
|
'currentTaskforceAgentWatermarks',
|
|
@@ -176,6 +178,7 @@ const OPTIONAL_DIAGNOSTIC_DOMAINS = [
|
|
|
176
178
|
'taskforceAgents',
|
|
177
179
|
'taskforceAgentSkills',
|
|
178
180
|
'agentConversations',
|
|
181
|
+
'planningIdentities',
|
|
179
182
|
];
|
|
180
183
|
function isDeltaDiagnostics(value) {
|
|
181
184
|
if (!isRecord(value) || !hasExactKeys(value, [
|
|
@@ -240,6 +243,7 @@ function isEncodedWorkspaceSyncPayload(value) {
|
|
|
240
243
|
'currentTaskWatermarks',
|
|
241
244
|
'currentTaskChangeKeys',
|
|
242
245
|
'currentTaskRelationshipChangeKeys',
|
|
246
|
+
'currentPlanningIdentityWatermarks',
|
|
243
247
|
'currentAiProfileChangeKeys',
|
|
244
248
|
'currentTaskforceAgentWatermarks',
|
|
245
249
|
'currentTaskforceAgentSkillWatermarks',
|
|
@@ -302,6 +306,7 @@ export function encodeWorkspaceSyncPayload(payload) {
|
|
|
302
306
|
currentInitiativeWatermarks: encodeStringMap(payload.currentInitiativeWatermarks, 'Initiative watermarks'),
|
|
303
307
|
currentWorkstreamIds: encodeStringSet(payload.currentWorkstreamIds, 'Current workstream ids'),
|
|
304
308
|
currentWorkstreamWatermarks: encodeStringMap(payload.currentWorkstreamWatermarks, 'Workstream watermarks'),
|
|
309
|
+
currentPlanningIdentityWatermarks: encodeStringMap(payload.currentPlanningIdentityWatermarks || new Map(), 'Planning identity watermarks'),
|
|
305
310
|
currentAiProfileIds: encodeStringSet(payload.currentAiProfileIds, 'Current AI profile ids'),
|
|
306
311
|
currentAiProfileWatermarks: encodeStringMap(payload.currentAiProfileWatermarks, 'AI profile watermarks'),
|
|
307
312
|
currentAiProfileChangeKeys: encodeOptionalStringMap(payload.currentAiProfileChangeKeys, 'AI profile change keys'),
|
|
@@ -356,6 +361,7 @@ export function decodeWorkspaceSyncPayload(encoded) {
|
|
|
356
361
|
currentInitiativeWatermarks: new Map(encoded.currentInitiativeWatermarks),
|
|
357
362
|
currentWorkstreamIds: new Set(encoded.currentWorkstreamIds),
|
|
358
363
|
currentWorkstreamWatermarks: new Map(encoded.currentWorkstreamWatermarks),
|
|
364
|
+
currentPlanningIdentityWatermarks: new Map(encoded.currentPlanningIdentityWatermarks || []),
|
|
359
365
|
currentAiProfileIds: new Set(encoded.currentAiProfileIds),
|
|
360
366
|
currentAiProfileWatermarks: new Map(encoded.currentAiProfileWatermarks),
|
|
361
367
|
currentAiProfileChangeKeys: encoded.currentAiProfileChangeKeys
|
|
@@ -411,6 +417,21 @@ export function createLocalWorkspaceSyncPendingV2Push(input) {
|
|
|
411
417
|
export function fingerprintLocalWorkspaceSyncPreparedPlan(plan) {
|
|
412
418
|
return fingerprintWorkspaceSyncPayload(plan);
|
|
413
419
|
}
|
|
420
|
+
export function upgradeLocalWorkspaceSyncPendingV2PushSettlement(pending) {
|
|
421
|
+
if (pending.settlementVersion === 1)
|
|
422
|
+
return structuredClone(pending);
|
|
423
|
+
if (!pending.preparedPlan || !pending.preparedPlanFingerprint) {
|
|
424
|
+
throw new Error('The frozen V2 push must have a prepared plan before settlement activation.');
|
|
425
|
+
}
|
|
426
|
+
return {
|
|
427
|
+
...structuredClone(pending),
|
|
428
|
+
settlementVersion: 1,
|
|
429
|
+
settledBatchOperationIdentities: [
|
|
430
|
+
...pending.acknowledgedNonApplyingBatchOperationIdentities,
|
|
431
|
+
],
|
|
432
|
+
settledBatchContributions: [],
|
|
433
|
+
};
|
|
434
|
+
}
|
|
414
435
|
function isPushBaseline(value) {
|
|
415
436
|
if (!isRecord(value))
|
|
416
437
|
return false;
|
|
@@ -421,6 +442,7 @@ function isPushBaseline(value) {
|
|
|
421
442
|
'taskRelationshipChangeKeys',
|
|
422
443
|
'initiativeWatermarks',
|
|
423
444
|
'workstreamWatermarks',
|
|
445
|
+
'planningIdentityWatermarks',
|
|
424
446
|
'aiProfileWatermarks',
|
|
425
447
|
'aiProfileChangeKeys',
|
|
426
448
|
'taskforceAgentWatermarks',
|
|
@@ -458,6 +480,7 @@ function isPushBaseline(value) {
|
|
|
458
480
|
'taskforceAgentWatermarks',
|
|
459
481
|
'taskforceAgentSkillWatermarks',
|
|
460
482
|
'agentConversationWatermarks',
|
|
483
|
+
'planningIdentityWatermarks',
|
|
461
484
|
];
|
|
462
485
|
if (optionalPairs.some((key) => value[key] !== undefined && !isStringPairArray(value[key])))
|
|
463
486
|
return false;
|
|
@@ -470,7 +493,9 @@ function isPushBaseline(value) {
|
|
|
470
493
|
return true;
|
|
471
494
|
}
|
|
472
495
|
function isPendingV2Push(value) {
|
|
473
|
-
if (!isRecord(value)
|
|
496
|
+
if (!isRecord(value))
|
|
497
|
+
return false;
|
|
498
|
+
const legacyKeys = [
|
|
474
499
|
'signature',
|
|
475
500
|
'payloadFingerprint',
|
|
476
501
|
'frozenPayload',
|
|
@@ -480,8 +505,71 @@ function isPendingV2Push(value) {
|
|
|
480
505
|
'preparedPlanFingerprint',
|
|
481
506
|
'acknowledgedNonApplyingBatchOperationIdentities',
|
|
482
507
|
'lastBatchProgress',
|
|
483
|
-
]
|
|
508
|
+
];
|
|
509
|
+
const settlementKeys = [
|
|
510
|
+
...legacyKeys,
|
|
511
|
+
'settlementVersion',
|
|
512
|
+
'settledBatchOperationIdentities',
|
|
513
|
+
'settledBatchContributions',
|
|
514
|
+
];
|
|
515
|
+
const hasLegacyShape = hasExactKeys(value, legacyKeys);
|
|
516
|
+
const hasSettlementShape = hasExactKeys(value, settlementKeys);
|
|
517
|
+
if (!hasLegacyShape && !hasSettlementShape)
|
|
484
518
|
return false;
|
|
519
|
+
const settledBatchOperationIdentities = isStringArray(value.settledBatchOperationIdentities) ? value.settledBatchOperationIdentities : null;
|
|
520
|
+
const settledBatchContributions = Array.isArray(value.settledBatchContributions) ? value.settledBatchContributions : null;
|
|
521
|
+
const preparedPlan = isPreparedV2PushPlan(value.preparedPlan)
|
|
522
|
+
? value.preparedPlan
|
|
523
|
+
: null;
|
|
524
|
+
const settlementValid = hasLegacyShape || (value.settlementVersion === 1
|
|
525
|
+
&& settledBatchOperationIdentities !== null
|
|
526
|
+
&& new Set(settledBatchOperationIdentities).size
|
|
527
|
+
=== settledBatchOperationIdentities.length
|
|
528
|
+
&& settledBatchOperationIdentities.every((identity) => /^[a-f0-9]{64}$/.test(identity))
|
|
529
|
+
&& settledBatchContributions !== null
|
|
530
|
+
&& settledBatchContributions.every((entry) => (isRecord(entry)
|
|
531
|
+
&& hasExactKeys(entry, [
|
|
532
|
+
'operationIdentity',
|
|
533
|
+
'settlementIdentityFingerprint',
|
|
534
|
+
'appliedTaskUpserts',
|
|
535
|
+
])
|
|
536
|
+
&& typeof entry.operationIdentity === 'string'
|
|
537
|
+
&& /^[a-f0-9]{64}$/.test(entry.operationIdentity)
|
|
538
|
+
&& typeof entry.settlementIdentityFingerprint === 'string'
|
|
539
|
+
&& /^[a-f0-9]{64}$/.test(entry.settlementIdentityFingerprint)
|
|
540
|
+
&& Array.isArray(entry.appliedTaskUpserts)
|
|
541
|
+
&& entry.appliedTaskUpserts.every((upsert) => (isRecord(upsert)
|
|
542
|
+
&& hasRequiredAndAllowedKeys(upsert, ['archived', 'task'], ['durableRevision'])
|
|
543
|
+
&& typeof upsert.archived === 'boolean'
|
|
544
|
+
&& isRecord(upsert.task)
|
|
545
|
+
&& isNonEmptyText(upsert.task.id)
|
|
546
|
+
&& isJson(upsert.task)
|
|
547
|
+
&& (upsert.durableRevision === undefined
|
|
548
|
+
|| (isRecord(upsert.durableRevision) && isJson(upsert.durableRevision)))))))
|
|
549
|
+
&& new Set(settledBatchContributions.map((entry) => entry.operationIdentity)).size === settledBatchContributions.length
|
|
550
|
+
&& settledBatchContributions.every((entry) => (settledBatchOperationIdentities.includes(entry.operationIdentity))));
|
|
551
|
+
const settlementContributionsMatchPlan = hasLegacyShape || (preparedPlan !== null
|
|
552
|
+
&& settledBatchContributions !== null
|
|
553
|
+
&& settledBatchContributions.every((rawEntry) => {
|
|
554
|
+
const entry = rawEntry;
|
|
555
|
+
const batchIndex = preparedPlan.batchOperationIdentities.indexOf(entry.operationIdentity);
|
|
556
|
+
if (batchIndex < 0)
|
|
557
|
+
return false;
|
|
558
|
+
const changes = preparedPlan.batches[batchIndex].map((planEntry) => (planEntry.preparedChange
|
|
559
|
+
|| value.frozenPayload
|
|
560
|
+
.changes[planEntry.sourceChangeIndex]));
|
|
561
|
+
try {
|
|
562
|
+
return fingerprintWorkspaceSyncPayload(createWorkspaceSyncEngineV2SettlementIdentityProjection({
|
|
563
|
+
operationIdentity: entry.operationIdentity,
|
|
564
|
+
changes,
|
|
565
|
+
appliedTaskUpserts: entry.appliedTaskUpserts,
|
|
566
|
+
excludedProjections: preparedPlan.ownership.combinedExcludedProjections,
|
|
567
|
+
})) === entry.settlementIdentityFingerprint;
|
|
568
|
+
}
|
|
569
|
+
catch {
|
|
570
|
+
return false;
|
|
571
|
+
}
|
|
572
|
+
}));
|
|
485
573
|
return isNonEmptyText(value.signature)
|
|
486
574
|
&& typeof value.payloadFingerprint === 'string'
|
|
487
575
|
&& /^[a-f0-9]{64}$/.test(value.payloadFingerprint)
|
|
@@ -499,6 +587,12 @@ function isPendingV2Push(value) {
|
|
|
499
587
|
< value.frozenPayload.changes.length))))
|
|
500
588
|
&& isStringArray(value.acknowledgedNonApplyingBatchOperationIdentities)
|
|
501
589
|
&& value.acknowledgedNonApplyingBatchOperationIdentities.every((identity) => /^[a-f0-9]{64}$/.test(identity))
|
|
590
|
+
&& settlementValid
|
|
591
|
+
&& settlementContributionsMatchPlan
|
|
592
|
+
&& (!hasSettlementShape
|
|
593
|
+
|| (preparedPlan !== null
|
|
594
|
+
&& settledBatchOperationIdentities !== null
|
|
595
|
+
&& settledBatchOperationIdentities.every((identity) => preparedPlan.batchOperationIdentities.includes(identity))))
|
|
502
596
|
&& (value.lastBatchProgress === null
|
|
503
597
|
|| (isPendingV2PushBatchProgress(value.lastBatchProgress)
|
|
504
598
|
&& value.lastBatchProgress.completedChanges <= value.frozenPayload.changes.length
|
|
@@ -582,6 +676,9 @@ function normalizePendingV2Push(value) {
|
|
|
582
676
|
'preparedPlan',
|
|
583
677
|
'preparedPlanFingerprint',
|
|
584
678
|
'acknowledgedNonApplyingBatchOperationIdentities',
|
|
679
|
+
'settlementVersion',
|
|
680
|
+
'settledBatchOperationIdentities',
|
|
681
|
+
'settledBatchContributions',
|
|
585
682
|
'lastBatchProgress',
|
|
586
683
|
])) {
|
|
587
684
|
return value;
|
|
@@ -43,6 +43,7 @@ export declare class WorkspaceSyncCredentialBrokerError extends Error {
|
|
|
43
43
|
export declare class WorkspaceSyncCredentialBroker {
|
|
44
44
|
private readonly options;
|
|
45
45
|
private capability;
|
|
46
|
+
private boundIdentity;
|
|
46
47
|
private blockedReason;
|
|
47
48
|
constructor(options: {
|
|
48
49
|
sessionCookieName: string;
|
|
@@ -12,6 +12,9 @@ export class WorkspaceSyncCredentialBrokerError extends Error {
|
|
|
12
12
|
export class WorkspaceSyncCredentialBroker {
|
|
13
13
|
options;
|
|
14
14
|
capability = null;
|
|
15
|
+
// Retain the non-secret principal fence while auth is blocked so a logout or
|
|
16
|
+
// expired cookie cannot let another account adopt the live coordinator.
|
|
17
|
+
boundIdentity = null;
|
|
15
18
|
blockedReason = 'server-restart';
|
|
16
19
|
constructor(options) {
|
|
17
20
|
this.options = options;
|
|
@@ -39,16 +42,21 @@ export class WorkspaceSyncCredentialBroker {
|
|
|
39
42
|
throw new WorkspaceSyncCredentialBrokerError('The Taskforce session is not valid for the requested workspace.', 'SYNC_COORDINATOR_AUTH_INVALID');
|
|
40
43
|
}
|
|
41
44
|
const existing = this.capability;
|
|
45
|
+
const identity = existing || this.boundIdentity;
|
|
42
46
|
const samePrincipal = existing
|
|
43
47
|
&& existing.workspaceId === validated.workspaceId
|
|
44
48
|
&& existing.principal.userId === validated.principal.userId
|
|
45
49
|
&& existing.principal.tenantId === validated.principal.tenantId;
|
|
46
|
-
|
|
50
|
+
const sameBoundIdentity = identity
|
|
51
|
+
&& identity.workspaceId === validated.workspaceId
|
|
52
|
+
&& identity.principal.userId === validated.principal.userId
|
|
53
|
+
&& identity.principal.tenantId === validated.principal.tenantId;
|
|
54
|
+
if (identity && !sameBoundIdentity && !input.allowPrincipalRebind) {
|
|
47
55
|
throw new WorkspaceSyncCredentialBrokerError('A different Taskforce principal is already bound to this workspace coordinator.', 'SYNC_COORDINATOR_PRINCIPAL_CONFLICT');
|
|
48
56
|
}
|
|
49
|
-
if (
|
|
50
|
-
&& input.coordinatorGeneration <
|
|
51
|
-
throw new WorkspaceSyncCredentialBrokerError(`Coordinator generation ${input.coordinatorGeneration} is stale; current generation is ${
|
|
57
|
+
if (sameBoundIdentity
|
|
58
|
+
&& input.coordinatorGeneration < identity.coordinatorGeneration) {
|
|
59
|
+
throw new WorkspaceSyncCredentialBrokerError(`Coordinator generation ${input.coordinatorGeneration} is stale; current generation is ${identity.coordinatorGeneration}.`, 'SYNC_COORDINATOR_STALE_GENERATION');
|
|
52
60
|
}
|
|
53
61
|
const authorizedCookies = samePrincipal
|
|
54
62
|
? new Map(existing.authorizedCookies)
|
|
@@ -67,6 +75,11 @@ export class WorkspaceSyncCredentialBroker {
|
|
|
67
75
|
cookieHeader,
|
|
68
76
|
authorizedCookies,
|
|
69
77
|
};
|
|
78
|
+
this.boundIdentity = {
|
|
79
|
+
workspaceId: validated.workspaceId,
|
|
80
|
+
coordinatorGeneration: input.coordinatorGeneration,
|
|
81
|
+
principal: validated.principal,
|
|
82
|
+
};
|
|
70
83
|
this.blockedReason = null;
|
|
71
84
|
return this.readSnapshot();
|
|
72
85
|
}
|
|
@@ -143,6 +156,11 @@ export class WorkspaceSyncCredentialBroker {
|
|
|
143
156
|
cookieHeader: prepared.cookieHeader,
|
|
144
157
|
authorizedCookies: new Map([[cookieValue, prepared.validation]]),
|
|
145
158
|
};
|
|
159
|
+
this.boundIdentity = {
|
|
160
|
+
workspaceId: prepared.targetWorkspaceId,
|
|
161
|
+
coordinatorGeneration: prepared.targetCoordinatorGeneration,
|
|
162
|
+
principal: prepared.principal,
|
|
163
|
+
};
|
|
146
164
|
prepared.activated = true;
|
|
147
165
|
this.blockedReason = null;
|
|
148
166
|
return this.readSnapshot();
|
|
@@ -159,6 +177,11 @@ export class WorkspaceSyncCredentialBroker {
|
|
|
159
177
|
coordinatorGeneration,
|
|
160
178
|
authorizedCookies: new Map(prepared.sourceCapability.authorizedCookies),
|
|
161
179
|
};
|
|
180
|
+
this.boundIdentity = {
|
|
181
|
+
workspaceId: prepared.sourceWorkspaceId,
|
|
182
|
+
coordinatorGeneration,
|
|
183
|
+
principal: prepared.sourceCapability.principal,
|
|
184
|
+
};
|
|
162
185
|
prepared.activated = false;
|
|
163
186
|
this.blockedReason = null;
|
|
164
187
|
}
|
|
@@ -175,6 +198,9 @@ export class WorkspaceSyncCredentialBroker {
|
|
|
175
198
|
throw new WorkspaceSyncCredentialBrokerError('The coordinator generation transition is invalid.', 'SYNC_COORDINATOR_STALE_GENERATION');
|
|
176
199
|
}
|
|
177
200
|
this.capability.coordinatorGeneration = input.toCoordinatorGeneration;
|
|
201
|
+
if (this.boundIdentity) {
|
|
202
|
+
this.boundIdentity.coordinatorGeneration = input.toCoordinatorGeneration;
|
|
203
|
+
}
|
|
178
204
|
return this.readSnapshot();
|
|
179
205
|
}
|
|
180
206
|
/**
|
|
@@ -197,6 +223,9 @@ export class WorkspaceSyncCredentialBroker {
|
|
|
197
223
|
throw new WorkspaceSyncCredentialBrokerError('The coordinator generation transition is stale or non-adjacent.', 'SYNC_COORDINATOR_STALE_GENERATION');
|
|
198
224
|
}
|
|
199
225
|
capability.coordinatorGeneration = input.toCoordinatorGeneration;
|
|
226
|
+
if (this.boundIdentity) {
|
|
227
|
+
this.boundIdentity.coordinatorGeneration = input.toCoordinatorGeneration;
|
|
228
|
+
}
|
|
200
229
|
return this.readSnapshot();
|
|
201
230
|
}
|
|
202
231
|
authorizeCookieHeader(input) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type WorkspaceSyncContentHead, type WorkspaceSyncContentKind, type WorkspaceSyncContentScope, type WorkspaceSyncContentVersionStore } from './workspaceSyncContentVersionStore.js';
|
|
1
|
+
import { type WorkspaceSyncContentHead, type WorkspaceSyncContentKind, type WorkspaceSyncContentScope, type WorkspaceSyncContentTombstoneProvenance, type WorkspaceSyncContentVersionStore } from './workspaceSyncContentVersionStore.js';
|
|
2
2
|
export type WorkspaceSyncContentTombstoneInput = WorkspaceSyncContentScope & {
|
|
3
3
|
kind: WorkspaceSyncContentKind;
|
|
4
4
|
logicalPath: string;
|
|
@@ -6,6 +6,7 @@ export type WorkspaceSyncContentTombstoneInput = WorkspaceSyncContentScope & {
|
|
|
6
6
|
publishedAt: string;
|
|
7
7
|
deletedAt: string;
|
|
8
8
|
retireGcAfter?: string | null;
|
|
9
|
+
provenance?: WorkspaceSyncContentTombstoneProvenance;
|
|
9
10
|
};
|
|
10
11
|
export interface WorkspaceSyncContentLifecyclePort {
|
|
11
12
|
tombstone(input: WorkspaceSyncContentTombstoneInput): WorkspaceSyncContentHead;
|
|
@@ -48,6 +48,36 @@ export type WorkspaceSyncContentHead = WorkspaceSyncContentScope & {
|
|
|
48
48
|
publishedAt: string;
|
|
49
49
|
deletedAt: string | null;
|
|
50
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* Durable, queryable attribution for an accepted content tombstone. operationId/
|
|
53
|
+
* actorId are optional because the current WorkspaceSyncChange wire format and
|
|
54
|
+
* apply pipeline don't yet carry per-change requester identity from origin
|
|
55
|
+
* through to this layer — threading that through is a larger, separate change
|
|
56
|
+
* (it would mean extending the delete-change payload and every intermediate
|
|
57
|
+
* outbox/apply layer, not just this store). What IS reliably knowable at the
|
|
58
|
+
* point a tombstone is admitted is recorded: which admission path produced it,
|
|
59
|
+
* the source revision it was admitted at, which runtime applied it, and
|
|
60
|
+
* whether workspace repair was involved.
|
|
61
|
+
*/
|
|
62
|
+
export type WorkspaceSyncContentTombstoneProvenance = {
|
|
63
|
+
source: 'explicit-delete' | 'synchronized-tombstone' | 'repair';
|
|
64
|
+
operationId?: string | null;
|
|
65
|
+
actorId?: string | null;
|
|
66
|
+
sourceRuntime?: string | null;
|
|
67
|
+
repairInvolved?: boolean;
|
|
68
|
+
};
|
|
69
|
+
export type WorkspaceSyncContentTombstoneProvenanceRecord = WorkspaceSyncContentScope & {
|
|
70
|
+
id: string;
|
|
71
|
+
kind: WorkspaceSyncContentKind;
|
|
72
|
+
logicalPath: string;
|
|
73
|
+
source: string;
|
|
74
|
+
operationId: string | null;
|
|
75
|
+
actorId: string | null;
|
|
76
|
+
sourceRuntime: string | null;
|
|
77
|
+
sourceUpdatedAt: string;
|
|
78
|
+
repairInvolved: boolean;
|
|
79
|
+
recordedAt: string;
|
|
80
|
+
};
|
|
51
81
|
export type WorkspaceSyncContentLegacyFallback = {
|
|
52
82
|
source: 'legacy';
|
|
53
83
|
};
|
|
@@ -141,7 +171,15 @@ export declare class WorkspaceSyncContentVersionStore {
|
|
|
141
171
|
publishedAt: string;
|
|
142
172
|
deletedAt: string;
|
|
143
173
|
retireGcAfter?: string | null;
|
|
174
|
+
provenance?: WorkspaceSyncContentTombstoneProvenance;
|
|
144
175
|
}): WorkspaceSyncContentHead;
|
|
176
|
+
private recordTombstoneProvenance;
|
|
177
|
+
/** Queryable read side for tombstone provenance — most recent admission first. */
|
|
178
|
+
listTombstoneProvenance(input: WorkspaceSyncContentScope & {
|
|
179
|
+
kind?: WorkspaceSyncContentKind;
|
|
180
|
+
logicalPath?: string;
|
|
181
|
+
limit?: number;
|
|
182
|
+
}): WorkspaceSyncContentTombstoneProvenanceRecord[];
|
|
145
183
|
resolveHead(input: WorkspaceSyncContentScope & {
|
|
146
184
|
kind: WorkspaceSyncContentKind;
|
|
147
185
|
logicalPath: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createHash } from 'crypto';
|
|
1
|
+
import { createHash, randomUUID } from 'crypto';
|
|
2
2
|
import { compareWorkspaceMutationOrdering } from '../workspaceSyncSurface.js';
|
|
3
3
|
import { canonicalWorkspaceSyncJson } from '../v3/canonicalWorkspaceSyncJson.js';
|
|
4
4
|
export class WorkspaceSyncContentVersionConflictError extends Error {
|
|
@@ -577,9 +577,58 @@ export class WorkspaceSyncContentVersionStore {
|
|
|
577
577
|
contentSha256: null,
|
|
578
578
|
sizeBytes: null,
|
|
579
579
|
});
|
|
580
|
+
// Only a tombstone that's actually newly accepted (didn't early-return
|
|
581
|
+
// above as superseded/no-op) gets a provenance record — provenance
|
|
582
|
+
// tracks admission events, not every replayed/no-op call.
|
|
583
|
+
this.recordTombstoneProvenance(input);
|
|
580
584
|
return this.requireHead(input);
|
|
581
585
|
})();
|
|
582
586
|
}
|
|
587
|
+
recordTombstoneProvenance(input) {
|
|
588
|
+
const provenance = input.provenance;
|
|
589
|
+
this.db.prepare(`
|
|
590
|
+
INSERT INTO workspace_sync_content_tombstone_provenance (
|
|
591
|
+
id, tenant_id, workspace_id, kind, logical_path, source,
|
|
592
|
+
operation_id, actor_id, source_runtime, source_updated_at,
|
|
593
|
+
repair_involved, recorded_at
|
|
594
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
595
|
+
`).run(randomUUID(), input.tenantId, input.workspaceId, input.kind, input.logicalPath, provenance?.source || 'unknown', provenance?.operationId || null, provenance?.actorId || null, provenance?.sourceRuntime || null, input.sourceUpdatedAt, provenance?.repairInvolved === true ? 1 : 0, input.publishedAt);
|
|
596
|
+
}
|
|
597
|
+
/** Queryable read side for tombstone provenance — most recent admission first. */
|
|
598
|
+
listTombstoneProvenance(input) {
|
|
599
|
+
const limit = Math.max(1, Math.min(500, Math.floor(Number(input.limit) || 100)));
|
|
600
|
+
const conditions = ['tenant_id = ?', 'workspace_id = ?'];
|
|
601
|
+
const params = [input.tenantId, input.workspaceId];
|
|
602
|
+
if (input.kind) {
|
|
603
|
+
conditions.push('kind = ?');
|
|
604
|
+
params.push(input.kind);
|
|
605
|
+
}
|
|
606
|
+
if (input.logicalPath) {
|
|
607
|
+
conditions.push('logical_path = ?');
|
|
608
|
+
params.push(input.logicalPath);
|
|
609
|
+
}
|
|
610
|
+
const rows = this.db.prepare(`
|
|
611
|
+
SELECT *
|
|
612
|
+
FROM workspace_sync_content_tombstone_provenance
|
|
613
|
+
WHERE ${conditions.join(' AND ')}
|
|
614
|
+
ORDER BY recorded_at DESC
|
|
615
|
+
LIMIT ?
|
|
616
|
+
`).all(...params, limit);
|
|
617
|
+
return rows.map((row) => ({
|
|
618
|
+
id: String(row.id || ''),
|
|
619
|
+
tenantId: String(row.tenant_id || ''),
|
|
620
|
+
workspaceId: String(row.workspace_id || ''),
|
|
621
|
+
kind: row.kind === 'document' ? 'document' : 'asset',
|
|
622
|
+
logicalPath: String(row.logical_path || ''),
|
|
623
|
+
source: String(row.source || 'unknown'),
|
|
624
|
+
operationId: row.operation_id == null ? null : String(row.operation_id),
|
|
625
|
+
actorId: row.actor_id == null ? null : String(row.actor_id),
|
|
626
|
+
sourceRuntime: row.source_runtime == null ? null : String(row.source_runtime),
|
|
627
|
+
sourceUpdatedAt: String(row.source_updated_at || ''),
|
|
628
|
+
repairInvolved: Number(row.repair_involved) === 1,
|
|
629
|
+
recordedAt: String(row.recorded_at || ''),
|
|
630
|
+
}));
|
|
631
|
+
}
|
|
583
632
|
resolveHead(input) {
|
|
584
633
|
const head = this.getHead(input);
|
|
585
634
|
return head ? { source: 'versioned', head } : { source: 'legacy' };
|
|
@@ -25,7 +25,7 @@ export function resolveWorkspaceSyncPresentation({ enabled, phase, busy, retryAt
|
|
|
25
25
|
summary: busy
|
|
26
26
|
? 'Uploading this workspace to cloud for the first time.'
|
|
27
27
|
: 'Preparing the first upload to cloud.',
|
|
28
|
-
recommendedAction: 'Keep this window open while the first upload finishes.
|
|
28
|
+
recommendedAction: 'Keep this window open while the first upload finishes.'
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
if (phase === 'attach-cloud') {
|
|
@@ -71,14 +71,14 @@ export function resolveWorkspaceSyncPresentation({ enabled, phase, busy, retryAt
|
|
|
71
71
|
return {
|
|
72
72
|
status: 'attention',
|
|
73
73
|
summary: 'Sync hit a temporary problem and will retry automatically.',
|
|
74
|
-
recommendedAction: 'Wait for the automatic retry
|
|
74
|
+
recommendedAction: 'Wait for the automatic retry.'
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
if (lastErrorMessage || phase === 'error') {
|
|
78
78
|
return {
|
|
79
79
|
status: 'attention',
|
|
80
80
|
summary: 'Sync needs attention before it can continue.',
|
|
81
|
-
recommendedAction: '
|
|
81
|
+
recommendedAction: 'Keep sync enabled. If the same error keeps returning, press Repair.'
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
84
|
if (pendingChanges > 0 || (durableOutbox?.pending || 0) > 0 || (durableOutbox?.inFlight || 0) > 0) {
|
|
@@ -104,14 +104,14 @@ export function resolveWorkspaceSyncPresentation({ enabled, phase, busy, retryAt
|
|
|
104
104
|
summary: lastPushMs === null
|
|
105
105
|
? 'This device has not completed its first cloud pull.'
|
|
106
106
|
: 'Cloud uploads are working, but this device has not completed a cloud pull.',
|
|
107
|
-
recommendedAction: '
|
|
107
|
+
recommendedAction: 'Keep sync enabled. If the cloud check still does not complete, press Repair and copy the report.'
|
|
108
108
|
};
|
|
109
109
|
}
|
|
110
110
|
if (lastErrorMs !== null && lastErrorMs > lastPullMs) {
|
|
111
111
|
return {
|
|
112
112
|
status: 'attention',
|
|
113
113
|
summary: 'A sync issue occurred after the last successful cloud pull.',
|
|
114
|
-
recommendedAction: '
|
|
114
|
+
recommendedAction: 'Wait for the automatic retry. If the issue returns, copy the report.'
|
|
115
115
|
};
|
|
116
116
|
}
|
|
117
117
|
const pullIsStale = Number.isFinite(nowMs)
|
|
@@ -122,7 +122,7 @@ export function resolveWorkspaceSyncPresentation({ enabled, phase, busy, retryAt
|
|
|
122
122
|
summary: lastPushMs !== null && lastPushMs > lastPullMs
|
|
123
123
|
? 'Cloud uploads are succeeding, but this device has not received cloud changes recently.'
|
|
124
124
|
: 'This device has not checked for cloud changes recently.',
|
|
125
|
-
recommendedAction: '
|
|
125
|
+
recommendedAction: 'Keep sync enabled. If Last cloud check does not advance, press Repair and copy the report.'
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
128
|
return {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WorkspaceSyncChange, WorkspaceSyncDurableTaskRevision, WorkspaceSyncTaskSnapshot } from '../workspaceSyncModel.js';
|
|
2
|
+
import type { WorkspaceSyncV2ProjectionExclusion } from '../v3/workspaceSyncV2ProjectionExclusions.js';
|
|
2
3
|
export declare const WORKSPACE_SYNC_ENGINE_V2_PUSH_BOUNDARY_VERSION: 1;
|
|
3
4
|
/**
|
|
4
5
|
* Stable attempt-wide boundary shared by every V2 push batch. Individual
|
|
@@ -18,3 +19,16 @@ export interface WorkspaceSyncEngineAppliedTaskUpsert {
|
|
|
18
19
|
}
|
|
19
20
|
export declare function workspaceSyncEngineExpectedTaskEchoIds(changes: readonly WorkspaceSyncChange[]): string[];
|
|
20
21
|
export declare function parseWorkspaceSyncEngineAppliedTaskUpserts(value: unknown, expectedTaskIds: readonly string[]): WorkspaceSyncEngineAppliedTaskUpsert[];
|
|
22
|
+
export declare function createWorkspaceSyncEngineV2SettlementIdentityProjection(input: {
|
|
23
|
+
operationIdentity: string;
|
|
24
|
+
changes: readonly WorkspaceSyncChange[];
|
|
25
|
+
appliedTaskUpserts: readonly WorkspaceSyncEngineAppliedTaskUpsert[];
|
|
26
|
+
excludedProjections?: readonly WorkspaceSyncV2ProjectionExclusion[];
|
|
27
|
+
}): {
|
|
28
|
+
version: 1;
|
|
29
|
+
operationIdentity: string;
|
|
30
|
+
taskUpserts: Array<{
|
|
31
|
+
archived: boolean;
|
|
32
|
+
task: Record<string, unknown>;
|
|
33
|
+
}>;
|
|
34
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { canonicalWorkspaceSyncJson } from '../v3/canonicalWorkspaceSyncJson.js';
|
|
1
2
|
export const WORKSPACE_SYNC_ENGINE_V2_PUSH_BOUNDARY_VERSION = 1;
|
|
2
3
|
export function createWorkspaceSyncEngineV2PushBoundary(batchOperationIdentities) {
|
|
3
4
|
if (!Array.isArray(batchOperationIdentities)
|
|
@@ -85,3 +86,86 @@ export function parseWorkspaceSyncEngineAppliedTaskUpserts(value, expectedTaskId
|
|
|
85
86
|
}
|
|
86
87
|
return normalized;
|
|
87
88
|
}
|
|
89
|
+
function taskSettlementProjection(task, preserveReferenceNumber) {
|
|
90
|
+
const { updatedAt: _updatedAt, ...stableTask } = structuredClone(task);
|
|
91
|
+
if (!preserveReferenceNumber)
|
|
92
|
+
delete stableTask.referenceNumber;
|
|
93
|
+
return stableTask;
|
|
94
|
+
}
|
|
95
|
+
function taskSettlementOwnedProjection(input) {
|
|
96
|
+
// The cloud echo is authoritative for the complete task row, but this V2
|
|
97
|
+
// page may own only carrier fields. Validate exactly that remaining V2
|
|
98
|
+
// surface; V3-owned fields are checked by their own acknowledgement/feed.
|
|
99
|
+
const task = taskSettlementProjection(input.task, input.preserveReferenceNumber);
|
|
100
|
+
const rootOwnedByV3 = input.excludedProjections.has('task/root-v1');
|
|
101
|
+
const commentsOwnedByV3 = input.excludedProjections.has('task-comments/full-v1');
|
|
102
|
+
const checklistOwnedByV3 = input.excludedProjections.has('task-checklist/full-v1');
|
|
103
|
+
const attachmentLinksV1OwnedByV3 = input.excludedProjections
|
|
104
|
+
.has('task-attachment-links/full-v1');
|
|
105
|
+
const attachmentLinksV2OwnedByV3 = input.excludedProjections
|
|
106
|
+
.has('task-attachment-links/full-v2');
|
|
107
|
+
if (rootOwnedByV3) {
|
|
108
|
+
for (const key of Object.keys(task)) {
|
|
109
|
+
if (![
|
|
110
|
+
'id',
|
|
111
|
+
'comments',
|
|
112
|
+
'checklistItems',
|
|
113
|
+
'attachments',
|
|
114
|
+
'cardCoverAssetId',
|
|
115
|
+
].includes(key)) {
|
|
116
|
+
delete task[key];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (commentsOwnedByV3)
|
|
121
|
+
delete task.comments;
|
|
122
|
+
if (checklistOwnedByV3)
|
|
123
|
+
delete task.checklistItems;
|
|
124
|
+
if (attachmentLinksV1OwnedByV3 || attachmentLinksV2OwnedByV3) {
|
|
125
|
+
delete task.attachments;
|
|
126
|
+
}
|
|
127
|
+
if (attachmentLinksV2OwnedByV3)
|
|
128
|
+
delete task.cardCoverAssetId;
|
|
129
|
+
return {
|
|
130
|
+
...(rootOwnedByV3 ? {} : { archived: input.archived }),
|
|
131
|
+
task,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
export function createWorkspaceSyncEngineV2SettlementIdentityProjection(input) {
|
|
135
|
+
const operationIdentity = String(input.operationIdentity || '').trim();
|
|
136
|
+
if (!operationIdentity || operationIdentity !== input.operationIdentity) {
|
|
137
|
+
throw new TypeError('The V2 push settlement operation identity is invalid.');
|
|
138
|
+
}
|
|
139
|
+
const expectedTaskUpserts = input.changes.filter((change) => change.op === 'upsert');
|
|
140
|
+
if (expectedTaskUpserts.length !== input.appliedTaskUpserts.length) {
|
|
141
|
+
throw new TypeError('The V2 push authoritative settlement projection is incomplete.');
|
|
142
|
+
}
|
|
143
|
+
const expectedProjection = expectedTaskUpserts.map((change) => ({
|
|
144
|
+
archived: change.archived,
|
|
145
|
+
task: taskSettlementProjection(change.task, change.task.referenceNumber !== undefined && change.task.referenceNumber !== null),
|
|
146
|
+
}));
|
|
147
|
+
const excludedProjections = new Set(input.excludedProjections || []);
|
|
148
|
+
const expectedOwnedProjection = expectedTaskUpserts.map((change) => (taskSettlementOwnedProjection({
|
|
149
|
+
archived: change.archived,
|
|
150
|
+
task: change.task,
|
|
151
|
+
preserveReferenceNumber: change.task.referenceNumber !== undefined
|
|
152
|
+
&& change.task.referenceNumber !== null,
|
|
153
|
+
excludedProjections,
|
|
154
|
+
})));
|
|
155
|
+
const authoritativeOwnedProjection = input.appliedTaskUpserts.map((entry, index) => (taskSettlementOwnedProjection({
|
|
156
|
+
archived: entry.archived,
|
|
157
|
+
task: entry.task,
|
|
158
|
+
preserveReferenceNumber: expectedTaskUpserts[index]?.task.referenceNumber !== undefined
|
|
159
|
+
&& expectedTaskUpserts[index]?.task.referenceNumber !== null,
|
|
160
|
+
excludedProjections,
|
|
161
|
+
})));
|
|
162
|
+
if (canonicalWorkspaceSyncJson(authoritativeOwnedProjection)
|
|
163
|
+
!== canonicalWorkspaceSyncJson(expectedOwnedProjection)) {
|
|
164
|
+
throw new TypeError('The V2 push authoritative settlement does not match the canonical request state.');
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
version: 1,
|
|
168
|
+
operationIdentity,
|
|
169
|
+
taskUpserts: expectedProjection,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
@@ -10,6 +10,7 @@ function resetWorkspaceSyncStatePushBaselines(runtime) {
|
|
|
10
10
|
runtime.lastPushedInitiativeWatermarks.current = new Map();
|
|
11
11
|
runtime.lastPushedWorkstreamIds.current = new Set();
|
|
12
12
|
runtime.lastPushedWorkstreamWatermarks.current = new Map();
|
|
13
|
+
runtime.lastPushedPlanningIdentityWatermarks.current = new Map();
|
|
13
14
|
runtime.lastPushedAiProfileIds.current = new Set();
|
|
14
15
|
runtime.lastPushedAiProfileWatermarks.current = new Map();
|
|
15
16
|
runtime.lastPushedAiProfileChangeKeys.current = new Map();
|
|
@@ -26,6 +26,7 @@ export interface WorkspaceSyncEngineRuntime {
|
|
|
26
26
|
lastPushedInitiativeWatermarks: WorkspaceSyncMutableValue<Map<string, string>>;
|
|
27
27
|
lastPushedWorkstreamIds: WorkspaceSyncMutableValue<Set<string>>;
|
|
28
28
|
lastPushedWorkstreamWatermarks: WorkspaceSyncMutableValue<Map<string, string>>;
|
|
29
|
+
lastPushedPlanningIdentityWatermarks: WorkspaceSyncMutableValue<Map<string, string>>;
|
|
29
30
|
lastPushedAiProfileIds: WorkspaceSyncMutableValue<Set<string>>;
|
|
30
31
|
lastPushedAiProfileWatermarks: WorkspaceSyncMutableValue<Map<string, string>>;
|
|
31
32
|
lastPushedAiProfileChangeKeys: WorkspaceSyncMutableValue<Map<string, string>>;
|
|
@@ -24,6 +24,7 @@ export function createWorkspaceSyncEngineRuntime() {
|
|
|
24
24
|
lastPushedInitiativeWatermarks: mutable(new Map()),
|
|
25
25
|
lastPushedWorkstreamIds: mutable(new Set()),
|
|
26
26
|
lastPushedWorkstreamWatermarks: mutable(new Map()),
|
|
27
|
+
lastPushedPlanningIdentityWatermarks: mutable(new Map()),
|
|
27
28
|
lastPushedAiProfileIds: mutable(new Set()),
|
|
28
29
|
lastPushedAiProfileWatermarks: mutable(new Map()),
|
|
29
30
|
lastPushedAiProfileChangeKeys: mutable(new Map()),
|