@taskforcehq/taskforce 0.3.328 → 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 (485) hide show
  1. package/dist/Taskforce.module.css +523 -79
  2. package/dist/TaskforceCore.js +237 -230
  3. package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.js +1 -1
  4. package/dist/cli.js +34 -0
  5. package/dist/cliCloudTargetGuard.d.ts +5 -0
  6. package/dist/cliCloudTargetGuard.js +11 -0
  7. package/dist/components/features/AiProfilesModule.js +3 -5
  8. package/dist/components/features/AnnotatedAttachmentWorkspace.js +24 -8
  9. package/dist/components/features/TaskSettings.d.ts +12 -1
  10. package/dist/components/features/TaskSettings.js +217 -54
  11. package/dist/components/features/TaskforceAgentsModule.d.ts +1 -2
  12. package/dist/components/features/TaskforceAgentsModule.js +586 -116
  13. package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.d.ts +1 -1
  14. package/dist/components/features/agentConnections/AgentConnectionControl.d.ts +15 -0
  15. package/dist/components/features/agentConnections/AgentConnectionControl.js +125 -0
  16. package/dist/components/features/agentConnections/ModelConnectionsPanel.d.ts +18 -0
  17. package/dist/components/features/agentConnections/ModelConnectionsPanel.js +393 -0
  18. package/dist/components/features/agentConnections/modelConnectionsApi.d.ts +65 -0
  19. package/dist/components/features/agentConnections/modelConnectionsApi.js +129 -0
  20. package/dist/components/features/planning/PlanningModule.js +2 -5
  21. package/dist/components/features/planning/PlanningTaskOrderList.d.ts +1 -1
  22. package/dist/components/features/planning/PlanningTaskOrderList.js +17 -6
  23. package/dist/components/features/planning/planningTaskArrangement.d.ts +1 -0
  24. package/dist/components/features/planning/planningTaskArrangement.js +5 -5
  25. package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +15 -24
  26. package/dist/components/features/taskforceAgentEditorModel.d.ts +2 -1
  27. package/dist/components/features/taskforceAgentEditorModel.js +5 -1
  28. package/dist/components/features/workflowManager/workflowManagerApi.d.ts +1 -1
  29. package/dist/components/features/workflowManager/workflowManagerApi.js +3 -0
  30. package/dist/components/task/TaskCard.d.ts +5 -0
  31. package/dist/components/task/TaskCard.js +65 -10
  32. package/dist/components/task/TaskImageReviews.js +14 -5
  33. package/dist/components/task/TaskKanban.d.ts +6 -1
  34. package/dist/components/task/TaskKanban.js +152 -6
  35. package/dist/components/task/TaskList.d.ts +5 -0
  36. package/dist/components/task/TaskList.js +3 -3
  37. package/dist/components/task/TaskWorkflowAssignmentField.js +68 -10
  38. package/dist/components/ui/PasswordInput.d.ts +6 -0
  39. package/dist/components/ui/PasswordInput.js +11 -0
  40. package/dist/components/ui/TopNoticeLayer.js +1 -1
  41. package/dist/components/views/AppShellHeader.js +32 -11
  42. package/dist/components/views/PlanComparisonPage.js +12 -0
  43. package/dist/components/views/StandaloneLayout.js +32 -55
  44. package/dist/components/views/WidgetView.js +3 -3
  45. package/dist/components/views/panels/PlanningDrawer.js +5 -12
  46. package/dist/components/views/standalone/modals/AccountSettingsModal.js +26 -17
  47. package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +4 -3
  48. package/dist/components/views/standalone/modals/SyncStatusModal.js +33 -38
  49. package/dist/config/envSchema.js +60 -1
  50. package/dist/config/localServiceRuntimeContract.d.ts +13 -0
  51. package/dist/config/localServiceRuntimeContract.js +135 -0
  52. package/dist/core/AiProfileService.js +46 -8
  53. package/dist/core/DeletedTaskLifecycleService.d.ts +1 -0
  54. package/dist/core/DeletedTaskLifecycleService.js +37 -6
  55. package/dist/core/McpTokenService.d.ts +23 -1
  56. package/dist/core/McpTokenService.js +93 -10
  57. package/dist/core/TaskAttachmentLinksDurableMutationService.d.ts +3 -2
  58. package/dist/core/TaskAttachmentLinksDurableMutationService.js +33 -9
  59. package/dist/core/TaskChecklistCommandService.d.ts +27 -0
  60. package/dist/core/TaskChecklistCommandService.js +83 -5
  61. package/dist/core/TaskLifecycleCommandService.d.ts +3 -1
  62. package/dist/core/TaskLifecycleCommandService.js +6 -2
  63. package/dist/core/Taskforce.d.ts +94 -2
  64. package/dist/core/Taskforce.js +760 -36
  65. package/dist/core/types.d.ts +14 -0
  66. package/dist/documentReviews/commandService.d.ts +2 -1
  67. package/dist/documentReviews/commandService.js +6 -3
  68. package/dist/hooks/sync/orchestratorShared.d.ts +1 -0
  69. package/dist/hooks/sync/orchestratorShared.js +2 -0
  70. package/dist/hooks/sync/useDurableLocalOutboxDrain.d.ts +1 -1
  71. package/dist/hooks/sync/useDurableTaskCreateMutation.js +1 -1
  72. package/dist/hooks/sync/useDurableTaskMetadataMutation.d.ts +1 -0
  73. package/dist/hooks/sync/useDurableTaskMetadataMutation.js +1 -0
  74. package/dist/hooks/sync/useDurableTaskStatusMutation.d.ts +1 -0
  75. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.d.ts +3 -0
  76. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.js +85 -9
  77. package/dist/hooks/sync/useSyncStatusControls.d.ts +4 -1
  78. package/dist/hooks/sync/useSyncStatusControls.js +47 -11
  79. package/dist/hooks/tasks/taskHttpMutation.js +1 -0
  80. package/dist/hooks/tasks/useCloudTaskSearch.d.ts +12 -0
  81. package/dist/hooks/tasks/useCloudTaskSearch.js +71 -0
  82. package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.d.ts +16 -0
  83. package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.js +197 -0
  84. package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +16 -3
  85. package/dist/hooks/tasks/useTaskEditorNavigation.js +72 -13
  86. package/dist/hooks/tasks/useTaskFormActions.d.ts +6 -0
  87. package/dist/hooks/tasks/useTaskFormActions.js +65 -12
  88. package/dist/hooks/ui/useSettingsModel.d.ts +24 -2
  89. package/dist/hooks/ui/useSettingsModel.js +13 -2
  90. package/dist/hooks/ui/useSettingsPersistence.d.ts +12 -1
  91. package/dist/hooks/ui/useSettingsPersistence.js +74 -47
  92. package/dist/hooks/useFilterSort.d.ts +7 -3
  93. package/dist/hooks/useFilterSort.js +15 -5
  94. package/dist/hooks/useSyncOrchestrator.d.ts +3 -0
  95. package/dist/hooks/useSyncOrchestrator.js +111 -2
  96. package/dist/hooks/useTaskData.d.ts +40 -1
  97. package/dist/hooks/useTaskData.js +240 -9
  98. package/dist/hooks/useTaskMutations.d.ts +12 -2
  99. package/dist/hooks/useTaskMutations.js +266 -52
  100. package/dist/hooks/useTaskforce.d.ts +39 -9
  101. package/dist/hooks/useTaskforce.js +359 -40
  102. package/dist/hooks/useUiNotice.d.ts +4 -0
  103. package/dist/hooks/useUiNotice.js +4 -0
  104. package/dist/mcp/adminWorkspaceRegistrar.js +3 -3
  105. package/dist/mcp/clientRegistry.d.ts +2 -2
  106. package/dist/mcp/clientRegistry.js +1 -1
  107. package/dist/mcp/documentAssetRegistrar.js +53 -41
  108. package/dist/mcp/documentHelpers.d.ts +1 -0
  109. package/dist/mcp/documentHelpers.js +7 -3
  110. package/dist/mcp/durableTaskMutationRouter.d.ts +4 -1
  111. package/dist/mcp/durableTaskMutationRouter.js +10 -0
  112. package/dist/mcp/durableTaskRelationshipMutationRouter.js +4 -0
  113. package/dist/mcp/httpProtocolRouting.d.ts +10 -0
  114. package/dist/mcp/httpProtocolRouting.js +19 -0
  115. package/dist/mcp/localCliHealth.d.ts +2 -2
  116. package/dist/mcp/localCliHealth.js +2 -2
  117. package/dist/mcp/localServiceProxy.d.ts +1 -0
  118. package/dist/mcp/localServiceProxy.js +530 -68
  119. package/dist/mcp/planningAttachmentCommandAdapter.d.ts +3 -1
  120. package/dist/mcp/planningAttachmentCommandAdapter.js +20 -2
  121. package/dist/mcp/runtime.d.ts +54 -79
  122. package/dist/mcp/runtime.js +556 -139
  123. package/dist/mcp/taskPlanningRegistrar.js +64 -42
  124. package/dist/mcp/toolCallCompatibility.js +38 -1
  125. package/dist/mcp/toolCatalog.d.ts +1 -0
  126. package/dist/mcp/toolProfiles.d.ts +2 -0
  127. package/dist/mcp/toolProfiles.js +10 -0
  128. package/dist/mcp/toolRegistry.d.ts +1 -0
  129. package/dist/mcp/toolRegistry.js +1 -0
  130. package/dist/mcp/workflowExecutionRegistrar.js +4 -4
  131. package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
  132. package/dist/migrations/taskSchemaMigrations.js +427 -0
  133. package/dist/runtime/appGateDefinitions.d.ts +30 -6
  134. package/dist/runtime/appGateDefinitions.js +6 -6
  135. package/dist/runtime/appGates.d.ts +13 -13
  136. package/dist/runtime/appGates.js +36 -13
  137. package/dist/runtime/nodeAppGates.d.ts +8 -0
  138. package/dist/runtime/nodeAppGates.js +27 -0
  139. package/dist/server/cloudCollectionRead.d.ts +1 -1
  140. package/dist/server/cloudCollectionRead.js +2 -2
  141. package/dist/server/index.d.ts +6 -0
  142. package/dist/server/index.js +123 -14
  143. package/dist/server/localDatabaseIdentity.js +4 -1
  144. package/dist/server/localServiceLease.d.ts +3 -0
  145. package/dist/server/localServiceLease.js +11 -2
  146. package/dist/server/localServiceSessions.d.ts +14 -17
  147. package/dist/server/localServiceSessions.js +308 -94
  148. package/dist/server/localWorkspaceSyncServerRuntime.js +12 -7
  149. package/dist/server/rateLimit.d.ts +1 -0
  150. package/dist/server/rateLimit.js +4 -0
  151. package/dist/server/realtimeSyncWs.js +36 -12
  152. package/dist/server/routes/admin.d.ts +4 -0
  153. package/dist/server/routes/admin.js +113 -3
  154. package/dist/server/routes/agentRoles.js +3 -2
  155. package/dist/server/routes/agentSkills.js +3 -2
  156. package/dist/server/routes/agents.d.ts +7 -0
  157. package/dist/server/routes/agents.js +394 -39
  158. package/dist/server/routes/annotatedAttachments.js +3 -2
  159. package/dist/server/routes/auth.js +3 -1
  160. package/dist/server/routes/billing.js +5 -1
  161. package/dist/server/routes/durableTaskHttpRouters.d.ts +11 -2
  162. package/dist/server/routes/executorPhaseAApprovals.d.ts +19 -0
  163. package/dist/server/routes/executorPhaseAApprovals.js +140 -0
  164. package/dist/server/routes/executorPhaseAIssuerRedemptions.d.ts +11 -0
  165. package/dist/server/routes/executorPhaseAIssuerRedemptions.js +24 -0
  166. package/dist/server/routes/githubReviewEvidence.d.ts +19 -0
  167. package/dist/server/routes/githubReviewEvidence.js +116 -0
  168. package/dist/server/routes/localService.d.ts +15 -4
  169. package/dist/server/routes/localService.js +138 -40
  170. package/dist/server/routes/modelConnections.d.ts +24 -0
  171. package/dist/server/routes/modelConnections.js +205 -0
  172. package/dist/server/routes/primitives.d.ts +2 -0
  173. package/dist/server/routes/shared.d.ts +19 -0
  174. package/dist/server/routes/shared.js +95 -19
  175. package/dist/server/routes/sync.js +1 -0
  176. package/dist/server/routes/syncAuxRoutes.js +9 -2
  177. package/dist/server/routes/syncPullApplyRoutes.js +23 -4
  178. package/dist/server/routes/syncPushRoutes.d.ts +1 -0
  179. package/dist/server/routes/syncPushRoutes.js +1 -0
  180. package/dist/server/routes/syncV3FeedRoutes.js +27 -16
  181. package/dist/server/routes/syncV3LocalCaptureRoutes.js +28 -2
  182. package/dist/server/routes/syncV3LocalFeedApplyRoutes.d.ts +1 -0
  183. package/dist/server/routes/syncV3LocalFeedApplyRoutes.js +26 -0
  184. package/dist/server/routes/syncV3OperationRoutes.js +45 -9
  185. package/dist/server/routes/tasks.js +124 -13
  186. package/dist/server/routes/workflows.js +9 -1
  187. package/dist/server/routes/workspaces.js +43 -1
  188. package/dist/server/routes.js +59 -0
  189. package/dist/server/workspaceDeletionAdmission.d.ts +23 -0
  190. package/dist/server/workspaceDeletionAdmission.js +50 -0
  191. package/dist/service/localServiceCli.js +16 -0
  192. package/dist/service/localServiceClientLifecycle.js +36 -10
  193. package/dist/services/codexAppServerModelGateway.d.ts +161 -0
  194. package/dist/services/codexAppServerModelGateway.js +663 -0
  195. package/dist/services/codexDeviceCodeLoginManager.d.ts +39 -0
  196. package/dist/services/codexDeviceCodeLoginManager.js +265 -0
  197. package/dist/services/codexModelProviderConnectionLifecycle.d.ts +8 -0
  198. package/dist/services/codexModelProviderConnectionLifecycle.js +73 -0
  199. package/dist/services/executorPhaseAApprovalRuntime.d.ts +14 -0
  200. package/dist/services/executorPhaseAApprovalRuntime.js +24 -0
  201. package/dist/services/executorPhaseAApprovalService.d.ts +40 -0
  202. package/dist/services/executorPhaseAApprovalService.js +609 -0
  203. package/dist/services/executorPhaseADriftEvaluator.d.ts +78 -0
  204. package/dist/services/executorPhaseADriftEvaluator.js +93 -0
  205. package/dist/services/executorPhaseAIssuerCore.d.ts +126 -0
  206. package/dist/services/executorPhaseAIssuerCore.js +295 -0
  207. package/dist/services/executorPhaseAIssuerRedemptionService.d.ts +34 -0
  208. package/dist/services/executorPhaseAIssuerRedemptionService.js +158 -0
  209. package/dist/services/githubReviewEvidenceRuntime.d.ts +14 -0
  210. package/dist/services/githubReviewEvidenceRuntime.js +30 -0
  211. package/dist/services/githubReviewEvidenceService.d.ts +93 -0
  212. package/dist/services/githubReviewEvidenceService.js +336 -0
  213. package/dist/services/modelGateway.d.ts +7 -0
  214. package/dist/services/modelProviderConnectionService.d.ts +71 -0
  215. package/dist/services/modelProviderConnectionService.js +279 -0
  216. package/dist/services/modelProviderCredentialHome.d.ts +32 -0
  217. package/dist/services/modelProviderCredentialHome.js +271 -0
  218. package/dist/services/ownerScopedModelConnectionGateway.d.ts +12 -0
  219. package/dist/services/ownerScopedModelConnectionGateway.js +30 -0
  220. package/dist/services/taskforceAgentConnectionBindingService.d.ts +66 -0
  221. package/dist/services/taskforceAgentConnectionBindingService.js +185 -0
  222. package/dist/services/taskforceAgentMcpBridge.d.ts +8 -2
  223. package/dist/services/taskforceAgentMcpBridge.js +30 -27
  224. package/dist/shared/adminEdgeProxy.d.ts +5 -0
  225. package/dist/shared/adminEdgeProxy.js +94 -0
  226. package/dist/shared/adminProxySessionCookies.d.ts +16 -0
  227. package/dist/shared/adminProxySessionCookies.js +86 -0
  228. package/dist/shared/aiProfileColors.d.ts +31 -1
  229. package/dist/shared/aiProfileColors.js +14 -6
  230. package/dist/shared/executorPhaseAApprovalGoldenVector.json +269 -0
  231. package/dist/shared/executorPhaseAApprovalReceipt.d.ts +112 -0
  232. package/dist/shared/executorPhaseAApprovalReceipt.js +58 -0
  233. package/dist/shared/executorPhaseAApprovalTrustPolicy.json +10 -0
  234. package/dist/shared/executorPhaseADriftContracts.d.ts +37 -0
  235. package/dist/shared/executorPhaseADriftContracts.js +63 -0
  236. package/dist/shared/executorPhaseAIssuerContracts.d.ts +75 -0
  237. package/dist/shared/executorPhaseAIssuerContracts.js +90 -0
  238. package/dist/shared/executorPhaseARunAuthorization.d.ts +120 -0
  239. package/dist/shared/executorPhaseARunAuthorization.js +232 -0
  240. package/dist/shared/executorPhaseASchemaValidation.d.ts +7 -0
  241. package/dist/shared/executorPhaseASchemaValidation.js +53 -0
  242. package/dist/shared/executorPhaseASchemas/approval-receipt.schema.json +106 -0
  243. package/dist/shared/executorPhaseASchemas/drift-attestation.schema.json +54 -0
  244. package/dist/shared/executorPhaseASchemas/drift-request.schema.json +47 -0
  245. package/dist/shared/executorPhaseASchemas/foundation-manifest.schema.json +29 -0
  246. package/dist/shared/executorPhaseASchemas/issuer-audit-record.schema.json +24 -0
  247. package/dist/shared/executorPhaseASchemas/issuer-proof.schema.json +43 -0
  248. package/dist/shared/executorPhaseASchemas/issuer-redemption-request.schema.json +18 -0
  249. package/dist/shared/executorPhaseASchemas/issuer-redemption-response.schema.json +39 -0
  250. package/dist/shared/executorPhaseASchemas/logical-envelope.schema.json +149 -0
  251. package/dist/shared/executorPhaseASchemas/preflight-report.schema.json +216 -0
  252. package/dist/shared/executorPhaseASchemas/run-capability.schema.json +111 -0
  253. package/dist/shared/executorPhaseASchemas/sender-proof.schema.json +37 -0
  254. package/dist/shared/executorPhaseASchemas/workload-grant.schema.json +68 -0
  255. package/dist/shared/executorPhaseASchemas/workload-jwt-claims.schema.json +67 -0
  256. package/dist/shared/executorPhaseATiming.d.ts +1 -0
  257. package/dist/shared/executorPhaseATiming.js +1 -0
  258. package/dist/shared/planningIdentity.js +1 -1
  259. package/dist/shared/productLogoKeys.d.ts +2 -0
  260. package/dist/shared/productLogoKeys.js +18 -0
  261. package/dist/shared/taskforceAgentDefinition.d.ts +0 -1
  262. package/dist/shared/taskforceAgentDefinition.js +6 -3
  263. package/dist/shared/taskforceAgentModels.d.ts +1 -0
  264. package/dist/shared/taskforceAgentModels.js +36 -3
  265. package/dist/shared/userFeatureGrants.d.ts +4 -0
  266. package/dist/shared/userFeatureGrants.js +7 -0
  267. package/dist/storage/executorPhaseAApprovalReceiptStore.d.ts +37 -0
  268. package/dist/storage/executorPhaseAApprovalReceiptStore.js +81 -0
  269. package/dist/storage/executorPhaseARunAuthorizationStore.d.ts +103 -0
  270. package/dist/storage/executorPhaseARunAuthorizationStore.js +492 -0
  271. package/dist/storage/githubReviewEvidenceInstallationStore.d.ts +26 -0
  272. package/dist/storage/githubReviewEvidenceInstallationStore.js +89 -0
  273. package/dist/storage/modelProviderConnectionStore.d.ts +99 -0
  274. package/dist/storage/modelProviderConnectionStore.js +446 -0
  275. package/dist/storage/postgresAdapter.d.ts +24 -3
  276. package/dist/storage/postgresAdapter.js +117 -14
  277. package/dist/storage/postgresWorker.js +22 -5
  278. package/dist/storage/postgresWorkerProtocol.d.ts +30 -0
  279. package/dist/storage/postgresWorkerProtocol.js +30 -0
  280. package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
  281. package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -0
  282. package/dist/sync/cloudSyncApi.d.ts +4 -1
  283. package/dist/sync/cloudSyncApi.js +7 -2
  284. package/dist/sync/contentSyncState.d.ts +1 -1
  285. package/dist/sync/coordinator/localSyncExecutionPermitStore.d.ts +1 -0
  286. package/dist/sync/coordinator/localSyncExecutionPermitStore.js +67 -30
  287. package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.d.ts +10 -0
  288. package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.js +29 -0
  289. package/dist/sync/coordinator/localWorkspaceSyncRunner.js +6 -2
  290. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.d.ts +15 -1
  291. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.js +99 -2
  292. package/dist/sync/coordinator/workspaceSyncCredentialBroker.d.ts +1 -0
  293. package/dist/sync/coordinator/workspaceSyncCredentialBroker.js +33 -4
  294. package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.d.ts +2 -1
  295. package/dist/sync/engine/workspaceSyncContentVersionStore.d.ts +38 -0
  296. package/dist/sync/engine/workspaceSyncContentVersionStore.js +50 -1
  297. package/dist/sync/engine/workspaceSyncEngineBrowserGatewayRemoteServices.js +20 -2
  298. package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +6 -6
  299. package/dist/sync/engine/workspaceSyncEngineLocalServices.d.ts +4 -0
  300. package/dist/sync/engine/workspaceSyncEngineLocalServices.js +11 -0
  301. package/dist/sync/engine/workspaceSyncEnginePushCompletion.d.ts +14 -0
  302. package/dist/sync/engine/workspaceSyncEnginePushCompletion.js +84 -0
  303. package/dist/sync/engine/workspaceSyncEngineRecovery.js +1 -0
  304. package/dist/sync/engine/workspaceSyncEngineRemoteServices.d.ts +11 -0
  305. package/dist/sync/engine/workspaceSyncEngineRemoteServices.js +2 -1
  306. package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +1 -0
  307. package/dist/sync/engine/workspaceSyncEngineRuntime.js +1 -0
  308. package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.js +31 -4
  309. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.d.ts +3 -1
  310. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +134 -43
  311. package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +6 -0
  312. package/dist/sync/engine/workspaceSyncEngineTransfers.d.ts +1 -1
  313. package/dist/sync/engine/workspaceSyncEngineTransfers.js +11 -4
  314. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.d.ts +1 -0
  315. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +29 -0
  316. package/dist/sync/syncApplyHandlers.d.ts +2 -0
  317. package/dist/sync/syncApplyHandlers.js +10 -1
  318. package/dist/sync/syncService.d.ts +17 -0
  319. package/dist/sync/syncService.js +87 -19
  320. package/dist/sync/taskforceAgentSyncAuthorization.d.ts +16 -0
  321. package/dist/sync/taskforceAgentSyncAuthorization.js +20 -0
  322. package/dist/sync/v3/combinedFeedCapability.js +8 -0
  323. package/dist/sync/v3/durableInitiativeMutationRouter.js +18 -10
  324. package/dist/sync/v3/durableOperationReplay.d.ts +14 -0
  325. package/dist/sync/v3/durableOperationReplay.js +18 -0
  326. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.d.ts +2 -0
  327. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +14 -1
  328. package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +4 -1
  329. package/dist/sync/v3/durableTaskChecklistMutationRouter.js +62 -15
  330. package/dist/sync/v3/durableTaskCommentMutationRouter.js +3 -0
  331. package/dist/sync/v3/durableTaskHttpBulkMutationRouter.d.ts +1 -0
  332. package/dist/sync/v3/durableTaskHttpBulkMutationRouter.js +30 -8
  333. package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +5 -3
  334. package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +37 -2
  335. package/dist/sync/v3/durableTaxonomyMutationRouter.js +5 -0
  336. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.d.ts +11 -0
  337. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +39 -10
  338. package/dist/sync/v3/durableWorkstreamMutationRouter.js +18 -10
  339. package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.js +16 -5
  340. package/dist/sync/v3/localOutboxDispatchRuntime.js +2 -2
  341. package/dist/sync/v3/localTaskAttachmentLinksOutboxService.d.ts +2 -0
  342. package/dist/sync/v3/localTaskAttachmentLinksOutboxService.js +47 -7
  343. package/dist/sync/v3/localTaskChecklistOutboxHandler.js +16 -2
  344. package/dist/sync/v3/localTaskChecklistOutboxService.d.ts +4 -0
  345. package/dist/sync/v3/localTaskChecklistOutboxService.js +14 -1
  346. package/dist/sync/v3/localTaskCreateOutboxService.js +15 -6
  347. package/dist/sync/v3/localTaskMetadataClient.d.ts +1 -0
  348. package/dist/sync/v3/localTaskMetadataClient.js +1 -0
  349. package/dist/sync/v3/localTaskMetadataOutboxHandler.js +5 -1
  350. package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -0
  351. package/dist/sync/v3/localTaskMetadataOutboxService.js +7 -0
  352. package/dist/sync/v3/localTaskRestoreOutboxService.js +14 -6
  353. package/dist/sync/v3/localTaskStatusClient.d.ts +1 -0
  354. package/dist/sync/v3/localTaskStatusClient.js +6 -1
  355. package/dist/sync/v3/localTaskStatusOutboxService.d.ts +10 -0
  356. package/dist/sync/v3/localTaskStatusOutboxService.js +272 -24
  357. package/dist/sync/v3/syncDurabilityStore.d.ts +41 -0
  358. package/dist/sync/v3/syncDurabilityStore.js +199 -13
  359. package/dist/sync/v3/taskAttachmentLinksMutationService.d.ts +6 -4
  360. package/dist/sync/v3/taskAttachmentLinksMutationService.js +19 -10
  361. package/dist/sync/v3/taskChecklistMutationService.d.ts +15 -2
  362. package/dist/sync/v3/taskChecklistMutationService.js +48 -1
  363. package/dist/sync/v3/taskCreateMutationService.d.ts +2 -2
  364. package/dist/sync/v3/taskCreateMutationService.js +7 -4
  365. package/dist/sync/v3/taskMetadataMutationService.d.ts +3 -0
  366. package/dist/sync/v3/taskMetadataMutationService.js +4 -0
  367. package/dist/sync/v3/taskRestoreMutationService.d.ts +2 -2
  368. package/dist/sync/v3/taskRestoreMutationService.js +7 -4
  369. package/dist/sync/v3/taskStatusMutationService.d.ts +31 -1
  370. package/dist/sync/v3/taskStatusMutationService.js +123 -3
  371. package/dist/sync/v3/workflowAssignmentSync.d.ts +6 -0
  372. package/dist/sync/v3/workflowAssignmentSync.js +30 -0
  373. package/dist/sync/v3/workspaceSyncJournalReader.js +1 -1
  374. package/dist/sync/v3/workspaceSyncOperationRetentionService.d.ts +16 -0
  375. package/dist/sync/v3/workspaceSyncOperationRetentionService.js +83 -0
  376. package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.d.ts +1 -1
  377. package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.js +13 -3
  378. package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.d.ts +11 -0
  379. package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.js +27 -10
  380. package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.d.ts +2 -1
  381. package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.js +52 -10
  382. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +1 -0
  383. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +18 -3
  384. package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.js +8 -3
  385. package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +51 -10
  386. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +14 -0
  387. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +49 -25
  388. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +13 -4
  389. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +124 -57
  390. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +20 -0
  391. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +106 -30
  392. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +4 -1
  393. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +34 -0
  394. package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +12 -0
  395. package/dist/sync/v3/workspaceSyncV3FeedProfile.d.ts +1 -1
  396. package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.d.ts +1 -0
  397. package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.js +23 -10
  398. package/dist/sync/v3/workspaceSyncV3NestedTaskApply.d.ts +3 -0
  399. package/dist/sync/v3/workspaceSyncV3NestedTaskApply.js +64 -13
  400. package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.d.ts +9 -0
  401. package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.js +26 -0
  402. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +15 -5
  403. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +50 -14
  404. package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.d.ts +2 -1
  405. package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.js +11 -3
  406. package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +5 -0
  407. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +7 -0
  408. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +55 -9
  409. package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.d.ts +17 -0
  410. package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.js +64 -0
  411. package/dist/sync/v3/workspaceSyncV3TaskCommentAudit.js +9 -2
  412. package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.d.ts +7 -0
  413. package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.js +37 -0
  414. package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.d.ts +6 -0
  415. package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.js +9 -0
  416. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.d.ts +7 -0
  417. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.js +33 -0
  418. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.d.ts +7 -0
  419. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.js +8 -0
  420. package/dist/sync/workspacePullFeed.js +2 -1
  421. package/dist/sync/workspaceRepair.d.ts +8 -2
  422. package/dist/sync/workspaceRepair.js +222 -6
  423. package/dist/sync/workspaceSyncModel.d.ts +21 -0
  424. package/dist/sync/workspaceSyncModel.js +35 -7
  425. package/dist/sync/workspaceSyncState.d.ts +1 -0
  426. package/dist/sync/workspaceSyncV2SnapshotBuilder.d.ts +6 -0
  427. package/dist/sync/workspaceSyncV2SnapshotBuilder.js +5 -0
  428. package/dist/types.d.ts +47 -1
  429. package/dist/types.js +6 -0
  430. package/dist/ui/assets/AiIdentityRosterCard-OcSz1PkK.js +1 -0
  431. package/dist/ui/assets/AiProfilesModule-ByhYW5Xi.js +1 -0
  432. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BTM6nIg_.js +3 -0
  433. package/dist/ui/assets/AnnotatedAttachmentWorkspace-TzYu7pkG.css +1 -0
  434. package/dist/ui/assets/{AssetTraySortControl-Kf1pelSy.js → AssetTraySortControl-DabEG8L4.js} +1 -1
  435. package/dist/ui/assets/{ContextAttachmentManager-B8boOs6Q.js → ContextAttachmentManager-Coa8yVGM.js} +2 -2
  436. package/dist/ui/assets/{DocumentWorkspace-DXH4XUsB.js → DocumentWorkspace-BB0qhdix.js} +1 -1
  437. package/dist/ui/assets/{EntityActivityTimeline-BtSTq0ON.js → EntityActivityTimeline-CZ8x4UJE.js} +1 -1
  438. package/dist/ui/assets/PlanningModule-pRPjR7v5.js +1 -0
  439. package/dist/ui/assets/PlansPage-D86pZSSl.js +1 -0
  440. package/dist/ui/assets/TaskContextUpload-BVIkU9yT.js +1 -0
  441. package/dist/ui/assets/TaskSettings-Cv1mNhv_.js +12 -0
  442. package/dist/ui/assets/TaskforceAgentsModule-b-8R25cJ.css +1 -0
  443. package/dist/ui/assets/TaskforceAgentsModule-gmH-PD2q.js +24 -0
  444. package/dist/ui/assets/{WorkflowManagerModule-DWFspC-o.js → WorkflowManagerModule-DbfnHJ-f.js} +1 -1
  445. package/dist/ui/assets/index-BZ-hdZSk.css +1 -0
  446. package/dist/ui/assets/index-CTsDBaef.js +7 -0
  447. package/dist/ui/assets/{vendor-icons-BkFLXavV.js → vendor-icons-Bsq-mcEn.js} +1 -1
  448. package/dist/ui/branding/logos/letterhead_dark.png +0 -0
  449. package/dist/ui/branding/logos/letterhead_light.png +0 -0
  450. package/dist/ui/branding/logos/signature_dark.png +0 -0
  451. package/dist/ui/branding/logos/signature_light.png +0 -0
  452. package/dist/ui/index.html +3 -3
  453. package/dist/utils/aiProfileDefaultLogo.js +16 -48
  454. package/dist/utils/httpSetCookie.d.ts +1 -0
  455. package/dist/utils/httpSetCookie.js +4 -1
  456. package/dist/utils/localRuntimeUrl.d.ts +1 -0
  457. package/dist/utils/localRuntimeUrl.js +14 -0
  458. package/dist/utils/productLogoRegistry.d.ts +2 -0
  459. package/dist/utils/productLogoRegistry.js +36 -0
  460. package/dist/utils/syncStatusPresentation.d.ts +4 -0
  461. package/dist/utils/syncStatusPresentation.js +17 -0
  462. package/dist/utils/taskActivity.d.ts +3 -2
  463. package/dist/utils/taskActivity.js +19 -2
  464. package/dist/utils/taskEditorReconciliation.d.ts +40 -0
  465. package/dist/utils/taskEditorReconciliation.js +217 -0
  466. package/dist/utils/taskEvents.d.ts +2 -0
  467. package/dist/utils/taskNormalization.d.ts +1 -0
  468. package/dist/utils/taskNormalization.js +39 -0
  469. package/dist/utils/taskSearch.js +2 -2
  470. package/dist/utils/uiNotice.d.ts +4 -0
  471. package/dist/utils/workspaceSyncPresentation.d.ts +1 -1
  472. package/dist/utils/workspaceSyncPresentation.js +23 -17
  473. package/package.json +36 -6
  474. package/dist/ui/assets/AiIdentityRosterCard-MZs7lVED.js +0 -1
  475. package/dist/ui/assets/AiProfilesModule-C3i0LOxe.js +0 -1
  476. package/dist/ui/assets/AnnotatedAttachmentWorkspace-CBRZ8rca.css +0 -1
  477. package/dist/ui/assets/AnnotatedAttachmentWorkspace-DVZk5Tln.js +0 -3
  478. package/dist/ui/assets/PlanningModule-BPVyEa-f.js +0 -1
  479. package/dist/ui/assets/PlansPage-ChqgxALc.js +0 -1
  480. package/dist/ui/assets/TaskContextUpload-CB3ol0sN.js +0 -1
  481. package/dist/ui/assets/TaskSettings-g4ECKNOz.js +0 -12
  482. package/dist/ui/assets/TaskforceAgentsModule-BazdUwxZ.js +0 -21
  483. package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +0 -1
  484. package/dist/ui/assets/index-BUplSsv_.js +0 -7
  485. package/dist/ui/assets/index-gz2EXuoK.css +0 -1
@@ -0,0 +1,30 @@
1
+ export class OwnerScopedModelConnectionGateway {
2
+ connectionService;
3
+ ownerUserId;
4
+ connectionId;
5
+ createGateway;
6
+ constructor(connectionService, ownerUserId, connectionId, createGateway) {
7
+ this.connectionService = connectionService;
8
+ this.ownerUserId = ownerUserId;
9
+ this.connectionId = connectionId;
10
+ this.createGateway = createGateway;
11
+ }
12
+ generate(input) {
13
+ return this.connectionService.withConnectionLease({
14
+ ownerUserId: this.ownerUserId,
15
+ connectionId: this.connectionId,
16
+ operation: 'invoke',
17
+ }, async (context) => {
18
+ const result = await this.createGateway(context).generate(input);
19
+ return {
20
+ ...result,
21
+ sourceMetadata: {
22
+ modelSource: 'subscription_dev',
23
+ connectionScope: 'personal',
24
+ providerKey: context.connection.providerKey,
25
+ billable: false,
26
+ },
27
+ };
28
+ });
29
+ }
30
+ }
@@ -0,0 +1,66 @@
1
+ import type { TaskforceAgentStore } from '../storage/taskforceAgentStore.js';
2
+ import type { ModelProviderConnectionRecord, ModelProviderConnectionStore } from '../storage/modelProviderConnectionStore.js';
3
+ import type { TaskforceAgentConnectionBindingRecord, TaskforceAgentConnectionBindingStore } from '../storage/taskforceAgentConnectionBindingStore.js';
4
+ import type { ModelProviderConnectionService } from './modelProviderConnectionService.js';
5
+ export declare class TaskforceAgentConnectionBindingError extends Error {
6
+ readonly statusCode: number;
7
+ readonly code: string;
8
+ constructor(message: string, statusCode: number, code: string);
9
+ }
10
+ type AgentStore = Pick<TaskforceAgentStore, 'get'>;
11
+ type ConnectionStore = Pick<ModelProviderConnectionStore, 'getOwned'>;
12
+ type BindingStore = Pick<TaskforceAgentConnectionBindingStore, 'get' | 'bind' | 'clear'>;
13
+ type ConnectionRuntime = Pick<ModelProviderConnectionService, 'assertReady' | 'withConnectionLease'>;
14
+ export interface ResolvedTaskforceAgentConnectionBinding {
15
+ binding: TaskforceAgentConnectionBindingRecord;
16
+ connection: ModelProviderConnectionRecord;
17
+ }
18
+ export interface PublicTaskforceAgentConnectionBinding {
19
+ bound: boolean;
20
+ available: boolean;
21
+ providerKey?: string;
22
+ modelSource?: string;
23
+ ownerIsCaller?: boolean;
24
+ connectionId?: string;
25
+ reasonCode?: string;
26
+ }
27
+ export declare class TaskforceAgentConnectionBindingService {
28
+ private readonly bindings;
29
+ private readonly agents;
30
+ private readonly connections;
31
+ private readonly connectionRuntime;
32
+ private readonly hasGrant;
33
+ constructor(bindings: BindingStore, agents: AgentStore, connections: ConnectionStore, connectionRuntime: ConnectionRuntime, hasGrant: (userId: string) => boolean);
34
+ inspect(input: {
35
+ workspaceId: string;
36
+ agentId: string;
37
+ callerUserId: string;
38
+ }): PublicTaskforceAgentConnectionBinding;
39
+ bind(input: {
40
+ workspaceId: string;
41
+ agentId: string;
42
+ connectionId: string;
43
+ actorUserId: string;
44
+ }): Promise<TaskforceAgentConnectionBindingRecord>;
45
+ clear(input: {
46
+ workspaceId: string;
47
+ agentId: string;
48
+ actorUserId: string;
49
+ }): boolean;
50
+ resolveSaved(input: {
51
+ workspaceId: string;
52
+ agentId: string;
53
+ callerUserId: string;
54
+ }): ResolvedTaskforceAgentConnectionBinding;
55
+ resolveDraft(input: {
56
+ callerUserId: string;
57
+ connectionId: string;
58
+ providerKey: string;
59
+ }): ModelProviderConnectionRecord;
60
+ private requireBindableAgentSelection;
61
+ private requireOwnedActiveConnection;
62
+ private requireOwnedReadyConnection;
63
+ private assertCompatibleConnection;
64
+ private assertGranted;
65
+ }
66
+ export {};
@@ -0,0 +1,185 @@
1
+ export class TaskforceAgentConnectionBindingError extends Error {
2
+ statusCode;
3
+ code;
4
+ constructor(message, statusCode, code) {
5
+ super(message);
6
+ this.statusCode = statusCode;
7
+ this.code = code;
8
+ this.name = 'TaskforceAgentConnectionBindingError';
9
+ }
10
+ }
11
+ const SUBSCRIPTION_AUTHENTICATION_TYPES = {
12
+ openai: 'chatgpt_device_code',
13
+ };
14
+ function requireIdentity(value) {
15
+ const normalized = String(value || '').trim();
16
+ if (!normalized) {
17
+ throw new TaskforceAgentConnectionBindingError('Authentication is required.', 401, 'AUTH_REQUIRED');
18
+ }
19
+ return normalized;
20
+ }
21
+ export class TaskforceAgentConnectionBindingService {
22
+ bindings;
23
+ agents;
24
+ connections;
25
+ connectionRuntime;
26
+ hasGrant;
27
+ constructor(bindings, agents, connections, connectionRuntime, hasGrant) {
28
+ this.bindings = bindings;
29
+ this.agents = agents;
30
+ this.connections = connections;
31
+ this.connectionRuntime = connectionRuntime;
32
+ this.hasGrant = hasGrant;
33
+ }
34
+ inspect(input) {
35
+ const callerUserId = requireIdentity(input.callerUserId);
36
+ const agent = this.agents.get(input.workspaceId, input.agentId);
37
+ if (!agent || agent.deletedAt) {
38
+ throw new TaskforceAgentConnectionBindingError('Taskforce Agent was not found.', 404, 'TASKFORCE_AGENT_NOT_FOUND');
39
+ }
40
+ const binding = this.bindings.get(input.workspaceId, input.agentId);
41
+ if (!binding)
42
+ return { bound: false, available: false, reasonCode: 'MODEL_CONNECTION_REQUIRED' };
43
+ const selection = agent.definition?.model;
44
+ const ownerIsCaller = binding.ownerUserId === callerUserId;
45
+ const callerGranted = this.hasGrant(callerUserId);
46
+ const ownerGranted = this.hasGrant(binding.ownerUserId);
47
+ let connectionReady = false;
48
+ if (callerGranted && ownerGranted) {
49
+ try {
50
+ const connection = this.requireOwnedReadyConnection(binding.ownerUserId, binding.connectionId, binding.providerKey);
51
+ connectionReady = Boolean(connection);
52
+ }
53
+ catch {
54
+ connectionReady = false;
55
+ }
56
+ }
57
+ const available = Boolean(connectionReady
58
+ && selection?.providerKey === binding.providerKey
59
+ && selection?.modelSource === binding.modelSource);
60
+ return {
61
+ bound: true,
62
+ available,
63
+ providerKey: binding.providerKey,
64
+ modelSource: binding.modelSource,
65
+ ownerIsCaller,
66
+ ...(ownerIsCaller ? { connectionId: binding.connectionId } : {}),
67
+ ...(available ? {} : { reasonCode: 'MODEL_CONNECTION_UNAVAILABLE' }),
68
+ };
69
+ }
70
+ async bind(input) {
71
+ const actorUserId = requireIdentity(input.actorUserId);
72
+ this.assertGranted(actorUserId);
73
+ const selection = this.requireBindableAgentSelection(input.workspaceId, input.agentId);
74
+ const existing = this.bindings.get(input.workspaceId, input.agentId);
75
+ if (existing && existing.ownerUserId !== actorUserId) {
76
+ throw new TaskforceAgentConnectionBindingError('Only the current connection owner can replace this Agent binding.', 403, 'AGENT_CONNECTION_OWNER_REQUIRED');
77
+ }
78
+ return this.connectionRuntime.withConnectionLease({
79
+ ownerUserId: actorUserId,
80
+ connectionId: String(input.connectionId || '').trim(),
81
+ operation: 'invoke',
82
+ }, async (context) => {
83
+ this.assertCompatibleConnection(context.connection, selection.providerKey);
84
+ const binding = this.bindings.bind({
85
+ workspaceId: input.workspaceId,
86
+ agentId: input.agentId,
87
+ connectionId: context.connection.id,
88
+ ownerUserId: actorUserId,
89
+ providerKey: selection.providerKey,
90
+ modelSource: selection.modelSource,
91
+ actorUserId,
92
+ });
93
+ if (!binding) {
94
+ throw new TaskforceAgentConnectionBindingError('Only the current connection owner can replace this Agent binding.', 403, 'AGENT_CONNECTION_OWNER_REQUIRED');
95
+ }
96
+ return binding;
97
+ });
98
+ }
99
+ clear(input) {
100
+ const actorUserId = requireIdentity(input.actorUserId);
101
+ const binding = this.bindings.get(input.workspaceId, input.agentId);
102
+ if (!binding)
103
+ return false;
104
+ if (binding.ownerUserId !== actorUserId) {
105
+ throw new TaskforceAgentConnectionBindingError('Only the connection owner can clear this Agent binding.', 403, 'AGENT_CONNECTION_OWNER_REQUIRED');
106
+ }
107
+ const cleared = this.bindings.clear(input.workspaceId, input.agentId, actorUserId);
108
+ if (cleared)
109
+ return true;
110
+ const current = this.bindings.get(input.workspaceId, input.agentId);
111
+ if (current && current.ownerUserId !== actorUserId) {
112
+ throw new TaskforceAgentConnectionBindingError('Only the connection owner can clear this Agent binding.', 403, 'AGENT_CONNECTION_OWNER_REQUIRED');
113
+ }
114
+ return false;
115
+ }
116
+ resolveSaved(input) {
117
+ const callerUserId = requireIdentity(input.callerUserId);
118
+ this.assertGranted(callerUserId);
119
+ const selection = this.requireBindableAgentSelection(input.workspaceId, input.agentId);
120
+ const binding = this.bindings.get(input.workspaceId, input.agentId);
121
+ if (!binding) {
122
+ throw new TaskforceAgentConnectionBindingError('Connect this Agent to an eligible model account before running it.', 409, 'AGENT_MODEL_CONNECTION_REQUIRED');
123
+ }
124
+ this.assertGranted(binding.ownerUserId);
125
+ if (binding.providerKey !== selection.providerKey || binding.modelSource !== selection.modelSource) {
126
+ throw new TaskforceAgentConnectionBindingError('The saved Agent model selection no longer matches its local connection.', 409, 'AGENT_MODEL_CONNECTION_MISMATCH');
127
+ }
128
+ const connection = this.requireOwnedReadyConnection(binding.ownerUserId, binding.connectionId, binding.providerKey);
129
+ return { binding, connection };
130
+ }
131
+ resolveDraft(input) {
132
+ const callerUserId = requireIdentity(input.callerUserId);
133
+ this.assertGranted(callerUserId);
134
+ return this.requireOwnedReadyConnection(callerUserId, input.connectionId, input.providerKey);
135
+ }
136
+ requireBindableAgentSelection(workspaceId, agentId) {
137
+ const agent = this.agents.get(workspaceId, agentId);
138
+ if (!agent || agent.deletedAt) {
139
+ throw new TaskforceAgentConnectionBindingError('Taskforce Agent was not found.', 404, 'TASKFORCE_AGENT_NOT_FOUND');
140
+ }
141
+ const model = agent.definition?.model;
142
+ if (!model
143
+ || model.modelSource !== 'subscription_dev'
144
+ || (model.connectionScope !== 'personal' && model.connectionScope !== 'local_dev')) {
145
+ throw new TaskforceAgentConnectionBindingError('This Agent does not use a personal subscription model connection.', 409, 'AGENT_MODEL_CONNECTION_NOT_APPLICABLE');
146
+ }
147
+ return model;
148
+ }
149
+ requireOwnedActiveConnection(ownerUserId, connectionIdRaw, providerKey) {
150
+ const connectionId = String(connectionIdRaw || '').trim();
151
+ const connection = connectionId
152
+ ? this.connections.getOwned(ownerUserId, connectionId)
153
+ : null;
154
+ if (!connection) {
155
+ throw new TaskforceAgentConnectionBindingError('Model connection was not found.', 404, 'MODEL_CONNECTION_NOT_FOUND');
156
+ }
157
+ if (connection.providerKey !== providerKey) {
158
+ throw new TaskforceAgentConnectionBindingError('The model connection does not match the selected provider.', 409, 'MODEL_CONNECTION_PROVIDER_MISMATCH');
159
+ }
160
+ if (connection.lifecycleStatus !== 'active') {
161
+ throw new TaskforceAgentConnectionBindingError('The model connection is not active.', 409, 'MODEL_CONNECTION_INACTIVE');
162
+ }
163
+ this.assertCompatibleConnection(connection, providerKey);
164
+ return connection;
165
+ }
166
+ requireOwnedReadyConnection(ownerUserId, connectionId, providerKey) {
167
+ this.requireOwnedActiveConnection(ownerUserId, connectionId, providerKey);
168
+ const connection = this.connectionRuntime.assertReady(ownerUserId, connectionId);
169
+ this.assertCompatibleConnection(connection, providerKey);
170
+ return connection;
171
+ }
172
+ assertCompatibleConnection(connection, providerKey) {
173
+ const expectedAuthenticationType = SUBSCRIPTION_AUTHENTICATION_TYPES[providerKey];
174
+ if (!expectedAuthenticationType
175
+ || connection.providerKey !== providerKey
176
+ || connection.authenticationType !== expectedAuthenticationType) {
177
+ throw new TaskforceAgentConnectionBindingError('The model connection is not compatible with this subscription model.', 409, 'MODEL_CONNECTION_AUTHENTICATION_MISMATCH');
178
+ }
179
+ }
180
+ assertGranted(userId) {
181
+ if (this.hasGrant(userId))
182
+ return;
183
+ throw new TaskforceAgentConnectionBindingError('Subscription-backed models are not enabled for this account.', 403, 'SUBSCRIPTION_MODEL_ACCESS_REQUIRED');
184
+ }
185
+ }
@@ -1,4 +1,5 @@
1
1
  import { type TaskforceCore } from '../core/Taskforce.js';
2
+ import { createTaskforceMcpServer } from '../mcp/runtime.js';
2
3
  import { type ManagedAgentMcpToolProfile } from '../mcp/toolProfiles.js';
3
4
  import { type McpToolName } from '../mcp/toolRegistry.js';
4
5
  import type { AgentToolPolicy } from '../shared/taskforceAgentDefinition.js';
@@ -33,8 +34,12 @@ export type PrepareTaskforceAgentMcpBridgeInput = {
33
34
  readOnly?: boolean;
34
35
  toolProfile?: ManagedAgentMcpToolProfile;
35
36
  toolPolicy?: AgentToolPolicy;
37
+ executionRequestId: string;
36
38
  system: string;
37
39
  };
40
+ type PrepareTaskforceAgentMcpBridgeDependencies = {
41
+ createMcpServer?: typeof createTaskforceMcpServer;
42
+ };
38
43
  export declare const MANAGED_AGENT_LIST_TASKS_DEFAULT_LIMIT = 25;
39
44
  export declare const MANAGED_AGENT_LIST_TASKS_MAX_LIMIT = 50;
40
45
  export declare const MANAGED_AGENT_TOOL_RESULT_MAX_BYTES: number;
@@ -50,8 +55,9 @@ type McpToolDescriptor = {
50
55
  export declare function hashTaskforceAgentMcpToolContract(tools: McpToolDescriptor[]): string;
51
56
  export declare function isTaskforceAgentMutationToolName(name: string): boolean;
52
57
  export declare function taskforceAgentMutationCallKey(name: string, argumentsValue: Record<string, unknown>): string | null;
58
+ export declare function taskforceAgentMcpRequestId(call: TaskforceAgentMcpToolCall): string;
53
59
  declare const MANAGED_AGENT_CAPABILITY_TOOLS: Readonly<{
54
- readonly tasks: readonly ["add_comment", "add_task_checklist_item", "complete_workflow_step", "get_schedule_board", "get_stats", "get_task", "get_task_attachments", "get_task_checklist", "get_task_workflow", "list_task_relationships", "list_tasks", "replace_task_checklist", "search_tasks"];
60
+ readonly tasks: readonly ["add_comment", "add_task_checklist_item", "complete_workflow_step", "get_schedule_board", "get_stats", "get_task", "get_task_attachments", "get_task_checklist", "get_task_workflow", "list_task_relationships", "list_tasks", "replace_task_checklist", "search_tasks", "update_task_checklist_item"];
55
61
  readonly planning: readonly ["add_initiative_comment", "add_workstream_comment", "get_initiative", "get_workstream", "list_initiatives", "list_workstreams"];
56
62
  readonly documents: readonly ["get_document", "get_document_reviews", "search_documents"];
57
63
  readonly images: readonly ["get_image", "get_image_annotations", "search_images"];
@@ -72,6 +78,6 @@ type BoundedManagedAgentToolResult = {
72
78
  rejected: boolean;
73
79
  };
74
80
  export declare function boundManagedAgentMcpToolResult(toolName: string, text: string): BoundedManagedAgentToolResult;
75
- export declare function prepareTaskforceAgentMcpBridge(input: PrepareTaskforceAgentMcpBridgeInput): Promise<PreparedTaskforceAgentMcpBridge | null>;
81
+ export declare function prepareTaskforceAgentMcpBridge(input: PrepareTaskforceAgentMcpBridgeInput, dependencies?: PrepareTaskforceAgentMcpBridgeDependencies): Promise<PreparedTaskforceAgentMcpBridge | null>;
76
82
  export declare function serializeTaskforceAgentMcpToolResult(result: TaskforceAgentMcpToolResult): Record<string, unknown>;
77
83
  export {};
@@ -31,9 +31,19 @@ export function taskforceAgentMutationCallKey(name, argumentsValue) {
31
31
  return null;
32
32
  return `${normalizedName}:${serializeCanonicalJson(argumentsValue || {})}`;
33
33
  }
34
+ export function taskforceAgentMcpRequestId(call) {
35
+ return `managed-agent-${createHash('sha256')
36
+ .update(serializeCanonicalJson({
37
+ name: String(call.name || '').trim(),
38
+ arguments: call.arguments || {},
39
+ }))
40
+ .digest('hex')
41
+ .slice(0, 32)}`;
42
+ }
34
43
  const TASK_SCOPED_MUTATION_TOOL_NAMES = new Set([
35
44
  'add_comment',
36
45
  'add_task_checklist_item',
46
+ 'update_task_checklist_item',
37
47
  'replace_task_checklist',
38
48
  'complete_workflow_step',
39
49
  ]);
@@ -52,6 +62,7 @@ const MANAGED_AGENT_CAPABILITY_TOOLS = Object.freeze({
52
62
  'list_tasks',
53
63
  'replace_task_checklist',
54
64
  'search_tasks',
65
+ 'update_task_checklist_item',
55
66
  ],
56
67
  planning: [
57
68
  'add_initiative_comment',
@@ -120,21 +131,8 @@ export function resolveManagedAgentMcpToolNames(toolPolicy, profile = MCP_MANAGE
120
131
  }
121
132
  return Array.from(effective).sort((left, right) => left.localeCompare(right));
122
133
  }
123
- function getRuntimeHandler(runtime, method) {
124
- const handler = runtime.server._requestHandlers?.get(method);
125
- if (typeof handler !== 'function') {
126
- throw new Error(`Taskforce MCP ${method} handler is unavailable.`);
127
- }
128
- return handler;
129
- }
130
134
  async function listRuntimeTools(runtime) {
131
- const handler = getRuntimeHandler(runtime, 'tools/list');
132
- const result = await handler({
133
- jsonrpc: '2.0',
134
- id: 'taskforce-agent-tools-list',
135
- method: 'tools/list',
136
- params: {},
137
- }, {});
135
+ const result = await runtime.listTools();
138
136
  return Array.isArray(result?.tools) ? result.tools : [];
139
137
  }
140
138
  function compactText(value, maxLength) {
@@ -199,7 +197,7 @@ function buildToolInstructions(baseSystem, tools, allowedMutationTaskId, readOnl
199
197
  ? 'Allowed writes: task comments, checklist changes, and completion of the current owned workflow step. Use complete_workflow_step only after finishing that step.'
200
198
  : 'Allowed writes: task comments and checklist changes.',
201
199
  ...(canCompleteWorkflow && !readOnly ? [
202
- 'For workflow-step work, call get_task_workflow before acting. If requiresCommentEvidence is true, call add_comment and pass its returned comment.id to complete_workflow_step as evidenceCommentId. After all required work succeeds, call complete_workflow_step before answering. A comment or other task mutation does not complete the workflow step.',
200
+ 'For workflow-step work, call get_task_workflow before acting. Reuse its completionCall arguments exactly; never invent or reuse workflow IDs. If requiresCommentEvidence is true, call add_comment and add its returned comment.id as evidenceCommentId. After all required work succeeds, call complete_workflow_step before answering. A comment or other task mutation does not complete the workflow step.',
203
201
  ] : []),
204
202
  ...(taskScope ? [`This run is task-scoped to ${taskScope}. Mutating Taskforce tools must target only this task.`] : []),
205
203
  'To use a Taskforce tool, respond with only one JSON object and no prose:',
@@ -284,6 +282,14 @@ function utf8ByteLength(value) {
284
282
  return Buffer.byteLength(value, 'utf8');
285
283
  }
286
284
  export function normalizeManagedAgentMcpToolCall(call) {
285
+ if (call.name === 'get_task_workflow' || call.name === 'complete_workflow_step') {
286
+ const args = { ...call.arguments };
287
+ if (!String(args.taskId || '').trim() && String(args.id || '').trim()) {
288
+ args.taskId = args.id;
289
+ }
290
+ delete args.id;
291
+ return { name: call.name, arguments: args };
292
+ }
287
293
  if (call.name !== 'list_tasks')
288
294
  return call;
289
295
  const args = { ...call.arguments };
@@ -438,7 +444,7 @@ function buildManagedAgentToolResultMessage(result, workflowReminder) {
438
444
  'Use a narrower Taskforce read before answering the user.',
439
445
  ].join('\n');
440
446
  }
441
- export async function prepareTaskforceAgentMcpBridge(input) {
447
+ export async function prepareTaskforceAgentMcpBridge(input, dependencies = {}) {
442
448
  if (!input.core)
443
449
  return null;
444
450
  if (input.runtimeMode !== 'cloud') {
@@ -454,7 +460,7 @@ export async function prepareTaskforceAgentMcpBridge(input) {
454
460
  }
455
461
  if (!input.agentProfileId)
456
462
  managedToolNames.delete('complete_workflow_step');
457
- const runtime = createTaskforceMcpServer({
463
+ const runtime = (dependencies.createMcpServer || createTaskforceMcpServer)({
458
464
  core: input.core,
459
465
  workspaceId: input.workspaceId,
460
466
  runtimeMode: input.runtimeMode,
@@ -469,6 +475,7 @@ export async function prepareTaskforceAgentMcpBridge(input) {
469
475
  aiProfileProvider: input.providerKey || 'taskforce_hq',
470
476
  aiProfileModel: input.modelKey || null,
471
477
  aiProfileSurfaceType: 'agent',
478
+ requestId: input.executionRequestId,
472
479
  },
473
480
  });
474
481
  const tools = (await listRuntimeTools(runtime))
@@ -477,7 +484,6 @@ export async function prepareTaskforceAgentMcpBridge(input) {
477
484
  if (tools.length === 0)
478
485
  return null;
479
486
  const availableToolNames = new Set(tools.map((tool) => tool.name));
480
- const callTool = getRuntimeHandler(runtime, 'tools/call');
481
487
  return {
482
488
  system: buildToolInstructions(input.system, tools, input.allowedMutationTaskId, input.readOnly),
483
489
  availableToolNames: Array.from(availableToolNames),
@@ -491,15 +497,12 @@ export async function prepareTaskforceAgentMcpBridge(input) {
491
497
  if (scopeFailure)
492
498
  return scopeFailure;
493
499
  const effectiveCall = normalizeManagedAgentMcpToolCall(call);
494
- const result = await callTool({
495
- jsonrpc: '2.0',
496
- id: `taskforce-agent-tool-${effectiveCall.name}`,
497
- method: 'tools/call',
498
- params: {
499
- name: effectiveCall.name,
500
- arguments: effectiveCall.arguments,
501
- },
502
- }, {});
500
+ const result = await runtime.callTool({
501
+ name: effectiveCall.name,
502
+ arguments: effectiveCall.arguments,
503
+ }, {
504
+ requestId: taskforceAgentMcpRequestId(effectiveCall),
505
+ });
503
506
  const bounded = boundManagedAgentMcpToolResult(effectiveCall.name, extractToolResultText(result));
504
507
  return {
505
508
  name: effectiveCall.name,
@@ -0,0 +1,5 @@
1
+ export interface AdminEdgeProxyContext {
2
+ request: Request;
3
+ env?: Record<string, unknown>;
4
+ }
5
+ export declare function handleAdminEdgeProxyRequest(context: AdminEdgeProxyContext): Promise<Response>;
@@ -0,0 +1,94 @@
1
+ import { TASKFORCE_CLOUD_ENVIRONMENTS, parseTaskforceCloudEnvironment } from '../config/cloudEnvironment.js';
2
+ import { readSetCookieHeaders, stripSetCookieDomainAttribute } from '../utils/httpSetCookie.js';
3
+ import { resolveAllAdminProxyUpstreamSessionCookieNames, resolveAdminProxyUpstreamSessionCookieName, rewriteAdminProxyRequestCookieHeader, rewriteAdminProxyResponseSetCookie, } from './adminProxySessionCookies.js';
4
+ function readEnvValue(env, key) {
5
+ const value = env[key];
6
+ return typeof value === 'string' ? value.trim() : '';
7
+ }
8
+ function resolveProxyEnvironment(context) {
9
+ const processEnvironment = typeof process !== 'undefined' ? process.env : {};
10
+ return { ...processEnvironment, ...context.env };
11
+ }
12
+ function resolveUpstreamBaseUrl(environment) {
13
+ return TASKFORCE_CLOUD_ENVIRONMENTS[environment].appBaseUrl.replace(/\/+$/, '');
14
+ }
15
+ function isCloudflareAccessRedirect(response) {
16
+ if (response.status < 300 || response.status >= 400)
17
+ return false;
18
+ const location = String(response.headers.get('location') || '').trim();
19
+ if (!location)
20
+ return false;
21
+ try {
22
+ const url = new URL(location);
23
+ return url.hostname.toLowerCase() === 'stratnexus.cloudflareaccess.com'
24
+ || url.pathname.startsWith('/cdn-cgi/access/login');
25
+ }
26
+ catch {
27
+ return location.includes('/cdn-cgi/access/login');
28
+ }
29
+ }
30
+ function jsonError(status, error, code) {
31
+ return new Response(JSON.stringify({ error, code }), {
32
+ status,
33
+ headers: {
34
+ 'Content-Type': 'application/json',
35
+ 'Cache-Control': 'no-store',
36
+ },
37
+ });
38
+ }
39
+ export async function handleAdminEdgeProxyRequest(context) {
40
+ const request = context.request;
41
+ const environment = parseTaskforceCloudEnvironment(request.headers.get('x-taskforce-cloud-environment'));
42
+ if (!environment) {
43
+ return jsonError(400, 'A valid admin cloud environment is required.', 'ADMIN_ENVIRONMENT_REQUIRED');
44
+ }
45
+ const proxyEnvironment = resolveProxyEnvironment(context);
46
+ const upstreamSessionCookieName = resolveAdminProxyUpstreamSessionCookieName(environment, proxyEnvironment);
47
+ const requestUrl = new URL(request.url);
48
+ const upstreamUrl = `${resolveUpstreamBaseUrl(environment)}${requestUrl.pathname}${requestUrl.search}`;
49
+ const headers = new Headers(request.headers);
50
+ headers.delete('host');
51
+ const rewrittenCookie = rewriteAdminProxyRequestCookieHeader(headers.get('cookie'), environment, upstreamSessionCookieName, resolveAllAdminProxyUpstreamSessionCookieNames(proxyEnvironment));
52
+ if (rewrittenCookie)
53
+ headers.set('cookie', rewrittenCookie);
54
+ else
55
+ headers.delete('cookie');
56
+ headers.set('x-taskforce-origin-host', requestUrl.host);
57
+ headers.set('x-taskforce-origin-proto', requestUrl.protocol.replace(':', ''));
58
+ headers.set('x-taskforce-origin-base-url', requestUrl.origin);
59
+ headers.set('x-taskforce-origin-runtime', 'admin-edge-proxy');
60
+ const cloudProxyClientId = readEnvValue(proxyEnvironment, 'TASKFORCE_CF_ACCESS_CLIENT_ID')
61
+ || readEnvValue(proxyEnvironment, 'CF_ACCESS_CLIENT_ID');
62
+ const cloudProxyClientSecret = readEnvValue(proxyEnvironment, 'TASKFORCE_CF_ACCESS_CLIENT_SECRET')
63
+ || readEnvValue(proxyEnvironment, 'CF_ACCESS_CLIENT_SECRET');
64
+ if (cloudProxyClientId && cloudProxyClientSecret) {
65
+ headers.set('CF-Access-Client-Id', cloudProxyClientId);
66
+ headers.set('CF-Access-Client-Secret', cloudProxyClientSecret);
67
+ }
68
+ const method = request.method.toUpperCase();
69
+ const upstreamResponse = await fetch(upstreamUrl, {
70
+ method,
71
+ headers,
72
+ body: method !== 'GET' && method !== 'HEAD' ? await request.arrayBuffer() : undefined,
73
+ redirect: 'manual',
74
+ });
75
+ if (isCloudflareAccessRedirect(upstreamResponse)) {
76
+ return jsonError(401, 'Cloudflare Access authentication required for the selected environment.', 'CLOUDFLARE_ACCESS_REQUIRED');
77
+ }
78
+ const responseHeaders = new Headers(upstreamResponse.headers);
79
+ responseHeaders.delete('access-control-allow-origin');
80
+ responseHeaders.delete('access-control-allow-credentials');
81
+ responseHeaders.delete('access-control-allow-methods');
82
+ responseHeaders.delete('access-control-allow-headers');
83
+ responseHeaders.set('cache-control', 'no-store');
84
+ const setCookies = readSetCookieHeaders(upstreamResponse.headers);
85
+ responseHeaders.delete('set-cookie');
86
+ for (const setCookie of setCookies) {
87
+ responseHeaders.append('set-cookie', stripSetCookieDomainAttribute(rewriteAdminProxyResponseSetCookie(setCookie, environment, upstreamSessionCookieName)));
88
+ }
89
+ return new Response(upstreamResponse.body, {
90
+ status: upstreamResponse.status,
91
+ statusText: upstreamResponse.statusText,
92
+ headers: responseHeaders,
93
+ });
94
+ }
@@ -0,0 +1,16 @@
1
+ import { type TaskforceCloudEnvironment } from '../config/cloudEnvironment.js';
2
+ export declare const ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME = "taskforce_session";
3
+ export declare const ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_ENV = "TASKFORCE_ADMIN_PROXY_UPSTREAM_SESSION_COOKIE";
4
+ export declare function resolveAdminProxyUpstreamSessionCookieName(environment: TaskforceCloudEnvironment, env?: Record<string, unknown>): string;
5
+ export declare function resolveAllAdminProxyUpstreamSessionCookieNames(env?: Record<string, unknown>): string[];
6
+ export declare function adminProxySessionCookieName(environment: TaskforceCloudEnvironment): string;
7
+ /**
8
+ * Replace all browser-visible admin session cookies with the one upstream
9
+ * session cookie expected by the selected cloud environment.
10
+ */
11
+ export declare function rewriteAdminProxyRequestCookieHeader(cookieHeader: string | null | undefined, environment: TaskforceCloudEnvironment, upstreamSessionCookieName?: string, additionalSessionCookieNames?: readonly string[]): string;
12
+ /**
13
+ * Namespace an upstream cloud session for the admin proxy host. Removing the
14
+ * upstream Domain attribute keeps the isolated session scoped to that proxy.
15
+ */
16
+ export declare function rewriteAdminProxyResponseSetCookie(setCookie: string, environment: TaskforceCloudEnvironment, upstreamSessionCookieName?: string): string;
@@ -0,0 +1,86 @@
1
+ import { TASKFORCE_CLOUD_ENVIRONMENT_ORDER, } from '../config/cloudEnvironment.js';
2
+ export const ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME = 'taskforce_session';
3
+ export const ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_ENV = 'TASKFORCE_ADMIN_PROXY_UPSTREAM_SESSION_COOKIE';
4
+ const ADMIN_PROXY_SESSION_COOKIE_PREFIX = '__Host-taskforce_admin_session_';
5
+ const LEGACY_ADMIN_PROXY_SESSION_COOKIE_PREFIX = 'taskforce_admin_session_';
6
+ const TASKFORCE_SESSION_COOKIE_NAMES = new Set([
7
+ ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME,
8
+ 'taskforce_session_prod',
9
+ 'taskforce_session_staging',
10
+ 'taskforce_session_performance',
11
+ ]);
12
+ export function resolveAdminProxyUpstreamSessionCookieName(environment, env = {}) {
13
+ const environmentKey = `${ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_ENV}_${environment.toUpperCase()}`;
14
+ const configured = String(env[environmentKey] || env[ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_ENV] || '').trim();
15
+ if (!configured)
16
+ return ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME;
17
+ if (!/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/.test(configured)) {
18
+ throw new Error(`Invalid admin proxy upstream session cookie name for ${environment}.`);
19
+ }
20
+ return configured;
21
+ }
22
+ export function resolveAllAdminProxyUpstreamSessionCookieNames(env = {}) {
23
+ return [...new Set(TASKFORCE_CLOUD_ENVIRONMENT_ORDER.map((environment) => resolveAdminProxyUpstreamSessionCookieName(environment, env)))];
24
+ }
25
+ export function adminProxySessionCookieName(environment) {
26
+ return `${ADMIN_PROXY_SESSION_COOKIE_PREFIX}${environment}`;
27
+ }
28
+ function cookiePairName(pair) {
29
+ const separator = pair.indexOf('=');
30
+ return (separator >= 0 ? pair.slice(0, separator) : pair).trim();
31
+ }
32
+ /**
33
+ * Replace all browser-visible admin session cookies with the one upstream
34
+ * session cookie expected by the selected cloud environment.
35
+ */
36
+ export function rewriteAdminProxyRequestCookieHeader(cookieHeader, environment, upstreamSessionCookieName = ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME, additionalSessionCookieNames = []) {
37
+ const selectedCookieName = adminProxySessionCookieName(environment);
38
+ const pairs = String(cookieHeader || '')
39
+ .split(';')
40
+ .map((part) => part.trim())
41
+ .filter(Boolean);
42
+ const selectedPair = pairs.find((pair) => cookiePairName(pair) === selectedCookieName);
43
+ const forwardedPairs = pairs.filter((pair) => {
44
+ const name = cookiePairName(pair);
45
+ return name !== upstreamSessionCookieName
46
+ && !additionalSessionCookieNames.includes(name)
47
+ && !TASKFORCE_SESSION_COOKIE_NAMES.has(name)
48
+ && !name.startsWith(ADMIN_PROXY_SESSION_COOKIE_PREFIX)
49
+ && !name.startsWith(LEGACY_ADMIN_PROXY_SESSION_COOKIE_PREFIX);
50
+ });
51
+ if (selectedPair) {
52
+ const separator = selectedPair.indexOf('=');
53
+ forwardedPairs.push(`${upstreamSessionCookieName}=${selectedPair.slice(separator + 1)}`);
54
+ }
55
+ return forwardedPairs.join('; ');
56
+ }
57
+ /**
58
+ * Namespace an upstream cloud session for the admin proxy host. Removing the
59
+ * upstream Domain attribute keeps the isolated session scoped to that proxy.
60
+ */
61
+ export function rewriteAdminProxyResponseSetCookie(setCookie, environment, upstreamSessionCookieName = ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME) {
62
+ const parts = String(setCookie || '')
63
+ .split(';')
64
+ .map((part) => part.trim())
65
+ .filter(Boolean);
66
+ if (parts.length === 0)
67
+ return setCookie;
68
+ const [nameValue, ...attributes] = parts;
69
+ const separator = nameValue.indexOf('=');
70
+ if (separator < 0 || nameValue.slice(0, separator).trim() !== upstreamSessionCookieName) {
71
+ return setCookie;
72
+ }
73
+ const value = nameValue.slice(separator + 1);
74
+ const hostOnlyAttributes = attributes.filter((attribute) => {
75
+ const lower = attribute.toLowerCase();
76
+ return !lower.startsWith('domain=')
77
+ && !lower.startsWith('path=')
78
+ && lower !== 'secure';
79
+ });
80
+ return [
81
+ `${adminProxySessionCookieName(environment)}=${value}`,
82
+ 'Path=/',
83
+ 'Secure',
84
+ ...hostOnlyAttributes,
85
+ ].join('; ');
86
+ }