@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
@@ -0,0 +1,129 @@
1
+ import { fetchTaskforceApi } from '../../../utils/taskforceApiClient.js';
2
+ export class ModelConnectionsApiError extends Error {
3
+ code;
4
+ status;
5
+ constructor(message, code, status) {
6
+ super(message);
7
+ this.code = code;
8
+ this.status = status;
9
+ this.name = 'ModelConnectionsApiError';
10
+ }
11
+ }
12
+ async function requestJson(path, init, context) {
13
+ const headers = new Headers(init?.headers || undefined);
14
+ if (init?.body)
15
+ headers.set('Content-Type', 'application/json');
16
+ const workspaceId = String(context.workspaceId || '').trim();
17
+ if (workspaceId && workspaceId !== 'default')
18
+ headers.set('x-taskforce-workspace-id', workspaceId);
19
+ const requestPath = context.resolveApiUrl?.(path) || path;
20
+ const response = await fetchTaskforceApi(requestPath, {
21
+ credentials: 'include',
22
+ ...init,
23
+ headers,
24
+ }, context.apiBaseUrl);
25
+ const payload = await response.json().catch(() => ({}));
26
+ if (!response.ok || payload.success === false) {
27
+ throw new ModelConnectionsApiError(String(payload.error || `Model connection request failed (${response.status}).`), payload.code, response.status);
28
+ }
29
+ return payload;
30
+ }
31
+ export async function listModelConnections(context) {
32
+ const payload = await requestJson('/api/taskforce/model-connections', undefined, context);
33
+ return Array.isArray(payload.connections) ? payload.connections : [];
34
+ }
35
+ export async function loadModelConnectionsSnapshot(context) {
36
+ const payload = await requestJson('/api/taskforce/model-connections', undefined, context);
37
+ return {
38
+ eligible: payload.eligible === true,
39
+ connections: Array.isArray(payload.connections) ? payload.connections : [],
40
+ };
41
+ }
42
+ export async function createOpenAiCodexConnection(context) {
43
+ const payload = await requestJson('/api/taskforce/model-connections', {
44
+ method: 'POST',
45
+ body: JSON.stringify({
46
+ providerKey: 'openai',
47
+ authenticationType: 'chatgpt_device_code',
48
+ }),
49
+ }, context);
50
+ if (!payload.connection)
51
+ throw new ModelConnectionsApiError('Model connection response was incomplete.');
52
+ return payload.connection;
53
+ }
54
+ export async function startDeviceCodeLogin(connectionId, context) {
55
+ const payload = await requestJson(`/api/taskforce/model-connections/${encodeURIComponent(connectionId)}/login`, { method: 'POST' }, context);
56
+ if (!payload.login)
57
+ throw new ModelConnectionsApiError('Device authorization response was incomplete.');
58
+ return payload.login;
59
+ }
60
+ export async function getDeviceCodeLogin(connectionId, sessionId, context) {
61
+ const payload = await requestJson(`/api/taskforce/model-connections/${encodeURIComponent(connectionId)}/login/${encodeURIComponent(sessionId)}`, undefined, context);
62
+ if (!payload.login)
63
+ throw new ModelConnectionsApiError('Device authorization response was incomplete.');
64
+ return payload.login;
65
+ }
66
+ export async function cancelDeviceCodeLogin(connectionId, sessionId, context) {
67
+ const payload = await requestJson(`/api/taskforce/model-connections/${encodeURIComponent(connectionId)}/login/${encodeURIComponent(sessionId)}/cancel`, { method: 'POST' }, context);
68
+ if (!payload.login)
69
+ throw new ModelConnectionsApiError('Device authorization response was incomplete.');
70
+ return payload.login;
71
+ }
72
+ async function runConnectionOperation(connectionId, operation, context) {
73
+ const payload = await requestJson(`/api/taskforce/model-connections/${encodeURIComponent(connectionId)}/${operation}`, { method: 'POST' }, context);
74
+ if (!payload.connection)
75
+ throw new ModelConnectionsApiError('Model connection response was incomplete.');
76
+ return payload.connection;
77
+ }
78
+ export const verifyModelConnection = (connectionId, context) => (runConnectionOperation(connectionId, 'verify', context));
79
+ export const refreshModelConnection = (connectionId, context) => (runConnectionOperation(connectionId, 'refresh', context));
80
+ export const disconnectModelConnection = (connectionId, context) => (runConnectionOperation(connectionId, 'disconnect', context));
81
+ export async function renameModelConnection(connectionId, displayName, context) {
82
+ const payload = await requestJson(`/api/taskforce/model-connections/${encodeURIComponent(connectionId)}`, {
83
+ method: 'PATCH',
84
+ body: JSON.stringify({ displayName }),
85
+ }, context);
86
+ if (!payload.connection)
87
+ throw new ModelConnectionsApiError('Model connection response was incomplete.');
88
+ return payload.connection;
89
+ }
90
+ export async function removeModelConnection(connectionId, context) {
91
+ await requestJson(`/api/taskforce/model-connections/${encodeURIComponent(connectionId)}`, { method: 'DELETE' }, context);
92
+ }
93
+ export async function inspectAgentConnectionBinding(agentId, context) {
94
+ const workspaceId = encodeURIComponent(String(context.workspaceId || '').trim());
95
+ const payload = await requestJson(`/api/taskforce/agents/${encodeURIComponent(agentId)}/connection-binding?workspaceId=${workspaceId}`, undefined, context);
96
+ return payload.binding || { bound: false, available: false, reasonCode: 'MODEL_CONNECTION_REQUIRED' };
97
+ }
98
+ export async function bindAgentConnection(agentId, connectionId, context) {
99
+ const payload = await requestJson(`/api/taskforce/agents/${encodeURIComponent(agentId)}/connection-binding`, {
100
+ method: 'PUT',
101
+ body: JSON.stringify({ workspaceId: context.workspaceId, connectionId }),
102
+ }, context);
103
+ if (!payload.binding)
104
+ throw new ModelConnectionsApiError('Agent connection response was incomplete.');
105
+ return payload.binding;
106
+ }
107
+ export async function clearAgentConnectionBinding(agentId, context) {
108
+ await requestJson(`/api/taskforce/agents/${encodeURIComponent(agentId)}/connection-binding`, {
109
+ method: 'DELETE',
110
+ body: JSON.stringify({ workspaceId: context.workspaceId }),
111
+ }, context);
112
+ }
113
+ export function modelConnectionFailureMessage(code, fallback = 'The connection needs to be authorized again.') {
114
+ switch (String(code || '').trim().toUpperCase()) {
115
+ case 'MODEL_CONNECTION_DEVICE_CODE_UNAVAILABLE':
116
+ return 'ChatGPT device authorization is unavailable for this account. Retry later or use another connection.';
117
+ case 'MODEL_CONNECTION_RATE_LIMITED':
118
+ return 'ChatGPT temporarily rate limited this connection. Wait a moment, then retry.';
119
+ case 'MODEL_CONNECTION_LOGIN_LIMIT_REACHED':
120
+ case 'MODEL_CONNECTION_LOGIN_CAPACITY_REACHED':
121
+ return 'Device authorization capacity is temporarily full. Wait a moment, then retry.';
122
+ case 'MODEL_CONNECTION_LOGIN_CANCELLED':
123
+ return 'Device authorization was cancelled.';
124
+ case 'MODEL_CONNECTION_LEASE_LOST':
125
+ return 'The connection changed while authorization was running. Start again.';
126
+ default:
127
+ return fallback;
128
+ }
129
+ }
@@ -6,8 +6,8 @@ import { TASKFORCE_AGENT_SKILLS_MUTATED_EVENT, } from '../../../utils/taskforceA
6
6
  import taskforceStyles from '../../../Taskforce.module.css';
7
7
  import { loadAgentBehaviorCatalogs, } from './agentBehaviorCatalogApi.js';
8
8
  import styles from './AgentBehaviorAssignments.module.css';
9
- function revisionValue(reference) {
10
- return reference.resolution === 'pinned' ? String(reference.revision ?? '') : '';
9
+ function versionValue(reference) {
10
+ return reference.resolution === 'pinned' ? `revision:${String(reference.revision ?? '')}` : 'current';
11
11
  }
12
12
  function pinReference(reference, revision) {
13
13
  return {
@@ -45,6 +45,11 @@ function selectedRevision(value) {
45
45
  const numeric = Number(value);
46
46
  return Number.isInteger(numeric) && String(numeric) === value ? numeric : value;
47
47
  }
48
+ function referenceForVersion(reference, value) {
49
+ if (value === 'current')
50
+ return currentReference(reference);
51
+ return pinReference(reference, selectedRevision(value.slice('revision:'.length)));
52
+ }
48
53
  export function AgentBehaviorAssignments({ workspaceId, roleRef, skillRefs, onRoleRefChange, onSkillRefsChange, onManageRoles, onManageSkills, }) {
49
54
  const [roles, setRoles] = useState([]);
50
55
  const [skills, setSkills] = useState([]);
@@ -113,26 +118,18 @@ export function AgentBehaviorAssignments({ workspaceId, roleRef, skillRefs, onRo
113
118
  ...(roleRef.resolution === 'pinned'
114
119
  && selectedRole
115
120
  && !selectedRole.revisions.some((revision) => String(revision.revision) === String(roleRef.revision))
116
- ? [`Pinned Role revision ${String(roleRef.revision)} is unavailable.`]
121
+ ? [`Role version ${String(roleRef.revision)} is unavailable.`]
117
122
  : []),
118
123
  ]
119
124
  : [];
120
125
  return (_jsxs("div", { className: styles.assignments, children: [_jsxs("section", { className: styles.section, "aria-labelledby": "agent-role-heading", children: [_jsxs("div", { className: styles.sectionHeader, children: [_jsxs("div", { className: styles.sectionHeading, children: [_jsx(BriefcaseBusiness, { size: 17 }), _jsxs("div", { children: [_jsx("strong", { id: "agent-role-heading", children: "Role" }), _jsx("small", { children: "Optional reusable professional profile. An Agent can have one Role." })] })] }), _jsx("button", { type: "button", className: taskforceStyles.secondaryHeaderBtn, onClick: onManageRoles, children: "Manage Roles" })] }), _jsxs("div", { className: styles.roleControls, children: [_jsxs("label", { className: taskforceStyles.field, children: [_jsx("span", { className: taskforceStyles.label, children: "Role" }), _jsxs("select", { className: taskforceStyles.select, "aria-label": "Role", value: roleRef?.id || '', disabled: loading, onChange: (event) => {
121
126
  const id = event.target.value;
122
127
  onRoleRefChange(id ? { id, resolution: 'current' } : null);
123
- }, children: [_jsx("option", { value: "", children: "No Role" }), roleRef && !selectedRole ? (_jsxs("option", { value: roleRef.id, children: ["Missing Role \u00B7 ", roleRef.id] })) : null, roles.map((role) => (_jsxs("option", { value: role.id, disabled: role.lifecycleStatus === 'retired', children: [role.definition.name, role.lifecycleStatus === 'retired' ? ' · Retired' : ''] }, role.id)))] })] }), _jsxs("label", { className: taskforceStyles.field, children: [_jsx("span", { className: taskforceStyles.label, children: "Version" }), _jsxs("select", { className: taskforceStyles.select, "aria-label": "Role version", value: roleRef?.resolution || 'current', disabled: !roleRef || !selectedRole, onChange: (event) => {
124
- if (!roleRef || !selectedRole)
125
- return;
126
- if (event.target.value === 'current') {
127
- onRoleRefChange(currentReference(roleRef));
128
- return;
129
- }
130
- onRoleRefChange(pinReference(roleRef, selectedRole.currentRevision));
131
- }, children: [_jsx("option", { value: "current", children: "Use latest" }), _jsx("option", { value: "pinned", children: "Pin revision" })] })] }), _jsxs("label", { className: taskforceStyles.field, children: [_jsx("span", { className: taskforceStyles.label, children: "Revision" }), _jsxs("select", { className: taskforceStyles.select, "aria-label": "Role pinned revision", value: roleRef ? revisionValue(roleRef) : '', disabled: !roleRef || roleRef.resolution !== 'pinned', onChange: (event) => {
128
+ }, children: [_jsx("option", { value: "", children: "No Role" }), roleRef && !selectedRole ? (_jsxs("option", { value: roleRef.id, children: ["Missing Role \u00B7 ", roleRef.id] })) : null, roles.map((role) => (_jsxs("option", { value: role.id, disabled: role.lifecycleStatus === 'retired', children: [role.definition.name, role.lifecycleStatus === 'retired' ? ' · Retired' : ''] }, role.id)))] })] }), _jsxs("label", { className: taskforceStyles.field, children: [_jsx("span", { className: taskforceStyles.label, children: "Version" }), _jsxs("select", { className: taskforceStyles.select, "aria-label": "Role version", value: roleRef ? versionValue(roleRef) : 'current', disabled: !roleRef || !selectedRole, onChange: (event) => {
132
129
  if (!roleRef)
133
130
  return;
134
- onRoleRefChange(pinReference(roleRef, selectedRevision(event.target.value)));
135
- }, children: [_jsx("option", { value: "", children: "Current" }), roleRef ? availableRevisions(selectedRole, roleRef).map((revision) => (_jsxs("option", { value: revision, children: ["Revision ", revision] }, revision))) : null] })] })] }), selectedRole?.definition.shortDescription ? (_jsx("small", { className: styles.empty, children: selectedRole.definition.shortDescription })) : null, roleIssues.map((message) => (_jsxs("div", { className: styles.issue, role: "alert", children: [_jsx(AlertTriangle, { size: 13 }), _jsxs("span", { children: [message, " Agent execution is blocked until this reference is repaired."] })] }, message)))] }), _jsxs("section", { className: styles.section, "aria-labelledby": "agent-skills-heading", children: [_jsxs("div", { className: styles.sectionHeader, children: [_jsxs("div", { className: styles.sectionHeading, children: [_jsx(Sparkles, { size: 17 }), _jsxs("div", { children: [_jsx("strong", { id: "agent-skills-heading", children: "Skills" }), _jsx("small", { children: "Composable behavior applied in this exact order. Later Skills take precedence when guidance conflicts." })] })] }), _jsx("button", { type: "button", className: taskforceStyles.secondaryHeaderBtn, onClick: onManageSkills, children: "Manage Skills" })] }), _jsxs("div", { className: styles.skillAdd, children: [_jsxs("label", { className: taskforceStyles.field, children: [_jsx("span", { className: taskforceStyles.label, children: "Add Skill" }), _jsxs("select", { className: taskforceStyles.select, "aria-label": "Skill to add", value: skillToAdd, disabled: loading || activeSkillsToAdd.length === 0, onChange: (event) => setSkillToAdd(event.target.value), children: [_jsx("option", { value: "", children: "Select a Skill" }), activeSkillsToAdd.map((skill) => (_jsx("option", { value: skill.id, children: skill.definition.name }, skill.id)))] })] }), _jsx("button", { type: "button", className: "tf-control-icon", disabled: !skillToAdd, "aria-label": "Add selected Skill", title: "Add selected Skill", onClick: () => {
131
+ onRoleRefChange(referenceForVersion(roleRef, event.target.value));
132
+ }, children: [_jsx("option", { value: "current", children: selectedRole ? `Use latest (Version ${selectedRole.currentRevision})` : 'Use latest' }), roleRef ? availableRevisions(selectedRole, roleRef).map((revision) => (_jsxs("option", { value: `revision:${String(revision)}`, children: ["Version ", revision] }, revision))) : null] })] })] }), selectedRole?.definition.shortDescription ? (_jsx("small", { className: styles.empty, children: selectedRole.definition.shortDescription })) : null, roleIssues.map((message) => (_jsxs("div", { className: styles.issue, role: "alert", children: [_jsx(AlertTriangle, { size: 13 }), _jsxs("span", { children: [message, " Agent execution is blocked until this reference is repaired."] })] }, message)))] }), _jsxs("section", { className: styles.section, "aria-labelledby": "agent-skills-heading", children: [_jsxs("div", { className: styles.sectionHeader, children: [_jsxs("div", { className: styles.sectionHeading, children: [_jsx(Sparkles, { size: 17 }), _jsxs("div", { children: [_jsx("strong", { id: "agent-skills-heading", children: "Skills" }), _jsx("small", { children: "Composable behavior applied in this exact order. Later Skills take precedence when guidance conflicts." })] })] }), _jsx("button", { type: "button", className: taskforceStyles.secondaryHeaderBtn, onClick: onManageSkills, children: "Manage Skills" })] }), _jsxs("div", { className: styles.skillAdd, children: [_jsxs("label", { className: taskforceStyles.field, children: [_jsx("span", { className: taskforceStyles.label, children: "Add Skill" }), _jsxs("select", { className: taskforceStyles.select, "aria-label": "Skill to add", value: skillToAdd, disabled: loading || activeSkillsToAdd.length === 0, onChange: (event) => setSkillToAdd(event.target.value), children: [_jsx("option", { value: "", children: "Select a Skill" }), activeSkillsToAdd.map((skill) => (_jsx("option", { value: skill.id, children: skill.definition.name }, skill.id)))] })] }), _jsx("button", { type: "button", className: "tf-control-icon", disabled: !skillToAdd, "aria-label": "Add selected Skill", title: "Add selected Skill", onClick: () => {
136
133
  if (!skillToAdd || selectedSkillIds.has(skillToAdd))
137
134
  return;
138
135
  onSkillRefsChange([...skillRefs, { id: skillToAdd, resolution: 'current' }]);
@@ -145,20 +142,14 @@ export function AgentBehaviorAssignments({ workspaceId, roleRef, skillRefs, onRo
145
142
  ...(reference.resolution === 'pinned'
146
143
  && skill
147
144
  && !skill.revisions.some((revision) => String(revision.revision) === String(reference.revision))
148
- ? [`Pinned Skill revision ${String(reference.revision)} is unavailable.`]
145
+ ? [`Skill version ${String(reference.revision)} is unavailable.`]
149
146
  : []),
150
147
  ];
151
- return (_jsxs("li", { children: [_jsxs("div", { className: styles.referenceRow, children: [_jsxs("div", { className: styles.referenceCopy, children: [_jsxs("strong", { children: [index + 1, ". ", skill?.definition.name || `Missing Skill · ${reference.id}`] }), _jsx("small", { children: skill?.definition.shortDescription || reference.id })] }), _jsxs("select", { className: taskforceStyles.select, "aria-label": `${skill?.definition.name || reference.id} version`, value: reference.resolution, disabled: !skill, onChange: (event) => {
152
- const next = [...skillRefs];
153
- next[index] = event.target.value === 'current'
154
- ? currentReference(reference)
155
- : pinReference(reference, skill?.revision || 1);
156
- onSkillRefsChange(next);
157
- }, children: [_jsx("option", { value: "current", children: "Use latest" }), _jsx("option", { value: "pinned", children: "Pin revision" })] }), _jsxs("select", { className: taskforceStyles.select, "aria-label": `${skill?.definition.name || reference.id} pinned revision`, value: revisionValue(reference), disabled: reference.resolution !== 'pinned', onChange: (event) => {
148
+ return (_jsxs("li", { children: [_jsxs("div", { className: styles.referenceRow, children: [_jsxs("div", { className: styles.referenceCopy, children: [_jsxs("strong", { children: [index + 1, ". ", skill?.definition.name || `Missing Skill · ${reference.id}`] }), _jsx("small", { children: skill?.definition.shortDescription || reference.id })] }), _jsxs("select", { className: taskforceStyles.select, "aria-label": `${skill?.definition.name || reference.id} version`, value: versionValue(reference), disabled: !skill, onChange: (event) => {
158
149
  const next = [...skillRefs];
159
- next[index] = pinReference(reference, selectedRevision(event.target.value));
150
+ next[index] = referenceForVersion(reference, event.target.value);
160
151
  onSkillRefsChange(next);
161
- }, children: [_jsx("option", { value: "", children: "Current" }), availableRevisions(skill, reference).map((revision) => (_jsxs("option", { value: revision, children: ["Revision ", revision] }, revision)))] }), _jsxs("div", { className: styles.rowActions, children: [_jsx("button", { type: "button", className: "tf-control-icon tf-control-icon-compact", "aria-label": `Move ${skill?.definition.name || reference.id} up`, disabled: index === 0, onClick: () => {
152
+ }, children: [_jsx("option", { value: "current", children: skill ? `Use latest (Version ${skill.revision})` : 'Use latest' }), availableRevisions(skill, reference).map((revision) => (_jsxs("option", { value: `revision:${String(revision)}`, children: ["Version ", revision] }, revision)))] }), _jsxs("div", { className: styles.rowActions, children: [_jsx("button", { type: "button", className: "tf-control-icon tf-control-icon-compact", "aria-label": `Move ${skill?.definition.name || reference.id} up`, disabled: index === 0, onClick: () => {
162
153
  if (index === 0)
163
154
  return;
164
155
  const next = [...skillRefs];
@@ -1,5 +1,5 @@
1
1
  import { type AgentDefinitionV1, type BehaviorReference } from '../../shared/taskforceAgentDefinition.js';
2
- import { type TaskforceAgentProviderKey } from '../../shared/taskforceAgentModels.js';
2
+ import { type TaskforceAgentProviderKey, type TaskforceAgentConnectionScope } from '../../shared/taskforceAgentModels.js';
3
3
  import type { ModelGatewayTier } from '../../services/modelGateway.js';
4
4
  export declare const PERSONALITY_PRESETS: readonly [{
5
5
  readonly key: "practical";
@@ -104,6 +104,7 @@ export declare function buildTaskforceAgentDefinitionFromDraft(input: {
104
104
  providerKey: TaskforceAgentProviderKey;
105
105
  modelKey: string;
106
106
  tier: ModelGatewayTier;
107
+ connectionScope?: TaskforceAgentConnectionScope;
107
108
  }): AgentDefinitionV1;
108
109
  export declare function hasUnsavedAvatarPresentation(definition: AgentDefinitionV1 | null | undefined, draft: TaskforceAgentEditorDraft): boolean;
109
110
  export {};
@@ -107,7 +107,9 @@ export function buildTaskforceAgentDefinitionFromDraft(input) {
107
107
  modelKey: input.modelKey,
108
108
  modelSource: selectedModel?.source || 'bedrock',
109
109
  tier: input.tier,
110
- ...(selectedModel?.source === 'subscription_dev' ? { connectionScope: 'local_dev' } : {}),
110
+ ...(selectedModel?.source === 'subscription_dev'
111
+ ? { connectionScope: input.connectionScope || 'local_dev' }
112
+ : {}),
111
113
  },
112
114
  behavior: {
113
115
  ...(personality ? { personality } : {}),
@@ -14,7 +14,7 @@ export declare function getTaskWorkflowAssignment(taskId: string, context?: Work
14
14
  export type WorkflowCompletionProjection = {
15
15
  executionId: string;
16
16
  taskId: string;
17
- assignmentSnapshot: unknown;
17
+ assignmentSnapshot: WorkflowAssignmentDetails;
18
18
  taskSnapshot?: TaskItem | null;
19
19
  taskAuthoritative?: unknown;
20
20
  };
@@ -80,6 +80,9 @@ export async function completeCurrentWorkflowStep(executionId, idempotencyKey, c
80
80
  taskId: payload.result.taskSnapshot.id,
81
81
  reason: 'workflow-step',
82
82
  ...(installedTask ? { authoritativeTask: installedTask } : {}),
83
+ ...(payload.result.assignmentSnapshot
84
+ ? { authoritativeWorkflowAssignment: payload.result.assignmentSnapshot }
85
+ : {}),
83
86
  });
84
87
  }
85
88
  return payload.result;
@@ -11,6 +11,40 @@ const NO_WORKFLOW = '__none__';
11
11
  function statusLabel(status) {
12
12
  return status.charAt(0).toUpperCase() + status.slice(1);
13
13
  }
14
+ function workflowAssignmentFromMutation(value, taskId) {
15
+ if (!value || typeof value !== 'object' || Array.isArray(value))
16
+ return null;
17
+ const assignment = value;
18
+ if (!assignment.execution
19
+ || assignment.execution.taskId !== taskId
20
+ || !assignment.template
21
+ || !assignment.version
22
+ || !Array.isArray(assignment.steps)
23
+ || !Array.isArray(assignment.events))
24
+ return null;
25
+ return assignment;
26
+ }
27
+ function latestWorkflowEventSequence(assignment) {
28
+ return Math.max(0, ...(assignment?.events || []).map((event) => event.sequenceNumber || 0));
29
+ }
30
+ function workflowExecutionCreatedAt(assignment) {
31
+ const timestamp = Date.parse(assignment.execution.createdAt);
32
+ return Number.isFinite(timestamp) ? timestamp : 0;
33
+ }
34
+ function newerWorkflowAssignment(current, candidate) {
35
+ if (!candidate)
36
+ return current;
37
+ if (!current)
38
+ return candidate;
39
+ if (current.execution.id !== candidate.execution.id) {
40
+ return workflowExecutionCreatedAt(candidate) > workflowExecutionCreatedAt(current)
41
+ ? candidate
42
+ : current;
43
+ }
44
+ return latestWorkflowEventSequence(candidate) >= latestWorkflowEventSequence(current)
45
+ ? candidate
46
+ : current;
47
+ }
14
48
  export function TaskWorkflowAssignmentField({ taskId, workspaceId, taskStatus, taskUpdatedAt, comments = [], assigneeOptions = [], currentActorId, apiBaseUrl, runtimeMode = 'local', disabled = false, onActivatePendingWorkflow, onActiveOwnerChange, }) {
15
49
  const [workflows, setWorkflows] = React.useState([]);
16
50
  const [assignment, setAssignment] = React.useState(null);
@@ -21,6 +55,7 @@ export function TaskWorkflowAssignmentField({ taskId, workspaceId, taskStatus, t
21
55
  const [activationRetryToken, setActivationRetryToken] = React.useState(0);
22
56
  const [error, setError] = React.useState('');
23
57
  const requestGenerationRef = React.useRef(0);
58
+ const assignmentRefreshGenerationRef = React.useRef(0);
24
59
  const activationAttemptRef = React.useRef(null);
25
60
  const refreshedTaskRevisionRef = React.useRef({
26
61
  taskId,
@@ -29,6 +64,7 @@ export function TaskWorkflowAssignmentField({ taskId, workspaceId, taskStatus, t
29
64
  const requestContext = React.useMemo(() => ({ workspaceId, apiBaseUrl, runtimeMode }), [apiBaseUrl, runtimeMode, workspaceId]);
30
65
  React.useEffect(() => {
31
66
  const requestGeneration = ++requestGenerationRef.current;
67
+ const assignmentRefreshGeneration = ++assignmentRefreshGenerationRef.current;
32
68
  setLoading(true);
33
69
  setAssigning(false);
34
70
  setCompletingStep(false);
@@ -47,18 +83,23 @@ export function TaskWorkflowAssignmentField({ taskId, workspaceId, taskStatus, t
47
83
  if (workflowResult.status === 'fulfilled') {
48
84
  setWorkflows(workflowResult.value.filter((summary) => (summary.template.status === 'active' && Boolean(summary.latestPublishedVersion))));
49
85
  }
50
- if (assignmentResult.status === 'fulfilled') {
51
- setAssignment(assignmentResult.value);
52
- }
53
- if (assignmentResult.status === 'rejected') {
54
- setError(String(assignmentResult.reason?.message || 'Unable to load workflow assignment.'));
55
- }
56
- else if (!assignmentResult.value && workflowResult.status === 'rejected') {
57
- setError(String(workflowResult.reason?.message || 'Unable to load workflows.'));
86
+ if (assignmentRefreshGeneration === assignmentRefreshGenerationRef.current) {
87
+ if (assignmentResult.status === 'fulfilled') {
88
+ setAssignment(assignmentResult.value);
89
+ if (!assignmentResult.value && workflowResult.status === 'rejected') {
90
+ setError(String(workflowResult.reason?.message || 'Unable to load workflows.'));
91
+ }
92
+ }
93
+ else {
94
+ setError(String(assignmentResult.reason?.message || 'Unable to load workflow assignment.'));
95
+ }
58
96
  }
59
97
  setLoading(false);
60
98
  });
61
- return () => { requestGenerationRef.current += 1; };
99
+ return () => {
100
+ requestGenerationRef.current += 1;
101
+ assignmentRefreshGenerationRef.current += 1;
102
+ };
62
103
  }, [requestContext, taskId]);
63
104
  const latestAssignment = assignment?.execution.taskId === taskId ? assignment : null;
64
105
  const hasActiveExecution = latestAssignment
@@ -186,13 +227,18 @@ export function TaskWorkflowAssignmentField({ taskId, workspaceId, taskStatus, t
186
227
  return;
187
228
  refreshedTaskRevisionRef.current = { taskId, revision: taskRevision };
188
229
  const requestGeneration = requestGenerationRef.current;
230
+ const assignmentRefreshGeneration = ++assignmentRefreshGenerationRef.current;
189
231
  void getTaskWorkflowAssignment(taskId, requestContext).then((nextAssignment) => {
190
232
  if (requestGeneration !== requestGenerationRef.current)
191
233
  return;
234
+ if (assignmentRefreshGeneration !== assignmentRefreshGenerationRef.current)
235
+ return;
192
236
  setAssignment(nextAssignment);
193
237
  }).catch((requestError) => {
194
238
  if (requestGeneration !== requestGenerationRef.current)
195
239
  return;
240
+ if (assignmentRefreshGeneration !== assignmentRefreshGenerationRef.current)
241
+ return;
196
242
  setError(String(requestError?.message || 'Unable to refresh workflow assignment.'));
197
243
  });
198
244
  }, [isPending, requestContext, taskId, taskStatus, taskUpdatedAt]);
@@ -210,15 +256,27 @@ export function TaskWorkflowAssignmentField({ taskId, workspaceId, taskStatus, t
210
256
  const eventTaskId = String(detail.taskId || '').trim();
211
257
  if (eventTaskId !== taskId)
212
258
  return;
213
- const requestGeneration = ++requestGenerationRef.current;
259
+ const authoritativeAssignment = workflowAssignmentFromMutation(detail.authoritativeWorkflowAssignment, taskId);
260
+ if (authoritativeAssignment) {
261
+ ++assignmentRefreshGenerationRef.current;
262
+ setAssignment((current) => newerWorkflowAssignment(current, authoritativeAssignment));
263
+ setError('');
264
+ return;
265
+ }
266
+ const requestGeneration = requestGenerationRef.current;
267
+ const assignmentRefreshGeneration = ++assignmentRefreshGenerationRef.current;
214
268
  void getTaskWorkflowAssignment(taskId, requestContext).then((nextAssignment) => {
215
269
  if (requestGeneration !== requestGenerationRef.current)
216
270
  return;
271
+ if (assignmentRefreshGeneration !== assignmentRefreshGenerationRef.current)
272
+ return;
217
273
  setAssignment(nextAssignment);
218
274
  setError('');
219
275
  }).catch((requestError) => {
220
276
  if (requestGeneration !== requestGenerationRef.current)
221
277
  return;
278
+ if (assignmentRefreshGeneration !== assignmentRefreshGenerationRef.current)
279
+ return;
222
280
  setError(String(requestError?.message || 'Unable to refresh workflow assignment.'));
223
281
  });
224
282
  };
@@ -41,7 +41,7 @@ import { DEFAULT_TYPE_VALUE } from '../../shared/taxonomyDefaults.js';
41
41
  import { getImageReferenceLabel } from '../../utils/imageReferences';
42
42
  import { TASK_DEEP_LINK_QUERY_KEYS } from '../../shared/taskDeepLinks';
43
43
  import { isPlanningEntityVisibleForScope, scopePlanningSummaries, scopeTasksToPlanningSelection } from './planningScope';
44
- import { buildReferenceMismatchSummaries, buildSyncDiagnosticsSummary, buildSyncEventRows, getActiveReferenceMismatchCount, resolveSyncStageLabel, resolveSyncStatusMeta, resolveHeaderSyncStatusMeta, } from '../../utils/syncStatusPresentation';
44
+ import { buildReferenceMismatchSummaries, buildSyncDiagnosticsSummary, buildSyncEventRows, getActiveReferenceMismatchCount, resolveSyncStageLabel, resolveSyncStatusMeta, resolveHeaderSyncStatusMeta, resolveEffectiveWorkspaceSyncDiagnostics, } from '../../utils/syncStatusPresentation';
45
45
  import { buildCustomTaxonomySortOptions } from '../../utils/taxonomySorting.js';
46
46
  import { getLocale, t } from '../../localization';
47
47
  import { getAnnotatedAttachmentContextIdentity, resolveAnnotatedAttachmentDetail, shouldApplyPersistedAnnotatedAttachmentContext, } from '../../utils/annotatedAttachments';
@@ -74,7 +74,7 @@ import { useRecentSyncEvents } from '../../hooks/sync/useRecentSyncEvents';
74
74
  import { useSyncStatusActions } from '../../hooks/sync/useSyncStatusActions';
75
75
  import { useSyncStatusControls } from '../../hooks/sync/useSyncStatusControls';
76
76
  import { toDateOnlyLocal, parseDateOnlyLocal, startOfWeek, getDayOffsetFromWeekStart, addDays, dateOnlyToIsoWeekKey, SCHEDULE_DAY_KEYS, SCHEDULE_DAY_LABELS, } from './panels/scheduleUtils';
77
- import { ANNOTATED_ATTACHMENTS_WORKSPACE_FEATURE_KEY, DOCUMENT_WORKSPACE_FEATURE_KEY, TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY, resolveAppGateAccessMap, } from '../../runtime/appGates';
77
+ import { ANNOTATED_ATTACHMENTS_WORKSPACE_FEATURE_KEY, DOCUMENT_WORKSPACE_FEATURE_KEY, TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY, resolveClientAppGateAccessMap, } from '../../runtime/appGates';
78
78
  // Heavy feature modules — lazy-loaded to reduce the initial app chunk size.
79
79
  const TaskSettings = React.lazy(() => import('../features/TaskSettings').then(m => ({ default: m.TaskSettings })));
80
80
  const AnnotatedAttachmentWorkspaceShell = React.lazy(() => import('../features/AnnotatedAttachmentWorkspace').then(m => ({ default: m.AnnotatedAttachmentWorkspaceShell })));
@@ -186,7 +186,7 @@ export function StandaloneLayout(props) {
186
186
  // clearFilters, // This was duplicated, removed one instance
187
187
  // activeTypes, // This was duplicated, removed one instance
188
188
  // Settings State & Props
189
- settingsModel, configLoaded, currentTheme, setCurrentTheme, pathSaved, saveSettings, keyShortcut, setKeyShortcut, globalWeekStartsOn, locale, jsonBackupEnabled, setJsonBackupEnabled, mcpHostRoot, setMcpHostRoot, settingsSection, setSettingsSection, runtimeMode, workspaceSwitchingEnabled, cloudAuthConfigured, authRequiredForApi, authBlocked, isAuthenticated, authUserId, authWorkspaceId, authUserEmail, authUserDisplayName, authUserAvatarUrl, authSessionResolved, realtimeSyncEnabled, realtimeSyncFlagSource, workspaceCloudSyncEnabled, workspaceSyncPhase, workspaceSyncStatus, workspaceSyncSummary, workspaceSyncRecommendedAction, workspaceSyncBusy, workspaceSyncPendingChanges, localCoordinatorStatus, transferLocalCoordinatorOwnership, saveWorkspaceCloudSyncSettings, pushNotice, userGlobalSyncStatus, workspaceLastSuccessfulSyncAt, workspaceLastPullAt, workspaceLastPushAt, workspaceLastErrorAt, userGlobalSyncError, workspaceLastErrorMessage, retryWorkspaceCloudSync, resetWorkspaceSyncCursorAndPull, getWorkspaceSyncDiagnostics, currentWorkspaceId, currentWorkspaceRole, availableWorkspaces, switchWorkspace, updateCurrentUserProfile, resolveCloudAuthUrl = resolveSameOriginTaskforcePath, logout, fetchLoginMethods, unlinkLoginMethod, addPasswordToAccount, changePassword, beginOAuthLogin, beginOAuthLink, availableAuthProviders, projectRoot, projectName, mcpScriptPath, serverHostRoot,
189
+ settingsModel, configLoaded, currentTheme, setCurrentTheme, pathSaved, saveSettings, keyShortcut, setKeyShortcut, globalWeekStartsOn, locale, jsonBackupEnabled, setJsonBackupEnabled, mcpHostRoot, setMcpHostRoot, settingsSection, setSettingsSection, runtimeMode, workspaceSwitchingEnabled, cloudAuthConfigured, authRequiredForApi, authBlocked, isAuthenticated, authUserId, authWorkspaceId, authUserEmail, authUserDisplayName, authUserAvatarUrl, authSessionResolved, realtimeSyncEnabled, realtimeSyncFlagSource, workspaceCloudSyncEnabled, workspaceSyncPhase, workspaceSyncStatus, workspaceSyncSummary, workspaceSyncRecommendedAction, workspaceSyncBusy, workspaceSyncPendingChanges, localCoordinatorStatus, transferLocalCoordinatorOwnership, saveWorkspaceCloudSyncSettings, pushNotice, userGlobalSyncStatus, workspaceLastSuccessfulSyncAt, workspaceLastPullAt, workspaceLastPushAt, workspaceLastErrorAt, userGlobalSyncError, workspaceLastErrorMessage, resetWorkspaceSyncCursorAndPull, getWorkspaceSyncDiagnostics, currentWorkspaceId, currentWorkspaceRole, availableWorkspaces, switchWorkspace, updateCurrentUserProfile, resolveCloudAuthUrl = resolveSameOriginTaskforcePath, logout, fetchLoginMethods, unlinkLoginMethod, addPasswordToAccount, changePassword, beginOAuthLogin, beginOAuthLink, availableAuthProviders, projectRoot, projectName, mcpScriptPath, serverHostRoot,
190
190
  // Browser Props
191
191
  showFolderBrowser, setShowFolderBrowser, folders, files, currentBrowsePath, fetchFolders, browserTarget, setBrowserTarget, handleSelectPath, handleAddPath, handleRemovePath,
192
192
  // Settings Managers
@@ -401,7 +401,7 @@ export function StandaloneLayout(props) {
401
401
  setRequestedAnnotatedTarget(null);
402
402
  setRequestedAnnotatedSessionId(null);
403
403
  }, [layoutStateWorkspaceKey]);
404
- const workspaceFeatureAccess = useMemo(() => props.config?.appGates || resolveAppGateAccessMap('production'), [props.config?.appGates]);
404
+ const workspaceFeatureAccess = useMemo(() => resolveClientAppGateAccessMap(props.config?.appGates, props.config?.cloudEnvironment), [props.config?.appGates, props.config?.cloudEnvironment]);
405
405
  const workspaceModules = useMemo(() => getWorkspaceModuleDefinitions({ featureAccess: workspaceFeatureAccess }), [workspaceFeatureAccess]);
406
406
  const resolvedWorkspaceModule = useMemo(() => resolveWorkspaceModule(activeWorkspaceModule, workspaceModules), [activeWorkspaceModule, workspaceModules]);
407
407
  const planningSurfaceVisible = planningDrawerOpen || resolvedWorkspaceModule === 'planning';
@@ -1805,9 +1805,15 @@ export function StandaloneLayout(props) {
1805
1805
  const effectiveWorkspaceCloudSyncEnabled = typeof serverCoordinatorSyncEnabled === 'boolean'
1806
1806
  ? serverCoordinatorSyncEnabled
1807
1807
  : workspaceCloudSyncEnabled;
1808
- const { showSyncStatusModal, showSyncEnableWarning, workspaceSyncError, syncControlBusy, openSyncStatusModal, closeSyncStatusModal, handleWorkspaceSyncToggle, cancelSyncEnableWarning, confirmSyncEnableWarning, } = useSyncStatusControls({
1808
+ const persistedSyncToggleIntent = localCoordinatorStatus?.activePriorityCommandType === 'DisableSync'
1809
+ ? 'disabling'
1810
+ : localCoordinatorStatus?.activeCommandType === 'EnableSync'
1811
+ ? 'enabling'
1812
+ : null;
1813
+ const { showSyncStatusModal, showSyncEnableWarning, workspaceSyncError, syncControlBusy, syncControlIntent, openSyncStatusModal, closeSyncStatusModal, handleWorkspaceSyncToggle, cancelSyncEnableWarning, confirmSyncEnableWarning, } = useSyncStatusControls({
1809
1814
  canManageWorkspaceSync,
1810
1815
  workspaceCloudSyncEnabled: effectiveWorkspaceCloudSyncEnabled,
1816
+ persistedToggleIntent: persistedSyncToggleIntent,
1811
1817
  saveWorkspaceCloudSyncSettings,
1812
1818
  });
1813
1819
  const currentWorkspaceLabel = useMemo(() => {
@@ -2742,8 +2748,19 @@ export function StandaloneLayout(props) {
2742
2748
  ]);
2743
2749
  const syncLastError = headerSyncPresentation.lastError;
2744
2750
  const [headerSyncStatus, setHeaderSyncStatus] = useState(headerSyncPresentation.status);
2751
+ const effectiveWorkspaceSyncDiagnostics = useMemo(() => resolveEffectiveWorkspaceSyncDiagnostics(workspaceSyncDiagnostics, localCoordinatorStatus?.phase === 'ready'
2752
+ && localCoordinatorStatus.snapshot?.state.ownershipMode === 'server'
2753
+ ? {
2754
+ recoveryObligations: coordinatorRecoveryObligations,
2755
+ outbox: localCoordinatorStatus.snapshot.workspace?.outbox || null,
2756
+ }
2757
+ : null), [
2758
+ coordinatorRecoveryObligations,
2759
+ localCoordinatorStatus,
2760
+ workspaceSyncDiagnostics,
2761
+ ]);
2745
2762
  const syncDiagnosticsSummary = useMemo(() => coordinatorSyncPresentation?.diagnostics
2746
- || buildSyncDiagnosticsSummary({ ...workspaceSyncDiagnostics, coordinatorRecoveryObligations }), [coordinatorSyncPresentation, workspaceSyncDiagnostics, coordinatorRecoveryObligations]);
2763
+ || buildSyncDiagnosticsSummary(effectiveWorkspaceSyncDiagnostics), [coordinatorSyncPresentation, effectiveWorkspaceSyncDiagnostics]);
2747
2764
  const { syncRecentEvents, syncRecentEventsLoading, syncRecentEventsError, syncEventsListRef, loadRecentSyncEvents, } = useRecentSyncEvents({
2748
2765
  isOpen: showSyncStatusModal,
2749
2766
  workspaceId: currentWorkspaceId,
@@ -2785,7 +2802,7 @@ export function StandaloneLayout(props) {
2785
2802
  formattedLastSyncTime: effectiveFormattedLastSyncTime,
2786
2803
  formattedLastPullTime: effectiveFormattedLastPullTime,
2787
2804
  formattedLastPushTime: effectiveFormattedLastPushTime,
2788
- workspaceSyncDiagnostics,
2805
+ workspaceSyncDiagnostics: effectiveWorkspaceSyncDiagnostics,
2789
2806
  workspaceSyncPendingChanges: effectivePendingLocalChanges,
2790
2807
  syncLastError,
2791
2808
  workspaceSyncPhase,
@@ -3760,18 +3777,6 @@ export function StandaloneLayout(props) {
3760
3777
  pushNotice,
3761
3778
  workspaceFeatureAccess,
3762
3779
  ]);
3763
- const handleOpenTaskforceAgentConversation = useCallback((agentId) => {
3764
- const normalizedAgentId = String(agentId || '').trim();
3765
- if (!normalizedAgentId)
3766
- return;
3767
- handleRememberTaskforceAgentSelection({
3768
- agentId: normalizedAgentId,
3769
- conversationId: taskforceAgentConversationByAgentId[normalizedAgentId] || null,
3770
- });
3771
- setTaskforceAgentsLaunchContext(null);
3772
- setTaskforceAgentPanelCollapsed(false);
3773
- setTaskforceAgentDrawerOpen(true);
3774
- }, [handleRememberTaskforceAgentSelection, taskforceAgentConversationByAgentId]);
3775
3780
  const handleOpenTaskforceAgentTaskContext = useCallback((taskId) => {
3776
3781
  handleOpenTaskById(taskId);
3777
3782
  setTaskModalFullscreen(false);
@@ -4293,7 +4298,7 @@ export function StandaloneLayout(props) {
4293
4298
  }, children: _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(PlansPage, { ...props, currentTheme: currentTheme, projectName: projectName, currentWorkspaceId: currentWorkspaceId, authUserId: authUserId, apiBaseUrl: apiBaseUrl, connectedEnvironmentSource: props.config?.cloudAuthBaseUrl || props.config?.apiBaseUrl || '', resolveCloudAuthUrl: resolveCloudAuthUrl, embedded: true, shellOwnsScroll: true, onAccountProfileSummaryChange: applyPlansAccountProfileSummary, onContinueToTaskforce: handlePlansBack, continueBusy: plansNavigationBusy }) }) })) : resolvedWorkspaceModule === 'planning' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(PlanningModule, { model: planningWorkspaceModel }) })] })) : resolvedWorkspaceModule === 'docs' && documentsWorkspaceEnabled ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(DocumentWorkspaceShell, { taskReferences: taskReferences, tasks: tasks, runtimeMode: runtimeMode, workspaceId: currentWorkspaceId, apiBaseUrl: props.config?.apiBaseUrl || '', cloudAuthBaseUrl: props.config?.cloudAuthBaseUrl || '', typeFilters: documentTypeFilters, attachmentFilters: documentAttachmentFilters, onTypeFiltersChange: setDocumentTypeFilters, onAttachmentFiltersChange: setDocumentAttachmentFilters, sortField: documentSortField, sortOrder: documentSortOrder, onSortFieldChange: setDocumentSortField, onSortOrderChange: setDocumentSortOrder, pinnedDocIds: documentPinnedDocIds, onPinnedDocIdsChange: setDocumentPinnedDocIds, searchQuery: documentSearchQuery, onSearchQueryChange: setDocumentSearchQuery, selectedDocId: documentSelectedDocId, onSelectedDocIdChange: setDocumentSelectedDocId, selectionReady: layoutUiStateReady, documentScrollByDocId: documentScrollByDocId, onDocumentScrollChange: handleDocumentScrollChange, documentListScrollTop: documentListScrollTop, onDocumentListScrollChange: handleDocumentListScrollChange, documentTrayOpen: documentTrayOpen, onCloseDocumentTray: () => setDocumentTrayOpen(false), requestedDocPath: requestedDocPath, requestedDocAssetId: requestedDocAssetId, onRequestedDocHandled: () => {
4294
4299
  setRequestedDocPath(null);
4295
4300
  setRequestedDocAssetId(null);
4296
- }, onBackToTask: handleBackToTaskFromDocument, enableTaskGeneration: true }) })] })) : resolvedWorkspaceModule === 'annotate' && annotatedAttachmentsWorkspaceEnabled ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AnnotatedAttachmentWorkspaceShell, { runtimeMode: runtimeMode, apiBaseUrl: props.config?.apiBaseUrl || '', cloudAuthBaseUrl: props.config?.cloudAuthBaseUrl || '', workspaceId: currentWorkspaceId, sessionLoadReady: annotatedWorkspaceReady, requestedTarget: scopedRequestedAnnotatedTarget, requestedSessionId: scopedRequestedAnnotatedSessionId, requestedOpenVersion: requestedAnnotatedOpenVersion, imageTrayOpen: imageTrayOpen, onCloseImageTray: () => setImageTrayOpen(false), resolveTaskReferenceLabel: resolveAnnotatedTaskReferenceLabel, resolveImageReferenceLabel: resolveAnnotatedImageReferenceLabel, onOpenTarget: handleAnnotatedAttachmentOpenTarget, onContextChange: handleAnnotatedAttachmentContextChange, viewportByContextKey: annotatedViewportByContextKey, onViewportChange: handleAnnotatedViewportChange, onBackToTask: handleBackToTaskFromAnnotatedAttachment }) })] })) : resolvedWorkspaceModule === 'workflowManager' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(WorkflowManagerModule, { workspaceId: currentWorkspaceId, libraryTrayOpen: workflowLibraryTrayOpen, onCloseLibraryTray: () => setWorkflowLibraryTrayOpen(false), assigneeOptions: assigneeOptions, theme: currentTheme, onUnsavedChangesChange: setWorkflowManagerHasUnsavedChanges }) })] })) : resolvedWorkspaceModule === 'taskforceAgents' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(TaskforceAgentsModule, { workspaceId: currentWorkspaceId, taskReferences: taskReferences, agentRosterTrayOpen: taskforceAgentRosterTrayOpen, onCloseAgentRosterTray: () => setTaskforceAgentRosterTrayOpen(false), runtimeMode: runtimeMode, cloudAuthConfigured: cloudAuthConfigured, authSessionResolved: authSessionResolved, isAuthenticated: isAuthenticated, resolveCloudAuthUrl: resolveCloudAuthUrl, theme: currentTheme, rememberedAgentId: taskforceAgentId, rememberedConversationId: taskforceAgentConversationId, rememberedConversationByAgentId: taskforceAgentConversationByAgentId, rememberedSelectionReady: uiStateReady, onRememberSelection: handleRememberTaskforceAgentSelection, onOpenConversation: handleOpenTaskforceAgentConversation }) })] })) : resolvedWorkspaceModule === 'aiProfiles' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AiProfilesModule, { workspaceId: currentWorkspaceId, runtimeMode: runtimeMode, cloudAuthConfigured: cloudAuthConfigured, authSessionResolved: authSessionResolved, isAuthenticated: isAuthenticated, cloudAiProfileSeatUsage: accountProfileSummary?.aiProfileSeatUsage ?? null, agentTrayOpen: agentTrayOpen, onCloseAgentTray: () => setAgentTrayOpen(false), resolveCloudAuthUrl: resolveCloudAuthUrl, theme: currentTheme, onNotice: pushNotice, mcpSettingsNode: _jsx(TaskSettings, { settingsModel: {
4301
+ }, onBackToTask: handleBackToTaskFromDocument, enableTaskGeneration: true }) })] })) : resolvedWorkspaceModule === 'annotate' && annotatedAttachmentsWorkspaceEnabled ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AnnotatedAttachmentWorkspaceShell, { runtimeMode: runtimeMode, apiBaseUrl: props.config?.apiBaseUrl || '', cloudAuthBaseUrl: props.config?.cloudAuthBaseUrl || '', workspaceId: currentWorkspaceId, sessionLoadReady: annotatedWorkspaceReady, requestedTarget: scopedRequestedAnnotatedTarget, requestedSessionId: scopedRequestedAnnotatedSessionId, requestedOpenVersion: requestedAnnotatedOpenVersion, imageTrayOpen: imageTrayOpen, onCloseImageTray: () => setImageTrayOpen(false), resolveTaskReferenceLabel: resolveAnnotatedTaskReferenceLabel, resolveImageReferenceLabel: resolveAnnotatedImageReferenceLabel, onOpenTarget: handleAnnotatedAttachmentOpenTarget, onContextChange: handleAnnotatedAttachmentContextChange, viewportByContextKey: annotatedViewportByContextKey, onViewportChange: handleAnnotatedViewportChange, onBackToTask: handleBackToTaskFromAnnotatedAttachment }) })] })) : resolvedWorkspaceModule === 'workflowManager' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(WorkflowManagerModule, { workspaceId: currentWorkspaceId, libraryTrayOpen: workflowLibraryTrayOpen, onCloseLibraryTray: () => setWorkflowLibraryTrayOpen(false), assigneeOptions: assigneeOptions, theme: currentTheme, onUnsavedChangesChange: setWorkflowManagerHasUnsavedChanges }) })] })) : resolvedWorkspaceModule === 'taskforceAgents' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(TaskforceAgentsModule, { workspaceId: currentWorkspaceId, taskReferences: taskReferences, agentRosterTrayOpen: taskforceAgentRosterTrayOpen, onCloseAgentRosterTray: () => setTaskforceAgentRosterTrayOpen(false), runtimeMode: runtimeMode, cloudAuthConfigured: cloudAuthConfigured, authSessionResolved: authSessionResolved, isAuthenticated: isAuthenticated, resolveCloudAuthUrl: resolveCloudAuthUrl, theme: currentTheme, rememberedAgentId: taskforceAgentId, rememberedConversationId: taskforceAgentConversationId, rememberedConversationByAgentId: taskforceAgentConversationByAgentId, rememberedSelectionReady: uiStateReady, onRememberSelection: handleRememberTaskforceAgentSelection }) })] })) : resolvedWorkspaceModule === 'aiProfiles' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AiProfilesModule, { workspaceId: currentWorkspaceId, runtimeMode: runtimeMode, cloudAuthConfigured: cloudAuthConfigured, authSessionResolved: authSessionResolved, isAuthenticated: isAuthenticated, cloudAiProfileSeatUsage: accountProfileSummary?.aiProfileSeatUsage ?? null, agentTrayOpen: agentTrayOpen, onCloseAgentTray: () => setAgentTrayOpen(false), resolveCloudAuthUrl: resolveCloudAuthUrl, theme: currentTheme, onNotice: pushNotice, mcpSettingsNode: _jsx(TaskSettings, { settingsModel: {
4297
4302
  ...settingsModel,
4298
4303
  initialSection: 'mcp',
4299
4304
  onOpenCloudAuth: openSharedLoginRoute
@@ -4476,13 +4481,9 @@ export function StandaloneLayout(props) {
4476
4481
  headers: teamAdminHeaders(),
4477
4482
  credentials: 'include'
4478
4483
  }));
4479
- }, onInviteEmailChange: setTeamInviteEmail, onInviteRoleChange: setTeamInviteRole, onInvitePermissionModeChange: setTeamInvitePermissionMode, onSubmitInvite: () => { void submitTeamInvite(); }, onLoadAuditPrevious: () => { void loadTeamAuditPage(teamAuditPage - 1); }, onLoadAuditNext: () => { void loadTeamAuditPage(teamAuditPage + 1); } }), _jsx(CreateWorkspaceConfirmModal, { isOpen: showCreateWorkspaceConfirm, theme: currentTheme, onClose: () => setShowCreateWorkspaceConfirm(false), onConfirm: () => openWorkspaceSetup({ intent: 'create-workspace' }) }), _jsx(SyncStatusModal, { isOpen: showSyncStatusModal, theme: currentTheme, currentWorkspaceLabel: currentWorkspaceLabel, syncStatus: headerSyncStatus, syncStatusMeta: syncStatusMeta, workspaceCloudSyncEnabled: effectiveWorkspaceCloudSyncEnabled, syncControlBusy: syncControlBusy, canManageWorkspaceSync: canManageWorkspaceSync, workspaceSyncSummary: headerSyncPresentation.summary, workspaceSyncRecommendedAction: headerSyncPresentation.recommendedAction, workspaceSyncRepairBusy: effectiveWorkspaceSyncRepairBusy, referenceMismatchCount: referenceMismatchCount, syncStageLabel: syncStageLabel, workspaceSyncPendingChanges: effectivePendingLocalChanges, incomingCloudChanges: coordinatorSyncPresentation?.incomingCloudChanges || 'Unknown', formattedLastSyncTime: effectiveFormattedLastSyncTime, formattedLastPullTime: effectiveFormattedLastPullTime, formattedLastPushTime: effectiveFormattedLastPushTime, syncLastError: syncLastError, activeReferenceMismatchSummaries: activeReferenceMismatchSummaries, syncDiagnosticsSummary: syncDiagnosticsSummary, syncEventRows: syncEventRows, syncEventsListRef: syncEventsListRef, workspaceSyncRepairQueued: workspaceSyncRepairQueued, workspaceSyncBusy: effectiveWorkspaceSyncBusy, workspaceSyncCopied: workspaceSyncCopied, coordinatorOwnershipMode: coordinatorOwnershipMode, coordinatorOwnershipTransferBusy: coordinatorOwnershipTransferBusy, coordinatorOwnershipTransferDisabled: coordinatorOwnershipTransferDisabled, onClose: closeSyncStatusModal, onToggleWorkspaceSync: (enabled) => {
4484
+ }, onInviteEmailChange: setTeamInviteEmail, onInviteRoleChange: setTeamInviteRole, onInvitePermissionModeChange: setTeamInvitePermissionMode, onSubmitInvite: () => { void submitTeamInvite(); }, onLoadAuditPrevious: () => { void loadTeamAuditPage(teamAuditPage - 1); }, onLoadAuditNext: () => { void loadTeamAuditPage(teamAuditPage + 1); } }), _jsx(CreateWorkspaceConfirmModal, { isOpen: showCreateWorkspaceConfirm, theme: currentTheme, onClose: () => setShowCreateWorkspaceConfirm(false), onConfirm: () => openWorkspaceSetup({ intent: 'create-workspace' }) }), _jsx(SyncStatusModal, { isOpen: showSyncStatusModal, theme: currentTheme, currentWorkspaceLabel: currentWorkspaceLabel, syncStatus: headerSyncStatus, syncStatusMeta: syncStatusMeta, workspaceCloudSyncEnabled: effectiveWorkspaceCloudSyncEnabled, syncControlBusy: syncControlBusy, syncControlIntent: syncControlIntent, canManageWorkspaceSync: canManageWorkspaceSync, workspaceSyncSummary: headerSyncPresentation.summary, workspaceSyncRecommendedAction: headerSyncPresentation.recommendedAction, workspaceSyncRepairBusy: effectiveWorkspaceSyncRepairBusy, referenceMismatchCount: referenceMismatchCount, syncStageLabel: syncStageLabel, workspaceSyncPendingChanges: effectivePendingLocalChanges, incomingCloudChanges: coordinatorSyncPresentation?.incomingCloudChanges || 'Unknown', formattedLastSyncTime: effectiveFormattedLastSyncTime, formattedLastPullTime: effectiveFormattedLastPullTime, formattedLastPushTime: effectiveFormattedLastPushTime, syncLastError: syncLastError, activeReferenceMismatchSummaries: activeReferenceMismatchSummaries, syncDiagnosticsSummary: syncDiagnosticsSummary, syncEventRows: syncEventRows, syncEventsListRef: syncEventsListRef, workspaceSyncRepairQueued: workspaceSyncRepairQueued, workspaceSyncBusy: effectiveWorkspaceSyncBusy, workspaceSyncCopied: workspaceSyncCopied, coordinatorOwnershipMode: coordinatorOwnershipMode, coordinatorOwnershipTransferBusy: coordinatorOwnershipTransferBusy, coordinatorOwnershipTransferDisabled: coordinatorOwnershipTransferDisabled, onClose: closeSyncStatusModal, onToggleWorkspaceSync: (enabled) => {
4480
4485
  void handleWorkspaceSyncToggle(enabled);
4481
- }, onRepairSync: handleQueueOrRunRepairSync, onCopyReport: () => { void handleCopySyncDetails(); }, onRetrySync: () => {
4482
- void retryWorkspaceCloudSync().catch(() => {
4483
- // Coordinator status owns the durable error and retry presentation.
4484
- });
4485
- }, onTransferCoordinatorOwnership: () => {
4486
+ }, onRepairSync: handleQueueOrRunRepairSync, onCopyReport: () => { void handleCopySyncDetails(); }, onTransferCoordinatorOwnership: () => {
4486
4487
  void handleCoordinatorOwnershipTransfer();
4487
4488
  } }), _jsx(DiscardChangesDialog, { isOpen: Boolean(pendingWorkflowDiscardAction), onKeepEditing: () => setPendingWorkflowDiscardAction(null), onDiscard: () => {
4488
4489
  const action = pendingWorkflowDiscardAction;
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { ModalThemeName } from './types';
3
+ import type { WorkspaceSyncToggleIntent } from '../../../../hooks/sync/useSyncStatusControls';
3
4
  interface SyncStatusMeta {
4
5
  label: string;
5
6
  color: string;
@@ -24,10 +25,11 @@ interface SyncStatusModalProps {
24
25
  isOpen: boolean;
25
26
  theme: ModalThemeName;
26
27
  currentWorkspaceLabel: string;
27
- syncStatus: 'off' | 'syncing' | 'attention' | 'healthy';
28
+ syncStatus: 'off' | 'checking' | 'syncing' | 'attention' | 'healthy';
28
29
  syncStatusMeta: SyncStatusMeta;
29
30
  workspaceCloudSyncEnabled: boolean;
30
31
  syncControlBusy: boolean;
32
+ syncControlIntent: WorkspaceSyncToggleIntent;
31
33
  canManageWorkspaceSync: boolean;
32
34
  workspaceSyncSummary: string;
33
35
  workspaceSyncRecommendedAction: string;
@@ -54,8 +56,7 @@ interface SyncStatusModalProps {
54
56
  onToggleWorkspaceSync: (enabled: boolean) => void;
55
57
  onRepairSync: () => void;
56
58
  onCopyReport: () => void;
57
- onRetrySync: () => void;
58
59
  onTransferCoordinatorOwnership: () => void;
59
60
  }
60
- export declare function SyncStatusModal({ isOpen, theme, currentWorkspaceLabel, syncStatus, syncStatusMeta, workspaceCloudSyncEnabled, syncControlBusy, canManageWorkspaceSync, workspaceSyncSummary, workspaceSyncRecommendedAction, workspaceSyncRepairBusy, referenceMismatchCount, syncStageLabel, workspaceSyncPendingChanges, incomingCloudChanges, formattedLastSyncTime, formattedLastPullTime, formattedLastPushTime, syncLastError, activeReferenceMismatchSummaries, syncDiagnosticsSummary, syncEventRows, syncEventsListRef, workspaceSyncRepairQueued, workspaceSyncBusy, workspaceSyncCopied, coordinatorOwnershipMode, coordinatorOwnershipTransferBusy, coordinatorOwnershipTransferDisabled, onClose, onToggleWorkspaceSync, onRepairSync, onCopyReport, onRetrySync, onTransferCoordinatorOwnership, }: SyncStatusModalProps): import("react/jsx-runtime").JSX.Element;
61
+ export declare function SyncStatusModal({ isOpen, theme, currentWorkspaceLabel, syncStatus, syncStatusMeta, workspaceCloudSyncEnabled, syncControlBusy, syncControlIntent, canManageWorkspaceSync, workspaceSyncSummary, workspaceSyncRecommendedAction, workspaceSyncRepairBusy, referenceMismatchCount, syncStageLabel, workspaceSyncPendingChanges, incomingCloudChanges, formattedLastSyncTime, formattedLastPullTime, formattedLastPushTime, syncLastError, activeReferenceMismatchSummaries, syncDiagnosticsSummary, syncEventRows, syncEventsListRef, workspaceSyncRepairQueued, workspaceSyncBusy, workspaceSyncCopied, coordinatorOwnershipMode, coordinatorOwnershipTransferBusy, coordinatorOwnershipTransferDisabled, onClose, onToggleWorkspaceSync, onRepairSync, onCopyReport, onTransferCoordinatorOwnership, }: SyncStatusModalProps): import("react/jsx-runtime").JSX.Element;
61
62
  export {};