@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.
Files changed (321) hide show
  1. package/dist/Taskforce.module.css +290 -45
  2. package/dist/components/features/AiProfilesModule.js +3 -5
  3. package/dist/components/features/TaskSettings.js +70 -14
  4. package/dist/components/features/TaskforceAgentsModule.d.ts +1 -2
  5. package/dist/components/features/TaskforceAgentsModule.js +586 -116
  6. package/dist/components/features/agentConnections/AgentConnectionControl.d.ts +15 -0
  7. package/dist/components/features/agentConnections/AgentConnectionControl.js +125 -0
  8. package/dist/components/features/agentConnections/ModelConnectionsPanel.d.ts +18 -0
  9. package/dist/components/features/agentConnections/ModelConnectionsPanel.js +393 -0
  10. package/dist/components/features/agentConnections/modelConnectionsApi.d.ts +65 -0
  11. package/dist/components/features/agentConnections/modelConnectionsApi.js +129 -0
  12. package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +15 -24
  13. package/dist/components/features/taskforceAgentEditorModel.d.ts +2 -1
  14. package/dist/components/features/taskforceAgentEditorModel.js +3 -1
  15. package/dist/components/features/workflowManager/workflowManagerApi.d.ts +1 -1
  16. package/dist/components/features/workflowManager/workflowManagerApi.js +3 -0
  17. package/dist/components/task/TaskWorkflowAssignmentField.js +68 -10
  18. package/dist/components/views/StandaloneLayout.js +27 -26
  19. package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +4 -3
  20. package/dist/components/views/standalone/modals/SyncStatusModal.js +33 -38
  21. package/dist/config/envSchema.js +48 -1
  22. package/dist/core/McpTokenService.d.ts +23 -1
  23. package/dist/core/McpTokenService.js +93 -10
  24. package/dist/core/TaskChecklistCommandService.d.ts +27 -0
  25. package/dist/core/TaskChecklistCommandService.js +83 -5
  26. package/dist/core/TaskLifecycleCommandService.d.ts +3 -1
  27. package/dist/core/TaskLifecycleCommandService.js +6 -2
  28. package/dist/core/Taskforce.d.ts +32 -0
  29. package/dist/core/Taskforce.js +125 -4
  30. package/dist/core/types.d.ts +8 -0
  31. package/dist/documentReviews/commandService.d.ts +2 -1
  32. package/dist/documentReviews/commandService.js +6 -3
  33. package/dist/hooks/sync/orchestratorShared.d.ts +1 -0
  34. package/dist/hooks/sync/orchestratorShared.js +2 -0
  35. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.d.ts +3 -0
  36. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.js +85 -9
  37. package/dist/hooks/sync/useSyncStatusControls.d.ts +4 -1
  38. package/dist/hooks/sync/useSyncStatusControls.js +47 -11
  39. package/dist/hooks/useSyncOrchestrator.d.ts +3 -0
  40. package/dist/hooks/useSyncOrchestrator.js +111 -2
  41. package/dist/hooks/useTaskData.d.ts +31 -1
  42. package/dist/hooks/useTaskData.js +29 -7
  43. package/dist/hooks/useTaskMutations.d.ts +3 -1
  44. package/dist/hooks/useTaskMutations.js +46 -12
  45. package/dist/hooks/useTaskforce.d.ts +2 -0
  46. package/dist/hooks/useTaskforce.js +11 -2
  47. package/dist/mcp/clientRegistry.d.ts +2 -2
  48. package/dist/mcp/clientRegistry.js +1 -1
  49. package/dist/mcp/documentAssetRegistrar.js +9 -6
  50. package/dist/mcp/durableTaskMutationRouter.d.ts +4 -1
  51. package/dist/mcp/durableTaskMutationRouter.js +10 -0
  52. package/dist/mcp/durableTaskRelationshipMutationRouter.js +4 -0
  53. package/dist/mcp/httpProtocolRouting.d.ts +10 -0
  54. package/dist/mcp/httpProtocolRouting.js +19 -0
  55. package/dist/mcp/localCliHealth.d.ts +2 -2
  56. package/dist/mcp/localCliHealth.js +2 -2
  57. package/dist/mcp/localServiceProxy.d.ts +1 -0
  58. package/dist/mcp/localServiceProxy.js +530 -68
  59. package/dist/mcp/planningAttachmentCommandAdapter.d.ts +3 -1
  60. package/dist/mcp/planningAttachmentCommandAdapter.js +20 -2
  61. package/dist/mcp/runtime.d.ts +54 -79
  62. package/dist/mcp/runtime.js +384 -97
  63. package/dist/mcp/taskPlanningRegistrar.js +23 -4
  64. package/dist/mcp/toolProfiles.d.ts +2 -0
  65. package/dist/mcp/toolProfiles.js +10 -0
  66. package/dist/mcp/toolRegistry.d.ts +1 -0
  67. package/dist/mcp/toolRegistry.js +1 -0
  68. package/dist/mcp/workflowExecutionRegistrar.js +4 -4
  69. package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
  70. package/dist/migrations/taskSchemaMigrations.js +415 -0
  71. package/dist/runtime/appGates.d.ts +2 -1
  72. package/dist/runtime/appGates.js +7 -0
  73. package/dist/server/index.d.ts +3 -0
  74. package/dist/server/index.js +108 -11
  75. package/dist/server/localDatabaseIdentity.js +4 -1
  76. package/dist/server/localServiceLease.js +2 -1
  77. package/dist/server/localServiceSessions.d.ts +14 -17
  78. package/dist/server/localServiceSessions.js +308 -94
  79. package/dist/server/localWorkspaceSyncServerRuntime.js +12 -14
  80. package/dist/server/routes/admin.d.ts +4 -0
  81. package/dist/server/routes/admin.js +112 -3
  82. package/dist/server/routes/agents.d.ts +7 -0
  83. package/dist/server/routes/agents.js +277 -24
  84. package/dist/server/routes/billing.js +5 -1
  85. package/dist/server/routes/durableTaskHttpRouters.d.ts +2 -0
  86. package/dist/server/routes/executorPhaseAApprovals.d.ts +19 -0
  87. package/dist/server/routes/executorPhaseAApprovals.js +140 -0
  88. package/dist/server/routes/executorPhaseAIssuerRedemptions.d.ts +11 -0
  89. package/dist/server/routes/executorPhaseAIssuerRedemptions.js +24 -0
  90. package/dist/server/routes/githubReviewEvidence.d.ts +19 -0
  91. package/dist/server/routes/githubReviewEvidence.js +116 -0
  92. package/dist/server/routes/localService.d.ts +15 -4
  93. package/dist/server/routes/localService.js +136 -40
  94. package/dist/server/routes/modelConnections.d.ts +24 -0
  95. package/dist/server/routes/modelConnections.js +205 -0
  96. package/dist/server/routes/shared.d.ts +19 -0
  97. package/dist/server/routes/shared.js +95 -19
  98. package/dist/server/routes/sync.js +1 -0
  99. package/dist/server/routes/syncAuxRoutes.js +5 -1
  100. package/dist/server/routes/syncPushRoutes.d.ts +1 -0
  101. package/dist/server/routes/syncPushRoutes.js +1 -0
  102. package/dist/server/routes/syncV3FeedRoutes.js +10 -1
  103. package/dist/server/routes/syncV3OperationRoutes.js +35 -9
  104. package/dist/server/routes/tasks.js +21 -2
  105. package/dist/server/routes/workflows.js +9 -1
  106. package/dist/server/routes.js +59 -0
  107. package/dist/services/codexAppServerModelGateway.d.ts +54 -5
  108. package/dist/services/codexAppServerModelGateway.js +246 -21
  109. package/dist/services/codexDeviceCodeLoginManager.d.ts +39 -0
  110. package/dist/services/codexDeviceCodeLoginManager.js +265 -0
  111. package/dist/services/codexModelProviderConnectionLifecycle.d.ts +8 -0
  112. package/dist/services/codexModelProviderConnectionLifecycle.js +73 -0
  113. package/dist/services/executorPhaseAApprovalRuntime.d.ts +14 -0
  114. package/dist/services/executorPhaseAApprovalRuntime.js +24 -0
  115. package/dist/services/executorPhaseAApprovalService.d.ts +40 -0
  116. package/dist/services/executorPhaseAApprovalService.js +609 -0
  117. package/dist/services/executorPhaseADriftEvaluator.d.ts +78 -0
  118. package/dist/services/executorPhaseADriftEvaluator.js +93 -0
  119. package/dist/services/executorPhaseAIssuerCore.d.ts +126 -0
  120. package/dist/services/executorPhaseAIssuerCore.js +295 -0
  121. package/dist/services/executorPhaseAIssuerRedemptionService.d.ts +34 -0
  122. package/dist/services/executorPhaseAIssuerRedemptionService.js +158 -0
  123. package/dist/services/githubReviewEvidenceRuntime.d.ts +14 -0
  124. package/dist/services/githubReviewEvidenceRuntime.js +30 -0
  125. package/dist/services/githubReviewEvidenceService.d.ts +93 -0
  126. package/dist/services/githubReviewEvidenceService.js +336 -0
  127. package/dist/services/modelGateway.d.ts +7 -0
  128. package/dist/services/modelProviderConnectionService.d.ts +71 -0
  129. package/dist/services/modelProviderConnectionService.js +279 -0
  130. package/dist/services/modelProviderCredentialHome.d.ts +32 -0
  131. package/dist/services/modelProviderCredentialHome.js +271 -0
  132. package/dist/services/ownerScopedModelConnectionGateway.d.ts +12 -0
  133. package/dist/services/ownerScopedModelConnectionGateway.js +30 -0
  134. package/dist/services/taskforceAgentConnectionBindingService.d.ts +66 -0
  135. package/dist/services/taskforceAgentConnectionBindingService.js +185 -0
  136. package/dist/services/taskforceAgentMcpBridge.d.ts +1 -1
  137. package/dist/services/taskforceAgentMcpBridge.js +7 -24
  138. package/dist/shared/adminEdgeProxy.d.ts +5 -0
  139. package/dist/shared/adminEdgeProxy.js +94 -0
  140. package/dist/shared/adminProxySessionCookies.d.ts +16 -0
  141. package/dist/shared/adminProxySessionCookies.js +86 -0
  142. package/dist/shared/aiProfileColors.d.ts +31 -1
  143. package/dist/shared/aiProfileColors.js +14 -6
  144. package/dist/shared/executorPhaseAApprovalGoldenVector.json +269 -0
  145. package/dist/shared/executorPhaseAApprovalReceipt.d.ts +112 -0
  146. package/dist/shared/executorPhaseAApprovalReceipt.js +58 -0
  147. package/dist/shared/executorPhaseAApprovalTrustPolicy.json +10 -0
  148. package/dist/shared/executorPhaseADriftContracts.d.ts +37 -0
  149. package/dist/shared/executorPhaseADriftContracts.js +63 -0
  150. package/dist/shared/executorPhaseAIssuerContracts.d.ts +75 -0
  151. package/dist/shared/executorPhaseAIssuerContracts.js +90 -0
  152. package/dist/shared/executorPhaseARunAuthorization.d.ts +120 -0
  153. package/dist/shared/executorPhaseARunAuthorization.js +232 -0
  154. package/dist/shared/executorPhaseASchemaValidation.d.ts +7 -0
  155. package/dist/shared/executorPhaseASchemaValidation.js +53 -0
  156. package/dist/shared/executorPhaseASchemas/approval-receipt.schema.json +106 -0
  157. package/dist/shared/executorPhaseASchemas/drift-attestation.schema.json +54 -0
  158. package/dist/shared/executorPhaseASchemas/drift-request.schema.json +47 -0
  159. package/dist/shared/executorPhaseASchemas/foundation-manifest.schema.json +29 -0
  160. package/dist/shared/executorPhaseASchemas/issuer-audit-record.schema.json +24 -0
  161. package/dist/shared/executorPhaseASchemas/issuer-proof.schema.json +43 -0
  162. package/dist/shared/executorPhaseASchemas/issuer-redemption-request.schema.json +18 -0
  163. package/dist/shared/executorPhaseASchemas/issuer-redemption-response.schema.json +39 -0
  164. package/dist/shared/executorPhaseASchemas/logical-envelope.schema.json +149 -0
  165. package/dist/shared/executorPhaseASchemas/preflight-report.schema.json +216 -0
  166. package/dist/shared/executorPhaseASchemas/run-capability.schema.json +111 -0
  167. package/dist/shared/executorPhaseASchemas/sender-proof.schema.json +37 -0
  168. package/dist/shared/executorPhaseASchemas/workload-grant.schema.json +68 -0
  169. package/dist/shared/executorPhaseASchemas/workload-jwt-claims.schema.json +67 -0
  170. package/dist/shared/executorPhaseATiming.d.ts +1 -0
  171. package/dist/shared/executorPhaseATiming.js +1 -0
  172. package/dist/shared/planningIdentity.js +1 -1
  173. package/dist/shared/productLogoKeys.d.ts +2 -0
  174. package/dist/shared/productLogoKeys.js +18 -0
  175. package/dist/shared/taskforceAgentDefinition.d.ts +0 -1
  176. package/dist/shared/taskforceAgentDefinition.js +6 -9
  177. package/dist/shared/taskforceAgentModels.js +7 -3
  178. package/dist/shared/userFeatureGrants.d.ts +4 -0
  179. package/dist/shared/userFeatureGrants.js +7 -0
  180. package/dist/storage/executorPhaseAApprovalReceiptStore.d.ts +37 -0
  181. package/dist/storage/executorPhaseAApprovalReceiptStore.js +81 -0
  182. package/dist/storage/executorPhaseARunAuthorizationStore.d.ts +103 -0
  183. package/dist/storage/executorPhaseARunAuthorizationStore.js +492 -0
  184. package/dist/storage/githubReviewEvidenceInstallationStore.d.ts +26 -0
  185. package/dist/storage/githubReviewEvidenceInstallationStore.js +89 -0
  186. package/dist/storage/modelProviderConnectionStore.d.ts +99 -0
  187. package/dist/storage/modelProviderConnectionStore.js +446 -0
  188. package/dist/storage/postgresAdapter.d.ts +4 -0
  189. package/dist/storage/postgresAdapter.js +11 -0
  190. package/dist/storage/postgresWorker.js +9 -1
  191. package/dist/storage/postgresWorkerProtocol.d.ts +1 -0
  192. package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
  193. package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -0
  194. package/dist/sync/coordinator/localSyncExecutionPermitStore.js +60 -29
  195. package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.d.ts +10 -0
  196. package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.js +29 -0
  197. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.d.ts +15 -1
  198. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.js +99 -2
  199. package/dist/sync/coordinator/workspaceSyncCredentialBroker.d.ts +1 -0
  200. package/dist/sync/coordinator/workspaceSyncCredentialBroker.js +33 -4
  201. package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.d.ts +2 -1
  202. package/dist/sync/engine/workspaceSyncContentVersionStore.d.ts +38 -0
  203. package/dist/sync/engine/workspaceSyncContentVersionStore.js +50 -1
  204. package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +6 -6
  205. package/dist/sync/engine/workspaceSyncEnginePushCompletion.d.ts +14 -0
  206. package/dist/sync/engine/workspaceSyncEnginePushCompletion.js +84 -0
  207. package/dist/sync/engine/workspaceSyncEngineRecovery.js +1 -0
  208. package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +1 -0
  209. package/dist/sync/engine/workspaceSyncEngineRuntime.js +1 -0
  210. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +112 -38
  211. package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +6 -0
  212. package/dist/sync/engine/workspaceSyncEngineTransfers.js +3 -1
  213. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.d.ts +1 -0
  214. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +29 -0
  215. package/dist/sync/syncApplyHandlers.d.ts +2 -0
  216. package/dist/sync/syncApplyHandlers.js +10 -1
  217. package/dist/sync/syncService.d.ts +15 -0
  218. package/dist/sync/syncService.js +83 -18
  219. package/dist/sync/taskforceAgentSyncAuthorization.d.ts +16 -0
  220. package/dist/sync/taskforceAgentSyncAuthorization.js +20 -0
  221. package/dist/sync/v3/combinedFeedCapability.js +4 -0
  222. package/dist/sync/v3/durableInitiativeMutationRouter.js +18 -10
  223. package/dist/sync/v3/durableOperationReplay.d.ts +14 -0
  224. package/dist/sync/v3/durableOperationReplay.js +18 -0
  225. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +3 -0
  226. package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +2 -1
  227. package/dist/sync/v3/durableTaskChecklistMutationRouter.js +58 -15
  228. package/dist/sync/v3/durableTaskCommentMutationRouter.js +3 -0
  229. package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +1 -1
  230. package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +10 -0
  231. package/dist/sync/v3/durableTaxonomyMutationRouter.js +5 -0
  232. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.d.ts +11 -0
  233. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +39 -10
  234. package/dist/sync/v3/durableWorkstreamMutationRouter.js +18 -10
  235. package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.js +16 -5
  236. package/dist/sync/v3/localOutboxDispatchRuntime.js +2 -2
  237. package/dist/sync/v3/localTaskChecklistOutboxHandler.js +16 -2
  238. package/dist/sync/v3/localTaskChecklistOutboxService.d.ts +4 -0
  239. package/dist/sync/v3/localTaskChecklistOutboxService.js +14 -1
  240. package/dist/sync/v3/localTaskStatusOutboxService.d.ts +8 -0
  241. package/dist/sync/v3/localTaskStatusOutboxService.js +219 -12
  242. package/dist/sync/v3/syncDurabilityStore.d.ts +34 -0
  243. package/dist/sync/v3/syncDurabilityStore.js +168 -2
  244. package/dist/sync/v3/taskChecklistMutationService.d.ts +11 -0
  245. package/dist/sync/v3/taskChecklistMutationService.js +44 -1
  246. package/dist/sync/v3/taskStatusMutationService.d.ts +29 -1
  247. package/dist/sync/v3/taskStatusMutationService.js +119 -3
  248. package/dist/sync/v3/workflowAssignmentSync.d.ts +5 -0
  249. package/dist/sync/v3/workflowAssignmentSync.js +27 -0
  250. package/dist/sync/v3/workspaceSyncJournalReader.js +1 -1
  251. package/dist/sync/v3/workspaceSyncOperationRetentionService.d.ts +16 -0
  252. package/dist/sync/v3/workspaceSyncOperationRetentionService.js +83 -0
  253. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +1 -0
  254. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +9 -2
  255. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +7 -0
  256. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +44 -32
  257. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +9 -5
  258. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +54 -38
  259. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +10 -0
  260. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +70 -31
  261. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +2 -1
  262. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +16 -0
  263. package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +6 -0
  264. package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +3 -0
  265. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +5 -0
  266. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +36 -2
  267. package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.d.ts +17 -0
  268. package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.js +64 -0
  269. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.d.ts +7 -0
  270. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.js +33 -0
  271. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.d.ts +7 -0
  272. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.js +8 -0
  273. package/dist/sync/workspaceRepair.d.ts +5 -2
  274. package/dist/sync/workspaceRepair.js +161 -6
  275. package/dist/sync/workspaceSyncModel.d.ts +21 -0
  276. package/dist/sync/workspaceSyncModel.js +35 -7
  277. package/dist/sync/workspaceSyncState.d.ts +1 -0
  278. package/dist/sync/workspaceSyncV2SnapshotBuilder.d.ts +6 -0
  279. package/dist/sync/workspaceSyncV2SnapshotBuilder.js +5 -0
  280. package/dist/ui/assets/AiIdentityRosterCard-OcSz1PkK.js +1 -0
  281. package/dist/ui/assets/AiProfilesModule-ByhYW5Xi.js +1 -0
  282. package/dist/ui/assets/{AnnotatedAttachmentWorkspace-B68Wg-RV.js → AnnotatedAttachmentWorkspace-BTM6nIg_.js} +1 -1
  283. package/dist/ui/assets/{AssetTraySortControl-C8Rztyal.js → AssetTraySortControl-DabEG8L4.js} +1 -1
  284. package/dist/ui/assets/{ContextAttachmentManager-Cj3c7X9y.js → ContextAttachmentManager-Coa8yVGM.js} +1 -1
  285. package/dist/ui/assets/{DocumentWorkspace-B5uvzems.js → DocumentWorkspace-BB0qhdix.js} +1 -1
  286. package/dist/ui/assets/{EntityActivityTimeline-BVFvCB5R.js → EntityActivityTimeline-CZ8x4UJE.js} +1 -1
  287. package/dist/ui/assets/{PlanningModule-B5DWQOGz.js → PlanningModule-pRPjR7v5.js} +1 -1
  288. package/dist/ui/assets/{PlansPage-AY4cGWco.js → PlansPage-D86pZSSl.js} +1 -1
  289. package/dist/ui/assets/{TaskContextUpload-DZxTVesW.js → TaskContextUpload-BVIkU9yT.js} +1 -1
  290. package/dist/ui/assets/TaskSettings-Cv1mNhv_.js +12 -0
  291. package/dist/ui/assets/TaskforceAgentsModule-b-8R25cJ.css +1 -0
  292. package/dist/ui/assets/TaskforceAgentsModule-gmH-PD2q.js +24 -0
  293. package/dist/ui/assets/{WorkflowManagerModule-DEr5di_r.js → WorkflowManagerModule-DbfnHJ-f.js} +1 -1
  294. package/dist/ui/assets/index-BZ-hdZSk.css +1 -0
  295. package/dist/ui/assets/index-CTsDBaef.js +7 -0
  296. package/dist/ui/assets/{vendor-icons-D9Lpw-j4.js → vendor-icons-Bsq-mcEn.js} +1 -1
  297. package/dist/ui/branding/logos/letterhead_dark.png +0 -0
  298. package/dist/ui/branding/logos/letterhead_light.png +0 -0
  299. package/dist/ui/branding/logos/signature_dark.png +0 -0
  300. package/dist/ui/branding/logos/signature_light.png +0 -0
  301. package/dist/ui/index.html +3 -3
  302. package/dist/utils/aiProfileDefaultLogo.js +16 -48
  303. package/dist/utils/httpSetCookie.d.ts +1 -0
  304. package/dist/utils/httpSetCookie.js +4 -1
  305. package/dist/utils/localRuntimeUrl.d.ts +1 -0
  306. package/dist/utils/localRuntimeUrl.js +14 -0
  307. package/dist/utils/productLogoRegistry.d.ts +2 -0
  308. package/dist/utils/productLogoRegistry.js +36 -0
  309. package/dist/utils/syncStatusPresentation.d.ts +4 -0
  310. package/dist/utils/syncStatusPresentation.js +17 -0
  311. package/dist/utils/taskEvents.d.ts +2 -0
  312. package/dist/utils/workspaceSyncPresentation.d.ts +1 -1
  313. package/dist/utils/workspaceSyncPresentation.js +23 -17
  314. package/package.json +22 -4
  315. package/dist/ui/assets/AiIdentityRosterCard-BZM4aQnM.js +0 -1
  316. package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +0 -1
  317. package/dist/ui/assets/TaskSettings-BeWAuyZj.js +0 -12
  318. package/dist/ui/assets/TaskforceAgentsModule-BifCYtjR.js +0 -21
  319. package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +0 -1
  320. package/dist/ui/assets/index-I5zhdtgt.js +0 -7
  321. 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
- const snapshot = snapshotRef.current;
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
- return activePriority.promise;
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
- return resumedPriority;
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 (!priorityCommand && active?.workspaceId === input.workspaceId) {
269
- await active.promise;
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
- if (!priorityCommand) {
272
- const resumed = resumePendingCommand(scopeRef.current);
273
- if (resumed)
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
- try {
13
- const result = await saveWorkspaceCloudSyncSettings({ enabled });
14
- if (!result.success) {
15
- setWorkspaceSyncError(result.error || (enabled ? 'Failed to enable sync.' : 'Failed to disable sync.'));
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 (fingerprint === workspaceSyncMarkdownDocumentsFingerprintRef.current)
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 (fingerprint === workspaceSyncAssetsFingerprintRef.current)
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,