@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
@@ -1,3 +1,28 @@
1
+ /**
2
+ * useTaskData
3
+ *
4
+ * Manages the task fetch lifecycle, recently-changed-task highlighting,
5
+ * and merge/coalesce helpers. Task and archive state arrays live in
6
+ * useTaskforce.ts (because they must be passed to useSyncOrchestrator),
7
+ * but all fetch and mutation helpers are encapsulated here.
8
+ *
9
+ * === SECTION MAP ===
10
+ * === SECTION: Recently Changed === — recentlyChangedTaskIds, markRecentlyChangedTasks, timer cleanup
11
+ * === SECTION: Fetch Functions === — fetchTasks, fetchArchive, refreshTaskCollections, refreshTaskCollectionsFromInvalidation
12
+ * === SECTION: Revision Tracking === — getTaskRevisionKey, taskRevisionMapRef, hasFetchedTasksRef
13
+ * === SECTION: Merge Helper === — mergeTaskFromServer
14
+ *
15
+ * Key return values:
16
+ * - fetchTasks(isSilent?, options?) — refresh the active task list
17
+ * - fetchArchive(isSilent?, options?) — refresh the archive
18
+ * - refreshTaskCollections(options?) — refresh both in parallel
19
+ * - refreshTaskCollectionsFromInvalidation() — scoped task collection refresh
20
+ * - mergeTaskFromServer(task) — merge a single server response into both collections
21
+ * - markRecentlyChangedTasks(ids) — flag task IDs for highlight animation
22
+ * - recentlyChangedTaskIds — task IDs that changed in the last 2s
23
+ * - getTaskRevisionKey(task) — stable revision string for change detection
24
+ */
25
+ import { type MutableRefObject } from 'react';
1
26
  import type { TaskItem } from '../types';
2
27
  interface UseTaskDataProps {
3
28
  tasks: TaskItem[];
@@ -14,8 +39,13 @@ interface UseTaskDataProps {
14
39
  authRequiredForApi: boolean;
15
40
  setError?: (value: string) => void;
16
41
  setLoading?: (value: boolean) => void;
42
+ pendingTaskMetadataOverlaysRef?: MutableRefObject<Map<string, PendingTaskMetadataOverlay>>;
17
43
  }
18
- export declare function useTaskData({ tasks, archivedTasks, setTasks, setArchivedTasks, setLoadingTasks, getCurrentWorkspaceId, workspaceResetKey, shouldDeferProtectedApiCalls, shouldBlockProtectedApiCalls, handleUnauthorized, authRequiredForApi, setError, setLoading }: UseTaskDataProps): {
44
+ export interface PendingTaskMetadataOverlay {
45
+ patch: Partial<TaskItem>;
46
+ observedUpdatedAt: string | null;
47
+ }
48
+ export declare function useTaskData({ tasks, archivedTasks, setTasks, setArchivedTasks, setLoadingTasks, getCurrentWorkspaceId, workspaceResetKey, shouldDeferProtectedApiCalls, shouldBlockProtectedApiCalls, handleUnauthorized, authRequiredForApi, setError, setLoading, pendingTaskMetadataOverlaysRef, }: UseTaskDataProps): {
19
49
  tasksRef: import("react").RefObject<TaskItem[]>;
20
50
  archivedTasksRef: import("react").RefObject<TaskItem[]>;
21
51
  taskDetails: TaskItem[];
@@ -25,7 +25,8 @@
25
25
  import { useState, useEffect, useCallback, useRef } from 'react';
26
26
  import { getTaskContentRevision, mergeNormalizedTaskIntoCollections, normalizeTaskFromApi, reconcileTaskCollection, toTaskCollectionSummary } from '../utils/taskNormalization.js';
27
27
  import { resolveTaskReferenceId } from '../utils/taskReferences.js';
28
- export function useTaskData({ tasks, archivedTasks, setTasks, setArchivedTasks, setLoadingTasks, getCurrentWorkspaceId, workspaceResetKey, shouldDeferProtectedApiCalls, shouldBlockProtectedApiCalls, handleUnauthorized, authRequiredForApi, setError, setLoading }) {
28
+ import { canonicalWorkspaceSyncJson } from '../sync/v3/canonicalWorkspaceSyncJson.js';
29
+ export function useTaskData({ tasks, archivedTasks, setTasks, setArchivedTasks, setLoadingTasks, getCurrentWorkspaceId, workspaceResetKey, shouldDeferProtectedApiCalls, shouldBlockProtectedApiCalls, handleUnauthorized, authRequiredForApi, setError, setLoading, pendingTaskMetadataOverlaysRef, }) {
29
30
  // === SECTION: Revision Tracking ===
30
31
  const taskRevisionMapRef = useRef(new Map());
31
32
  const hasFetchedTasksRef = useRef(false);
@@ -58,6 +59,26 @@ export function useTaskData({ tasks, archivedTasks, setTasks, setArchivedTasks,
58
59
  const getTaskRevisionKey = useCallback((task) => {
59
60
  return getTaskContentRevision(task);
60
61
  }, []);
62
+ const preservePendingTaskMetadata = useCallback((task) => {
63
+ const pending = pendingTaskMetadataOverlaysRef?.current.get(task.id);
64
+ if (!pending)
65
+ return task;
66
+ const patchMatches = Object.entries(pending.patch).every(([key, value]) => {
67
+ const candidate = task[key];
68
+ return candidate === undefined || value === undefined
69
+ ? candidate === value
70
+ : canonicalWorkspaceSyncJson(candidate) === canonicalWorkspaceSyncJson(value);
71
+ });
72
+ const candidateUpdatedAt = Date.parse(String(task.updatedAt || ''));
73
+ const observedUpdatedAt = Date.parse(String(pending.observedUpdatedAt || ''));
74
+ if (patchMatches || (Number.isFinite(candidateUpdatedAt)
75
+ && Number.isFinite(observedUpdatedAt)
76
+ && candidateUpdatedAt > observedUpdatedAt)) {
77
+ pendingTaskMetadataOverlaysRef?.current.delete(task.id);
78
+ return task;
79
+ }
80
+ return { ...task, ...pending.patch };
81
+ }, [pendingTaskMetadataOverlaysRef]);
61
82
  const isExpectedAbortFailure = useCallback((error, signal) => {
62
83
  if (!signal.aborted)
63
84
  return false;
@@ -192,7 +213,7 @@ export function useTaskData({ tasks, archivedTasks, setTasks, setArchivedTasks,
192
213
  }
193
214
  if (res.ok) {
194
215
  const data = await res.json();
195
- const sanitized = (data.tasks || []).map((t) => normalizeTaskFromApi(t));
216
+ const sanitized = (data.tasks || []).map((t) => (preservePendingTaskMetadata(normalizeTaskFromApi(t))));
196
217
  const liveWorkspaceId = String(getCurrentWorkspaceId() || '').trim();
197
218
  if (liveWorkspaceId !== requestWorkspaceId) {
198
219
  return;
@@ -251,7 +272,8 @@ export function useTaskData({ tasks, archivedTasks, setTasks, setArchivedTasks,
251
272
  authRequiredForApi,
252
273
  shouldDeferProtectedApiCalls,
253
274
  shouldBlockProtectedApiCalls,
254
- reconcileTaskDetailCache
275
+ reconcileTaskDetailCache,
276
+ preservePendingTaskMetadata,
255
277
  ]);
256
278
  const fetchArchive = useCallback(async (isSilent = false, options) => {
257
279
  const ignoreAuthGuard = options?.ignoreAuthGuard === true;
@@ -272,7 +294,7 @@ export function useTaskData({ tasks, archivedTasks, setTasks, setArchivedTasks,
272
294
  return false;
273
295
  }
274
296
  const sanitized = (data.archived || []).map((t) => ({
275
- ...normalizeTaskFromApi(t),
297
+ ...preservePendingTaskMetadata(normalizeTaskFromApi(t)),
276
298
  isArchived: true
277
299
  }));
278
300
  reconcileTaskDetailCache(sanitized, true);
@@ -299,7 +321,7 @@ export function useTaskData({ tasks, archivedTasks, setTasks, setArchivedTasks,
299
321
  setLoadingTasks(false);
300
322
  }
301
323
  }
302
- }, [getCurrentWorkspaceId, isExpectedAbortFailure, reconcileTaskDetailCache, setArchivedTasks, setLoadingTasks, shouldDeferProtectedApiCalls, shouldBlockProtectedApiCalls]);
324
+ }, [getCurrentWorkspaceId, isExpectedAbortFailure, preservePendingTaskMetadata, reconcileTaskDetailCache, setArchivedTasks, setLoadingTasks, shouldDeferProtectedApiCalls, shouldBlockProtectedApiCalls]);
303
325
  const loadTaskDetail = useCallback(async (task, options) => {
304
326
  const force = options?.force === true;
305
327
  if (!force && !task.isSummary) {
@@ -429,7 +451,7 @@ export function useTaskData({ tasks, archivedTasks, setTasks, setArchivedTasks,
429
451
  }, [refreshTaskCollections]);
430
452
  // === SECTION: Merge Helper ===
431
453
  const mergeTaskFromServer = useCallback((task) => {
432
- const normalized = normalizeTaskFromApi(task);
454
+ const normalized = preservePendingTaskMetadata(normalizeTaskFromApi(task));
433
455
  const existingSummary = [...tasksRef.current, ...archivedTasksRef.current]
434
456
  .find((candidate) => candidate.id === normalized.id);
435
457
  const collectionSummary = normalized.isSummary
@@ -467,7 +489,7 @@ export function useTaskData({ tasks, archivedTasks, setTasks, setArchivedTasks,
467
489
  setTasks(merged.tasks);
468
490
  if (archivedTasksChanged)
469
491
  setArchivedTasks(merged.archivedTasks);
470
- }, [getTaskSummaryRevision, publishTaskDetailCache, setTasks, setArchivedTasks]);
492
+ }, [getTaskSummaryRevision, preservePendingTaskMetadata, publishTaskDetailCache, setTasks, setArchivedTasks]);
471
493
  return {
472
494
  // Stable refs (for use inside closures)
473
495
  tasksRef,
@@ -8,6 +8,7 @@ import type { DurableTaskDeleteMutationAdapter } from './sync/useDurableTaskDele
8
8
  import type { DurableTaskRestoreMutationAdapter } from './sync/useDurableTaskRestoreMutation.js';
9
9
  import type { TaskRestoreDestination } from '../shared/taskRestoreDestination.js';
10
10
  import type { DurableTaskTargetStatus } from '../core/TaskDurableStatusMutationService.js';
11
+ import type { PendingTaskMetadataOverlay } from './useTaskData.js';
11
12
  import { createCloudTaskHttpMutationClient } from './tasks/taskHttpMutation.js';
12
13
  export interface UseTaskMutationsProps {
13
14
  tasks: TaskItem[];
@@ -47,6 +48,7 @@ export interface UseTaskMutationsProps {
47
48
  taskHttpMutationClient?: ReturnType<typeof createCloudTaskHttpMutationClient>;
48
49
  onTaskRevisionConflict?: (taskId: string, currentDetailRevision: string | null) => TaskRevisionConflictResolution | void | Promise<TaskRevisionConflictResolution | void>;
49
50
  onTaskMutationAccepted?: (task: TaskItem) => void;
51
+ pendingTaskMetadataOverlaysRef?: MutableRefObject<Map<string, PendingTaskMetadataOverlay>>;
50
52
  }
51
53
  export interface TaskRevisionConflictResolution {
52
54
  handled: boolean;
@@ -66,7 +68,7 @@ export interface DeletedTaskRestoreBatchResult {
66
68
  succeeded: DeletedTaskRecord[];
67
69
  failed: DeletedTaskRestoreFailure[];
68
70
  }
69
- export declare function useTaskMutations({ tasks, archivedTasks, editingTaskId, editingTaskDetailRevision, setTasks, setArchivedTasks, setDeletedTasks, setError, resetForm, setActiveTab, fetchTasks, fetchArchive, fetchDeletedTasks, mergeTaskFromServer, pushNotice, cloudAuthConfigured, runtimeMode, isAuthenticated, workspaceCloudSyncEnabled, buildWorkspaceSyncSignature, pushWorkspaceChangesToCloud, workspacePendingSignatureRef, workspaceDeletedTaskIdsRef, workspaceDeletedTaskWatermarksRef, mutateTaskMetadata, mutateTaskStatus, mutateTaskLifecycle, mutateTaskDelete, mutateTaskRestore, durableTaskMetadataActivationEnabled, durableTaskStatusActivationEnabled, durableTaskDeleteActivationEnabled, durableTaskHttpRootActivationEnabled, workspaceId, taskHttpMutationClient, onTaskRevisionConflict, onTaskMutationAccepted, }: UseTaskMutationsProps): {
71
+ export declare function useTaskMutations({ tasks, archivedTasks, editingTaskId, editingTaskDetailRevision, setTasks, setArchivedTasks, setDeletedTasks, setError, resetForm, setActiveTab, fetchTasks, fetchArchive, fetchDeletedTasks, mergeTaskFromServer, pushNotice, cloudAuthConfigured, runtimeMode, isAuthenticated, workspaceCloudSyncEnabled, buildWorkspaceSyncSignature, pushWorkspaceChangesToCloud, workspacePendingSignatureRef, workspaceDeletedTaskIdsRef, workspaceDeletedTaskWatermarksRef, mutateTaskMetadata, mutateTaskStatus, mutateTaskLifecycle, mutateTaskDelete, mutateTaskRestore, durableTaskMetadataActivationEnabled, durableTaskStatusActivationEnabled, durableTaskDeleteActivationEnabled, durableTaskHttpRootActivationEnabled, workspaceId, taskHttpMutationClient, onTaskRevisionConflict, onTaskMutationAccepted, pendingTaskMetadataOverlaysRef, }: UseTaskMutationsProps): {
70
72
  copiedId: string | null;
71
73
  handleDelete: (id: string, archive?: boolean, options?: {
72
74
  skipConfirm?: boolean;
@@ -41,7 +41,7 @@ function taskHttpObservedPrecondition(task, taskId) {
41
41
  isArchived: task?.isArchived === true,
42
42
  };
43
43
  }
44
- export function useTaskMutations({ tasks, archivedTasks, editingTaskId, editingTaskDetailRevision = null, setTasks, setArchivedTasks, setDeletedTasks, setError, resetForm, setActiveTab, fetchTasks, fetchArchive, fetchDeletedTasks, mergeTaskFromServer, pushNotice, cloudAuthConfigured, runtimeMode, isAuthenticated, workspaceCloudSyncEnabled, buildWorkspaceSyncSignature, pushWorkspaceChangesToCloud, workspacePendingSignatureRef, workspaceDeletedTaskIdsRef, workspaceDeletedTaskWatermarksRef, mutateTaskMetadata, mutateTaskStatus, mutateTaskLifecycle, mutateTaskDelete, mutateTaskRestore, durableTaskMetadataActivationEnabled = false, durableTaskStatusActivationEnabled = false, durableTaskDeleteActivationEnabled = false, durableTaskHttpRootActivationEnabled = false, workspaceId = 'default', taskHttpMutationClient, onTaskRevisionConflict, onTaskMutationAccepted, }) {
44
+ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, editingTaskDetailRevision = null, setTasks, setArchivedTasks, setDeletedTasks, setError, resetForm, setActiveTab, fetchTasks, fetchArchive, fetchDeletedTasks, mergeTaskFromServer, pushNotice, cloudAuthConfigured, runtimeMode, isAuthenticated, workspaceCloudSyncEnabled, buildWorkspaceSyncSignature, pushWorkspaceChangesToCloud, workspacePendingSignatureRef, workspaceDeletedTaskIdsRef, workspaceDeletedTaskWatermarksRef, mutateTaskMetadata, mutateTaskStatus, mutateTaskLifecycle, mutateTaskDelete, mutateTaskRestore, durableTaskMetadataActivationEnabled = false, durableTaskStatusActivationEnabled = false, durableTaskDeleteActivationEnabled = false, durableTaskHttpRootActivationEnabled = false, workspaceId = 'default', taskHttpMutationClient, onTaskRevisionConflict, onTaskMutationAccepted, pendingTaskMetadataOverlaysRef, }) {
45
45
  const authoritativeTaskSnapshotsRef = useRef(new Map());
46
46
  useEffect(() => {
47
47
  if (typeof window === 'undefined')
@@ -703,6 +703,18 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, editingT
703
703
  let hasLegacyCarriers = Object.keys(legacyCarrierPatch).length > 0;
704
704
  let durableMetadataHandled = false;
705
705
  if (hasDurableMetadata && mutateTaskMetadata) {
706
+ const pendingOverlay = {
707
+ patch: durableMetadataPatch,
708
+ observedUpdatedAt: observedTask?.updatedAt || null,
709
+ };
710
+ pendingTaskMetadataOverlaysRef?.current.set(id, pendingOverlay);
711
+ const clearPendingOverlay = () => {
712
+ if (pendingTaskMetadataOverlaysRef?.current.get(id) === pendingOverlay) {
713
+ pendingTaskMetadataOverlaysRef.current.delete(id);
714
+ }
715
+ };
716
+ const ownsPendingOverlay = () => (!pendingTaskMetadataOverlaysRef
717
+ || pendingTaskMetadataOverlaysRef.current.get(id) === pendingOverlay);
706
718
  try {
707
719
  const initialMutationOptions = {
708
720
  ...(saveSource ? { saveSource } : {}),
@@ -711,6 +723,8 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, editingT
711
723
  let durableResult = Object.keys(initialMutationOptions).length > 0
712
724
  ? await mutateTaskMetadata(id, durableMetadataPatch, initialMutationOptions)
713
725
  : await mutateTaskMetadata(id, durableMetadataPatch);
726
+ if (!ownsPendingOverlay())
727
+ return false;
714
728
  if (durableResult && durableResult.state !== 'disabled') {
715
729
  if ((durableResult.state === 'rejected' || durableResult.state === 'failed')
716
730
  && durableResult.errorCode === 'TASK_DETAIL_REVISION_CONFLICT') {
@@ -719,6 +733,8 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, editingT
719
733
  setTasks((currentTasks) => rollbackTargetTaskPatch(currentTasks, previousTask, id, updates));
720
734
  setArchivedTasks((currentTasks) => rollbackTargetTaskPatch(currentTasks, previousTask, id, updates));
721
735
  const resolution = await onTaskRevisionConflict?.(id, null);
736
+ if (!ownsPendingOverlay())
737
+ return false;
722
738
  if (resolution?.retryDetailRevision) {
723
739
  const reconciledPatch = resolution.retryPatch;
724
740
  const retryMetadataPatch = Object.fromEntries(Object.entries(durableMetadataPatch).map(([key, value]) => [
@@ -727,10 +743,13 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, editingT
727
743
  ? reconciledPatch[key]
728
744
  : value,
729
745
  ]));
746
+ pendingOverlay.patch = retryMetadataPatch;
730
747
  durableResult = await mutateTaskMetadata(id, retryMetadataPatch, {
731
748
  ...(saveSource ? { saveSource } : {}),
732
749
  expectedDetailRevision: resolution.retryDetailRevision,
733
750
  });
751
+ if (!ownsPendingOverlay())
752
+ return false;
734
753
  if (durableResult
735
754
  && (durableResult.state === 'rejected' || durableResult.state === 'failed')
736
755
  && durableResult.errorCode === 'TASK_DETAIL_REVISION_CONFLICT') {
@@ -757,6 +776,7 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, editingT
757
776
  return false;
758
777
  }
759
778
  if (durableResult.state === 'rejected' || durableResult.state === 'failed') {
779
+ clearPendingOverlay();
760
780
  const previousTask = previousTasks.find((task) => task.id === id)
761
781
  || previousArchivedTasks.find((task) => task.id === id);
762
782
  setTasks((currentTasks) => rollbackTargetTaskPatch(currentTasks, previousTask, id, updates));
@@ -771,7 +791,15 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, editingT
771
791
  return false;
772
792
  }
773
793
  durableMetadataHandled = true;
774
- if ('task' in durableResult && durableResult.task) {
794
+ if ('task' in durableResult
795
+ && durableResult.task?.updatedAt
796
+ && pendingTaskMetadataOverlaysRef?.current.get(id) === pendingOverlay) {
797
+ pendingOverlay.observedUpdatedAt = durableResult.task.updatedAt;
798
+ }
799
+ if ('task' in durableResult
800
+ && durableResult.task
801
+ && (!pendingTaskMetadataOverlaysRef
802
+ || pendingTaskMetadataOverlaysRef.current.get(id) === pendingOverlay)) {
775
803
  mergeTaskFromServer(durableResult.task);
776
804
  onTaskMutationAccepted?.(durableResult.task);
777
805
  }
@@ -807,18 +835,24 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, editingT
807
835
  if (!hasLegacyCarriers)
808
836
  return true;
809
837
  }
810
- else if (durableTaskMetadataActivationEnabled) {
811
- const previousTask = previousTasks.find((task) => task.id === id)
812
- || previousArchivedTasks.find((task) => task.id === id);
813
- setTasks((currentTasks) => rollbackTargetTaskPatch(currentTasks, previousTask, id, updates));
814
- setArchivedTasks((currentTasks) => rollbackTargetTaskPatch(currentTasks, previousTask, id, updates));
815
- const message = 'Task was not saved because durable metadata capture was unavailable.';
816
- setError(message);
817
- pushNotice(message, 'error');
818
- return false;
838
+ else {
839
+ clearPendingOverlay();
840
+ if (durableTaskMetadataActivationEnabled) {
841
+ const previousTask = previousTasks.find((task) => task.id === id)
842
+ || previousArchivedTasks.find((task) => task.id === id);
843
+ setTasks((currentTasks) => rollbackTargetTaskPatch(currentTasks, previousTask, id, updates));
844
+ setArchivedTasks((currentTasks) => rollbackTargetTaskPatch(currentTasks, previousTask, id, updates));
845
+ const message = 'Task was not saved because durable metadata capture was unavailable.';
846
+ setError(message);
847
+ pushNotice(message, 'error');
848
+ return false;
849
+ }
819
850
  }
820
851
  }
821
852
  catch (error) {
853
+ if (!ownsPendingOverlay())
854
+ return false;
855
+ clearPendingOverlay();
822
856
  console.error('Durable task metadata update failed before a conclusive result.', error);
823
857
  if (hasLegacyCarriers) {
824
858
  const previousTask = previousTasks.find((task) => task.id === id)
@@ -926,7 +960,7 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, editingT
926
960
  setArchivedTasks((currentTasks) => rollbackTargetTaskPatch(currentTasks, previousTask, id, legacyCarrierPatch));
927
961
  return false;
928
962
  }
929
- }, [tasks, archivedTasks, editingTaskDetailRevision, editingTaskId, pushNotice, mergeTaskFromServer, mutateTaskMetadata, onTaskMutationAccepted, onTaskRevisionConflict, queueWorkspaceSyncFromAuthoritativeTaskState, handleSetStatus, durableTaskMetadataActivationEnabled, durableTaskStatusActivationEnabled, fetchCloudTaskRootPatch]);
963
+ }, [tasks, archivedTasks, editingTaskDetailRevision, editingTaskId, pushNotice, mergeTaskFromServer, mutateTaskMetadata, onTaskMutationAccepted, onTaskRevisionConflict, pendingTaskMetadataOverlaysRef, queueWorkspaceSyncFromAuthoritativeTaskState, handleSetStatus, durableTaskMetadataActivationEnabled, durableTaskStatusActivationEnabled, fetchCloudTaskRootPatch]);
930
964
  const handleToggleComplete = async (task) => {
931
965
  const newStatus = task.status === 'done' ? 'task' : 'done';
932
966
  await handleSetStatus(task, newStatus);
@@ -205,6 +205,8 @@ export declare function useTaskforce({ config, initialTaskId, initialActivityEnt
205
205
  phase: import("./sync/useLocalSyncCoordinatorSnapshot").LocalSyncCoordinatorSnapshotPhase;
206
206
  snapshot: import("../sync/coordinator/localSyncCoordinatorBrowserClient").LocalSyncCoordinatorStatusResponse | null;
207
207
  errorMessage: string | null;
208
+ activeCommandType: import("../sync/coordinator/localSyncCoordinatorTypes").LocalSyncCoordinatorCommandType | null;
209
+ activePriorityCommandType: import("../sync/coordinator/localSyncCoordinatorTypes").LocalSyncCoordinatorCommandType | null;
208
210
  } | null;
209
211
  transferLocalCoordinatorOwnership: (targetMode: "server" | "browser-gateway") => Promise<boolean>;
210
212
  retryUserGlobalSettingsSync: () => Promise<void>;
@@ -395,6 +395,9 @@ export function useTaskforce({ config = {}, initialTaskId, initialActivityEntryI
395
395
  const isCloudScopedPath = path.startsWith('/api/taskforce/auth/')
396
396
  || path.startsWith('/api/taskforce/account/')
397
397
  || path.startsWith('/api/taskforce/billing/')
398
+ || /^\/api\/taskforce\/model-connections(?:[/?]|$)/i.test(path)
399
+ || /^\/api\/taskforce\/agents\/model-catalog(?:\?|$)/i.test(path)
400
+ || /^\/api\/taskforce\/agents\/[^/]+\/connection-binding(?:\?|$)/i.test(path)
398
401
  || path.startsWith('/api/taskforce/sync/')
399
402
  || path.startsWith('/api/taskforce/settings/mcp/');
400
403
  if (!isCloudHost && isCloudScopedPath) {
@@ -883,6 +886,7 @@ export function useTaskforce({ config = {}, initialTaskId, initialActivityEntryI
883
886
  }, [AUTH_REQUIRED_ERROR, runtimeMode]);
884
887
  // === SECTION: Task Data ===
885
888
  // Delegated to useTaskData — see src/hooks/useTaskData.ts
889
+ const pendingTaskMetadataOverlaysRef = useRef(new Map());
886
890
  const { tasksRef, archivedTasksRef, taskDetails, staleTaskDetailRevisions, recentlyChangedTaskIds, markRecentlyChangedTasks, fetchTasks: fetchTasksBase, fetchArchive: fetchArchiveBase, loadTaskDetail, cancelTaskDetailLoad, refreshTaskCollections: refreshTaskCollectionsBase, refreshTaskCollectionsFromInvalidation: refreshTaskCollectionsFromInvalidationBase, mergeTaskFromServer, getTaskRevisionKey } = useTaskData({
887
891
  tasks,
888
892
  archivedTasks,
@@ -896,7 +900,8 @@ export function useTaskforce({ config = {}, initialTaskId, initialActivityEntryI
896
900
  handleUnauthorized,
897
901
  authRequiredForApi,
898
902
  setError,
899
- setLoading
903
+ setLoading,
904
+ pendingTaskMetadataOverlaysRef,
900
905
  });
901
906
  useEffect(() => {
902
907
  if (workspaceTransitionEpoch === 0)
@@ -918,6 +923,7 @@ export function useTaskforce({ config = {}, initialTaskId, initialActivityEntryI
918
923
  deletedHydrationRequestRef.current = null;
919
924
  setTasks([]);
920
925
  setArchivedTasks([]);
926
+ pendingTaskMetadataOverlaysRef.current.clear();
921
927
  setInitiatives([]);
922
928
  setWorkstreams([]);
923
929
  setPlanningBootstrapTaskSummaries([]);
@@ -1363,7 +1369,7 @@ export function useTaskforce({ config = {}, initialTaskId, initialActivityEntryI
1363
1369
  const setUserGlobalSyncErrorRef = useRef(() => undefined);
1364
1370
  const checkAuthSessionImplRef = useRef(async () => false);
1365
1371
  const checkAuthSession = useCallback((options) => checkAuthSessionImplRef.current(options), []);
1366
- const { userGlobalSyncStatus, setUserGlobalSyncStatus, userGlobalSyncError, setUserGlobalSyncError, workspaceLastPullAt, workspaceLastPushAt, workspaceLastErrorAt, workspaceLastErrorMessage, workspaceLastSuccessfulSyncAt, workspaceCloudSyncEnabled, workspaceSyncPhase, workspaceSyncSetupIntent, workspaceSyncStatus, workspaceSyncSummary, workspaceSyncRecommendedAction, workspaceSyncBusy, workspaceSyncPendingChanges, workspaceTaskRelationships, localCoordinatorDataVersion, localCoordinatorStatus, switchLocalCoordinatorWorkspace, transferLocalCoordinatorOwnership, workspacePushInFlightRef, workspacePullInFlightRef, workspaceLastPushedSignatureRef, workspacePendingSignatureRef, workspaceLastPushedTaskIdsRef, workspaceDeletedTaskIdsRef, workspaceDeletedTaskWatermarksRef, workspacePullCursorRef, clearWorkspaceRetry, persistWorkspaceSyncPatch, loadWorkspaceSyncState, applyWorkspaceSyncStateSnapshot, syncUserGlobalSettings, buildWorkspaceSyncSignature, pushWorkspaceChangesToCloud, saveWorkspaceCloudSyncSettings, retryUserGlobalSettingsSync, retryWorkspaceCloudSync, resetWorkspaceSyncCursorAndPull, getWorkspaceSyncDiagnostics } = useSyncOrchestrator({
1372
+ const { userGlobalSyncStatus, setUserGlobalSyncStatus, userGlobalSyncError, setUserGlobalSyncError, workspaceLastPullAt, workspaceLastPushAt, workspaceLastErrorAt, workspaceLastErrorMessage, workspaceLastSuccessfulSyncAt, workspaceCloudSyncEnabled, workspaceSyncPhase, workspaceSyncSetupIntent, workspaceSyncStatus, workspaceSyncSummary, workspaceSyncRecommendedAction, workspaceSyncBusy, workspaceSyncPendingChanges, workspaceTaskRelationships, localCoordinatorDataVersion, localCoordinatorStatus, switchLocalCoordinatorWorkspace, transferLocalCoordinatorOwnership, clearLocalCoordinatorCredential, workspacePushInFlightRef, workspacePullInFlightRef, workspaceLastPushedSignatureRef, workspacePendingSignatureRef, workspaceLastPushedTaskIdsRef, workspaceDeletedTaskIdsRef, workspaceDeletedTaskWatermarksRef, workspacePullCursorRef, clearWorkspaceRetry, persistWorkspaceSyncPatch, loadWorkspaceSyncState, applyWorkspaceSyncStateSnapshot, syncUserGlobalSettings, buildWorkspaceSyncSignature, pushWorkspaceChangesToCloud, saveWorkspaceCloudSyncSettings, retryUserGlobalSettingsSync, retryWorkspaceCloudSync, resetWorkspaceSyncCursorAndPull, getWorkspaceSyncDiagnostics } = useSyncOrchestrator({
1367
1373
  currentWorkspaceId,
1368
1374
  cloudAuthConfigured,
1369
1375
  runtimeMode,
@@ -2769,6 +2775,7 @@ export function useTaskforce({ config = {}, initialTaskId, initialActivityEntryI
2769
2775
  }, [abortWorkspaceScopedRequests, resetPersistedUiStateLoad, setArchivedTasks, setTasks]);
2770
2776
  const logout = useCallback(async () => {
2771
2777
  try {
2778
+ await clearLocalCoordinatorCredential().catch(() => false);
2772
2779
  if (cloudAuthConfigured) {
2773
2780
  await fetch(resolveCloudAuthUrl('/api/taskforce/auth/logout'), {
2774
2781
  method: 'POST',
@@ -2826,6 +2833,7 @@ export function useTaskforce({ config = {}, initialTaskId, initialActivityEntryI
2826
2833
  }, [
2827
2834
  abortWorkspaceScopedRequests,
2828
2835
  authRequiredForApi,
2836
+ clearLocalCoordinatorCredential,
2829
2837
  clearPersistedWorkspaceId,
2830
2838
  commitCurrentWorkspaceId,
2831
2839
  resolveCloudAuthUrl,
@@ -3999,6 +4007,7 @@ export function useTaskforce({ config = {}, initialTaskId, initialActivityEntryI
3999
4007
  workspaceId: currentWorkspaceId,
4000
4008
  onTaskRevisionConflict: handleTaskRevisionConflict,
4001
4009
  onTaskMutationAccepted: handleTaskMutationAccepted,
4010
+ pendingTaskMetadataOverlaysRef,
4002
4011
  });
4003
4012
  const { resolveDraft: resolveDescriptionImageDraft } = useTaskDescriptionImageDraftRecovery(currentWorkspaceId, authUserId);
4004
4013
  const promoteDescriptionImageDraft = useCallback(async () => {
@@ -1,11 +1,11 @@
1
1
  import type { AiProfileSurfaceType } from '../shared/aiProfileSurfaceType.js';
2
+ import type { ProductLogoKey } from '../shared/productLogoKeys.js';
2
3
  export declare const MCP_CLIENT_IDS: readonly ["general", "cursor", "cline", "vscode", "kiro", "windsurf", "antigravity", "openclaw", "codex", "grok", "claude-code", "gemini-cli", "grok-chat", "gemini-chat", "mistral-chat", "perplexity-chat", "claude-chat", "chatgpt-desktop"];
3
4
  export type McpClientId = typeof MCP_CLIENT_IDS[number];
4
- export type McpClientLogoKey = Exclude<McpClientId, 'general' | 'openclaw'>;
5
5
  export interface McpClientRegistryEntry {
6
6
  id: McpClientId;
7
7
  label: string;
8
- logoKey?: McpClientLogoKey;
8
+ logoKey?: ProductLogoKey;
9
9
  surfaceHint?: AiProfileSurfaceType;
10
10
  generatedOption?: boolean;
11
11
  signatureColor?: string;
@@ -36,7 +36,7 @@ export const MCP_CLIENT_REGISTRY = {
36
36
  openclaw: { id: 'openclaw', label: 'OpenClaw', surfaceHint: 'agent', generatedOption: true },
37
37
  vscode: { id: 'vscode', label: 'VS Code / Copilot', logoKey: 'vscode', surfaceHint: 'ide', generatedOption: true, signatureColor: '#256ee4' },
38
38
  windsurf: { id: 'windsurf', label: 'Windsurf', logoKey: 'windsurf', surfaceHint: 'ide', generatedOption: true, signatureColor: '#189587' },
39
- 'chatgpt-desktop': { id: 'chatgpt-desktop', label: 'ChatGPT Desktop', logoKey: 'chatgpt-desktop', surfaceHint: 'chat_app', signatureColor: '#10a37f' },
39
+ 'chatgpt-desktop': { id: 'chatgpt-desktop', label: 'ChatGPT Desktop', logoKey: 'chatgpt', surfaceHint: 'chat_app', signatureColor: '#10a37f' },
40
40
  };
41
41
  export function parseMcpClientId(value) {
42
42
  const normalized = String(value || '').trim().toLowerCase();
@@ -460,14 +460,14 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
460
460
  },
461
461
  }));
462
462
  register('review_document', (context) => ({
463
- description: context.describeTool('Create or reuse a review session for one document and append review comments. Use this for plan and document reviews.'),
463
+ description: context.describeTool('Add document review comments, reply to a root thread, or resolve/reopen a thread. Reply/thread modes require sessionId and are exclusive.'),
464
464
  inputSchema: {
465
465
  properties: {
466
- documentId: stringProperty('Document asset id or document reference such as D-123.'),
467
- sessionId: stringProperty('Optional existing review session id.'),
468
- title: stringProperty('Optional review session title when a new session is created.'),
469
- prompt: stringProperty('Review instructions or focus areas.'),
470
- comments: arrayProperty('Explicit review comments to add. When omitted, prompt is saved as a single review comment.', {
466
+ documentId: stringProperty('D-123 or asset id.'),
467
+ sessionId: stringProperty('Existing review session id.'),
468
+ title: stringProperty('New-session title.'),
469
+ prompt: stringProperty('Single comment.'),
470
+ comments: arrayProperty('Comments; prompt can supply one.', {
471
471
  type: 'object',
472
472
  properties: {
473
473
  body: { type: 'string' },
@@ -475,6 +475,9 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
475
475
  },
476
476
  required: ['body'],
477
477
  }),
478
+ parentCommentId: stringProperty('Root id for an unanchored reply.'),
479
+ threadCommentId: stringProperty('Root id to resolve or reopen.'),
480
+ threadStatus: stringProperty('Thread status.', ['open', 'resolved']),
478
481
  },
479
482
  },
480
483
  }));
@@ -6,6 +6,7 @@ import { type LocalTaskStatusOutboxCore } from '../sync/v3/localTaskStatusOutbox
6
6
  import { type DurableTaskLifecycleServiceCore } from '../sync/v3/taskLifecycleMutationService.js';
7
7
  import { type DurableTaskStatusServiceCore } from '../sync/v3/taskStatusMutationService.js';
8
8
  import { type DurableTaskWorkflowServiceCore } from '../sync/v3/taskWorkflowMutationService.js';
9
+ import type { TaskStatusReviewHandoff } from '../sync/v3/workflowAssignmentSync.js';
9
10
  export type McpTaskStatusActivationCapability = {
10
11
  taskStatusMcpActivation: boolean;
11
12
  };
@@ -29,7 +30,9 @@ export type DurableTaskMutationRouter = {
29
30
  enabled: boolean;
30
31
  setStatus(args: {
31
32
  taskId: string;
32
- payload: DurableTaskStatusMutationPayload;
33
+ payload: DurableTaskStatusMutationPayload & {
34
+ reviewHandoff?: TaskStatusReviewHandoff;
35
+ };
33
36
  actorRef: string;
34
37
  }): DurableMcpTaskMutationResult;
35
38
  mutateLifecycle(args: {
@@ -7,6 +7,7 @@ import { runDurableTaskLifecycleMutation, } from '../sync/v3/taskLifecycleMutati
7
7
  import { runDurableTaskStatusMutation, } from '../sync/v3/taskStatusMutationService.js';
8
8
  import { runDurableTaskWorkflowMutation, } from '../sync/v3/taskWorkflowMutationService.js';
9
9
  import { readDurableOperationReplay } from '../sync/v3/durableOperationReplay.js';
10
+ import { areWorkflowRuntimeMutationsFenced, resolveWorkflowRuntimeDurableTransportCapability, } from '../sync/v3/durableWorkflowRuntimeMutationRouter.js';
10
11
  const OPERATION_LEASE_MS = 30_000;
11
12
  function isEnabled(value) {
12
13
  return /^(1|true|on|yes)$/i.test(String(value || '').trim());
@@ -70,6 +71,13 @@ export function createDurableTaskMutationRouter(input) {
70
71
  const identityStore = new LocalSyncIdentityStore(input.core.getDatabaseAdapter());
71
72
  const createOperationId = input.createOperationId || defaultOperationId;
72
73
  const now = input.now || (() => new Date());
74
+ const workflowRuntimeJournalEnabled = resolveWorkflowRuntimeDurableTransportCapability({
75
+ runtimeMode: input.runtimeMode,
76
+ surface: 'mcp',
77
+ env: input.env,
78
+ });
79
+ const rejectWorkflowRuntimeActivation = workflowRuntimeJournalEnabled
80
+ && areWorkflowRuntimeMutationsFenced(input.env);
73
81
  const operationContext = (enabled, mutationKind, taskId) => {
74
82
  if (!enabled)
75
83
  throw new DurableTaskMutationRouterDisabledError();
@@ -156,6 +164,8 @@ export function createDurableTaskMutationRouter(input) {
156
164
  const result = runDurableTaskStatusMutation({
157
165
  ...cloudCommon(taskId, actorRef, context, revisions),
158
166
  payload: args.payload,
167
+ includeWorkflowRuntimeJournal: workflowRuntimeJournalEnabled,
168
+ rejectWorkflowRuntimeActivation,
159
169
  });
160
170
  if (result.state === 'in_progress')
161
171
  throw new DurableTaskMutationRouterInProgressError(result.retryAt);
@@ -53,6 +53,10 @@ export function createDurableTaskRelationshipMutationRouter(input) {
53
53
  || persisted.mutationKind !== args.mutationKind)) {
54
54
  throw new Error('Operation identity is already assigned to another task relationship mutation.');
55
55
  }
56
+ if (persisted)
57
+ store.assertOutboxOperationIdentity(persisted, {
58
+ domain: 'task-relationship', entityId: canonical.id, mutationKind: args.mutationKind,
59
+ });
56
60
  if (!persisted && args.mutationKind === 'link' && current && !current.deletedAt) {
57
61
  return { state: 'noop', route: 'no-change', operationId: null, relationship: current, outcome: 'existing' };
58
62
  }
@@ -0,0 +1,10 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ import { type McpServerFactory } from '@modelcontextprotocol/server';
3
+ export declare function isModernMcpHttpRequest(req: IncomingMessage, parsedBody: unknown): Promise<boolean>;
4
+ export declare function handleModernMcpHttpRequest(input: {
5
+ req: IncomingMessage;
6
+ res: ServerResponse;
7
+ parsedBody: unknown;
8
+ factory: McpServerFactory;
9
+ onerror?: (error: Error) => void;
10
+ }): Promise<void>;
@@ -0,0 +1,19 @@
1
+ import { toNodeHandler, toWebRequest } from '@modelcontextprotocol/node';
2
+ import { createMcpHandler, isLegacyRequest, } from '@modelcontextprotocol/server';
3
+ export async function isModernMcpHttpRequest(req, parsedBody) {
4
+ const request = await toWebRequest(req, parsedBody);
5
+ return !(await isLegacyRequest(request, parsedBody));
6
+ }
7
+ export async function handleModernMcpHttpRequest(input) {
8
+ const handler = createMcpHandler(input.factory, {
9
+ legacy: 'reject',
10
+ responseMode: 'auto',
11
+ onerror: input.onerror,
12
+ });
13
+ try {
14
+ await toNodeHandler(handler, { onerror: input.onerror })(input.req, input.res, input.parsedBody);
15
+ }
16
+ finally {
17
+ await handler.close();
18
+ }
19
+ }
@@ -1,5 +1,5 @@
1
- import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
- import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
1
+ import { Client } from '@modelcontextprotocol/client';
2
+ import { StdioClientTransport } from '@modelcontextprotocol/client/stdio';
3
3
  export type LocalCliHealthState = 'healthy' | 'version-mismatch' | 'unusable';
4
4
  export interface LocalCliHealthResult {
5
5
  state: LocalCliHealthState;
@@ -3,8 +3,8 @@ import { constants as fsConstants, accessSync, readFileSync, statSync } from 'no
3
3
  import path from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
5
  import { promisify } from 'node:util';
6
- import { Client } from '@modelcontextprotocol/sdk/client/index.js';
7
- import { getDefaultEnvironment, StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
6
+ import { Client } from '@modelcontextprotocol/client';
7
+ import { getDefaultEnvironment, StdioClientTransport } from '@modelcontextprotocol/client/stdio';
8
8
  const execFileAsync = promisify(execFile);
9
9
  const DEFAULT_TIMEOUT_MS = 5_000;
10
10
  function stripAnsi(value) {
@@ -15,6 +15,7 @@ export interface LocalServiceProxyOptions {
15
15
  requestTimeoutMs?: number;
16
16
  onFatal?: (error: Error) => void;
17
17
  logError?: (message: string) => void;
18
+ sleep?: (delayMs: number) => Promise<void>;
18
19
  }
19
20
  export interface LocalServiceProxyRuntime {
20
21
  close(): Promise<void>;