@taskforcehq/taskforce 0.3.329 → 0.3.330
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Taskforce.module.css +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/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/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 +27 -26
- 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 +48 -1
- package/dist/core/McpTokenService.d.ts +23 -1
- package/dist/core/McpTokenService.js +93 -10
- 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 +32 -0
- package/dist/core/Taskforce.js +125 -4
- package/dist/core/types.d.ts +8 -0
- 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 +10 -0
- package/dist/mcp/httpProtocolRouting.js +19 -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 +384 -97
- package/dist/mcp/taskPlanningRegistrar.js +23 -4
- package/dist/mcp/toolProfiles.d.ts +2 -0
- package/dist/mcp/toolProfiles.js +10 -0
- package/dist/mcp/toolRegistry.d.ts +1 -0
- package/dist/mcp/toolRegistry.js +1 -0
- 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/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 +12 -14
- package/dist/server/routes/admin.d.ts +4 -0
- package/dist/server/routes/admin.js +112 -3
- 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 +19 -0
- package/dist/server/routes/shared.js +95 -19
- 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/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 +126 -0
- package/dist/services/executorPhaseAIssuerCore.js +295 -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 +1 -1
- package/dist/services/taskforceAgentMcpBridge.js +7 -24
- 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 +11 -0
- package/dist/storage/postgresWorker.js +9 -1
- package/dist/storage/postgresWorkerProtocol.d.ts +1 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -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/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 +29 -0
- package/dist/sync/syncApplyHandlers.d.ts +2 -0
- package/dist/sync/syncApplyHandlers.js +10 -1
- 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 +11 -0
- package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +39 -10
- 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/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/localTaskStatusOutboxService.d.ts +8 -0
- package/dist/sync/v3/localTaskStatusOutboxService.js +219 -12
- package/dist/sync/v3/syncDurabilityStore.d.ts +34 -0
- package/dist/sync/v3/syncDurabilityStore.js +168 -2
- 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/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/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/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/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-OcSz1PkK.js +1 -0
- package/dist/ui/assets/AiProfilesModule-ByhYW5Xi.js +1 -0
- package/dist/ui/assets/{AnnotatedAttachmentWorkspace-B68Wg-RV.js → AnnotatedAttachmentWorkspace-BTM6nIg_.js} +1 -1
- package/dist/ui/assets/{AssetTraySortControl-C8Rztyal.js → AssetTraySortControl-DabEG8L4.js} +1 -1
- package/dist/ui/assets/{ContextAttachmentManager-Cj3c7X9y.js → ContextAttachmentManager-Coa8yVGM.js} +1 -1
- package/dist/ui/assets/{DocumentWorkspace-B5uvzems.js → DocumentWorkspace-BB0qhdix.js} +1 -1
- package/dist/ui/assets/{EntityActivityTimeline-BVFvCB5R.js → EntityActivityTimeline-CZ8x4UJE.js} +1 -1
- package/dist/ui/assets/{PlanningModule-B5DWQOGz.js → PlanningModule-pRPjR7v5.js} +1 -1
- package/dist/ui/assets/{PlansPage-AY4cGWco.js → PlansPage-D86pZSSl.js} +1 -1
- package/dist/ui/assets/{TaskContextUpload-DZxTVesW.js → TaskContextUpload-BVIkU9yT.js} +1 -1
- package/dist/ui/assets/TaskSettings-Cv1mNhv_.js +12 -0
- package/dist/ui/assets/TaskforceAgentsModule-b-8R25cJ.css +1 -0
- package/dist/ui/assets/TaskforceAgentsModule-gmH-PD2q.js +24 -0
- package/dist/ui/assets/{WorkflowManagerModule-DEr5di_r.js → WorkflowManagerModule-DbfnHJ-f.js} +1 -1
- package/dist/ui/assets/index-BZ-hdZSk.css +1 -0
- package/dist/ui/assets/index-CTsDBaef.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 +22 -4
- package/dist/ui/assets/AiIdentityRosterCard-BZM4aQnM.js +0 -1
- package/dist/ui/assets/AiProfilesModule-BbAEWtHH.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
|
@@ -180,6 +180,7 @@ export function buildPersistedSyncWatermarksSnapshot(data) {
|
|
|
180
180
|
taskRelationshipChangeKeys: Array.from((data.taskRelationshipChangeKeys || new Map()).entries()),
|
|
181
181
|
initiativeWatermarks: Array.from(data.initiativeWatermarks.entries()),
|
|
182
182
|
workstreamWatermarks: Array.from(data.workstreamWatermarks.entries()),
|
|
183
|
+
planningIdentityWatermarks: Array.from((data.planningIdentityWatermarks || new Map()).entries()),
|
|
183
184
|
aiProfileWatermarks: Array.from(data.aiProfileWatermarks.entries()),
|
|
184
185
|
aiProfileChangeKeys: Array.from((data.aiProfileChangeKeys || new Map()).entries()),
|
|
185
186
|
taskforceAgentWatermarks: Array.from((data.taskforceAgentWatermarks || new Map()).entries()),
|
|
@@ -214,6 +215,7 @@ export function parsePersistedSyncWatermarksSnapshot(snapshot, taxonomyStateFing
|
|
|
214
215
|
taskRelationshipChangeKeys: new Map(Array.isArray(snapshot.taskRelationshipChangeKeys) ? snapshot.taskRelationshipChangeKeys : []),
|
|
215
216
|
initiativeWatermarks: new Map(Array.isArray(snapshot.initiativeWatermarks) ? snapshot.initiativeWatermarks : []),
|
|
216
217
|
workstreamWatermarks: new Map(Array.isArray(snapshot.workstreamWatermarks) ? snapshot.workstreamWatermarks : []),
|
|
218
|
+
planningIdentityWatermarks: new Map(Array.isArray(snapshot.planningIdentityWatermarks) ? snapshot.planningIdentityWatermarks : []),
|
|
217
219
|
aiProfileWatermarks: new Map(Array.isArray(snapshot.aiProfileWatermarks) ? snapshot.aiProfileWatermarks : []),
|
|
218
220
|
aiProfileChangeKeys: new Map(Array.isArray(snapshot.aiProfileChangeKeys) ? snapshot.aiProfileChangeKeys : []),
|
|
219
221
|
taskforceAgentWatermarks: new Map(Array.isArray(snapshot.taskforceAgentWatermarks) ? snapshot.taskforceAgentWatermarks : []),
|
|
@@ -12,9 +12,12 @@ export declare function useLocalSyncCoordinatorSnapshot(input: {
|
|
|
12
12
|
pollIntervalMs?: number;
|
|
13
13
|
client?: LocalSyncCoordinatorBrowserClient;
|
|
14
14
|
}): {
|
|
15
|
+
activeCommandType: LocalSyncCoordinatorCommandType | null;
|
|
16
|
+
activePriorityCommandType: LocalSyncCoordinatorCommandType | null;
|
|
15
17
|
refresh: () => Promise<LocalSyncCoordinatorStatusResponse | null>;
|
|
16
18
|
issueCommand: (type: Exclude<LocalSyncCoordinatorCommandType, "SwitchWorkspace" | "TransferOwnership">, args?: unknown) => Promise<LocalSyncCoordinatorCommandRecord>;
|
|
17
19
|
signalWake: (source: "realtime" | "connectivity", eventIds?: string[]) => Promise<boolean>;
|
|
20
|
+
clearCredential: () => Promise<boolean>;
|
|
18
21
|
switchWorkspace: (targetWorkspaceId: string) => Promise<LocalSyncCoordinatorStatusResponse["state"]>;
|
|
19
22
|
transferOwnership: (targetMode: "server" | "browser-gateway") => Promise<LocalSyncCoordinatorStatusResponse["state"]>;
|
|
20
23
|
phase: LocalSyncCoordinatorSnapshotPhase;
|
|
@@ -15,8 +15,14 @@ export function useLocalSyncCoordinatorSnapshot(input) {
|
|
|
15
15
|
const requestEpochRef = useRef(0);
|
|
16
16
|
const commandLifecycleRef = useRef(null);
|
|
17
17
|
const priorityCommandLifecycleRef = useRef(null);
|
|
18
|
+
const [activeCommandType, setActiveCommandType] = useState(null);
|
|
19
|
+
const [activePriorityCommandType, setActivePriorityCommandType] = useState(null);
|
|
18
20
|
const snapshotRef = useRef(null);
|
|
19
21
|
snapshotRef.current = state.snapshot;
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
setActiveCommandType(null);
|
|
24
|
+
setActivePriorityCommandType(null);
|
|
25
|
+
}, [input.workspaceId]);
|
|
20
26
|
const resumePendingCommand = useCallback((scope) => {
|
|
21
27
|
const existing = commandLifecycleRef.current;
|
|
22
28
|
if (existing?.workspaceId === input.workspaceId)
|
|
@@ -36,14 +42,17 @@ export function useLocalSyncCoordinatorSnapshot(input) {
|
|
|
36
42
|
const lifecycle = {
|
|
37
43
|
workspaceId: input.workspaceId,
|
|
38
44
|
scope,
|
|
45
|
+
type: pending.type,
|
|
39
46
|
promise,
|
|
40
47
|
};
|
|
41
48
|
commandLifecycleRef.current = lifecycle;
|
|
49
|
+
setActiveCommandType(pending.type);
|
|
42
50
|
void promise
|
|
43
51
|
.catch(() => { })
|
|
44
52
|
.finally(() => {
|
|
45
53
|
if (commandLifecycleRef.current === lifecycle) {
|
|
46
54
|
commandLifecycleRef.current = null;
|
|
55
|
+
setActiveCommandType(null);
|
|
47
56
|
}
|
|
48
57
|
});
|
|
49
58
|
return promise;
|
|
@@ -68,14 +77,17 @@ export function useLocalSyncCoordinatorSnapshot(input) {
|
|
|
68
77
|
const lifecycle = {
|
|
69
78
|
workspaceId: input.workspaceId,
|
|
70
79
|
scope,
|
|
80
|
+
type: pending.type,
|
|
71
81
|
promise,
|
|
72
82
|
};
|
|
73
83
|
priorityCommandLifecycleRef.current = lifecycle;
|
|
84
|
+
setActivePriorityCommandType(pending.type);
|
|
74
85
|
void promise
|
|
75
86
|
.catch(() => { })
|
|
76
87
|
.finally(() => {
|
|
77
88
|
if (priorityCommandLifecycleRef.current === lifecycle) {
|
|
78
89
|
priorityCommandLifecycleRef.current = null;
|
|
90
|
+
setActivePriorityCommandType(null);
|
|
79
91
|
}
|
|
80
92
|
});
|
|
81
93
|
return promise;
|
|
@@ -250,7 +262,7 @@ export function useLocalSyncCoordinatorSnapshot(input) {
|
|
|
250
262
|
refresh,
|
|
251
263
|
]);
|
|
252
264
|
const issueCommand = useCallback(async (type, args = null) => {
|
|
253
|
-
|
|
265
|
+
let snapshot = snapshotRef.current;
|
|
254
266
|
if (!snapshot) {
|
|
255
267
|
throw new LocalSyncCoordinatorBrowserClientError('The local sync coordinator is not attached.', 'SYNC_COORDINATOR_UNAVAILABLE', 409);
|
|
256
268
|
}
|
|
@@ -258,21 +270,54 @@ export function useLocalSyncCoordinatorSnapshot(input) {
|
|
|
258
270
|
if (priorityCommand) {
|
|
259
271
|
const activePriority = priorityCommandLifecycleRef.current;
|
|
260
272
|
if (activePriority?.workspaceId === input.workspaceId) {
|
|
261
|
-
|
|
273
|
+
if (activePriority.type === type)
|
|
274
|
+
return activePriority.promise;
|
|
275
|
+
await activePriority.promise;
|
|
262
276
|
}
|
|
263
277
|
const resumedPriority = resumePendingPriorityCommand(scopeRef.current);
|
|
264
|
-
if (resumedPriority)
|
|
265
|
-
|
|
278
|
+
if (resumedPriority) {
|
|
279
|
+
const resumedType = priorityCommandLifecycleRef.current?.type;
|
|
280
|
+
if (resumedType === type)
|
|
281
|
+
return resumedPriority;
|
|
282
|
+
await resumedPriority;
|
|
283
|
+
}
|
|
266
284
|
}
|
|
267
285
|
const active = commandLifecycleRef.current;
|
|
268
|
-
if (
|
|
269
|
-
|
|
286
|
+
if (active?.workspaceId === input.workspaceId) {
|
|
287
|
+
if (active.type === type)
|
|
288
|
+
return active.promise;
|
|
289
|
+
const activeIsToggle = active.type === 'EnableSync' || active.type === 'DisableSync';
|
|
290
|
+
if (!priorityCommand || activeIsToggle)
|
|
291
|
+
await active.promise;
|
|
270
292
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
293
|
+
const resumed = resumePendingCommand(scopeRef.current);
|
|
294
|
+
if (resumed) {
|
|
295
|
+
const resumedType = commandLifecycleRef.current?.type;
|
|
296
|
+
if (resumedType === type)
|
|
297
|
+
return resumed;
|
|
298
|
+
const resumedIsToggle = resumedType === 'EnableSync' || resumedType === 'DisableSync';
|
|
299
|
+
if (!priorityCommand || resumedIsToggle)
|
|
274
300
|
await resumed;
|
|
275
301
|
}
|
|
302
|
+
if (!priorityCommand) {
|
|
303
|
+
const activePriority = priorityCommandLifecycleRef.current;
|
|
304
|
+
if (activePriority?.workspaceId === input.workspaceId) {
|
|
305
|
+
if (activePriority.type === type)
|
|
306
|
+
return activePriority.promise;
|
|
307
|
+
await activePriority.promise;
|
|
308
|
+
}
|
|
309
|
+
const resumedPriority = resumePendingPriorityCommand(scopeRef.current);
|
|
310
|
+
if (resumedPriority) {
|
|
311
|
+
const resumedType = priorityCommandLifecycleRef.current?.type;
|
|
312
|
+
if (resumedType === type)
|
|
313
|
+
return resumedPriority;
|
|
314
|
+
await resumedPriority;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
snapshot = snapshotRef.current;
|
|
318
|
+
if (!snapshot) {
|
|
319
|
+
throw new LocalSyncCoordinatorBrowserClientError('The local sync coordinator is not attached.', 'SYNC_COORDINATOR_UNAVAILABLE', 409);
|
|
320
|
+
}
|
|
276
321
|
const envelope = {
|
|
277
322
|
commandId: crypto.randomUUID(),
|
|
278
323
|
workspaceId: input.workspaceId,
|
|
@@ -290,15 +335,28 @@ export function useLocalSyncCoordinatorSnapshot(input) {
|
|
|
290
335
|
const lifecycle = {
|
|
291
336
|
workspaceId: input.workspaceId,
|
|
292
337
|
scope: scopeRef.current,
|
|
338
|
+
type,
|
|
293
339
|
promise: commandPromise,
|
|
294
340
|
};
|
|
295
341
|
const lifecycleRef = priorityCommand
|
|
296
342
|
? priorityCommandLifecycleRef
|
|
297
343
|
: commandLifecycleRef;
|
|
298
344
|
lifecycleRef.current = lifecycle;
|
|
345
|
+
if (priorityCommand) {
|
|
346
|
+
setActivePriorityCommandType(type);
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
setActiveCommandType(type);
|
|
350
|
+
}
|
|
299
351
|
const finalize = () => {
|
|
300
352
|
if (lifecycleRef.current === lifecycle) {
|
|
301
353
|
lifecycleRef.current = null;
|
|
354
|
+
if (priorityCommand) {
|
|
355
|
+
setActivePriorityCommandType(null);
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
setActiveCommandType(null);
|
|
359
|
+
}
|
|
302
360
|
}
|
|
303
361
|
if (scopeRef.current === lifecycle.scope
|
|
304
362
|
&& input.workspaceId === lifecycle.workspaceId) {
|
|
@@ -326,6 +384,18 @@ export function useLocalSyncCoordinatorSnapshot(input) {
|
|
|
326
384
|
});
|
|
327
385
|
return true;
|
|
328
386
|
}, [client, input.workspaceId]);
|
|
387
|
+
const clearCredential = useCallback(async () => {
|
|
388
|
+
const snapshot = snapshotRef.current;
|
|
389
|
+
if (!snapshot || !input.workspaceId)
|
|
390
|
+
return false;
|
|
391
|
+
await client.clearCredential({
|
|
392
|
+
workspaceId: input.workspaceId,
|
|
393
|
+
coordinatorGeneration: snapshot.state.coordinatorGeneration,
|
|
394
|
+
});
|
|
395
|
+
snapshotRef.current = null;
|
|
396
|
+
setState({ phase: 'idle', snapshot: null, error: null });
|
|
397
|
+
return true;
|
|
398
|
+
}, [client, input.workspaceId]);
|
|
329
399
|
const switchWorkspace = useCallback(async (targetWorkspaceId) => {
|
|
330
400
|
const snapshot = snapshotRef.current;
|
|
331
401
|
const expectedActiveWorkspaceId = String(snapshot?.state.activeWorkspaceId || '').trim();
|
|
@@ -381,12 +451,18 @@ export function useLocalSyncCoordinatorSnapshot(input) {
|
|
|
381
451
|
}, [client, input.workspaceId, refresh]);
|
|
382
452
|
return useMemo(() => ({
|
|
383
453
|
...state,
|
|
454
|
+
activeCommandType,
|
|
455
|
+
activePriorityCommandType,
|
|
384
456
|
refresh,
|
|
385
457
|
issueCommand,
|
|
386
458
|
signalWake,
|
|
459
|
+
clearCredential,
|
|
387
460
|
switchWorkspace,
|
|
388
461
|
transferOwnership,
|
|
389
462
|
}), [
|
|
463
|
+
activeCommandType,
|
|
464
|
+
activePriorityCommandType,
|
|
465
|
+
clearCredential,
|
|
390
466
|
issueCommand,
|
|
391
467
|
refresh,
|
|
392
468
|
signalWake,
|
|
@@ -5,21 +5,24 @@ interface SaveWorkspaceCloudSyncSettingsResult {
|
|
|
5
5
|
interface UseSyncStatusControlsInput {
|
|
6
6
|
canManageWorkspaceSync: boolean;
|
|
7
7
|
workspaceCloudSyncEnabled: boolean;
|
|
8
|
+
persistedToggleIntent?: WorkspaceSyncToggleIntent;
|
|
8
9
|
saveWorkspaceCloudSyncSettings: (input: {
|
|
9
10
|
enabled: boolean;
|
|
10
11
|
}) => Promise<SaveWorkspaceCloudSyncSettingsResult>;
|
|
11
12
|
}
|
|
13
|
+
export type WorkspaceSyncToggleIntent = 'enabling' | 'disabling' | null;
|
|
12
14
|
interface UseSyncStatusControlsResult {
|
|
13
15
|
showSyncStatusModal: boolean;
|
|
14
16
|
showSyncEnableWarning: boolean;
|
|
15
17
|
workspaceSyncToggleBusy: boolean;
|
|
16
18
|
workspaceSyncError: string | null;
|
|
17
19
|
syncControlBusy: boolean;
|
|
20
|
+
syncControlIntent: WorkspaceSyncToggleIntent;
|
|
18
21
|
openSyncStatusModal: () => void;
|
|
19
22
|
closeSyncStatusModal: () => void;
|
|
20
23
|
handleWorkspaceSyncToggle: (enabled: boolean) => Promise<void>;
|
|
21
24
|
cancelSyncEnableWarning: () => void;
|
|
22
25
|
confirmSyncEnableWarning: () => void;
|
|
23
26
|
}
|
|
24
|
-
export declare function useSyncStatusControls({ canManageWorkspaceSync, workspaceCloudSyncEnabled, saveWorkspaceCloudSyncSettings, }: UseSyncStatusControlsInput): UseSyncStatusControlsResult;
|
|
27
|
+
export declare function useSyncStatusControls({ canManageWorkspaceSync, workspaceCloudSyncEnabled, persistedToggleIntent, saveWorkspaceCloudSyncSettings, }: UseSyncStatusControlsInput): UseSyncStatusControlsResult;
|
|
25
28
|
export {};
|
|
@@ -1,23 +1,58 @@
|
|
|
1
|
-
import { useCallback, useState } from 'react';
|
|
2
|
-
export function useSyncStatusControls({ canManageWorkspaceSync, workspaceCloudSyncEnabled, saveWorkspaceCloudSyncSettings, }) {
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
+
export function useSyncStatusControls({ canManageWorkspaceSync, workspaceCloudSyncEnabled, persistedToggleIntent = null, saveWorkspaceCloudSyncSettings, }) {
|
|
3
3
|
const [showSyncStatusModal, setShowSyncStatusModal] = useState(false);
|
|
4
4
|
const [showSyncEnableWarning, setShowSyncEnableWarning] = useState(false);
|
|
5
5
|
const [workspaceSyncToggleBusy, setWorkspaceSyncToggleBusy] = useState(false);
|
|
6
6
|
const [workspaceSyncError, setWorkspaceSyncError] = useState(null);
|
|
7
|
+
const [requestedSyncEnabled, setRequestedSyncEnabled] = useState(null);
|
|
8
|
+
const inFlightToggleRef = useRef(null);
|
|
9
|
+
const requestedToggleIntent = requestedSyncEnabled === null
|
|
10
|
+
? null
|
|
11
|
+
: requestedSyncEnabled ? 'enabling' : 'disabling';
|
|
12
|
+
const syncControlIntent = requestedToggleIntent || persistedToggleIntent;
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
if (requestedSyncEnabled !== null && requestedSyncEnabled === workspaceCloudSyncEnabled) {
|
|
15
|
+
setRequestedSyncEnabled(null);
|
|
16
|
+
}
|
|
17
|
+
}, [requestedSyncEnabled, workspaceCloudSyncEnabled]);
|
|
7
18
|
const persistWorkspaceSyncToggle = useCallback(async (enabled) => {
|
|
8
19
|
if (!canManageWorkspaceSync)
|
|
9
20
|
return;
|
|
10
21
|
setWorkspaceSyncError(null);
|
|
22
|
+
setRequestedSyncEnabled(enabled);
|
|
11
23
|
setWorkspaceSyncToggleBusy(true);
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
if (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
finally {
|
|
19
|
-
setWorkspaceSyncToggleBusy(false);
|
|
24
|
+
while (inFlightToggleRef.current) {
|
|
25
|
+
const active = inFlightToggleRef.current;
|
|
26
|
+
if (active.enabled === enabled)
|
|
27
|
+
return active.promise;
|
|
28
|
+
await active.promise;
|
|
20
29
|
}
|
|
30
|
+
setRequestedSyncEnabled(enabled);
|
|
31
|
+
setWorkspaceSyncToggleBusy(true);
|
|
32
|
+
let commandPromise;
|
|
33
|
+
commandPromise = (async () => {
|
|
34
|
+
try {
|
|
35
|
+
const result = await saveWorkspaceCloudSyncSettings({ enabled });
|
|
36
|
+
if (!result.success) {
|
|
37
|
+
setRequestedSyncEnabled(null);
|
|
38
|
+
setWorkspaceSyncError(result.error || (enabled ? 'Failed to enable sync.' : 'Failed to disable sync.'));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
setRequestedSyncEnabled(null);
|
|
43
|
+
setWorkspaceSyncError(error instanceof Error && error.message.trim()
|
|
44
|
+
? error.message
|
|
45
|
+
: enabled ? 'Failed to enable sync.' : 'Failed to disable sync.');
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
if (inFlightToggleRef.current?.promise === commandPromise) {
|
|
49
|
+
inFlightToggleRef.current = null;
|
|
50
|
+
setWorkspaceSyncToggleBusy(false);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
})();
|
|
54
|
+
inFlightToggleRef.current = { enabled, promise: commandPromise };
|
|
55
|
+
return commandPromise;
|
|
21
56
|
}, [
|
|
22
57
|
canManageWorkspaceSync,
|
|
23
58
|
saveWorkspaceCloudSyncSettings
|
|
@@ -50,7 +85,8 @@ export function useSyncStatusControls({ canManageWorkspaceSync, workspaceCloudSy
|
|
|
50
85
|
showSyncEnableWarning,
|
|
51
86
|
workspaceSyncToggleBusy,
|
|
52
87
|
workspaceSyncError,
|
|
53
|
-
syncControlBusy: workspaceSyncToggleBusy,
|
|
88
|
+
syncControlBusy: workspaceSyncToggleBusy || syncControlIntent !== null,
|
|
89
|
+
syncControlIntent,
|
|
54
90
|
openSyncStatusModal,
|
|
55
91
|
closeSyncStatusModal,
|
|
56
92
|
handleWorkspaceSyncToggle,
|
|
@@ -79,9 +79,12 @@ export declare function useSyncOrchestrator(input: UseSyncOrchestratorInput): {
|
|
|
79
79
|
phase: import("./sync/useLocalSyncCoordinatorSnapshot.js").LocalSyncCoordinatorSnapshotPhase;
|
|
80
80
|
snapshot: import("../sync/coordinator/localSyncCoordinatorBrowserClient.js").LocalSyncCoordinatorStatusResponse | null;
|
|
81
81
|
errorMessage: string | null;
|
|
82
|
+
activeCommandType: import("../sync/coordinator/localSyncCoordinatorTypes").LocalSyncCoordinatorCommandType | null;
|
|
83
|
+
activePriorityCommandType: import("../sync/coordinator/localSyncCoordinatorTypes").LocalSyncCoordinatorCommandType | null;
|
|
82
84
|
} | null;
|
|
83
85
|
switchLocalCoordinatorWorkspace: (targetWorkspaceId: string) => Promise<boolean>;
|
|
84
86
|
transferLocalCoordinatorOwnership: (targetMode: "server" | "browser-gateway") => Promise<boolean>;
|
|
87
|
+
clearLocalCoordinatorCredential: () => Promise<boolean>;
|
|
85
88
|
syncInFlightRef: import("react").RefObject<boolean>;
|
|
86
89
|
workspaceRetryAt: string | null;
|
|
87
90
|
isWorkspaceRetryPending: () => boolean;
|
|
@@ -156,6 +156,29 @@ export function useSyncOrchestrator(input) {
|
|
|
156
156
|
const bootstrapPhaseStartedAtRef = useRef(null);
|
|
157
157
|
const bootstrapLastProgressAtRef = useRef(null);
|
|
158
158
|
const lastBootstrapPhaseRef = useRef('idle');
|
|
159
|
+
// Incremented every time the workspace-switch reset effect runs (including a
|
|
160
|
+
// switch back to the same workspace id). Reference-snapshot refreshes capture
|
|
161
|
+
// this value before their first await and refuse to commit a response whose
|
|
162
|
+
// generation has since moved on, so a stale/raced fetch can never overwrite a
|
|
163
|
+
// fresher (or freshly-reset) snapshot with data for the wrong workspace visit.
|
|
164
|
+
const workspaceSyncGenerationRef = useRef(0);
|
|
165
|
+
// Positive completeness signal for the document/asset snapshots, mirrored in a
|
|
166
|
+
// ref (not React state) so buildWorkspaceSyncPayload's ref-only read pattern
|
|
167
|
+
// can't observe a stale value from an earlier render's closure. Only ever set
|
|
168
|
+
// true immediately alongside a validated, non-stale successful refresh; reset
|
|
169
|
+
// to false whenever the workspace-switch effect invalidates the current
|
|
170
|
+
// generation. buildWorkspaceSyncPayloadModel refuses to compute any deletions
|
|
171
|
+
// for a domain while its completeness flag is false.
|
|
172
|
+
const workspaceSyncDocumentsSnapshotCompleteRef = useRef(false);
|
|
173
|
+
const workspaceSyncAssetsSnapshotCompleteRef = useRef(false);
|
|
174
|
+
// Per-domain monotonic request counters. Incremented at the start of every
|
|
175
|
+
// refresh call (independent of workspaceSyncGenerationRef, which only tracks
|
|
176
|
+
// workspace switches). Guards against two overlapping in-flight requests for
|
|
177
|
+
// the SAME workspace/generation — e.g. an interval tick firing while an
|
|
178
|
+
// event-triggered refresh is still in flight — where an older response could
|
|
179
|
+
// otherwise resolve after a newer one and overwrite fresher data.
|
|
180
|
+
const workspaceSyncDocumentsRequestSeqRef = useRef(0);
|
|
181
|
+
const workspaceSyncAssetsRequestSeqRef = useRef(0);
|
|
159
182
|
// === SECTION: User global settings sync ===
|
|
160
183
|
const clearUserSettingsRetry = useCallback(() => {
|
|
161
184
|
if (userSettingsRetryTimeoutRef.current !== null) {
|
|
@@ -256,6 +279,7 @@ export function useSyncOrchestrator(input) {
|
|
|
256
279
|
const workspaceLastPushedInitiativeWatermarksRef = useRef(new Map());
|
|
257
280
|
const workspaceLastPushedWorkstreamIdsRef = useRef(new Set());
|
|
258
281
|
const workspaceLastPushedWorkstreamWatermarksRef = useRef(new Map());
|
|
282
|
+
const workspaceLastPushedPlanningIdentityWatermarksRef = useRef(new Map());
|
|
259
283
|
const workspaceLastPushedAiProfileIdsRef = useRef(new Set());
|
|
260
284
|
const workspaceLastPushedAiProfileWatermarksRef = useRef(new Map());
|
|
261
285
|
const workspaceLastPushedAiProfileChangeKeysRef = useRef(new Map());
|
|
@@ -288,6 +312,7 @@ export function useSyncOrchestrator(input) {
|
|
|
288
312
|
workspaceLastPushedInitiativeWatermarksRef.current = persisted.initiativeWatermarks;
|
|
289
313
|
workspaceLastPushedWorkstreamIdsRef.current = new Set(Array.from(persisted.workstreamWatermarks.keys()));
|
|
290
314
|
workspaceLastPushedWorkstreamWatermarksRef.current = persisted.workstreamWatermarks;
|
|
315
|
+
workspaceLastPushedPlanningIdentityWatermarksRef.current = new Map(persisted.planningIdentityWatermarks || []);
|
|
291
316
|
workspaceLastPushedAiProfileIdsRef.current = new Set(Array.from(persisted.aiProfileWatermarks.keys()));
|
|
292
317
|
workspaceLastPushedAiProfileWatermarksRef.current = persisted.aiProfileWatermarks;
|
|
293
318
|
workspaceLastPushedAiProfileChangeKeysRef.current = persisted.aiProfileChangeKeys || new Map();
|
|
@@ -319,6 +344,7 @@ export function useSyncOrchestrator(input) {
|
|
|
319
344
|
taxonomyChangeKey: workspaceLastPushedTaxonomyChangeKeyRef.current,
|
|
320
345
|
initiativeWatermarks: workspaceLastPushedInitiativeWatermarksRef.current,
|
|
321
346
|
workstreamWatermarks: workspaceLastPushedWorkstreamWatermarksRef.current,
|
|
347
|
+
planningIdentityWatermarks: workspaceLastPushedPlanningIdentityWatermarksRef.current,
|
|
322
348
|
aiProfileWatermarks: workspaceLastPushedAiProfileWatermarksRef.current,
|
|
323
349
|
aiProfileChangeKeys: workspaceLastPushedAiProfileChangeKeysRef.current,
|
|
324
350
|
taskforceAgentWatermarks: workspaceLastPushedTaskforceAgentWatermarksRef.current,
|
|
@@ -604,6 +630,9 @@ export function useSyncOrchestrator(input) {
|
|
|
604
630
|
taxonomyStateFingerprint
|
|
605
631
|
]);
|
|
606
632
|
useEffect(() => {
|
|
633
|
+
workspaceSyncGenerationRef.current += 1;
|
|
634
|
+
workspaceSyncDocumentsSnapshotCompleteRef.current = false;
|
|
635
|
+
workspaceSyncAssetsSnapshotCompleteRef.current = false;
|
|
607
636
|
workspaceSyncMarkdownDocumentsFingerprintRef.current = '';
|
|
608
637
|
workspaceSyncAiProfilesFingerprintRef.current = '';
|
|
609
638
|
workspaceSyncAssetsFingerprintRef.current = '';
|
|
@@ -612,11 +641,15 @@ export function useSyncOrchestrator(input) {
|
|
|
612
641
|
workspaceSyncTaskforceAgentsFingerprintRef.current = '';
|
|
613
642
|
workspaceAttachBootstrapBaselineSignatureRef.current = '';
|
|
614
643
|
workspaceCaptureAttachBootstrapBaselineRef.current = false;
|
|
644
|
+
workspaceSyncMarkdownDocumentsRef.current = [];
|
|
645
|
+
workspaceSyncKnownDocumentPathsRef.current = new Set();
|
|
615
646
|
setWorkspaceSyncMarkdownDocuments([]);
|
|
616
647
|
setWorkspaceSyncMarkdownDocumentsFingerprint('');
|
|
617
648
|
workspaceSyncAiProfilesRef.current = [];
|
|
618
649
|
setWorkspaceSyncAiProfiles([]);
|
|
619
650
|
setWorkspaceSyncAiProfilesFingerprint('');
|
|
651
|
+
workspaceSyncAssetsRef.current = [];
|
|
652
|
+
workspaceSyncKnownAssetPathsRef.current = new Set();
|
|
620
653
|
setWorkspaceSyncAssets([]);
|
|
621
654
|
setWorkspaceSyncAssetsFingerprint('');
|
|
622
655
|
workspaceSyncDocumentReviewSessionsRef.current = [];
|
|
@@ -648,6 +681,7 @@ export function useSyncOrchestrator(input) {
|
|
|
648
681
|
workspaceLastPushedInitiativeWatermarksRef.current = new Map();
|
|
649
682
|
workspaceLastPushedWorkstreamIdsRef.current = new Set();
|
|
650
683
|
workspaceLastPushedWorkstreamWatermarksRef.current = new Map();
|
|
684
|
+
workspaceLastPushedPlanningIdentityWatermarksRef.current = new Map();
|
|
651
685
|
workspaceLastPushedAiProfileIdsRef.current = new Set();
|
|
652
686
|
workspaceLastPushedAiProfileWatermarksRef.current = new Map();
|
|
653
687
|
workspaceLastPushedAiProfileChangeKeysRef.current = new Map();
|
|
@@ -806,6 +840,7 @@ export function useSyncOrchestrator(input) {
|
|
|
806
840
|
lastPushedInitiativeWatermarks: workspaceLastPushedInitiativeWatermarksRef,
|
|
807
841
|
lastPushedWorkstreamIds: workspaceLastPushedWorkstreamIdsRef,
|
|
808
842
|
lastPushedWorkstreamWatermarks: workspaceLastPushedWorkstreamWatermarksRef,
|
|
843
|
+
lastPushedPlanningIdentityWatermarks: workspaceLastPushedPlanningIdentityWatermarksRef,
|
|
809
844
|
lastPushedAiProfileIds: workspaceLastPushedAiProfileIdsRef,
|
|
810
845
|
lastPushedAiProfileWatermarks: workspaceLastPushedAiProfileWatermarksRef,
|
|
811
846
|
lastPushedAiProfileChangeKeys: workspaceLastPushedAiProfileChangeKeysRef,
|
|
@@ -937,6 +972,8 @@ export function useSyncOrchestrator(input) {
|
|
|
937
972
|
assets: workspaceSyncAssetsRef.current,
|
|
938
973
|
currentDocumentPaths: workspaceSyncKnownDocumentPathsRef.current,
|
|
939
974
|
currentAssetPaths: workspaceSyncKnownAssetPathsRef.current,
|
|
975
|
+
documentsSnapshotComplete: workspaceSyncDocumentsSnapshotCompleteRef.current,
|
|
976
|
+
assetsSnapshotComplete: workspaceSyncAssetsSnapshotCompleteRef.current,
|
|
940
977
|
documentReviewSessions: workspaceSyncDocumentReviewSessionsRef.current,
|
|
941
978
|
documentReviewComments: workspaceSyncDocumentReviewCommentsRef.current,
|
|
942
979
|
annotatedAttachmentSessions: workspaceSyncAnnotatedAttachmentSessionsRef.current,
|
|
@@ -961,6 +998,7 @@ export function useSyncOrchestrator(input) {
|
|
|
961
998
|
lastPushedInitiativeWatermarks: workspaceLastPushedInitiativeWatermarksRef.current,
|
|
962
999
|
lastPushedWorkstreamIds: workspaceLastPushedWorkstreamIdsRef.current,
|
|
963
1000
|
lastPushedWorkstreamWatermarks: workspaceLastPushedWorkstreamWatermarksRef.current,
|
|
1001
|
+
lastPushedPlanningIdentityWatermarks: workspaceLastPushedPlanningIdentityWatermarksRef.current,
|
|
964
1002
|
lastPushedAiProfileIds: workspaceLastPushedAiProfileIdsRef.current,
|
|
965
1003
|
lastPushedAiProfileWatermarks: workspaceLastPushedAiProfileWatermarksRef.current,
|
|
966
1004
|
lastPushedAiProfileChangeKeys: workspaceLastPushedAiProfileChangeKeysRef.current,
|
|
@@ -1165,14 +1203,27 @@ export function useSyncOrchestrator(input) {
|
|
|
1165
1203
|
return false;
|
|
1166
1204
|
if (cloudAuthConfigured && (!authSessionResolved || !isAuthenticated))
|
|
1167
1205
|
return false;
|
|
1206
|
+
// See refreshWorkspaceSyncAssetsSnapshot for the snapshot-completeness contract
|
|
1207
|
+
// this mirrors: only a response that still answers the CURRENT workspace visit
|
|
1208
|
+
// may be committed or raise "ready".
|
|
1209
|
+
const requestWorkspaceId = currentWorkspaceId;
|
|
1210
|
+
const requestGeneration = workspaceSyncGenerationRef.current;
|
|
1211
|
+
const requestSeq = (workspaceSyncDocumentsRequestSeqRef.current += 1);
|
|
1212
|
+
const isStaleRequest = () => (requestWorkspaceId !== currentWorkspaceIdRef.current
|
|
1213
|
+
|| requestGeneration !== workspaceSyncGenerationRef.current
|
|
1214
|
+
|| requestSeq !== workspaceSyncDocumentsRequestSeqRef.current);
|
|
1168
1215
|
try {
|
|
1169
1216
|
const res = await fetch(`/api/taskforce/sync/workspace/documents?workspaceId=${encodeURIComponent(currentWorkspaceId)}`, {
|
|
1170
1217
|
method: 'GET',
|
|
1171
1218
|
credentials: 'include'
|
|
1172
1219
|
});
|
|
1220
|
+
if (isStaleRequest())
|
|
1221
|
+
return false;
|
|
1173
1222
|
if (!res.ok)
|
|
1174
1223
|
return false;
|
|
1175
1224
|
const data = await res.json();
|
|
1225
|
+
if (isStaleRequest())
|
|
1226
|
+
return false;
|
|
1176
1227
|
if (!Array.isArray(data?.documents))
|
|
1177
1228
|
return false;
|
|
1178
1229
|
const docs = Array.isArray(data?.documents)
|
|
@@ -1201,13 +1252,18 @@ export function useSyncOrchestrator(input) {
|
|
|
1201
1252
|
const fingerprint = typeof data?.fingerprint === 'string'
|
|
1202
1253
|
? data.fingerprint
|
|
1203
1254
|
: JSON.stringify(docs.map((entry) => `${entry.path}:${entry.updatedAt}:${entry.content.length}`).sort());
|
|
1204
|
-
if (
|
|
1255
|
+
if (isStaleRequest())
|
|
1256
|
+
return false;
|
|
1257
|
+
if (fingerprint === workspaceSyncMarkdownDocumentsFingerprintRef.current) {
|
|
1258
|
+
workspaceSyncDocumentsSnapshotCompleteRef.current = true;
|
|
1205
1259
|
return true;
|
|
1260
|
+
}
|
|
1206
1261
|
workspaceSyncMarkdownDocumentsFingerprintRef.current = fingerprint;
|
|
1207
1262
|
workspaceSyncMarkdownDocumentsRef.current = docs;
|
|
1208
1263
|
workspaceSyncKnownDocumentPathsRef.current = knownDocumentPaths;
|
|
1209
1264
|
setWorkspaceSyncMarkdownDocuments(docs);
|
|
1210
1265
|
setWorkspaceSyncMarkdownDocumentsFingerprint(fingerprint);
|
|
1266
|
+
workspaceSyncDocumentsSnapshotCompleteRef.current = true;
|
|
1211
1267
|
return true;
|
|
1212
1268
|
}
|
|
1213
1269
|
catch (error) {
|
|
@@ -1218,6 +1274,12 @@ export function useSyncOrchestrator(input) {
|
|
|
1218
1274
|
return false;
|
|
1219
1275
|
}
|
|
1220
1276
|
finally {
|
|
1277
|
+
// General push readiness intentionally stays decoupled from the strict
|
|
1278
|
+
// per-domain completeness contract above: a domain that's temporarily
|
|
1279
|
+
// erroring must not block ALL sync forever. What must never happen is
|
|
1280
|
+
// this domain's ref/deletion-completeness being treated as trustworthy
|
|
1281
|
+
// off the back of a failed or stale fetch — that's guarded above, not
|
|
1282
|
+
// here. See workspaceSyncDocumentsSnapshotCompleteRef.
|
|
1221
1283
|
markWorkspaceSyncReferenceSnapshotReady('documents');
|
|
1222
1284
|
}
|
|
1223
1285
|
}, [runtimeMode, currentWorkspaceId, cloudAuthConfigured, authSessionResolved, isAuthenticated, markWorkspaceSyncReferenceSnapshotReady]);
|
|
@@ -1288,14 +1350,31 @@ export function useSyncOrchestrator(input) {
|
|
|
1288
1350
|
return false;
|
|
1289
1351
|
if (cloudAuthConfigured && (!authSessionResolved || !isAuthenticated))
|
|
1290
1352
|
return false;
|
|
1353
|
+
// Snapshot-completeness contract: a response is only ever committed, and
|
|
1354
|
+
// "ready" only ever raised, when it demonstrably answers the CURRENT
|
|
1355
|
+
// workspace visit. Any failure, malformed payload, or response that
|
|
1356
|
+
// resolves after the workspace has moved on (switched away and possibly
|
|
1357
|
+
// back) is discarded outright — never coerced into "assume unchanged" or
|
|
1358
|
+
// "assume empty". This is what makeWorkspaceSyncPayloadModel's delete-diff
|
|
1359
|
+
// relies on via assetsSnapshotComplete.
|
|
1360
|
+
const requestWorkspaceId = currentWorkspaceId;
|
|
1361
|
+
const requestGeneration = workspaceSyncGenerationRef.current;
|
|
1362
|
+
const requestSeq = (workspaceSyncAssetsRequestSeqRef.current += 1);
|
|
1363
|
+
const isStaleRequest = () => (requestWorkspaceId !== currentWorkspaceIdRef.current
|
|
1364
|
+
|| requestGeneration !== workspaceSyncGenerationRef.current
|
|
1365
|
+
|| requestSeq !== workspaceSyncAssetsRequestSeqRef.current);
|
|
1291
1366
|
try {
|
|
1292
1367
|
const res = await fetch(`/api/taskforce/sync/workspace/assets?workspaceId=${encodeURIComponent(currentWorkspaceId)}`, {
|
|
1293
1368
|
method: 'GET',
|
|
1294
1369
|
credentials: 'include'
|
|
1295
1370
|
});
|
|
1371
|
+
if (isStaleRequest())
|
|
1372
|
+
return false;
|
|
1296
1373
|
if (!res.ok)
|
|
1297
1374
|
return false;
|
|
1298
1375
|
const data = await res.json();
|
|
1376
|
+
if (isStaleRequest())
|
|
1377
|
+
return false;
|
|
1299
1378
|
if (!Array.isArray(data?.assets))
|
|
1300
1379
|
return false;
|
|
1301
1380
|
const assets = Array.isArray(data?.assets)
|
|
@@ -1328,13 +1407,18 @@ export function useSyncOrchestrator(input) {
|
|
|
1328
1407
|
const fingerprint = typeof data?.fingerprint === 'string'
|
|
1329
1408
|
? data.fingerprint
|
|
1330
1409
|
: JSON.stringify(assets.map((entry) => `${entry.path}:${entry.updatedAt}:${entry.contentBase64.length}`).sort());
|
|
1331
|
-
if (
|
|
1410
|
+
if (isStaleRequest())
|
|
1411
|
+
return false;
|
|
1412
|
+
if (fingerprint === workspaceSyncAssetsFingerprintRef.current) {
|
|
1413
|
+
workspaceSyncAssetsSnapshotCompleteRef.current = true;
|
|
1332
1414
|
return true;
|
|
1415
|
+
}
|
|
1333
1416
|
workspaceSyncAssetsFingerprintRef.current = fingerprint;
|
|
1334
1417
|
workspaceSyncAssetsRef.current = assets;
|
|
1335
1418
|
workspaceSyncKnownAssetPathsRef.current = knownAssetPaths;
|
|
1336
1419
|
setWorkspaceSyncAssets(assets);
|
|
1337
1420
|
setWorkspaceSyncAssetsFingerprint(fingerprint);
|
|
1421
|
+
workspaceSyncAssetsSnapshotCompleteRef.current = true;
|
|
1338
1422
|
return true;
|
|
1339
1423
|
}
|
|
1340
1424
|
catch (error) {
|
|
@@ -1345,6 +1429,8 @@ export function useSyncOrchestrator(input) {
|
|
|
1345
1429
|
return false;
|
|
1346
1430
|
}
|
|
1347
1431
|
finally {
|
|
1432
|
+
// See refreshWorkspaceSyncMarkdownDocumentsSnapshot: general push
|
|
1433
|
+
// readiness stays decoupled from the strict completeness contract above.
|
|
1348
1434
|
markWorkspaceSyncReferenceSnapshotReady('assets');
|
|
1349
1435
|
}
|
|
1350
1436
|
}, [runtimeMode, currentWorkspaceId, cloudAuthConfigured, authSessionResolved, isAuthenticated, markWorkspaceSyncReferenceSnapshotReady]);
|
|
@@ -1622,6 +1708,16 @@ export function useSyncOrchestrator(input) {
|
|
|
1622
1708
|
workspaceLastPushedWorkstreamWatermarksRef.current = new Map(workspaceWorkstreamsRef.current
|
|
1623
1709
|
.map((entry) => [String(entry?.id || '').trim(), String(entry?.updatedAt || entry?.createdAt || '').trim()])
|
|
1624
1710
|
.filter(([id]) => id.length > 0));
|
|
1711
|
+
workspaceLastPushedPlanningIdentityWatermarksRef.current = new Map([
|
|
1712
|
+
...workspaceInitiativesRef.current.map((entry) => [
|
|
1713
|
+
`initiative:${String(entry?.id || '').trim()}`,
|
|
1714
|
+
String(entry?.identityUpdatedAt || '').trim(),
|
|
1715
|
+
]),
|
|
1716
|
+
...workspaceWorkstreamsRef.current.map((entry) => [
|
|
1717
|
+
`workstream:${String(entry?.id || '').trim()}`,
|
|
1718
|
+
String(entry?.identityUpdatedAt || '').trim(),
|
|
1719
|
+
]),
|
|
1720
|
+
].filter(([key, watermark]) => !key.endsWith(':') && Number.isFinite(Date.parse(watermark))));
|
|
1625
1721
|
workspaceLastPushedAiProfileIdsRef.current = new Set(workspaceSyncAiProfilesRef.current
|
|
1626
1722
|
.map((entry) => String(entry?.id || '').trim())
|
|
1627
1723
|
.filter((id) => id.length > 0));
|
|
@@ -2636,6 +2732,8 @@ export function useSyncOrchestrator(input) {
|
|
|
2636
2732
|
phase: localCoordinator.phase,
|
|
2637
2733
|
snapshot: localCoordinator.snapshot,
|
|
2638
2734
|
errorMessage: localCoordinator.error?.message || null,
|
|
2735
|
+
activeCommandType: localCoordinator.activeCommandType,
|
|
2736
|
+
activePriorityCommandType: localCoordinator.activePriorityCommandType,
|
|
2639
2737
|
}
|
|
2640
2738
|
: null;
|
|
2641
2739
|
const switchLocalCoordinatorWorkspace = useCallback(async (targetWorkspaceId) => {
|
|
@@ -2677,6 +2775,16 @@ export function useSyncOrchestrator(input) {
|
|
|
2677
2775
|
runtimeMode,
|
|
2678
2776
|
workspaceCloudSyncEnabled,
|
|
2679
2777
|
]);
|
|
2778
|
+
const clearLocalCoordinatorCredential = useCallback(async () => {
|
|
2779
|
+
if (runtimeMode !== 'local'
|
|
2780
|
+
|| !localCoordinatorAttachmentEnabled)
|
|
2781
|
+
return false;
|
|
2782
|
+
return localCoordinator.clearCredential();
|
|
2783
|
+
}, [
|
|
2784
|
+
localCoordinator,
|
|
2785
|
+
localCoordinatorAttachmentEnabled,
|
|
2786
|
+
runtimeMode,
|
|
2787
|
+
]);
|
|
2680
2788
|
return {
|
|
2681
2789
|
userGlobalSyncStatus,
|
|
2682
2790
|
setUserGlobalSyncStatus,
|
|
@@ -2700,6 +2808,7 @@ export function useSyncOrchestrator(input) {
|
|
|
2700
2808
|
localCoordinatorStatus,
|
|
2701
2809
|
switchLocalCoordinatorWorkspace,
|
|
2702
2810
|
transferLocalCoordinatorOwnership,
|
|
2811
|
+
clearLocalCoordinatorCredential,
|
|
2703
2812
|
syncInFlightRef,
|
|
2704
2813
|
workspaceRetryAt,
|
|
2705
2814
|
isWorkspaceRetryPending,
|