@taskforcehq/taskforce 0.3.327 → 0.3.329
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.
- package/dist/Taskforce.module.css +257 -87
- package/dist/TaskforceCore.js +237 -230
- package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.js +1 -1
- package/dist/cli.js +34 -0
- package/dist/cliCloudTargetGuard.d.ts +5 -0
- package/dist/cliCloudTargetGuard.js +11 -0
- package/dist/components/activity/EntityActivityTimeline.js +15 -5
- package/dist/components/context/AttachmentPreviewHost.js +1 -1
- package/dist/components/context/ContextAttachmentManager.d.ts +3 -0
- package/dist/components/context/ContextAttachmentManager.js +116 -20
- package/dist/components/features/AnnotatedAttachmentWorkspace.js +24 -8
- package/dist/components/features/TaskSettings.d.ts +12 -1
- package/dist/components/features/TaskSettings.js +147 -40
- package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.d.ts +1 -1
- package/dist/components/features/planning/PlanningEntitySummary.d.ts +3 -1
- package/dist/components/features/planning/PlanningEntitySummary.js +3 -2
- package/dist/components/features/planning/PlanningLinkPicker.d.ts +3 -1
- package/dist/components/features/planning/PlanningLinkPicker.js +5 -3
- package/dist/components/features/planning/PlanningModule.js +28 -14
- package/dist/components/features/planning/PlanningTaskOrderList.d.ts +1 -1
- package/dist/components/features/planning/PlanningTaskOrderList.js +17 -6
- package/dist/components/features/planning/PlanningVisualIdentity.d.ts +14 -0
- package/dist/components/features/planning/PlanningVisualIdentity.js +106 -0
- package/dist/components/features/planning/planningTaskArrangement.d.ts +1 -0
- package/dist/components/features/planning/planningTaskArrangement.js +5 -5
- package/dist/components/features/planning/planningWorkspaceModel.d.ts +11 -0
- package/dist/components/features/taskforceAgentEditorModel.js +3 -1
- package/dist/components/task/TaskActionHeader.d.ts +2 -1
- package/dist/components/task/TaskActionHeader.js +2 -2
- package/dist/components/task/TaskCard.d.ts +5 -0
- package/dist/components/task/TaskCard.js +101 -13
- package/dist/components/task/TaskContextUpload.d.ts +3 -0
- package/dist/components/task/TaskContextUpload.js +2 -2
- package/dist/components/task/TaskForm.d.ts +4 -0
- package/dist/components/task/TaskForm.js +32 -7
- package/dist/components/task/TaskImageReviews.js +28 -19
- package/dist/components/task/TaskKanban.d.ts +6 -1
- package/dist/components/task/TaskKanban.js +152 -6
- package/dist/components/task/TaskList.d.ts +5 -0
- package/dist/components/task/TaskList.js +3 -3
- package/dist/components/task/TaskStatusActions.js +11 -2
- package/dist/components/task/TaskWorkstreamPicker.js +2 -1
- package/dist/components/ui/DocumentTypeIcon.d.ts +7 -0
- package/dist/components/ui/DocumentTypeIcon.js +8 -0
- package/dist/components/ui/PasswordInput.d.ts +6 -0
- package/dist/components/ui/PasswordInput.js +11 -0
- package/dist/components/ui/TaxonomyDropdown.d.ts +9 -1
- package/dist/components/ui/TaxonomyDropdown.js +30 -3
- package/dist/components/ui/TopNoticeLayer.js +1 -1
- package/dist/components/views/AppShellHeader.js +32 -11
- package/dist/components/views/PlanComparisonPage.js +12 -0
- package/dist/components/views/StandaloneLayout.js +68 -39
- package/dist/components/views/WidgetView.js +10 -7
- package/dist/components/views/panels/PlanningDrawer.d.ts +7 -1
- package/dist/components/views/panels/PlanningDrawer.js +51 -54
- package/dist/components/views/standalone/modals/AccountSettingsModal.js +26 -17
- package/dist/config/envSchema.js +13 -0
- package/dist/config/localServiceCloudTarget.d.ts +10 -0
- package/dist/config/localServiceCloudTarget.js +76 -0
- package/dist/config/localServiceRuntimeContract.d.ts +13 -0
- package/dist/config/localServiceRuntimeContract.js +135 -0
- package/dist/core/AiProfileService.d.ts +1 -0
- package/dist/core/AiProfileService.js +48 -9
- package/dist/core/AttachmentLinkService.js +7 -4
- package/dist/core/DeletedTaskLifecycleService.d.ts +5 -0
- package/dist/core/DeletedTaskLifecycleService.js +55 -3
- package/dist/core/McpTokenService.d.ts +4 -0
- package/dist/core/McpTokenService.js +52 -0
- package/dist/core/TaskAttachmentLinksDurableMutationService.d.ts +8 -2
- package/dist/core/TaskAttachmentLinksDurableMutationService.js +51 -18
- package/dist/core/Taskforce.d.ts +124 -2
- package/dist/core/Taskforce.js +1175 -87
- package/dist/core/types.d.ts +8 -1
- package/dist/documentReviews/DocumentReviewCommentStore.d.ts +11 -0
- package/dist/documentReviews/DocumentReviewCommentStore.js +35 -2
- package/dist/documentReviews/service.d.ts +4 -0
- package/dist/documentReviews/service.js +141 -46
- package/dist/hooks/sync/useDurableLocalOutboxDrain.d.ts +1 -1
- package/dist/hooks/sync/useDurableTaskCreateMutation.js +1 -1
- package/dist/hooks/sync/useDurableTaskMetadataMutation.d.ts +1 -0
- package/dist/hooks/sync/useDurableTaskMetadataMutation.js +1 -0
- package/dist/hooks/sync/useDurableTaskStatusMutation.d.ts +1 -0
- package/dist/hooks/tasks/taskHttpMutation.js +1 -0
- package/dist/hooks/tasks/useCloudTaskSearch.d.ts +12 -0
- package/dist/hooks/tasks/useCloudTaskSearch.js +71 -0
- package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.d.ts +16 -0
- package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.js +197 -0
- package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +16 -3
- package/dist/hooks/tasks/useTaskEditorNavigation.js +72 -13
- package/dist/hooks/tasks/useTaskFormActions.d.ts +9 -0
- package/dist/hooks/tasks/useTaskFormActions.js +96 -17
- package/dist/hooks/ui/useSettingsModel.d.ts +24 -2
- package/dist/hooks/ui/useSettingsModel.js +13 -2
- package/dist/hooks/ui/useSettingsPersistence.d.ts +12 -1
- package/dist/hooks/ui/useSettingsPersistence.js +74 -47
- package/dist/hooks/useFilterSort.d.ts +7 -3
- package/dist/hooks/useFilterSort.js +15 -5
- package/dist/hooks/useTaskData.d.ts +10 -1
- package/dist/hooks/useTaskData.js +216 -7
- package/dist/hooks/useTaskMutations.d.ts +10 -2
- package/dist/hooks/useTaskMutations.js +223 -43
- package/dist/hooks/useTaskforce.d.ts +94 -57
- package/dist/hooks/useTaskforce.js +428 -16
- package/dist/hooks/useUiNotice.d.ts +4 -0
- package/dist/hooks/useUiNotice.js +4 -0
- package/dist/mcp/adminWorkspaceRegistrar.js +3 -3
- package/dist/mcp/canonicalAssetHelpers.d.ts +13 -0
- package/dist/mcp/canonicalAssetHelpers.js +39 -5
- package/dist/mcp/collaborationRegistrar.js +15 -13
- package/dist/mcp/documentAssetRegistrar.js +60 -44
- package/dist/mcp/documentHelpers.d.ts +1 -0
- package/dist/mcp/documentHelpers.js +7 -3
- package/dist/mcp/localServiceProxy.js +4 -1
- package/dist/mcp/runtime.d.ts +16 -0
- package/dist/mcp/runtime.js +735 -210
- package/dist/mcp/taskAttachmentCommandAdapter.d.ts +2 -0
- package/dist/mcp/taskAttachmentCommandAdapter.js +14 -8
- package/dist/mcp/taskPlanningRegistrar.js +78 -67
- package/dist/mcp/toolCallCompatibility.js +38 -1
- package/dist/mcp/toolCatalog.d.ts +1 -0
- package/dist/mcp/toolRegistry.js +2 -2
- package/dist/migrations/taskSchemaMigrations.js +47 -0
- package/dist/runtime/appGateDefinitions.d.ts +30 -6
- package/dist/runtime/appGateDefinitions.js +6 -6
- package/dist/runtime/appGates.d.ts +12 -13
- package/dist/runtime/appGates.js +29 -13
- package/dist/runtime/nodeAppGates.d.ts +8 -0
- package/dist/runtime/nodeAppGates.js +27 -0
- package/dist/server/appAccess.d.ts +12 -0
- package/dist/server/appAccess.js +21 -0
- package/dist/server/authorizedWorkspaceAccess.d.ts +12 -0
- package/dist/server/authorizedWorkspaceAccess.js +40 -0
- package/dist/server/cloudCollectionRead.d.ts +25 -0
- package/dist/server/cloudCollectionRead.js +120 -0
- package/dist/server/cloudCollectionReadPool.d.ts +52 -0
- package/dist/server/cloudCollectionReadPool.js +140 -0
- package/dist/server/cloudCollectionReadWorker.d.ts +1 -0
- package/dist/server/cloudCollectionReadWorker.js +36 -0
- package/dist/server/index.d.ts +6 -11
- package/dist/server/index.js +67 -42
- package/dist/server/localServiceLease.d.ts +6 -0
- package/dist/server/localServiceLease.js +17 -1
- package/dist/server/localWorkspaceSyncServerRuntime.js +10 -3
- package/dist/server/rateLimit.d.ts +1 -0
- package/dist/server/rateLimit.js +4 -0
- package/dist/server/realtimeSyncWs.js +36 -12
- package/dist/server/routes/admin.js +1 -0
- package/dist/server/routes/agentRoles.js +3 -2
- package/dist/server/routes/agentSkills.js +3 -2
- package/dist/server/routes/agents.js +118 -16
- package/dist/server/routes/annotatedAttachments.js +3 -2
- package/dist/server/routes/auth.js +3 -1
- package/dist/server/routes/documents.d.ts +5 -2
- package/dist/server/routes/documents.js +160 -13
- package/dist/server/routes/durableTaskHttpRouters.d.ts +11 -2
- package/dist/server/routes/durableTaskHttpRouters.js +2 -2
- package/dist/server/routes/localService.js +4 -0
- package/dist/server/routes/primitives.d.ts +4 -0
- package/dist/server/routes/shared.d.ts +24 -0
- package/dist/server/routes/shared.js +114 -18
- package/dist/server/routes/sync.js +22 -0
- package/dist/server/routes/syncAuxRoutes.js +5 -2
- package/dist/server/routes/syncPullApplyRoutes.js +23 -4
- package/dist/server/routes/syncV3FeedRoutes.js +22 -18
- package/dist/server/routes/syncV3LocalCaptureRoutes.js +48 -4
- package/dist/server/routes/syncV3LocalFeedApplyRoutes.d.ts +1 -0
- package/dist/server/routes/syncV3LocalFeedApplyRoutes.js +26 -0
- package/dist/server/routes/syncV3OperationRoutes.js +27 -2
- package/dist/server/routes/tasks.js +299 -97
- package/dist/server/routes/workspaces.js +43 -1
- package/dist/server/routes.js +35 -7
- package/dist/server/workspaceDeletionAdmission.d.ts +23 -0
- package/dist/server/workspaceDeletionAdmission.js +50 -0
- package/dist/service/localServiceCli.js +52 -25
- package/dist/service/localServiceClientLifecycle.js +93 -6
- package/dist/services/codexAppServerModelGateway.d.ts +112 -0
- package/dist/services/codexAppServerModelGateway.js +438 -0
- package/dist/services/taskforceAgentMcpBridge.d.ts +7 -1
- package/dist/services/taskforceAgentMcpBridge.js +23 -3
- package/dist/shared/planningIdentity.d.ts +20 -0
- package/dist/shared/planningIdentity.js +79 -0
- package/dist/shared/taskforceAgentDefinition.js +7 -1
- package/dist/shared/taskforceAgentModels.d.ts +1 -0
- package/dist/shared/taskforceAgentModels.js +30 -1
- package/dist/storage/postgresAdapter.d.ts +20 -3
- package/dist/storage/postgresAdapter.js +110 -14
- package/dist/storage/postgresRequestDiagnostics.d.ts +8 -0
- package/dist/storage/postgresRequestDiagnostics.js +24 -0
- package/dist/storage/postgresWorker.js +13 -4
- package/dist/storage/postgresWorkerProtocol.d.ts +29 -0
- package/dist/storage/postgresWorkerProtocol.js +30 -0
- package/dist/storage/workspaceAssetStore.d.ts +32 -0
- package/dist/storage/workspaceAssetStore.js +70 -0
- package/dist/sync/cloudSyncApi.d.ts +4 -1
- package/dist/sync/cloudSyncApi.js +7 -2
- package/dist/sync/contentSyncState.d.ts +1 -1
- package/dist/sync/coordinator/localSyncExecutionPermitStore.d.ts +17 -0
- package/dist/sync/coordinator/localSyncExecutionPermitStore.js +77 -23
- package/dist/sync/coordinator/localWorkspaceSyncRunner.js +6 -2
- package/dist/sync/coordinator/workspaceSyncTransportGateway.js +4 -2
- package/dist/sync/engine/workspaceSyncEngineBrowserGatewayRemoteServices.js +20 -2
- package/dist/sync/engine/workspaceSyncEngineLocalServices.d.ts +4 -0
- package/dist/sync/engine/workspaceSyncEngineLocalServices.js +11 -0
- package/dist/sync/engine/workspaceSyncEngineRemoteServices.d.ts +16 -0
- package/dist/sync/engine/workspaceSyncEngineRemoteServices.js +2 -1
- package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.d.ts +1 -1
- package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.js +46 -4
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.d.ts +3 -1
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +51 -11
- package/dist/sync/engine/workspaceSyncEngineTransfers.d.ts +1 -1
- package/dist/sync/engine/workspaceSyncEngineTransfers.js +8 -3
- package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +2 -0
- package/dist/sync/syncApplyHandlers.d.ts +3 -1
- package/dist/sync/syncApplyHandlers.js +29 -0
- package/dist/sync/syncService.d.ts +2 -0
- package/dist/sync/syncService.js +13 -1
- package/dist/sync/taskSyncPayload.d.ts +1 -0
- package/dist/sync/taskSyncPayload.js +6 -0
- package/dist/sync/v3/combinedFeedCapability.js +4 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.d.ts +3 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +31 -3
- package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +2 -0
- package/dist/sync/v3/durableTaskChecklistMutationRouter.js +4 -0
- package/dist/sync/v3/durableTaskHttpBulkMutationRouter.d.ts +1 -0
- package/dist/sync/v3/durableTaskHttpBulkMutationRouter.js +47 -12
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +5 -3
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +27 -2
- package/dist/sync/v3/localInitiativeOutboxService.js +4 -2
- package/dist/sync/v3/localOutboxDispatcher.js +5 -1
- package/dist/sync/v3/localTaskAttachmentLinksOutboxHandler.js +12 -2
- package/dist/sync/v3/localTaskAttachmentLinksOutboxService.d.ts +3 -0
- package/dist/sync/v3/localTaskAttachmentLinksOutboxService.js +62 -10
- package/dist/sync/v3/localTaskCreateOutboxService.js +15 -6
- package/dist/sync/v3/localTaskMetadataClient.d.ts +1 -0
- package/dist/sync/v3/localTaskMetadataClient.js +1 -0
- package/dist/sync/v3/localTaskMetadataOutboxHandler.js +5 -1
- package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -0
- package/dist/sync/v3/localTaskMetadataOutboxService.js +7 -0
- package/dist/sync/v3/localTaskRestoreOutboxService.js +14 -6
- package/dist/sync/v3/localTaskStatusClient.d.ts +1 -0
- package/dist/sync/v3/localTaskStatusClient.js +6 -1
- package/dist/sync/v3/localTaskStatusOutboxService.d.ts +2 -0
- package/dist/sync/v3/localTaskStatusOutboxService.js +54 -13
- package/dist/sync/v3/localWorkstreamOutboxService.js +4 -2
- package/dist/sync/v3/syncDurabilityStore.d.ts +15 -0
- package/dist/sync/v3/syncDurabilityStore.js +201 -43
- package/dist/sync/v3/taskAttachmentLinksMutationService.d.ts +7 -4
- package/dist/sync/v3/taskAttachmentLinksMutationService.js +37 -12
- package/dist/sync/v3/taskChecklistMutationService.d.ts +4 -2
- package/dist/sync/v3/taskChecklistMutationService.js +4 -0
- package/dist/sync/v3/taskCreateMutationService.d.ts +2 -2
- package/dist/sync/v3/taskCreateMutationService.js +7 -4
- package/dist/sync/v3/taskMetadataCoexistence.js +4 -0
- package/dist/sync/v3/taskMetadataMutationService.d.ts +3 -0
- package/dist/sync/v3/taskMetadataMutationService.js +4 -0
- package/dist/sync/v3/taskRestoreMutationService.d.ts +2 -2
- package/dist/sync/v3/taskRestoreMutationService.js +7 -4
- package/dist/sync/v3/taskStatusMutationService.d.ts +2 -0
- package/dist/sync/v3/taskStatusMutationService.js +4 -0
- package/dist/sync/v3/workflowAssignmentSync.d.ts +1 -0
- package/dist/sync/v3/workflowAssignmentSync.js +3 -0
- package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.d.ts +1 -1
- package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.js +14 -12
- package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.d.ts +11 -0
- package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.js +27 -10
- package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.d.ts +2 -1
- package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.js +52 -10
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +10 -1
- package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.js +15 -4
- package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +66 -13
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +11 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +57 -22
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +10 -4
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +124 -51
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +10 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +120 -28
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +3 -1
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +18 -0
- package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +6 -0
- package/dist/sync/v3/workspaceSyncV3FeedProfile.d.ts +1 -1
- package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.js +23 -10
- package/dist/sync/v3/workspaceSyncV3NestedTaskApply.d.ts +3 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskApply.js +64 -13
- package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.d.ts +9 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.js +26 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +15 -5
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +50 -14
- package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.d.ts +2 -1
- package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.js +11 -3
- package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +3 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +2 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +19 -7
- package/dist/sync/v3/workspaceSyncV3RepairSqlBatching.d.ts +2 -0
- package/dist/sync/v3/workspaceSyncV3RepairSqlBatching.js +10 -0
- package/dist/sync/v3/workspaceSyncV3TaskCommentAudit.js +9 -2
- package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.js +37 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.d.ts +6 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.js +9 -0
- package/dist/sync/v3/workspaceSyncV3TaskRootProjection.d.ts +1 -1
- package/dist/sync/v3/workspaceSyncV3TaskRootProjection.js +1 -1
- package/dist/sync/workspacePullFeed.d.ts +6 -1
- package/dist/sync/workspacePullFeed.js +174 -162
- package/dist/sync/workspaceRepair.d.ts +3 -0
- package/dist/sync/workspaceRepair.js +67 -6
- package/dist/sync/workspaceSyncModel.d.ts +11 -0
- package/dist/sync/workspaceSyncModel.js +27 -2
- package/dist/types.d.ts +55 -1
- package/dist/types.js +6 -0
- package/dist/ui/assets/{AiIdentityRosterCard-DB1BLO_j.js → AiIdentityRosterCard-BZM4aQnM.js} +1 -1
- package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +1 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-B68Wg-RV.js +3 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-TzYu7pkG.css +1 -0
- package/dist/ui/assets/AssetTraySortControl-C8Rztyal.js +1 -0
- package/dist/ui/assets/ContextAttachmentManager-Cj3c7X9y.js +3 -0
- package/dist/ui/assets/{DocumentWorkspace-BC7sy5TG.js → DocumentWorkspace-B5uvzems.js} +4 -4
- package/dist/ui/assets/EntityActivityTimeline-BVFvCB5R.js +1 -0
- package/dist/ui/assets/PlanningModule-B5DWQOGz.js +1 -0
- package/dist/ui/assets/PlanningModule-CoIR9hbV.css +1 -0
- package/dist/ui/assets/PlansPage-AY4cGWco.js +1 -0
- package/dist/ui/assets/TaskContextUpload-DZxTVesW.js +1 -0
- package/dist/ui/assets/TaskContextUpload-qmBeUw3u.css +1 -0
- package/dist/ui/assets/TaskSettings-BeWAuyZj.js +12 -0
- package/dist/ui/assets/{TaskforceAgentsModule-CkAxW19K.js → TaskforceAgentsModule-BifCYtjR.js} +6 -6
- package/dist/ui/assets/WorkflowManagerModule-DEr5di_r.js +1 -0
- package/dist/ui/assets/index-I5zhdtgt.js +7 -0
- package/dist/ui/assets/index-VRFsx3wz.css +1 -0
- package/dist/ui/assets/{vendor-icons-B8ZNsH1g.js → vendor-icons-D9Lpw-j4.js} +1 -1
- package/dist/ui/index.html +3 -3
- package/dist/utils/constants.d.ts +2 -2
- package/dist/utils/constants.js +1 -1
- package/dist/utils/contextAttachmentUpload.d.ts +2 -0
- package/dist/utils/contextAttachmentUpload.js +7 -0
- package/dist/utils/contextFiles.d.ts +1 -1
- package/dist/utils/contextFiles.js +4 -4
- package/dist/utils/taskActivity.d.ts +3 -2
- package/dist/utils/taskActivity.js +19 -2
- package/dist/utils/taskEditorReconciliation.d.ts +40 -0
- package/dist/utils/taskEditorReconciliation.js +217 -0
- package/dist/utils/taskNormalization.d.ts +1 -0
- package/dist/utils/taskNormalization.js +39 -0
- package/dist/utils/taskSearch.js +2 -2
- package/dist/utils/uiNotice.d.ts +4 -0
- package/package.json +21 -4
- package/dist/ui/assets/AiProfilesModule-DPxQeF9N.js +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-CBRZ8rca.css +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-DHNYaNg6.js +0 -3
- package/dist/ui/assets/AssetTraySortControl-DphbyHVc.js +0 -1
- package/dist/ui/assets/ContextAttachmentManager-CMxSzHqc.js +0 -3
- package/dist/ui/assets/EntityActivityTimeline-pJ2ZjZ-k.js +0 -1
- package/dist/ui/assets/PlanningModule-CeTqXMMz.css +0 -1
- package/dist/ui/assets/PlanningModule-t5GbvVR9.js +0 -1
- package/dist/ui/assets/PlansPage-BVH_NfgT.js +0 -1
- package/dist/ui/assets/TaskContextUpload-Ds4LnDzV.css +0 -1
- package/dist/ui/assets/TaskContextUpload-bl4fOOUz.js +0 -1
- package/dist/ui/assets/TaskSettings-xVsxSa0g.js +0 -12
- package/dist/ui/assets/WorkflowManagerModule-BKqIGVnF.js +0 -1
- package/dist/ui/assets/index-BzJlVnNS.css +0 -1
- package/dist/ui/assets/index-Cx7vZJHL.js +0 -7
|
@@ -11,10 +11,12 @@
|
|
|
11
11
|
* POST /api/taskforce/agents/model-gateway/test
|
|
12
12
|
* PATCH /api/taskforce/agents/:agentId/conversations/:conversationId
|
|
13
13
|
*/
|
|
14
|
+
import { createHash } from 'node:crypto';
|
|
14
15
|
import { assignedAiProfileColor, normalizeAiProfileColor } from '../../shared/aiProfileColors.js';
|
|
15
16
|
import { BedrockAnthropicMessagesModelGateway } from '../../services/bedrockAnthropicMessagesModelGateway.js';
|
|
16
17
|
import { BedrockMantleModelGateway } from '../../services/bedrockMantleModelGateway.js';
|
|
17
18
|
import { BedrockModelGateway } from '../../services/bedrockModelGateway.js';
|
|
19
|
+
import { CodexAppServerModelGateway } from '../../services/codexAppServerModelGateway.js';
|
|
18
20
|
import { saveAiProfileAvatarAssets } from '../aiProfileAvatarAssets.js';
|
|
19
21
|
import { ModelGatewayConfigurationError, normalizePersistedModelGatewayMessages } from '../../services/modelGateway.js';
|
|
20
22
|
import { BedrockAvatarImageProvider, buildTaskforceAgentAvatarPrompt, } from '../../services/taskforceAgentAvatarImageProvider.js';
|
|
@@ -25,10 +27,11 @@ import { TaskforceAgentSkillStore } from '../../storage/taskforceAgentSkillStore
|
|
|
25
27
|
import { WorkflowStore } from '../../storage/workflowStore.js';
|
|
26
28
|
import { WorkspaceSyncDurabilityStore } from '../../sync/v3/syncDurabilityStore.js';
|
|
27
29
|
import { projectLegacyTaskforceAgentResponse } from '../../compat/taskforceAgentDefinitionCompat.js';
|
|
28
|
-
import { TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY,
|
|
30
|
+
import { TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY, } from '../../runtime/appGates.js';
|
|
31
|
+
import { resolveNodeAppGateAccess } from '../../runtime/nodeAppGates.js';
|
|
29
32
|
import { DEFAULT_TASKFORCE_AGENT_MODEL_KEY, DEFAULT_TASKFORCE_AGENT_PROVIDER_KEY, getTaskforceAgentModel, isTaskforceAgentModelVisible, labelForTaskforceAgentModel, labelForTaskforceAgentProvider, normalizeTaskforceAgentModelKey, normalizeTaskforceAgentModelSelection, normalizeTaskforceAgentProviderKey, } from '../../shared/taskforceAgentModels.js';
|
|
30
33
|
import { buildTaskforceAgentRunContext } from '../../shared/taskforceAgentRunContext.js';
|
|
31
|
-
import { inspectAgentDefinition } from '../../shared/taskforceAgentDefinition.js';
|
|
34
|
+
import { inspectAgentDefinition, serializeCanonicalJson } from '../../shared/taskforceAgentDefinition.js';
|
|
32
35
|
import { buildResolvedTaskforceAgentSystemPrompt, resolveTaskforceAgentRuntimeConfiguration, TaskforceAgentRuntimeResolutionError, } from '../../shared/taskforceAgentRuntimeResolution.js';
|
|
33
36
|
import { serializeTaskforceAgentExecutionSnapshot } from '../../shared/taskforceAgentExecutionSnapshot.js';
|
|
34
37
|
import { getTaskReferenceLabel } from '../../utils/taskReferences.js';
|
|
@@ -113,6 +116,11 @@ function normalizeMessages(value, fallbackPrompt) {
|
|
|
113
116
|
return { error: 'Prompt must be 4,000 characters or less.' };
|
|
114
117
|
return { messages: [{ role: 'user', content: prompt }] };
|
|
115
118
|
}
|
|
119
|
+
function buildManagedAgentExecutionRequestId(input) {
|
|
120
|
+
return createHash('sha256')
|
|
121
|
+
.update(serializeCanonicalJson(input))
|
|
122
|
+
.digest('hex');
|
|
123
|
+
}
|
|
116
124
|
function toGatewayMessages(messages) {
|
|
117
125
|
return messages.map((message) => ({
|
|
118
126
|
role: message.role,
|
|
@@ -122,7 +130,13 @@ function toGatewayMessages(messages) {
|
|
|
122
130
|
function requestsWorkflowStepCompletion(messages) {
|
|
123
131
|
const latestUserMessage = [...messages].reverse().find((message) => message.role === 'user');
|
|
124
132
|
const content = String(latestUserMessage?.content || '').trim().toLowerCase();
|
|
125
|
-
return /^(?:please\s+|(?:can|could|would)\s+you\s+)?(?:perform\s+and\s+complete|complete|finish)\s+(?:your|the|this)\s+(?:current\s+)?workflow\s+step[.!?]*$/.test(content);
|
|
133
|
+
return /^(?:(?:hey|hi|hello)\b[^,!?]{0,80},?\s+)?(?:please\s+|(?:can|could|would)\s+you\s+)?(?:perform\s+and\s+complete|complete|finish)\s+(?:your|the|this)\s+(?:current\s+)?workflow\s+step(?:\s+(?:on|for)\s+(?:task\s+)?(?:t-\d+|[a-z0-9][a-z0-9-]{0,119}))?[.!?]*$/.test(content);
|
|
134
|
+
}
|
|
135
|
+
function extractLatestExplicitTaskReference(messages) {
|
|
136
|
+
const latestUserMessage = [...messages].reverse().find((message) => message.role === 'user');
|
|
137
|
+
const matches = String(latestUserMessage?.content || '').match(/\bT-\d+\b/gi) || [];
|
|
138
|
+
const references = [...new Set(matches.map((match) => match.toUpperCase()))];
|
|
139
|
+
return references.length === 1 ? references[0] : null;
|
|
126
140
|
}
|
|
127
141
|
function normalizeTaskId(value) {
|
|
128
142
|
const taskId = String(value || '').trim();
|
|
@@ -144,6 +158,18 @@ function resolveTaskContextTask(core, workspaceId, taskId) {
|
|
|
144
158
|
return core.getTask(taskId, workspaceId)
|
|
145
159
|
|| (typeof core.resolveTaskIdentifier === 'function' ? core.resolveTaskIdentifier(taskId, workspaceId) : null);
|
|
146
160
|
}
|
|
161
|
+
function workflowToolCallsTargetSameTask(core, workspaceId, left, right) {
|
|
162
|
+
const resolveCanonicalId = (value) => {
|
|
163
|
+
const taskId = normalizeTaskId(value);
|
|
164
|
+
if (!taskId)
|
|
165
|
+
return null;
|
|
166
|
+
const task = resolveTaskContextTask(core, workspaceId, taskId);
|
|
167
|
+
return normalizeTaskId(task?.id)?.toLowerCase() || taskId.toLowerCase();
|
|
168
|
+
};
|
|
169
|
+
const leftTaskId = resolveCanonicalId(left);
|
|
170
|
+
const rightTaskId = resolveCanonicalId(right);
|
|
171
|
+
return Boolean(leftTaskId && rightTaskId && leftTaskId === rightTaskId);
|
|
172
|
+
}
|
|
147
173
|
function resolveTaskScopeContext(core, workspaceId, input) {
|
|
148
174
|
const taskId = String(input.taskId || '').trim();
|
|
149
175
|
if (!taskId)
|
|
@@ -244,6 +270,12 @@ function createDefaultModelGateway(selection) {
|
|
|
244
270
|
}
|
|
245
271
|
const source = selection?.modelSource || model?.source || 'bedrock';
|
|
246
272
|
const runtime = selection?.runtime || model?.runtime || 'bedrock-runtime';
|
|
273
|
+
if (source === 'subscription_dev' && runtime === 'subscription-dev') {
|
|
274
|
+
if (selection?.connectionScope !== 'local_dev') {
|
|
275
|
+
throw new ModelGatewayConfigurationError('Subscription-dev models require local_dev connection scope.', 'MODEL_SOURCE_UNAVAILABLE');
|
|
276
|
+
}
|
|
277
|
+
return new CodexAppServerModelGateway();
|
|
278
|
+
}
|
|
247
279
|
if (source !== 'bedrock') {
|
|
248
280
|
throw new ModelGatewayConfigurationError('Selected model source is not configured yet.', 'MODEL_SOURCE_NOT_IMPLEMENTED');
|
|
249
281
|
}
|
|
@@ -693,7 +725,7 @@ export function registerAgentsRoutes(deps) {
|
|
|
693
725
|
const ensureTaskforceAgentsAccess = (req, res) => {
|
|
694
726
|
if (!ensureAppAccess(req, res))
|
|
695
727
|
return false;
|
|
696
|
-
const gate =
|
|
728
|
+
const gate = resolveNodeAppGateAccess(TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY);
|
|
697
729
|
if (gate.allowed)
|
|
698
730
|
return true;
|
|
699
731
|
writeJson(res, 403, {
|
|
@@ -1149,9 +1181,30 @@ export function registerAgentsRoutes(deps) {
|
|
|
1149
1181
|
}
|
|
1150
1182
|
}
|
|
1151
1183
|
const savedConversationTaskId = savedConversation?.taskId ? normalizeTaskId(savedConversation.taskId) : null;
|
|
1152
|
-
const
|
|
1153
|
-
const
|
|
1154
|
-
|
|
1184
|
+
const explicitTaskReference = extractLatestExplicitTaskReference(normalizedMessages.messages);
|
|
1185
|
+
const explicitTask = explicitTaskReference
|
|
1186
|
+
? resolveTaskContextTask(core, workspaceId, explicitTaskReference)
|
|
1187
|
+
: null;
|
|
1188
|
+
if (explicitTaskReference
|
|
1189
|
+
&& !explicitTask
|
|
1190
|
+
&& requestsWorkflowStepCompletion(normalizedMessages.messages)) {
|
|
1191
|
+
writeJson(res, 404, {
|
|
1192
|
+
success: false,
|
|
1193
|
+
error: `Task ${explicitTaskReference} was not found.`,
|
|
1194
|
+
code: 'TASK_NOT_FOUND',
|
|
1195
|
+
});
|
|
1196
|
+
return;
|
|
1197
|
+
}
|
|
1198
|
+
const taskId = normalizeTaskId(explicitTask?.id)
|
|
1199
|
+
|| (explicitTaskReference ? null : hasTaskId ? bodyTaskId : savedConversationTaskId);
|
|
1200
|
+
const taskReference = taskId
|
|
1201
|
+
? normalizeTaskContextValue(getTaskReferenceLabel(explicitTask)
|
|
1202
|
+
|| (explicitTask ? explicitTaskReference : null)
|
|
1203
|
+
|| body?.taskReference)
|
|
1204
|
+
: '';
|
|
1205
|
+
const taskTitle = taskId
|
|
1206
|
+
? normalizeTaskContextValue(explicitTask?.title || body?.taskTitle)
|
|
1207
|
+
: '';
|
|
1155
1208
|
if (resolvedRuntimeConfiguration) {
|
|
1156
1209
|
const definition = resolvedRuntimeConfiguration.definition;
|
|
1157
1210
|
const draftDiffers = ((body?.providerKey !== undefined
|
|
@@ -1272,6 +1325,13 @@ export function registerAgentsRoutes(deps) {
|
|
|
1272
1325
|
allowedMutationTaskId: taskId ?? null,
|
|
1273
1326
|
readOnly: !savedAgent,
|
|
1274
1327
|
toolPolicy: resolvedRuntimeConfiguration?.definition.toolPolicy,
|
|
1328
|
+
executionRequestId: buildManagedAgentExecutionRequestId({
|
|
1329
|
+
workspaceId,
|
|
1330
|
+
agentId: savedAgent?.id || agentId || null,
|
|
1331
|
+
conversationId,
|
|
1332
|
+
taskId: taskId ?? null,
|
|
1333
|
+
messages: normalizedMessages.messages,
|
|
1334
|
+
}),
|
|
1275
1335
|
system: scopedAgentSystem,
|
|
1276
1336
|
});
|
|
1277
1337
|
const executionSnapshot = savedAgent && resolvedRuntimeConfiguration
|
|
@@ -1304,21 +1364,40 @@ export function registerAgentsRoutes(deps) {
|
|
|
1304
1364
|
&& mcpBridge?.availableToolNames.includes('complete_workflow_step')
|
|
1305
1365
|
&& requestsWorkflowStepCompletion(gatewayInput.messages));
|
|
1306
1366
|
let workflowCompletionCorrectionSent = false;
|
|
1367
|
+
let reservedWorkflowCompletionUsed = false;
|
|
1307
1368
|
while (mcpBridge) {
|
|
1308
1369
|
if (requestedToolCall) {
|
|
1309
|
-
|
|
1370
|
+
const activeToolCall = requestedToolCall;
|
|
1371
|
+
const workflowStepAlreadyCompleted = mcpToolResults.some((toolResult) => (toolResult.name === 'complete_workflow_step' && toolResult.ok));
|
|
1372
|
+
const workflowStepLoaded = activeToolCall.name === 'complete_workflow_step'
|
|
1373
|
+
&& mcpToolResults.some((toolResult) => (toolResult.name === 'get_task_workflow'
|
|
1374
|
+
&& toolResult.ok
|
|
1375
|
+
&& workflowToolCallsTargetSameTask(core, workspaceId, toolResult.arguments?.taskId, activeToolCall.arguments?.taskId)));
|
|
1376
|
+
const canUseReservedWorkflowCompletion = Boolean(workflowCompletionRequested
|
|
1377
|
+
&& !workflowStepAlreadyCompleted
|
|
1378
|
+
&& !reservedWorkflowCompletionUsed
|
|
1379
|
+
&& activeToolCall.name === 'complete_workflow_step'
|
|
1380
|
+
&& workflowStepLoaded
|
|
1381
|
+
&& unresolvedFailedMutations.size === 0);
|
|
1382
|
+
if (mcpToolResults.length >= MAX_MCP_TOOL_ITERATIONS
|
|
1383
|
+
&& !canUseReservedWorkflowCompletion)
|
|
1310
1384
|
break;
|
|
1311
|
-
|
|
1312
|
-
|
|
1385
|
+
if (mcpToolResults.length >= MAX_MCP_TOOL_ITERATIONS) {
|
|
1386
|
+
reservedWorkflowCompletionUsed = true;
|
|
1387
|
+
}
|
|
1388
|
+
const blocksWorkflowCompletion = activeToolCall.name === 'complete_workflow_step'
|
|
1389
|
+
&& (!workflowStepLoaded || unresolvedFailedMutations.size > 0);
|
|
1313
1390
|
const unresolvedMutationNames = [...new Set(unresolvedFailedMutations.values())];
|
|
1314
1391
|
const toolResult = blocksWorkflowCompletion
|
|
1315
1392
|
? {
|
|
1316
|
-
name:
|
|
1317
|
-
arguments:
|
|
1393
|
+
name: activeToolCall.name,
|
|
1394
|
+
arguments: activeToolCall.arguments,
|
|
1318
1395
|
ok: false,
|
|
1319
|
-
text:
|
|
1396
|
+
text: !workflowStepLoaded
|
|
1397
|
+
? 'Taskforce refused workflow completion because the current workflow step was not loaded successfully. Call get_task_workflow first, perform its instructions, then retry completion.'
|
|
1398
|
+
: `Taskforce refused workflow completion because these earlier changes failed: ${unresolvedMutationNames.join(', ')}. Retry the failed changes successfully before completing the step.`,
|
|
1320
1399
|
}
|
|
1321
|
-
: await mcpBridge.executeToolCall(
|
|
1400
|
+
: await mcpBridge.executeToolCall(activeToolCall);
|
|
1322
1401
|
mcpToolResults.push(toolResult);
|
|
1323
1402
|
if (isTaskforceAgentMutationToolName(toolResult.name)
|
|
1324
1403
|
&& toolResult.name !== 'complete_workflow_step') {
|
|
@@ -1349,6 +1428,17 @@ export function registerAgentsRoutes(deps) {
|
|
|
1349
1428
|
throw error;
|
|
1350
1429
|
}
|
|
1351
1430
|
requestedToolCall = mcpBridge.parseToolCall(result.text);
|
|
1431
|
+
if (toolResult.name === 'complete_workflow_step'
|
|
1432
|
+
&& toolResult.ok
|
|
1433
|
+
&& requestedToolCall
|
|
1434
|
+
&& mcpToolResults.length >= MAX_MCP_TOOL_ITERATIONS) {
|
|
1435
|
+
result = {
|
|
1436
|
+
...result,
|
|
1437
|
+
text: 'Workflow step completed successfully.',
|
|
1438
|
+
};
|
|
1439
|
+
requestedToolCall = null;
|
|
1440
|
+
break;
|
|
1441
|
+
}
|
|
1352
1442
|
continue;
|
|
1353
1443
|
}
|
|
1354
1444
|
const workflowStepCompleted = mcpToolResults.some((toolResult) => (toolResult.name === 'complete_workflow_step' && toolResult.ok));
|
|
@@ -1358,7 +1448,7 @@ export function registerAgentsRoutes(deps) {
|
|
|
1358
1448
|
role: 'user',
|
|
1359
1449
|
content: unresolvedFailedMutations.size > 0
|
|
1360
1450
|
? `The workflow step is not complete because these Taskforce changes failed: ${[...new Set(unresolvedFailedMutations.values())].join(', ')}. Retry those exact changes successfully before calling complete_workflow_step. If they cannot succeed, respond exactly WORKFLOW_STEP_INCOMPLETE: followed by the reason.`
|
|
1361
|
-
: 'The workflow step is not authoritatively complete.
|
|
1451
|
+
: 'The workflow step is not authoritatively complete. Call get_task_workflow first if it has not succeeded in this response, perform the returned step instructions, then call complete_workflow_step. Otherwise respond exactly WORKFLOW_STEP_INCOMPLETE: followed by the reason. Do not claim completion without successful tool results.',
|
|
1362
1452
|
});
|
|
1363
1453
|
result = await gateway.generate({
|
|
1364
1454
|
...gatewayInput,
|
|
@@ -1370,7 +1460,19 @@ export function registerAgentsRoutes(deps) {
|
|
|
1370
1460
|
break;
|
|
1371
1461
|
}
|
|
1372
1462
|
if (requestedToolCall) {
|
|
1373
|
-
|
|
1463
|
+
mcpToolResults.push({
|
|
1464
|
+
name: requestedToolCall.name,
|
|
1465
|
+
arguments: requestedToolCall.arguments,
|
|
1466
|
+
ok: false,
|
|
1467
|
+
text: 'Taskforce did not execute this call because the per-message tool limit was reached.',
|
|
1468
|
+
});
|
|
1469
|
+
result = {
|
|
1470
|
+
...result,
|
|
1471
|
+
text: workflowCompletionRequested
|
|
1472
|
+
? 'WORKFLOW_STEP_INCOMPLETE: Taskforce reached the per-message tool limit before finishing the workflow step. Review Tool Activity and retry.'
|
|
1473
|
+
: 'Taskforce reached the per-message tool limit. Review Tool Activity and retry.',
|
|
1474
|
+
};
|
|
1475
|
+
requestedToolCall = null;
|
|
1374
1476
|
}
|
|
1375
1477
|
if (workflowCompletionRequested && !mcpToolResults.some((toolResult) => (toolResult.name === 'complete_workflow_step' && toolResult.ok))) {
|
|
1376
1478
|
const incompletePrefix = 'WORKFLOW_STEP_INCOMPLETE:';
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
* DELETE /api/taskforce/annotated-attachments/sessions/:id
|
|
12
12
|
* GET /api/taskforce/annotated-attachments/sessions/:id/payload
|
|
13
13
|
*/
|
|
14
|
-
import { ANNOTATED_ATTACHMENTS_WORKSPACE_FEATURE_KEY,
|
|
14
|
+
import { ANNOTATED_ATTACHMENTS_WORKSPACE_FEATURE_KEY, } from '../../runtime/appGates.js';
|
|
15
|
+
import { resolveNodeAppGateAccess } from '../../runtime/nodeAppGates.js';
|
|
15
16
|
import { parseJsonBody } from './primitives.js';
|
|
16
17
|
import { resolveErrorStatusCode } from './shared.js';
|
|
17
18
|
import { getImageReferenceLabel, parseImageReference } from '../../utils/imageReferences.js';
|
|
@@ -37,7 +38,7 @@ export function registerAnnotatedAttachmentRoutes(deps) {
|
|
|
37
38
|
const ensureAnnotatedAttachmentAccess = (req, res, workspaceId) => {
|
|
38
39
|
if (!ensureAppAccess(req, res))
|
|
39
40
|
return false;
|
|
40
|
-
const gate =
|
|
41
|
+
const gate = resolveNodeAppGateAccess(ANNOTATED_ATTACHMENTS_WORKSPACE_FEATURE_KEY);
|
|
41
42
|
if (gate.allowed)
|
|
42
43
|
return true;
|
|
43
44
|
writeJson(res, 403, {
|
|
@@ -60,6 +60,7 @@ import { buildGithubAuthUrl, exchangeGithubCode } from '../auth/providers/github
|
|
|
60
60
|
import { hasValidSession, createClearSessionCookie, createSessionTokenCookie, resolveRequestAccess, resolveSessionCookieAttributesForRequest, } from '../auth.js';
|
|
61
61
|
import { sendEmail } from '../email.js';
|
|
62
62
|
import { resolveDeploymentConfig } from '../../config/deployment.js';
|
|
63
|
+
import { resolveNodeAppGateAccessMap } from '../../runtime/nodeAppGates.js';
|
|
63
64
|
import { resolveTaskMetadataActivationCapability } from '../../sync/v3/taskMetadataActivation.js';
|
|
64
65
|
import { resolveTaskCreateActivationCapability } from '../../sync/v3/taskCreateActivation.js';
|
|
65
66
|
import { resolveTaskStatusActivationCapability } from '../../sync/v3/taskStatusActivation.js';
|
|
@@ -401,7 +402,7 @@ export function registerAuthRoutes(deps) {
|
|
|
401
402
|
: 'Reset your Taskforce password';
|
|
402
403
|
const text = kind === 'verify-email'
|
|
403
404
|
? `Welcome to Taskforce.\n\nYou're almost in. Enter this verification token on the verification screen to activate your account:\n\n${token}\n\nPrefer the faster route? Open the link below to verify your email automatically:\n${link}\n\nIf you didn't create a Taskforce account, you can safely ignore this email.`
|
|
404
|
-
: `
|
|
405
|
+
: `Enter this password reset token on the reset screen:\n\n${token}\n\nOr reset your Taskforce password using this link:\n${link}\n\nIf you did not request this reset, you can ignore this message.`;
|
|
405
406
|
const result = await sendEmail({
|
|
406
407
|
to: email,
|
|
407
408
|
subject,
|
|
@@ -470,6 +471,7 @@ export function registerAuthRoutes(deps) {
|
|
|
470
471
|
authSource: runtimeContract.authSource,
|
|
471
472
|
workspaceMode: runtimeContract.workspaceMode,
|
|
472
473
|
workspaceSwitchingEnabled: runtimeContract.workspaceSwitchingEnabled,
|
|
474
|
+
appGates: resolveNodeAppGateAccessMap(process.env),
|
|
473
475
|
syncV3
|
|
474
476
|
}
|
|
475
477
|
}));
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* POST /api/taskforce/context-upload/init
|
|
9
9
|
* POST /api/taskforce/context-upload/finalize
|
|
10
10
|
* POST /api/taskforce/context-upload
|
|
11
|
+
* POST /api/taskforce/context-upload/draft/promote
|
|
12
|
+
* POST /api/taskforce/context-upload/draft/discard
|
|
11
13
|
* GET /api/taskforce/context/:filename
|
|
12
14
|
* GET /api/taskforce/documents/:assetId/content
|
|
13
15
|
* GET /api/taskforce/context-link
|
|
@@ -39,7 +41,7 @@ type AssetMetadata = DocumentRegistryEntry & {
|
|
|
39
41
|
originalFilename?: string | null;
|
|
40
42
|
};
|
|
41
43
|
interface CanonicalReadResult {
|
|
42
|
-
statusCode: 200 | 302 | 404;
|
|
44
|
+
statusCode: 200 | 302 | 404 | 409;
|
|
43
45
|
headers?: Record<string, string>;
|
|
44
46
|
body?: Buffer;
|
|
45
47
|
}
|
|
@@ -81,6 +83,7 @@ export interface DocumentRouteDependencies {
|
|
|
81
83
|
workspaceId?: string;
|
|
82
84
|
taskId?: string | null;
|
|
83
85
|
originalName?: string | null;
|
|
86
|
+
actorRef?: string | null;
|
|
84
87
|
}) => Promise<{
|
|
85
88
|
scan?: {
|
|
86
89
|
verdict?: string;
|
|
@@ -110,7 +113,7 @@ export interface DocumentRouteDependencies {
|
|
|
110
113
|
sanitizeDownloadFilename: (nameRaw: string, fallback?: string) => string;
|
|
111
114
|
contentTypeForExt: (ext: string) => string;
|
|
112
115
|
inferInlineDocumentFromPath: (pathValue: string | null | undefined) => boolean;
|
|
113
|
-
|
|
116
|
+
resolveCanonicalContentRead: (params: {
|
|
114
117
|
asset: WorkspaceAssetEntry;
|
|
115
118
|
forceDownload: boolean;
|
|
116
119
|
requestedFilename?: string | null;
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* POST /api/taskforce/context-upload/init
|
|
9
9
|
* POST /api/taskforce/context-upload/finalize
|
|
10
10
|
* POST /api/taskforce/context-upload
|
|
11
|
+
* POST /api/taskforce/context-upload/draft/promote
|
|
12
|
+
* POST /api/taskforce/context-upload/draft/discard
|
|
11
13
|
* GET /api/taskforce/context/:filename
|
|
12
14
|
* GET /api/taskforce/documents/:assetId/content
|
|
13
15
|
* GET /api/taskforce/context-link
|
|
@@ -33,7 +35,7 @@ import { parsePlan } from '../../utils/planParser.js';
|
|
|
33
35
|
import { getCanonicalDocumentName, getReadableDocumentName, isGeneratedDocumentName } from '../../utils/documentNames.js';
|
|
34
36
|
import { createWorkspaceAssetAccessGuard } from './assetAccess.js';
|
|
35
37
|
import { parseJsonBody } from './primitives.js';
|
|
36
|
-
import { requestHeader, requestRuntimeMode, resolveErrorStatusCode } from './shared.js';
|
|
38
|
+
import { requestHeader, requestHumanActorRef, requestRuntimeMode, requestUserId, resolveErrorStatusCode, } from './shared.js';
|
|
37
39
|
import { resolveDeploymentConfig } from '../../config/deployment.js';
|
|
38
40
|
import { isAiProfileAvatarStorageKey } from '../../utils/aiProfileAvatarPaths.js';
|
|
39
41
|
import { createTaskHttpDurableRouters } from './durableTaskHttpRouters.js';
|
|
@@ -110,7 +112,7 @@ async function proxyCloudUserProfileAvatar(req, res, relativePath, contentTypeFo
|
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
114
|
export function registerDocumentRoutes(deps) {
|
|
113
|
-
const { addRoute, core, context, requestWorkspaceId, ensureAdminRole, resolveEffectiveObjectStorageConfig, getObjectStorageClient, resolveStorageWorkspaceId, ensureContextUploadAllowed, parseStorageFolderSegments, buildCanonicalWorkspaceAssetRelativePath, inferAssetKindFromPath, appendStorageTelemetry, scanAndRecordDocument, buildTaskAttachmentPayload, workspaceAssetStore, taskAssetStore, normalizeDocumentPathInput, getAssetMetadata, getCanonicalAssetMetadata, documentRetentionDays, appendDocumentPurgeHistory, markAssetDeleted, isAssetDeleted, clearAssetDeleted, ensureWithinDir, sanitizeDownloadFilename, contentTypeForExt, inferInlineDocumentFromPath,
|
|
115
|
+
const { addRoute, core, context, requestWorkspaceId, ensureAdminRole, resolveEffectiveObjectStorageConfig, getObjectStorageClient, resolveStorageWorkspaceId, ensureContextUploadAllowed, parseStorageFolderSegments, buildCanonicalWorkspaceAssetRelativePath, inferAssetKindFromPath, appendStorageTelemetry, scanAndRecordDocument, buildTaskAttachmentPayload, workspaceAssetStore, taskAssetStore, normalizeDocumentPathInput, getAssetMetadata, getCanonicalAssetMetadata, documentRetentionDays, appendDocumentPurgeHistory, markAssetDeleted, isAssetDeleted, clearAssetDeleted, ensureWithinDir, sanitizeDownloadFilename, contentTypeForExt, inferInlineDocumentFromPath, resolveCanonicalContentRead, inferWorkspaceIdFromStoragePath, inferTaskIdFromStoragePath, } = deps;
|
|
114
116
|
const isTaskAttachmentDurable = (req, workspaceId) => (createTaskHttpDurableRouters({ core, context, req, workspaceId }).attachmentLinks.enabled);
|
|
115
117
|
const durableUploadIdentity = (req, workspaceId, taskId) => {
|
|
116
118
|
const normalizedTaskId = String(taskId || '').trim();
|
|
@@ -172,6 +174,69 @@ export function registerDocumentRoutes(deps) {
|
|
|
172
174
|
return String(url.searchParams.get('workspaceId') || '').trim() || requestWorkspaceId(req);
|
|
173
175
|
};
|
|
174
176
|
const { ensureWorkspaceAssetAccess, isCloudAssetRequest } = createWorkspaceAssetAccessGuard({ core, context });
|
|
177
|
+
const readTaskDescriptionDraftUpload = (body) => {
|
|
178
|
+
const draftId = String(body?.draftUploadId || '').trim();
|
|
179
|
+
const purpose = String(body?.uploadPurpose || '').trim();
|
|
180
|
+
if (!draftId && !purpose)
|
|
181
|
+
return null;
|
|
182
|
+
if (purpose !== 'task-description-draft' || !/^[a-zA-Z0-9-]{16,160}$/.test(draftId)) {
|
|
183
|
+
throw Object.assign(new Error('Invalid task Description draft upload identity.'), { statusCode: 400 });
|
|
184
|
+
}
|
|
185
|
+
return { draftId, purpose };
|
|
186
|
+
};
|
|
187
|
+
const recordTaskDescriptionDraftUpload = (input) => {
|
|
188
|
+
const draft = readTaskDescriptionDraftUpload(input.body);
|
|
189
|
+
if (!draft || !workspaceAssetStore)
|
|
190
|
+
return;
|
|
191
|
+
workspaceAssetStore.recordUploadDraft({
|
|
192
|
+
workspaceId: input.workspaceId,
|
|
193
|
+
draftId: draft.draftId,
|
|
194
|
+
assetId: input.assetId,
|
|
195
|
+
storageKey: input.storageKey,
|
|
196
|
+
purpose: draft.purpose,
|
|
197
|
+
createdByUserId: String(requestUserId(input.req) || '').trim() || 'anonymous',
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
const retireOrDeleteTaskDescriptionDraftUploads = async (input) => {
|
|
201
|
+
if (!workspaceAssetStore)
|
|
202
|
+
return { total: 0, promoted: 0, discarded: 0 };
|
|
203
|
+
const records = workspaceAssetStore.listUploadDrafts(input);
|
|
204
|
+
const now = new Date();
|
|
205
|
+
const deletedAt = now.toISOString();
|
|
206
|
+
const purgeAfter = new Date(now.getTime() + documentRetentionDays * 86_400_000).toISOString();
|
|
207
|
+
let promoted = 0;
|
|
208
|
+
let discarded = 0;
|
|
209
|
+
for (const record of records) {
|
|
210
|
+
const links = workspaceAssetStore.listLinksForAsset(record.assetId, record.workspaceId);
|
|
211
|
+
if (links.length > 0) {
|
|
212
|
+
workspaceAssetStore.retireUploadDraft({
|
|
213
|
+
workspaceId: record.workspaceId,
|
|
214
|
+
draftId: record.draftId,
|
|
215
|
+
assetId: record.assetId,
|
|
216
|
+
retiredAt: deletedAt,
|
|
217
|
+
});
|
|
218
|
+
promoted += 1;
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
const asset = workspaceAssetStore.get(record.assetId, record.workspaceId);
|
|
222
|
+
if (asset && !asset.deletedAt) {
|
|
223
|
+
workspaceAssetStore.assertAssetDeletionAllowed(record.assetId, record.workspaceId);
|
|
224
|
+
workspaceAssetStore.markDeleted(record.assetId, record.workspaceId, deletedAt, purgeAfter);
|
|
225
|
+
core.notifyDocumentMetadataMutation(record.workspaceId, [record.storageKey], 'delete');
|
|
226
|
+
}
|
|
227
|
+
else if (!asset) {
|
|
228
|
+
await getObjectStorageClient()?.deleteObject(record.storageKey);
|
|
229
|
+
}
|
|
230
|
+
workspaceAssetStore.retireUploadDraft({
|
|
231
|
+
workspaceId: record.workspaceId,
|
|
232
|
+
draftId: record.draftId,
|
|
233
|
+
assetId: record.assetId,
|
|
234
|
+
retiredAt: deletedAt,
|
|
235
|
+
});
|
|
236
|
+
discarded += 1;
|
|
237
|
+
}
|
|
238
|
+
return { total: records.length, promoted, discarded };
|
|
239
|
+
};
|
|
175
240
|
const removeDocumentAttachmentFromTaskAttachments = (attachmentsRaw, asset) => {
|
|
176
241
|
const canonicalDocumentPath = `/api/taskforce/documents/${encodeURIComponent(asset.assetId)}/content`;
|
|
177
242
|
const legacyContextPath = `/api/taskforce/context/${encodeURIComponent(asset.storageKey)}`;
|
|
@@ -260,6 +325,13 @@ export function registerDocumentRoutes(deps) {
|
|
|
260
325
|
const relativeToStorage = canonicalAsset.relativePath;
|
|
261
326
|
const relativePath = path.relative(projectRoot, path.join(basePath, relativeToStorage));
|
|
262
327
|
if (objectStorageClient && resolvedObjectStorage.provider === 'r2' && resolvedObjectStorage.r2) {
|
|
328
|
+
recordTaskDescriptionDraftUpload({
|
|
329
|
+
req,
|
|
330
|
+
body,
|
|
331
|
+
workspaceId,
|
|
332
|
+
assetId: canonicalAsset.assetId,
|
|
333
|
+
storageKey: relativeToStorage,
|
|
334
|
+
});
|
|
263
335
|
const uploadUrl = objectStorageClient.createSignedPutUrl(relativeToStorage, resolvedObjectStorage.r2.signedUploadTtlSeconds, String(mimeType || 'application/octet-stream'));
|
|
264
336
|
appendStorageTelemetry('upload.initiated', {
|
|
265
337
|
path: relativeToStorage,
|
|
@@ -345,8 +417,19 @@ export function registerDocumentRoutes(deps) {
|
|
|
345
417
|
provider: 'r2',
|
|
346
418
|
workspaceId: inferWorkspaceIdFromStoragePath(relativeToStorage),
|
|
347
419
|
taskId: durableTaskAttachment ? null : taskId,
|
|
348
|
-
originalName: typeof body?.originalName === 'string' ? body.originalName.trim() : null
|
|
420
|
+
originalName: typeof body?.originalName === 'string' ? body.originalName.trim() : null,
|
|
421
|
+
actorRef: requestHumanActorRef(req),
|
|
349
422
|
});
|
|
423
|
+
const finalizedAsset = workspaceAssetStore?.getByStorageKey(relativeToStorage, workspaceId);
|
|
424
|
+
if (finalizedAsset) {
|
|
425
|
+
recordTaskDescriptionDraftUpload({
|
|
426
|
+
req,
|
|
427
|
+
body,
|
|
428
|
+
workspaceId,
|
|
429
|
+
assetId: finalizedAsset.assetId,
|
|
430
|
+
storageKey: relativeToStorage,
|
|
431
|
+
});
|
|
432
|
+
}
|
|
350
433
|
if (durableTaskAttachment && taskId) {
|
|
351
434
|
attachUploadedAssetThroughDurableBoundary({
|
|
352
435
|
req,
|
|
@@ -456,7 +539,8 @@ export function registerDocumentRoutes(deps) {
|
|
|
456
539
|
provider: 'r2',
|
|
457
540
|
workspaceId,
|
|
458
541
|
taskId: durableTaskAttachment ? null : normalizedTaskId,
|
|
459
|
-
originalName: safeOriginal || actualFilename
|
|
542
|
+
originalName: safeOriginal || actualFilename,
|
|
543
|
+
actorRef: requestHumanActorRef(req),
|
|
460
544
|
});
|
|
461
545
|
appendStorageTelemetry('upload.completed', {
|
|
462
546
|
path: relativeToStorage,
|
|
@@ -476,7 +560,8 @@ export function registerDocumentRoutes(deps) {
|
|
|
476
560
|
provider: 'local',
|
|
477
561
|
workspaceId,
|
|
478
562
|
taskId: durableTaskAttachment ? null : normalizedTaskId,
|
|
479
|
-
originalName: safeOriginal || actualFilename
|
|
563
|
+
originalName: safeOriginal || actualFilename,
|
|
564
|
+
actorRef: requestHumanActorRef(req),
|
|
480
565
|
});
|
|
481
566
|
appendStorageTelemetry('upload.completed', {
|
|
482
567
|
path: relativeToStorage,
|
|
@@ -494,6 +579,16 @@ export function registerDocumentRoutes(deps) {
|
|
|
494
579
|
caption: safeOriginal || actualFilename,
|
|
495
580
|
});
|
|
496
581
|
}
|
|
582
|
+
const uploadedAsset = workspaceAssetStore?.getByStorageKey(relativeToStorage, workspaceId);
|
|
583
|
+
if (uploadedAsset) {
|
|
584
|
+
recordTaskDescriptionDraftUpload({
|
|
585
|
+
req,
|
|
586
|
+
body,
|
|
587
|
+
workspaceId,
|
|
588
|
+
assetId: uploadedAsset.assetId,
|
|
589
|
+
storageKey: relativeToStorage,
|
|
590
|
+
});
|
|
591
|
+
}
|
|
497
592
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
498
593
|
const attachment = buildTaskAttachmentPayload(relativeToStorage, {
|
|
499
594
|
caption: safeOriginal || actualFilename,
|
|
@@ -508,6 +603,40 @@ export function registerDocumentRoutes(deps) {
|
|
|
508
603
|
})
|
|
509
604
|
}));
|
|
510
605
|
});
|
|
606
|
+
addRoute('POST', '/api/taskforce/context-upload/draft/promote', async (req, res) => {
|
|
607
|
+
const body = await parseJsonBody(req);
|
|
608
|
+
const workspaceId = resolveStorageWorkspaceId(req, body);
|
|
609
|
+
const draft = readTaskDescriptionDraftUpload(body);
|
|
610
|
+
if (!workspaceId || !draft) {
|
|
611
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
612
|
+
res.end(JSON.stringify({ error: 'workspaceId and draft upload identity are required.' }));
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
const summary = await retireOrDeleteTaskDescriptionDraftUploads({
|
|
616
|
+
workspaceId,
|
|
617
|
+
draftId: draft.draftId,
|
|
618
|
+
createdByUserId: String(requestUserId(req) || '').trim() || 'anonymous',
|
|
619
|
+
});
|
|
620
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
621
|
+
res.end(JSON.stringify({ success: true, ...summary }));
|
|
622
|
+
});
|
|
623
|
+
addRoute('POST', '/api/taskforce/context-upload/draft/discard', async (req, res) => {
|
|
624
|
+
const body = await parseJsonBody(req);
|
|
625
|
+
const workspaceId = resolveStorageWorkspaceId(req, body);
|
|
626
|
+
const draft = readTaskDescriptionDraftUpload(body);
|
|
627
|
+
if (!workspaceId || !draft) {
|
|
628
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
629
|
+
res.end(JSON.stringify({ error: 'workspaceId and draft upload identity are required.' }));
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
const summary = await retireOrDeleteTaskDescriptionDraftUploads({
|
|
633
|
+
workspaceId,
|
|
634
|
+
draftId: draft.draftId,
|
|
635
|
+
createdByUserId: String(requestUserId(req) || '').trim() || 'anonymous',
|
|
636
|
+
});
|
|
637
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
638
|
+
res.end(JSON.stringify({ success: true, ...summary }));
|
|
639
|
+
});
|
|
511
640
|
addRoute('GET', '/api/taskforce/context/:filename', async (req, res, params) => {
|
|
512
641
|
const resolvedObjectStorage = resolveEffectiveObjectStorageConfig();
|
|
513
642
|
const objectStorageClient = getObjectStorageClient();
|
|
@@ -556,8 +685,8 @@ export function registerDocumentRoutes(deps) {
|
|
|
556
685
|
? `attachment; filename="${resolvedDownloadName.replace(/"/g, '')}"`
|
|
557
686
|
: 'inline';
|
|
558
687
|
const shouldProxyInlineDocument = !forceDownload && (canonicalAsset?.kind === 'document' || inferInlineDocumentFromPath(normalizedRelative));
|
|
559
|
-
if (canonicalAsset
|
|
560
|
-
const response = await
|
|
688
|
+
if (canonicalAsset && !canonicalAsset.deletedAt && (canonicalAsset.kind === 'document' || !filePath)) {
|
|
689
|
+
const response = await resolveCanonicalContentRead({
|
|
561
690
|
asset: canonicalAsset,
|
|
562
691
|
forceDownload,
|
|
563
692
|
requestedFilename
|
|
@@ -567,6 +696,11 @@ export function registerDocumentRoutes(deps) {
|
|
|
567
696
|
res.end('Context file not found');
|
|
568
697
|
return;
|
|
569
698
|
}
|
|
699
|
+
if (response.statusCode === 409) {
|
|
700
|
+
res.writeHead(409, response.headers || { 'Content-Type': 'application/json' });
|
|
701
|
+
res.end(response.body);
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
570
704
|
if (forceDownload && response.statusCode === 302 && response.headers?.Location) {
|
|
571
705
|
res.writeHead(302, { Location: response.headers.Location });
|
|
572
706
|
res.end();
|
|
@@ -659,7 +793,7 @@ export function registerDocumentRoutes(deps) {
|
|
|
659
793
|
res.end('Document scan pending');
|
|
660
794
|
return;
|
|
661
795
|
}
|
|
662
|
-
const response = await
|
|
796
|
+
const response = await resolveCanonicalContentRead({
|
|
663
797
|
asset,
|
|
664
798
|
forceDownload,
|
|
665
799
|
requestedFilename
|
|
@@ -669,6 +803,11 @@ export function registerDocumentRoutes(deps) {
|
|
|
669
803
|
res.end(JSON.stringify({ error: 'Document content not found' }));
|
|
670
804
|
return;
|
|
671
805
|
}
|
|
806
|
+
if (response.statusCode === 409) {
|
|
807
|
+
res.writeHead(409, response.headers || { 'Content-Type': 'application/json' });
|
|
808
|
+
res.end(response.body);
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
672
811
|
if (forceDownload && response.statusCode === 302 && response.headers?.Location) {
|
|
673
812
|
res.writeHead(302, { Location: response.headers.Location });
|
|
674
813
|
res.end();
|
|
@@ -791,6 +930,12 @@ export function registerDocumentRoutes(deps) {
|
|
|
791
930
|
res.end(JSON.stringify({ error: 'Forbidden: admin role required.' }));
|
|
792
931
|
return;
|
|
793
932
|
}
|
|
933
|
+
const workspaceId = requestWorkspaceId(req);
|
|
934
|
+
const draftExpiry = new Date(Date.now() - 30 * 86_400_000).toISOString();
|
|
935
|
+
const draftSummary = await retireOrDeleteTaskDescriptionDraftUploads({
|
|
936
|
+
workspaceId,
|
|
937
|
+
createdBefore: draftExpiry,
|
|
938
|
+
});
|
|
794
939
|
const { basePath } = core.getPaths();
|
|
795
940
|
const summary = await purgeExpiredDocuments({
|
|
796
941
|
basePath,
|
|
@@ -804,7 +949,7 @@ export function registerDocumentRoutes(deps) {
|
|
|
804
949
|
provider: resolveEffectiveObjectStorageConfig().provider
|
|
805
950
|
});
|
|
806
951
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
807
|
-
res.end(JSON.stringify({ success: true, ...summary }));
|
|
952
|
+
res.end(JSON.stringify({ success: true, ...summary, draftUploads: draftSummary }));
|
|
808
953
|
});
|
|
809
954
|
addRoute('GET', '/api/taskforce/documents', async (req, res) => {
|
|
810
955
|
const workspaceId = requestWorkspaceIdWithQuery(req);
|
|
@@ -1059,7 +1204,7 @@ export function registerDocumentRoutes(deps) {
|
|
|
1059
1204
|
core.updateTask(targetId, {
|
|
1060
1205
|
attachments: [...(Array.isArray(task.attachments) ? task.attachments : []), payload],
|
|
1061
1206
|
}, workspaceId, {
|
|
1062
|
-
actorRef:
|
|
1207
|
+
actorRef: requestHumanActorRef(req),
|
|
1063
1208
|
saveSource: 'manual',
|
|
1064
1209
|
});
|
|
1065
1210
|
}
|
|
@@ -1124,7 +1269,7 @@ export function registerDocumentRoutes(deps) {
|
|
|
1124
1269
|
else {
|
|
1125
1270
|
const updatedAttachments = removeDocumentAttachmentFromTaskAttachments(task.attachments, asset);
|
|
1126
1271
|
core.updateTask(taskId, { attachments: updatedAttachments }, workspaceId, {
|
|
1127
|
-
actorRef:
|
|
1272
|
+
actorRef: requestHumanActorRef(req),
|
|
1128
1273
|
saveSource: 'manual'
|
|
1129
1274
|
});
|
|
1130
1275
|
}
|
|
@@ -1280,7 +1425,8 @@ export function registerDocumentRoutes(deps) {
|
|
|
1280
1425
|
contentType: 'text/markdown; charset=utf-8',
|
|
1281
1426
|
provider: 'r2',
|
|
1282
1427
|
workspaceId: assetWorkspaceId,
|
|
1283
|
-
originalName: metadata.logicalName || metadata.originalFilename || path.basename(normalizedStoragePath)
|
|
1428
|
+
originalName: metadata.logicalName || metadata.originalFilename || path.basename(normalizedStoragePath),
|
|
1429
|
+
actorRef: requestHumanActorRef(req),
|
|
1284
1430
|
});
|
|
1285
1431
|
clearAssetDeleted(normalizedStoragePath);
|
|
1286
1432
|
const version = workspaceAssetStore
|
|
@@ -1336,7 +1482,8 @@ export function registerDocumentRoutes(deps) {
|
|
|
1336
1482
|
contentType: 'text/markdown; charset=utf-8',
|
|
1337
1483
|
provider: 'local',
|
|
1338
1484
|
workspaceId: assetWorkspaceId,
|
|
1339
|
-
originalName: path.basename(normalizedStoragePath)
|
|
1485
|
+
originalName: path.basename(normalizedStoragePath),
|
|
1486
|
+
actorRef: requestHumanActorRef(req),
|
|
1340
1487
|
});
|
|
1341
1488
|
clearAssetDeleted(normalizedStoragePath);
|
|
1342
1489
|
version = workspaceAssetStore
|