@taskforcehq/taskforce 0.3.329 → 0.3.332

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (363) hide show
  1. package/README.md +7 -2
  2. package/dist/Taskforce.module.css +290 -45
  3. package/dist/components/features/AiProfilesModule.js +3 -5
  4. package/dist/components/features/TaskSettings.js +70 -14
  5. package/dist/components/features/TaskforceAgentsModule.d.ts +1 -2
  6. package/dist/components/features/TaskforceAgentsModule.js +586 -116
  7. package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.d.ts +2 -2
  8. package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.js +2 -2
  9. package/dist/components/features/agentConnections/AgentConnectionControl.d.ts +15 -0
  10. package/dist/components/features/agentConnections/AgentConnectionControl.js +125 -0
  11. package/dist/components/features/agentConnections/ModelConnectionsPanel.d.ts +18 -0
  12. package/dist/components/features/agentConnections/ModelConnectionsPanel.js +393 -0
  13. package/dist/components/features/agentConnections/modelConnectionsApi.d.ts +65 -0
  14. package/dist/components/features/agentConnections/modelConnectionsApi.js +129 -0
  15. package/dist/components/features/planning/PlanningModule.js +15 -3
  16. package/dist/components/features/planning/planningMetadata.d.ts +10 -0
  17. package/dist/components/features/planning/planningMetadata.js +8 -0
  18. package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +15 -24
  19. package/dist/components/features/taskforceAgentEditorModel.d.ts +2 -1
  20. package/dist/components/features/taskforceAgentEditorModel.js +3 -1
  21. package/dist/components/features/workflowManager/workflowManagerApi.d.ts +1 -1
  22. package/dist/components/features/workflowManager/workflowManagerApi.js +3 -0
  23. package/dist/components/task/TaskWorkflowAssignmentField.js +68 -10
  24. package/dist/components/views/StandaloneLayout.js +62 -27
  25. package/dist/components/views/panels/PlanningDrawer.d.ts +2 -1
  26. package/dist/components/views/panels/PlanningDrawer.js +12 -8
  27. package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +4 -3
  28. package/dist/components/views/standalone/modals/SyncStatusModal.js +33 -38
  29. package/dist/config/envSchema.js +55 -1
  30. package/dist/core/McpTokenService.d.ts +25 -1
  31. package/dist/core/McpTokenService.js +106 -15
  32. package/dist/core/TaskChecklistCommandService.d.ts +27 -0
  33. package/dist/core/TaskChecklistCommandService.js +83 -5
  34. package/dist/core/TaskLifecycleCommandService.d.ts +3 -1
  35. package/dist/core/TaskLifecycleCommandService.js +6 -2
  36. package/dist/core/Taskforce.d.ts +43 -3
  37. package/dist/core/Taskforce.js +158 -7
  38. package/dist/core/types.d.ts +9 -0
  39. package/dist/documentReviews/DocumentReviewCommentStore.d.ts +2 -0
  40. package/dist/documentReviews/DocumentReviewCommentStore.js +28 -9
  41. package/dist/documentReviews/commandService.d.ts +2 -1
  42. package/dist/documentReviews/commandService.js +6 -3
  43. package/dist/hooks/sync/orchestratorShared.d.ts +1 -0
  44. package/dist/hooks/sync/orchestratorShared.js +2 -0
  45. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.d.ts +3 -0
  46. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.js +85 -9
  47. package/dist/hooks/sync/useSyncStatusControls.d.ts +4 -1
  48. package/dist/hooks/sync/useSyncStatusControls.js +47 -11
  49. package/dist/hooks/useSyncOrchestrator.d.ts +3 -0
  50. package/dist/hooks/useSyncOrchestrator.js +111 -2
  51. package/dist/hooks/useTaskData.d.ts +31 -1
  52. package/dist/hooks/useTaskData.js +29 -7
  53. package/dist/hooks/useTaskMutations.d.ts +3 -1
  54. package/dist/hooks/useTaskMutations.js +46 -12
  55. package/dist/hooks/useTaskforce.d.ts +2 -0
  56. package/dist/hooks/useTaskforce.js +11 -2
  57. package/dist/mcp/clientRegistry.d.ts +2 -2
  58. package/dist/mcp/clientRegistry.js +1 -1
  59. package/dist/mcp/documentAssetRegistrar.js +9 -6
  60. package/dist/mcp/durableTaskMutationRouter.d.ts +4 -1
  61. package/dist/mcp/durableTaskMutationRouter.js +10 -0
  62. package/dist/mcp/durableTaskRelationshipMutationRouter.js +4 -0
  63. package/dist/mcp/httpProtocolRouting.d.ts +11 -0
  64. package/dist/mcp/httpProtocolRouting.js +22 -0
  65. package/dist/mcp/localCliHealth.d.ts +2 -2
  66. package/dist/mcp/localCliHealth.js +2 -2
  67. package/dist/mcp/localServiceProxy.d.ts +1 -0
  68. package/dist/mcp/localServiceProxy.js +530 -68
  69. package/dist/mcp/planningAttachmentCommandAdapter.d.ts +3 -1
  70. package/dist/mcp/planningAttachmentCommandAdapter.js +20 -2
  71. package/dist/mcp/runtime.d.ts +54 -79
  72. package/dist/mcp/runtime.js +408 -102
  73. package/dist/mcp/taskPlanningRegistrar.js +25 -6
  74. package/dist/mcp/toolProfiles.d.ts +2 -0
  75. package/dist/mcp/toolProfiles.js +11 -0
  76. package/dist/mcp/toolRegistry.d.ts +1 -0
  77. package/dist/mcp/toolRegistry.js +9 -8
  78. package/dist/mcp/workflowExecutionRegistrar.js +4 -4
  79. package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
  80. package/dist/migrations/taskSchemaMigrations.js +415 -0
  81. package/dist/runtime/appGates.d.ts +2 -1
  82. package/dist/runtime/appGates.js +7 -0
  83. package/dist/server/buildInfo.d.ts +1 -0
  84. package/dist/server/buildInfo.js +5 -1
  85. package/dist/server/cloudMcpCapacityTelemetry.d.ts +68 -0
  86. package/dist/server/cloudMcpCapacityTelemetry.js +221 -0
  87. package/dist/server/index.d.ts +3 -0
  88. package/dist/server/index.js +108 -11
  89. package/dist/server/localDatabaseIdentity.js +4 -1
  90. package/dist/server/localServiceLease.js +2 -1
  91. package/dist/server/localServiceSessions.d.ts +14 -17
  92. package/dist/server/localServiceSessions.js +308 -94
  93. package/dist/server/localWorkspaceSyncServerRuntime.js +25 -19
  94. package/dist/server/routes/admin.d.ts +4 -0
  95. package/dist/server/routes/admin.js +126 -5
  96. package/dist/server/routes/agents.d.ts +7 -0
  97. package/dist/server/routes/agents.js +277 -24
  98. package/dist/server/routes/billing.js +5 -1
  99. package/dist/server/routes/durableTaskHttpRouters.d.ts +2 -0
  100. package/dist/server/routes/executorPhaseAApprovals.d.ts +19 -0
  101. package/dist/server/routes/executorPhaseAApprovals.js +140 -0
  102. package/dist/server/routes/executorPhaseAIssuerRedemptions.d.ts +11 -0
  103. package/dist/server/routes/executorPhaseAIssuerRedemptions.js +24 -0
  104. package/dist/server/routes/githubReviewEvidence.d.ts +19 -0
  105. package/dist/server/routes/githubReviewEvidence.js +116 -0
  106. package/dist/server/routes/localService.d.ts +15 -4
  107. package/dist/server/routes/localService.js +136 -40
  108. package/dist/server/routes/modelConnections.d.ts +24 -0
  109. package/dist/server/routes/modelConnections.js +205 -0
  110. package/dist/server/routes/shared.d.ts +22 -0
  111. package/dist/server/routes/shared.js +298 -182
  112. package/dist/server/routes/sync.js +1 -0
  113. package/dist/server/routes/syncAuxRoutes.js +5 -1
  114. package/dist/server/routes/syncPushRoutes.d.ts +1 -0
  115. package/dist/server/routes/syncPushRoutes.js +1 -0
  116. package/dist/server/routes/syncV3FeedRoutes.js +10 -1
  117. package/dist/server/routes/syncV3OperationRoutes.js +35 -9
  118. package/dist/server/routes/tasks.js +21 -2
  119. package/dist/server/routes/workflows.js +9 -1
  120. package/dist/server/routes.js +59 -0
  121. package/dist/service/localServiceCli.d.ts +2 -2
  122. package/dist/service/localServiceCli.js +4 -3
  123. package/dist/services/codexAppServerModelGateway.d.ts +54 -5
  124. package/dist/services/codexAppServerModelGateway.js +246 -21
  125. package/dist/services/codexDeviceCodeLoginManager.d.ts +39 -0
  126. package/dist/services/codexDeviceCodeLoginManager.js +265 -0
  127. package/dist/services/codexModelProviderConnectionLifecycle.d.ts +8 -0
  128. package/dist/services/codexModelProviderConnectionLifecycle.js +73 -0
  129. package/dist/services/executorPhaseAApprovalRuntime.d.ts +14 -0
  130. package/dist/services/executorPhaseAApprovalRuntime.js +24 -0
  131. package/dist/services/executorPhaseAApprovalService.d.ts +40 -0
  132. package/dist/services/executorPhaseAApprovalService.js +609 -0
  133. package/dist/services/executorPhaseADriftEvaluator.d.ts +78 -0
  134. package/dist/services/executorPhaseADriftEvaluator.js +93 -0
  135. package/dist/services/executorPhaseAIssuerCore.d.ts +139 -0
  136. package/dist/services/executorPhaseAIssuerCore.js +402 -0
  137. package/dist/services/executorPhaseAIssuerRedemptionService.d.ts +34 -0
  138. package/dist/services/executorPhaseAIssuerRedemptionService.js +158 -0
  139. package/dist/services/githubReviewEvidenceRuntime.d.ts +14 -0
  140. package/dist/services/githubReviewEvidenceRuntime.js +30 -0
  141. package/dist/services/githubReviewEvidenceService.d.ts +93 -0
  142. package/dist/services/githubReviewEvidenceService.js +336 -0
  143. package/dist/services/modelGateway.d.ts +7 -0
  144. package/dist/services/modelProviderConnectionService.d.ts +71 -0
  145. package/dist/services/modelProviderConnectionService.js +279 -0
  146. package/dist/services/modelProviderCredentialHome.d.ts +32 -0
  147. package/dist/services/modelProviderCredentialHome.js +271 -0
  148. package/dist/services/ownerScopedModelConnectionGateway.d.ts +12 -0
  149. package/dist/services/ownerScopedModelConnectionGateway.js +30 -0
  150. package/dist/services/taskforceAgentConnectionBindingService.d.ts +66 -0
  151. package/dist/services/taskforceAgentConnectionBindingService.js +185 -0
  152. package/dist/services/taskforceAgentMcpBridge.d.ts +2 -2
  153. package/dist/services/taskforceAgentMcpBridge.js +42 -29
  154. package/dist/shared/adminEdgeProxy.d.ts +5 -0
  155. package/dist/shared/adminEdgeProxy.js +94 -0
  156. package/dist/shared/adminProxySessionCookies.d.ts +16 -0
  157. package/dist/shared/adminProxySessionCookies.js +86 -0
  158. package/dist/shared/aiProfileColors.d.ts +31 -1
  159. package/dist/shared/aiProfileColors.js +14 -6
  160. package/dist/shared/executorPhaseAApprovalGoldenVector.json +269 -0
  161. package/dist/shared/executorPhaseAApprovalReceipt.d.ts +112 -0
  162. package/dist/shared/executorPhaseAApprovalReceipt.js +58 -0
  163. package/dist/shared/executorPhaseAApprovalTrustPolicy.json +10 -0
  164. package/dist/shared/executorPhaseADriftContracts.d.ts +37 -0
  165. package/dist/shared/executorPhaseADriftContracts.js +63 -0
  166. package/dist/shared/executorPhaseAIssuerContracts.d.ts +75 -0
  167. package/dist/shared/executorPhaseAIssuerContracts.js +90 -0
  168. package/dist/shared/executorPhaseARunAuthorization.d.ts +120 -0
  169. package/dist/shared/executorPhaseARunAuthorization.js +232 -0
  170. package/dist/shared/executorPhaseASchemaValidation.d.ts +7 -0
  171. package/dist/shared/executorPhaseASchemaValidation.js +53 -0
  172. package/dist/shared/executorPhaseASchemas/approval-receipt.schema.json +106 -0
  173. package/dist/shared/executorPhaseASchemas/drift-attestation.schema.json +54 -0
  174. package/dist/shared/executorPhaseASchemas/drift-request.schema.json +47 -0
  175. package/dist/shared/executorPhaseASchemas/foundation-manifest.schema.json +29 -0
  176. package/dist/shared/executorPhaseASchemas/issuer-audit-record.schema.json +24 -0
  177. package/dist/shared/executorPhaseASchemas/issuer-proof.schema.json +43 -0
  178. package/dist/shared/executorPhaseASchemas/issuer-redemption-request.schema.json +18 -0
  179. package/dist/shared/executorPhaseASchemas/issuer-redemption-response.schema.json +39 -0
  180. package/dist/shared/executorPhaseASchemas/logical-envelope.schema.json +149 -0
  181. package/dist/shared/executorPhaseASchemas/preflight-report.schema.json +216 -0
  182. package/dist/shared/executorPhaseASchemas/run-capability.schema.json +111 -0
  183. package/dist/shared/executorPhaseASchemas/sender-proof.schema.json +37 -0
  184. package/dist/shared/executorPhaseASchemas/workload-grant.schema.json +68 -0
  185. package/dist/shared/executorPhaseASchemas/workload-jwt-claims.schema.json +67 -0
  186. package/dist/shared/executorPhaseATiming.d.ts +1 -0
  187. package/dist/shared/executorPhaseATiming.js +1 -0
  188. package/dist/shared/planningIdentity.js +1 -1
  189. package/dist/shared/productLogoKeys.d.ts +2 -0
  190. package/dist/shared/productLogoKeys.js +18 -0
  191. package/dist/shared/taskforceAgentDefinition.d.ts +0 -1
  192. package/dist/shared/taskforceAgentDefinition.js +6 -9
  193. package/dist/shared/taskforceAgentModels.js +7 -3
  194. package/dist/shared/userFeatureGrants.d.ts +4 -0
  195. package/dist/shared/userFeatureGrants.js +7 -0
  196. package/dist/storage/executorPhaseAApprovalReceiptStore.d.ts +37 -0
  197. package/dist/storage/executorPhaseAApprovalReceiptStore.js +81 -0
  198. package/dist/storage/executorPhaseARunAuthorizationStore.d.ts +103 -0
  199. package/dist/storage/executorPhaseARunAuthorizationStore.js +492 -0
  200. package/dist/storage/githubReviewEvidenceInstallationStore.d.ts +26 -0
  201. package/dist/storage/githubReviewEvidenceInstallationStore.js +89 -0
  202. package/dist/storage/modelProviderConnectionStore.d.ts +99 -0
  203. package/dist/storage/modelProviderConnectionStore.js +446 -0
  204. package/dist/storage/postgresAdapter.d.ts +4 -0
  205. package/dist/storage/postgresAdapter.js +14 -1
  206. package/dist/storage/postgresRequestDiagnostics.d.ts +9 -1
  207. package/dist/storage/postgresRequestDiagnostics.js +15 -2
  208. package/dist/storage/postgresWorker.js +20 -2
  209. package/dist/storage/postgresWorkerProtocol.d.ts +7 -0
  210. package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
  211. package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -0
  212. package/dist/storage/workflowStore.d.ts +2 -0
  213. package/dist/storage/workflowStore.js +39 -2
  214. package/dist/sync/cloudSyncApi.js +4 -2
  215. package/dist/sync/collaborationSyncState.js +5 -0
  216. package/dist/sync/coordinator/localSyncExecutionPermitStore.js +60 -29
  217. package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.d.ts +10 -0
  218. package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.js +29 -0
  219. package/dist/sync/coordinator/localWorkspaceSyncRunner.d.ts +3 -1
  220. package/dist/sync/coordinator/localWorkspaceSyncRunner.js +18 -0
  221. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.d.ts +15 -1
  222. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.js +99 -2
  223. package/dist/sync/coordinator/workspaceSyncCredentialBroker.d.ts +1 -0
  224. package/dist/sync/coordinator/workspaceSyncCredentialBroker.js +33 -4
  225. package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.d.ts +2 -1
  226. package/dist/sync/engine/workspaceSyncContentVersionStore.d.ts +38 -0
  227. package/dist/sync/engine/workspaceSyncContentVersionStore.js +50 -1
  228. package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +6 -6
  229. package/dist/sync/engine/workspaceSyncEnginePushCompletion.d.ts +14 -0
  230. package/dist/sync/engine/workspaceSyncEnginePushCompletion.js +84 -0
  231. package/dist/sync/engine/workspaceSyncEngineRecovery.js +1 -0
  232. package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +1 -0
  233. package/dist/sync/engine/workspaceSyncEngineRuntime.js +1 -0
  234. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +112 -38
  235. package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +6 -0
  236. package/dist/sync/engine/workspaceSyncEngineTransfers.js +3 -1
  237. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.d.ts +1 -0
  238. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +31 -0
  239. package/dist/sync/syncApplyHandlers.d.ts +3 -0
  240. package/dist/sync/syncApplyHandlers.js +81 -15
  241. package/dist/sync/syncService.d.ts +15 -0
  242. package/dist/sync/syncService.js +83 -18
  243. package/dist/sync/taskforceAgentSyncAuthorization.d.ts +16 -0
  244. package/dist/sync/taskforceAgentSyncAuthorization.js +20 -0
  245. package/dist/sync/v3/combinedFeedCapability.js +4 -0
  246. package/dist/sync/v3/durableInitiativeMutationRouter.js +18 -10
  247. package/dist/sync/v3/durableOperationReplay.d.ts +14 -0
  248. package/dist/sync/v3/durableOperationReplay.js +18 -0
  249. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +3 -0
  250. package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +2 -1
  251. package/dist/sync/v3/durableTaskChecklistMutationRouter.js +58 -15
  252. package/dist/sync/v3/durableTaskCommentMutationRouter.js +3 -0
  253. package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +1 -1
  254. package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +10 -0
  255. package/dist/sync/v3/durableTaxonomyMutationRouter.js +5 -0
  256. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.d.ts +18 -7
  257. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +89 -23
  258. package/dist/sync/v3/durableWorkstreamMutationRouter.js +18 -10
  259. package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.js +16 -5
  260. package/dist/sync/v3/localOutboxDispatchRuntime.js +2 -2
  261. package/dist/sync/v3/localOutboxRecoveryPreparationService.js +8 -2
  262. package/dist/sync/v3/localTaskChecklistOutboxHandler.js +16 -2
  263. package/dist/sync/v3/localTaskChecklistOutboxService.d.ts +4 -0
  264. package/dist/sync/v3/localTaskChecklistOutboxService.js +14 -1
  265. package/dist/sync/v3/localTaskCreateOutboxService.d.ts +3 -1
  266. package/dist/sync/v3/localTaskCreateOutboxService.js +6 -1
  267. package/dist/sync/v3/localTaskDeleteOutboxService.js +1 -0
  268. package/dist/sync/v3/localTaskLifecycleOutboxService.d.ts +2 -1
  269. package/dist/sync/v3/localTaskLifecycleOutboxService.js +5 -1
  270. package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -1
  271. package/dist/sync/v3/localTaskMetadataOutboxService.js +6 -2
  272. package/dist/sync/v3/localTaskStatusOutboxService.d.ts +10 -1
  273. package/dist/sync/v3/localTaskStatusOutboxService.js +238 -16
  274. package/dist/sync/v3/syncDurabilityStore.d.ts +36 -1
  275. package/dist/sync/v3/syncDurabilityStore.js +202 -8
  276. package/dist/sync/v3/taskChecklistMutationService.d.ts +11 -0
  277. package/dist/sync/v3/taskChecklistMutationService.js +44 -1
  278. package/dist/sync/v3/taskStatusMutationService.d.ts +29 -1
  279. package/dist/sync/v3/taskStatusMutationService.js +119 -3
  280. package/dist/sync/v3/workflowAssignmentSync.d.ts +5 -0
  281. package/dist/sync/v3/workflowAssignmentSync.js +27 -0
  282. package/dist/sync/v3/workflowRuntimeMutationService.d.ts +5 -0
  283. package/dist/sync/v3/workflowRuntimeMutationService.js +124 -71
  284. package/dist/sync/v3/workspaceSyncJournalReader.js +1 -1
  285. package/dist/sync/v3/workspaceSyncOperationRetentionService.d.ts +16 -0
  286. package/dist/sync/v3/workspaceSyncOperationRetentionService.js +83 -0
  287. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +1 -0
  288. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +9 -2
  289. package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +25 -3
  290. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +7 -0
  291. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +44 -32
  292. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +9 -5
  293. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +54 -38
  294. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +10 -0
  295. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +70 -31
  296. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +2 -1
  297. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +16 -0
  298. package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +6 -0
  299. package/dist/sync/v3/workspaceSyncV3Feed.d.ts +1 -0
  300. package/dist/sync/v3/workspaceSyncV3Feed.js +6 -1
  301. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +2 -0
  302. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +49 -18
  303. package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +3 -0
  304. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +5 -0
  305. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +36 -2
  306. package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.d.ts +17 -0
  307. package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.js +64 -0
  308. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.d.ts +1 -0
  309. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.js +50 -5
  310. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.d.ts +7 -0
  311. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.js +33 -0
  312. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.d.ts +7 -0
  313. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.js +8 -0
  314. package/dist/sync/workspaceRepair.d.ts +5 -2
  315. package/dist/sync/workspaceRepair.js +161 -6
  316. package/dist/sync/workspaceSyncModel.d.ts +21 -0
  317. package/dist/sync/workspaceSyncModel.js +35 -7
  318. package/dist/sync/workspaceSyncState.d.ts +1 -0
  319. package/dist/sync/workspaceSyncV2SnapshotBuilder.d.ts +6 -0
  320. package/dist/sync/workspaceSyncV2SnapshotBuilder.js +5 -0
  321. package/dist/ui/assets/AiIdentityRosterCard-CDMPtnbC.js +1 -0
  322. package/dist/ui/assets/AiProfilesModule-Cww85C4E.js +1 -0
  323. package/dist/ui/assets/{AnnotatedAttachmentWorkspace-B68Wg-RV.js → AnnotatedAttachmentWorkspace-Dt9TKYSH.js} +1 -1
  324. package/dist/ui/assets/{AssetTraySortControl-C8Rztyal.js → AssetTraySortControl-CKgapnxu.js} +1 -1
  325. package/dist/ui/assets/{ContextAttachmentManager-Cj3c7X9y.js → ContextAttachmentManager-T-cEVcOZ.js} +2 -2
  326. package/dist/ui/assets/{DocumentWorkspace-B5uvzems.js → DocumentWorkspace-HD4MUjAZ.js} +1 -1
  327. package/dist/ui/assets/{EntityActivityTimeline-BVFvCB5R.js → EntityActivityTimeline-_V0zfMuh.js} +1 -1
  328. package/dist/ui/assets/PlanningModule-mTkBygsB.js +1 -0
  329. package/dist/ui/assets/{PlansPage-AY4cGWco.js → PlansPage-Btiq06VO.js} +1 -1
  330. package/dist/ui/assets/{TaskContextUpload-DZxTVesW.js → TaskContextUpload-C00NVUpn.js} +1 -1
  331. package/dist/ui/assets/TaskSettings-Cp-L-4xh.js +12 -0
  332. package/dist/ui/assets/TaskforceAgentsModule-Coq9-PUp.js +24 -0
  333. package/dist/ui/assets/TaskforceAgentsModule-b-8R25cJ.css +1 -0
  334. package/dist/ui/assets/{WorkflowManagerModule-DEr5di_r.js → WorkflowManagerModule-CuqRzMmM.js} +1 -1
  335. package/dist/ui/assets/index-BZ-hdZSk.css +1 -0
  336. package/dist/ui/assets/index-DSQINwt9.js +7 -0
  337. package/dist/ui/assets/{vendor-icons-D9Lpw-j4.js → vendor-icons-Bsq-mcEn.js} +1 -1
  338. package/dist/ui/branding/logos/letterhead_dark.png +0 -0
  339. package/dist/ui/branding/logos/letterhead_light.png +0 -0
  340. package/dist/ui/branding/logos/signature_dark.png +0 -0
  341. package/dist/ui/branding/logos/signature_light.png +0 -0
  342. package/dist/ui/index.html +3 -3
  343. package/dist/utils/aiProfileDefaultLogo.js +16 -48
  344. package/dist/utils/httpSetCookie.d.ts +1 -0
  345. package/dist/utils/httpSetCookie.js +4 -1
  346. package/dist/utils/localRuntimeUrl.d.ts +1 -0
  347. package/dist/utils/localRuntimeUrl.js +14 -0
  348. package/dist/utils/productLogoRegistry.d.ts +2 -0
  349. package/dist/utils/productLogoRegistry.js +36 -0
  350. package/dist/utils/syncStatusPresentation.d.ts +4 -0
  351. package/dist/utils/syncStatusPresentation.js +17 -0
  352. package/dist/utils/taskEvents.d.ts +2 -0
  353. package/dist/utils/workspaceSyncPresentation.d.ts +1 -1
  354. package/dist/utils/workspaceSyncPresentation.js +23 -17
  355. package/package.json +24 -4
  356. package/dist/ui/assets/AiIdentityRosterCard-BZM4aQnM.js +0 -1
  357. package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +0 -1
  358. package/dist/ui/assets/PlanningModule-B5DWQOGz.js +0 -1
  359. package/dist/ui/assets/TaskSettings-BeWAuyZj.js +0 -12
  360. package/dist/ui/assets/TaskforceAgentsModule-BifCYtjR.js +0 -21
  361. package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +0 -1
  362. package/dist/ui/assets/index-I5zhdtgt.js +0 -7
  363. package/dist/ui/assets/index-VRFsx3wz.css +0 -1
@@ -8,13 +8,13 @@
8
8
  <link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png" />
9
9
  <link rel="apple-touch-icon" href="/taskforce/favicon/apple-touch-icon.png" />
10
10
  <title>Taskforce</title>
11
- <script type="module" crossorigin src="/taskforce/assets/index-I5zhdtgt.js"></script>
11
+ <script type="module" crossorigin src="/taskforce/assets/index-DSQINwt9.js"></script>
12
12
  <link rel="modulepreload" crossorigin href="/taskforce/assets/vendor-react-CKJs5o3c.js">
13
- <link rel="modulepreload" crossorigin href="/taskforce/assets/vendor-icons-D9Lpw-j4.js">
13
+ <link rel="modulepreload" crossorigin href="/taskforce/assets/vendor-icons-Bsq-mcEn.js">
14
14
  <link rel="modulepreload" crossorigin href="/taskforce/assets/vendor-markdown-_lhNCyq-.js">
15
15
  <link rel="modulepreload" crossorigin href="/taskforce/assets/vendor-dnd-CJ-AjP-Y.js">
16
16
  <link rel="modulepreload" crossorigin href="/taskforce/assets/vendor-router-AqJMU8Lz.js">
17
- <link rel="stylesheet" crossorigin href="/taskforce/assets/index-VRFsx3wz.css">
17
+ <link rel="stylesheet" crossorigin href="/taskforce/assets/index-BZ-hdZSk.css">
18
18
  </head>
19
19
  <body>
20
20
  <div id="root"></div>
@@ -1,38 +1,6 @@
1
- import antigravityLogo from '../assets/ai-profile-clients/antigravity.png';
2
- import chatgptLogo from '../assets/ai-profile-clients/chatgpt.svg';
3
- import claudeChatLogo from '../assets/ai-profile-clients/claude-chat.svg';
4
- import claudeCodeLogo from '../assets/ai-profile-clients/claude-code.svg';
5
- import clineLogo from '../assets/ai-profile-clients/cline.svg';
6
- import codexLogo from '../assets/ai-profile-clients/codex.svg';
7
- import cursorLogo from '../assets/ai-profile-clients/cursor.svg';
8
- import geminiLogo from '../assets/ai-profile-clients/gemini-cli-icon.png';
9
- import geminiChatLogo from '../assets/ai-profile-clients/gemini.svg';
10
- import grokLogo from '../assets/ai-profile-clients/grok.svg';
11
- import kiroLogo from '../assets/ai-profile-clients/kiro.svg';
12
- import mistralLogo from '../assets/ai-profile-clients/mistral.svg';
13
- import perplexityLogo from '../assets/ai-profile-clients/perplexity.svg';
14
- import vscodeLogo from '../assets/ai-profile-clients/vscode.svg';
15
- import windsurfLogo from '../assets/ai-profile-clients/windsurf.svg';
16
1
  import { getMcpClientRegistryEntry } from '../mcp/clientRegistry.js';
17
2
  import { isTaskforceManagedAiProfile } from '../shared/aiProfileAvatarEligibility.js';
18
- const LOGO_URLS = {
19
- antigravity: antigravityLogo,
20
- 'chatgpt-desktop': chatgptLogo,
21
- 'claude-code': claudeCodeLogo,
22
- 'claude-chat': claudeChatLogo,
23
- 'grok-chat': grokLogo,
24
- 'gemini-chat': geminiChatLogo,
25
- 'mistral-chat': mistralLogo,
26
- 'perplexity-chat': perplexityLogo,
27
- cline: clineLogo,
28
- codex: codexLogo,
29
- cursor: cursorLogo,
30
- 'gemini-cli': geminiLogo,
31
- grok: grokLogo,
32
- kiro: kiroLogo,
33
- vscode: vscodeLogo,
34
- windsurf: windsurfLogo,
35
- };
3
+ import { getProductLogoUrl } from './productLogoRegistry.js';
36
4
  export function getAiProfileDefaultLogoUrl(profile) {
37
5
  if (!profile || isTaskforceManagedAiProfile(profile))
38
6
  return '';
@@ -42,7 +10,7 @@ export function getAiProfileDefaultLogoUrl(profile) {
42
10
  : null;
43
11
  const registryEntry = getMcpClientRegistryEntry(clientId);
44
12
  if (registryEntry?.logoKey)
45
- return LOGO_URLS[registryEntry.logoKey];
13
+ return getProductLogoUrl(registryEntry.logoKey);
46
14
  if (!['chat_app', 'ide', 'cli', 'coding_tool'].includes(String(profile.surfaceType || '')))
47
15
  return '';
48
16
  const identity = [profile.username, profile.name]
@@ -53,32 +21,32 @@ export function getAiProfileDefaultLogoUrl(profile) {
53
21
  if (identity.includes('openclaw') || identity.includes('hermes agent'))
54
22
  return '';
55
23
  if (identity.includes('chatgpt'))
56
- return chatgptLogo;
24
+ return getProductLogoUrl('chatgpt');
57
25
  if (identity.includes('claude code'))
58
- return claudeCodeLogo;
26
+ return getProductLogoUrl('claude-code');
59
27
  if (identity.includes('claude desktop'))
60
- return claudeChatLogo;
28
+ return getProductLogoUrl('claude-chat');
61
29
  if (identity.includes('cline'))
62
- return clineLogo;
30
+ return getProductLogoUrl('cline');
63
31
  if (identity.includes('codex'))
64
- return codexLogo;
32
+ return getProductLogoUrl('codex');
65
33
  if (identity.includes('cursor'))
66
- return cursorLogo;
34
+ return getProductLogoUrl('cursor');
67
35
  if (identity.includes('cascade') || identity.includes('windsurf'))
68
- return windsurfLogo;
36
+ return getProductLogoUrl('windsurf');
69
37
  if (identity.includes('antigravity'))
70
- return antigravityLogo;
38
+ return getProductLogoUrl('antigravity');
71
39
  if (identity.includes('gemini'))
72
- return geminiLogo;
40
+ return getProductLogoUrl('gemini-cli');
73
41
  if (identity.includes('grok'))
74
- return grokLogo;
42
+ return getProductLogoUrl('grok');
75
43
  if (identity.includes('mistral') || identity.includes('le chat'))
76
- return mistralLogo;
44
+ return getProductLogoUrl('mistral-chat');
77
45
  if (identity.includes('perplexity'))
78
- return perplexityLogo;
46
+ return getProductLogoUrl('perplexity-chat');
79
47
  if (identity.includes('kiro'))
80
- return kiroLogo;
48
+ return getProductLogoUrl('kiro');
81
49
  if (identity.includes('visual studio code') || identity.includes('vs code') || identity.includes('vscode'))
82
- return vscodeLogo;
50
+ return getProductLogoUrl('vscode');
83
51
  return '';
84
52
  }
@@ -1,3 +1,4 @@
1
+ export declare function stripSetCookieDomainAttribute(cookie: string): string;
1
2
  export declare function rewriteSetCookieForLocalHost(cookie: string): string;
2
3
  export declare function readSetCookieHeaders(headers: Headers): string[];
3
4
  export declare function findSetCookieHeader(headers: readonly string[], cookieName: string): string | null;
@@ -1,4 +1,4 @@
1
- export function rewriteSetCookieForLocalHost(cookie) {
1
+ export function stripSetCookieDomainAttribute(cookie) {
2
2
  const parts = String(cookie || '').split(';').map((part) => part.trim()).filter(Boolean);
3
3
  if (parts.length === 0)
4
4
  return cookie;
@@ -6,6 +6,9 @@ export function rewriteSetCookieForLocalHost(cookie) {
6
6
  const filteredAttrs = attrs.filter((attr) => !attr.toLowerCase().startsWith('domain='));
7
7
  return [nameValue, ...filteredAttrs].join('; ');
8
8
  }
9
+ export function rewriteSetCookieForLocalHost(cookie) {
10
+ return stripSetCookieDomainAttribute(cookie);
11
+ }
9
12
  export function readSetCookieHeaders(headers) {
10
13
  const values = headers.getSetCookie?.();
11
14
  if (Array.isArray(values) && values.length > 0)
@@ -0,0 +1 @@
1
+ export declare function retargetRestartedLocalUrl(currentUrl: string, previousPort: number, restartedPort: number): string | null;
@@ -0,0 +1,14 @@
1
+ export function retargetRestartedLocalUrl(currentUrl, previousPort, restartedPort) {
2
+ if (previousPort === restartedPort)
3
+ return null;
4
+ try {
5
+ const target = new URL(currentUrl);
6
+ if (target.origin !== `http://localhost:${previousPort}`)
7
+ return null;
8
+ target.port = String(restartedPort);
9
+ return target.toString();
10
+ }
11
+ catch {
12
+ return null;
13
+ }
14
+ }
@@ -0,0 +1,2 @@
1
+ import type { ProductLogoKey } from '../shared/productLogoKeys.js';
2
+ export declare function getProductLogoUrl(key: ProductLogoKey | null | undefined): string;
@@ -0,0 +1,36 @@
1
+ import antigravityLogo from '../assets/ai-profile-clients/antigravity.png';
2
+ import chatgptLogo from '../assets/ai-profile-clients/chatgpt.svg';
3
+ import claudeChatLogo from '../assets/ai-profile-clients/claude-chat.svg';
4
+ import claudeCodeLogo from '../assets/ai-profile-clients/claude-code.svg';
5
+ import clineLogo from '../assets/ai-profile-clients/cline.svg';
6
+ import codexLogo from '../assets/ai-profile-clients/codex.svg';
7
+ import cursorLogo from '../assets/ai-profile-clients/cursor.svg';
8
+ import geminiLogo from '../assets/ai-profile-clients/gemini-cli-icon.png';
9
+ import geminiChatLogo from '../assets/ai-profile-clients/gemini.svg';
10
+ import grokLogo from '../assets/ai-profile-clients/grok.svg';
11
+ import kiroLogo from '../assets/ai-profile-clients/kiro.svg';
12
+ import mistralLogo from '../assets/ai-profile-clients/mistral.svg';
13
+ import perplexityLogo from '../assets/ai-profile-clients/perplexity.svg';
14
+ import vscodeLogo from '../assets/ai-profile-clients/vscode.svg';
15
+ import windsurfLogo from '../assets/ai-profile-clients/windsurf.svg';
16
+ const PRODUCT_LOGO_URLS = {
17
+ antigravity: antigravityLogo,
18
+ chatgpt: chatgptLogo,
19
+ 'claude-chat': claudeChatLogo,
20
+ 'claude-code': claudeCodeLogo,
21
+ cline: clineLogo,
22
+ codex: codexLogo,
23
+ cursor: cursorLogo,
24
+ 'gemini-chat': geminiChatLogo,
25
+ 'gemini-cli': geminiLogo,
26
+ grok: grokLogo,
27
+ 'grok-chat': grokLogo,
28
+ kiro: kiroLogo,
29
+ 'mistral-chat': mistralLogo,
30
+ 'perplexity-chat': perplexityLogo,
31
+ vscode: vscodeLogo,
32
+ windsurf: windsurfLogo,
33
+ };
34
+ export function getProductLogoUrl(key) {
35
+ return key ? PRODUCT_LOGO_URLS[key] : '';
36
+ }
@@ -65,6 +65,10 @@ export interface WorkspaceSyncDiagnosticsPresentation {
65
65
  } | null;
66
66
  coordinatorRecoveryObligations?: number;
67
67
  }
68
+ export declare function resolveEffectiveWorkspaceSyncDiagnostics(browserDiagnostics: WorkspaceSyncDiagnosticsPresentation, coordinator: {
69
+ recoveryObligations: number;
70
+ outbox: WorkspaceSyncDiagnosticsPresentation['durableOutbox'];
71
+ } | null): WorkspaceSyncDiagnosticsPresentation;
68
72
  interface BuildSyncEventRowsInput {
69
73
  syncRecentEvents: SyncEventRecord[];
70
74
  syncRecentEventsError: string | null;
@@ -22,6 +22,15 @@ function getCollapsibleEventSignature(event) {
22
22
  stableStringifySyncEventDetails(event.details),
23
23
  ].join('|');
24
24
  }
25
+ export function resolveEffectiveWorkspaceSyncDiagnostics(browserDiagnostics, coordinator) {
26
+ if (!coordinator)
27
+ return browserDiagnostics;
28
+ return {
29
+ ...browserDiagnostics,
30
+ durableOutbox: coordinator.outbox,
31
+ coordinatorRecoveryObligations: coordinator.recoveryObligations,
32
+ };
33
+ }
25
34
  function formatDiagnosticsTimestamp(value) {
26
35
  if (!value)
27
36
  return 'Never';
@@ -48,6 +57,14 @@ export function resolveSyncStatusMeta(status) {
48
57
  border: 'rgba(96, 165, 250, 0.35)',
49
58
  background: 'rgba(59, 130, 246, 0.12)',
50
59
  };
60
+ case 'checking':
61
+ return {
62
+ label: 'Checking',
63
+ icon: 'cloud',
64
+ color: '#94a3b8',
65
+ border: 'rgba(148, 163, 184, 0.35)',
66
+ background: 'rgba(148, 163, 184, 0.12)',
67
+ };
51
68
  case 'attention':
52
69
  return {
53
70
  label: 'Needs Attention',
@@ -1,4 +1,5 @@
1
1
  import type { TaskItem } from '../types.js';
2
+ import type { WorkflowAssignmentDetails } from '../components/features/workflowManager/types.js';
2
3
  import type { TaskCollection } from './taskInvalidation.js';
3
4
  export declare const TASKFORCE_TASKS_MUTATED_EVENT = "taskforce:tasks-mutated";
4
5
  export interface TaskforceTasksMutatedDetail {
@@ -6,6 +7,7 @@ export interface TaskforceTasksMutatedDetail {
6
7
  taskId?: string | null;
7
8
  reason?: 'agent-comment' | 'agent-checklist' | 'workflow-step';
8
9
  authoritativeTask?: TaskItem | null;
10
+ authoritativeWorkflowAssignment?: WorkflowAssignmentDetails | null;
9
11
  affectedCollections?: TaskCollection[];
10
12
  }
11
13
  export declare function dispatchTaskforceTasksMutated(detail: TaskforceTasksMutatedDetail): void;
@@ -1,5 +1,5 @@
1
1
  import type { LocalSyncCoordinatorStatusResponse } from '../sync/coordinator/localSyncCoordinatorBrowserClient';
2
- export type HeaderWorkspaceSyncStatus = 'off' | 'syncing' | 'attention' | 'healthy';
2
+ export type HeaderWorkspaceSyncStatus = 'off' | 'checking' | 'syncing' | 'attention' | 'healthy';
3
3
  type WorkspaceSyncBlockedReason = 'cloud-auth-unconfigured' | 'runtime-not-local' | 'sync-disabled' | 'invalid-workspace' | 'repair-active' | 'attach-cloud' | 'provision-local' | 'auth-required' | 'push-in-flight' | 'pull-in-flight' | 'retry-pending' | 'lease-held';
4
4
  interface ResolveHeaderWorkspaceSyncPresentationInput {
5
5
  runtimeMode: 'local' | 'cloud';
@@ -1,3 +1,4 @@
1
+ import { resolveLocalWorkspaceSyncPendingV2PushProgress } from '../sync/coordinator/localWorkspaceSyncPendingV2PushProgress';
1
2
  export function isWorkspaceSyncAuthenticationError(message) {
2
3
  return /\btaskforce session is invalid\b|\bauthenticated taskforce session is required\b/i
3
4
  .test(message || '');
@@ -7,23 +8,20 @@ export function resolveCoordinatorWorkspaceSyncPresentation(source) {
7
8
  return null;
8
9
  const snapshot = source.snapshot;
9
10
  if (source.phase !== 'ready') {
10
- if (snapshot?.state.ownershipMode === 'browser-gateway' && source.phase !== 'error') {
11
- return null;
12
- }
13
11
  const unavailable = source.phase === 'error';
14
12
  const authenticationRequired = isWorkspaceSyncAuthenticationError(source.errorMessage);
15
13
  return {
16
14
  header: {
17
- actionable: true,
18
- status: unavailable ? 'attention' : 'syncing',
15
+ actionable: unavailable,
16
+ status: unavailable ? 'attention' : 'checking',
19
17
  syncEnabledLabel: 'unknown',
20
18
  summary: unavailable
21
19
  ? 'The shared sync coordinator status is unavailable.'
22
20
  : 'Reading shared sync coordinator status.',
23
21
  recommendedAction: unavailable
24
22
  ? authenticationRequired
25
- ? 'Sign out and sign back in, then retry sync.'
26
- : 'Retry sync. If the coordinator remains unavailable, restart the local server.'
23
+ ? 'Sign out and sign back in so automatic sync can resume.'
24
+ : 'Wait for automatic recovery. If the coordinator remains unavailable, restart the local server.'
27
25
  : 'Wait for the coordinator status check to finish.',
28
26
  lastError: source.errorMessage || (unavailable ? 'Coordinator status unavailable.' : 'None'),
29
27
  },
@@ -61,8 +59,16 @@ export function resolveCoordinatorWorkspaceSyncPresentation(source) {
61
59
  const recoveryObligations = snapshot.permits.recoveryObligations;
62
60
  const pendingV2Push = checkpoint?.pendingV2Push || null;
63
61
  const pushBatchProgress = pendingV2Push?.lastBatchProgress || null;
64
- const pendingV2PushChangeCount = Math.max(0, (pendingV2Push?.frozenPayload.changes.length || 0)
65
- - (pushBatchProgress?.completedChanges || 0));
62
+ const effectivePushProgress = resolveLocalWorkspaceSyncPendingV2PushProgress(pendingV2Push);
63
+ const pendingV2PushChangeCount = effectivePushProgress?.remainingChanges
64
+ ?? Math.max(0, (pendingV2Push?.frozenPayload.changes.length || 0)
65
+ - (pushBatchProgress?.completedChanges || 0));
66
+ const settledPushBatches = effectivePushProgress?.settledBatches
67
+ ?? pushBatchProgress?.completedBatches
68
+ ?? 0;
69
+ const totalPushBatches = effectivePushProgress?.effectiveTotalBatches
70
+ ?? pushBatchProgress?.totalBatches
71
+ ?? 0;
66
72
  const contentPushBlocked = Boolean(pushBatchProgress
67
73
  && (pushBatchProgress.failureDomain === 'content'
68
74
  || pushBatchProgress.failureDomain === 'mixed')
@@ -95,7 +101,7 @@ export function resolveCoordinatorWorkspaceSyncPresentation(source) {
95
101
  else if (runnerUnavailable) {
96
102
  status = 'attention';
97
103
  summary = 'The shared sync runner is unavailable.';
98
- recommendedAction = 'Retry sync. If the runner does not recover, restart the local server.';
104
+ recommendedAction = 'Wait for automatic recovery. If the runner does not recover, restart the local server.';
99
105
  }
100
106
  else if (attachmentApplyOpen > 0) {
101
107
  status = 'attention';
@@ -120,7 +126,7 @@ export function resolveCoordinatorWorkspaceSyncPresentation(source) {
120
126
  summary = `${pushBatchProgress.failedChangeCount} ${failedChangeKind} ${pushBatchProgress.failedChangeCount === 1 ? 'change is' : 'changes are'} waiting to retry; ${pendingV2PushChangeCount} total push ${pendingV2PushChangeCount === 1 ? 'change remains' : 'changes remain'}.`;
121
127
  recommendedAction = checkpoint && !checkpoint.syncEnabled
122
128
  ? 'Turn on sync to resume the bounded content retry.'
123
- : 'Wait for the scheduled content retry, or press Retry now.';
129
+ : 'Wait for the scheduled content retry.';
124
130
  }
125
131
  else if (checkpoint && !checkpoint.syncEnabled) {
126
132
  status = 'off';
@@ -131,12 +137,12 @@ export function resolveCoordinatorWorkspaceSyncPresentation(source) {
131
137
  else if (runnerError && !runnerOperationActive) {
132
138
  status = 'attention';
133
139
  summary = checkpoint?.lastError || 'The shared sync runner reported an error.';
134
- recommendedAction = 'Press Retry now. If the same issue returns, press Repair.';
140
+ recommendedAction = 'Wait for the automatic retry. If the same issue returns, press Repair.';
135
141
  }
136
142
  else if (retryWait) {
137
143
  status = 'attention';
138
144
  summary = 'Sync is waiting for a scheduled retry.';
139
- recommendedAction = 'Wait for the retry, or press Retry now.';
145
+ recommendedAction = 'Wait for the scheduled retry.';
140
146
  }
141
147
  else if (baselineUnknown) {
142
148
  status = 'attention';
@@ -208,7 +214,7 @@ export function resolveCoordinatorWorkspaceSyncPresentation(source) {
208
214
  label: 'Content push backlog',
209
215
  value: contentPushBlocked
210
216
  ? `${pushBatchProgress.failedChangeCount} blocked ${pushBatchProgress.failureDomain === 'content' ? 'content' : 'push'} ${pushBatchProgress.failedChangeCount === 1 ? 'change' : 'changes'}; ${pendingV2PushChangeCount} total push ${pendingV2PushChangeCount === 1 ? 'change remains' : 'changes remain'}; `
211
- + `${pushBatchProgress.completedBatches}/${pushBatchProgress.totalBatches} batches settled`
217
+ + `${settledPushBatches}/${totalPushBatches} batches settled`
212
218
  : 'None',
213
219
  },
214
220
  {
@@ -227,7 +233,7 @@ function resolveBlockedReasonPresentation(reason) {
227
233
  case 'auth-required':
228
234
  return {
229
235
  summary: 'Sync is paused until you sign in again.',
230
- recommendedAction: 'Sign in, then press Sync to retry.'
236
+ recommendedAction: 'Sign in so automatic sync can resume.'
231
237
  };
232
238
  case 'attach-cloud':
233
239
  return {
@@ -242,12 +248,12 @@ function resolveBlockedReasonPresentation(reason) {
242
248
  case 'repair-active':
243
249
  return {
244
250
  summary: 'Repair is already running for this workspace.',
245
- recommendedAction: 'Wait for repair to finish before retrying sync.'
251
+ recommendedAction: 'Wait for repair to finish.'
246
252
  };
247
253
  case 'retry-pending':
248
254
  return {
249
255
  summary: 'Sync hit a temporary problem and is waiting for its scheduled retry.',
250
- recommendedAction: 'Wait for the automatic retry, or press Sync to retry now.'
256
+ recommendedAction: 'Wait for the automatic retry.'
251
257
  };
252
258
  case 'lease-held':
253
259
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taskforcehq/taskforce",
3
- "version": "0.3.329",
3
+ "version": "0.3.332",
4
4
  "description": "Shared task and planning workspace for humans collaborating with AI (public beta)",
5
5
  "author": "Taskforce HQ <hello@taskforcehq.ai> (https://taskforcehq.ai)",
6
6
  "license": "SEE LICENSE IN LICENSE.md",
@@ -61,7 +61,7 @@
61
61
  "build:app": "vite build --config vite.config.standalone.ts",
62
62
  "build:ui": "npm run build:app",
63
63
  "check:verified": "sh scripts/run-validation-command.sh",
64
- "check:deploy-preflight": "npm run build",
64
+ "check:deploy-preflight": "npm run build && npm run build:site && npm run build:admin",
65
65
  "hooks:install": "git config core.hooksPath .githooks",
66
66
  "build": "shx rm -rf dist && tsc && shx cp src/Taskforce.module.css dist/Taskforce.module.css && shx mkdir -p dist/styles && shx cp src/styles/fonts.css dist/styles/fonts.css && shx mkdir -p dist/assets/fonts && shx cp src/assets/fonts/*.woff2 dist/assets/fonts/ && shx mkdir -p dist/public && shx cp -r src/assets/images/* dist/public/ && shx cp -r src/assets/favicon/* dist/public/ && shx chmod +x dist/cli.js && npm run build:ui",
67
67
  "mcp": "node dist/cli.js mcp",
@@ -98,6 +98,7 @@
98
98
  "test:sync:program-scaffold:postgres": "vitest run src/sync/v3/programScaffoldService.postgres.integration.test.ts",
99
99
  "test:postgres:run": "node scripts/run-with-disposable-postgres.mjs --",
100
100
  "test:postgres:smoke": "node scripts/run-with-disposable-postgres.mjs -- npm run test:sync:coordinator:postgres",
101
+ "test:executor-phase-a:postgres": "npm run build && node scripts/run-with-disposable-postgres.mjs -- npx vitest run --maxWorkers=1 --hookTimeout=120000 src/storage/executorPhaseAApprovalReceiptStore.postgres.integration.test.ts src/storage/executorPhaseARunAuthorizationStore.postgres.integration.test.ts",
101
102
  "test:cloud-read-workers:postgres": "npm run build && node scripts/run-with-disposable-postgres.mjs -- node scripts/run-cloud-collection-read-worker-gate.mjs",
102
103
  "test:soak": "sh scripts/run-soak.sh",
103
104
  "test:soak:smoke": "SYNC_SOAK_PROFILE=smoke sh scripts/run-soak.sh",
@@ -113,7 +114,7 @@
113
114
  "test:aqr:sync-fault-matrix": "node --import tsx scripts/aqr/sync-fault-matrix.ts",
114
115
  "test:aqr:cloud-writers:contract": "vitest run scripts/aqr/cloud-writer-acceptance.test.ts",
115
116
  "test:aqr:cloud-writers": "node --import tsx scripts/aqr/cloud-writer-acceptance.ts",
116
- "test:aqr:remote-sync:contract": "vitest run scripts/aqr/remote-sync-run.test.ts",
117
+ "test:aqr:remote-sync:contract": "vitest run scripts/aqr/remote-sync-run.test.ts && node --test scripts/aqr/reap-digitalocean-runners.test.mjs",
117
118
  "test:aqr:remote-sync": "node --import tsx scripts/aqr/remote-sync-run.ts",
118
119
  "aqr:smoke": "node --import tsx scripts/run-aqr-capsule.ts --contract-smoke",
119
120
  "test:e2e:realtime": "sh scripts/run-e2e-realtime.sh",
@@ -129,6 +130,7 @@
129
130
  "test:e2e:realtime:durable-initiative": "npm run test:e2e:realtime -- tests/e2e/durable-initiative-canary.spec.ts",
130
131
  "test:e2e:realtime:durable-initiative-feed": "SYNC_V3_INITIATIVE_FEED_CANARY_ENABLED=true npm run test:e2e:realtime:durable-initiative",
131
132
  "test:e2e:realtime:durable-combined-feed": "SYNC_V3_COMBINED_CANARY_ENABLED=true npm run test:e2e:realtime -- tests/e2e/durable-combined-feed-canary.spec.ts",
133
+ "test:e2e:realtime:durable-workflow-runtime-v8": "SYNC_V3_WORKFLOW_RUNTIME_V8_CANARY_ENABLED=true npm run test:e2e:realtime -- tests/e2e/durable-workflow-runtime-v8-canary.spec.ts",
132
134
  "test:e2e:onboarding": "npx playwright test -c playwright.e2e.config.ts tests/e2e/auth-runtime.spec.ts tests/e2e/billing-runtime.spec.ts",
133
135
  "test:billing:deterministic": "npx vitest run src/server/routes/billing.test.ts src/components/views/PlansPage.test.tsx src/components/views/PlanComparisonPage.test.tsx src/migrations/billingSchemaParity.test.ts",
134
136
  "test:billing:runtime:mock": "npx playwright test -c playwright.e2e.config.ts tests/e2e/billing-runtime.spec.ts",
@@ -142,6 +144,8 @@
142
144
  "mailpit:down": "docker compose -f docker-compose.mailpit.yml down",
143
145
  "mailpit:check": "node scripts/check-mailpit.mjs",
144
146
  "qa:railway:check": "node scripts/check-railway-qa-access.mjs",
147
+ "verify:performance-deploy": "node scripts/wait-for-performance-deploy.mjs",
148
+ "test:performance-deploy-verifier": "node --test scripts/wait-for-performance-deploy.test.mjs",
145
149
  "playwright:interactive": "playwright test -c playwright.interactive.config.ts tests/e2e/interactive.smoke.spec.ts",
146
150
  "playwright:interactive:headed": "playwright test --headed -c playwright.interactive.config.ts tests/e2e/interactive.smoke.spec.ts",
147
151
  "playwright:planning": "playwright test -c playwright.interactive.config.ts tests/e2e/planning-workspace.interactive.spec.ts",
@@ -155,9 +159,19 @@
155
159
  "check:mcp-smoke": "node scripts/check-cloud-mcp.mjs",
156
160
  "check:mcp-connection": "node scripts/check-authenticated-mcp.mjs",
157
161
  "check:mcp-latency": "node scripts/run-mcp-latency-gate.mjs",
162
+ "check:mcp-capacity": "node scripts/run-mcp-capacity-gate.mjs",
163
+ "baseline:mcp:s1:cloud": "sh scripts/run-mcp-s1-cloud-baseline.sh",
164
+ "baseline:mcp:s1:assemble": "node scripts/assemble-mcp-s1-baseline.mjs",
165
+ "test:mcp:s1-baseline": "node --test scripts/run-mcp-latency-gate.test.mjs scripts/run-mcp-s1-cloud-baseline.test.mjs scripts/assemble-mcp-s1-baseline.test.mjs",
166
+ "test:mcp:conformance:2025": "node --import tsx scripts/run-mcp-conformance-gate.ts --requirements 2025-11-25",
167
+ "test:mcp:conformance:2026": "node --import tsx scripts/run-mcp-conformance-gate.ts --requirements 2026-07-28",
168
+ "test:mcp:conformance": "npm run test:mcp:conformance:2025 && npm run test:mcp:conformance:2026",
169
+ "test:mcp:conformance:contract": "vitest run tests/mcp/conformance/gateEvidence.test.ts tests/mcp/conformance/httpHarness.test.ts tests/mcp/conformance/stdioCompanion.test.ts",
158
170
  "check:cloud-performance": "sh scripts/run-cloud-performance-gate.sh",
159
171
  "check:committed-mcp-secrets": "node scripts/check-committed-mcp-secrets.mjs",
160
172
  "test:committed-mcp-secrets": "node --test scripts/check-committed-mcp-secrets.test.mjs",
173
+ "executor-capability-probe": "node scripts/executor-capability-probe.mjs",
174
+ "test:executor-capability-probe": "node --test scripts/executor-capability-policy.test.mjs scripts/executor-capability-probe.test.mjs scripts/executor-phase-a-evidence-envelope.test.mjs scripts/executor-provider-tunnel.test.mjs",
161
175
  "check:native-deps": "node scripts/check-native-deps.cjs",
162
176
  "model-gateway:smoke": "node --import tsx scripts/model-gateway-smoke.ts",
163
177
  "model-gateway:mantle-smoke": "node --import tsx scripts/model-gateway-mantle-smoke.ts",
@@ -178,11 +192,16 @@
178
192
  "dependencies": {
179
193
  "@aws-sdk/client-bedrock-runtime": "^3.1075.0",
180
194
  "@iarna/toml": "^2.2.5",
181
- "@modelcontextprotocol/sdk": "^1.25.3",
195
+ "@modelcontextprotocol/client": "^2.0.0",
196
+ "@modelcontextprotocol/core": "^2.0.0",
197
+ "@modelcontextprotocol/node": "^2.0.0",
198
+ "@modelcontextprotocol/server": "^2.0.0",
199
+ "@openai/codex": "0.148.0-alpha.9",
182
200
  "@smithy/hash-node": "^4.4.2",
183
201
  "ajv": "~8.18.0",
184
202
  "better-sqlite3": "^12.6.2",
185
203
  "chokidar": "^3.6.0",
204
+ "json-canonicalize": "2.0.0",
186
205
  "lucide-react": "^0.474.0",
187
206
  "nodemailer": "^9.0.3",
188
207
  "openai": "^6.45.0",
@@ -197,6 +216,7 @@
197
216
  "@dnd-kit/core": "^6.3.1",
198
217
  "@dnd-kit/sortable": "^10.0.0",
199
218
  "@dnd-kit/utilities": "^3.2.2",
219
+ "@modelcontextprotocol/conformance": "0.2.0-alpha.11",
200
220
  "@playwright/test": "^1.58.2",
201
221
  "@testing-library/jest-dom": "^6.9.1",
202
222
  "@testing-library/react": "^16.3.2",
@@ -1 +0,0 @@
1
- import{W as C,t as a}from"./index-I5zhdtgt.js";import{j as i}from"./vendor-react-CKJs5o3c.js";const l=["red-500","orange-500","amber-500","green-700","teal-700","sky-500","sky-700","blue-500","indigo-700","violet-500"];function y(e){const r=String(e||"ai").trim().toLowerCase();let s=2166136261;for(let t=0;t<r.length;t+=1)s^=r.charCodeAt(t),s=Math.imul(s,16777619);const o=l[(s>>>0)%l.length];return C[o].toLowerCase()}function $(e){const[r,s=""]=e.split("#"),o=r.includes("?")?"&":"?";return`${r}${o}taskforceCloud=1${s?`#${s}`:""}`}function A(e){return/^https?:\/\//i.test(e)?e:$(e)}function N({name:e,username:r,subtitle:s,avatar:o,selected:t,disabled:n=!1,onSelect:c,ariaLabel:d,avatarVariant:u="portrait",avatarClassName:f="",avatarStyle:p,className:m="",topUtility:h,bottomUtility:P,footer:x}){return i.jsxs("button",{type:"button",className:`${a.aiProfileGroup} ${t?a.aiProfileGroupSelected:""} ${m}`.trim(),onClick:c,disabled:n,"aria-label":d,"aria-pressed":t,children:[h,P,i.jsxs("span",{className:a.aiProfileGroupHeader,children:[i.jsx("span",{className:`${a.aiProfileGroupAvatar} ${u==="logo"?a.aiProfileGroupAvatarLogo:""} ${f}`.trim(),style:p,"aria-hidden":"true",children:o}),i.jsxs("span",{className:a.aiProfileGroupIdentity,children:[i.jsx("span",{className:a.aiProfileName,children:e}),r?i.jsxs("span",{className:a.aiProfileHandle,children:["@",r]}):null,i.jsx("span",{className:a.aiProfileRole,children:s}),x]})]})]})}export{N as A,y as a,l as b,A as r,$ as w};
@@ -1 +0,0 @@
1
- import{r as f,j as a}from"./vendor-react-CKJs5o3c.js";import{ad as qe,ae as re,Q as Ue,af as ea,ag as W,t as r,V as aa,W as ra,ah as ta,ai as Re,X as ia,aj as oa,ak as te,al as Me,am as la,Z as sa,Y as Ee,a0 as b,a1 as ke}from"./index-I5zhdtgt.js";import{A as na,b as ca,r as Ce}from"./AiIdentityRosterCard-BZM4aQnM.js";import{ay as da,ak as fa,U as ua,w as pa,Z as J,J as Le,ax as ma,aC as va}from"./vendor-icons-D9Lpw-j4.js";import"./vendor-markdown-_lhNCyq-.js";import"./vendor-dnd-CJ-AjP-Y.js";import"./vendor-router-AqJMU8Lz.js";const ga=["chat_app","ide","cli","coding_tool","taskforce_agent","agent","unclassified"];function L(o){return typeof o.avatarUrl=="string"&&o.avatarUrl.trim().length>0}function ie(o){return o?Ee(o.avatarUrl,o.avatarRevision,o.avatarUpdatedAt):""}function ha(o){return o?Ee(o.avatarSourceUrl,o.avatarRevision,o.avatarUpdatedAt):""}function ya(o){return o.find(L)||o[0]}function Pa({profile:o,className:g=""}){const A=ie(o),$=W(o),{activeImageUrl:T,handleImageError:Y}=sa(A,$);return T?a.jsx("img",{src:T,alt:"",className:g,onError:Y}):a.jsx(Le,{size:22})}function K(o){const g=te(o);return g?`taskforce-agent:${g}`:`${o.seatScope||"unknown"}:${o.name.trim().toLowerCase()}`}function oe(o){const g=o.providerMetadata?.taskforce;return!!(g&&typeof g=="object"&&!Array.isArray(g)&&String(g.taskforceAgentId||"").trim())}function Aa(o){return oe(o)?"taskforce_agent":Me(o.surfaceType)}function Te(o){return o==="taskforce_agent"?"Taskforce Agents":la(o)}function Sa(o){return oe(o)?"Taskforce Agent":o.surfaceType?Re(o.surfaceType):""}function xa(o){const g=Math.max(0,o-1);return`${g} duplicate${g===1?"":"s"}`}function we(o){return!o||typeof o!="object"?null:{used:Math.max(0,Number(o.used||0)),limit:o.limit===null||o.limit===void 0?null:Math.max(0,Number(o.limit||0)),remaining:o.remaining===null||o.remaining===void 0?null:Math.max(0,Number(o.remaining||0))}}function De(o,g){const A=g?.variant==="inline"?`${r.aiProfileSeatScopeIcon} ${r.aiProfileSeatScopeIconInline}`:g?.variant==="detail"?`${r.aiProfileSeatScopeIcon} ${r.aiProfileSeatScopeIconDetail}`:r.aiProfileSeatScopeIcon;return o==="cloud_metered"?a.jsx("span",{className:`${A} ${r.aiProfileSeatScopeIconCloud}`,title:"Cloud MCP","aria-label":"Cloud MCP",children:a.jsx(ma,{size:20})}):o==="local_unmetered"?a.jsx("span",{className:`${A} ${r.aiProfileSeatScopeIconLocal}`,title:"Local MCP","aria-label":"Local MCP",children:a.jsx(va,{size:20})}):null}function Ta({workspaceId:o,runtimeMode:g="local",cloudAuthConfigured:A=!1,authSessionResolved:$=!1,isAuthenticated:T=!1,cloudAiProfileSeatUsage:Y=null,agentTrayOpen:Z=!1,onCloseAgentTray:$e,mcpSettingsNode:le=null,resolveCloudAuthUrl:B,theme:Be="dark",onNotice:w}){const[N,O]=f.useState([]),[Oe,Fe]=f.useState(null),[Ge,se]=f.useState(!1),[S,F]=f.useState(null),[G,D]=f.useState(null),[ne,Q]=f.useState(null),[_e,ce]=f.useState(!1),[U,_]=f.useState(null),[de,fe]=f.useState(null),[ue,z]=f.useState(!1),[ze,P]=f.useState(null),[He,x]=f.useState(null),[R,pe]=f.useState(null),[me,k]=f.useState({}),[ve,ge]=f.useState(!1),[X,he]=f.useState(!1),[ye,Pe]=f.useState(null),C=f.useCallback(async()=>{if(o){se(!0);try{const e=`/api/taskforce/workspace/assignee-options?workspaceId=${encodeURIComponent(o)}&kind=agent`,t=await fetch(e,{credentials:"include"}),l=t.ok?await t.json().catch(()=>({})):{},s=we(l?.aiProfileSeatUsage),d=Array.isArray(l?.assignees)?l.assignees.filter(i=>i.kind==="agent").map(i=>({id:String(i.value||""),name:String(i.label||i.value||"Unknown Agent"),username:String(i.username||i.value||""),icon:String(i.icon||"Bot"),color:String(i.color||"#6B7280"),colorSource:typeof i.colorSource=="string"?i.colorSource:null,colorUpdatedAt:typeof i.colorUpdatedAt=="string"?i.colorUpdatedAt:null,avatarUrl:typeof i.avatarUrl=="string"?i.avatarUrl:null,avatarSourceUrl:typeof i.avatarSourceUrl=="string"?i.avatarSourceUrl:null,avatarRevision:Number.isFinite(Number(i.avatarRevision))?Math.max(0,Math.floor(Number(i.avatarRevision))):0,avatarUpdatedAt:typeof i.avatarUpdatedAt=="string"?i.avatarUpdatedAt:null,kind:String(i.kind||"agent"),description:typeof i.description=="string"?i.description:null,role:typeof i.role=="string"?i.role:null,provider:typeof i.provider=="string"?i.provider:null,model:typeof i.model=="string"?i.model:null,surfaceType:re(i.surfaceType),seatScope:qe(i.seatScope),providerMetadata:i.providerMetadata&&typeof i.providerMetadata=="object"&&!Array.isArray(i.providerMetadata)?i.providerMetadata:null,archivedAt:typeof i.archivedAt=="string"?i.archivedAt:null,createdAt:String(i.createdAt||""),updatedAt:String(i.updatedAt||i.createdAt||""),lastActiveAt:typeof i.lastActiveAt=="string"?i.lastActiveAt:null})):[];O(d),Fe(s),D(i=>i&&!d.some(u=>u.id===i.profileId)?null:i),Q(i=>i&&!d.some(u=>u.id===i.profileId)?null:i)}finally{se(!1)}}},[o]);f.useEffect(()=>{C()},[C]),f.useEffect(()=>{const e=t=>{const l=t.detail;(String(l?.workspaceId||"").trim()||"default")===o&&l?.origin!=="ai-profiles-module"&&C()};return window.addEventListener(Ue,e),()=>window.removeEventListener(Ue,e)},[C,o]);const H=f.useMemo(()=>{const e=new Map;for(const t of N){const l=Aa(t);e.has(l)||e.set(l,new Map);const s=e.get(l),d=K(t);s.has(d)||s.set(d,[]),s.get(d).push(t)}return ga.map(t=>({section:t,label:Te(t),groups:Array.from(e.get(t)?.entries()||[]).map(([l,s])=>({groupId:`${t}:${l}`,section:t,sectionLabel:Te(t),profiles:s,primaryProfile:ya(s)}))})).filter(t=>t.groups.length>0)},[N]),j=f.useMemo(()=>H.flatMap(e=>e.groups),[H]),n=f.useMemo(()=>j.find(e=>e.groupId===U)||j[0]||null,[j,U]),p=f.useMemo(()=>N.find(e=>e.id===de)||null,[N,de]),Ae=p&&me[p.id]||null,Se=n&&me[n.primaryProfile.id]||null;f.useEffect(()=>{if(!j.length){U!==null&&_(null);return}(!U||!j.some(e=>e.groupId===U))&&_(j[0].groupId)},[j,U]);const Ve=async(e,t)=>{D(null);try{const l=await fetch("/api/taskforce/workspace/ai-profiles/merge",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({keepId:e,mergeId:t})}),s=await l.json().catch(()=>({}));if(!l.ok){w?.(String(s?.error||"Failed to merge AI profiles."),"error");return}F(null),w?.("AI profiles merged.","success"),await C(),b({workspaceId:o,profileId:e,reason:"merge",origin:"ai-profiles-module"})}catch{w?.("Failed to merge AI profiles.","error")}},xe=async e=>{if(window.confirm(`Remove ${e.name} from the active roster? This frees an AI profile seat and preserves task and comment history.`)){D(null);try{const l=await fetch("/api/taskforce/workspace/ai-profiles/archive",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({profileId:e.id,reason:"manual_archive"})}),s=await l.json().catch(()=>({}));if(!l.ok){D({profileId:e.id,message:String(s?.error||"Failed to remove AI profile from roster.")});return}(S?.keepId===e.id||S?.mergeId===e.id)&&F(null),w?.("AI profile removed from active roster.","success"),await C(),b({workspaceId:o,profileId:e.id,reason:"archive",origin:"ai-profiles-module"})}catch{D({profileId:e.id,message:"Failed to remove AI profile from roster."})}}},Je=async(e,t)=>{const l=re(t),s=new Set(e.profiles.map(u=>u.surfaceType??"")),d=l??"";if(s.size===1&&s.has(d))return;ce(!0),Q(null);const i=[];try{for(const c of e.profiles){const m=await fetch("/api/taskforce/workspace/ai-profiles/surface-type",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({profileId:c.id,surfaceType:l})}),v=await m.json().catch(()=>({}));if(!m.ok||!v?.profile)throw new Error(String(v?.error||"Failed to update AI profile category."));const I=v.profile;i.push({...c,surfaceType:re(I.surfaceType),updatedAt:typeof I.updatedAt=="string"?I.updatedAt:c.updatedAt})}const u=new Map(i.map(c=>[c.id,c]));O(c=>c.map(m=>u.get(m.id)||m));const h=u.get(e.primaryProfile.id)||{...e.primaryProfile,surfaceType:l},y=Me(h.surfaceType);_(`${y}:${K(h)}`),w?.("AI profile category updated.","success");for(const c of i)b({workspaceId:o,profileId:c.id,reason:"update",origin:"ai-profiles-module"})}catch(u){Q({profileId:e.primaryProfile.id,message:String(u?.message||"Failed to update AI profile category.")})}finally{ce(!1)}},je=async(e,t,l=!1)=>{he(!0),Pe(null);try{const s=K(e.primaryProfile),d=N.filter(c=>K(c)===s),i=await fetch("/api/taskforce/workspace/ai-profiles/color",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({profileIds:d.map(c=>c.id),color:t,reset:l})}),u=await i.text();let h={};try{h=u?JSON.parse(u):{}}catch{h={}}if(!i.ok){const c=i.status===404?"Color updates are unavailable in the running Taskforce server. Restart Taskforce and try again.":`Failed to update AI profile color (HTTP ${i.status}).`;throw new Error(String(h.error||c))}if(!Array.isArray(h.profiles))throw new Error("Taskforce returned an invalid response while updating the AI profile color.");const y=new Map(h.profiles.map(c=>[String(c.id),c]));O(c=>c.map(m=>{const v=y.get(m.id);return v?{...m,color:String(v.color||m.color),colorSource:v.colorSource??m.colorSource,colorUpdatedAt:v.colorUpdatedAt??m.colorUpdatedAt,updatedAt:v.updatedAt??m.updatedAt}:m})),ge(!1);for(const c of d)b({workspaceId:o,profileId:c.id,reason:"update",origin:"ai-profiles-module"})}catch(s){Pe(String(s?.message||"Failed to update AI profile color."))}finally{he(!1)}},Ie=e=>new Promise((t,l)=>{const s=new FileReader;s.onload=()=>t(String(s.result||"")),s.onerror=()=>l(new Error("Failed to read image file.")),s.readAsDataURL(e)}),q=e=>{const t=String(e?.id||"").trim();t&&O(l=>l.map(s=>s.id===t?{...s,avatarUrl:typeof e.avatarUrl=="string"?e.avatarUrl:null,avatarSourceUrl:typeof e.avatarSourceUrl=="string"?e.avatarSourceUrl:null,avatarRevision:Number.isFinite(Number(e.avatarRevision))?Math.max(0,Math.floor(Number(e.avatarRevision))):s.avatarRevision,avatarUpdatedAt:typeof e.avatarUpdatedAt=="string"?e.avatarUpdatedAt:s.avatarUpdatedAt,updatedAt:typeof e.updatedAt=="string"?e.updatedAt:s.updatedAt}:s))},Ke=async(e,t,l,s=!1)=>{const d=await Ie(t),i=l?await Ie(l):null,u={profileId:e,preserveExistingSource:s,displayImage:{dataUrl:d,mimeType:t.type||"application/octet-stream",originalName:t.name||"display-avatar"}};l&&i&&(u.sourceImage={dataUrl:i,mimeType:l.type||"application/octet-stream",originalName:l.name||"source-avatar"});const h=await fetch("/api/taskforce/workspace/ai-profiles/avatar/upload",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify(u)}),y=await h.json().catch(()=>({}));if(!h.ok||!y?.profile)throw new Error(String(y?.error||"Failed to update AI profile avatar."));q(y.profile),b({workspaceId:o,profileId:e,reason:"avatar",origin:"ai-profiles-module"})},We=async e=>{const t=await fetch("/api/taskforce/workspace/ai-profiles/avatar",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({profileId:e,avatarUrl:null,avatarSourceUrl:null})}),l=await t.json().catch(()=>({}));if(!t.ok||!l?.profile)throw new Error(String(l?.error||"Failed to update AI profile avatar."));q(l.profile),b({workspaceId:o,profileId:e,reason:"avatar",origin:"ai-profiles-module"})},Ye=async e=>{if(R)return!1;const t=te(e),l=L(e);if(l&&!window.confirm(`Replace the existing avatar for ${e.name}?`))return!1;const s=t?"":window.prompt("Optional visual direction (300 characters maximum). Leave blank to use the profile details.","");if(s===null)return!1;const d=g==="local";if(d&&(!A||!$||!T||!B))return P("Sign in to Taskforce Cloud to generate profile avatars."),x(null),!1;pe(e.id),P(null),x(null),k(i=>({...i,[e.id]:{error:null,notice:null}}));try{const i=t?`/api/taskforce/agents/${encodeURIComponent(t)}/avatar/generate`:"/api/taskforce/workspace/ai-profiles/avatar/generate",u=d&&B?B(i):i,h=await fetch(u,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify(t?{workspaceId:o}:{workspaceId:o,profileId:e.id,visualDirection:s.slice(0,300),replaceExisting:l})}),y=await h.text().catch(()=>"");let c={};if(y&&!/^\s*(?:<!doctype\s+html|<html\b)/i.test(y))try{c=JSON.parse(y)}catch{c={}}if(!h.ok||!c?.profile&&!c?.agent)throw new Error(String(c?.error||(h.status?`Unable to generate avatar. HTTP ${h.status}.`:"Unable to generate avatar.")));const m=c.profile||{id:e.id,avatarUrl:c.agent?.avatarUrl??null,avatarSourceUrl:c.agent?.avatarSourceUrl??null,avatarRevision:c.agent?.avatarRevision??0,avatarUpdatedAt:c.agent?.avatarUpdatedAt??null},v=d&&B?{...m,avatarUrl:m.avatarUrl?Ce(m.avatarUrl):m.avatarUrl,avatarSourceUrl:m.avatarSourceUrl?Ce(m.avatarSourceUrl):m.avatarSourceUrl}:m;return q(v),k(d?I=>({...I,[e.id]:{error:null,notice:`Generated photo for ${e.name} was saved in Taskforce Cloud. The local copy will be retained when sync runs.`}}):I=>({...I,[e.id]:{error:null,notice:`Generated photo for ${e.name} was saved.`}})),b({workspaceId:o,profileId:e.id,reason:"avatar",origin:"ai-profiles-module",...t?{taskforceAgentAvatar:{agentId:t,avatarUrl:typeof v.avatarUrl=="string"?v.avatarUrl:null,avatarSourceUrl:typeof v.avatarSourceUrl=="string"?v.avatarSourceUrl:null,avatarRevision:Number.isFinite(Number(v.avatarRevision))?Math.max(0,Math.floor(Number(v.avatarRevision))):0,avatarUpdatedAt:typeof v.avatarUpdatedAt=="string"?v.avatarUpdatedAt:null}}:{}}),!0}catch(i){return k(u=>({...u,[e.id]:{error:String(i?.message||"Unable to generate profile avatar."),notice:null}})),!1}finally{pe(null)}},Ze=async(e,t,l)=>{if(!p)return!1;if(!e.type.startsWith("image/"))return P("AI profile photo must be an image file."),!1;z(!0),P(null),x(null),k(s=>{const d={...s};return delete d[p.id],d});try{const s=await ke(e,{maxBytes:5242880});if(s.exceededLimit)throw new Error(e.type==="image/gif"?"Animated GIF AI profile photos must be 5 MB or smaller.":"AI profile photo must be 5 MB or smaller.");const d=s.file;let i=null;if(t){const u=await ke(t,{maxBytes:5242880});if(u.exceededLimit)throw new Error(t.type==="image/gif"?"Animated GIF AI profile photos must be 5 MB or smaller.":"AI profile source photo must be 5 MB or smaller.");i=u.file}return await Ke(p.id,d,i,l?.preserveExistingSource===!0),!0}catch(s){return P(String(s?.message||"Failed to update AI profile photo.")),!1}finally{z(!1)}},Qe=async()=>{if(p){z(!0),P(null),x(null),k(e=>{const t={...e};return delete t[p.id],t});try{await We(p.id),x("Profile photo removed.")}catch(e){P(String(e?.message||"Failed to remove AI profile photo."))}finally{z(!1)}}},M=e=>{const t=String(e||"").trim();if(!t)return"Unknown";const l=Date.parse(t);return Number.isFinite(l)?new Date(l).toLocaleString(void 0,{dateStyle:"medium",timeStyle:"short"}):t},be=f.useMemo(()=>{if(!n)return{attributes:[],dates:[]};const e=n.primaryProfile,t=l=>l||"Not set";return{attributes:[{label:"Category",value:Sa(e)},{label:"Connection",value:e.seatScope?ea(e.seatScope):""},{label:"Provider",value:e.provider||""},{label:"Model",value:e.model||""}].map(l=>({...l,value:t(l.value)})),dates:[{label:"Status",value:e.archivedAt?"Retired":"Active"},{label:"Recruited",value:M(e.createdAt)},{label:"Last updated",value:M(e.updatedAt)},{label:"Last active",value:M(e.lastActiveAt)}].map(l=>({...l,value:t(l.value)}))}},[n]),Xe=!!n&&n.profiles.length>1,E=!!n&&!L(n.primaryProfile)&&!!W(n.primaryProfile),Ne=A&&$&&!T,V=A?we(Y):Oe,ee=Ne?"Log into account for Cloud AI Profiles":V?`${V.used}/${V.limit===null?"Unlimited":V.limit}`:null,ae=!!le;return a.jsxs("section",{className:`${r.agentsModuleRoot} ${ae?r.agentsModuleWithTray:""} ${ae&&Z?r.agentsModuleTrayOpen:""}`.trim(),children:[ae&&a.jsxs("aside",{className:`${r.agentTrayPanel} ${Z?r.agentTrayPanelOpen:""}`.trim(),"aria-label":"AI Profile MCP settings tray","aria-hidden":!Z,children:[a.jsxs("div",{className:r.agentTrayHeader,children:[a.jsxs("span",{className:r.agentTrayTitle,children:[a.jsx(da,{size:14}),"MCP Settings"]}),a.jsx("button",{type:"button",className:"tf-control-icon",onClick:$e,title:"Collapse AI Profile tray","aria-label":"Collapse AI Profile tray",children:a.jsx(fa,{size:16})})]}),a.jsx("div",{className:`${r.agentTrayContent} tf-scrollbar tf-scrollbar--track-transparent`,children:a.jsx("div",{className:r.agentTrayContentInner,children:le})})]}),a.jsx("div",{className:r.agentsModuleContent,children:a.jsxs("div",{className:r.aiProfilesExplorer,children:[a.jsxs("aside",{className:r.aiProfilesRosterPanel,"aria-label":"AI profile roster",children:[a.jsx("div",{className:r.taskforceAgentRosterHeader,children:a.jsxs("span",{className:r.taskforceAgentRosterTitle,children:[a.jsx(ua,{size:14}),"AI Profiles"]})}),ee&&a.jsx("div",{className:r.aiProfilesRosterSummary,children:a.jsx("div",{className:r.aiProfileSeatSummary,children:Ne?ee:`Registered Cloud AI Profiles: ${ee}`})}),Ge?a.jsxs("div",{className:r.aiProfilesRosterState,role:"status","aria-live":"polite",children:[a.jsx(pa,{size:13,className:r.spinner})," Loading profiles…"]}):N.length===0?a.jsx("div",{className:r.aiProfilesRosterState,children:"No AI profiles registered yet."}):H.length>0?a.jsx("div",{className:`${r.aiProfilesListPane} tf-scrollbar tf-scrollbar--track-transparent tf-tray-scroll-viewport`,children:a.jsx("div",{className:r.aiProfilesList,children:H.map(e=>a.jsxs("div",{className:r.aiProfilesSection,children:[a.jsx("div",{className:r.aiProfilesSectionHeader,children:e.label}),e.groups.map(t=>{const l=n?.groupId===t.groupId,s=t.primaryProfile,d=!L(s)&&!!W(s);return a.jsx(na,{name:s.name,username:s.username,subtitle:s.role||"Role not set",selected:l,onSelect:()=>_(t.groupId),avatarVariant:d?"logo":"portrait",avatar:a.jsx(Pa,{profile:s}),avatarStyle:{color:s.color},className:t.profiles.length>1?r.aiProfileGroupDuplicate:"",topUtility:De(s.seatScope),bottomUtility:a.jsx("span",{className:r.aiProfileGroupSignatureSwatch,style:{backgroundColor:s.color},title:`Signature color ${s.color}`,"aria-hidden":"true"}),footer:t.profiles.length>1?a.jsxs("span",{className:r.aiProfileDuplicateBadge,children:[a.jsx(J,{size:11})," ",xa(t.profiles.length)]}):null},t.groupId)})]},e.section))})}):null]}),a.jsx("main",{className:`${r.aiProfilesDetailViewport} tf-scrollbar`,"aria-label":"AI profile details",children:n&&a.jsx("div",{className:r.aiProfileDetailPane,children:a.jsxs("div",{className:r.aiProfileDetailCard,children:[De(n.primaryProfile.seatScope,{variant:"detail"}),a.jsxs("div",{className:r.aiProfileDetailHero,children:[a.jsx(aa,{label:"Edit AI profile photo",imageUrl:ie(n.primaryProfile),fallbackImageUrl:W(n.primaryProfile),fallback:a.jsx(Le,{size:38}),accentColor:E?null:n.primaryProfile.color,size:176,width:E?176:153,height:E?176:207,radius:E?0:6,editBadgeSize:28,editIconSize:14,loading:R===n.primaryProfile.id,loadingLabel:`Generating ${n.primaryProfile.name} photo`,error:!!Se?.error,errorLabel:Se?.error||"Profile photo generation failed",className:`${r.aiProfileDetailAvatar} ${E?r.aiProfileDetailAvatarLogo:""}`.trim(),onClick:()=>{P(null),x(null),fe(n.primaryProfile.id)}}),a.jsxs("div",{className:r.aiProfileDetailHeading,children:[a.jsx("div",{className:r.aiProfileDetailTitleRow,children:a.jsx("h5",{className:r.aiProfileDetailTitle,children:n.primaryProfile.name})}),a.jsxs("div",{className:r.aiProfileDetailMetaRow,children:[a.jsxs("span",{className:r.aiProfileDetailHandle,children:["@",n.primaryProfile.username]}),n.profiles.length>1&&a.jsxs("span",{className:r.aiProfileDetailLinkedCount,children:[n.profiles.length," linked"]})]}),a.jsxs("div",{className:r.aiProfileDetailRole,children:["Role: ",n.primaryProfile.role||"Not set"]}),n.primaryProfile.description&&a.jsx("div",{className:r.aiProfileDetailDescription,children:n.primaryProfile.description}),a.jsxs("div",{className:r.aiProfileSignatureColor,children:[a.jsx("span",{children:"Signature color"}),a.jsxs("button",{type:"button",className:r.aiProfileSignatureColorButton,onClick:()=>ge(e=>!e),disabled:X,"aria-expanded":ve,"aria-label":"Change signature color",children:[a.jsx("span",{className:r.aiProfileSignatureSwatch,style:{backgroundColor:n.primaryProfile.color},"aria-hidden":"true"}),a.jsx("span",{children:n.primaryProfile.color})]})]}),ve&&a.jsxs("div",{className:r.aiProfileColorPicker,"aria-label":"Signature color options",children:[ca.map(e=>{const t=ra[e];return a.jsx("button",{type:"button",className:r.aiProfileColorOption,style:{backgroundColor:t},"aria-label":`Use ${e}`,"aria-pressed":n.primaryProfile.color.toLowerCase()===t.toLowerCase(),disabled:X,onClick:()=>{je(n,t)}},e)}),a.jsx("button",{type:"button",className:r.secondaryHeaderBtn,disabled:X,onClick:()=>{je(n,void 0,!0)},children:"Reset"})]}),ye&&a.jsx("div",{className:r.aiProfileInlineError,children:ye})]})]}),a.jsxs("div",{className:r.aiProfileDetailDataList,children:[a.jsx("div",{className:r.aiProfileDetailDataGroup,children:be.attributes.map(e=>a.jsxs("div",{className:r.aiProfileDetailDataRow,children:[a.jsx("span",{className:r.aiProfileDetailDataLabel,children:e.label}),e.label==="Category"&&!oe(n.primaryProfile)?a.jsx("span",{className:r.aiProfileDetailDataValue,children:a.jsxs("select",{className:r.aiProfileStatusSelect,"aria-label":"Agent category",value:n.primaryProfile.surfaceType??"",disabled:_e,onChange:t=>{Je(n,t.target.value)},children:[a.jsx("option",{value:"",children:"Unclassified"}),ta.map(t=>a.jsx("option",{value:t,children:Re(t)},t))]})}):a.jsx("span",{className:r.aiProfileDetailDataValue,children:e.value})]},e.label))}),a.jsx("div",{className:`${r.aiProfileDetailDataGroup} ${r.aiProfileDetailDateGroup}`,children:be.dates.map(e=>a.jsxs("div",{className:r.aiProfileDetailDataRow,children:[a.jsx("span",{className:r.aiProfileDetailDataLabel,children:e.label}),e.label==="Status"?a.jsx("span",{className:r.aiProfileDetailDataValue,children:a.jsxs("select",{className:r.aiProfileStatusSelect,"aria-label":"Agent roster status",value:n.primaryProfile.archivedAt?"retired":"active",onChange:t=>{t.target.value==="retire"&&xe(n.primaryProfile)},children:[a.jsx("option",{value:"active",children:"Active"}),n.primaryProfile.archivedAt?a.jsx("option",{value:"retired",children:"Retired"}):a.jsx("option",{value:"retire",children:"Retire from roster"})]})}):a.jsx("span",{className:r.aiProfileDetailDataValue,children:e.value})]},e.label))})]}),ne?.profileId===n.primaryProfile.id&&a.jsxs("div",{className:r.aiProfileInlineError,role:"alert",children:[a.jsx(J,{size:12}),a.jsx("span",{children:ne.message})]}),Xe?a.jsxs("div",{className:r.aiProfileInstanceSection,children:[a.jsxs("div",{className:r.aiProfileInstanceSectionHeader,children:[a.jsx("span",{children:"Profile instances"}),a.jsx("span",{className:r.settingsHint,children:"Choose a keeper here if duplicates need to be merged."})]}),a.jsx("div",{className:r.aiProfileInstanceList,children:n.profiles.map(e=>a.jsxs("div",{className:r.aiProfileInstanceCard,children:[a.jsxs("div",{className:r.aiProfileInstanceTopRow,children:[a.jsxs("div",{children:[a.jsxs("div",{className:r.aiProfileInstanceName,children:["@",e.username]}),a.jsx("div",{className:r.aiProfileIdChip,children:e.id})]}),S?.keepId===e.id&&a.jsx("span",{className:r.aiProfileKeepBadge,children:"Keeping"})]}),a.jsxs("div",{className:r.aiProfileInstanceMeta,children:[a.jsxs("span",{children:["Created ",M(e.createdAt)]}),a.jsxs("span",{children:["Updated ",M(e.updatedAt)]})]}),S?.keepId!==e.id&&a.jsx("button",{className:r.secondaryHeaderBtn,title:"Keep this profile, merge others into it",onClick:()=>{const t=n.profiles.find(l=>l.id!==e.id)?.id;t&&F({keepId:e.id,mergeId:t})},children:"Keep this"}),G?.profileId===e.id&&a.jsxs("div",{className:r.aiProfileInlineError,role:"alert",children:[a.jsx(J,{size:12}),a.jsx("span",{children:G.message})]}),a.jsx("button",{className:r.aiProfileDangerTextButton,title:"Remove this profile from the active roster",onClick:()=>{xe(e)},children:"Remove from roster"})]},e.id))}),S&&n.profiles.some(e=>e.id===S.keepId)&&a.jsxs("div",{className:r.aiProfileMergeActions,children:[a.jsx("button",{className:r.dangerBtn,onClick:()=>{Ve(S.keepId,S.mergeId)},children:"Merge duplicates"}),a.jsx("button",{className:r.secondaryHeaderBtn,onClick:()=>F(null),children:"Cancel"})]})]}):a.jsxs("div",{className:r.aiProfileIdFooter,children:[a.jsx("div",{className:r.aiProfileIdFooterValue,children:n.primaryProfile.id}),G?.profileId===n.primaryProfile.id&&a.jsxs("div",{className:r.aiProfileInlineError,role:"alert",children:[a.jsx(J,{size:12}),a.jsx("span",{children:G.message})]})]})]})})})]})}),a.jsx(ia,{isOpen:!!p,theme:Be,title:"Edit AI Profile Photo",currentImageUrl:ie(p),editorImageUrl:ha(p),fallbackInitial:(p?.name||"AI").charAt(0).toUpperCase(),accept:"image/png,image/jpeg,image/webp,image/gif",busy:ue,generating:R===p?.id,generateLabel:p&&L(p)?"Regenerate":"Generate",hasPendingImage:!1,canRemove:!!p?.avatarUrl,error:ze||Ae?.error||null,notice:He||Ae?.notice||null,onClose:()=>{ue||(fe(null),P(null),x(null))},onApplyImage:Ze,onGenerateImage:p&&(!R||R===p.id)&&(oa(p)||te(p))?()=>Ye(p):void 0,onRemoveImage:Qe},p?.id||"ai-profile-avatar-closed")]})}export{Ta as AiProfilesModule};