@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
@@ -1,10 +1,15 @@
1
1
  import { createHash, timingSafeEqual } from 'crypto';
2
- import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
2
+ import { NodeStreamableHTTPServerTransport } from '@modelcontextprotocol/node';
3
+ import { isJsonContentType } from '@modelcontextprotocol/server';
3
4
  import { parseMcpClientId } from '../../mcp/clientRegistry.js';
4
- import { createTaskforceMcpServer } from '../../mcp/runtime.js';
5
+ import { handleModernMcpHttpRequest, isModernMcpHttpRequest, } from '../../mcp/httpProtocolRouting.js';
6
+ import { createStatelessTaskforceMcpServer, createTaskforceMcpServer, } from '../../mcp/runtime.js';
5
7
  import { MCP_TOOL_PROFILES } from '../../mcp/toolRegistry.js';
6
8
  import { parseJsonBody } from './primitives.js';
9
+ import { setServerTimingHeader } from './shared.js';
7
10
  import { LocalServiceSessionError } from '../localServiceSessions.js';
11
+ import { WorkspaceSyncDurabilityStore } from '../../sync/v3/syncDurabilityStore.js';
12
+ import { assertDurableOperationIdentity, DurableOperationReplayIdentityConflictError, } from '../../sync/v3/durableOperationReplay.js';
8
13
  const API_BASE = '/api/taskforce/local-service/v1';
9
14
  const ALLOWED_SCOPES = new Set(['tasks:read', 'tasks:write', 'workspace:read']);
10
15
  const MAX_REGISTRATION_BODY_BYTES = 32 * 1024;
@@ -16,6 +21,13 @@ function writeJson(res, statusCode, body) {
16
21
  function fail(res, statusCode, error, code) {
17
22
  writeJson(res, statusCode, { error, code });
18
23
  }
24
+ function failMcp(res, statusCode, message) {
25
+ writeJson(res, statusCode, {
26
+ jsonrpc: '2.0',
27
+ error: { code: -32000, message },
28
+ id: null,
29
+ });
30
+ }
19
31
  function isLoopback(req) {
20
32
  const address = String(req.socket.remoteAddress || '').toLowerCase();
21
33
  return address === '127.0.0.1' || address === '::1' || address === '::ffff:127.0.0.1';
@@ -59,7 +71,17 @@ function authenticateSession(req, res, context) {
59
71
  fail(res, 401, 'A valid local service session bearer is required.', 'SESSION_AUTH_REQUIRED');
60
72
  return null;
61
73
  }
62
- const session = context.sessions.authenticate(token);
74
+ let session;
75
+ try {
76
+ session = context.sessions.authenticate(token);
77
+ }
78
+ catch (error) {
79
+ if (error instanceof LocalServiceSessionError) {
80
+ fail(res, error.statusCode, error.message, error.code);
81
+ return null;
82
+ }
83
+ throw error;
84
+ }
63
85
  if (!session) {
64
86
  fail(res, 401, 'The local service session is invalid or expired.', 'SESSION_INVALID');
65
87
  return null;
@@ -110,42 +132,60 @@ function normalizeRegistration(body, context) {
110
132
  profileToken: profileToken || null,
111
133
  };
112
134
  }
113
- function lookupBoundOperation(core, context, session, operationId, req) {
135
+ function lookupDurableOperation(core, context, session, operationId, req) {
114
136
  const url = new URL(req.url || '/', 'http://127.0.0.1');
115
137
  const expectedMutationKind = String(url.searchParams.get('mutationKind') || '').trim() || null;
116
138
  const expectedPayloadFingerprint = String(url.searchParams.get('payloadFingerprint') || '').trim() || null;
117
- const binding = context.sessions.getOperationBinding(session.id, operationId, {
118
- mutationKind: expectedMutationKind,
119
- payloadFingerprint: expectedPayloadFingerprint,
139
+ const row = new WorkspaceSyncDurabilityStore(core.getDatabaseAdapter()).readOutboxOperationLookup({
140
+ tenantId: core.getTenantId(),
141
+ workspaceId: session.workspaceId,
142
+ clientId: context.operationClientId,
143
+ operationId,
120
144
  });
121
- if (!binding)
122
- return null;
123
- const row = core.getDatabaseAdapter().prepare(`
124
- SELECT status, authoritative_response_json, created_at,
125
- mutation_kind, payload_fingerprint
126
- FROM workspace_sync_outbox
127
- WHERE tenant_id = ?
128
- AND workspace_id = ?
129
- AND client_id = ?
130
- AND operation_id = ?
131
- LIMIT 1
132
- `).get(core.getTenantId(), session.workspaceId, context.operationClientId, operationId);
133
145
  if (!row)
134
146
  return null;
135
- const responseJson = typeof row.authoritative_response_json === 'string'
136
- ? row.authoritative_response_json
137
- : null;
147
+ try {
148
+ assertDurableOperationIdentity({
149
+ operationId: row.operationId,
150
+ domain: row.domain,
151
+ entityId: row.entityId,
152
+ mutationKind: row.mutationKind,
153
+ payloadFingerprint: row.payloadFingerprint,
154
+ }, {
155
+ operationId,
156
+ domain: row.domain,
157
+ entityId: row.entityId,
158
+ mutationKind: expectedMutationKind || row.mutationKind,
159
+ payloadFingerprint: expectedPayloadFingerprint || row.payloadFingerprint,
160
+ });
161
+ }
162
+ catch (error) {
163
+ if (!(error instanceof DurableOperationReplayIdentityConflictError))
164
+ throw error;
165
+ throw new LocalServiceSessionError('Operation identity is assigned to a different durable mutation.', 409, 'OPERATION_IDENTITY_CONFLICT');
166
+ }
167
+ const responseJson = row.authoritativeResponseJson;
138
168
  if (responseJson && Buffer.byteLength(responseJson, 'utf8') > MAX_MCP_BODY_BYTES) {
139
169
  throw new LocalServiceSessionError('Operation response exceeds the local service limit.', 500, 'OPERATION_RESPONSE_INVALID');
140
170
  }
171
+ let response = null;
172
+ if (responseJson) {
173
+ try {
174
+ response = JSON.parse(responseJson);
175
+ }
176
+ catch {
177
+ throw new LocalServiceSessionError('Operation response is invalid.', 500, 'OPERATION_RESPONSE_INVALID');
178
+ }
179
+ }
141
180
  return {
142
181
  operationId,
143
182
  status: row.status,
144
- createdAt: row.created_at,
145
- mutationKind: row.mutation_kind,
146
- payloadFingerprint: binding.payloadFingerprint,
147
- durablePayloadFingerprint: row.payload_fingerprint,
148
- response: responseJson ? JSON.parse(responseJson) : null,
183
+ createdAt: row.createdAt,
184
+ mutationKind: row.mutationKind,
185
+ payloadFingerprint: row.payloadFingerprint,
186
+ domain: row.domain,
187
+ entityId: row.entityId,
188
+ response,
149
189
  };
150
190
  }
151
191
  function auditShutdown(core, context, input) {
@@ -186,6 +226,7 @@ export function registerLocalServiceRoutes(deps) {
186
226
  projectIdentity: context.projectIdentity,
187
227
  dataIdentity: context.ownershipKey,
188
228
  cloudTarget: context.cloudTarget,
229
+ runtimeContract: context.runtimeContract,
189
230
  transports: ['streamable-http'],
190
231
  health: {
191
232
  lifecycle: context.sessions.state(),
@@ -254,7 +295,7 @@ export function registerLocalServiceRoutes(deps) {
254
295
  if (!session)
255
296
  return;
256
297
  try {
257
- const operation = lookupBoundOperation(deps.core, context, session, params.operationId, req);
298
+ const operation = lookupDurableOperation(deps.core, context, session, params.operationId, req);
258
299
  if (!operation) {
259
300
  fail(res, 404, 'Operation not found.', 'OPERATION_NOT_FOUND');
260
301
  return;
@@ -281,6 +322,7 @@ export function registerLocalServiceRoutes(deps) {
281
322
  protocolVersion: context.protocolVersion,
282
323
  ownerPid: context.ownerPid,
283
324
  cloudTarget: context.cloudTarget,
325
+ runtimeContract: context.runtimeContract,
284
326
  sessions: context.sessions.list(),
285
327
  ...(context.diagnostics?.() || {}),
286
328
  });
@@ -341,21 +383,34 @@ export function registerLocalServiceRoutes(deps) {
341
383
  deps.addRoute('POST', '/mcp', async (req, res) => {
342
384
  if (!guardLocalRequest(req, res))
343
385
  return;
386
+ const authStartedAtMs = Date.now();
344
387
  const session = authenticateSession(req, res, context);
345
388
  if (!session)
346
389
  return;
390
+ if (!isJsonContentType(header(req, 'content-type'))) {
391
+ failMcp(res, 415, 'Unsupported Media Type: Content-Type must be application/json');
392
+ return;
393
+ }
394
+ const authMs = Date.now() - authStartedAtMs;
347
395
  let runtime = null;
396
+ let runtimeLease = null;
397
+ let bodyParseMs = 0;
398
+ let runtimeConstructionMs = 0;
399
+ let transportConnectMs = 0;
348
400
  let requestStarted = false;
349
401
  let unregisterCancellation = () => { };
350
402
  let resolveCancellation = () => { };
351
403
  const cancellation = new Promise((resolve) => { resolveCancellation = resolve; });
352
404
  try {
405
+ const bodyParseStartedAtMs = Date.now();
353
406
  const body = await parseJsonBody(req, MAX_MCP_BODY_BYTES);
407
+ bodyParseMs = Date.now() - bodyParseStartedAtMs;
408
+ const modernProtocolRequest = await isModernMcpHttpRequest(req, body);
354
409
  const cancellationId = body?.method === 'notifications/cancelled'
355
410
  && (typeof body?.params?.requestId === 'string' || typeof body?.params?.requestId === 'number')
356
411
  ? body.params.requestId
357
412
  : null;
358
- if (cancellationId !== null) {
413
+ if (cancellationId !== null && !modernProtocolRequest) {
359
414
  const correlationId = requestCorrelation(req, 'x-taskforce-mcp-cancel-correlation');
360
415
  if (correlationId)
361
416
  context.sessions.cancelRequest(session.id, correlationId);
@@ -375,7 +430,8 @@ export function registerLocalServiceRoutes(deps) {
375
430
  }
376
431
  if (cancelled)
377
432
  return;
378
- runtime = (deps.createMcpServer || createTaskforceMcpServer)({
433
+ const runtimeStartedAtMs = Date.now();
434
+ const runtimeOptions = {
379
435
  projectRoot: deps.core.getPaths().projectRoot,
380
436
  tenantId: deps.core.getTenantId(),
381
437
  workspaceId: session.workspaceId,
@@ -384,8 +440,6 @@ export function registerLocalServiceRoutes(deps) {
384
440
  logStartup: false,
385
441
  runtimeMode: 'local',
386
442
  operationIdentityScope: {
387
- generation: context.generation,
388
- sessionId: session.id,
389
443
  connectionInstance: session.connectionInstance,
390
444
  },
391
445
  toolProfile: session.toolProfile,
@@ -402,18 +456,59 @@ export function registerLocalServiceRoutes(deps) {
402
456
  userAgent: header(req, 'user-agent').trim() || null,
403
457
  },
404
458
  onAiProfileBound: (profileId) => context.sessions.bindAiProfile(session.id, profileId),
405
- onOperationAccepted: (operation) => context.sessions.recordOperation({
406
- sessionId: session.id,
407
- ...operation,
408
- }),
409
- });
410
- const transport = deps.createMcpTransport?.() || new StreamableHTTPServerTransport({
459
+ };
460
+ if (modernProtocolRequest) {
461
+ const handling = handleModernMcpHttpRequest({
462
+ req,
463
+ res,
464
+ parsedBody: body,
465
+ factory: ({ era }) => {
466
+ const constructionStartedAtMs = Date.now();
467
+ const modernRuntime = createStatelessTaskforceMcpServer({ ...runtimeOptions, protocolEra: era }, deps.createMcpServer || createTaskforceMcpServer);
468
+ runtimeConstructionMs = Date.now() - constructionStartedAtMs;
469
+ if (!res.headersSent) {
470
+ setServerTimingHeader(res, [
471
+ { name: 'auth', durationMs: authMs },
472
+ { name: 'body-parse', durationMs: bodyParseMs },
473
+ { name: 'runtime', durationMs: runtimeConstructionMs },
474
+ ]);
475
+ }
476
+ return modernRuntime.server;
477
+ },
478
+ });
479
+ await Promise.race([handling, cancellation]);
480
+ if (cancelled)
481
+ void handling.catch(() => undefined);
482
+ if (cancellationId !== null && res.statusCode === 202) {
483
+ const cancellationCorrelation = requestCorrelation(req, 'x-taskforce-mcp-cancel-correlation');
484
+ if (cancellationCorrelation) {
485
+ context.sessions.cancelRequest(session.id, cancellationCorrelation);
486
+ }
487
+ }
488
+ return;
489
+ }
490
+ runtimeLease = deps.acquireMcpRuntime
491
+ ? await deps.acquireMcpRuntime({ req, options: runtimeOptions })
492
+ : null;
493
+ runtime = runtimeLease?.runtime
494
+ || createStatelessTaskforceMcpServer(runtimeOptions, deps.createMcpServer || createTaskforceMcpServer);
495
+ runtimeConstructionMs = Date.now() - runtimeStartedAtMs;
496
+ const transport = runtimeLease?.transport || deps.createMcpTransport?.() || new NodeStreamableHTTPServerTransport({
411
497
  sessionIdGenerator: undefined,
412
498
  enableJsonResponse: true,
413
499
  });
414
- await runtime.server.connect(transport);
500
+ const transportStartedAtMs = Date.now();
501
+ if (!runtimeLease)
502
+ await runtime.server.connect(transport);
503
+ transportConnectMs = Date.now() - transportStartedAtMs;
415
504
  if (cancelled)
416
505
  return;
506
+ setServerTimingHeader(res, [
507
+ { name: 'auth', durationMs: authMs },
508
+ { name: 'body-parse', durationMs: bodyParseMs },
509
+ { name: 'runtime', durationMs: runtimeConstructionMs },
510
+ { name: 'transport-connect', durationMs: transportConnectMs },
511
+ ]);
417
512
  const handling = transport.handleRequest(req, res, body);
418
513
  await Promise.race([handling, cancellation]);
419
514
  if (cancelled)
@@ -428,7 +523,10 @@ export function registerLocalServiceRoutes(deps) {
428
523
  }
429
524
  finally {
430
525
  unregisterCancellation();
431
- await runtime?.server.close().catch(() => undefined);
526
+ if (runtimeLease)
527
+ await runtimeLease.release().catch(() => undefined);
528
+ else
529
+ await runtime?.server.close().catch(() => undefined);
432
530
  if (requestStarted)
433
531
  context.sessions.endRequest(session.id);
434
532
  }
@@ -0,0 +1,24 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ import type { TaskforceCore } from '../../core/Taskforce.js';
3
+ import { ModelProviderConnectionService, type ModelProviderConnectionLifecycleHandlers } from '../../services/modelProviderConnectionService.js';
4
+ import { CodexDeviceCodeLoginManager } from '../../services/codexDeviceCodeLoginManager.js';
5
+ import { type RouteHandler } from './primitives.js';
6
+ type ConnectionService = Pick<ModelProviderConnectionService, 'create' | 'list' | 'get' | 'rename' | 'verify' | 'refresh' | 'disconnect' | 'cleanup'>;
7
+ type DeviceCodeLoginManager = Pick<CodexDeviceCodeLoginManager, 'start' | 'get' | 'cancel'>;
8
+ export interface ModelConnectionsRouteDependencies {
9
+ addRoute: (method: string, path: string, handler: RouteHandler) => void;
10
+ ensureAppAccess: (req: IncomingMessage, res: ServerResponse) => boolean;
11
+ resolveAuthenticatedUserId: (req: IncomingMessage) => string | null;
12
+ resolveRuntimeMode: (req: IncomingMessage) => 'local' | 'cloud';
13
+ core?: TaskforceCore;
14
+ service?: ConnectionService;
15
+ loginManager?: DeviceCodeLoginManager;
16
+ credentialStoragePath?: string | null;
17
+ lifecycleHandlers?: Array<{
18
+ providerKey: string;
19
+ authenticationType: string;
20
+ lifecycle: ModelProviderConnectionLifecycleHandlers;
21
+ }>;
22
+ }
23
+ export declare function registerModelConnectionsRoutes(deps: ModelConnectionsRouteDependencies): void;
24
+ export {};
@@ -0,0 +1,205 @@
1
+ import { INTERNAL_SUBSCRIPTION_MODEL_FEATURE_KEY } from '../../shared/userFeatureGrants.js';
2
+ import { ModelProviderConnectionError, ModelProviderConnectionStore, } from '../../storage/modelProviderConnectionStore.js';
3
+ import { ModelProviderCredentialHomeManager } from '../../services/modelProviderCredentialHome.js';
4
+ import { ModelProviderConnectionService, } from '../../services/modelProviderConnectionService.js';
5
+ import { CodexDeviceCodeLoginManager, } from '../../services/codexDeviceCodeLoginManager.js';
6
+ import { createCodexModelProviderConnectionLifecycleHandlers } from '../../services/codexModelProviderConnectionLifecycle.js';
7
+ import { parseJsonBody } from './primitives.js';
8
+ function writeJson(res, statusCode, payload) {
9
+ res.writeHead(statusCode, { 'Content-Type': 'application/json' });
10
+ res.end(JSON.stringify(payload));
11
+ }
12
+ function writeError(res, error) {
13
+ const knownError = error instanceof ModelProviderConnectionError;
14
+ const statusCode = Number(error?.statusCode);
15
+ const safeStatusCode = Number.isInteger(statusCode) && statusCode >= 400 && statusCode <= 599
16
+ ? statusCode
17
+ : 500;
18
+ const code = knownError && typeof error?.code === 'string'
19
+ ? String(error.code)
20
+ : 'MODEL_CONNECTION_REQUEST_FAILED';
21
+ const message = knownError
22
+ ? String(error?.message || 'Model connection request failed.')
23
+ : 'Model connection request failed.';
24
+ writeJson(res, safeStatusCode, { success: false, error: message, code });
25
+ }
26
+ export function registerModelConnectionsRoutes(deps) {
27
+ const { addRoute, ensureAppAccess, resolveAuthenticatedUserId, resolveRuntimeMode, core, } = deps;
28
+ let resolvedService = deps.service;
29
+ let resolvedLoginManager = deps.loginManager;
30
+ let resolvedStore = null;
31
+ const store = () => {
32
+ if (resolvedStore)
33
+ return resolvedStore;
34
+ if (!core)
35
+ throw new Error('Model connection store is unavailable.');
36
+ resolvedStore = new ModelProviderConnectionStore(core.getDatabaseAdapter(), core.getTenantId());
37
+ return resolvedStore;
38
+ };
39
+ const service = () => {
40
+ if (resolvedService)
41
+ return resolvedService;
42
+ if (!core)
43
+ throw new Error('Model connection service is unavailable.');
44
+ const lifecycleHandlers = deps.lifecycleHandlers || [{
45
+ providerKey: 'openai',
46
+ authenticationType: 'chatgpt_device_code',
47
+ lifecycle: createCodexModelProviderConnectionLifecycleHandlers(),
48
+ }];
49
+ resolvedService = new ModelProviderConnectionService(store(), new ModelProviderCredentialHomeManager(deps.credentialStoragePath), (userId) => core.hasUserFeatureGrant(userId, INTERNAL_SUBSCRIPTION_MODEL_FEATURE_KEY), lifecycleHandlers);
50
+ return resolvedService;
51
+ };
52
+ const loginManager = () => {
53
+ if (resolvedLoginManager)
54
+ return resolvedLoginManager;
55
+ const connectionService = service();
56
+ if (!(connectionService instanceof ModelProviderConnectionService)) {
57
+ throw new Error('Model connection login manager is unavailable.');
58
+ }
59
+ resolvedLoginManager = new CodexDeviceCodeLoginManager(connectionService, store());
60
+ return resolvedLoginManager;
61
+ };
62
+ const authorize = (req, res) => {
63
+ if (!ensureAppAccess(req, res))
64
+ return null;
65
+ if (resolveRuntimeMode(req) !== 'cloud') {
66
+ writeJson(res, 404, {
67
+ success: false,
68
+ error: 'Model connections are unavailable in this runtime.',
69
+ code: 'MODEL_CONNECTIONS_CLOUD_ONLY',
70
+ });
71
+ return null;
72
+ }
73
+ const userId = String(resolveAuthenticatedUserId(req) || '').trim();
74
+ if (!userId) {
75
+ writeJson(res, 401, {
76
+ success: false,
77
+ error: 'Authentication is required.',
78
+ code: 'AUTH_REQUIRED',
79
+ });
80
+ return null;
81
+ }
82
+ return userId;
83
+ };
84
+ addRoute('GET', '/api/taskforce/model-connections', async (req, res) => {
85
+ const ownerUserId = authorize(req, res);
86
+ if (!ownerUserId)
87
+ return;
88
+ try {
89
+ writeJson(res, 200, {
90
+ success: true,
91
+ eligible: core ? core.hasUserFeatureGrant(ownerUserId, INTERNAL_SUBSCRIPTION_MODEL_FEATURE_KEY) : true,
92
+ connections: service().list(ownerUserId),
93
+ });
94
+ }
95
+ catch (error) {
96
+ writeError(res, error);
97
+ }
98
+ });
99
+ addRoute('POST', '/api/taskforce/model-connections', async (req, res) => {
100
+ const ownerUserId = authorize(req, res);
101
+ if (!ownerUserId)
102
+ return;
103
+ try {
104
+ const body = await parseJsonBody(req, 16 * 1024);
105
+ const connection = service().create({
106
+ ownerUserId,
107
+ providerKey: String(body?.providerKey || ''),
108
+ authenticationType: String(body?.authenticationType || ''),
109
+ });
110
+ writeJson(res, 201, { success: true, connection });
111
+ }
112
+ catch (error) {
113
+ writeError(res, error);
114
+ }
115
+ });
116
+ addRoute('GET', '/api/taskforce/model-connections/:connectionId', async (req, res, params) => {
117
+ const ownerUserId = authorize(req, res);
118
+ if (!ownerUserId)
119
+ return;
120
+ try {
121
+ writeJson(res, 200, {
122
+ success: true,
123
+ connection: service().get(ownerUserId, params.connectionId),
124
+ });
125
+ }
126
+ catch (error) {
127
+ writeError(res, error);
128
+ }
129
+ });
130
+ addRoute('PATCH', '/api/taskforce/model-connections/:connectionId', async (req, res, params) => {
131
+ const ownerUserId = authorize(req, res);
132
+ if (!ownerUserId)
133
+ return;
134
+ try {
135
+ const body = await parseJsonBody(req, 16 * 1024);
136
+ const connection = service().rename(ownerUserId, params.connectionId, body?.displayName);
137
+ writeJson(res, 200, { success: true, connection });
138
+ }
139
+ catch (error) {
140
+ writeError(res, error);
141
+ }
142
+ });
143
+ addRoute('POST', '/api/taskforce/model-connections/:connectionId/login', async (req, res, params) => {
144
+ const ownerUserId = authorize(req, res);
145
+ if (!ownerUserId)
146
+ return;
147
+ try {
148
+ const login = await loginManager().start(ownerUserId, params.connectionId);
149
+ writeJson(res, 202, { success: true, login });
150
+ }
151
+ catch (error) {
152
+ writeError(res, error);
153
+ }
154
+ });
155
+ addRoute('GET', '/api/taskforce/model-connections/:connectionId/login/:sessionId', async (req, res, params) => {
156
+ const ownerUserId = authorize(req, res);
157
+ if (!ownerUserId)
158
+ return;
159
+ try {
160
+ const login = loginManager().get(ownerUserId, params.connectionId, params.sessionId);
161
+ writeJson(res, 200, { success: true, login });
162
+ }
163
+ catch (error) {
164
+ writeError(res, error);
165
+ }
166
+ });
167
+ addRoute('POST', '/api/taskforce/model-connections/:connectionId/login/:sessionId/cancel', async (req, res, params) => {
168
+ const ownerUserId = authorize(req, res);
169
+ if (!ownerUserId)
170
+ return;
171
+ try {
172
+ const login = await loginManager().cancel(ownerUserId, params.connectionId, params.sessionId);
173
+ writeJson(res, 200, { success: true, login });
174
+ }
175
+ catch (error) {
176
+ writeError(res, error);
177
+ }
178
+ });
179
+ for (const operation of ['verify', 'refresh', 'disconnect']) {
180
+ addRoute('POST', `/api/taskforce/model-connections/:connectionId/${operation}`, async (req, res, params) => {
181
+ const ownerUserId = authorize(req, res);
182
+ if (!ownerUserId)
183
+ return;
184
+ try {
185
+ const connection = await service()[operation](ownerUserId, params.connectionId);
186
+ writeJson(res, 200, { success: true, connection });
187
+ }
188
+ catch (error) {
189
+ writeError(res, error);
190
+ }
191
+ });
192
+ }
193
+ addRoute('DELETE', '/api/taskforce/model-connections/:connectionId', async (req, res, params) => {
194
+ const ownerUserId = authorize(req, res);
195
+ if (!ownerUserId)
196
+ return;
197
+ try {
198
+ const result = await service().cleanup(ownerUserId, params.connectionId);
199
+ writeJson(res, 200, { success: true, ...result });
200
+ }
201
+ catch (error) {
202
+ writeError(res, error);
203
+ }
204
+ });
205
+ }
@@ -5,6 +5,7 @@ import type { LocalSyncCoordinatorRouteServices } from '../../sync/coordinator/l
5
5
  import type { WorkspaceSyncServerDataServices } from '../../sync/engine/workspaceSyncServerDataServices.js';
6
6
  import type { LocalServiceSessionManager } from '../localServiceSessions.js';
7
7
  import type { LocalServiceCloudTarget } from '../../config/localServiceCloudTarget.js';
8
+ import type { LocalServiceRuntimeContract } from '../../config/localServiceRuntimeContract.js';
8
9
  export interface LocalServiceRouteContext {
9
10
  generation: string;
10
11
  protocolVersion: string;
@@ -13,6 +14,7 @@ export interface LocalServiceRouteContext {
13
14
  bootstrapCapability: string;
14
15
  ownershipKey: string;
15
16
  cloudTarget: LocalServiceCloudTarget;
17
+ runtimeContract: LocalServiceRuntimeContract;
16
18
  projectIdentity: string;
17
19
  operationClientId: string;
18
20
  sessions: LocalServiceSessionManager;
@@ -6,9 +6,11 @@
6
6
  * routes.ts at runtime.
7
7
  */
8
8
  import { IncomingMessage, ServerResponse } from 'http';
9
+ import { NodeStreamableHTTPServerTransport } from '@modelcontextprotocol/node';
9
10
  import { TaskforceCore } from '../../core/Taskforce.js';
10
11
  import type { McpAccessTokenAuthResult, McpOAuthAccessTokenAuthResult, McpAccessTokenScope } from '../../core/Taskforce.js';
11
12
  import { type RouteContext } from './primitives.js';
13
+ import { type McpRuntimeFactory, type TaskforceMcpServerOptions } from '../../mcp/runtime.js';
12
14
  import { type AiProfileBootstrapConfig } from '../../mcp/aiProfileBootstrap.js';
13
15
  import type { AiProfileSeatScope } from '../../shared/aiProfileSeatScope.js';
14
16
  import { type RequestPerformanceDiagnostics } from '../../storage/postgresRequestDiagnostics.js';
@@ -100,6 +102,20 @@ export declare function makeAuthenticateCloudMcpRequest(core: TaskforceCore, dep
100
102
  resolveAuthenticatedUserId: (req: IncomingMessage) => string;
101
103
  writeMcpHttpError: (res: ServerResponse, statusCode: number, message: string, data?: Record<string, unknown>) => void;
102
104
  }): (req: IncomingMessage, res: ServerResponse) => CloudMcpRequestAuth | null;
105
+ export type CloudMcpToolPolicy = {
106
+ requiredScope: McpAccessTokenScope | null;
107
+ isWrite: boolean;
108
+ };
109
+ export type CloudMcpToolPolicyResolver = (toolName: string) => CloudMcpToolPolicy;
110
+ export interface CloudMcpRuntimeLease {
111
+ runtime: ReturnType<McpRuntimeFactory>;
112
+ transport: NodeStreamableHTTPServerTransport;
113
+ release(): Promise<void>;
114
+ }
115
+ export type AcquireCloudMcpRuntime = (input: {
116
+ req: IncomingMessage;
117
+ options: TaskforceMcpServerOptions;
118
+ }) => Promise<CloudMcpRuntimeLease>;
103
119
  export declare function makeHandleCloudMcpRequest(core: TaskforceCore, deps: {
104
120
  ensureAppAccess: (req: IncomingMessage, res: ServerResponse) => boolean;
105
121
  resolveAuthenticatedUserId: (req: IncomingMessage) => string;
@@ -109,6 +125,9 @@ export declare function makeHandleCloudMcpRequest(core: TaskforceCore, deps: {
109
125
  workspaceMaxRequests: number;
110
126
  windowMs: number;
111
127
  };
128
+ createMcpServer?: McpRuntimeFactory;
129
+ resolveMcpToolPolicy?: CloudMcpToolPolicyResolver;
130
+ acquireMcpRuntime?: AcquireCloudMcpRuntime;
112
131
  }): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
113
132
  export declare function requestHeader(req: IncomingMessage, name: string, fallback?: string): string;
114
133
  export declare function requestWorkspaceHeader(req: IncomingMessage): string;